semantic.js 674 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351
  1. /*
  2. * # Semantic UI - 2.1.4
  3. * https://github.com/Semantic-Org/Semantic-UI
  4. * http://www.semantic-ui.com/
  5. *
  6. * Copyright 2014 Contributors
  7. * Released under the MIT license
  8. * http://opensource.org/licenses/MIT
  9. *
  10. */
  11. /*!
  12. * # Semantic UI 2.1.4 - Site
  13. * http://github.com/semantic-org/semantic-ui/
  14. *
  15. *
  16. * Copyright 2015 Contributors
  17. * Released under the MIT license
  18. * http://opensource.org/licenses/MIT
  19. *
  20. */
  21. ;(function ( $, window, document, undefined ) {
  22. $.site = $.fn.site = function(parameters) {
  23. var
  24. time = new Date().getTime(),
  25. performance = [],
  26. query = arguments[0],
  27. methodInvoked = (typeof query == 'string'),
  28. queryArguments = [].slice.call(arguments, 1),
  29. settings = ( $.isPlainObject(parameters) )
  30. ? $.extend(true, {}, $.site.settings, parameters)
  31. : $.extend({}, $.site.settings),
  32. namespace = settings.namespace,
  33. error = settings.error,
  34. eventNamespace = '.' + namespace,
  35. moduleNamespace = 'module-' + namespace,
  36. $document = $(document),
  37. $module = $document,
  38. element = this,
  39. instance = $module.data(moduleNamespace),
  40. module,
  41. returnedValue
  42. ;
  43. module = {
  44. initialize: function() {
  45. module.instantiate();
  46. },
  47. instantiate: function() {
  48. module.verbose('Storing instance of site', module);
  49. instance = module;
  50. $module
  51. .data(moduleNamespace, module)
  52. ;
  53. },
  54. normalize: function() {
  55. module.fix.console();
  56. module.fix.requestAnimationFrame();
  57. },
  58. fix: {
  59. console: function() {
  60. module.debug('Normalizing window.console');
  61. if (console === undefined || console.log === undefined) {
  62. module.verbose('Console not available, normalizing events');
  63. module.disable.console();
  64. }
  65. if (typeof console.group == 'undefined' || typeof console.groupEnd == 'undefined' || typeof console.groupCollapsed == 'undefined') {
  66. module.verbose('Console group not available, normalizing events');
  67. window.console.group = function() {};
  68. window.console.groupEnd = function() {};
  69. window.console.groupCollapsed = function() {};
  70. }
  71. if (typeof console.markTimeline == 'undefined') {
  72. module.verbose('Mark timeline not available, normalizing events');
  73. window.console.markTimeline = function() {};
  74. }
  75. },
  76. consoleClear: function() {
  77. module.debug('Disabling programmatic console clearing');
  78. window.console.clear = function() {};
  79. },
  80. requestAnimationFrame: function() {
  81. module.debug('Normalizing requestAnimationFrame');
  82. if(window.requestAnimationFrame === undefined) {
  83. module.debug('RequestAnimationFrame not available, normalizing event');
  84. window.requestAnimationFrame = window.requestAnimationFrame
  85. || window.mozRequestAnimationFrame
  86. || window.webkitRequestAnimationFrame
  87. || window.msRequestAnimationFrame
  88. || function(callback) { setTimeout(callback, 0); }
  89. ;
  90. }
  91. }
  92. },
  93. moduleExists: function(name) {
  94. return ($.fn[name] !== undefined && $.fn[name].settings !== undefined);
  95. },
  96. enabled: {
  97. modules: function(modules) {
  98. var
  99. enabledModules = []
  100. ;
  101. modules = modules || settings.modules;
  102. $.each(modules, function(index, name) {
  103. if(module.moduleExists(name)) {
  104. enabledModules.push(name);
  105. }
  106. });
  107. return enabledModules;
  108. }
  109. },
  110. disabled: {
  111. modules: function(modules) {
  112. var
  113. disabledModules = []
  114. ;
  115. modules = modules || settings.modules;
  116. $.each(modules, function(index, name) {
  117. if(!module.moduleExists(name)) {
  118. disabledModules.push(name);
  119. }
  120. });
  121. return disabledModules;
  122. }
  123. },
  124. change: {
  125. setting: function(setting, value, modules, modifyExisting) {
  126. modules = (typeof modules === 'string')
  127. ? (modules === 'all')
  128. ? settings.modules
  129. : [modules]
  130. : modules || settings.modules
  131. ;
  132. modifyExisting = (modifyExisting !== undefined)
  133. ? modifyExisting
  134. : true
  135. ;
  136. $.each(modules, function(index, name) {
  137. var
  138. namespace = (module.moduleExists(name))
  139. ? $.fn[name].settings.namespace || false
  140. : true,
  141. $existingModules
  142. ;
  143. if(module.moduleExists(name)) {
  144. module.verbose('Changing default setting', setting, value, name);
  145. $.fn[name].settings[setting] = value;
  146. if(modifyExisting && namespace) {
  147. $existingModules = $(':data(module-' + namespace + ')');
  148. if($existingModules.length > 0) {
  149. module.verbose('Modifying existing settings', $existingModules);
  150. $existingModules[name]('setting', setting, value);
  151. }
  152. }
  153. }
  154. });
  155. },
  156. settings: function(newSettings, modules, modifyExisting) {
  157. modules = (typeof modules === 'string')
  158. ? [modules]
  159. : modules || settings.modules
  160. ;
  161. modifyExisting = (modifyExisting !== undefined)
  162. ? modifyExisting
  163. : true
  164. ;
  165. $.each(modules, function(index, name) {
  166. var
  167. $existingModules
  168. ;
  169. if(module.moduleExists(name)) {
  170. module.verbose('Changing default setting', newSettings, name);
  171. $.extend(true, $.fn[name].settings, newSettings);
  172. if(modifyExisting && namespace) {
  173. $existingModules = $(':data(module-' + namespace + ')');
  174. if($existingModules.length > 0) {
  175. module.verbose('Modifying existing settings', $existingModules);
  176. $existingModules[name]('setting', newSettings);
  177. }
  178. }
  179. }
  180. });
  181. }
  182. },
  183. enable: {
  184. console: function() {
  185. module.console(true);
  186. },
  187. debug: function(modules, modifyExisting) {
  188. modules = modules || settings.modules;
  189. module.debug('Enabling debug for modules', modules);
  190. module.change.setting('debug', true, modules, modifyExisting);
  191. },
  192. verbose: function(modules, modifyExisting) {
  193. modules = modules || settings.modules;
  194. module.debug('Enabling verbose debug for modules', modules);
  195. module.change.setting('verbose', true, modules, modifyExisting);
  196. }
  197. },
  198. disable: {
  199. console: function() {
  200. module.console(false);
  201. },
  202. debug: function(modules, modifyExisting) {
  203. modules = modules || settings.modules;
  204. module.debug('Disabling debug for modules', modules);
  205. module.change.setting('debug', false, modules, modifyExisting);
  206. },
  207. verbose: function(modules, modifyExisting) {
  208. modules = modules || settings.modules;
  209. module.debug('Disabling verbose debug for modules', modules);
  210. module.change.setting('verbose', false, modules, modifyExisting);
  211. }
  212. },
  213. console: function(enable) {
  214. if(enable) {
  215. if(instance.cache.console === undefined) {
  216. module.error(error.console);
  217. return;
  218. }
  219. module.debug('Restoring console function');
  220. window.console = instance.cache.console;
  221. }
  222. else {
  223. module.debug('Disabling console function');
  224. instance.cache.console = window.console;
  225. window.console = {
  226. clear : function(){},
  227. error : function(){},
  228. group : function(){},
  229. groupCollapsed : function(){},
  230. groupEnd : function(){},
  231. info : function(){},
  232. log : function(){},
  233. markTimeline : function(){},
  234. warn : function(){}
  235. };
  236. }
  237. },
  238. destroy: function() {
  239. module.verbose('Destroying previous site for', $module);
  240. $module
  241. .removeData(moduleNamespace)
  242. ;
  243. },
  244. cache: {},
  245. setting: function(name, value) {
  246. if( $.isPlainObject(name) ) {
  247. $.extend(true, settings, name);
  248. }
  249. else if(value !== undefined) {
  250. settings[name] = value;
  251. }
  252. else {
  253. return settings[name];
  254. }
  255. },
  256. internal: function(name, value) {
  257. if( $.isPlainObject(name) ) {
  258. $.extend(true, module, name);
  259. }
  260. else if(value !== undefined) {
  261. module[name] = value;
  262. }
  263. else {
  264. return module[name];
  265. }
  266. },
  267. debug: function() {
  268. if(settings.debug) {
  269. if(settings.performance) {
  270. module.performance.log(arguments);
  271. }
  272. else {
  273. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  274. module.debug.apply(console, arguments);
  275. }
  276. }
  277. },
  278. verbose: function() {
  279. if(settings.verbose && settings.debug) {
  280. if(settings.performance) {
  281. module.performance.log(arguments);
  282. }
  283. else {
  284. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  285. module.verbose.apply(console, arguments);
  286. }
  287. }
  288. },
  289. error: function() {
  290. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  291. module.error.apply(console, arguments);
  292. },
  293. performance: {
  294. log: function(message) {
  295. var
  296. currentTime,
  297. executionTime,
  298. previousTime
  299. ;
  300. if(settings.performance) {
  301. currentTime = new Date().getTime();
  302. previousTime = time || currentTime;
  303. executionTime = currentTime - previousTime;
  304. time = currentTime;
  305. performance.push({
  306. 'Element' : element,
  307. 'Name' : message[0],
  308. 'Arguments' : [].slice.call(message, 1) || '',
  309. 'Execution Time' : executionTime
  310. });
  311. }
  312. clearTimeout(module.performance.timer);
  313. module.performance.timer = setTimeout(module.performance.display, 500);
  314. },
  315. display: function() {
  316. var
  317. title = settings.name + ':',
  318. totalTime = 0
  319. ;
  320. time = false;
  321. clearTimeout(module.performance.timer);
  322. $.each(performance, function(index, data) {
  323. totalTime += data['Execution Time'];
  324. });
  325. title += ' ' + totalTime + 'ms';
  326. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  327. console.groupCollapsed(title);
  328. if(console.table) {
  329. console.table(performance);
  330. }
  331. else {
  332. $.each(performance, function(index, data) {
  333. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  334. });
  335. }
  336. console.groupEnd();
  337. }
  338. performance = [];
  339. }
  340. },
  341. invoke: function(query, passedArguments, context) {
  342. var
  343. object = instance,
  344. maxDepth,
  345. found,
  346. response
  347. ;
  348. passedArguments = passedArguments || queryArguments;
  349. context = element || context;
  350. if(typeof query == 'string' && object !== undefined) {
  351. query = query.split(/[\. ]/);
  352. maxDepth = query.length - 1;
  353. $.each(query, function(depth, value) {
  354. var camelCaseValue = (depth != maxDepth)
  355. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  356. : query
  357. ;
  358. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  359. object = object[camelCaseValue];
  360. }
  361. else if( object[camelCaseValue] !== undefined ) {
  362. found = object[camelCaseValue];
  363. return false;
  364. }
  365. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  366. object = object[value];
  367. }
  368. else if( object[value] !== undefined ) {
  369. found = object[value];
  370. return false;
  371. }
  372. else {
  373. module.error(error.method, query);
  374. return false;
  375. }
  376. });
  377. }
  378. if ( $.isFunction( found ) ) {
  379. response = found.apply(context, passedArguments);
  380. }
  381. else if(found !== undefined) {
  382. response = found;
  383. }
  384. if($.isArray(returnedValue)) {
  385. returnedValue.push(response);
  386. }
  387. else if(returnedValue !== undefined) {
  388. returnedValue = [returnedValue, response];
  389. }
  390. else if(response !== undefined) {
  391. returnedValue = response;
  392. }
  393. return found;
  394. }
  395. };
  396. if(methodInvoked) {
  397. if(instance === undefined) {
  398. module.initialize();
  399. }
  400. module.invoke(query);
  401. }
  402. else {
  403. if(instance !== undefined) {
  404. module.destroy();
  405. }
  406. module.initialize();
  407. }
  408. return (returnedValue !== undefined)
  409. ? returnedValue
  410. : this
  411. ;
  412. };
  413. $.site.settings = {
  414. name : 'Site',
  415. namespace : 'site',
  416. error : {
  417. console : 'Console cannot be restored, most likely it was overwritten outside of module',
  418. method : 'The method you called is not defined.'
  419. },
  420. debug : false,
  421. verbose : false,
  422. performance : true,
  423. modules: [
  424. 'accordion',
  425. 'api',
  426. 'checkbox',
  427. 'dimmer',
  428. 'dropdown',
  429. 'embed',
  430. 'form',
  431. 'modal',
  432. 'nag',
  433. 'popup',
  434. 'rating',
  435. 'shape',
  436. 'sidebar',
  437. 'state',
  438. 'sticky',
  439. 'tab',
  440. 'transition',
  441. 'visit',
  442. 'visibility'
  443. ],
  444. siteNamespace : 'site',
  445. namespaceStub : {
  446. cache : {},
  447. config : {},
  448. sections : {},
  449. section : {},
  450. utilities : {}
  451. }
  452. };
  453. // allows for selection of elements with data attributes
  454. $.extend($.expr[ ":" ], {
  455. data: ($.expr.createPseudo)
  456. ? $.expr.createPseudo(function(dataName) {
  457. return function(elem) {
  458. return !!$.data(elem, dataName);
  459. };
  460. })
  461. : function(elem, i, match) {
  462. // support: jQuery < 1.8
  463. return !!$.data(elem, match[ 3 ]);
  464. }
  465. });
  466. })( jQuery, window , document );
  467. /*!
  468. * # Semantic UI 2.1.4 - Form Validation
  469. * http://github.com/semantic-org/semantic-ui/
  470. *
  471. *
  472. * Copyright 2015 Contributors
  473. * Released under the MIT license
  474. * http://opensource.org/licenses/MIT
  475. *
  476. */
  477. ;(function ( $, window, document, undefined ) {
  478. "use strict";
  479. $.fn.form = function(parameters) {
  480. var
  481. $allModules = $(this),
  482. moduleSelector = $allModules.selector || '',
  483. time = new Date().getTime(),
  484. performance = [],
  485. query = arguments[0],
  486. legacyParameters = arguments[1],
  487. methodInvoked = (typeof query == 'string'),
  488. queryArguments = [].slice.call(arguments, 1),
  489. returnedValue
  490. ;
  491. $allModules
  492. .each(function() {
  493. var
  494. $module = $(this),
  495. element = this,
  496. formErrors = [],
  497. keyHeldDown = false,
  498. // set at run-time
  499. $field,
  500. $group,
  501. $message,
  502. $prompt,
  503. $submit,
  504. $clear,
  505. $reset,
  506. settings,
  507. validation,
  508. metadata,
  509. selector,
  510. className,
  511. error,
  512. namespace,
  513. moduleNamespace,
  514. eventNamespace,
  515. instance,
  516. module
  517. ;
  518. module = {
  519. initialize: function() {
  520. // settings grabbed at run time
  521. module.get.settings();
  522. if(methodInvoked) {
  523. if(instance === undefined) {
  524. module.instantiate();
  525. }
  526. module.invoke(query);
  527. }
  528. else {
  529. module.verbose('Initializing form validation', $module, settings);
  530. module.bindEvents();
  531. module.set.defaults();
  532. module.instantiate();
  533. }
  534. },
  535. instantiate: function() {
  536. module.verbose('Storing instance of module', module);
  537. instance = module;
  538. $module
  539. .data(moduleNamespace, module)
  540. ;
  541. },
  542. destroy: function() {
  543. module.verbose('Destroying previous module', instance);
  544. module.removeEvents();
  545. $module
  546. .removeData(moduleNamespace)
  547. ;
  548. },
  549. refresh: function() {
  550. module.verbose('Refreshing selector cache');
  551. $field = $module.find(selector.field);
  552. $group = $module.find(selector.group);
  553. $message = $module.find(selector.message);
  554. $prompt = $module.find(selector.prompt);
  555. $submit = $module.find(selector.submit);
  556. $clear = $module.find(selector.clear);
  557. $reset = $module.find(selector.reset);
  558. },
  559. submit: function() {
  560. module.verbose('Submitting form', $module);
  561. $module
  562. .submit()
  563. ;
  564. },
  565. attachEvents: function(selector, action) {
  566. action = action || 'submit';
  567. $(selector)
  568. .on('click' + eventNamespace, function(event) {
  569. module[action]();
  570. event.preventDefault();
  571. })
  572. ;
  573. },
  574. bindEvents: function() {
  575. module.verbose('Attaching form events');
  576. $module
  577. .on('submit' + eventNamespace, module.validate.form)
  578. .on('blur' + eventNamespace, selector.field, module.event.field.blur)
  579. .on('click' + eventNamespace, selector.submit, module.submit)
  580. .on('click' + eventNamespace, selector.reset, module.reset)
  581. .on('click' + eventNamespace, selector.clear, module.clear)
  582. ;
  583. if(settings.keyboardShortcuts) {
  584. $module
  585. .on('keydown' + eventNamespace, selector.field, module.event.field.keydown)
  586. ;
  587. }
  588. $field
  589. .each(function() {
  590. var
  591. $input = $(this),
  592. type = $input.prop('type'),
  593. inputEvent = module.get.changeEvent(type, $input)
  594. ;
  595. $(this)
  596. .on(inputEvent + eventNamespace, module.event.field.change)
  597. ;
  598. })
  599. ;
  600. },
  601. clear: function() {
  602. $field
  603. .each(function () {
  604. var
  605. $field = $(this),
  606. $element = $field.parent(),
  607. $fieldGroup = $field.closest($group),
  608. $prompt = $fieldGroup.find(selector.prompt),
  609. defaultValue = $field.data(metadata.defaultValue) || '',
  610. isCheckbox = $element.is(selector.uiCheckbox),
  611. isDropdown = $element.is(selector.uiDropdown),
  612. isErrored = $fieldGroup.hasClass(className.error)
  613. ;
  614. if(isErrored) {
  615. module.verbose('Resetting error on field', $fieldGroup);
  616. $fieldGroup.removeClass(className.error);
  617. $prompt.remove();
  618. }
  619. if(isDropdown) {
  620. module.verbose('Resetting dropdown value', $element, defaultValue);
  621. $element.dropdown('clear');
  622. }
  623. else if(isCheckbox) {
  624. $field.prop('checked', false);
  625. }
  626. else {
  627. module.verbose('Resetting field value', $field, defaultValue);
  628. $field.val('');
  629. }
  630. })
  631. ;
  632. },
  633. reset: function() {
  634. $field
  635. .each(function () {
  636. var
  637. $field = $(this),
  638. $element = $field.parent(),
  639. $fieldGroup = $field.closest($group),
  640. $prompt = $fieldGroup.find(selector.prompt),
  641. defaultValue = $field.data(metadata.defaultValue),
  642. isCheckbox = $element.is(selector.uiCheckbox),
  643. isDropdown = $element.is(selector.uiDropdown),
  644. isErrored = $fieldGroup.hasClass(className.error)
  645. ;
  646. if(defaultValue === undefined) {
  647. return;
  648. }
  649. if(isErrored) {
  650. module.verbose('Resetting error on field', $fieldGroup);
  651. $fieldGroup.removeClass(className.error);
  652. $prompt.remove();
  653. }
  654. if(isDropdown) {
  655. module.verbose('Resetting dropdown value', $element, defaultValue);
  656. $element.dropdown('restore defaults');
  657. }
  658. else if(isCheckbox) {
  659. module.verbose('Resetting checkbox value', $element, defaultValue);
  660. $field.prop('checked', defaultValue);
  661. }
  662. else {
  663. module.verbose('Resetting field value', $field, defaultValue);
  664. $field.val(defaultValue);
  665. }
  666. })
  667. ;
  668. },
  669. is: {
  670. bracketedRule: function(rule) {
  671. return (rule.type && rule.type.match(settings.regExp.bracket));
  672. },
  673. valid: function() {
  674. var
  675. allValid = true
  676. ;
  677. module.verbose('Checking if form is valid');
  678. $.each(validation, function(fieldName, field) {
  679. if( !( module.validate.field(field, fieldName) ) ) {
  680. allValid = false;
  681. }
  682. });
  683. return allValid;
  684. }
  685. },
  686. removeEvents: function() {
  687. $module
  688. .off(eventNamespace)
  689. ;
  690. $field
  691. .off(eventNamespace)
  692. ;
  693. $submit
  694. .off(eventNamespace)
  695. ;
  696. $field
  697. .off(eventNamespace)
  698. ;
  699. },
  700. event: {
  701. field: {
  702. keydown: function(event) {
  703. var
  704. $field = $(this),
  705. key = event.which,
  706. keyCode = {
  707. enter : 13,
  708. escape : 27
  709. }
  710. ;
  711. if( key == keyCode.escape) {
  712. module.verbose('Escape key pressed blurring field');
  713. $field
  714. .blur()
  715. ;
  716. }
  717. if(!event.ctrlKey && key == keyCode.enter && $field.is(selector.input) && $field.not(selector.checkbox).length > 0 ) {
  718. if(!keyHeldDown) {
  719. $field
  720. .one('keyup' + eventNamespace, module.event.field.keyup)
  721. ;
  722. module.submit();
  723. module.debug('Enter pressed on input submitting form');
  724. }
  725. keyHeldDown = true;
  726. }
  727. },
  728. keyup: function() {
  729. keyHeldDown = false;
  730. },
  731. blur: function(event) {
  732. var
  733. $field = $(this),
  734. $fieldGroup = $field.closest($group),
  735. validationRules = module.get.validation($field)
  736. ;
  737. if( $fieldGroup.hasClass(className.error) ) {
  738. module.debug('Revalidating field', $field, validationRules);
  739. module.validate.form.call(module, event, true);
  740. }
  741. else if(settings.on == 'blur' || settings.on == 'change') {
  742. module.validate.field( validationRules );
  743. }
  744. },
  745. change: function(event) {
  746. var
  747. $field = $(this),
  748. $fieldGroup = $field.closest($group)
  749. ;
  750. if(settings.on == 'change' || ( $fieldGroup.hasClass(className.error) && settings.revalidate) ) {
  751. clearTimeout(module.timer);
  752. module.timer = setTimeout(function() {
  753. module.debug('Revalidating field', $field, module.get.validation($field));
  754. module.validate.form.call(module, event, true);
  755. }, settings.delay);
  756. }
  757. }
  758. }
  759. },
  760. get: {
  761. ancillaryValue: function(rule) {
  762. if(!rule.type || !module.is.bracketedRule(rule)) {
  763. return false;
  764. }
  765. return rule.type.match(settings.regExp.bracket)[1] + '';
  766. },
  767. ruleName: function(rule) {
  768. if( module.is.bracketedRule(rule) ) {
  769. return rule.type.replace(rule.type.match(settings.regExp.bracket)[0], '');
  770. }
  771. return rule.type;
  772. },
  773. changeEvent: function(type, $input) {
  774. if(type == 'checkbox' || type == 'radio' || type == 'hidden' || $input.is('select')) {
  775. return 'change';
  776. }
  777. else {
  778. return module.get.inputEvent();
  779. }
  780. },
  781. inputEvent: function() {
  782. return (document.createElement('input').oninput !== undefined)
  783. ? 'input'
  784. : (document.createElement('input').onpropertychange !== undefined)
  785. ? 'propertychange'
  786. : 'keyup'
  787. ;
  788. },
  789. prompt: function(rule, field) {
  790. var
  791. ruleName = module.get.ruleName(rule),
  792. ancillary = module.get.ancillaryValue(rule),
  793. prompt = rule.prompt || settings.prompt[ruleName] || settings.text.unspecifiedRule,
  794. requiresValue = (prompt.search('{value}') !== -1),
  795. requiresName = (prompt.search('{name}') !== -1),
  796. $label,
  797. $field,
  798. name
  799. ;
  800. if(requiresName || requiresValue) {
  801. $field = module.get.field(field.identifier);
  802. }
  803. if(requiresValue) {
  804. prompt = prompt.replace('{value}', $field.val());
  805. }
  806. if(requiresName) {
  807. $label = $field.closest(selector.group).find('label').eq(0);
  808. name = ($label.size() == 1)
  809. ? $label.text()
  810. : $field.prop('placeholder') || settings.text.unspecifiedField
  811. ;
  812. prompt = prompt.replace('{name}', name);
  813. }
  814. prompt = prompt.replace('{identifier}', field.identifier);
  815. prompt = prompt.replace('{ruleValue}', ancillary);
  816. if(!rule.prompt) {
  817. module.verbose('Using default validation prompt for type', prompt, ruleName);
  818. }
  819. return prompt;
  820. },
  821. settings: function() {
  822. if($.isPlainObject(parameters)) {
  823. var
  824. keys = Object.keys(parameters),
  825. isLegacySettings = (keys.length > 0)
  826. ? (parameters[keys[0]].identifier !== undefined && parameters[keys[0]].rules !== undefined)
  827. : false,
  828. ruleKeys
  829. ;
  830. if(isLegacySettings) {
  831. // 1.x (ducktyped)
  832. settings = $.extend(true, {}, $.fn.form.settings, legacyParameters);
  833. validation = $.extend({}, $.fn.form.settings.defaults, parameters);
  834. module.error(settings.error.oldSyntax, element);
  835. module.verbose('Extending settings from legacy parameters', validation, settings);
  836. }
  837. else {
  838. // 2.x
  839. if(parameters.fields) {
  840. ruleKeys = Object.keys(parameters.fields);
  841. if( typeof parameters.fields[ruleKeys[0]] == 'string' || $.isArray(parameters.fields[ruleKeys[0]]) ) {
  842. $.each(parameters.fields, function(name, rules) {
  843. if(typeof rules == 'string') {
  844. rules = [rules];
  845. }
  846. parameters.fields[name] = {
  847. rules: []
  848. };
  849. $.each(rules, function(index, rule) {
  850. parameters.fields[name].rules.push({ type: rule });
  851. });
  852. });
  853. }
  854. }
  855. settings = $.extend(true, {}, $.fn.form.settings, parameters);
  856. validation = $.extend({}, $.fn.form.settings.defaults, settings.fields);
  857. module.verbose('Extending settings', validation, settings);
  858. }
  859. }
  860. else {
  861. settings = $.fn.form.settings;
  862. validation = $.fn.form.settings.defaults;
  863. module.verbose('Using default form validation', validation, settings);
  864. }
  865. // shorthand
  866. namespace = settings.namespace;
  867. metadata = settings.metadata;
  868. selector = settings.selector;
  869. className = settings.className;
  870. error = settings.error;
  871. moduleNamespace = 'module-' + namespace;
  872. eventNamespace = '.' + namespace;
  873. // grab instance
  874. instance = $module.data(moduleNamespace);
  875. // refresh selector cache
  876. module.refresh();
  877. },
  878. field: function(identifier) {
  879. module.verbose('Finding field with identifier', identifier);
  880. if( $field.filter('#' + identifier).length > 0 ) {
  881. return $field.filter('#' + identifier);
  882. }
  883. else if( $field.filter('[name="' + identifier +'"]').length > 0 ) {
  884. return $field.filter('[name="' + identifier +'"]');
  885. }
  886. else if( $field.filter('[name="' + identifier +'[]"]').length > 0 ) {
  887. return $field.filter('[name="' + identifier +'[]"]');
  888. }
  889. else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) {
  890. return $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]');
  891. }
  892. return $('<input/>');
  893. },
  894. fields: function(fields) {
  895. var
  896. $fields = $()
  897. ;
  898. $.each(fields, function(index, name) {
  899. $fields = $fields.add( module.get.field(name) );
  900. });
  901. return $fields;
  902. },
  903. validation: function($field) {
  904. var
  905. fieldValidation,
  906. identifier
  907. ;
  908. if(!validation) {
  909. return false;
  910. }
  911. $.each(validation, function(fieldName, field) {
  912. identifier = field.identifier || fieldName;
  913. if( module.get.field(identifier)[0] == $field[0] ) {
  914. field.identifier = identifier;
  915. fieldValidation = field;
  916. }
  917. });
  918. return fieldValidation || false;
  919. },
  920. value: function (field) {
  921. var
  922. fields = [],
  923. results
  924. ;
  925. fields.push(field);
  926. results = module.get.values.call(element, fields);
  927. return results[field];
  928. },
  929. values: function (fields) {
  930. var
  931. $fields = $.isArray(fields)
  932. ? module.get.fields(fields)
  933. : $field,
  934. values = {}
  935. ;
  936. $fields.each(function(index, field) {
  937. var
  938. $field = $(field),
  939. type = $field.prop('type'),
  940. name = $field.prop('name'),
  941. value = $field.val(),
  942. isCheckbox = $field.is(selector.checkbox),
  943. isRadio = $field.is(selector.radio),
  944. isMultiple = (name.indexOf('[]') !== -1),
  945. isChecked = (isCheckbox)
  946. ? $field.is(':checked')
  947. : false
  948. ;
  949. if(name) {
  950. if(isMultiple) {
  951. name = name.replace('[]', '');
  952. if(!values[name]) {
  953. values[name] = [];
  954. }
  955. if(isCheckbox) {
  956. if(isChecked) {
  957. values[name].push(value || true);
  958. }
  959. else {
  960. values[name].push(false);
  961. }
  962. }
  963. else {
  964. values[name].push(value);
  965. }
  966. }
  967. else {
  968. if(isRadio) {
  969. if(isChecked) {
  970. values[name] = value;
  971. }
  972. }
  973. else if(isCheckbox) {
  974. if(isChecked) {
  975. values[name] = value || true;
  976. }
  977. else {
  978. values[name] = false;
  979. }
  980. }
  981. else {
  982. values[name] = value;
  983. }
  984. }
  985. }
  986. });
  987. return values;
  988. }
  989. },
  990. has: {
  991. field: function(identifier) {
  992. module.verbose('Checking for existence of a field with identifier', identifier);
  993. if(typeof identifier !== 'string') {
  994. module.error(error.identifier, identifier);
  995. }
  996. if( $field.filter('#' + identifier).length > 0 ) {
  997. return true;
  998. }
  999. else if( $field.filter('[name="' + identifier +'"]').length > 0 ) {
  1000. return true;
  1001. }
  1002. else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) {
  1003. return true;
  1004. }
  1005. return false;
  1006. }
  1007. },
  1008. add: {
  1009. prompt: function(identifier, errors) {
  1010. var
  1011. $field = module.get.field(identifier),
  1012. $fieldGroup = $field.closest($group),
  1013. $prompt = $fieldGroup.children(selector.prompt),
  1014. promptExists = ($prompt.length !== 0)
  1015. ;
  1016. errors = (typeof errors == 'string')
  1017. ? [errors]
  1018. : errors
  1019. ;
  1020. module.verbose('Adding field error state', identifier);
  1021. $fieldGroup
  1022. .addClass(className.error)
  1023. ;
  1024. if(settings.inline) {
  1025. if(!promptExists) {
  1026. $prompt = settings.templates.prompt(errors);
  1027. $prompt
  1028. .appendTo($fieldGroup)
  1029. ;
  1030. }
  1031. $prompt
  1032. .html(errors[0])
  1033. ;
  1034. if(!promptExists) {
  1035. if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  1036. module.verbose('Displaying error with css transition', settings.transition);
  1037. $prompt.transition(settings.transition + ' in', settings.duration);
  1038. }
  1039. else {
  1040. module.verbose('Displaying error with fallback javascript animation');
  1041. $prompt
  1042. .fadeIn(settings.duration)
  1043. ;
  1044. }
  1045. }
  1046. else {
  1047. module.verbose('Inline errors are disabled, no inline error added', identifier);
  1048. }
  1049. }
  1050. },
  1051. errors: function(errors) {
  1052. module.debug('Adding form error messages', errors);
  1053. module.set.error();
  1054. $message
  1055. .html( settings.templates.error(errors) )
  1056. ;
  1057. }
  1058. },
  1059. remove: {
  1060. prompt: function(identifier) {
  1061. var
  1062. $field = module.get.field(identifier),
  1063. $fieldGroup = $field.closest($group),
  1064. $prompt = $fieldGroup.children(selector.prompt)
  1065. ;
  1066. $fieldGroup
  1067. .removeClass(className.error)
  1068. ;
  1069. if(settings.inline && $prompt.is(':visible')) {
  1070. module.verbose('Removing prompt for field', identifier);
  1071. if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  1072. $prompt.transition(settings.transition + ' out', settings.duration, function() {
  1073. $prompt.remove();
  1074. });
  1075. }
  1076. else {
  1077. $prompt
  1078. .fadeOut(settings.duration, function(){
  1079. $prompt.remove();
  1080. })
  1081. ;
  1082. }
  1083. }
  1084. }
  1085. },
  1086. set: {
  1087. success: function() {
  1088. $module
  1089. .removeClass(className.error)
  1090. .addClass(className.success)
  1091. ;
  1092. },
  1093. defaults: function () {
  1094. $field
  1095. .each(function () {
  1096. var
  1097. $field = $(this),
  1098. isCheckbox = ($field.filter(selector.checkbox).length > 0),
  1099. value = (isCheckbox)
  1100. ? $field.is(':checked')
  1101. : $field.val()
  1102. ;
  1103. $field.data(metadata.defaultValue, value);
  1104. })
  1105. ;
  1106. },
  1107. error: function() {
  1108. $module
  1109. .removeClass(className.success)
  1110. .addClass(className.error)
  1111. ;
  1112. },
  1113. value: function (field, value) {
  1114. var
  1115. fields = {}
  1116. ;
  1117. fields[field] = value;
  1118. return module.set.values.call(element, fields);
  1119. },
  1120. values: function (fields) {
  1121. if($.isEmptyObject(fields)) {
  1122. return;
  1123. }
  1124. $.each(fields, function(key, value) {
  1125. var
  1126. $field = module.get.field(key),
  1127. $element = $field.parent(),
  1128. isMultiple = $.isArray(value),
  1129. isCheckbox = $element.is(selector.uiCheckbox),
  1130. isDropdown = $element.is(selector.uiDropdown),
  1131. isRadio = ($field.is(selector.radio) && isCheckbox),
  1132. fieldExists = ($field.length > 0),
  1133. $multipleField
  1134. ;
  1135. if(fieldExists) {
  1136. if(isMultiple && isCheckbox) {
  1137. module.verbose('Selecting multiple', value, $field);
  1138. $element.checkbox('uncheck');
  1139. $.each(value, function(index, value) {
  1140. $multipleField = $field.filter('[value="' + value + '"]');
  1141. $element = $multipleField.parent();
  1142. if($multipleField.length > 0) {
  1143. $element.checkbox('check');
  1144. }
  1145. });
  1146. }
  1147. else if(isRadio) {
  1148. module.verbose('Selecting radio value', value, $field);
  1149. $field.filter('[value="' + value + '"]')
  1150. .parent(selector.uiCheckbox)
  1151. .checkbox('check')
  1152. ;
  1153. }
  1154. else if(isCheckbox) {
  1155. module.verbose('Setting checkbox value', value, $element);
  1156. if(value === true) {
  1157. $element.checkbox('check');
  1158. }
  1159. else {
  1160. $element.checkbox('uncheck');
  1161. }
  1162. }
  1163. else if(isDropdown) {
  1164. module.verbose('Setting dropdown value', value, $element);
  1165. $element.dropdown('set selected', value);
  1166. }
  1167. else {
  1168. module.verbose('Setting field value', value, $field);
  1169. $field.val(value);
  1170. }
  1171. }
  1172. });
  1173. }
  1174. },
  1175. validate: {
  1176. form: function(event, ignoreCallbacks) {
  1177. var
  1178. values = module.get.values(),
  1179. apiRequest
  1180. ;
  1181. // input keydown event will fire submit repeatedly by browser default
  1182. if(keyHeldDown) {
  1183. return false;
  1184. }
  1185. // reset errors
  1186. formErrors = [];
  1187. if( module.is.valid() ) {
  1188. module.debug('Form has no validation errors, submitting');
  1189. module.set.success();
  1190. if(ignoreCallbacks !== true) {
  1191. return settings.onSuccess.call(element, event, values);
  1192. }
  1193. }
  1194. else {
  1195. module.debug('Form has errors');
  1196. module.set.error();
  1197. if(!settings.inline) {
  1198. module.add.errors(formErrors);
  1199. }
  1200. // prevent ajax submit
  1201. if($module.data('moduleApi') !== undefined) {
  1202. event.stopImmediatePropagation();
  1203. }
  1204. if(ignoreCallbacks !== true) {
  1205. return settings.onFailure.call(element, formErrors, values);
  1206. }
  1207. }
  1208. },
  1209. // takes a validation object and returns whether field passes validation
  1210. field: function(field, fieldName) {
  1211. var
  1212. identifier = field.identifier || fieldName,
  1213. $field = module.get.field(identifier),
  1214. fieldValid = true,
  1215. fieldErrors = []
  1216. ;
  1217. if(!field.identifier) {
  1218. module.debug('Using field name as identifier', identifier);
  1219. field.identifier = identifier;
  1220. }
  1221. if($field.prop('disabled')) {
  1222. module.debug('Field is disabled. Skipping', identifier);
  1223. fieldValid = true;
  1224. }
  1225. else if(field.optional && $.trim($field.val()) === ''){
  1226. module.debug('Field is optional and empty. Skipping', identifier);
  1227. fieldValid = true;
  1228. }
  1229. else if(field.rules !== undefined) {
  1230. $.each(field.rules, function(index, rule) {
  1231. if( module.has.field(identifier) && !( module.validate.rule(field, rule) ) ) {
  1232. module.debug('Field is invalid', identifier, rule.type);
  1233. fieldErrors.push(module.get.prompt(rule, field));
  1234. fieldValid = false;
  1235. }
  1236. });
  1237. }
  1238. if(fieldValid) {
  1239. module.remove.prompt(identifier, fieldErrors);
  1240. settings.onValid.call($field);
  1241. }
  1242. else {
  1243. formErrors = formErrors.concat(fieldErrors);
  1244. module.add.prompt(identifier, fieldErrors);
  1245. settings.onInvalid.call($field, fieldErrors);
  1246. return false;
  1247. }
  1248. return true;
  1249. },
  1250. // takes validation rule and returns whether field passes rule
  1251. rule: function(field, rule) {
  1252. var
  1253. $field = module.get.field(field.identifier),
  1254. type = rule.type,
  1255. value = $field.val(),
  1256. isValid = true,
  1257. ancillary = module.get.ancillaryValue(rule),
  1258. ruleName = module.get.ruleName(rule),
  1259. ruleFunction = settings.rules[ruleName]
  1260. ;
  1261. if( !$.isFunction(ruleFunction) ) {
  1262. module.error(error.noRule, ruleName);
  1263. return;
  1264. }
  1265. // cast to string avoiding encoding special values
  1266. value = (value === undefined || value === '' || value === null)
  1267. ? ''
  1268. : $.trim(value + '')
  1269. ;
  1270. return ruleFunction.call($field, value, ancillary);
  1271. }
  1272. },
  1273. setting: function(name, value) {
  1274. if( $.isPlainObject(name) ) {
  1275. $.extend(true, settings, name);
  1276. }
  1277. else if(value !== undefined) {
  1278. settings[name] = value;
  1279. }
  1280. else {
  1281. return settings[name];
  1282. }
  1283. },
  1284. internal: function(name, value) {
  1285. if( $.isPlainObject(name) ) {
  1286. $.extend(true, module, name);
  1287. }
  1288. else if(value !== undefined) {
  1289. module[name] = value;
  1290. }
  1291. else {
  1292. return module[name];
  1293. }
  1294. },
  1295. debug: function() {
  1296. if(settings.debug) {
  1297. if(settings.performance) {
  1298. module.performance.log(arguments);
  1299. }
  1300. else {
  1301. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  1302. module.debug.apply(console, arguments);
  1303. }
  1304. }
  1305. },
  1306. verbose: function() {
  1307. if(settings.verbose && settings.debug) {
  1308. if(settings.performance) {
  1309. module.performance.log(arguments);
  1310. }
  1311. else {
  1312. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  1313. module.verbose.apply(console, arguments);
  1314. }
  1315. }
  1316. },
  1317. error: function() {
  1318. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  1319. module.error.apply(console, arguments);
  1320. },
  1321. performance: {
  1322. log: function(message) {
  1323. var
  1324. currentTime,
  1325. executionTime,
  1326. previousTime
  1327. ;
  1328. if(settings.performance) {
  1329. currentTime = new Date().getTime();
  1330. previousTime = time || currentTime;
  1331. executionTime = currentTime - previousTime;
  1332. time = currentTime;
  1333. performance.push({
  1334. 'Name' : message[0],
  1335. 'Arguments' : [].slice.call(message, 1) || '',
  1336. 'Element' : element,
  1337. 'Execution Time' : executionTime
  1338. });
  1339. }
  1340. clearTimeout(module.performance.timer);
  1341. module.performance.timer = setTimeout(module.performance.display, 500);
  1342. },
  1343. display: function() {
  1344. var
  1345. title = settings.name + ':',
  1346. totalTime = 0
  1347. ;
  1348. time = false;
  1349. clearTimeout(module.performance.timer);
  1350. $.each(performance, function(index, data) {
  1351. totalTime += data['Execution Time'];
  1352. });
  1353. title += ' ' + totalTime + 'ms';
  1354. if(moduleSelector) {
  1355. title += ' \'' + moduleSelector + '\'';
  1356. }
  1357. if($allModules.length > 1) {
  1358. title += ' ' + '(' + $allModules.length + ')';
  1359. }
  1360. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  1361. console.groupCollapsed(title);
  1362. if(console.table) {
  1363. console.table(performance);
  1364. }
  1365. else {
  1366. $.each(performance, function(index, data) {
  1367. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  1368. });
  1369. }
  1370. console.groupEnd();
  1371. }
  1372. performance = [];
  1373. }
  1374. },
  1375. invoke: function(query, passedArguments, context) {
  1376. var
  1377. object = instance,
  1378. maxDepth,
  1379. found,
  1380. response
  1381. ;
  1382. passedArguments = passedArguments || queryArguments;
  1383. context = element || context;
  1384. if(typeof query == 'string' && object !== undefined) {
  1385. query = query.split(/[\. ]/);
  1386. maxDepth = query.length - 1;
  1387. $.each(query, function(depth, value) {
  1388. var camelCaseValue = (depth != maxDepth)
  1389. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  1390. : query
  1391. ;
  1392. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  1393. object = object[camelCaseValue];
  1394. }
  1395. else if( object[camelCaseValue] !== undefined ) {
  1396. found = object[camelCaseValue];
  1397. return false;
  1398. }
  1399. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  1400. object = object[value];
  1401. }
  1402. else if( object[value] !== undefined ) {
  1403. found = object[value];
  1404. return false;
  1405. }
  1406. else {
  1407. return false;
  1408. }
  1409. });
  1410. }
  1411. if( $.isFunction( found ) ) {
  1412. response = found.apply(context, passedArguments);
  1413. }
  1414. else if(found !== undefined) {
  1415. response = found;
  1416. }
  1417. if($.isArray(returnedValue)) {
  1418. returnedValue.push(response);
  1419. }
  1420. else if(returnedValue !== undefined) {
  1421. returnedValue = [returnedValue, response];
  1422. }
  1423. else if(response !== undefined) {
  1424. returnedValue = response;
  1425. }
  1426. return found;
  1427. }
  1428. };
  1429. module.initialize();
  1430. })
  1431. ;
  1432. return (returnedValue !== undefined)
  1433. ? returnedValue
  1434. : this
  1435. ;
  1436. };
  1437. $.fn.form.settings = {
  1438. name : 'Form',
  1439. namespace : 'form',
  1440. debug : false,
  1441. verbose : false,
  1442. performance : true,
  1443. fields : false,
  1444. keyboardShortcuts : true,
  1445. on : 'submit',
  1446. inline : false,
  1447. delay : 200,
  1448. revalidate : true,
  1449. transition : 'scale',
  1450. duration : 200,
  1451. onValid : function() {},
  1452. onInvalid : function() {},
  1453. onSuccess : function() { return true; },
  1454. onFailure : function() { return false; },
  1455. metadata : {
  1456. defaultValue : 'default',
  1457. validate : 'validate'
  1458. },
  1459. regExp: {
  1460. bracket : /\[(.*)\]/i,
  1461. decimal : /^\-?\d*(\.\d+)?$/,
  1462. email : "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",
  1463. escape : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,
  1464. flags : /^\/(.*)\/(.*)?/,
  1465. integer : /^\-?\d+$/,
  1466. number : /^\-?\d*(\.\d+)?$/,
  1467. url : /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/i
  1468. },
  1469. text: {
  1470. unspecifiedRule : 'Please enter a valid value',
  1471. unspecifiedField : 'This field'
  1472. },
  1473. prompt: {
  1474. empty : '{name} must have a value',
  1475. checked : '{name} must be checked',
  1476. email : '{name} must be a valid e-mail',
  1477. url : '{name} must be a valid url',
  1478. regExp : '{name} is not formatted correctly',
  1479. integer : '{name} must be an integer',
  1480. decimal : '{name} must be a decimal number',
  1481. number : '{name} must be set to a number',
  1482. is : '{name} must be "{ruleValue}"',
  1483. isExactly : '{name} must be exactly "{ruleValue}"',
  1484. not : '{name} cannot be set to "{ruleValue}"',
  1485. notExactly : '{name} cannot be set to exactly "{ruleValue}"',
  1486. contain : '{name} cannot contain "{ruleValue}"',
  1487. containExactly : '{name} cannot contain exactly "{ruleValue}"',
  1488. doesntContain : '{name} must contain "{ruleValue}"',
  1489. doesntContainExactly : '{name} must contain exactly "{ruleValue}"',
  1490. minLength : '{name} must be at least {ruleValue} characters',
  1491. length : '{name} must be at least {ruleValue} characters',
  1492. exactLength : '{name} must be exactly {ruleValue} characters',
  1493. maxLength : '{name} cannot be longer than {ruleValue} characters',
  1494. match : '{name} must match {ruleValue} field',
  1495. different : '{name} must have a different value than {ruleValue} field',
  1496. creditCard : '{name} must be a valid credit card number',
  1497. minCount : '{name} must have at least {ruleValue} choices',
  1498. exactCount : '{name} must have exactly {ruleValue} choices',
  1499. maxCount : '{name} must have {ruleValue} or less choices'
  1500. },
  1501. selector : {
  1502. checkbox : 'input[type="checkbox"], input[type="radio"]',
  1503. clear : '.clear',
  1504. field : 'input, textarea, select',
  1505. group : '.field',
  1506. input : 'input',
  1507. message : '.error.message',
  1508. prompt : '.prompt.label',
  1509. radio : 'input[type="radio"]',
  1510. reset : '.reset:not([type="reset"])',
  1511. submit : '.submit:not([type="submit"])',
  1512. uiCheckbox : '.ui.checkbox',
  1513. uiDropdown : '.ui.dropdown'
  1514. },
  1515. className : {
  1516. error : 'error',
  1517. label : 'ui prompt label',
  1518. pressed : 'down',
  1519. success : 'success'
  1520. },
  1521. error: {
  1522. identifier : 'You must specify a string identifier for each field',
  1523. method : 'The method you called is not defined.',
  1524. noRule : 'There is no rule matching the one you specified',
  1525. oldSyntax : 'Starting in 2.0 forms now only take a single settings object. Validation settings converted to new syntax automatically.'
  1526. },
  1527. templates: {
  1528. // template that produces error message
  1529. error: function(errors) {
  1530. var
  1531. html = '<ul class="list">'
  1532. ;
  1533. $.each(errors, function(index, value) {
  1534. html += '<li>' + value + '</li>';
  1535. });
  1536. html += '</ul>';
  1537. return $(html);
  1538. },
  1539. // template that produces label
  1540. prompt: function(errors) {
  1541. return $('<div/>')
  1542. .addClass('ui basic red pointing prompt label')
  1543. .html(errors[0])
  1544. ;
  1545. }
  1546. },
  1547. rules: {
  1548. // is not empty or blank string
  1549. empty: function(value) {
  1550. return !(value === undefined || '' === value || $.isArray(value) && value.length === 0);
  1551. },
  1552. // checkbox checked
  1553. checked: function() {
  1554. return ($(this).filter(':checked').length > 0);
  1555. },
  1556. // is most likely an email
  1557. email: function(value){
  1558. var
  1559. emailRegExp = new RegExp($.fn.form.settings.regExp.email, 'i')
  1560. ;
  1561. return emailRegExp.test(value);
  1562. },
  1563. // value is most likely url
  1564. url: function(value) {
  1565. return $.fn.form.settings.regExp.url.test(value);
  1566. },
  1567. // matches specified regExp
  1568. regExp: function(value, regExp) {
  1569. var
  1570. regExpParts = regExp.match($.fn.form.settings.regExp.flags),
  1571. flags
  1572. ;
  1573. // regular expression specified as /baz/gi (flags)
  1574. if(regExpParts) {
  1575. regExp = (regExpParts.length >= 2)
  1576. ? regExpParts[1]
  1577. : regExp
  1578. ;
  1579. flags = (regExpParts.length >= 3)
  1580. ? regExpParts[2]
  1581. : ''
  1582. ;
  1583. }
  1584. return value.match( new RegExp(regExp, flags) );
  1585. },
  1586. // is valid integer or matches range
  1587. integer: function(value, range) {
  1588. var
  1589. intRegExp = $.fn.form.settings.regExp.integer,
  1590. min,
  1591. max,
  1592. parts
  1593. ;
  1594. if(range === undefined || range === '' || range === '..') {
  1595. // do nothing
  1596. }
  1597. else if(range.indexOf('..') == -1) {
  1598. if(intRegExp.test(range)) {
  1599. min = max = range - 0;
  1600. }
  1601. }
  1602. else {
  1603. parts = range.split('..', 2);
  1604. if(intRegExp.test(parts[0])) {
  1605. min = parts[0] - 0;
  1606. }
  1607. if(intRegExp.test(parts[1])) {
  1608. max = parts[1] - 0;
  1609. }
  1610. }
  1611. return (
  1612. intRegExp.test(value) &&
  1613. (min === undefined || value >= min) &&
  1614. (max === undefined || value <= max)
  1615. );
  1616. },
  1617. // is valid number (with decimal)
  1618. decimal: function(value) {
  1619. return $.fn.form.settings.regExp.decimal.test(value);
  1620. },
  1621. // is valid number
  1622. number: function(value) {
  1623. return $.fn.form.settings.regExp.number.test(value);
  1624. },
  1625. // is value (case insensitive)
  1626. is: function(value, text) {
  1627. text = (typeof text == 'string')
  1628. ? text.toLowerCase()
  1629. : text
  1630. ;
  1631. value = (typeof value == 'string')
  1632. ? value.toLowerCase()
  1633. : value
  1634. ;
  1635. return (value == text);
  1636. },
  1637. // is value
  1638. isExactly: function(value, text) {
  1639. return (value == text);
  1640. },
  1641. // value is not another value (case insensitive)
  1642. not: function(value, notValue) {
  1643. value = (typeof value == 'string')
  1644. ? value.toLowerCase()
  1645. : value
  1646. ;
  1647. notValue = (typeof notValue == 'string')
  1648. ? notValue.toLowerCase()
  1649. : notValue
  1650. ;
  1651. return (value != notValue);
  1652. },
  1653. // value is not another value (case sensitive)
  1654. notExactly: function(value, notValue) {
  1655. return (value != notValue);
  1656. },
  1657. // value contains text (insensitive)
  1658. contains: function(value, text) {
  1659. // escape regex characters
  1660. text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
  1661. return (value.search( new RegExp(text, 'i') ) !== -1);
  1662. },
  1663. // value contains text (case sensitive)
  1664. containsExactly: function(value, text) {
  1665. // escape regex characters
  1666. text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
  1667. return (value.search( new RegExp(text) ) !== -1);
  1668. },
  1669. // value contains text (insensitive)
  1670. doesntContain: function(value, text) {
  1671. // escape regex characters
  1672. text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
  1673. return (value.search( new RegExp(text, 'i') ) === -1);
  1674. },
  1675. // value contains text (case sensitive)
  1676. doesntContainExactly: function(value, text) {
  1677. // escape regex characters
  1678. text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
  1679. return (value.search( new RegExp(text) ) === -1);
  1680. },
  1681. // is at least string length
  1682. minLength: function(value, requiredLength) {
  1683. return (value !== undefined)
  1684. ? (value.length >= requiredLength)
  1685. : false
  1686. ;
  1687. },
  1688. // see rls notes for 2.0.6 (this is a duplicate of minLength)
  1689. length: function(value, requiredLength) {
  1690. return (value !== undefined)
  1691. ? (value.length >= requiredLength)
  1692. : false
  1693. ;
  1694. },
  1695. // is exactly length
  1696. exactLength: function(value, requiredLength) {
  1697. return (value !== undefined)
  1698. ? (value.length == requiredLength)
  1699. : false
  1700. ;
  1701. },
  1702. // is less than length
  1703. maxLength: function(value, maxLength) {
  1704. return (value !== undefined)
  1705. ? (value.length <= maxLength)
  1706. : false
  1707. ;
  1708. },
  1709. // matches another field
  1710. match: function(value, identifier) {
  1711. var
  1712. $form = $(this),
  1713. matchingValue
  1714. ;
  1715. if( $('[data-validate="'+ identifier +'"]').length > 0 ) {
  1716. matchingValue = $('[data-validate="'+ identifier +'"]').val();
  1717. }
  1718. else if($('#' + identifier).length > 0) {
  1719. matchingValue = $('#' + identifier).val();
  1720. }
  1721. else if($('[name="' + identifier +'"]').length > 0) {
  1722. matchingValue = $('[name="' + identifier + '"]').val();
  1723. }
  1724. else if( $('[name="' + identifier +'[]"]').length > 0 ) {
  1725. matchingValue = $('[name="' + identifier +'[]"]');
  1726. }
  1727. return (matchingValue !== undefined)
  1728. ? ( value.toString() == matchingValue.toString() )
  1729. : false
  1730. ;
  1731. },
  1732. // different than another field
  1733. different: function(value, identifier) {
  1734. // use either id or name of field
  1735. var
  1736. $form = $(this),
  1737. matchingValue
  1738. ;
  1739. if( $('[data-validate="'+ identifier +'"]').length > 0 ) {
  1740. matchingValue = $('[data-validate="'+ identifier +'"]').val();
  1741. }
  1742. else if($('#' + identifier).length > 0) {
  1743. matchingValue = $('#' + identifier).val();
  1744. }
  1745. else if($('[name="' + identifier +'"]').length > 0) {
  1746. matchingValue = $('[name="' + identifier + '"]').val();
  1747. }
  1748. else if( $('[name="' + identifier +'[]"]').length > 0 ) {
  1749. matchingValue = $('[name="' + identifier +'[]"]');
  1750. }
  1751. return (matchingValue !== undefined)
  1752. ? ( value.toString() !== matchingValue.toString() )
  1753. : false
  1754. ;
  1755. },
  1756. creditCard: function(cardNumber, cardTypes) {
  1757. var
  1758. cards = {
  1759. visa: {
  1760. pattern : /^4/,
  1761. length : [16]
  1762. },
  1763. amex: {
  1764. pattern : /^3[47]/,
  1765. length : [15]
  1766. },
  1767. mastercard: {
  1768. pattern : /^5[1-5]/,
  1769. length : [16]
  1770. },
  1771. discover: {
  1772. pattern : /^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)/,
  1773. length : [16]
  1774. },
  1775. unionPay: {
  1776. pattern : /^(62|88)/,
  1777. length : [16, 17, 18, 19]
  1778. },
  1779. jcb: {
  1780. pattern : /^35(2[89]|[3-8][0-9])/,
  1781. length : [16]
  1782. },
  1783. maestro: {
  1784. pattern : /^(5018|5020|5038|6304|6759|676[1-3])/,
  1785. length : [12, 13, 14, 15, 16, 17, 18, 19]
  1786. },
  1787. dinersClub: {
  1788. pattern : /^(30[0-5]|^36)/,
  1789. length : [14]
  1790. },
  1791. laser: {
  1792. pattern : /^(6304|670[69]|6771)/,
  1793. length : [16, 17, 18, 19]
  1794. },
  1795. visaElectron: {
  1796. pattern : /^(4026|417500|4508|4844|491(3|7))/,
  1797. length : [16]
  1798. }
  1799. },
  1800. valid = {},
  1801. validCard = false,
  1802. requiredTypes = (typeof cardTypes == 'string')
  1803. ? cardTypes.split(',')
  1804. : false,
  1805. unionPay,
  1806. validation
  1807. ;
  1808. if(typeof cardNumber !== 'string' || cardNumber.length === 0) {
  1809. return;
  1810. }
  1811. // verify card types
  1812. if(requiredTypes) {
  1813. $.each(requiredTypes, function(index, type){
  1814. // verify each card type
  1815. validation = cards[type];
  1816. if(validation) {
  1817. valid = {
  1818. length : ($.inArray(cardNumber.length, validation.length) !== -1),
  1819. pattern : (cardNumber.search(validation.pattern) !== -1)
  1820. };
  1821. if(valid.length && valid.pattern) {
  1822. validCard = true;
  1823. }
  1824. }
  1825. });
  1826. if(!validCard) {
  1827. return false;
  1828. }
  1829. }
  1830. // skip luhn for UnionPay
  1831. unionPay = {
  1832. number : ($.inArray(cardNumber.length, cards.unionPay.length) !== -1),
  1833. pattern : (cardNumber.search(cards.unionPay.pattern) !== -1)
  1834. };
  1835. if(unionPay.number && unionPay.pattern) {
  1836. return true;
  1837. }
  1838. // verify luhn, adapted from <https://gist.github.com/2134376>
  1839. var
  1840. length = cardNumber.length,
  1841. multiple = 0,
  1842. producedValue = [
  1843. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
  1844. [0, 2, 4, 6, 8, 1, 3, 5, 7, 9]
  1845. ],
  1846. sum = 0
  1847. ;
  1848. while (length--) {
  1849. sum += producedValue[multiple][parseInt(cardNumber.charAt(length), 10)];
  1850. multiple ^= 1;
  1851. }
  1852. return (sum % 10 === 0 && sum > 0);
  1853. },
  1854. minCount: function(value, minCount) {
  1855. if(minCount == 0) {
  1856. return true;
  1857. }
  1858. if(minCount == 1) {
  1859. return (value !== '');
  1860. }
  1861. return (value.split(',').length >= minCount);
  1862. },
  1863. exactCount: function(value, exactCount) {
  1864. if(exactCount == 0) {
  1865. return (value === '');
  1866. }
  1867. if(exactCount == 1) {
  1868. return (value !== '' && value.search(',') === -1);
  1869. }
  1870. return (value.split(',').length == exactCount);
  1871. },
  1872. maxCount: function(value, maxCount) {
  1873. if(maxCount == 0) {
  1874. return false;
  1875. }
  1876. if(maxCount == 1) {
  1877. return (value.search(',') === -1);
  1878. }
  1879. return (value.split(',').length <= maxCount);
  1880. }
  1881. }
  1882. };
  1883. })( jQuery, window , document );
  1884. /*!
  1885. * # Semantic UI 2.1.4 - Accordion
  1886. * http://github.com/semantic-org/semantic-ui/
  1887. *
  1888. *
  1889. * Copyright 2015 Contributors
  1890. * Released under the MIT license
  1891. * http://opensource.org/licenses/MIT
  1892. *
  1893. */
  1894. ;(function ($, window, document, undefined) {
  1895. "use strict";
  1896. $.fn.accordion = function(parameters) {
  1897. var
  1898. $allModules = $(this),
  1899. time = new Date().getTime(),
  1900. performance = [],
  1901. query = arguments[0],
  1902. methodInvoked = (typeof query == 'string'),
  1903. queryArguments = [].slice.call(arguments, 1),
  1904. requestAnimationFrame = window.requestAnimationFrame
  1905. || window.mozRequestAnimationFrame
  1906. || window.webkitRequestAnimationFrame
  1907. || window.msRequestAnimationFrame
  1908. || function(callback) { setTimeout(callback, 0); },
  1909. returnedValue
  1910. ;
  1911. $allModules
  1912. .each(function() {
  1913. var
  1914. settings = ( $.isPlainObject(parameters) )
  1915. ? $.extend(true, {}, $.fn.accordion.settings, parameters)
  1916. : $.extend({}, $.fn.accordion.settings),
  1917. className = settings.className,
  1918. namespace = settings.namespace,
  1919. selector = settings.selector,
  1920. error = settings.error,
  1921. eventNamespace = '.' + namespace,
  1922. moduleNamespace = 'module-' + namespace,
  1923. moduleSelector = $allModules.selector || '',
  1924. $module = $(this),
  1925. $title = $module.find(selector.title),
  1926. $content = $module.find(selector.content),
  1927. element = this,
  1928. instance = $module.data(moduleNamespace),
  1929. observer,
  1930. module
  1931. ;
  1932. module = {
  1933. initialize: function() {
  1934. module.debug('Initializing', $module);
  1935. module.bind.events();
  1936. if(settings.observeChanges) {
  1937. module.observeChanges();
  1938. }
  1939. module.instantiate();
  1940. },
  1941. instantiate: function() {
  1942. instance = module;
  1943. $module
  1944. .data(moduleNamespace, module)
  1945. ;
  1946. },
  1947. destroy: function() {
  1948. module.debug('Destroying previous instance', $module);
  1949. $module
  1950. .off(eventNamespace)
  1951. .removeData(moduleNamespace)
  1952. ;
  1953. },
  1954. refresh: function() {
  1955. $title = $module.find(selector.title);
  1956. $content = $module.find(selector.content);
  1957. },
  1958. observeChanges: function() {
  1959. if('MutationObserver' in window) {
  1960. observer = new MutationObserver(function(mutations) {
  1961. module.debug('DOM tree modified, updating selector cache');
  1962. module.refresh();
  1963. });
  1964. observer.observe(element, {
  1965. childList : true,
  1966. subtree : true
  1967. });
  1968. module.debug('Setting up mutation observer', observer);
  1969. }
  1970. },
  1971. bind: {
  1972. events: function() {
  1973. module.debug('Binding delegated events');
  1974. $module
  1975. .on(settings.on + eventNamespace, selector.trigger, module.event.click)
  1976. ;
  1977. }
  1978. },
  1979. event: {
  1980. click: function() {
  1981. module.toggle.call(this);
  1982. }
  1983. },
  1984. toggle: function(query) {
  1985. var
  1986. $activeTitle = (query !== undefined)
  1987. ? (typeof query === 'number')
  1988. ? $title.eq(query)
  1989. : $(query).closest(selector.title)
  1990. : $(this).closest(selector.title),
  1991. $activeContent = $activeTitle.next($content),
  1992. isAnimating = $activeContent.hasClass(className.animating),
  1993. isActive = $activeContent.hasClass(className.active),
  1994. isOpen = (isActive && !isAnimating),
  1995. isOpening = (!isActive && isAnimating)
  1996. ;
  1997. module.debug('Toggling visibility of content', $activeTitle);
  1998. if(isOpen || isOpening) {
  1999. if(settings.collapsible) {
  2000. module.close.call($activeTitle);
  2001. }
  2002. else {
  2003. module.debug('Cannot close accordion content collapsing is disabled');
  2004. }
  2005. }
  2006. else {
  2007. module.open.call($activeTitle);
  2008. }
  2009. },
  2010. open: function(query) {
  2011. var
  2012. $activeTitle = (query !== undefined)
  2013. ? (typeof query === 'number')
  2014. ? $title.eq(query)
  2015. : $(query).closest(selector.title)
  2016. : $(this).closest(selector.title),
  2017. $activeContent = $activeTitle.next($content),
  2018. isAnimating = $activeContent.hasClass(className.animating),
  2019. isActive = $activeContent.hasClass(className.active),
  2020. isOpen = (isActive || isAnimating)
  2021. ;
  2022. if(isOpen) {
  2023. module.debug('Accordion already open, skipping', $activeContent);
  2024. return;
  2025. }
  2026. module.debug('Opening accordion content', $activeTitle);
  2027. settings.onOpening.call($activeContent);
  2028. if(settings.exclusive) {
  2029. module.closeOthers.call($activeTitle);
  2030. }
  2031. $activeTitle
  2032. .addClass(className.active)
  2033. ;
  2034. $activeContent
  2035. .stop(true, true)
  2036. .addClass(className.animating)
  2037. ;
  2038. if(settings.animateChildren) {
  2039. if($.fn.transition !== undefined && $module.transition('is supported')) {
  2040. $activeContent
  2041. .children()
  2042. .transition({
  2043. animation : 'fade in',
  2044. queue : false,
  2045. useFailSafe : true,
  2046. debug : settings.debug,
  2047. verbose : settings.verbose,
  2048. duration : settings.duration
  2049. })
  2050. ;
  2051. }
  2052. else {
  2053. $activeContent
  2054. .children()
  2055. .stop(true, true)
  2056. .animate({
  2057. opacity: 1
  2058. }, settings.duration, module.resetOpacity)
  2059. ;
  2060. }
  2061. }
  2062. $activeContent
  2063. .slideDown(settings.duration, settings.easing, function() {
  2064. $activeContent
  2065. .removeClass(className.animating)
  2066. .addClass(className.active)
  2067. ;
  2068. module.reset.display.call(this);
  2069. settings.onOpen.call(this);
  2070. settings.onChange.call(this);
  2071. })
  2072. ;
  2073. },
  2074. close: function(query) {
  2075. var
  2076. $activeTitle = (query !== undefined)
  2077. ? (typeof query === 'number')
  2078. ? $title.eq(query)
  2079. : $(query).closest(selector.title)
  2080. : $(this).closest(selector.title),
  2081. $activeContent = $activeTitle.next($content),
  2082. isAnimating = $activeContent.hasClass(className.animating),
  2083. isActive = $activeContent.hasClass(className.active),
  2084. isOpening = (!isActive && isAnimating),
  2085. isClosing = (isActive && isAnimating)
  2086. ;
  2087. if((isActive || isOpening) && !isClosing) {
  2088. module.debug('Closing accordion content', $activeContent);
  2089. settings.onClosing.call($activeContent);
  2090. $activeTitle
  2091. .removeClass(className.active)
  2092. ;
  2093. $activeContent
  2094. .stop(true, true)
  2095. .addClass(className.animating)
  2096. ;
  2097. if(settings.animateChildren) {
  2098. if($.fn.transition !== undefined && $module.transition('is supported')) {
  2099. $activeContent
  2100. .children()
  2101. .transition({
  2102. animation : 'fade out',
  2103. queue : false,
  2104. useFailSafe : true,
  2105. debug : settings.debug,
  2106. verbose : settings.verbose,
  2107. duration : settings.duration
  2108. })
  2109. ;
  2110. }
  2111. else {
  2112. $activeContent
  2113. .children()
  2114. .stop(true, true)
  2115. .animate({
  2116. opacity: 0
  2117. }, settings.duration, module.resetOpacity)
  2118. ;
  2119. }
  2120. }
  2121. $activeContent
  2122. .slideUp(settings.duration, settings.easing, function() {
  2123. $activeContent
  2124. .removeClass(className.animating)
  2125. .removeClass(className.active)
  2126. ;
  2127. module.reset.display.call(this);
  2128. settings.onClose.call(this);
  2129. settings.onChange.call(this);
  2130. })
  2131. ;
  2132. }
  2133. },
  2134. closeOthers: function(index) {
  2135. var
  2136. $activeTitle = (index !== undefined)
  2137. ? $title.eq(index)
  2138. : $(this).closest(selector.title),
  2139. $parentTitles = $activeTitle.parents(selector.content).prev(selector.title),
  2140. $activeAccordion = $activeTitle.closest(selector.accordion),
  2141. activeSelector = selector.title + '.' + className.active + ':visible',
  2142. activeContent = selector.content + '.' + className.active + ':visible',
  2143. $openTitles,
  2144. $nestedTitles,
  2145. $openContents
  2146. ;
  2147. if(settings.closeNested) {
  2148. $openTitles = $activeAccordion.find(activeSelector).not($parentTitles);
  2149. $openContents = $openTitles.next($content);
  2150. }
  2151. else {
  2152. $openTitles = $activeAccordion.find(activeSelector).not($parentTitles);
  2153. $nestedTitles = $activeAccordion.find(activeContent).find(activeSelector).not($parentTitles);
  2154. $openTitles = $openTitles.not($nestedTitles);
  2155. $openContents = $openTitles.next($content);
  2156. }
  2157. if( ($openTitles.length > 0) ) {
  2158. module.debug('Exclusive enabled, closing other content', $openTitles);
  2159. $openTitles
  2160. .removeClass(className.active)
  2161. ;
  2162. $openContents
  2163. .removeClass(className.animating)
  2164. .stop(true, true)
  2165. ;
  2166. if(settings.animateChildren) {
  2167. if($.fn.transition !== undefined && $module.transition('is supported')) {
  2168. $openContents
  2169. .children()
  2170. .transition({
  2171. animation : 'fade out',
  2172. useFailSafe : true,
  2173. debug : settings.debug,
  2174. verbose : settings.verbose,
  2175. duration : settings.duration
  2176. })
  2177. ;
  2178. }
  2179. else {
  2180. $openContents
  2181. .children()
  2182. .stop(true, true)
  2183. .animate({
  2184. opacity: 0
  2185. }, settings.duration, module.resetOpacity)
  2186. ;
  2187. }
  2188. }
  2189. $openContents
  2190. .slideUp(settings.duration , settings.easing, function() {
  2191. $(this).removeClass(className.active);
  2192. module.reset.display.call(this);
  2193. })
  2194. ;
  2195. }
  2196. },
  2197. reset: {
  2198. display: function() {
  2199. module.verbose('Removing inline display from element', this);
  2200. $(this).css('display', '');
  2201. if( $(this).attr('style') === '') {
  2202. $(this)
  2203. .attr('style', '')
  2204. .removeAttr('style')
  2205. ;
  2206. }
  2207. },
  2208. opacity: function() {
  2209. module.verbose('Removing inline opacity from element', this);
  2210. $(this).css('opacity', '');
  2211. if( $(this).attr('style') === '') {
  2212. $(this)
  2213. .attr('style', '')
  2214. .removeAttr('style')
  2215. ;
  2216. }
  2217. },
  2218. },
  2219. setting: function(name, value) {
  2220. module.debug('Changing setting', name, value);
  2221. if( $.isPlainObject(name) ) {
  2222. $.extend(true, settings, name);
  2223. }
  2224. else if(value !== undefined) {
  2225. settings[name] = value;
  2226. }
  2227. else {
  2228. return settings[name];
  2229. }
  2230. },
  2231. internal: function(name, value) {
  2232. module.debug('Changing internal', name, value);
  2233. if(value !== undefined) {
  2234. if( $.isPlainObject(name) ) {
  2235. $.extend(true, module, name);
  2236. }
  2237. else {
  2238. module[name] = value;
  2239. }
  2240. }
  2241. else {
  2242. return module[name];
  2243. }
  2244. },
  2245. debug: function() {
  2246. if(settings.debug) {
  2247. if(settings.performance) {
  2248. module.performance.log(arguments);
  2249. }
  2250. else {
  2251. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  2252. module.debug.apply(console, arguments);
  2253. }
  2254. }
  2255. },
  2256. verbose: function() {
  2257. if(settings.verbose && settings.debug) {
  2258. if(settings.performance) {
  2259. module.performance.log(arguments);
  2260. }
  2261. else {
  2262. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  2263. module.verbose.apply(console, arguments);
  2264. }
  2265. }
  2266. },
  2267. error: function() {
  2268. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  2269. module.error.apply(console, arguments);
  2270. },
  2271. performance: {
  2272. log: function(message) {
  2273. var
  2274. currentTime,
  2275. executionTime,
  2276. previousTime
  2277. ;
  2278. if(settings.performance) {
  2279. currentTime = new Date().getTime();
  2280. previousTime = time || currentTime;
  2281. executionTime = currentTime - previousTime;
  2282. time = currentTime;
  2283. performance.push({
  2284. 'Name' : message[0],
  2285. 'Arguments' : [].slice.call(message, 1) || '',
  2286. 'Element' : element,
  2287. 'Execution Time' : executionTime
  2288. });
  2289. }
  2290. clearTimeout(module.performance.timer);
  2291. module.performance.timer = setTimeout(module.performance.display, 500);
  2292. },
  2293. display: function() {
  2294. var
  2295. title = settings.name + ':',
  2296. totalTime = 0
  2297. ;
  2298. time = false;
  2299. clearTimeout(module.performance.timer);
  2300. $.each(performance, function(index, data) {
  2301. totalTime += data['Execution Time'];
  2302. });
  2303. title += ' ' + totalTime + 'ms';
  2304. if(moduleSelector) {
  2305. title += ' \'' + moduleSelector + '\'';
  2306. }
  2307. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  2308. console.groupCollapsed(title);
  2309. if(console.table) {
  2310. console.table(performance);
  2311. }
  2312. else {
  2313. $.each(performance, function(index, data) {
  2314. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  2315. });
  2316. }
  2317. console.groupEnd();
  2318. }
  2319. performance = [];
  2320. }
  2321. },
  2322. invoke: function(query, passedArguments, context) {
  2323. var
  2324. object = instance,
  2325. maxDepth,
  2326. found,
  2327. response
  2328. ;
  2329. passedArguments = passedArguments || queryArguments;
  2330. context = element || context;
  2331. if(typeof query == 'string' && object !== undefined) {
  2332. query = query.split(/[\. ]/);
  2333. maxDepth = query.length - 1;
  2334. $.each(query, function(depth, value) {
  2335. var camelCaseValue = (depth != maxDepth)
  2336. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  2337. : query
  2338. ;
  2339. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  2340. object = object[camelCaseValue];
  2341. }
  2342. else if( object[camelCaseValue] !== undefined ) {
  2343. found = object[camelCaseValue];
  2344. return false;
  2345. }
  2346. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  2347. object = object[value];
  2348. }
  2349. else if( object[value] !== undefined ) {
  2350. found = object[value];
  2351. return false;
  2352. }
  2353. else {
  2354. module.error(error.method, query);
  2355. return false;
  2356. }
  2357. });
  2358. }
  2359. if ( $.isFunction( found ) ) {
  2360. response = found.apply(context, passedArguments);
  2361. }
  2362. else if(found !== undefined) {
  2363. response = found;
  2364. }
  2365. if($.isArray(returnedValue)) {
  2366. returnedValue.push(response);
  2367. }
  2368. else if(returnedValue !== undefined) {
  2369. returnedValue = [returnedValue, response];
  2370. }
  2371. else if(response !== undefined) {
  2372. returnedValue = response;
  2373. }
  2374. return found;
  2375. }
  2376. };
  2377. if(methodInvoked) {
  2378. if(instance === undefined) {
  2379. module.initialize();
  2380. }
  2381. module.invoke(query);
  2382. }
  2383. else {
  2384. if(instance !== undefined) {
  2385. instance.invoke('destroy');
  2386. }
  2387. module.initialize();
  2388. }
  2389. })
  2390. ;
  2391. return (returnedValue !== undefined)
  2392. ? returnedValue
  2393. : this
  2394. ;
  2395. };
  2396. $.fn.accordion.settings = {
  2397. name : 'Accordion',
  2398. namespace : 'accordion',
  2399. debug : false,
  2400. verbose : false,
  2401. performance : true,
  2402. on : 'click', // event on title that opens accordion
  2403. observeChanges : true, // whether accordion should automatically refresh on DOM insertion
  2404. exclusive : true, // whether a single accordion content panel should be open at once
  2405. collapsible : true, // whether accordion content can be closed
  2406. closeNested : false, // whether nested content should be closed when a panel is closed
  2407. animateChildren : true, // whether children opacity should be animated
  2408. duration : 350, // duration of animation
  2409. easing : 'easeOutQuad', // easing equation for animation
  2410. onOpening : function(){}, // callback before open animation
  2411. onOpen : function(){}, // callback after open animation
  2412. onClosing : function(){}, // callback before closing animation
  2413. onClose : function(){}, // callback after closing animation
  2414. onChange : function(){}, // callback after closing or opening animation
  2415. error: {
  2416. method : 'The method you called is not defined'
  2417. },
  2418. className : {
  2419. active : 'active',
  2420. animating : 'animating'
  2421. },
  2422. selector : {
  2423. accordion : '.accordion',
  2424. title : '.title',
  2425. trigger : '.title',
  2426. content : '.content'
  2427. }
  2428. };
  2429. // Adds easing
  2430. $.extend( $.easing, {
  2431. easeOutQuad: function (x, t, b, c, d) {
  2432. return -c *(t/=d)*(t-2) + b;
  2433. }
  2434. });
  2435. })( jQuery, window , document );
  2436. /*!
  2437. * # Semantic UI 2.1.4 - Checkbox
  2438. * http://github.com/semantic-org/semantic-ui/
  2439. *
  2440. *
  2441. * Copyright 2015 Contributors
  2442. * Released under the MIT license
  2443. * http://opensource.org/licenses/MIT
  2444. *
  2445. */
  2446. ;(function ( $, window, document, undefined ) {
  2447. "use strict";
  2448. $.fn.checkbox = function(parameters) {
  2449. var
  2450. $allModules = $(this),
  2451. moduleSelector = $allModules.selector || '',
  2452. time = new Date().getTime(),
  2453. performance = [],
  2454. query = arguments[0],
  2455. methodInvoked = (typeof query == 'string'),
  2456. queryArguments = [].slice.call(arguments, 1),
  2457. returnedValue
  2458. ;
  2459. $allModules
  2460. .each(function() {
  2461. var
  2462. settings = $.extend(true, {}, $.fn.checkbox.settings, parameters),
  2463. className = settings.className,
  2464. namespace = settings.namespace,
  2465. selector = settings.selector,
  2466. error = settings.error,
  2467. eventNamespace = '.' + namespace,
  2468. moduleNamespace = 'module-' + namespace,
  2469. $module = $(this),
  2470. $label = $(this).children(selector.label),
  2471. $input = $(this).children(selector.input),
  2472. input = $input[0],
  2473. initialLoad = false,
  2474. shortcutPressed = false,
  2475. instance = $module.data(moduleNamespace),
  2476. observer,
  2477. element = this,
  2478. module
  2479. ;
  2480. module = {
  2481. initialize: function() {
  2482. module.verbose('Initializing checkbox', settings);
  2483. module.create.label();
  2484. module.bind.events();
  2485. module.set.tabbable();
  2486. module.hide.input();
  2487. module.observeChanges();
  2488. module.instantiate();
  2489. module.setup();
  2490. },
  2491. instantiate: function() {
  2492. module.verbose('Storing instance of module', module);
  2493. instance = module;
  2494. $module
  2495. .data(moduleNamespace, module)
  2496. ;
  2497. },
  2498. destroy: function() {
  2499. module.verbose('Destroying module');
  2500. module.unbind.events();
  2501. module.show.input();
  2502. $module.removeData(moduleNamespace);
  2503. },
  2504. fix: {
  2505. reference: function() {
  2506. if( $module.is(selector.input) ) {
  2507. module.debug('Behavior called on <input> adjusting invoked element');
  2508. $module = $module.closest(selector.checkbox);
  2509. module.refresh();
  2510. }
  2511. }
  2512. },
  2513. setup: function() {
  2514. module.set.initialLoad();
  2515. if( module.is.indeterminate() ) {
  2516. module.debug('Initial value is indeterminate');
  2517. module.indeterminate();
  2518. }
  2519. else if( module.is.checked() ) {
  2520. module.debug('Initial value is checked');
  2521. module.check();
  2522. }
  2523. else {
  2524. module.debug('Initial value is unchecked');
  2525. module.uncheck();
  2526. }
  2527. module.remove.initialLoad();
  2528. },
  2529. refresh: function() {
  2530. $label = $module.children(selector.label);
  2531. $input = $module.children(selector.input);
  2532. input = $input[0];
  2533. },
  2534. hide: {
  2535. input: function() {
  2536. module.verbose('Modfying <input> z-index to be unselectable');
  2537. $input.addClass(className.hidden);
  2538. }
  2539. },
  2540. show: {
  2541. input: function() {
  2542. module.verbose('Modfying <input> z-index to be selectable');
  2543. $input.removeClass(className.hidden);
  2544. }
  2545. },
  2546. observeChanges: function() {
  2547. if('MutationObserver' in window) {
  2548. observer = new MutationObserver(function(mutations) {
  2549. module.debug('DOM tree modified, updating selector cache');
  2550. module.refresh();
  2551. });
  2552. observer.observe(element, {
  2553. childList : true,
  2554. subtree : true
  2555. });
  2556. module.debug('Setting up mutation observer', observer);
  2557. }
  2558. },
  2559. attachEvents: function(selector, event) {
  2560. var
  2561. $element = $(selector)
  2562. ;
  2563. event = $.isFunction(module[event])
  2564. ? module[event]
  2565. : module.toggle
  2566. ;
  2567. if($element.length > 0) {
  2568. module.debug('Attaching checkbox events to element', selector, event);
  2569. $element
  2570. .on('click' + eventNamespace, event)
  2571. ;
  2572. }
  2573. else {
  2574. module.error(error.notFound);
  2575. }
  2576. },
  2577. event: {
  2578. click: function(event) {
  2579. var
  2580. $target = $(event.target)
  2581. ;
  2582. if( $target.is(selector.input) ) {
  2583. module.verbose('Using default check action on initialized checkbox');
  2584. return;
  2585. }
  2586. if( $target.is(selector.link) ) {
  2587. module.debug('Clicking link inside checkbox, skipping toggle');
  2588. return;
  2589. }
  2590. module.toggle();
  2591. $input.focus();
  2592. event.preventDefault();
  2593. },
  2594. keydown: function(event) {
  2595. var
  2596. key = event.which,
  2597. keyCode = {
  2598. enter : 13,
  2599. space : 32,
  2600. escape : 27
  2601. }
  2602. ;
  2603. if(key == keyCode.escape) {
  2604. module.verbose('Escape key pressed blurring field');
  2605. $input.blur();
  2606. shortcutPressed = true;
  2607. }
  2608. else if(!event.ctrlKey && ( key == keyCode.space || key == keyCode.enter) ) {
  2609. module.verbose('Enter/space key pressed, toggling checkbox');
  2610. module.toggle();
  2611. shortcutPressed = true;
  2612. }
  2613. else {
  2614. shortcutPressed = false;
  2615. }
  2616. },
  2617. keyup: function(event) {
  2618. if(shortcutPressed) {
  2619. event.preventDefault();
  2620. }
  2621. }
  2622. },
  2623. check: function() {
  2624. if( !module.should.allowCheck() ) {
  2625. return;
  2626. }
  2627. module.debug('Checking checkbox', $input);
  2628. module.set.checked();
  2629. if( !module.should.ignoreCallbacks() ) {
  2630. settings.onChecked.call(input);
  2631. settings.onChange.call(input);
  2632. }
  2633. },
  2634. uncheck: function() {
  2635. if( !module.should.allowUncheck() ) {
  2636. return;
  2637. }
  2638. module.debug('Unchecking checkbox');
  2639. module.set.unchecked();
  2640. if( !module.should.ignoreCallbacks() ) {
  2641. settings.onUnchecked.call(input);
  2642. settings.onChange.call(input);
  2643. }
  2644. },
  2645. indeterminate: function() {
  2646. if( module.should.allowIndeterminate() ) {
  2647. module.debug('Checkbox is already indeterminate');
  2648. return;
  2649. }
  2650. module.debug('Making checkbox indeterminate');
  2651. module.set.indeterminate();
  2652. if( !module.should.ignoreCallbacks() ) {
  2653. settings.onIndeterminate.call(input);
  2654. settings.onChange.call(input);
  2655. }
  2656. },
  2657. determinate: function() {
  2658. if( module.should.allowDeterminate() ) {
  2659. module.debug('Checkbox is already determinate');
  2660. return;
  2661. }
  2662. module.debug('Making checkbox determinate');
  2663. module.set.determinate();
  2664. if( !module.should.ignoreCallbacks() ) {
  2665. settings.onDeterminate.call(input);
  2666. settings.onChange.call(input);
  2667. }
  2668. },
  2669. enable: function() {
  2670. if( module.is.enabled() ) {
  2671. module.debug('Checkbox is already enabled');
  2672. return;
  2673. }
  2674. module.debug('Enabling checkbox');
  2675. module.set.enabled();
  2676. settings.onEnable.call(input);
  2677. },
  2678. disable: function() {
  2679. if( module.is.disabled() ) {
  2680. module.debug('Checkbox is already disabled');
  2681. return;
  2682. }
  2683. module.debug('Disabling checkbox');
  2684. module.set.disabled();
  2685. settings.onDisable.call(input);
  2686. },
  2687. get: {
  2688. radios: function() {
  2689. var
  2690. name = module.get.name()
  2691. ;
  2692. return $('input[name="' + name + '"]').closest(selector.checkbox);
  2693. },
  2694. otherRadios: function() {
  2695. return module.get.radios().not($module);
  2696. },
  2697. name: function() {
  2698. return $input.attr('name');
  2699. }
  2700. },
  2701. is: {
  2702. initialLoad: function() {
  2703. return initialLoad;
  2704. },
  2705. radio: function() {
  2706. return ($input.hasClass(className.radio) || $input.attr('type') == 'radio');
  2707. },
  2708. indeterminate: function() {
  2709. return $input.prop('indeterminate') !== undefined && $input.prop('indeterminate');
  2710. },
  2711. checked: function() {
  2712. return $input.prop('checked') !== undefined && $input.prop('checked');
  2713. },
  2714. disabled: function() {
  2715. return $input.prop('disabled') !== undefined && $input.prop('disabled');
  2716. },
  2717. enabled: function() {
  2718. return !module.is.disabled();
  2719. },
  2720. determinate: function() {
  2721. return !module.is.indeterminate();
  2722. },
  2723. unchecked: function() {
  2724. return !module.is.checked();
  2725. }
  2726. },
  2727. should: {
  2728. allowCheck: function() {
  2729. if(module.is.determinate() && module.is.checked() && !module.should.forceCallbacks() ) {
  2730. module.debug('Should not allow check, checkbox is already checked');
  2731. return false;
  2732. }
  2733. if(settings.beforeChecked.apply(input) === false) {
  2734. module.debug('Should not allow check, beforeChecked cancelled');
  2735. return false;
  2736. }
  2737. return true;
  2738. },
  2739. allowUncheck: function() {
  2740. if(module.is.determinate() && module.is.unchecked() && !module.should.forceCallbacks() ) {
  2741. module.debug('Should not allow uncheck, checkbox is already unchecked');
  2742. return false;
  2743. }
  2744. if(settings.beforeUnchecked.apply(input) === false) {
  2745. module.debug('Should not allow uncheck, beforeUnchecked cancelled');
  2746. return false;
  2747. }
  2748. return true;
  2749. },
  2750. allowIndeterminate: function() {
  2751. if(module.is.indeterminate() && !module.should.forceCallbacks() ) {
  2752. module.debug('Should not allow indeterminate, checkbox is already indeterminate');
  2753. return false;
  2754. }
  2755. if(settings.beforeIndeterminate.apply(input) === false) {
  2756. module.debug('Should not allow indeterminate, beforeIndeterminate cancelled');
  2757. return false;
  2758. }
  2759. return true;
  2760. },
  2761. allowDeterminate: function() {
  2762. if(module.is.determinate() && !module.should.forceCallbacks() ) {
  2763. module.debug('Should not allow determinate, checkbox is already determinate');
  2764. return false;
  2765. }
  2766. if(settings.beforeDeterminate.apply(input) === false) {
  2767. module.debug('Should not allow determinate, beforeDeterminate cancelled');
  2768. return false;
  2769. }
  2770. return true;
  2771. },
  2772. forceCallbacks: function() {
  2773. return (module.is.initialLoad() && settings.fireOnInit);
  2774. },
  2775. ignoreCallbacks: function() {
  2776. return (initialLoad && !settings.fireOnInit);
  2777. }
  2778. },
  2779. can: {
  2780. change: function() {
  2781. return !( $module.hasClass(className.disabled) || $module.hasClass(className.readOnly) || $input.prop('disabled') || $input.prop('readonly') );
  2782. },
  2783. uncheck: function() {
  2784. return (typeof settings.uncheckable === 'boolean')
  2785. ? settings.uncheckable
  2786. : !module.is.radio()
  2787. ;
  2788. }
  2789. },
  2790. set: {
  2791. initialLoad: function() {
  2792. initialLoad = true;
  2793. },
  2794. checked: function() {
  2795. module.verbose('Setting class to checked');
  2796. $module
  2797. .removeClass(className.indeterminate)
  2798. .addClass(className.checked)
  2799. ;
  2800. if( module.is.radio() ) {
  2801. module.uncheckOthers();
  2802. }
  2803. if(!module.is.indeterminate() && module.is.checked()) {
  2804. module.debug('Input is already checked, skipping input property change');
  2805. return;
  2806. }
  2807. module.verbose('Setting state to checked', input);
  2808. $input
  2809. .prop('indeterminate', false)
  2810. .prop('checked', true)
  2811. ;
  2812. module.trigger.change();
  2813. },
  2814. unchecked: function() {
  2815. module.verbose('Removing checked class');
  2816. $module
  2817. .removeClass(className.indeterminate)
  2818. .removeClass(className.checked)
  2819. ;
  2820. if(!module.is.indeterminate() && module.is.unchecked() ) {
  2821. module.debug('Input is already unchecked');
  2822. return;
  2823. }
  2824. module.debug('Setting state to unchecked');
  2825. $input
  2826. .prop('indeterminate', false)
  2827. .prop('checked', false)
  2828. ;
  2829. module.trigger.change();
  2830. },
  2831. indeterminate: function() {
  2832. module.verbose('Setting class to indeterminate');
  2833. $module
  2834. .addClass(className.indeterminate)
  2835. ;
  2836. if( module.is.indeterminate() ) {
  2837. module.debug('Input is already indeterminate, skipping input property change');
  2838. return;
  2839. }
  2840. module.debug('Setting state to indeterminate');
  2841. $input
  2842. .prop('indeterminate', true)
  2843. ;
  2844. module.trigger.change();
  2845. },
  2846. determinate: function() {
  2847. module.verbose('Removing indeterminate class');
  2848. $module
  2849. .removeClass(className.indeterminate)
  2850. ;
  2851. if( module.is.determinate() ) {
  2852. module.debug('Input is already determinate, skipping input property change');
  2853. return;
  2854. }
  2855. module.debug('Setting state to determinate');
  2856. $input
  2857. .prop('indeterminate', false)
  2858. ;
  2859. },
  2860. disabled: function() {
  2861. module.verbose('Setting class to disabled');
  2862. $module
  2863. .addClass(className.disabled)
  2864. ;
  2865. if( module.is.disabled() ) {
  2866. module.debug('Input is already disabled, skipping input property change');
  2867. return;
  2868. }
  2869. module.debug('Setting state to disabled');
  2870. $input
  2871. .prop('disabled', 'disabled')
  2872. ;
  2873. module.trigger.change();
  2874. },
  2875. enabled: function() {
  2876. module.verbose('Removing disabled class');
  2877. $module.removeClass(className.disabled);
  2878. if( module.is.enabled() ) {
  2879. module.debug('Input is already enabled, skipping input property change');
  2880. return;
  2881. }
  2882. module.debug('Setting state to enabled');
  2883. $input
  2884. .prop('disabled', false)
  2885. ;
  2886. module.trigger.change();
  2887. },
  2888. tabbable: function() {
  2889. module.verbose('Adding tabindex to checkbox');
  2890. if( $input.attr('tabindex') === undefined) {
  2891. $input.attr('tabindex', 0);
  2892. }
  2893. }
  2894. },
  2895. remove: {
  2896. initialLoad: function() {
  2897. initialLoad = false;
  2898. }
  2899. },
  2900. trigger: {
  2901. change: function() {
  2902. module.verbose('Triggering change event from programmatic change');
  2903. $input
  2904. .trigger('change')
  2905. ;
  2906. }
  2907. },
  2908. create: {
  2909. label: function() {
  2910. if($input.prevAll(selector.label).length > 0) {
  2911. $input.prev(selector.label).detach().insertAfter($input);
  2912. module.debug('Moving existing label', $label);
  2913. }
  2914. else if( !module.has.label() ) {
  2915. $label = $('<label>').insertAfter($input);
  2916. module.debug('Creating label', $label);
  2917. }
  2918. }
  2919. },
  2920. has: {
  2921. label: function() {
  2922. return ($label.length > 0);
  2923. }
  2924. },
  2925. bind: {
  2926. events: function() {
  2927. module.verbose('Attaching checkbox events');
  2928. $module
  2929. .on('click' + eventNamespace, module.event.click)
  2930. .on('keydown' + eventNamespace, selector.input, module.event.keydown)
  2931. .on('keyup' + eventNamespace, selector.input, module.event.keyup)
  2932. ;
  2933. }
  2934. },
  2935. unbind: {
  2936. events: function() {
  2937. module.debug('Removing events');
  2938. $module
  2939. .off(eventNamespace)
  2940. ;
  2941. }
  2942. },
  2943. uncheckOthers: function() {
  2944. var
  2945. $radios = module.get.otherRadios()
  2946. ;
  2947. module.debug('Unchecking other radios', $radios);
  2948. $radios.removeClass(className.checked);
  2949. },
  2950. toggle: function() {
  2951. if( !module.can.change() ) {
  2952. if(!module.is.radio()) {
  2953. module.debug('Checkbox is read-only or disabled, ignoring toggle');
  2954. }
  2955. return;
  2956. }
  2957. if( module.is.indeterminate() || module.is.unchecked() ) {
  2958. module.debug('Currently unchecked');
  2959. module.check();
  2960. }
  2961. else if( module.is.checked() && module.can.uncheck() ) {
  2962. module.debug('Currently checked');
  2963. module.uncheck();
  2964. }
  2965. },
  2966. setting: function(name, value) {
  2967. module.debug('Changing setting', name, value);
  2968. if( $.isPlainObject(name) ) {
  2969. $.extend(true, settings, name);
  2970. }
  2971. else if(value !== undefined) {
  2972. settings[name] = value;
  2973. }
  2974. else {
  2975. return settings[name];
  2976. }
  2977. },
  2978. internal: function(name, value) {
  2979. if( $.isPlainObject(name) ) {
  2980. $.extend(true, module, name);
  2981. }
  2982. else if(value !== undefined) {
  2983. module[name] = value;
  2984. }
  2985. else {
  2986. return module[name];
  2987. }
  2988. },
  2989. debug: function() {
  2990. if(settings.debug) {
  2991. if(settings.performance) {
  2992. module.performance.log(arguments);
  2993. }
  2994. else {
  2995. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  2996. module.debug.apply(console, arguments);
  2997. }
  2998. }
  2999. },
  3000. verbose: function() {
  3001. if(settings.verbose && settings.debug) {
  3002. if(settings.performance) {
  3003. module.performance.log(arguments);
  3004. }
  3005. else {
  3006. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  3007. module.verbose.apply(console, arguments);
  3008. }
  3009. }
  3010. },
  3011. error: function() {
  3012. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  3013. module.error.apply(console, arguments);
  3014. },
  3015. performance: {
  3016. log: function(message) {
  3017. var
  3018. currentTime,
  3019. executionTime,
  3020. previousTime
  3021. ;
  3022. if(settings.performance) {
  3023. currentTime = new Date().getTime();
  3024. previousTime = time || currentTime;
  3025. executionTime = currentTime - previousTime;
  3026. time = currentTime;
  3027. performance.push({
  3028. 'Name' : message[0],
  3029. 'Arguments' : [].slice.call(message, 1) || '',
  3030. 'Element' : element,
  3031. 'Execution Time' : executionTime
  3032. });
  3033. }
  3034. clearTimeout(module.performance.timer);
  3035. module.performance.timer = setTimeout(module.performance.display, 500);
  3036. },
  3037. display: function() {
  3038. var
  3039. title = settings.name + ':',
  3040. totalTime = 0
  3041. ;
  3042. time = false;
  3043. clearTimeout(module.performance.timer);
  3044. $.each(performance, function(index, data) {
  3045. totalTime += data['Execution Time'];
  3046. });
  3047. title += ' ' + totalTime + 'ms';
  3048. if(moduleSelector) {
  3049. title += ' \'' + moduleSelector + '\'';
  3050. }
  3051. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  3052. console.groupCollapsed(title);
  3053. if(console.table) {
  3054. console.table(performance);
  3055. }
  3056. else {
  3057. $.each(performance, function(index, data) {
  3058. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  3059. });
  3060. }
  3061. console.groupEnd();
  3062. }
  3063. performance = [];
  3064. }
  3065. },
  3066. invoke: function(query, passedArguments, context) {
  3067. var
  3068. object = instance,
  3069. maxDepth,
  3070. found,
  3071. response
  3072. ;
  3073. passedArguments = passedArguments || queryArguments;
  3074. context = element || context;
  3075. if(typeof query == 'string' && object !== undefined) {
  3076. query = query.split(/[\. ]/);
  3077. maxDepth = query.length - 1;
  3078. $.each(query, function(depth, value) {
  3079. var camelCaseValue = (depth != maxDepth)
  3080. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  3081. : query
  3082. ;
  3083. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  3084. object = object[camelCaseValue];
  3085. }
  3086. else if( object[camelCaseValue] !== undefined ) {
  3087. found = object[camelCaseValue];
  3088. return false;
  3089. }
  3090. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  3091. object = object[value];
  3092. }
  3093. else if( object[value] !== undefined ) {
  3094. found = object[value];
  3095. return false;
  3096. }
  3097. else {
  3098. module.error(error.method, query);
  3099. return false;
  3100. }
  3101. });
  3102. }
  3103. if ( $.isFunction( found ) ) {
  3104. response = found.apply(context, passedArguments);
  3105. }
  3106. else if(found !== undefined) {
  3107. response = found;
  3108. }
  3109. if($.isArray(returnedValue)) {
  3110. returnedValue.push(response);
  3111. }
  3112. else if(returnedValue !== undefined) {
  3113. returnedValue = [returnedValue, response];
  3114. }
  3115. else if(response !== undefined) {
  3116. returnedValue = response;
  3117. }
  3118. return found;
  3119. }
  3120. };
  3121. if(methodInvoked) {
  3122. if(instance === undefined) {
  3123. module.initialize();
  3124. }
  3125. module.invoke(query);
  3126. }
  3127. else {
  3128. if(instance !== undefined) {
  3129. instance.invoke('destroy');
  3130. }
  3131. module.initialize();
  3132. }
  3133. })
  3134. ;
  3135. return (returnedValue !== undefined)
  3136. ? returnedValue
  3137. : this
  3138. ;
  3139. };
  3140. $.fn.checkbox.settings = {
  3141. name : 'Checkbox',
  3142. namespace : 'checkbox',
  3143. debug : false,
  3144. verbose : true,
  3145. performance : true,
  3146. // delegated event context
  3147. uncheckable : 'auto',
  3148. fireOnInit : false,
  3149. onChange : function(){},
  3150. beforeChecked : function(){},
  3151. beforeUnchecked : function(){},
  3152. beforeDeterminate : function(){},
  3153. beforeIndeterminate : function(){},
  3154. onChecked : function(){},
  3155. onUnchecked : function(){},
  3156. onDeterminate : function() {},
  3157. onIndeterminate : function() {},
  3158. onEnabled : function(){},
  3159. onDisabled : function(){},
  3160. className : {
  3161. checked : 'checked',
  3162. indeterminate : 'indeterminate',
  3163. disabled : 'disabled',
  3164. hidden : 'hidden',
  3165. radio : 'radio',
  3166. readOnly : 'read-only'
  3167. },
  3168. error : {
  3169. method : 'The method you called is not defined'
  3170. },
  3171. selector : {
  3172. checkbox : '.ui.checkbox',
  3173. label : 'label, .box',
  3174. input : 'input[type="checkbox"], input[type="radio"]',
  3175. link : 'a[href]'
  3176. }
  3177. };
  3178. })( jQuery, window , document );
  3179. /*!
  3180. * # Semantic UI 2.1.4 - Dimmer
  3181. * http://github.com/semantic-org/semantic-ui/
  3182. *
  3183. *
  3184. * Copyright 2015 Contributors
  3185. * Released under the MIT license
  3186. * http://opensource.org/licenses/MIT
  3187. *
  3188. */
  3189. ;(function ( $, window, document, undefined ) {
  3190. "use strict";
  3191. $.fn.dimmer = function(parameters) {
  3192. var
  3193. $allModules = $(this),
  3194. time = new Date().getTime(),
  3195. performance = [],
  3196. query = arguments[0],
  3197. methodInvoked = (typeof query == 'string'),
  3198. queryArguments = [].slice.call(arguments, 1),
  3199. returnedValue
  3200. ;
  3201. $allModules
  3202. .each(function() {
  3203. var
  3204. settings = ( $.isPlainObject(parameters) )
  3205. ? $.extend(true, {}, $.fn.dimmer.settings, parameters)
  3206. : $.extend({}, $.fn.dimmer.settings),
  3207. selector = settings.selector,
  3208. namespace = settings.namespace,
  3209. className = settings.className,
  3210. error = settings.error,
  3211. eventNamespace = '.' + namespace,
  3212. moduleNamespace = 'module-' + namespace,
  3213. moduleSelector = $allModules.selector || '',
  3214. clickEvent = ('ontouchstart' in document.documentElement)
  3215. ? 'touchstart'
  3216. : 'click',
  3217. $module = $(this),
  3218. $dimmer,
  3219. $dimmable,
  3220. element = this,
  3221. instance = $module.data(moduleNamespace),
  3222. module
  3223. ;
  3224. module = {
  3225. preinitialize: function() {
  3226. if( module.is.dimmer() ) {
  3227. $dimmable = $module.parent();
  3228. $dimmer = $module;
  3229. }
  3230. else {
  3231. $dimmable = $module;
  3232. if( module.has.dimmer() ) {
  3233. if(settings.dimmerName) {
  3234. $dimmer = $dimmable.find(selector.dimmer).filter('.' + settings.dimmerName);
  3235. }
  3236. else {
  3237. $dimmer = $dimmable.find(selector.dimmer);
  3238. }
  3239. }
  3240. else {
  3241. $dimmer = module.create();
  3242. }
  3243. }
  3244. },
  3245. initialize: function() {
  3246. module.debug('Initializing dimmer', settings);
  3247. module.bind.events();
  3248. module.set.dimmable();
  3249. module.instantiate();
  3250. },
  3251. instantiate: function() {
  3252. module.verbose('Storing instance of module', module);
  3253. instance = module;
  3254. $module
  3255. .data(moduleNamespace, instance)
  3256. ;
  3257. },
  3258. destroy: function() {
  3259. module.verbose('Destroying previous module', $dimmer);
  3260. module.unbind.events();
  3261. module.remove.variation();
  3262. $dimmable
  3263. .off(eventNamespace)
  3264. ;
  3265. },
  3266. bind: {
  3267. events: function() {
  3268. if(settings.on == 'hover') {
  3269. $dimmable
  3270. .on('mouseenter' + eventNamespace, module.show)
  3271. .on('mouseleave' + eventNamespace, module.hide)
  3272. ;
  3273. }
  3274. else if(settings.on == 'click') {
  3275. $dimmable
  3276. .on(clickEvent + eventNamespace, module.toggle)
  3277. ;
  3278. }
  3279. if( module.is.page() ) {
  3280. module.debug('Setting as a page dimmer', $dimmable);
  3281. module.set.pageDimmer();
  3282. }
  3283. if( module.is.closable() ) {
  3284. module.verbose('Adding dimmer close event', $dimmer);
  3285. $dimmable
  3286. .on(clickEvent + eventNamespace, selector.dimmer, module.event.click)
  3287. ;
  3288. }
  3289. }
  3290. },
  3291. unbind: {
  3292. events: function() {
  3293. $module
  3294. .removeData(moduleNamespace)
  3295. ;
  3296. }
  3297. },
  3298. event: {
  3299. click: function(event) {
  3300. module.verbose('Determining if event occured on dimmer', event);
  3301. if( $dimmer.find(event.target).length === 0 || $(event.target).is(selector.content) ) {
  3302. module.hide();
  3303. event.stopImmediatePropagation();
  3304. }
  3305. }
  3306. },
  3307. addContent: function(element) {
  3308. var
  3309. $content = $(element)
  3310. ;
  3311. module.debug('Add content to dimmer', $content);
  3312. if($content.parent()[0] !== $dimmer[0]) {
  3313. $content.detach().appendTo($dimmer);
  3314. }
  3315. },
  3316. create: function() {
  3317. var
  3318. $element = $( settings.template.dimmer() )
  3319. ;
  3320. if(settings.variation) {
  3321. module.debug('Creating dimmer with variation', settings.variation);
  3322. $element.addClass(settings.variation);
  3323. }
  3324. if(settings.dimmerName) {
  3325. module.debug('Creating named dimmer', settings.dimmerName);
  3326. $element.addClass(settings.dimmerName);
  3327. }
  3328. $element
  3329. .appendTo($dimmable)
  3330. ;
  3331. return $element;
  3332. },
  3333. show: function(callback) {
  3334. callback = $.isFunction(callback)
  3335. ? callback
  3336. : function(){}
  3337. ;
  3338. module.debug('Showing dimmer', $dimmer, settings);
  3339. if( (!module.is.dimmed() || module.is.animating()) && module.is.enabled() ) {
  3340. module.animate.show(callback);
  3341. settings.onShow.call(element);
  3342. settings.onChange.call(element);
  3343. }
  3344. else {
  3345. module.debug('Dimmer is already shown or disabled');
  3346. }
  3347. },
  3348. hide: function(callback) {
  3349. callback = $.isFunction(callback)
  3350. ? callback
  3351. : function(){}
  3352. ;
  3353. if( module.is.dimmed() || module.is.animating() ) {
  3354. module.debug('Hiding dimmer', $dimmer);
  3355. module.animate.hide(callback);
  3356. settings.onHide.call(element);
  3357. settings.onChange.call(element);
  3358. }
  3359. else {
  3360. module.debug('Dimmer is not visible');
  3361. }
  3362. },
  3363. toggle: function() {
  3364. module.verbose('Toggling dimmer visibility', $dimmer);
  3365. if( !module.is.dimmed() ) {
  3366. module.show();
  3367. }
  3368. else {
  3369. module.hide();
  3370. }
  3371. },
  3372. animate: {
  3373. show: function(callback) {
  3374. callback = $.isFunction(callback)
  3375. ? callback
  3376. : function(){}
  3377. ;
  3378. if(settings.useCSS && $.fn.transition !== undefined && $dimmer.transition('is supported')) {
  3379. if(settings.opacity !== 'auto') {
  3380. module.set.opacity();
  3381. }
  3382. $dimmer
  3383. .transition({
  3384. animation : settings.transition + ' in',
  3385. queue : false,
  3386. duration : module.get.duration(),
  3387. useFailSafe : true,
  3388. onStart : function() {
  3389. module.set.dimmed();
  3390. },
  3391. onComplete : function() {
  3392. module.set.active();
  3393. callback();
  3394. }
  3395. })
  3396. ;
  3397. }
  3398. else {
  3399. module.verbose('Showing dimmer animation with javascript');
  3400. module.set.dimmed();
  3401. if(settings.opacity == 'auto') {
  3402. settings.opacity = 0.8;
  3403. }
  3404. $dimmer
  3405. .stop()
  3406. .css({
  3407. opacity : 0,
  3408. width : '100%',
  3409. height : '100%'
  3410. })
  3411. .fadeTo(module.get.duration(), settings.opacity, function() {
  3412. $dimmer.removeAttr('style');
  3413. module.set.active();
  3414. callback();
  3415. })
  3416. ;
  3417. }
  3418. },
  3419. hide: function(callback) {
  3420. callback = $.isFunction(callback)
  3421. ? callback
  3422. : function(){}
  3423. ;
  3424. if(settings.useCSS && $.fn.transition !== undefined && $dimmer.transition('is supported')) {
  3425. module.verbose('Hiding dimmer with css');
  3426. $dimmer
  3427. .transition({
  3428. animation : settings.transition + ' out',
  3429. queue : false,
  3430. duration : module.get.duration(),
  3431. useFailSafe : true,
  3432. onStart : function() {
  3433. module.remove.dimmed();
  3434. },
  3435. onComplete : function() {
  3436. module.remove.active();
  3437. callback();
  3438. }
  3439. })
  3440. ;
  3441. }
  3442. else {
  3443. module.verbose('Hiding dimmer with javascript');
  3444. module.remove.dimmed();
  3445. $dimmer
  3446. .stop()
  3447. .fadeOut(module.get.duration(), function() {
  3448. module.remove.active();
  3449. $dimmer.removeAttr('style');
  3450. callback();
  3451. })
  3452. ;
  3453. }
  3454. }
  3455. },
  3456. get: {
  3457. dimmer: function() {
  3458. return $dimmer;
  3459. },
  3460. duration: function() {
  3461. if(typeof settings.duration == 'object') {
  3462. if( module.is.active() ) {
  3463. return settings.duration.hide;
  3464. }
  3465. else {
  3466. return settings.duration.show;
  3467. }
  3468. }
  3469. return settings.duration;
  3470. }
  3471. },
  3472. has: {
  3473. dimmer: function() {
  3474. if(settings.dimmerName) {
  3475. return ($module.find(selector.dimmer).filter('.' + settings.dimmerName).length > 0);
  3476. }
  3477. else {
  3478. return ( $module.find(selector.dimmer).length > 0 );
  3479. }
  3480. }
  3481. },
  3482. is: {
  3483. active: function() {
  3484. return $dimmer.hasClass(className.active);
  3485. },
  3486. animating: function() {
  3487. return ( $dimmer.is(':animated') || $dimmer.hasClass(className.animating) );
  3488. },
  3489. closable: function() {
  3490. if(settings.closable == 'auto') {
  3491. if(settings.on == 'hover') {
  3492. return false;
  3493. }
  3494. return true;
  3495. }
  3496. return settings.closable;
  3497. },
  3498. dimmer: function() {
  3499. return $module.hasClass(className.dimmer);
  3500. },
  3501. dimmable: function() {
  3502. return $module.hasClass(className.dimmable);
  3503. },
  3504. dimmed: function() {
  3505. return $dimmable.hasClass(className.dimmed);
  3506. },
  3507. disabled: function() {
  3508. return $dimmable.hasClass(className.disabled);
  3509. },
  3510. enabled: function() {
  3511. return !module.is.disabled();
  3512. },
  3513. page: function () {
  3514. return $dimmable.is('body');
  3515. },
  3516. pageDimmer: function() {
  3517. return $dimmer.hasClass(className.pageDimmer);
  3518. }
  3519. },
  3520. can: {
  3521. show: function() {
  3522. return !$dimmer.hasClass(className.disabled);
  3523. }
  3524. },
  3525. set: {
  3526. opacity: function(opacity) {
  3527. var
  3528. color = $dimmer.css('background-color'),
  3529. colorArray = color.split(','),
  3530. isRGBA = (colorArray && colorArray.length == 4)
  3531. ;
  3532. opacity = settings.opacity || opacity;
  3533. if(isRGBA) {
  3534. colorArray[3] = opacity + ')';
  3535. color = colorArray.join(',');
  3536. }
  3537. else {
  3538. color = 'rgba(0, 0, 0, ' + opacity + ')';
  3539. }
  3540. module.debug('Setting opacity to', opacity);
  3541. $dimmer.css('background-color', color);
  3542. },
  3543. active: function() {
  3544. $dimmer.addClass(className.active);
  3545. },
  3546. dimmable: function() {
  3547. $dimmable.addClass(className.dimmable);
  3548. },
  3549. dimmed: function() {
  3550. $dimmable.addClass(className.dimmed);
  3551. },
  3552. pageDimmer: function() {
  3553. $dimmer.addClass(className.pageDimmer);
  3554. },
  3555. disabled: function() {
  3556. $dimmer.addClass(className.disabled);
  3557. },
  3558. variation: function(variation) {
  3559. variation = variation || settings.variation;
  3560. if(variation) {
  3561. $dimmer.addClass(variation);
  3562. }
  3563. }
  3564. },
  3565. remove: {
  3566. active: function() {
  3567. $dimmer
  3568. .removeClass(className.active)
  3569. ;
  3570. },
  3571. dimmed: function() {
  3572. $dimmable.removeClass(className.dimmed);
  3573. },
  3574. disabled: function() {
  3575. $dimmer.removeClass(className.disabled);
  3576. },
  3577. variation: function(variation) {
  3578. variation = variation || settings.variation;
  3579. if(variation) {
  3580. $dimmer.removeClass(variation);
  3581. }
  3582. }
  3583. },
  3584. setting: function(name, value) {
  3585. module.debug('Changing setting', name, value);
  3586. if( $.isPlainObject(name) ) {
  3587. $.extend(true, settings, name);
  3588. }
  3589. else if(value !== undefined) {
  3590. settings[name] = value;
  3591. }
  3592. else {
  3593. return settings[name];
  3594. }
  3595. },
  3596. internal: function(name, value) {
  3597. if( $.isPlainObject(name) ) {
  3598. $.extend(true, module, name);
  3599. }
  3600. else if(value !== undefined) {
  3601. module[name] = value;
  3602. }
  3603. else {
  3604. return module[name];
  3605. }
  3606. },
  3607. debug: function() {
  3608. if(settings.debug) {
  3609. if(settings.performance) {
  3610. module.performance.log(arguments);
  3611. }
  3612. else {
  3613. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  3614. module.debug.apply(console, arguments);
  3615. }
  3616. }
  3617. },
  3618. verbose: function() {
  3619. if(settings.verbose && settings.debug) {
  3620. if(settings.performance) {
  3621. module.performance.log(arguments);
  3622. }
  3623. else {
  3624. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  3625. module.verbose.apply(console, arguments);
  3626. }
  3627. }
  3628. },
  3629. error: function() {
  3630. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  3631. module.error.apply(console, arguments);
  3632. },
  3633. performance: {
  3634. log: function(message) {
  3635. var
  3636. currentTime,
  3637. executionTime,
  3638. previousTime
  3639. ;
  3640. if(settings.performance) {
  3641. currentTime = new Date().getTime();
  3642. previousTime = time || currentTime;
  3643. executionTime = currentTime - previousTime;
  3644. time = currentTime;
  3645. performance.push({
  3646. 'Name' : message[0],
  3647. 'Arguments' : [].slice.call(message, 1) || '',
  3648. 'Element' : element,
  3649. 'Execution Time' : executionTime
  3650. });
  3651. }
  3652. clearTimeout(module.performance.timer);
  3653. module.performance.timer = setTimeout(module.performance.display, 500);
  3654. },
  3655. display: function() {
  3656. var
  3657. title = settings.name + ':',
  3658. totalTime = 0
  3659. ;
  3660. time = false;
  3661. clearTimeout(module.performance.timer);
  3662. $.each(performance, function(index, data) {
  3663. totalTime += data['Execution Time'];
  3664. });
  3665. title += ' ' + totalTime + 'ms';
  3666. if(moduleSelector) {
  3667. title += ' \'' + moduleSelector + '\'';
  3668. }
  3669. if($allModules.length > 1) {
  3670. title += ' ' + '(' + $allModules.length + ')';
  3671. }
  3672. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  3673. console.groupCollapsed(title);
  3674. if(console.table) {
  3675. console.table(performance);
  3676. }
  3677. else {
  3678. $.each(performance, function(index, data) {
  3679. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  3680. });
  3681. }
  3682. console.groupEnd();
  3683. }
  3684. performance = [];
  3685. }
  3686. },
  3687. invoke: function(query, passedArguments, context) {
  3688. var
  3689. object = instance,
  3690. maxDepth,
  3691. found,
  3692. response
  3693. ;
  3694. passedArguments = passedArguments || queryArguments;
  3695. context = element || context;
  3696. if(typeof query == 'string' && object !== undefined) {
  3697. query = query.split(/[\. ]/);
  3698. maxDepth = query.length - 1;
  3699. $.each(query, function(depth, value) {
  3700. var camelCaseValue = (depth != maxDepth)
  3701. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  3702. : query
  3703. ;
  3704. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  3705. object = object[camelCaseValue];
  3706. }
  3707. else if( object[camelCaseValue] !== undefined ) {
  3708. found = object[camelCaseValue];
  3709. return false;
  3710. }
  3711. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  3712. object = object[value];
  3713. }
  3714. else if( object[value] !== undefined ) {
  3715. found = object[value];
  3716. return false;
  3717. }
  3718. else {
  3719. module.error(error.method, query);
  3720. return false;
  3721. }
  3722. });
  3723. }
  3724. if ( $.isFunction( found ) ) {
  3725. response = found.apply(context, passedArguments);
  3726. }
  3727. else if(found !== undefined) {
  3728. response = found;
  3729. }
  3730. if($.isArray(returnedValue)) {
  3731. returnedValue.push(response);
  3732. }
  3733. else if(returnedValue !== undefined) {
  3734. returnedValue = [returnedValue, response];
  3735. }
  3736. else if(response !== undefined) {
  3737. returnedValue = response;
  3738. }
  3739. return found;
  3740. }
  3741. };
  3742. module.preinitialize();
  3743. if(methodInvoked) {
  3744. if(instance === undefined) {
  3745. module.initialize();
  3746. }
  3747. module.invoke(query);
  3748. }
  3749. else {
  3750. if(instance !== undefined) {
  3751. instance.invoke('destroy');
  3752. }
  3753. module.initialize();
  3754. }
  3755. })
  3756. ;
  3757. return (returnedValue !== undefined)
  3758. ? returnedValue
  3759. : this
  3760. ;
  3761. };
  3762. $.fn.dimmer.settings = {
  3763. name : 'Dimmer',
  3764. namespace : 'dimmer',
  3765. debug : false,
  3766. verbose : false,
  3767. performance : true,
  3768. // name to distinguish between multiple dimmers in context
  3769. dimmerName : false,
  3770. // whether to add a variation type
  3771. variation : false,
  3772. // whether to bind close events
  3773. closable : 'auto',
  3774. // whether to use css animations
  3775. useCSS : true,
  3776. // css animation to use
  3777. transition : 'fade',
  3778. // event to bind to
  3779. on : false,
  3780. // overriding opacity value
  3781. opacity : 'auto',
  3782. // transition durations
  3783. duration : {
  3784. show : 500,
  3785. hide : 500
  3786. },
  3787. onChange : function(){},
  3788. onShow : function(){},
  3789. onHide : function(){},
  3790. error : {
  3791. method : 'The method you called is not defined.'
  3792. },
  3793. className : {
  3794. active : 'active',
  3795. animating : 'animating',
  3796. dimmable : 'dimmable',
  3797. dimmed : 'dimmed',
  3798. dimmer : 'dimmer',
  3799. disabled : 'disabled',
  3800. hide : 'hide',
  3801. pageDimmer : 'page',
  3802. show : 'show'
  3803. },
  3804. selector: {
  3805. dimmer : '> .ui.dimmer',
  3806. content : '.ui.dimmer > .content, .ui.dimmer > .content > .center'
  3807. },
  3808. template: {
  3809. dimmer: function() {
  3810. return $('<div />').attr('class', 'ui dimmer');
  3811. }
  3812. }
  3813. };
  3814. })( jQuery, window , document );
  3815. /*!
  3816. * # Semantic UI 2.1.4 - Dropdown
  3817. * http://github.com/semantic-org/semantic-ui/
  3818. *
  3819. *
  3820. * Copyright 2015 Contributors
  3821. * Released under the MIT license
  3822. * http://opensource.org/licenses/MIT
  3823. *
  3824. */
  3825. ;(function ( $, window, document, undefined ) {
  3826. "use strict";
  3827. $.fn.dropdown = function(parameters) {
  3828. var
  3829. $allModules = $(this),
  3830. $document = $(document),
  3831. moduleSelector = $allModules.selector || '',
  3832. hasTouch = ('ontouchstart' in document.documentElement),
  3833. time = new Date().getTime(),
  3834. performance = [],
  3835. query = arguments[0],
  3836. methodInvoked = (typeof query == 'string'),
  3837. queryArguments = [].slice.call(arguments, 1),
  3838. returnedValue
  3839. ;
  3840. $allModules
  3841. .each(function(elementIndex) {
  3842. var
  3843. settings = ( $.isPlainObject(parameters) )
  3844. ? $.extend(true, {}, $.fn.dropdown.settings, parameters)
  3845. : $.extend({}, $.fn.dropdown.settings),
  3846. className = settings.className,
  3847. message = settings.message,
  3848. fields = settings.fields,
  3849. metadata = settings.metadata,
  3850. namespace = settings.namespace,
  3851. regExp = settings.regExp,
  3852. selector = settings.selector,
  3853. error = settings.error,
  3854. templates = settings.templates,
  3855. eventNamespace = '.' + namespace,
  3856. moduleNamespace = 'module-' + namespace,
  3857. $module = $(this),
  3858. $context = $(settings.context),
  3859. $text = $module.find(selector.text),
  3860. $search = $module.find(selector.search),
  3861. $input = $module.find(selector.input),
  3862. $icon = $module.find(selector.icon),
  3863. $combo = ($module.prev().find(selector.text).length > 0)
  3864. ? $module.prev().find(selector.text)
  3865. : $module.prev(),
  3866. $menu = $module.children(selector.menu),
  3867. $item = $menu.find(selector.item),
  3868. activated = false,
  3869. itemActivated = false,
  3870. internalChange = false,
  3871. element = this,
  3872. instance = $module.data(moduleNamespace),
  3873. initialLoad,
  3874. pageLostFocus,
  3875. elementNamespace,
  3876. id,
  3877. selectObserver,
  3878. menuObserver,
  3879. module
  3880. ;
  3881. module = {
  3882. initialize: function() {
  3883. module.debug('Initializing dropdown', settings);
  3884. if( module.is.alreadySetup() ) {
  3885. module.setup.reference();
  3886. }
  3887. else {
  3888. module.setup.layout();
  3889. module.refreshData();
  3890. module.save.defaults();
  3891. module.restore.selected();
  3892. module.create.id();
  3893. module.bind.events();
  3894. module.observeChanges();
  3895. module.instantiate();
  3896. }
  3897. },
  3898. instantiate: function() {
  3899. module.verbose('Storing instance of dropdown', module);
  3900. instance = module;
  3901. $module
  3902. .data(moduleNamespace, module)
  3903. ;
  3904. },
  3905. destroy: function() {
  3906. module.verbose('Destroying previous dropdown', $module);
  3907. module.remove.tabbable();
  3908. $module
  3909. .off(eventNamespace)
  3910. .removeData(moduleNamespace)
  3911. ;
  3912. $menu
  3913. .off(eventNamespace)
  3914. ;
  3915. $document
  3916. .off(elementNamespace)
  3917. ;
  3918. if(selectObserver) {
  3919. selectObserver.disconnect();
  3920. }
  3921. if(menuObserver) {
  3922. menuObserver.disconnect();
  3923. }
  3924. },
  3925. observeChanges: function() {
  3926. if('MutationObserver' in window) {
  3927. selectObserver = new MutationObserver(function(mutations) {
  3928. module.debug('<select> modified, recreating menu');
  3929. module.setup.select();
  3930. });
  3931. menuObserver = new MutationObserver(function(mutations) {
  3932. module.debug('Menu modified, updating selector cache');
  3933. module.refresh();
  3934. });
  3935. if(module.has.input()) {
  3936. selectObserver.observe($input[0], {
  3937. childList : true,
  3938. subtree : true
  3939. });
  3940. }
  3941. if(module.has.menu()) {
  3942. menuObserver.observe($menu[0], {
  3943. childList : true,
  3944. subtree : true
  3945. });
  3946. }
  3947. module.debug('Setting up mutation observer', selectObserver, menuObserver);
  3948. }
  3949. },
  3950. create: {
  3951. id: function() {
  3952. id = (Math.random().toString(16) + '000000000').substr(2, 8);
  3953. elementNamespace = '.' + id;
  3954. module.verbose('Creating unique id for element', id);
  3955. },
  3956. userChoice: function(values) {
  3957. var
  3958. $userChoices,
  3959. $userChoice,
  3960. isUserValue,
  3961. html
  3962. ;
  3963. values = values || module.get.userValues();
  3964. if(!values) {
  3965. return false;
  3966. }
  3967. values = $.isArray(values)
  3968. ? values
  3969. : [values]
  3970. ;
  3971. $.each(values, function(index, value) {
  3972. if(module.get.item(value) === false) {
  3973. html = settings.templates.addition( module.add.variables(message.addResult, value) );
  3974. $userChoice = $('<div />')
  3975. .html(html)
  3976. .attr('data-' + metadata.value, value)
  3977. .attr('data-' + metadata.text, value)
  3978. .addClass(className.addition)
  3979. .addClass(className.item)
  3980. ;
  3981. $userChoices = ($userChoices === undefined)
  3982. ? $userChoice
  3983. : $userChoices.add($userChoice)
  3984. ;
  3985. module.verbose('Creating user choices for value', value, $userChoice);
  3986. }
  3987. });
  3988. return $userChoices;
  3989. },
  3990. userLabels: function(value) {
  3991. var
  3992. userValues = module.get.userValues()
  3993. ;
  3994. if(userValues) {
  3995. module.debug('Adding user labels', userValues);
  3996. $.each(userValues, function(index, value) {
  3997. module.verbose('Adding custom user value');
  3998. module.add.label(value, value);
  3999. });
  4000. }
  4001. },
  4002. menu: function() {
  4003. $menu = $('<div />')
  4004. .addClass(className.menu)
  4005. .appendTo($module)
  4006. ;
  4007. }
  4008. },
  4009. search: function(query) {
  4010. query = (query !== undefined)
  4011. ? query
  4012. : module.get.query()
  4013. ;
  4014. module.verbose('Searching for query', query);
  4015. module.filter(query);
  4016. },
  4017. select: {
  4018. firstUnfiltered: function() {
  4019. module.verbose('Selecting first non-filtered element');
  4020. module.remove.selectedItem();
  4021. $item
  4022. .not(selector.unselectable)
  4023. .eq(0)
  4024. .addClass(className.selected)
  4025. ;
  4026. },
  4027. nextAvailable: function($selected) {
  4028. $selected = $selected.eq(0);
  4029. var
  4030. $nextAvailable = $selected.nextAll(selector.item).not(selector.unselectable).eq(0),
  4031. $prevAvailable = $selected.prevAll(selector.item).not(selector.unselectable).eq(0),
  4032. hasNext = ($nextAvailable.length > 0)
  4033. ;
  4034. if(hasNext) {
  4035. module.verbose('Moving selection to', $nextAvailable);
  4036. $nextAvailable.addClass(className.selected);
  4037. }
  4038. else {
  4039. module.verbose('Moving selection to', $prevAvailable);
  4040. $prevAvailable.addClass(className.selected);
  4041. }
  4042. }
  4043. },
  4044. setup: {
  4045. api: function() {
  4046. var
  4047. apiSettings = {
  4048. debug : settings.debug,
  4049. on : false
  4050. }
  4051. ;
  4052. module.verbose('First request, initializing API');
  4053. $module
  4054. .api(apiSettings)
  4055. ;
  4056. },
  4057. layout: function() {
  4058. if( $module.is('select') ) {
  4059. module.setup.select();
  4060. module.setup.returnedObject();
  4061. }
  4062. if( !module.has.menu() ) {
  4063. module.create.menu();
  4064. }
  4065. if( module.is.search() && !module.has.search() ) {
  4066. module.verbose('Adding search input');
  4067. $search = $('<input />')
  4068. .addClass(className.search)
  4069. .insertBefore($text)
  4070. ;
  4071. }
  4072. if(settings.allowTab) {
  4073. module.set.tabbable();
  4074. }
  4075. },
  4076. select: function() {
  4077. var
  4078. selectValues = module.get.selectValues()
  4079. ;
  4080. module.debug('Dropdown initialized on a select', selectValues);
  4081. if( $module.is('select') ) {
  4082. $input = $module;
  4083. }
  4084. // see if select is placed correctly already
  4085. if($input.parent(selector.dropdown).length > 0) {
  4086. module.debug('UI dropdown already exists. Creating dropdown menu only');
  4087. $module = $input.closest(selector.dropdown);
  4088. if( !module.has.menu() ) {
  4089. module.create.menu();
  4090. }
  4091. $menu = $module.children(selector.menu);
  4092. module.setup.menu(selectValues);
  4093. }
  4094. else {
  4095. module.debug('Creating entire dropdown from select');
  4096. $module = $('<div />')
  4097. .attr('class', $input.attr('class') )
  4098. .addClass(className.selection)
  4099. .addClass(className.dropdown)
  4100. .html( templates.dropdown(selectValues) )
  4101. .insertBefore($input)
  4102. ;
  4103. if($input.hasClass(className.multiple) && $input.prop('multiple') === false) {
  4104. module.error(error.missingMultiple);
  4105. $input.prop('multiple', true);
  4106. }
  4107. if($input.is('[multiple]')) {
  4108. module.set.multiple();
  4109. }
  4110. if ($input.prop('disabled')) {
  4111. module.debug('Disabling dropdown')
  4112. $module.addClass(className.disabled)
  4113. }
  4114. $input
  4115. .removeAttr('class')
  4116. .detach()
  4117. .prependTo($module)
  4118. ;
  4119. }
  4120. module.refresh();
  4121. },
  4122. menu: function(values) {
  4123. $menu.html( templates.menu(values, fields));
  4124. $item = $menu.find(selector.item);
  4125. },
  4126. reference: function() {
  4127. module.debug('Dropdown behavior was called on select, replacing with closest dropdown');
  4128. // replace module reference
  4129. $module = $module.parent(selector.dropdown);
  4130. module.refresh();
  4131. module.setup.returnedObject();
  4132. // invoke method in context of current instance
  4133. if(methodInvoked) {
  4134. instance = module;
  4135. module.invoke(query);
  4136. }
  4137. },
  4138. returnedObject: function() {
  4139. var
  4140. $firstModules = $allModules.slice(0, elementIndex),
  4141. $lastModules = $allModules.slice(elementIndex + 1)
  4142. ;
  4143. // adjust all modules to use correct reference
  4144. $allModules = $firstModules.add($module).add($lastModules);
  4145. }
  4146. },
  4147. refresh: function() {
  4148. module.refreshSelectors();
  4149. module.refreshData();
  4150. },
  4151. refreshSelectors: function() {
  4152. module.verbose('Refreshing selector cache');
  4153. $text = $module.find(selector.text);
  4154. $search = $module.find(selector.search);
  4155. $input = $module.find(selector.input);
  4156. $icon = $module.find(selector.icon);
  4157. $combo = ($module.prev().find(selector.text).length > 0)
  4158. ? $module.prev().find(selector.text)
  4159. : $module.prev()
  4160. ;
  4161. $menu = $module.children(selector.menu);
  4162. $item = $menu.find(selector.item);
  4163. },
  4164. refreshData: function() {
  4165. module.verbose('Refreshing cached metadata');
  4166. $item
  4167. .removeData(metadata.text)
  4168. .removeData(metadata.value)
  4169. ;
  4170. $module
  4171. .removeData(metadata.defaultText)
  4172. .removeData(metadata.defaultValue)
  4173. .removeData(metadata.placeholderText)
  4174. ;
  4175. },
  4176. toggle: function() {
  4177. module.verbose('Toggling menu visibility');
  4178. if( !module.is.active() ) {
  4179. module.show();
  4180. }
  4181. else {
  4182. module.hide();
  4183. }
  4184. },
  4185. show: function(callback) {
  4186. callback = $.isFunction(callback)
  4187. ? callback
  4188. : function(){}
  4189. ;
  4190. if( module.can.show() && !module.is.active() ) {
  4191. module.debug('Showing dropdown');
  4192. if(module.is.multiple() && !module.has.search() && module.is.allFiltered()) {
  4193. return true;
  4194. }
  4195. if(module.has.message() && !module.has.maxSelections()) {
  4196. module.remove.message();
  4197. }
  4198. if(settings.onShow.call(element) !== false) {
  4199. module.animate.show(function() {
  4200. if( module.can.click() ) {
  4201. module.bind.intent();
  4202. }
  4203. module.set.visible();
  4204. callback.call(element);
  4205. });
  4206. }
  4207. }
  4208. },
  4209. hide: function(callback) {
  4210. callback = $.isFunction(callback)
  4211. ? callback
  4212. : function(){}
  4213. ;
  4214. if( module.is.active() ) {
  4215. module.debug('Hiding dropdown');
  4216. if(settings.onHide.call(element) !== false) {
  4217. module.animate.hide(function() {
  4218. module.remove.visible();
  4219. callback.call(element);
  4220. });
  4221. }
  4222. }
  4223. },
  4224. hideOthers: function() {
  4225. module.verbose('Finding other dropdowns to hide');
  4226. $allModules
  4227. .not($module)
  4228. .has(selector.menu + '.' + className.visible)
  4229. .dropdown('hide')
  4230. ;
  4231. },
  4232. hideMenu: function() {
  4233. module.verbose('Hiding menu instantaneously');
  4234. module.remove.active();
  4235. module.remove.visible();
  4236. $menu.transition('hide');
  4237. },
  4238. hideSubMenus: function() {
  4239. var
  4240. $subMenus = $menu.children(selector.item).find(selector.menu)
  4241. ;
  4242. module.verbose('Hiding sub menus', $subMenus);
  4243. $subMenus.transition('hide');
  4244. },
  4245. bind: {
  4246. events: function() {
  4247. if(hasTouch) {
  4248. module.bind.touchEvents();
  4249. }
  4250. module.bind.keyboardEvents();
  4251. module.bind.inputEvents();
  4252. module.bind.mouseEvents();
  4253. },
  4254. touchEvents: function() {
  4255. module.debug('Touch device detected binding additional touch events');
  4256. if( module.is.searchSelection() ) {
  4257. // do nothing special yet
  4258. }
  4259. else if( module.is.single() ) {
  4260. $module
  4261. .on('touchstart' + eventNamespace, module.event.test.toggle)
  4262. ;
  4263. }
  4264. $menu
  4265. .on('touchstart' + eventNamespace, selector.item, module.event.item.mouseenter)
  4266. ;
  4267. },
  4268. keyboardEvents: function() {
  4269. module.verbose('Binding keyboard events');
  4270. $module
  4271. .on('keydown' + eventNamespace, module.event.keydown)
  4272. ;
  4273. if( module.has.search() ) {
  4274. $module
  4275. .on(module.get.inputEvent() + eventNamespace, selector.search, module.event.input)
  4276. ;
  4277. }
  4278. if( module.is.multiple() ) {
  4279. $document
  4280. .on('keydown' + elementNamespace, module.event.document.keydown)
  4281. ;
  4282. }
  4283. },
  4284. inputEvents: function() {
  4285. module.verbose('Binding input change events');
  4286. $module
  4287. .on('change' + eventNamespace, selector.input, module.event.change)
  4288. ;
  4289. },
  4290. mouseEvents: function() {
  4291. module.verbose('Binding mouse events');
  4292. if(module.is.multiple()) {
  4293. $module
  4294. .on('click' + eventNamespace, selector.label, module.event.label.click)
  4295. .on('click' + eventNamespace, selector.remove, module.event.remove.click)
  4296. ;
  4297. }
  4298. if( module.is.searchSelection() ) {
  4299. $module
  4300. .on('mousedown' + eventNamespace, selector.menu, module.event.menu.mousedown)
  4301. .on('mouseup' + eventNamespace, selector.menu, module.event.menu.mouseup)
  4302. .on('click' + eventNamespace, selector.icon, module.event.icon.click)
  4303. .on('click' + eventNamespace, selector.search, module.show)
  4304. .on('focus' + eventNamespace, selector.search, module.event.search.focus)
  4305. .on('blur' + eventNamespace, selector.search, module.event.search.blur)
  4306. .on('click' + eventNamespace, selector.text, module.event.text.focus)
  4307. ;
  4308. if(module.is.multiple()) {
  4309. $module
  4310. .on('click' + eventNamespace, module.event.click)
  4311. ;
  4312. }
  4313. }
  4314. else {
  4315. if(settings.on == 'click') {
  4316. $module
  4317. .on('click' + eventNamespace, selector.icon, module.event.icon.click)
  4318. .on('click' + eventNamespace, module.event.test.toggle)
  4319. ;
  4320. }
  4321. else if(settings.on == 'hover') {
  4322. $module
  4323. .on('mouseenter' + eventNamespace, module.delay.show)
  4324. .on('mouseleave' + eventNamespace, module.delay.hide)
  4325. ;
  4326. }
  4327. else {
  4328. $module
  4329. .on(settings.on + eventNamespace, module.toggle)
  4330. ;
  4331. }
  4332. $module
  4333. .on('mousedown' + eventNamespace, module.event.mousedown)
  4334. .on('mouseup' + eventNamespace, module.event.mouseup)
  4335. .on('focus' + eventNamespace, module.event.focus)
  4336. .on('blur' + eventNamespace, module.event.blur)
  4337. ;
  4338. }
  4339. $menu
  4340. .on('mouseenter' + eventNamespace, selector.item, module.event.item.mouseenter)
  4341. .on('mouseleave' + eventNamespace, selector.item, module.event.item.mouseleave)
  4342. .on('click' + eventNamespace, selector.item, module.event.item.click)
  4343. ;
  4344. },
  4345. intent: function() {
  4346. module.verbose('Binding hide intent event to document');
  4347. if(hasTouch) {
  4348. $document
  4349. .on('touchstart' + elementNamespace, module.event.test.touch)
  4350. .on('touchmove' + elementNamespace, module.event.test.touch)
  4351. ;
  4352. }
  4353. $document
  4354. .on('click' + elementNamespace, module.event.test.hide)
  4355. ;
  4356. }
  4357. },
  4358. unbind: {
  4359. intent: function() {
  4360. module.verbose('Removing hide intent event from document');
  4361. if(hasTouch) {
  4362. $document
  4363. .off('touchstart' + elementNamespace)
  4364. .off('touchmove' + elementNamespace)
  4365. ;
  4366. }
  4367. $document
  4368. .off('click' + elementNamespace)
  4369. ;
  4370. }
  4371. },
  4372. filter: function(query) {
  4373. var
  4374. searchTerm = (query !== undefined)
  4375. ? query
  4376. : module.get.query(),
  4377. afterFiltered = function() {
  4378. if(module.is.multiple()) {
  4379. module.filterActive();
  4380. }
  4381. module.select.firstUnfiltered();
  4382. if( module.has.allResultsFiltered() ) {
  4383. if( settings.onNoResults.call(element, searchTerm) ) {
  4384. if(!settings.allowAdditions) {
  4385. module.verbose('All items filtered, showing message', searchTerm);
  4386. module.add.message(message.noResults);
  4387. }
  4388. }
  4389. else {
  4390. module.verbose('All items filtered, hiding dropdown', searchTerm);
  4391. module.hideMenu();
  4392. }
  4393. }
  4394. else {
  4395. module.remove.message();
  4396. }
  4397. if(settings.allowAdditions) {
  4398. module.add.userSuggestion(query);
  4399. }
  4400. if(module.is.searchSelection() && module.can.show() && module.is.focusedOnSearch() ) {
  4401. module.show();
  4402. }
  4403. }
  4404. ;
  4405. if(settings.useLabels && module.has.maxSelections()) {
  4406. return;
  4407. }
  4408. if(settings.apiSettings) {
  4409. if( module.can.useAPI() ) {
  4410. module.queryRemote(searchTerm, function() {
  4411. afterFiltered();
  4412. });
  4413. }
  4414. else {
  4415. module.error(error.noAPI);
  4416. }
  4417. }
  4418. else {
  4419. module.filterItems(searchTerm);
  4420. afterFiltered();
  4421. }
  4422. },
  4423. queryRemote: function(query, callback) {
  4424. var
  4425. apiSettings = {
  4426. errorDuration : false,
  4427. throttle : settings.throttle,
  4428. urlData : {
  4429. query: query
  4430. },
  4431. onError: function() {
  4432. module.add.message(message.serverError);
  4433. callback();
  4434. },
  4435. onFailure: function() {
  4436. module.add.message(message.serverError);
  4437. callback();
  4438. },
  4439. onSuccess : function(response) {
  4440. module.remove.message();
  4441. module.setup.menu({
  4442. values: response.results
  4443. });
  4444. callback();
  4445. }
  4446. }
  4447. ;
  4448. if( !$module.api('get request') ) {
  4449. module.setup.api();
  4450. }
  4451. apiSettings = $.extend(true, {}, apiSettings, settings.apiSettings);
  4452. $module
  4453. .api('setting', apiSettings)
  4454. .api('query')
  4455. ;
  4456. },
  4457. filterItems: function(query) {
  4458. var
  4459. searchTerm = (query !== undefined)
  4460. ? query
  4461. : module.get.query(),
  4462. $results = $(),
  4463. escapedTerm = module.escape.regExp(searchTerm),
  4464. beginsWithRegExp = new RegExp('^' + escapedTerm, 'igm')
  4465. ;
  4466. // avoid loop if we're matching nothing
  4467. if( !module.has.query() ) {
  4468. $results = $item;
  4469. }
  4470. else {
  4471. module.verbose('Searching for matching values', searchTerm);
  4472. $item
  4473. .each(function(){
  4474. var
  4475. $choice = $(this),
  4476. text,
  4477. value
  4478. ;
  4479. if(settings.match == 'both' || settings.match == 'text') {
  4480. text = String(module.get.choiceText($choice, false));
  4481. if(text.search(beginsWithRegExp) !== -1) {
  4482. $results = $results.add($choice);
  4483. return true;
  4484. }
  4485. else if(settings.fullTextSearch && module.fuzzySearch(searchTerm, text)) {
  4486. $results = $results.add($choice);
  4487. return true;
  4488. }
  4489. }
  4490. if(settings.match == 'both' || settings.match == 'value') {
  4491. value = String(module.get.choiceValue($choice, text));
  4492. if(value.search(beginsWithRegExp) !== -1) {
  4493. $results = $results.add($choice);
  4494. return true;
  4495. }
  4496. else if(settings.fullTextSearch && module.fuzzySearch(searchTerm, value)) {
  4497. $results = $results.add($choice);
  4498. return true;
  4499. }
  4500. }
  4501. })
  4502. ;
  4503. }
  4504. module.debug('Showing only matched items', searchTerm);
  4505. module.remove.filteredItem();
  4506. $item
  4507. .not($results)
  4508. .addClass(className.filtered)
  4509. ;
  4510. },
  4511. fuzzySearch: function(query, term) {
  4512. var
  4513. termLength = term.length,
  4514. queryLength = query.length
  4515. ;
  4516. query = query.toLowerCase();
  4517. term = term.toLowerCase();
  4518. if(queryLength > termLength) {
  4519. return false;
  4520. }
  4521. if(queryLength === termLength) {
  4522. return (query === term);
  4523. }
  4524. search: for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) {
  4525. var
  4526. queryCharacter = query.charCodeAt(characterIndex)
  4527. ;
  4528. while(nextCharacterIndex < termLength) {
  4529. if(term.charCodeAt(nextCharacterIndex++) === queryCharacter) {
  4530. continue search;
  4531. }
  4532. }
  4533. return false;
  4534. }
  4535. return true;
  4536. },
  4537. filterActive: function() {
  4538. if(settings.useLabels) {
  4539. $item.filter('.' + className.active)
  4540. .addClass(className.filtered)
  4541. ;
  4542. }
  4543. },
  4544. focusSearch: function() {
  4545. if( module.is.search() && !module.is.focusedOnSearch() ) {
  4546. $search[0].focus();
  4547. }
  4548. },
  4549. forceSelection: function() {
  4550. var
  4551. $currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0),
  4552. $activeItem = $item.not(className.filtered).filter('.' + className.active).eq(0),
  4553. $selectedItem = ($currentlySelected.length > 0)
  4554. ? $currentlySelected
  4555. : $activeItem,
  4556. hasSelected = ($selectedItem.size() > 0)
  4557. ;
  4558. if( hasSelected && module.has.query() ) {
  4559. module.debug('Forcing partial selection to selected item', $selectedItem);
  4560. module.event.item.click.call($selectedItem);
  4561. }
  4562. else {
  4563. module.hide();
  4564. }
  4565. },
  4566. event: {
  4567. change: function() {
  4568. if(!internalChange) {
  4569. module.debug('Input changed, updating selection');
  4570. module.set.selected();
  4571. }
  4572. },
  4573. focus: function() {
  4574. if(settings.showOnFocus && !activated && module.is.hidden() && !pageLostFocus) {
  4575. module.show();
  4576. }
  4577. },
  4578. click: function(event) {
  4579. var
  4580. $target = $(event.target)
  4581. ;
  4582. // focus search
  4583. if($target.is($module) && !module.is.focusedOnSearch()) {
  4584. module.focusSearch();
  4585. }
  4586. },
  4587. blur: function(event) {
  4588. pageLostFocus = (document.activeElement === this);
  4589. if(!activated && !pageLostFocus) {
  4590. module.remove.activeLabel();
  4591. module.hide();
  4592. }
  4593. },
  4594. // prevents focus callback from occurring on mousedown
  4595. mousedown: function() {
  4596. activated = true;
  4597. },
  4598. mouseup: function() {
  4599. activated = false;
  4600. },
  4601. search: {
  4602. focus: function() {
  4603. activated = true;
  4604. if(module.is.multiple()) {
  4605. module.remove.activeLabel();
  4606. }
  4607. if(settings.showOnFocus) {
  4608. module.show();
  4609. }
  4610. },
  4611. blur: function(event) {
  4612. pageLostFocus = (document.activeElement === this);
  4613. if(!itemActivated && !pageLostFocus) {
  4614. if(module.is.multiple()) {
  4615. module.remove.activeLabel();
  4616. module.hide();
  4617. }
  4618. else if(settings.forceSelection) {
  4619. module.forceSelection();
  4620. }
  4621. else {
  4622. module.hide();
  4623. }
  4624. }
  4625. else if(pageLostFocus) {
  4626. if(settings.forceSelection) {
  4627. module.forceSelection();
  4628. }
  4629. }
  4630. }
  4631. },
  4632. icon: {
  4633. click: function(event) {
  4634. module.toggle();
  4635. event.stopPropagation();
  4636. }
  4637. },
  4638. text: {
  4639. focus: function(event) {
  4640. activated = true;
  4641. module.focusSearch();
  4642. }
  4643. },
  4644. input: function(event) {
  4645. if(module.is.multiple() || module.is.searchSelection()) {
  4646. module.set.filtered();
  4647. }
  4648. clearTimeout(module.timer);
  4649. module.timer = setTimeout(module.search, settings.delay.search);
  4650. },
  4651. label: {
  4652. click: function(event) {
  4653. var
  4654. $label = $(this),
  4655. $labels = $module.find(selector.label),
  4656. $activeLabels = $labels.filter('.' + className.active),
  4657. $nextActive = $label.nextAll('.' + className.active),
  4658. $prevActive = $label.prevAll('.' + className.active),
  4659. $range = ($nextActive.length > 0)
  4660. ? $label.nextUntil($nextActive).add($activeLabels).add($label)
  4661. : $label.prevUntil($prevActive).add($activeLabels).add($label)
  4662. ;
  4663. if(event.shiftKey) {
  4664. $activeLabels.removeClass(className.active);
  4665. $range.addClass(className.active);
  4666. }
  4667. else if(event.ctrlKey) {
  4668. $label.toggleClass(className.active);
  4669. }
  4670. else {
  4671. $activeLabels.removeClass(className.active);
  4672. $label.addClass(className.active);
  4673. }
  4674. settings.onLabelSelect.apply(this, $labels.filter('.' + className.active));
  4675. }
  4676. },
  4677. remove: {
  4678. click: function() {
  4679. var
  4680. $label = $(this).parent()
  4681. ;
  4682. if( $label.hasClass(className.active) ) {
  4683. // remove all selected labels
  4684. module.remove.activeLabels();
  4685. }
  4686. else {
  4687. // remove this label only
  4688. module.remove.activeLabels( $label );
  4689. }
  4690. }
  4691. },
  4692. test: {
  4693. toggle: function(event) {
  4694. var
  4695. toggleBehavior = (module.is.multiple())
  4696. ? module.show
  4697. : module.toggle
  4698. ;
  4699. if( module.determine.eventOnElement(event, toggleBehavior) ) {
  4700. event.preventDefault();
  4701. }
  4702. },
  4703. touch: function(event) {
  4704. module.determine.eventOnElement(event, function() {
  4705. if(event.type == 'touchstart') {
  4706. module.timer = setTimeout(function() {
  4707. module.hide();
  4708. }, settings.delay.touch);
  4709. }
  4710. else if(event.type == 'touchmove') {
  4711. clearTimeout(module.timer);
  4712. }
  4713. });
  4714. event.stopPropagation();
  4715. },
  4716. hide: function(event) {
  4717. module.determine.eventInModule(event, module.hide);
  4718. }
  4719. },
  4720. menu: {
  4721. mousedown: function() {
  4722. itemActivated = true;
  4723. },
  4724. mouseup: function() {
  4725. itemActivated = false;
  4726. }
  4727. },
  4728. item: {
  4729. mouseenter: function(event) {
  4730. var
  4731. $subMenu = $(this).children(selector.menu),
  4732. $otherMenus = $(this).siblings(selector.item).children(selector.menu)
  4733. ;
  4734. if( $subMenu.length > 0 ) {
  4735. clearTimeout(module.itemTimer);
  4736. module.itemTimer = setTimeout(function() {
  4737. module.verbose('Showing sub-menu', $subMenu);
  4738. $.each($otherMenus, function() {
  4739. module.animate.hide(false, $(this));
  4740. });
  4741. module.animate.show(false, $subMenu);
  4742. }, settings.delay.show);
  4743. event.preventDefault();
  4744. }
  4745. },
  4746. mouseleave: function(event) {
  4747. var
  4748. $subMenu = $(this).children(selector.menu)
  4749. ;
  4750. if($subMenu.length > 0) {
  4751. clearTimeout(module.itemTimer);
  4752. module.itemTimer = setTimeout(function() {
  4753. module.verbose('Hiding sub-menu', $subMenu);
  4754. module.animate.hide(false, $subMenu);
  4755. }, settings.delay.hide);
  4756. }
  4757. },
  4758. touchend: function() {
  4759. },
  4760. click: function (event) {
  4761. var
  4762. $choice = $(this),
  4763. $target = (event)
  4764. ? $(event.target)
  4765. : $(''),
  4766. $subMenu = $choice.find(selector.menu),
  4767. text = module.get.choiceText($choice),
  4768. value = module.get.choiceValue($choice, text),
  4769. hasSubMenu = ($subMenu.length > 0),
  4770. isBubbledEvent = ($subMenu.find($target).length > 0)
  4771. ;
  4772. if(!isBubbledEvent && (!hasSubMenu || settings.allowCategorySelection)) {
  4773. if(!settings.useLabels) {
  4774. module.remove.filteredItem();
  4775. module.remove.searchTerm();
  4776. module.set.scrollPosition($choice);
  4777. }
  4778. module.determine.selectAction.call(this, text, value);
  4779. }
  4780. }
  4781. },
  4782. document: {
  4783. // label selection should occur even when element has no focus
  4784. keydown: function(event) {
  4785. var
  4786. pressedKey = event.which,
  4787. keys = module.get.shortcutKeys(),
  4788. isShortcutKey = module.is.inObject(pressedKey, keys)
  4789. ;
  4790. if(isShortcutKey) {
  4791. var
  4792. $label = $module.find(selector.label),
  4793. $activeLabel = $label.filter('.' + className.active),
  4794. activeValue = $activeLabel.data(metadata.value),
  4795. labelIndex = $label.index($activeLabel),
  4796. labelCount = $label.length,
  4797. hasActiveLabel = ($activeLabel.length > 0),
  4798. hasMultipleActive = ($activeLabel.length > 1),
  4799. isFirstLabel = (labelIndex === 0),
  4800. isLastLabel = (labelIndex + 1 == labelCount),
  4801. isSearch = module.is.searchSelection(),
  4802. isFocusedOnSearch = module.is.focusedOnSearch(),
  4803. isFocused = module.is.focused(),
  4804. caretAtStart = (isFocusedOnSearch && module.get.caretPosition() === 0),
  4805. $nextLabel
  4806. ;
  4807. if(isSearch && !hasActiveLabel && !isFocusedOnSearch) {
  4808. return;
  4809. }
  4810. if(pressedKey == keys.leftArrow) {
  4811. // activate previous label
  4812. if((isFocused || caretAtStart) && !hasActiveLabel) {
  4813. module.verbose('Selecting previous label');
  4814. $label.last().addClass(className.active);
  4815. }
  4816. else if(hasActiveLabel) {
  4817. if(!event.shiftKey) {
  4818. module.verbose('Selecting previous label');
  4819. $label.removeClass(className.active);
  4820. }
  4821. else {
  4822. module.verbose('Adding previous label to selection');
  4823. }
  4824. if(isFirstLabel && !hasMultipleActive) {
  4825. $activeLabel.addClass(className.active);
  4826. }
  4827. else {
  4828. $activeLabel.prev(selector.siblingLabel)
  4829. .addClass(className.active)
  4830. .end()
  4831. ;
  4832. }
  4833. event.preventDefault();
  4834. }
  4835. }
  4836. else if(pressedKey == keys.rightArrow) {
  4837. // activate first label
  4838. if(isFocused && !hasActiveLabel) {
  4839. $label.first().addClass(className.active);
  4840. }
  4841. // activate next label
  4842. if(hasActiveLabel) {
  4843. if(!event.shiftKey) {
  4844. module.verbose('Selecting next label');
  4845. $label.removeClass(className.active);
  4846. }
  4847. else {
  4848. module.verbose('Adding next label to selection');
  4849. }
  4850. if(isLastLabel) {
  4851. if(isSearch) {
  4852. if(!isFocusedOnSearch) {
  4853. module.focusSearch();
  4854. }
  4855. else {
  4856. $label.removeClass(className.active);
  4857. }
  4858. }
  4859. else if(hasMultipleActive) {
  4860. $activeLabel.next(selector.siblingLabel).addClass(className.active);
  4861. }
  4862. else {
  4863. $activeLabel.addClass(className.active);
  4864. }
  4865. }
  4866. else {
  4867. $activeLabel.next(selector.siblingLabel).addClass(className.active);
  4868. }
  4869. event.preventDefault();
  4870. }
  4871. }
  4872. else if(pressedKey == keys.deleteKey || pressedKey == keys.backspace) {
  4873. if(hasActiveLabel) {
  4874. module.verbose('Removing active labels');
  4875. if(isLastLabel) {
  4876. if(isSearch && !isFocusedOnSearch) {
  4877. module.focusSearch();
  4878. }
  4879. }
  4880. $activeLabel.last().next(selector.siblingLabel).addClass(className.active);
  4881. module.remove.activeLabels($activeLabel);
  4882. event.preventDefault();
  4883. }
  4884. else if(caretAtStart && !hasActiveLabel && pressedKey == keys.backspace) {
  4885. module.verbose('Removing last label on input backspace');
  4886. $activeLabel = $label.last().addClass(className.active);
  4887. module.remove.activeLabels($activeLabel);
  4888. }
  4889. }
  4890. else {
  4891. $activeLabel.removeClass(className.active);
  4892. }
  4893. }
  4894. }
  4895. },
  4896. keydown: function(event) {
  4897. var
  4898. pressedKey = event.which,
  4899. keys = module.get.shortcutKeys(),
  4900. isShortcutKey = module.is.inObject(pressedKey, keys)
  4901. ;
  4902. if(isShortcutKey) {
  4903. var
  4904. $currentlySelected = $item.not(selector.unselectable).filter('.' + className.selected).eq(0),
  4905. $activeItem = $menu.children('.' + className.active).eq(0),
  4906. $selectedItem = ($currentlySelected.length > 0)
  4907. ? $currentlySelected
  4908. : $activeItem,
  4909. $visibleItems = ($selectedItem.length > 0)
  4910. ? $selectedItem.siblings(':not(.' + className.filtered +')').andSelf()
  4911. : $menu.children(':not(.' + className.filtered +')'),
  4912. $subMenu = $selectedItem.children(selector.menu),
  4913. $parentMenu = $selectedItem.closest(selector.menu),
  4914. inVisibleMenu = ($parentMenu.hasClass(className.visible) || $parentMenu.hasClass(className.animating) || $parentMenu.parent(selector.menu).length > 0),
  4915. hasSubMenu = ($subMenu.length> 0),
  4916. hasSelectedItem = ($selectedItem.length > 0),
  4917. selectedIsSelectable = ($selectedItem.not(selector.unselectable).length > 0),
  4918. delimiterPressed = (pressedKey == keys.delimiter && settings.allowAdditions && module.is.multiple()),
  4919. $nextItem,
  4920. isSubMenuItem,
  4921. newIndex
  4922. ;
  4923. // visible menu keyboard shortcuts
  4924. if( module.is.visible() ) {
  4925. // enter (select or open sub-menu)
  4926. if(pressedKey == keys.enter || delimiterPressed) {
  4927. if(pressedKey == keys.enter && hasSelectedItem && hasSubMenu && !settings.allowCategorySelection) {
  4928. module.verbose('Pressed enter on unselectable category, opening sub menu');
  4929. pressedKey = keys.rightArrow;
  4930. }
  4931. else if(selectedIsSelectable) {
  4932. module.verbose('Selecting item from keyboard shortcut', $selectedItem);
  4933. module.event.item.click.call($selectedItem, event);
  4934. if(module.is.searchSelection()) {
  4935. module.remove.searchTerm();
  4936. }
  4937. }
  4938. event.preventDefault();
  4939. }
  4940. // left arrow (hide sub-menu)
  4941. if(pressedKey == keys.leftArrow) {
  4942. isSubMenuItem = ($parentMenu[0] !== $menu[0]);
  4943. if(isSubMenuItem) {
  4944. module.verbose('Left key pressed, closing sub-menu');
  4945. module.animate.hide(false, $parentMenu);
  4946. $selectedItem
  4947. .removeClass(className.selected)
  4948. ;
  4949. $parentMenu
  4950. .closest(selector.item)
  4951. .addClass(className.selected)
  4952. ;
  4953. event.preventDefault();
  4954. }
  4955. }
  4956. // right arrow (show sub-menu)
  4957. if(pressedKey == keys.rightArrow) {
  4958. if(hasSubMenu) {
  4959. module.verbose('Right key pressed, opening sub-menu');
  4960. module.animate.show(false, $subMenu);
  4961. $selectedItem
  4962. .removeClass(className.selected)
  4963. ;
  4964. $subMenu
  4965. .find(selector.item).eq(0)
  4966. .addClass(className.selected)
  4967. ;
  4968. event.preventDefault();
  4969. }
  4970. }
  4971. // up arrow (traverse menu up)
  4972. if(pressedKey == keys.upArrow) {
  4973. $nextItem = (hasSelectedItem && inVisibleMenu)
  4974. ? $selectedItem.prevAll(selector.item + ':not(' + selector.unselectable + ')').eq(0)
  4975. : $item.eq(0)
  4976. ;
  4977. if($visibleItems.index( $nextItem ) < 0) {
  4978. module.verbose('Up key pressed but reached top of current menu');
  4979. event.preventDefault();
  4980. return;
  4981. }
  4982. else {
  4983. module.verbose('Up key pressed, changing active item');
  4984. $selectedItem
  4985. .removeClass(className.selected)
  4986. ;
  4987. $nextItem
  4988. .addClass(className.selected)
  4989. ;
  4990. module.set.scrollPosition($nextItem);
  4991. }
  4992. event.preventDefault();
  4993. }
  4994. // down arrow (traverse menu down)
  4995. if(pressedKey == keys.downArrow) {
  4996. $nextItem = (hasSelectedItem && inVisibleMenu)
  4997. ? $nextItem = $selectedItem.nextAll(selector.item + ':not(' + selector.unselectable + ')').eq(0)
  4998. : $item.eq(0)
  4999. ;
  5000. if($nextItem.length === 0) {
  5001. module.verbose('Down key pressed but reached bottom of current menu');
  5002. event.preventDefault();
  5003. return;
  5004. }
  5005. else {
  5006. module.verbose('Down key pressed, changing active item');
  5007. $item
  5008. .removeClass(className.selected)
  5009. ;
  5010. $nextItem
  5011. .addClass(className.selected)
  5012. ;
  5013. module.set.scrollPosition($nextItem);
  5014. }
  5015. event.preventDefault();
  5016. }
  5017. // page down (show next page)
  5018. if(pressedKey == keys.pageUp) {
  5019. module.scrollPage('up');
  5020. event.preventDefault();
  5021. }
  5022. if(pressedKey == keys.pageDown) {
  5023. module.scrollPage('down');
  5024. event.preventDefault();
  5025. }
  5026. // escape (close menu)
  5027. if(pressedKey == keys.escape) {
  5028. module.verbose('Escape key pressed, closing dropdown');
  5029. module.hide();
  5030. }
  5031. }
  5032. else {
  5033. // delimiter key
  5034. if(delimiterPressed) {
  5035. event.preventDefault();
  5036. }
  5037. // down arrow (open menu)
  5038. if(pressedKey == keys.downArrow) {
  5039. module.verbose('Down key pressed, showing dropdown');
  5040. module.show();
  5041. event.preventDefault();
  5042. }
  5043. }
  5044. }
  5045. else {
  5046. if( module.is.selection() && !module.is.search() ) {
  5047. module.set.selectedLetter( String.fromCharCode(pressedKey) );
  5048. }
  5049. }
  5050. }
  5051. },
  5052. determine: {
  5053. selectAction: function(text, value) {
  5054. module.verbose('Determining action', settings.action);
  5055. if( $.isFunction( module.action[settings.action] ) ) {
  5056. module.verbose('Triggering preset action', settings.action, text, value);
  5057. module.action[ settings.action ].call(this, text, value);
  5058. }
  5059. else if( $.isFunction(settings.action) ) {
  5060. module.verbose('Triggering user action', settings.action, text, value);
  5061. settings.action.call(this, text, value);
  5062. }
  5063. else {
  5064. module.error(error.action, settings.action);
  5065. }
  5066. },
  5067. eventInModule: function(event, callback) {
  5068. var
  5069. $target = $(event.target),
  5070. inDocument = ($target.closest(document.documentElement).length > 0),
  5071. inModule = ($target.closest($module).length > 0)
  5072. ;
  5073. callback = $.isFunction(callback)
  5074. ? callback
  5075. : function(){}
  5076. ;
  5077. if(inDocument && !inModule) {
  5078. module.verbose('Triggering event', callback);
  5079. callback();
  5080. return true;
  5081. }
  5082. else {
  5083. module.verbose('Event occurred in dropdown, canceling callback');
  5084. return false;
  5085. }
  5086. },
  5087. eventOnElement: function(event, callback) {
  5088. var
  5089. $target = $(event.target),
  5090. $label = $target.closest(selector.siblingLabel),
  5091. notOnLabel = ($module.find($label).length === 0),
  5092. notInMenu = ($target.closest($menu).length === 0)
  5093. ;
  5094. callback = $.isFunction(callback)
  5095. ? callback
  5096. : function(){}
  5097. ;
  5098. if(notOnLabel && notInMenu) {
  5099. module.verbose('Triggering event', callback);
  5100. callback();
  5101. return true;
  5102. }
  5103. else {
  5104. module.verbose('Event occurred in dropdown menu, canceling callback');
  5105. return false;
  5106. }
  5107. }
  5108. },
  5109. action: {
  5110. nothing: function() {},
  5111. activate: function(text, value) {
  5112. value = (value !== undefined)
  5113. ? value
  5114. : text
  5115. ;
  5116. if( module.can.activate( $(this) ) ) {
  5117. module.set.selected(value, $(this));
  5118. if(module.is.multiple() && !module.is.allFiltered()) {
  5119. return;
  5120. }
  5121. else {
  5122. module.hideAndClear();
  5123. }
  5124. }
  5125. },
  5126. select: function(text, value) {
  5127. // mimics action.activate but does not select text
  5128. module.action.activate.call(this);
  5129. },
  5130. combo: function(text, value) {
  5131. value = (value !== undefined)
  5132. ? value
  5133. : text
  5134. ;
  5135. module.set.selected(value, $(this));
  5136. module.hideAndClear();
  5137. },
  5138. hide: function(text, value) {
  5139. module.set.value(value);
  5140. module.hideAndClear();
  5141. }
  5142. },
  5143. get: {
  5144. id: function() {
  5145. return id;
  5146. },
  5147. defaultText: function() {
  5148. return $module.data(metadata.defaultText);
  5149. },
  5150. defaultValue: function() {
  5151. return $module.data(metadata.defaultValue);
  5152. },
  5153. placeholderText: function() {
  5154. return $module.data(metadata.placeholderText) || '';
  5155. },
  5156. text: function() {
  5157. return $text.text();
  5158. },
  5159. query: function() {
  5160. return $.trim($search.val());
  5161. },
  5162. searchWidth: function(characterCount) {
  5163. return (characterCount * settings.glyphWidth) + 'em';
  5164. },
  5165. selectionCount: function() {
  5166. var
  5167. values = module.get.values(),
  5168. count
  5169. ;
  5170. count = ( module.is.multiple() )
  5171. ? $.isArray(values)
  5172. ? values.length
  5173. : 0
  5174. : (module.get.value() !== '')
  5175. ? 1
  5176. : 0
  5177. ;
  5178. return count;
  5179. },
  5180. transition: function($subMenu) {
  5181. return (settings.transition == 'auto')
  5182. ? module.is.upward($subMenu)
  5183. ? 'slide up'
  5184. : 'slide down'
  5185. : settings.transition
  5186. ;
  5187. },
  5188. userValues: function() {
  5189. var
  5190. values = module.get.values()
  5191. ;
  5192. if(!values) {
  5193. return false;
  5194. }
  5195. values = $.isArray(values)
  5196. ? values
  5197. : [values]
  5198. ;
  5199. return $.grep(values, function(value) {
  5200. return (module.get.item(value) === false);
  5201. });
  5202. },
  5203. uniqueArray: function(array) {
  5204. return $.grep(array, function (value, index) {
  5205. return $.inArray(value, array) === index;
  5206. });
  5207. },
  5208. caretPosition: function() {
  5209. var
  5210. input = $search.get(0),
  5211. range,
  5212. rangeLength
  5213. ;
  5214. if('selectionStart' in input) {
  5215. return input.selectionStart;
  5216. }
  5217. else if (document.selection) {
  5218. input.focus();
  5219. range = document.selection.createRange();
  5220. rangeLength = range.text.length;
  5221. range.moveStart('character', -input.value.length);
  5222. return range.text.length - rangeLength;
  5223. }
  5224. },
  5225. shortcutKeys: function() {
  5226. return {
  5227. backspace : 8,
  5228. delimiter : 188, // comma
  5229. deleteKey : 46,
  5230. enter : 13,
  5231. escape : 27,
  5232. pageUp : 33,
  5233. pageDown : 34,
  5234. leftArrow : 37,
  5235. upArrow : 38,
  5236. rightArrow : 39,
  5237. downArrow : 40
  5238. };
  5239. },
  5240. value: function() {
  5241. var
  5242. value = ($input.length > 0)
  5243. ? $input.val()
  5244. : $module.data(metadata.value)
  5245. ;
  5246. // prevents placeholder element from being selected when multiple
  5247. if($.isArray(value) && value.length === 1 && value[0] === '') {
  5248. return '';
  5249. }
  5250. return value;
  5251. },
  5252. values: function() {
  5253. var
  5254. value = module.get.value()
  5255. ;
  5256. if(value === '') {
  5257. return '';
  5258. }
  5259. return ( !module.has.selectInput() && module.is.multiple() )
  5260. ? (typeof value == 'string') // delimited string
  5261. ? value.split(settings.delimiter)
  5262. : ''
  5263. : value
  5264. ;
  5265. },
  5266. remoteValues: function() {
  5267. var
  5268. values = module.get.values(),
  5269. remoteValues = false
  5270. ;
  5271. if(values) {
  5272. if(typeof values == 'string') {
  5273. values = [values];
  5274. }
  5275. remoteValues = {};
  5276. $.each(values, function(index, value) {
  5277. var
  5278. name = module.read.remoteData(value)
  5279. ;
  5280. module.verbose('Restoring value from session data', name, value);
  5281. remoteValues[value] = (name)
  5282. ? name
  5283. : value
  5284. ;
  5285. });
  5286. }
  5287. return remoteValues;
  5288. },
  5289. choiceText: function($choice, preserveHTML) {
  5290. preserveHTML = (preserveHTML !== undefined)
  5291. ? preserveHTML
  5292. : settings.preserveHTML
  5293. ;
  5294. if($choice) {
  5295. if($choice.find(selector.menu).length > 0) {
  5296. module.verbose('Retreiving text of element with sub-menu');
  5297. $choice = $choice.clone();
  5298. $choice.find(selector.menu).remove();
  5299. $choice.find(selector.menuIcon).remove();
  5300. }
  5301. return ($choice.data(metadata.text) !== undefined)
  5302. ? $choice.data(metadata.text)
  5303. : (preserveHTML)
  5304. ? $.trim($choice.html())
  5305. : $.trim($choice.text())
  5306. ;
  5307. }
  5308. },
  5309. choiceValue: function($choice, choiceText) {
  5310. choiceText = choiceText || module.get.choiceText($choice);
  5311. if(!$choice) {
  5312. return false;
  5313. }
  5314. return ($choice.data(metadata.value) !== undefined)
  5315. ? String( $choice.data(metadata.value) )
  5316. : (typeof choiceText === 'string')
  5317. ? $.trim(choiceText.toLowerCase())
  5318. : String(choiceText)
  5319. ;
  5320. },
  5321. inputEvent: function() {
  5322. var
  5323. input = $search[0]
  5324. ;
  5325. if(input) {
  5326. return (input.oninput !== undefined)
  5327. ? 'input'
  5328. : (input.onpropertychange !== undefined)
  5329. ? 'propertychange'
  5330. : 'keyup'
  5331. ;
  5332. }
  5333. return false;
  5334. },
  5335. selectValues: function() {
  5336. var
  5337. select = {}
  5338. ;
  5339. select.values = [];
  5340. $module
  5341. .find('option')
  5342. .each(function() {
  5343. var
  5344. $option = $(this),
  5345. name = $option.html(),
  5346. disabled = $option.attr('disabled'),
  5347. value = ( $option.attr('value') !== undefined )
  5348. ? $option.attr('value')
  5349. : name
  5350. ;
  5351. if(settings.placeholder === 'auto' && value === '') {
  5352. select.placeholder = name;
  5353. }
  5354. else {
  5355. select.values.push({
  5356. name : name,
  5357. value : value,
  5358. disabled : disabled
  5359. });
  5360. }
  5361. })
  5362. ;
  5363. if(settings.placeholder && settings.placeholder !== 'auto') {
  5364. module.debug('Setting placeholder value to', settings.placeholder);
  5365. select.placeholder = settings.placeholder;
  5366. }
  5367. if(settings.sortSelect) {
  5368. select.values.sort(function(a, b) {
  5369. return (a.name > b.name)
  5370. ? 1
  5371. : -1
  5372. ;
  5373. });
  5374. module.debug('Retrieved and sorted values from select', select);
  5375. }
  5376. else {
  5377. module.debug('Retreived values from select', select);
  5378. }
  5379. return select;
  5380. },
  5381. activeItem: function() {
  5382. return $item.filter('.' + className.active);
  5383. },
  5384. selectedItem: function() {
  5385. var
  5386. $selectedItem = $item.not(selector.unselectable).filter('.' + className.selected)
  5387. ;
  5388. return ($selectedItem.length > 0)
  5389. ? $selectedItem
  5390. : $item.eq(0)
  5391. ;
  5392. },
  5393. itemWithAdditions: function(value) {
  5394. var
  5395. $items = module.get.item(value),
  5396. $userItems = module.create.userChoice(value),
  5397. hasUserItems = ($userItems && $userItems.length > 0)
  5398. ;
  5399. if(hasUserItems) {
  5400. $items = ($items.length > 0)
  5401. ? $items.add($userItems)
  5402. : $userItems
  5403. ;
  5404. }
  5405. return $items;
  5406. },
  5407. item: function(value, strict) {
  5408. var
  5409. $selectedItem = false,
  5410. shouldSearch,
  5411. isMultiple
  5412. ;
  5413. value = (value !== undefined)
  5414. ? value
  5415. : ( module.get.values() !== undefined)
  5416. ? module.get.values()
  5417. : module.get.text()
  5418. ;
  5419. shouldSearch = (isMultiple)
  5420. ? (value.length > 0)
  5421. : (value !== undefined && value !== null)
  5422. ;
  5423. isMultiple = (module.is.multiple() && $.isArray(value));
  5424. strict = (value === '' || value === 0)
  5425. ? true
  5426. : strict || false
  5427. ;
  5428. if(shouldSearch) {
  5429. $item
  5430. .each(function() {
  5431. var
  5432. $choice = $(this),
  5433. optionText = module.get.choiceText($choice),
  5434. optionValue = module.get.choiceValue($choice, optionText)
  5435. ;
  5436. // safe early exit
  5437. if(optionValue === null || optionValue === undefined) {
  5438. return;
  5439. }
  5440. if(isMultiple) {
  5441. if($.inArray( String(optionValue), value) !== -1 || $.inArray(optionText, value) !== -1) {
  5442. $selectedItem = ($selectedItem)
  5443. ? $selectedItem.add($choice)
  5444. : $choice
  5445. ;
  5446. }
  5447. }
  5448. else if(strict) {
  5449. module.verbose('Ambiguous dropdown value using strict type check', $choice, value);
  5450. if( optionValue === value || optionText === value) {
  5451. $selectedItem = $choice;
  5452. return true;
  5453. }
  5454. }
  5455. else {
  5456. if( String(optionValue) == String(value) || optionText == value) {
  5457. module.verbose('Found select item by value', optionValue, value);
  5458. $selectedItem = $choice;
  5459. return true;
  5460. }
  5461. }
  5462. })
  5463. ;
  5464. }
  5465. return $selectedItem;
  5466. }
  5467. },
  5468. check: {
  5469. maxSelections: function(selectionCount) {
  5470. if(settings.maxSelections) {
  5471. selectionCount = (selectionCount !== undefined)
  5472. ? selectionCount
  5473. : module.get.selectionCount()
  5474. ;
  5475. if(selectionCount >= settings.maxSelections) {
  5476. module.debug('Maximum selection count reached');
  5477. if(settings.useLabels) {
  5478. $item.addClass(className.filtered);
  5479. module.add.message(message.maxSelections);
  5480. }
  5481. return true;
  5482. }
  5483. else {
  5484. module.verbose('No longer at maximum selection count');
  5485. module.remove.message();
  5486. module.remove.filteredItem();
  5487. if(module.is.searchSelection()) {
  5488. module.filterItems();
  5489. }
  5490. return false;
  5491. }
  5492. }
  5493. return true;
  5494. }
  5495. },
  5496. restore: {
  5497. defaults: function() {
  5498. module.clear();
  5499. module.restore.defaultText();
  5500. module.restore.defaultValue();
  5501. },
  5502. defaultText: function() {
  5503. var
  5504. defaultText = module.get.defaultText(),
  5505. placeholderText = module.get.placeholderText
  5506. ;
  5507. if(defaultText === placeholderText) {
  5508. module.debug('Restoring default placeholder text', defaultText);
  5509. module.set.placeholderText(defaultText);
  5510. }
  5511. else {
  5512. module.debug('Restoring default text', defaultText);
  5513. module.set.text(defaultText);
  5514. }
  5515. },
  5516. defaultValue: function() {
  5517. var
  5518. defaultValue = module.get.defaultValue()
  5519. ;
  5520. if(defaultValue !== undefined) {
  5521. module.debug('Restoring default value', defaultValue);
  5522. if(defaultValue !== '') {
  5523. module.set.value(defaultValue);
  5524. module.set.selected();
  5525. }
  5526. else {
  5527. module.remove.activeItem();
  5528. module.remove.selectedItem();
  5529. }
  5530. }
  5531. },
  5532. labels: function() {
  5533. if(settings.allowAdditions) {
  5534. if(!settings.useLabels) {
  5535. module.error(error.labels);
  5536. settings.useLabels = true;
  5537. }
  5538. module.debug('Restoring selected values');
  5539. module.create.userLabels();
  5540. }
  5541. module.check.maxSelections();
  5542. },
  5543. selected: function() {
  5544. module.restore.values();
  5545. if(module.is.multiple()) {
  5546. module.debug('Restoring previously selected values and labels');
  5547. module.restore.labels();
  5548. }
  5549. else {
  5550. module.debug('Restoring previously selected values');
  5551. }
  5552. },
  5553. values: function() {
  5554. // prevents callbacks from occuring on initial load
  5555. module.set.initialLoad();
  5556. if(settings.apiSettings) {
  5557. if(settings.saveRemoteData) {
  5558. module.restore.remoteValues();
  5559. }
  5560. else {
  5561. module.clearValue();
  5562. }
  5563. }
  5564. else {
  5565. module.set.selected();
  5566. }
  5567. module.remove.initialLoad();
  5568. },
  5569. remoteValues: function() {
  5570. var
  5571. values = module.get.remoteValues()
  5572. ;
  5573. module.debug('Recreating selected from session data', values);
  5574. if(values) {
  5575. if( module.is.single() ) {
  5576. $.each(values, function(value, name) {
  5577. module.set.text(name);
  5578. });
  5579. }
  5580. else {
  5581. $.each(values, function(value, name) {
  5582. module.add.label(value, name);
  5583. });
  5584. }
  5585. }
  5586. }
  5587. },
  5588. read: {
  5589. remoteData: function(value) {
  5590. var
  5591. name
  5592. ;
  5593. if(window.Storage === undefined) {
  5594. module.error(error.noStorage);
  5595. return;
  5596. }
  5597. name = sessionStorage.getItem(value);
  5598. return (name !== undefined)
  5599. ? name
  5600. : false
  5601. ;
  5602. }
  5603. },
  5604. save: {
  5605. defaults: function() {
  5606. module.save.defaultText();
  5607. module.save.placeholderText();
  5608. module.save.defaultValue();
  5609. },
  5610. defaultValue: function() {
  5611. var
  5612. value = module.get.value()
  5613. ;
  5614. module.verbose('Saving default value as', value);
  5615. $module.data(metadata.defaultValue, value);
  5616. },
  5617. defaultText: function() {
  5618. var
  5619. text = module.get.text()
  5620. ;
  5621. module.verbose('Saving default text as', text);
  5622. $module.data(metadata.defaultText, text);
  5623. },
  5624. placeholderText: function() {
  5625. var
  5626. text
  5627. ;
  5628. if(settings.placeholder !== false && $text.hasClass(className.placeholder)) {
  5629. text = module.get.text();
  5630. module.verbose('Saving placeholder text as', text);
  5631. $module.data(metadata.placeholderText, text);
  5632. }
  5633. },
  5634. remoteData: function(name, value) {
  5635. if(window.Storage === undefined) {
  5636. module.error(error.noStorage);
  5637. return;
  5638. }
  5639. module.verbose('Saving remote data to session storage', value, name);
  5640. sessionStorage.setItem(value, name);
  5641. }
  5642. },
  5643. clear: function() {
  5644. if(module.is.multiple()) {
  5645. module.remove.labels();
  5646. }
  5647. else {
  5648. module.remove.activeItem();
  5649. module.remove.selectedItem();
  5650. }
  5651. module.set.placeholderText();
  5652. module.clearValue();
  5653. },
  5654. clearValue: function() {
  5655. module.set.value('');
  5656. },
  5657. scrollPage: function(direction, $selectedItem) {
  5658. var
  5659. $currentItem = $selectedItem || module.get.selectedItem(),
  5660. $menu = $currentItem.closest(selector.menu),
  5661. menuHeight = $menu.outerHeight(),
  5662. currentScroll = $menu.scrollTop(),
  5663. itemHeight = $item.eq(0).outerHeight(),
  5664. itemsPerPage = Math.floor(menuHeight / itemHeight),
  5665. maxScroll = $menu.prop('scrollHeight'),
  5666. newScroll = (direction == 'up')
  5667. ? currentScroll - (itemHeight * itemsPerPage)
  5668. : currentScroll + (itemHeight * itemsPerPage),
  5669. $selectableItem = $item.not(selector.unselectable),
  5670. isWithinRange,
  5671. $nextSelectedItem,
  5672. elementIndex
  5673. ;
  5674. elementIndex = (direction == 'up')
  5675. ? $selectableItem.index($currentItem) - itemsPerPage
  5676. : $selectableItem.index($currentItem) + itemsPerPage
  5677. ;
  5678. isWithinRange = (direction == 'up')
  5679. ? (elementIndex >= 0)
  5680. : (elementIndex < $selectableItem.length)
  5681. ;
  5682. $nextSelectedItem = (isWithinRange)
  5683. ? $selectableItem.eq(elementIndex)
  5684. : (direction == 'up')
  5685. ? $selectableItem.first()
  5686. : $selectableItem.last()
  5687. ;
  5688. if($nextSelectedItem.length > 0) {
  5689. module.debug('Scrolling page', direction, $nextSelectedItem);
  5690. $currentItem
  5691. .removeClass(className.selected)
  5692. ;
  5693. $nextSelectedItem
  5694. .addClass(className.selected)
  5695. ;
  5696. $menu
  5697. .scrollTop(newScroll)
  5698. ;
  5699. }
  5700. },
  5701. set: {
  5702. filtered: function() {
  5703. var
  5704. isMultiple = module.is.multiple(),
  5705. isSearch = module.is.searchSelection(),
  5706. isSearchMultiple = (isMultiple && isSearch),
  5707. searchValue = (isSearch)
  5708. ? module.get.query()
  5709. : '',
  5710. hasSearchValue = (typeof searchValue === 'string' && searchValue.length > 0),
  5711. searchWidth = module.get.searchWidth(searchValue.length),
  5712. valueIsSet = searchValue !== ''
  5713. ;
  5714. if(isMultiple && hasSearchValue) {
  5715. module.verbose('Adjusting input width', searchWidth, settings.glyphWidth);
  5716. $search.css('width', searchWidth);
  5717. }
  5718. if(hasSearchValue || (isSearchMultiple && valueIsSet)) {
  5719. module.verbose('Hiding placeholder text');
  5720. $text.addClass(className.filtered);
  5721. }
  5722. else if(!isMultiple || (isSearchMultiple && !valueIsSet)) {
  5723. module.verbose('Showing placeholder text');
  5724. $text.removeClass(className.filtered);
  5725. }
  5726. },
  5727. loading: function() {
  5728. $module.addClass(className.loading);
  5729. },
  5730. placeholderText: function(text) {
  5731. text = text || module.get.placeholderText();
  5732. module.debug('Setting placeholder text', text);
  5733. module.set.text(text);
  5734. $text.addClass(className.placeholder);
  5735. },
  5736. tabbable: function() {
  5737. if( module.has.search() ) {
  5738. module.debug('Added tabindex to searchable dropdown');
  5739. $search
  5740. .val('')
  5741. .attr('tabindex', 0)
  5742. ;
  5743. $menu
  5744. .attr('tabindex', -1)
  5745. ;
  5746. }
  5747. else {
  5748. module.debug('Added tabindex to dropdown');
  5749. if(!$module.attr('tabindex') ) {
  5750. $module
  5751. .attr('tabindex', 0)
  5752. ;
  5753. $menu
  5754. .attr('tabindex', -1)
  5755. ;
  5756. }
  5757. }
  5758. },
  5759. initialLoad: function() {
  5760. module.verbose('Setting initial load');
  5761. initialLoad = true;
  5762. },
  5763. activeItem: function($item) {
  5764. if( settings.allowAdditions && $item.filter(selector.addition).length > 0 ) {
  5765. $item.addClass(className.filtered);
  5766. }
  5767. else {
  5768. $item.addClass(className.active);
  5769. }
  5770. },
  5771. scrollPosition: function($item, forceScroll) {
  5772. var
  5773. edgeTolerance = 5,
  5774. $menu,
  5775. hasActive,
  5776. offset,
  5777. itemHeight,
  5778. itemOffset,
  5779. menuOffset,
  5780. menuScroll,
  5781. menuHeight,
  5782. abovePage,
  5783. belowPage
  5784. ;
  5785. $item = $item || module.get.selectedItem();
  5786. $menu = $item.closest(selector.menu);
  5787. hasActive = ($item && $item.length > 0);
  5788. forceScroll = (forceScroll !== undefined)
  5789. ? forceScroll
  5790. : false
  5791. ;
  5792. if($item && $menu.length > 0 && hasActive) {
  5793. itemOffset = $item.position().top;
  5794. $menu.addClass(className.loading);
  5795. menuScroll = $menu.scrollTop();
  5796. menuOffset = $menu.offset().top;
  5797. itemOffset = $item.offset().top;
  5798. offset = menuScroll - menuOffset + itemOffset;
  5799. if(!forceScroll) {
  5800. menuHeight = $menu.height();
  5801. belowPage = menuScroll + menuHeight < (offset + edgeTolerance);
  5802. abovePage = ((offset - edgeTolerance) < menuScroll);
  5803. }
  5804. module.debug('Scrolling to active item', offset);
  5805. if(forceScroll || abovePage || belowPage) {
  5806. $menu.scrollTop(offset);
  5807. }
  5808. $menu.removeClass(className.loading);
  5809. }
  5810. },
  5811. text: function(text) {
  5812. if(settings.action !== 'select') {
  5813. if(settings.action == 'combo') {
  5814. module.debug('Changing combo button text', text, $combo);
  5815. if(settings.preserveHTML) {
  5816. $combo.html(text);
  5817. }
  5818. else {
  5819. $combo.text(text);
  5820. }
  5821. }
  5822. else {
  5823. if(text !== module.get.placeholderText()) {
  5824. $text.removeClass(className.placeholder);
  5825. }
  5826. module.debug('Changing text', text, $text);
  5827. $text
  5828. .removeClass(className.filtered)
  5829. ;
  5830. if(settings.preserveHTML) {
  5831. $text.html(text);
  5832. }
  5833. else {
  5834. $text.text(text);
  5835. }
  5836. }
  5837. }
  5838. },
  5839. selectedLetter: function(letter) {
  5840. var
  5841. $selectedItem = $item.filter('.' + className.selected),
  5842. alreadySelectedLetter = $selectedItem.length > 0 && module.has.firstLetter($selectedItem, letter),
  5843. $nextValue = false,
  5844. $nextItem
  5845. ;
  5846. // check next of same letter
  5847. if(alreadySelectedLetter) {
  5848. $nextItem = $selectedItem.nextAll($item).eq(0);
  5849. if( module.has.firstLetter($nextItem, letter) ) {
  5850. $nextValue = $nextItem;
  5851. }
  5852. }
  5853. // check all values
  5854. if(!$nextValue) {
  5855. $item
  5856. .each(function(){
  5857. if(module.has.firstLetter($(this), letter)) {
  5858. $nextValue = $(this);
  5859. return false;
  5860. }
  5861. })
  5862. ;
  5863. }
  5864. // set next value
  5865. if($nextValue) {
  5866. module.verbose('Scrolling to next value with letter', letter);
  5867. module.set.scrollPosition($nextValue);
  5868. $selectedItem.removeClass(className.selected);
  5869. $nextValue.addClass(className.selected);
  5870. }
  5871. },
  5872. direction: function($menu) {
  5873. if(settings.direction == 'auto') {
  5874. if(module.is.onScreen($menu)) {
  5875. module.remove.upward($menu);
  5876. }
  5877. else {
  5878. module.set.upward($menu);
  5879. }
  5880. }
  5881. else if(settings.direction == 'upward') {
  5882. module.set.upward($menu);
  5883. }
  5884. },
  5885. upward: function($menu) {
  5886. var $element = $menu || $module;
  5887. $element.addClass(className.upward);
  5888. },
  5889. value: function(value, text, $selected) {
  5890. var
  5891. hasInput = ($input.length > 0),
  5892. isAddition = !module.has.value(value),
  5893. currentValue = module.get.values(),
  5894. stringValue = (value !== undefined)
  5895. ? String(value)
  5896. : value,
  5897. newValue
  5898. ;
  5899. if(hasInput) {
  5900. if(stringValue == currentValue) {
  5901. module.verbose('Skipping value update already same value', value, currentValue);
  5902. if(!module.is.initialLoad()) {
  5903. return;
  5904. }
  5905. }
  5906. if( module.is.single() && module.has.selectInput() && module.can.extendSelect() ) {
  5907. module.debug('Adding user option', value);
  5908. module.add.optionValue(value);
  5909. }
  5910. module.debug('Updating input value', value, currentValue);
  5911. internalChange = true;
  5912. $input
  5913. .val(value)
  5914. ;
  5915. if(settings.fireOnInit === false && module.is.initialLoad()) {
  5916. module.debug('Input native change event ignored on initial load');
  5917. }
  5918. else {
  5919. $input.trigger('change');
  5920. }
  5921. internalChange = false;
  5922. }
  5923. else {
  5924. module.verbose('Storing value in metadata', value, $input);
  5925. if(value !== currentValue) {
  5926. $module.data(metadata.value, stringValue);
  5927. }
  5928. }
  5929. if(settings.fireOnInit === false && module.is.initialLoad()) {
  5930. module.verbose('No callback on initial load', settings.onChange);
  5931. }
  5932. else {
  5933. settings.onChange.call(element, value, text, $selected);
  5934. }
  5935. },
  5936. active: function() {
  5937. $module
  5938. .addClass(className.active)
  5939. ;
  5940. },
  5941. multiple: function() {
  5942. $module.addClass(className.multiple);
  5943. },
  5944. visible: function() {
  5945. $module.addClass(className.visible);
  5946. },
  5947. exactly: function(value, $selectedItem) {
  5948. module.debug('Setting selected to exact values');
  5949. module.clear();
  5950. module.set.selected(value, $selectedItem);
  5951. },
  5952. selected: function(value, $selectedItem) {
  5953. var
  5954. isMultiple = module.is.multiple(),
  5955. $userSelectedItem
  5956. ;
  5957. $selectedItem = (settings.allowAdditions)
  5958. ? $selectedItem || module.get.itemWithAdditions(value)
  5959. : $selectedItem || module.get.item(value)
  5960. ;
  5961. if(!$selectedItem) {
  5962. return;
  5963. }
  5964. module.debug('Setting selected menu item to', $selectedItem);
  5965. if(module.is.single()) {
  5966. module.remove.activeItem();
  5967. module.remove.selectedItem();
  5968. }
  5969. else if(settings.useLabels) {
  5970. module.remove.selectedItem();
  5971. }
  5972. // select each item
  5973. $selectedItem
  5974. .each(function() {
  5975. var
  5976. $selected = $(this),
  5977. selectedText = module.get.choiceText($selected),
  5978. selectedValue = module.get.choiceValue($selected, selectedText),
  5979. isFiltered = $selected.hasClass(className.filtered),
  5980. isActive = $selected.hasClass(className.active),
  5981. isUserValue = $selected.hasClass(className.addition),
  5982. shouldAnimate = (isMultiple && $selectedItem.length == 1)
  5983. ;
  5984. if(isMultiple) {
  5985. if(!isActive || isUserValue) {
  5986. if(settings.apiSettings && settings.saveRemoteData) {
  5987. module.save.remoteData(selectedText, selectedValue);
  5988. }
  5989. if(settings.useLabels) {
  5990. module.add.value(selectedValue, selectedText, $selected);
  5991. module.add.label(selectedValue, selectedText, shouldAnimate);
  5992. module.set.activeItem($selected);
  5993. module.filterActive();
  5994. module.select.nextAvailable($selectedItem);
  5995. }
  5996. else {
  5997. module.add.value(selectedValue, selectedText, $selected);
  5998. module.set.text(module.add.variables(message.count));
  5999. module.set.activeItem($selected);
  6000. }
  6001. }
  6002. else if(!isFiltered) {
  6003. module.debug('Selected active value, removing label');
  6004. module.remove.selected(selectedValue);
  6005. }
  6006. }
  6007. else {
  6008. if(settings.apiSettings && settings.saveRemoteData) {
  6009. module.save.remoteData(selectedText, selectedValue);
  6010. }
  6011. module.set.text(selectedText);
  6012. module.set.value(selectedValue, selectedText, $selected);
  6013. $selected
  6014. .addClass(className.active)
  6015. .addClass(className.selected)
  6016. ;
  6017. }
  6018. })
  6019. ;
  6020. }
  6021. },
  6022. add: {
  6023. label: function(value, text, shouldAnimate) {
  6024. var
  6025. $next = module.is.searchSelection()
  6026. ? $search
  6027. : $text,
  6028. $label
  6029. ;
  6030. $label = $('<a />')
  6031. .addClass(className.label)
  6032. .attr('data-value', value)
  6033. .html(templates.label(value, text))
  6034. ;
  6035. $label = settings.onLabelCreate.call($label, value, text);
  6036. if(module.has.label(value)) {
  6037. module.debug('Label already exists, skipping', value);
  6038. return;
  6039. }
  6040. if(settings.label.variation) {
  6041. $label.addClass(settings.label.variation);
  6042. }
  6043. if(shouldAnimate === true) {
  6044. module.debug('Animating in label', $label);
  6045. $label
  6046. .addClass(className.hidden)
  6047. .insertBefore($next)
  6048. .transition(settings.label.transition, settings.label.duration)
  6049. ;
  6050. }
  6051. else {
  6052. module.debug('Adding selection label', $label);
  6053. $label
  6054. .insertBefore($next)
  6055. ;
  6056. }
  6057. },
  6058. message: function(message) {
  6059. var
  6060. $message = $menu.children(selector.message),
  6061. html = settings.templates.message(module.add.variables(message))
  6062. ;
  6063. if($message.length > 0) {
  6064. $message
  6065. .html(html)
  6066. ;
  6067. }
  6068. else {
  6069. $message = $('<div/>')
  6070. .html(html)
  6071. .addClass(className.message)
  6072. .appendTo($menu)
  6073. ;
  6074. }
  6075. },
  6076. optionValue: function(value) {
  6077. var
  6078. $option = $input.find('option[value="' + value + '"]'),
  6079. hasOption = ($option.length > 0)
  6080. ;
  6081. if(hasOption) {
  6082. return;
  6083. }
  6084. // temporarily disconnect observer
  6085. if(selectObserver) {
  6086. selectObserver.disconnect();
  6087. module.verbose('Temporarily disconnecting mutation observer', value);
  6088. }
  6089. if( module.is.single() ) {
  6090. module.verbose('Removing previous user addition');
  6091. $input.find('option.' + className.addition).remove();
  6092. }
  6093. $('<option/>')
  6094. .prop('value', value)
  6095. .addClass(className.addition)
  6096. .html(value)
  6097. .appendTo($input)
  6098. ;
  6099. module.verbose('Adding user addition as an <option>', value);
  6100. if(selectObserver) {
  6101. selectObserver.observe($input[0], {
  6102. childList : true,
  6103. subtree : true
  6104. });
  6105. }
  6106. },
  6107. userSuggestion: function(value) {
  6108. var
  6109. $addition = $menu.children(selector.addition),
  6110. $existingItem = module.get.item(value),
  6111. alreadyHasValue = $existingItem && $existingItem.not(selector.addition).length,
  6112. hasUserSuggestion = $addition.length > 0,
  6113. html
  6114. ;
  6115. if(settings.useLabels && module.has.maxSelections()) {
  6116. return;
  6117. }
  6118. if(value === '' || alreadyHasValue) {
  6119. $addition.remove();
  6120. return;
  6121. }
  6122. $item
  6123. .removeClass(className.selected)
  6124. ;
  6125. if(hasUserSuggestion) {
  6126. html = settings.templates.addition( module.add.variables(message.addResult, value) );
  6127. $addition
  6128. .html(html)
  6129. .attr('data-' + metadata.value, value)
  6130. .attr('data-' + metadata.text, value)
  6131. .removeClass(className.filtered)
  6132. .addClass(className.selected)
  6133. ;
  6134. module.verbose('Replacing user suggestion with new value', $addition);
  6135. }
  6136. else {
  6137. $addition = module.create.userChoice(value);
  6138. $addition
  6139. .prependTo($menu)
  6140. .addClass(className.selected)
  6141. ;
  6142. module.verbose('Adding item choice to menu corresponding with user choice addition', $addition);
  6143. }
  6144. },
  6145. variables: function(message, term) {
  6146. var
  6147. hasCount = (message.search('{count}') !== -1),
  6148. hasMaxCount = (message.search('{maxCount}') !== -1),
  6149. hasTerm = (message.search('{term}') !== -1),
  6150. values,
  6151. count,
  6152. query
  6153. ;
  6154. module.verbose('Adding templated variables to message', message);
  6155. if(hasCount) {
  6156. count = module.get.selectionCount();
  6157. message = message.replace('{count}', count);
  6158. }
  6159. if(hasMaxCount) {
  6160. count = module.get.selectionCount();
  6161. message = message.replace('{maxCount}', settings.maxSelections);
  6162. }
  6163. if(hasTerm) {
  6164. query = term || module.get.query();
  6165. message = message.replace('{term}', query);
  6166. }
  6167. return message;
  6168. },
  6169. value: function(addedValue, addedText, $selectedItem) {
  6170. var
  6171. currentValue = module.get.values(),
  6172. newValue
  6173. ;
  6174. if(addedValue === '') {
  6175. module.debug('Cannot select blank values from multiselect');
  6176. return;
  6177. }
  6178. // extend current array
  6179. if($.isArray(currentValue)) {
  6180. newValue = currentValue.concat([addedValue]);
  6181. newValue = module.get.uniqueArray(newValue);
  6182. }
  6183. else {
  6184. newValue = [addedValue];
  6185. }
  6186. // add values
  6187. if( module.has.selectInput() ) {
  6188. if(module.can.extendSelect()) {
  6189. module.debug('Adding value to select', addedValue, newValue, $input);
  6190. module.add.optionValue(addedValue);
  6191. }
  6192. }
  6193. else {
  6194. newValue = newValue.join(settings.delimiter);
  6195. module.debug('Setting hidden input to delimited value', newValue, $input);
  6196. }
  6197. if(settings.fireOnInit === false && module.is.initialLoad()) {
  6198. module.verbose('Skipping onadd callback on initial load', settings.onAdd);
  6199. }
  6200. else {
  6201. settings.onAdd.call(element, addedValue, addedText, $selectedItem);
  6202. }
  6203. module.set.value(newValue, addedValue, addedText, $selectedItem);
  6204. module.check.maxSelections();
  6205. }
  6206. },
  6207. remove: {
  6208. active: function() {
  6209. $module.removeClass(className.active);
  6210. },
  6211. activeLabel: function() {
  6212. $module.find(selector.label).removeClass(className.active);
  6213. },
  6214. loading: function() {
  6215. $module.removeClass(className.loading);
  6216. },
  6217. initialLoad: function() {
  6218. initialLoad = false;
  6219. },
  6220. upward: function($menu) {
  6221. var $element = $menu || $module;
  6222. $element.removeClass(className.upward);
  6223. },
  6224. visible: function() {
  6225. $module.removeClass(className.visible);
  6226. },
  6227. activeItem: function() {
  6228. $item.removeClass(className.active);
  6229. },
  6230. filteredItem: function() {
  6231. if(settings.useLabels && module.has.maxSelections() ) {
  6232. return;
  6233. }
  6234. if(settings.useLabels && module.is.multiple()) {
  6235. $item.not('.' + className.active).removeClass(className.filtered);
  6236. }
  6237. else {
  6238. $item.removeClass(className.filtered);
  6239. }
  6240. },
  6241. optionValue: function(value) {
  6242. var
  6243. $option = $input.find('option[value="' + value + '"]'),
  6244. hasOption = ($option.length > 0)
  6245. ;
  6246. if(!hasOption || !$option.hasClass(className.addition)) {
  6247. return;
  6248. }
  6249. // temporarily disconnect observer
  6250. if(selectObserver) {
  6251. selectObserver.disconnect();
  6252. module.verbose('Temporarily disconnecting mutation observer', value);
  6253. }
  6254. $option.remove();
  6255. module.verbose('Removing user addition as an <option>', value);
  6256. if(selectObserver) {
  6257. selectObserver.observe($input[0], {
  6258. childList : true,
  6259. subtree : true
  6260. });
  6261. }
  6262. },
  6263. message: function() {
  6264. $menu.children(selector.message).remove();
  6265. },
  6266. searchTerm: function() {
  6267. module.verbose('Cleared search term');
  6268. $search.val('');
  6269. module.set.filtered();
  6270. },
  6271. selected: function(value, $selectedItem) {
  6272. $selectedItem = (settings.allowAdditions)
  6273. ? $selectedItem || module.get.itemWithAdditions(value)
  6274. : $selectedItem || module.get.item(value)
  6275. ;
  6276. if(!$selectedItem) {
  6277. return false;
  6278. }
  6279. $selectedItem
  6280. .each(function() {
  6281. var
  6282. $selected = $(this),
  6283. selectedText = module.get.choiceText($selected),
  6284. selectedValue = module.get.choiceValue($selected, selectedText)
  6285. ;
  6286. if(module.is.multiple()) {
  6287. if(settings.useLabels) {
  6288. module.remove.value(selectedValue, selectedText, $selected);
  6289. module.remove.label(selectedValue);
  6290. }
  6291. else {
  6292. module.remove.value(selectedValue, selectedText, $selected);
  6293. if(module.get.selectionCount() === 0) {
  6294. module.set.placeholderText();
  6295. }
  6296. else {
  6297. module.set.text(module.add.variables(message.count));
  6298. }
  6299. }
  6300. }
  6301. else {
  6302. module.remove.value(selectedValue, selectedText, $selected);
  6303. }
  6304. $selected
  6305. .removeClass(className.filtered)
  6306. .removeClass(className.active)
  6307. ;
  6308. if(settings.useLabels) {
  6309. $selected.removeClass(className.selected);
  6310. }
  6311. })
  6312. ;
  6313. },
  6314. selectedItem: function() {
  6315. $item.removeClass(className.selected);
  6316. },
  6317. value: function(removedValue, removedText, $removedItem) {
  6318. var
  6319. values = module.get.values(),
  6320. newValue
  6321. ;
  6322. if( module.has.selectInput() ) {
  6323. module.verbose('Input is <select> removing selected option', removedValue);
  6324. newValue = module.remove.arrayValue(removedValue, values);
  6325. module.remove.optionValue(removedValue);
  6326. }
  6327. else {
  6328. module.verbose('Removing from delimited values', removedValue);
  6329. newValue = module.remove.arrayValue(removedValue, values);
  6330. newValue = newValue.join(settings.delimiter);
  6331. }
  6332. if(settings.fireOnInit === false && module.is.initialLoad()) {
  6333. module.verbose('No callback on initial load', settings.onRemove);
  6334. }
  6335. else {
  6336. settings.onRemove.call(element, removedValue, removedText, $removedItem);
  6337. }
  6338. module.set.value(newValue, removedText, $removedItem);
  6339. module.check.maxSelections();
  6340. },
  6341. arrayValue: function(removedValue, values) {
  6342. if( !$.isArray(values) ) {
  6343. values = [values];
  6344. }
  6345. values = $.grep(values, function(value){
  6346. return (removedValue != value);
  6347. });
  6348. module.verbose('Removed value from delimited string', removedValue, values);
  6349. return values;
  6350. },
  6351. label: function(value, shouldAnimate) {
  6352. var
  6353. $labels = $module.find(selector.label),
  6354. $removedLabel = $labels.filter('[data-value="' + value +'"]')
  6355. ;
  6356. module.verbose('Removing label', $removedLabel);
  6357. $removedLabel.remove();
  6358. },
  6359. activeLabels: function($activeLabels) {
  6360. $activeLabels = $activeLabels || $module.find(selector.label).filter('.' + className.active);
  6361. module.verbose('Removing active label selections', $activeLabels);
  6362. module.remove.labels($activeLabels);
  6363. },
  6364. labels: function($labels) {
  6365. $labels = $labels || $module.find(selector.label);
  6366. module.verbose('Removing labels', $labels);
  6367. $labels
  6368. .each(function(){
  6369. var
  6370. value = $(this).data(metadata.value),
  6371. stringValue = (value !== undefined)
  6372. ? String(value)
  6373. : value,
  6374. isUserValue = module.is.userValue(stringValue)
  6375. ;
  6376. if(isUserValue) {
  6377. module.remove.value(stringValue);
  6378. module.remove.label(stringValue);
  6379. }
  6380. else {
  6381. // selected will also remove label
  6382. module.remove.selected(stringValue);
  6383. }
  6384. })
  6385. ;
  6386. },
  6387. tabbable: function() {
  6388. if( module.has.search() ) {
  6389. module.debug('Searchable dropdown initialized');
  6390. $search
  6391. .attr('tabindex', '-1')
  6392. ;
  6393. $menu
  6394. .attr('tabindex', '-1')
  6395. ;
  6396. }
  6397. else {
  6398. module.debug('Simple selection dropdown initialized');
  6399. $module
  6400. .attr('tabindex', '-1')
  6401. ;
  6402. $menu
  6403. .attr('tabindex', '-1')
  6404. ;
  6405. }
  6406. }
  6407. },
  6408. has: {
  6409. search: function() {
  6410. return ($search.length > 0);
  6411. },
  6412. selectInput: function() {
  6413. return ( $input.is('select') );
  6414. },
  6415. firstLetter: function($item, letter) {
  6416. var
  6417. text,
  6418. firstLetter
  6419. ;
  6420. if(!$item || $item.length === 0 || typeof letter !== 'string') {
  6421. return false;
  6422. }
  6423. text = module.get.choiceText($item, false);
  6424. letter = letter.toLowerCase();
  6425. firstLetter = String(text).charAt(0).toLowerCase();
  6426. return (letter == firstLetter);
  6427. },
  6428. input: function() {
  6429. return ($input.length > 0);
  6430. },
  6431. items: function() {
  6432. return ($item.length > 0);
  6433. },
  6434. menu: function() {
  6435. return ($menu.length > 0);
  6436. },
  6437. message: function() {
  6438. return ($menu.children(selector.message).length !== 0);
  6439. },
  6440. label: function(value) {
  6441. var
  6442. $labels = $module.find(selector.label)
  6443. ;
  6444. return ($labels.filter('[data-value="' + value +'"]').length > 0);
  6445. },
  6446. maxSelections: function() {
  6447. return (settings.maxSelections && module.get.selectionCount() >= settings.maxSelections);
  6448. },
  6449. allResultsFiltered: function() {
  6450. return ($item.filter(selector.unselectable).length === $item.length);
  6451. },
  6452. query: function() {
  6453. return (module.get.query() !== '');
  6454. },
  6455. value: function(value) {
  6456. var
  6457. values = module.get.values(),
  6458. hasValue = $.isArray(values)
  6459. ? values && ($.inArray(value, values) !== -1)
  6460. : (values == value)
  6461. ;
  6462. return (hasValue)
  6463. ? true
  6464. : false
  6465. ;
  6466. }
  6467. },
  6468. is: {
  6469. active: function() {
  6470. return $module.hasClass(className.active);
  6471. },
  6472. alreadySetup: function() {
  6473. return ($module.is('select') && $module.parent(selector.dropdown).length > 0 && $module.prev().length === 0);
  6474. },
  6475. animating: function($subMenu) {
  6476. return ($subMenu)
  6477. ? $subMenu.transition && $subMenu.transition('is animating')
  6478. : $menu.transition && $menu.transition('is animating')
  6479. ;
  6480. },
  6481. disabled: function() {
  6482. return $module.hasClass(className.disabled);
  6483. },
  6484. focused: function() {
  6485. return (document.activeElement === $module[0]);
  6486. },
  6487. focusedOnSearch: function() {
  6488. return (document.activeElement === $search[0]);
  6489. },
  6490. allFiltered: function() {
  6491. return( (module.is.multiple() || module.has.search()) && !module.has.message() && module.has.allResultsFiltered() );
  6492. },
  6493. hidden: function($subMenu) {
  6494. return !module.is.visible($subMenu);
  6495. },
  6496. initialLoad: function() {
  6497. return initialLoad;
  6498. },
  6499. onScreen: function($subMenu) {
  6500. var
  6501. $currentMenu = $subMenu || $menu,
  6502. canOpenDownward = true,
  6503. onScreen = {},
  6504. calculations
  6505. ;
  6506. $currentMenu.addClass(className.loading);
  6507. calculations = {
  6508. context: {
  6509. scrollTop : $context.scrollTop(),
  6510. height : $context.outerHeight()
  6511. },
  6512. menu : {
  6513. offset: $currentMenu.offset(),
  6514. height: $currentMenu.outerHeight()
  6515. }
  6516. };
  6517. onScreen = {
  6518. above : (calculations.context.scrollTop) <= calculations.menu.offset.top - calculations.menu.height,
  6519. below : (calculations.context.scrollTop + calculations.context.height) >= calculations.menu.offset.top + calculations.menu.height
  6520. };
  6521. if(onScreen.below) {
  6522. module.verbose('Dropdown can fit in context downward', onScreen);
  6523. canOpenDownward = true;
  6524. }
  6525. else if(!onScreen.below && !onScreen.above) {
  6526. module.verbose('Dropdown cannot fit in either direction, favoring downward', onScreen);
  6527. canOpenDownward = true;
  6528. }
  6529. else {
  6530. module.verbose('Dropdown cannot fit below, opening upward', onScreen);
  6531. canOpenDownward = false;
  6532. }
  6533. $currentMenu.removeClass(className.loading);
  6534. return canOpenDownward;
  6535. },
  6536. inObject: function(needle, object) {
  6537. var
  6538. found = false
  6539. ;
  6540. $.each(object, function(index, property) {
  6541. if(property == needle) {
  6542. found = true;
  6543. return true;
  6544. }
  6545. });
  6546. return found;
  6547. },
  6548. multiple: function() {
  6549. return $module.hasClass(className.multiple);
  6550. },
  6551. single: function() {
  6552. return !module.is.multiple();
  6553. },
  6554. selectMutation: function(mutations) {
  6555. var
  6556. selectChanged = false
  6557. ;
  6558. $.each(mutations, function(index, mutation) {
  6559. if(mutation.target && $(mutation.target).is('select')) {
  6560. selectChanged = true;
  6561. return true;
  6562. }
  6563. });
  6564. return selectChanged;
  6565. },
  6566. search: function() {
  6567. return $module.hasClass(className.search);
  6568. },
  6569. searchSelection: function() {
  6570. return ( module.has.search() && $search.parent(selector.dropdown).length === 1 );
  6571. },
  6572. selection: function() {
  6573. return $module.hasClass(className.selection);
  6574. },
  6575. userValue: function(value) {
  6576. return ($.inArray(value, module.get.userValues()) !== -1);
  6577. },
  6578. upward: function($menu) {
  6579. var $element = $menu || $module;
  6580. return $element.hasClass(className.upward);
  6581. },
  6582. visible: function($subMenu) {
  6583. return ($subMenu)
  6584. ? $subMenu.hasClass(className.visible)
  6585. : $menu.hasClass(className.visible)
  6586. ;
  6587. }
  6588. },
  6589. can: {
  6590. activate: function($item) {
  6591. if(settings.useLabels) {
  6592. return true;
  6593. }
  6594. if(!module.has.maxSelections()) {
  6595. return true;
  6596. }
  6597. if(module.has.maxSelections() && $item.hasClass(className.active)) {
  6598. return true;
  6599. }
  6600. return false;
  6601. },
  6602. click: function() {
  6603. return (hasTouch || settings.on == 'click');
  6604. },
  6605. extendSelect: function() {
  6606. return settings.allowAdditions || settings.apiSettings;
  6607. },
  6608. show: function() {
  6609. return !module.is.disabled() && (module.has.items() || module.has.message());
  6610. },
  6611. useAPI: function() {
  6612. return $.fn.api !== undefined;
  6613. }
  6614. },
  6615. animate: {
  6616. show: function(callback, $subMenu) {
  6617. var
  6618. $currentMenu = $subMenu || $menu,
  6619. start = ($subMenu)
  6620. ? function() {}
  6621. : function() {
  6622. module.hideSubMenus();
  6623. module.hideOthers();
  6624. module.set.active();
  6625. },
  6626. transition
  6627. ;
  6628. callback = $.isFunction(callback)
  6629. ? callback
  6630. : function(){}
  6631. ;
  6632. module.verbose('Doing menu show animation', $currentMenu);
  6633. module.set.direction($subMenu);
  6634. transition = module.get.transition($subMenu);
  6635. if( module.is.selection() ) {
  6636. module.set.scrollPosition(module.get.selectedItem(), true);
  6637. }
  6638. if( module.is.hidden($currentMenu) || module.is.animating($currentMenu) ) {
  6639. if(transition == 'none') {
  6640. start();
  6641. $currentMenu.transition('show');
  6642. callback.call(element);
  6643. }
  6644. else if($.fn.transition !== undefined && $module.transition('is supported')) {
  6645. $currentMenu
  6646. .transition({
  6647. animation : transition + ' in',
  6648. debug : settings.debug,
  6649. verbose : settings.verbose,
  6650. duration : settings.duration,
  6651. queue : true,
  6652. onStart : start,
  6653. onComplete : function() {
  6654. callback.call(element);
  6655. }
  6656. })
  6657. ;
  6658. }
  6659. else {
  6660. module.error(error.noTransition, transition);
  6661. }
  6662. }
  6663. },
  6664. hide: function(callback, $subMenu) {
  6665. var
  6666. $currentMenu = $subMenu || $menu,
  6667. duration = ($subMenu)
  6668. ? (settings.duration * 0.9)
  6669. : settings.duration,
  6670. start = ($subMenu)
  6671. ? function() {}
  6672. : function() {
  6673. if( module.can.click() ) {
  6674. module.unbind.intent();
  6675. }
  6676. module.remove.active();
  6677. },
  6678. transition = module.get.transition($subMenu)
  6679. ;
  6680. callback = $.isFunction(callback)
  6681. ? callback
  6682. : function(){}
  6683. ;
  6684. if( module.is.visible($currentMenu) || module.is.animating($currentMenu) ) {
  6685. module.verbose('Doing menu hide animation', $currentMenu);
  6686. if(transition == 'none') {
  6687. start();
  6688. $currentMenu.transition('hide');
  6689. callback.call(element);
  6690. }
  6691. else if($.fn.transition !== undefined && $module.transition('is supported')) {
  6692. $currentMenu
  6693. .transition({
  6694. animation : transition + ' out',
  6695. duration : settings.duration,
  6696. debug : settings.debug,
  6697. verbose : settings.verbose,
  6698. queue : true,
  6699. onStart : start,
  6700. onComplete : function() {
  6701. if(settings.direction == 'auto') {
  6702. module.remove.upward($subMenu);
  6703. }
  6704. callback.call(element);
  6705. }
  6706. })
  6707. ;
  6708. }
  6709. else {
  6710. module.error(error.transition);
  6711. }
  6712. }
  6713. }
  6714. },
  6715. hideAndClear: function() {
  6716. module.remove.searchTerm();
  6717. if( module.has.maxSelections() ) {
  6718. return;
  6719. }
  6720. if(module.has.search()) {
  6721. module.hide(function() {
  6722. module.remove.filteredItem();
  6723. });
  6724. }
  6725. else {
  6726. module.hide();
  6727. }
  6728. },
  6729. delay: {
  6730. show: function() {
  6731. module.verbose('Delaying show event to ensure user intent');
  6732. clearTimeout(module.timer);
  6733. module.timer = setTimeout(module.show, settings.delay.show);
  6734. },
  6735. hide: function() {
  6736. module.verbose('Delaying hide event to ensure user intent');
  6737. clearTimeout(module.timer);
  6738. module.timer = setTimeout(module.hide, settings.delay.hide);
  6739. }
  6740. },
  6741. escape: {
  6742. regExp: function(text) {
  6743. text = String(text);
  6744. return text.replace(regExp.escape, '\\$&');
  6745. }
  6746. },
  6747. setting: function(name, value) {
  6748. module.debug('Changing setting', name, value);
  6749. if( $.isPlainObject(name) ) {
  6750. $.extend(true, settings, name);
  6751. }
  6752. else if(value !== undefined) {
  6753. settings[name] = value;
  6754. }
  6755. else {
  6756. return settings[name];
  6757. }
  6758. },
  6759. internal: function(name, value) {
  6760. if( $.isPlainObject(name) ) {
  6761. $.extend(true, module, name);
  6762. }
  6763. else if(value !== undefined) {
  6764. module[name] = value;
  6765. }
  6766. else {
  6767. return module[name];
  6768. }
  6769. },
  6770. debug: function() {
  6771. if(settings.debug) {
  6772. if(settings.performance) {
  6773. module.performance.log(arguments);
  6774. }
  6775. else {
  6776. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  6777. module.debug.apply(console, arguments);
  6778. }
  6779. }
  6780. },
  6781. verbose: function() {
  6782. if(settings.verbose && settings.debug) {
  6783. if(settings.performance) {
  6784. module.performance.log(arguments);
  6785. }
  6786. else {
  6787. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  6788. module.verbose.apply(console, arguments);
  6789. }
  6790. }
  6791. },
  6792. error: function() {
  6793. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  6794. module.error.apply(console, arguments);
  6795. },
  6796. performance: {
  6797. log: function(message) {
  6798. var
  6799. currentTime,
  6800. executionTime,
  6801. previousTime
  6802. ;
  6803. if(settings.performance) {
  6804. currentTime = new Date().getTime();
  6805. previousTime = time || currentTime;
  6806. executionTime = currentTime - previousTime;
  6807. time = currentTime;
  6808. performance.push({
  6809. 'Name' : message[0],
  6810. 'Arguments' : [].slice.call(message, 1) || '',
  6811. 'Element' : element,
  6812. 'Execution Time' : executionTime
  6813. });
  6814. }
  6815. clearTimeout(module.performance.timer);
  6816. module.performance.timer = setTimeout(module.performance.display, 500);
  6817. },
  6818. display: function() {
  6819. var
  6820. title = settings.name + ':',
  6821. totalTime = 0
  6822. ;
  6823. time = false;
  6824. clearTimeout(module.performance.timer);
  6825. $.each(performance, function(index, data) {
  6826. totalTime += data['Execution Time'];
  6827. });
  6828. title += ' ' + totalTime + 'ms';
  6829. if(moduleSelector) {
  6830. title += ' \'' + moduleSelector + '\'';
  6831. }
  6832. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  6833. console.groupCollapsed(title);
  6834. if(console.table) {
  6835. console.table(performance);
  6836. }
  6837. else {
  6838. $.each(performance, function(index, data) {
  6839. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  6840. });
  6841. }
  6842. console.groupEnd();
  6843. }
  6844. performance = [];
  6845. }
  6846. },
  6847. invoke: function(query, passedArguments, context) {
  6848. var
  6849. object = instance,
  6850. maxDepth,
  6851. found,
  6852. response
  6853. ;
  6854. passedArguments = passedArguments || queryArguments;
  6855. context = element || context;
  6856. if(typeof query == 'string' && object !== undefined) {
  6857. query = query.split(/[\. ]/);
  6858. maxDepth = query.length - 1;
  6859. $.each(query, function(depth, value) {
  6860. var camelCaseValue = (depth != maxDepth)
  6861. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  6862. : query
  6863. ;
  6864. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  6865. object = object[camelCaseValue];
  6866. }
  6867. else if( object[camelCaseValue] !== undefined ) {
  6868. found = object[camelCaseValue];
  6869. return false;
  6870. }
  6871. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  6872. object = object[value];
  6873. }
  6874. else if( object[value] !== undefined ) {
  6875. found = object[value];
  6876. return false;
  6877. }
  6878. else {
  6879. module.error(error.method, query);
  6880. return false;
  6881. }
  6882. });
  6883. }
  6884. if ( $.isFunction( found ) ) {
  6885. response = found.apply(context, passedArguments);
  6886. }
  6887. else if(found !== undefined) {
  6888. response = found;
  6889. }
  6890. if($.isArray(returnedValue)) {
  6891. returnedValue.push(response);
  6892. }
  6893. else if(returnedValue !== undefined) {
  6894. returnedValue = [returnedValue, response];
  6895. }
  6896. else if(response !== undefined) {
  6897. returnedValue = response;
  6898. }
  6899. return found;
  6900. }
  6901. };
  6902. if(methodInvoked) {
  6903. if(instance === undefined) {
  6904. module.initialize();
  6905. }
  6906. module.invoke(query);
  6907. }
  6908. else {
  6909. if(instance !== undefined) {
  6910. instance.invoke('destroy');
  6911. }
  6912. module.initialize();
  6913. }
  6914. })
  6915. ;
  6916. return (returnedValue !== undefined)
  6917. ? returnedValue
  6918. : $allModules
  6919. ;
  6920. };
  6921. $.fn.dropdown.settings = {
  6922. debug : false,
  6923. verbose : false,
  6924. performance : true,
  6925. on : 'click', // what event should show menu action on item selection
  6926. action : 'activate', // action on item selection (nothing, activate, select, combo, hide, function(){})
  6927. apiSettings : false,
  6928. saveRemoteData : true, // Whether remote name/value pairs should be stored in sessionStorage to allow remote data to be restored on page refresh
  6929. throttle : 200, // How long to wait after last user input to search remotely
  6930. context : window, // Context to use when determining if on screen
  6931. direction : 'auto', // Whether dropdown should always open in one direction
  6932. keepOnScreen : true, // Whether dropdown should check whether it is on screen before showing
  6933. match : 'both', // what to match against with search selection (both, text, or label)
  6934. fullTextSearch : false, // search anywhere in value
  6935. placeholder : 'auto', // whether to convert blank <select> values to placeholder text
  6936. preserveHTML : true, // preserve html when selecting value
  6937. sortSelect : false, // sort selection on init
  6938. forceSelection : true, // force a choice on blur with search selection
  6939. allowAdditions : false, // whether multiple select should allow user added values
  6940. maxSelections : false, // When set to a number limits the number of selections to this count
  6941. useLabels : true, // whether multiple select should filter currently active selections from choices
  6942. delimiter : ',', // when multiselect uses normal <input> the values will be delimited with this character
  6943. showOnFocus : true, // show menu on focus
  6944. allowTab : true, // add tabindex to element
  6945. allowCategorySelection : false, // allow elements with sub-menus to be selected
  6946. fireOnInit : false, // Whether callbacks should fire when initializing dropdown values
  6947. transition : 'auto', // auto transition will slide down or up based on direction
  6948. duration : 200, // duration of transition
  6949. glyphWidth : 1.0714, // widest glyph width in em (W is 1.0714 em) used to calculate multiselect input width
  6950. // label settings on multi-select
  6951. label: {
  6952. transition : 'scale',
  6953. duration : 200,
  6954. variation : false
  6955. },
  6956. // delay before event
  6957. delay : {
  6958. hide : 300,
  6959. show : 200,
  6960. search : 20,
  6961. touch : 50
  6962. },
  6963. /* Callbacks */
  6964. onChange : function(value, text, $selected){},
  6965. onAdd : function(value, text, $selected){},
  6966. onRemove : function(value, text, $selected){},
  6967. onLabelSelect : function($selectedLabels){},
  6968. onLabelCreate : function(value, text) { return $(this); },
  6969. onNoResults : function(searchTerm) { return true; },
  6970. onShow : function(){},
  6971. onHide : function(){},
  6972. /* Component */
  6973. name : 'Dropdown',
  6974. namespace : 'dropdown',
  6975. message: {
  6976. addResult : 'Add <b>{term}</b>',
  6977. count : '{count} selected',
  6978. maxSelections : 'Max {maxCount} selections',
  6979. noResults : 'No results found.',
  6980. serverError : 'There was an error contacting the server'
  6981. },
  6982. error : {
  6983. action : 'You called a dropdown action that was not defined',
  6984. alreadySetup : 'Once a select has been initialized behaviors must be called on the created ui dropdown',
  6985. labels : 'Allowing user additions currently requires the use of labels.',
  6986. missingMultiple : '<select> requires multiple property to be set to correctly preserve multiple values',
  6987. method : 'The method you called is not defined.',
  6988. noAPI : 'The API module is required to load resources remotely',
  6989. noStorage : 'Saving remote data requires session storage',
  6990. noTransition : 'This module requires ui transitions <https://github.com/Semantic-Org/UI-Transition>'
  6991. },
  6992. regExp : {
  6993. escape : /[-[\]{}()*+?.,\\^$|#\s]/g,
  6994. },
  6995. metadata : {
  6996. defaultText : 'defaultText',
  6997. defaultValue : 'defaultValue',
  6998. placeholderText : 'placeholder',
  6999. text : 'text',
  7000. value : 'value'
  7001. },
  7002. // property names for remote query
  7003. fields: {
  7004. values : 'values', // grouping for all dropdown values
  7005. name : 'name', // displayed dropdown text
  7006. value : 'value' // actual dropdown value
  7007. },
  7008. selector : {
  7009. addition : '.addition',
  7010. dropdown : '.ui.dropdown',
  7011. icon : '> .dropdown.icon',
  7012. input : '> input[type="hidden"], > select',
  7013. item : '.item',
  7014. label : '> .label',
  7015. remove : '> .label > .delete.icon',
  7016. siblingLabel : '.label',
  7017. menu : '.menu',
  7018. message : '.message',
  7019. menuIcon : '.dropdown.icon',
  7020. search : 'input.search, .menu > .search > input',
  7021. text : '> .text:not(.icon)',
  7022. unselectable : '.disabled, .filtered'
  7023. },
  7024. className : {
  7025. active : 'active',
  7026. addition : 'addition',
  7027. animating : 'animating',
  7028. disabled : 'disabled',
  7029. dropdown : 'ui dropdown',
  7030. filtered : 'filtered',
  7031. hidden : 'hidden transition',
  7032. item : 'item',
  7033. label : 'ui label',
  7034. loading : 'loading',
  7035. menu : 'menu',
  7036. message : 'message',
  7037. multiple : 'multiple',
  7038. placeholder : 'default',
  7039. search : 'search',
  7040. selected : 'selected',
  7041. selection : 'selection',
  7042. upward : 'upward',
  7043. visible : 'visible'
  7044. }
  7045. };
  7046. /* Templates */
  7047. $.fn.dropdown.settings.templates = {
  7048. // generates dropdown from select values
  7049. dropdown: function(select) {
  7050. var
  7051. placeholder = select.placeholder || false,
  7052. values = select.values || {},
  7053. html = ''
  7054. ;
  7055. html += '<i class="dropdown icon"></i>';
  7056. if(select.placeholder) {
  7057. html += '<div class="default text">' + placeholder + '</div>';
  7058. }
  7059. else {
  7060. html += '<div class="text"></div>';
  7061. }
  7062. html += '<div class="menu">';
  7063. $.each(select.values, function(index, option) {
  7064. html += (option.disabled)
  7065. ? '<div class="disabled item" data-value="' + option.value + '">' + option.name + '</div>'
  7066. : '<div class="item" data-value="' + option.value + '">' + option.name + '</div>'
  7067. ;
  7068. });
  7069. html += '</div>';
  7070. return html;
  7071. },
  7072. // generates just menu from select
  7073. menu: function(response, fields) {
  7074. var
  7075. values = response.values || {},
  7076. html = ''
  7077. ;
  7078. $.each(response[fields.values], function(index, option) {
  7079. html += '<div class="item" data-value="' + option[fields.value] + '">' + option[fields.name] + '</div>';
  7080. });
  7081. return html;
  7082. },
  7083. // generates label for multiselect
  7084. label: function(value, text) {
  7085. return text + '<i class="delete icon"></i>';
  7086. },
  7087. // generates messages like "No results"
  7088. message: function(message) {
  7089. return message;
  7090. },
  7091. // generates user addition to selection menu
  7092. addition: function(choice) {
  7093. return choice;
  7094. }
  7095. };
  7096. })( jQuery, window , document );
  7097. /*!
  7098. * # Semantic UI 2.1.4 - Video
  7099. * http://github.com/semantic-org/semantic-ui/
  7100. *
  7101. *
  7102. * Copyright 2015 Contributors
  7103. * Released under the MIT license
  7104. * http://opensource.org/licenses/MIT
  7105. *
  7106. */
  7107. ;(function ($, window, document, undefined) {
  7108. "use strict";
  7109. $.fn.embed = function(parameters) {
  7110. var
  7111. $allModules = $(this),
  7112. moduleSelector = $allModules.selector || '',
  7113. time = new Date().getTime(),
  7114. performance = [],
  7115. query = arguments[0],
  7116. methodInvoked = (typeof query == 'string'),
  7117. queryArguments = [].slice.call(arguments, 1),
  7118. returnedValue
  7119. ;
  7120. $allModules
  7121. .each(function() {
  7122. var
  7123. settings = ( $.isPlainObject(parameters) )
  7124. ? $.extend(true, {}, $.fn.embed.settings, parameters)
  7125. : $.extend({}, $.fn.embed.settings),
  7126. selector = settings.selector,
  7127. className = settings.className,
  7128. sources = settings.sources,
  7129. error = settings.error,
  7130. metadata = settings.metadata,
  7131. namespace = settings.namespace,
  7132. templates = settings.templates,
  7133. eventNamespace = '.' + namespace,
  7134. moduleNamespace = 'module-' + namespace,
  7135. $window = $(window),
  7136. $module = $(this),
  7137. $placeholder = $module.find(selector.placeholder),
  7138. $icon = $module.find(selector.icon),
  7139. $embed = $module.find(selector.embed),
  7140. element = this,
  7141. instance = $module.data(moduleNamespace),
  7142. module
  7143. ;
  7144. module = {
  7145. initialize: function() {
  7146. module.debug('Initializing embed');
  7147. module.determine.autoplay();
  7148. module.create();
  7149. module.bind.events();
  7150. module.instantiate();
  7151. },
  7152. instantiate: function() {
  7153. module.verbose('Storing instance of module', module);
  7154. instance = module;
  7155. $module
  7156. .data(moduleNamespace, module)
  7157. ;
  7158. },
  7159. destroy: function() {
  7160. module.verbose('Destroying previous instance of embed');
  7161. module.reset();
  7162. $module
  7163. .removeData(moduleNamespace)
  7164. .off(eventNamespace)
  7165. ;
  7166. },
  7167. refresh: function() {
  7168. module.verbose('Refreshing selector cache');
  7169. $placeholder = $module.find(selector.placeholder);
  7170. $icon = $module.find(selector.icon);
  7171. $embed = $module.find(selector.embed);
  7172. },
  7173. bind: {
  7174. events: function() {
  7175. if( module.has.placeholder() ) {
  7176. module.debug('Adding placeholder events');
  7177. $module
  7178. .on('click' + eventNamespace, selector.placeholder, module.createAndShow)
  7179. .on('click' + eventNamespace, selector.icon, module.createAndShow)
  7180. ;
  7181. }
  7182. }
  7183. },
  7184. create: function() {
  7185. var
  7186. placeholder = module.get.placeholder()
  7187. ;
  7188. if(placeholder) {
  7189. module.createPlaceholder();
  7190. }
  7191. else {
  7192. module.createAndShow();
  7193. }
  7194. },
  7195. createPlaceholder: function(placeholder) {
  7196. var
  7197. icon = module.get.icon(),
  7198. url = module.get.url(),
  7199. embed = module.generate.embed(url)
  7200. ;
  7201. placeholder = placeholder || module.get.placeholder();
  7202. $module.html( templates.placeholder(placeholder, icon) );
  7203. module.debug('Creating placeholder for embed', placeholder, icon);
  7204. },
  7205. createEmbed: function(url) {
  7206. module.refresh();
  7207. url = url || module.get.url();
  7208. $embed = $('<div/>')
  7209. .addClass(className.embed)
  7210. .html( module.generate.embed(url) )
  7211. .appendTo($module)
  7212. ;
  7213. settings.onCreate.call(element, url);
  7214. module.debug('Creating embed object', $embed);
  7215. },
  7216. createAndShow: function() {
  7217. module.createEmbed();
  7218. module.show();
  7219. },
  7220. // sets new embed
  7221. change: function(source, id, url) {
  7222. module.debug('Changing video to ', source, id, url);
  7223. $module
  7224. .data(metadata.source, source)
  7225. .data(metadata.id, id)
  7226. .data(metadata.url, url)
  7227. ;
  7228. module.create();
  7229. },
  7230. // clears embed
  7231. reset: function() {
  7232. module.debug('Clearing embed and showing placeholder');
  7233. module.remove.active();
  7234. module.remove.embed();
  7235. module.showPlaceholder();
  7236. settings.onReset.call(element);
  7237. },
  7238. // shows current embed
  7239. show: function() {
  7240. module.debug('Showing embed');
  7241. module.set.active();
  7242. settings.onDisplay.call(element);
  7243. },
  7244. hide: function() {
  7245. module.debug('Hiding embed');
  7246. module.showPlaceholder();
  7247. },
  7248. showPlaceholder: function() {
  7249. module.debug('Showing placeholder image');
  7250. module.remove.active();
  7251. settings.onPlaceholderDisplay.call(element);
  7252. },
  7253. get: {
  7254. id: function() {
  7255. return settings.id || $module.data(metadata.id);
  7256. },
  7257. placeholder: function() {
  7258. return settings.placeholder || $module.data(metadata.placeholder);
  7259. },
  7260. icon: function() {
  7261. return (settings.icon)
  7262. ? settings.icon
  7263. : ($module.data(metadata.icon) !== undefined)
  7264. ? $module.data(metadata.icon)
  7265. : module.determine.icon()
  7266. ;
  7267. },
  7268. source: function(url) {
  7269. return (settings.source)
  7270. ? settings.source
  7271. : ($module.data(metadata.source) !== undefined)
  7272. ? $module.data(metadata.source)
  7273. : module.determine.source()
  7274. ;
  7275. },
  7276. type: function() {
  7277. var source = module.get.source();
  7278. return (sources[source] !== undefined)
  7279. ? sources[source].type
  7280. : false
  7281. ;
  7282. },
  7283. url: function() {
  7284. return (settings.url)
  7285. ? settings.url
  7286. : ($module.data(metadata.url) !== undefined)
  7287. ? $module.data(metadata.url)
  7288. : module.determine.url()
  7289. ;
  7290. }
  7291. },
  7292. determine: {
  7293. autoplay: function() {
  7294. if(module.should.autoplay()) {
  7295. settings.autoplay = true;
  7296. }
  7297. },
  7298. source: function(url) {
  7299. var
  7300. matchedSource = false
  7301. ;
  7302. url = url || module.get.url();
  7303. if(url) {
  7304. $.each(sources, function(name, source) {
  7305. if(url.search(source.domain) !== -1) {
  7306. matchedSource = name;
  7307. return false;
  7308. }
  7309. });
  7310. }
  7311. return matchedSource;
  7312. },
  7313. icon: function() {
  7314. var
  7315. source = module.get.source()
  7316. ;
  7317. return (sources[source] !== undefined)
  7318. ? sources[source].icon
  7319. : false
  7320. ;
  7321. },
  7322. url: function() {
  7323. var
  7324. id = settings.id || $module.data(metadata.id),
  7325. source = settings.source || $module.data(metadata.source),
  7326. url
  7327. ;
  7328. url = (sources[source] !== undefined)
  7329. ? sources[source].url.replace('{id}', id)
  7330. : false
  7331. ;
  7332. if(url) {
  7333. $module.data(metadata.url, url);
  7334. }
  7335. return url;
  7336. }
  7337. },
  7338. set: {
  7339. active: function() {
  7340. $module.addClass(className.active);
  7341. }
  7342. },
  7343. remove: {
  7344. active: function() {
  7345. $module.removeClass(className.active);
  7346. },
  7347. embed: function() {
  7348. $embed.empty();
  7349. }
  7350. },
  7351. encode: {
  7352. parameters: function(parameters) {
  7353. var
  7354. urlString = [],
  7355. index
  7356. ;
  7357. for (index in parameters) {
  7358. urlString.push( encodeURIComponent(index) + '=' + encodeURIComponent( parameters[index] ) );
  7359. }
  7360. return urlString.join('&amp;');
  7361. }
  7362. },
  7363. generate: {
  7364. embed: function(url) {
  7365. module.debug('Generating embed html');
  7366. var
  7367. source = module.get.source(),
  7368. html,
  7369. parameters
  7370. ;
  7371. url = module.get.url(url);
  7372. if(url) {
  7373. parameters = module.generate.parameters(source);
  7374. html = templates.iframe(url, parameters);
  7375. }
  7376. else {
  7377. module.error(error.noURL, $module);
  7378. }
  7379. return html;
  7380. },
  7381. parameters: function(source, extraParameters) {
  7382. var
  7383. parameters = (sources[source] && sources[source].parameters !== undefined)
  7384. ? sources[source].parameters(settings)
  7385. : {}
  7386. ;
  7387. extraParameters = extraParameters || settings.parameters;
  7388. if(extraParameters) {
  7389. parameters = $.extend({}, parameters, extraParameters);
  7390. }
  7391. parameters = settings.onEmbed(parameters);
  7392. return module.encode.parameters(parameters);
  7393. }
  7394. },
  7395. has: {
  7396. placeholder: function() {
  7397. return settings.placeholder || $module.data(metadata.placeholder);
  7398. }
  7399. },
  7400. should: {
  7401. autoplay: function() {
  7402. return (settings.autoplay === 'auto')
  7403. ? (settings.placeholder || $module.data(metadata.placeholder) !== undefined)
  7404. : settings.autoplay
  7405. ;
  7406. }
  7407. },
  7408. is: {
  7409. video: function() {
  7410. return module.get.type() == 'video';
  7411. }
  7412. },
  7413. setting: function(name, value) {
  7414. module.debug('Changing setting', name, value);
  7415. if( $.isPlainObject(name) ) {
  7416. $.extend(true, settings, name);
  7417. }
  7418. else if(value !== undefined) {
  7419. settings[name] = value;
  7420. }
  7421. else {
  7422. return settings[name];
  7423. }
  7424. },
  7425. internal: function(name, value) {
  7426. if( $.isPlainObject(name) ) {
  7427. $.extend(true, module, name);
  7428. }
  7429. else if(value !== undefined) {
  7430. module[name] = value;
  7431. }
  7432. else {
  7433. return module[name];
  7434. }
  7435. },
  7436. debug: function() {
  7437. if(settings.debug) {
  7438. if(settings.performance) {
  7439. module.performance.log(arguments);
  7440. }
  7441. else {
  7442. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  7443. module.debug.apply(console, arguments);
  7444. }
  7445. }
  7446. },
  7447. verbose: function() {
  7448. if(settings.verbose && settings.debug) {
  7449. if(settings.performance) {
  7450. module.performance.log(arguments);
  7451. }
  7452. else {
  7453. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  7454. module.verbose.apply(console, arguments);
  7455. }
  7456. }
  7457. },
  7458. error: function() {
  7459. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  7460. module.error.apply(console, arguments);
  7461. },
  7462. performance: {
  7463. log: function(message) {
  7464. var
  7465. currentTime,
  7466. executionTime,
  7467. previousTime
  7468. ;
  7469. if(settings.performance) {
  7470. currentTime = new Date().getTime();
  7471. previousTime = time || currentTime;
  7472. executionTime = currentTime - previousTime;
  7473. time = currentTime;
  7474. performance.push({
  7475. 'Name' : message[0],
  7476. 'Arguments' : [].slice.call(message, 1) || '',
  7477. 'Element' : element,
  7478. 'Execution Time' : executionTime
  7479. });
  7480. }
  7481. clearTimeout(module.performance.timer);
  7482. module.performance.timer = setTimeout(module.performance.display, 500);
  7483. },
  7484. display: function() {
  7485. var
  7486. title = settings.name + ':',
  7487. totalTime = 0
  7488. ;
  7489. time = false;
  7490. clearTimeout(module.performance.timer);
  7491. $.each(performance, function(index, data) {
  7492. totalTime += data['Execution Time'];
  7493. });
  7494. title += ' ' + totalTime + 'ms';
  7495. if(moduleSelector) {
  7496. title += ' \'' + moduleSelector + '\'';
  7497. }
  7498. if($allModules.length > 1) {
  7499. title += ' ' + '(' + $allModules.length + ')';
  7500. }
  7501. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  7502. console.groupCollapsed(title);
  7503. if(console.table) {
  7504. console.table(performance);
  7505. }
  7506. else {
  7507. $.each(performance, function(index, data) {
  7508. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  7509. });
  7510. }
  7511. console.groupEnd();
  7512. }
  7513. performance = [];
  7514. }
  7515. },
  7516. invoke: function(query, passedArguments, context) {
  7517. var
  7518. object = instance,
  7519. maxDepth,
  7520. found,
  7521. response
  7522. ;
  7523. passedArguments = passedArguments || queryArguments;
  7524. context = element || context;
  7525. if(typeof query == 'string' && object !== undefined) {
  7526. query = query.split(/[\. ]/);
  7527. maxDepth = query.length - 1;
  7528. $.each(query, function(depth, value) {
  7529. var camelCaseValue = (depth != maxDepth)
  7530. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  7531. : query
  7532. ;
  7533. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  7534. object = object[camelCaseValue];
  7535. }
  7536. else if( object[camelCaseValue] !== undefined ) {
  7537. found = object[camelCaseValue];
  7538. return false;
  7539. }
  7540. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  7541. object = object[value];
  7542. }
  7543. else if( object[value] !== undefined ) {
  7544. found = object[value];
  7545. return false;
  7546. }
  7547. else {
  7548. module.error(error.method, query);
  7549. return false;
  7550. }
  7551. });
  7552. }
  7553. if ( $.isFunction( found ) ) {
  7554. response = found.apply(context, passedArguments);
  7555. }
  7556. else if(found !== undefined) {
  7557. response = found;
  7558. }
  7559. if($.isArray(returnedValue)) {
  7560. returnedValue.push(response);
  7561. }
  7562. else if(returnedValue !== undefined) {
  7563. returnedValue = [returnedValue, response];
  7564. }
  7565. else if(response !== undefined) {
  7566. returnedValue = response;
  7567. }
  7568. return found;
  7569. }
  7570. };
  7571. if(methodInvoked) {
  7572. if(instance === undefined) {
  7573. module.initialize();
  7574. }
  7575. module.invoke(query);
  7576. }
  7577. else {
  7578. if(instance !== undefined) {
  7579. instance.invoke('destroy');
  7580. }
  7581. module.initialize();
  7582. }
  7583. })
  7584. ;
  7585. return (returnedValue !== undefined)
  7586. ? returnedValue
  7587. : this
  7588. ;
  7589. };
  7590. $.fn.embed.settings = {
  7591. name : 'Embed',
  7592. namespace : 'embed',
  7593. debug : false,
  7594. verbose : false,
  7595. performance : true,
  7596. icon : false,
  7597. source : false,
  7598. url : false,
  7599. id : false,
  7600. // standard video settings
  7601. autoplay : 'auto',
  7602. color : '#444444',
  7603. hd : true,
  7604. brandedUI : false,
  7605. // additional parameters to include with the embed
  7606. parameters: false,
  7607. onDisplay : function() {},
  7608. onPlaceholderDisplay : function() {},
  7609. onReset : function() {},
  7610. onCreate : function(url) {},
  7611. onEmbed : function(parameters) {
  7612. return parameters;
  7613. },
  7614. metadata : {
  7615. id : 'id',
  7616. icon : 'icon',
  7617. placeholder : 'placeholder',
  7618. source : 'source',
  7619. url : 'url'
  7620. },
  7621. error : {
  7622. noURL : 'No URL specified',
  7623. method : 'The method you called is not defined'
  7624. },
  7625. className : {
  7626. active : 'active',
  7627. embed : 'embed'
  7628. },
  7629. selector : {
  7630. embed : '.embed',
  7631. placeholder : '.placeholder',
  7632. icon : '.icon'
  7633. },
  7634. sources: {
  7635. youtube: {
  7636. name : 'youtube',
  7637. type : 'video',
  7638. icon : 'video play',
  7639. domain : 'youtube.com',
  7640. url : '//www.youtube.com/embed/{id}',
  7641. parameters: function(settings) {
  7642. return {
  7643. autohide : !settings.brandedUI,
  7644. autoplay : settings.autoplay,
  7645. color : settings.colors || undefined,
  7646. hq : settings.hd,
  7647. jsapi : settings.api,
  7648. modestbranding : !settings.brandedUI
  7649. };
  7650. }
  7651. },
  7652. vimeo: {
  7653. name : 'vimeo',
  7654. type : 'video',
  7655. icon : 'video play',
  7656. domain : 'vimeo.com',
  7657. url : '//player.vimeo.com/video/{id}',
  7658. parameters: function(settings) {
  7659. return {
  7660. api : settings.api,
  7661. autoplay : settings.autoplay,
  7662. byline : settings.brandedUI,
  7663. color : settings.colors || undefined,
  7664. portrait : settings.brandedUI,
  7665. title : settings.brandedUI
  7666. };
  7667. }
  7668. }
  7669. },
  7670. templates: {
  7671. iframe : function(url, parameters) {
  7672. return ''
  7673. + '<iframe src="' + url + '?' + parameters + '"'
  7674. + ' width="100%" height="100%"'
  7675. + ' frameborder="0" scrolling="no" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>'
  7676. ;
  7677. },
  7678. placeholder : function(image, icon) {
  7679. var
  7680. html = ''
  7681. ;
  7682. if(icon) {
  7683. html += '<i class="' + icon + ' icon"></i>';
  7684. }
  7685. if(image) {
  7686. html += '<img class="placeholder" src="' + image + '">';
  7687. }
  7688. return html;
  7689. }
  7690. },
  7691. // NOT YET IMPLEMENTED
  7692. api : true,
  7693. onPause : function() {},
  7694. onPlay : function() {},
  7695. onStop : function() {}
  7696. };
  7697. })( jQuery, window , document );
  7698. /*!
  7699. * # Semantic UI 2.1.4 - Modal
  7700. * http://github.com/semantic-org/semantic-ui/
  7701. *
  7702. *
  7703. * Copyright 2015 Contributors
  7704. * Released under the MIT license
  7705. * http://opensource.org/licenses/MIT
  7706. *
  7707. */
  7708. ;(function ( $, window, document, undefined ) {
  7709. "use strict";
  7710. $.fn.modal = function(parameters) {
  7711. var
  7712. $allModules = $(this),
  7713. $window = $(window),
  7714. $document = $(document),
  7715. $body = $('body'),
  7716. moduleSelector = $allModules.selector || '',
  7717. time = new Date().getTime(),
  7718. performance = [],
  7719. query = arguments[0],
  7720. methodInvoked = (typeof query == 'string'),
  7721. queryArguments = [].slice.call(arguments, 1),
  7722. requestAnimationFrame = window.requestAnimationFrame
  7723. || window.mozRequestAnimationFrame
  7724. || window.webkitRequestAnimationFrame
  7725. || window.msRequestAnimationFrame
  7726. || function(callback) { setTimeout(callback, 0); },
  7727. returnedValue
  7728. ;
  7729. $allModules
  7730. .each(function() {
  7731. var
  7732. settings = ( $.isPlainObject(parameters) )
  7733. ? $.extend(true, {}, $.fn.modal.settings, parameters)
  7734. : $.extend({}, $.fn.modal.settings),
  7735. selector = settings.selector,
  7736. className = settings.className,
  7737. namespace = settings.namespace,
  7738. error = settings.error,
  7739. eventNamespace = '.' + namespace,
  7740. moduleNamespace = 'module-' + namespace,
  7741. $module = $(this),
  7742. $context = $(settings.context),
  7743. $close = $module.find(selector.close),
  7744. $allModals,
  7745. $otherModals,
  7746. $focusedElement,
  7747. $dimmable,
  7748. $dimmer,
  7749. element = this,
  7750. instance = $module.data(moduleNamespace),
  7751. elementNamespace,
  7752. id,
  7753. observer,
  7754. module
  7755. ;
  7756. module = {
  7757. initialize: function() {
  7758. module.verbose('Initializing dimmer', $context);
  7759. module.create.id();
  7760. module.create.dimmer();
  7761. module.refreshModals();
  7762. module.bind.events();
  7763. if(settings.observeChanges) {
  7764. module.observeChanges();
  7765. }
  7766. module.instantiate();
  7767. },
  7768. instantiate: function() {
  7769. module.verbose('Storing instance of modal');
  7770. instance = module;
  7771. $module
  7772. .data(moduleNamespace, instance)
  7773. ;
  7774. },
  7775. create: {
  7776. dimmer: function() {
  7777. var
  7778. defaultSettings = {
  7779. debug : settings.debug,
  7780. dimmerName : 'modals',
  7781. duration : {
  7782. show : settings.duration,
  7783. hide : settings.duration
  7784. }
  7785. },
  7786. dimmerSettings = $.extend(true, defaultSettings, settings.dimmerSettings)
  7787. ;
  7788. if(settings.inverted) {
  7789. dimmerSettings.variation = (dimmerSettings.variation !== undefined)
  7790. ? dimmerSettings.variation + ' inverted'
  7791. : 'inverted'
  7792. ;
  7793. }
  7794. if($.fn.dimmer === undefined) {
  7795. module.error(error.dimmer);
  7796. return;
  7797. }
  7798. module.debug('Creating dimmer with settings', dimmerSettings);
  7799. $dimmable = $context.dimmer(dimmerSettings);
  7800. if(settings.detachable) {
  7801. module.verbose('Modal is detachable, moving content into dimmer');
  7802. $dimmable.dimmer('add content', $module);
  7803. }
  7804. else {
  7805. module.set.undetached();
  7806. }
  7807. if(settings.blurring) {
  7808. $dimmable.addClass(className.blurring);
  7809. }
  7810. $dimmer = $dimmable.dimmer('get dimmer');
  7811. },
  7812. id: function() {
  7813. id = (Math.random().toString(16) + '000000000').substr(2,8);
  7814. elementNamespace = '.' + id;
  7815. module.verbose('Creating unique id for element', id);
  7816. }
  7817. },
  7818. destroy: function() {
  7819. module.verbose('Destroying previous modal');
  7820. $module
  7821. .removeData(moduleNamespace)
  7822. .off(eventNamespace)
  7823. ;
  7824. $window.off(elementNamespace);
  7825. $close.off(eventNamespace);
  7826. $context.dimmer('destroy');
  7827. },
  7828. observeChanges: function() {
  7829. if('MutationObserver' in window) {
  7830. observer = new MutationObserver(function(mutations) {
  7831. module.debug('DOM tree modified, refreshing');
  7832. module.refresh();
  7833. });
  7834. observer.observe(element, {
  7835. childList : true,
  7836. subtree : true
  7837. });
  7838. module.debug('Setting up mutation observer', observer);
  7839. }
  7840. },
  7841. refresh: function() {
  7842. module.remove.scrolling();
  7843. module.cacheSizes();
  7844. module.set.screenHeight();
  7845. module.set.type();
  7846. module.set.position();
  7847. },
  7848. refreshModals: function() {
  7849. $otherModals = $module.siblings(selector.modal);
  7850. $allModals = $otherModals.add($module);
  7851. },
  7852. attachEvents: function(selector, event) {
  7853. var
  7854. $toggle = $(selector)
  7855. ;
  7856. event = $.isFunction(module[event])
  7857. ? module[event]
  7858. : module.toggle
  7859. ;
  7860. if($toggle.length > 0) {
  7861. module.debug('Attaching modal events to element', selector, event);
  7862. $toggle
  7863. .off(eventNamespace)
  7864. .on('click' + eventNamespace, event)
  7865. ;
  7866. }
  7867. else {
  7868. module.error(error.notFound, selector);
  7869. }
  7870. },
  7871. bind: {
  7872. events: function() {
  7873. module.verbose('Attaching events');
  7874. $module
  7875. .on('click' + eventNamespace, selector.close, module.event.close)
  7876. .on('click' + eventNamespace, selector.approve, module.event.approve)
  7877. .on('click' + eventNamespace, selector.deny, module.event.deny)
  7878. ;
  7879. $window
  7880. .on('resize' + elementNamespace, module.event.resize)
  7881. ;
  7882. }
  7883. },
  7884. get: {
  7885. id: function() {
  7886. return (Math.random().toString(16) + '000000000').substr(2,8);
  7887. }
  7888. },
  7889. event: {
  7890. approve: function() {
  7891. if(settings.onApprove.call(element, $(this)) === false) {
  7892. module.verbose('Approve callback returned false cancelling hide');
  7893. return;
  7894. }
  7895. module.hide();
  7896. },
  7897. deny: function() {
  7898. if(settings.onDeny.call(element, $(this)) === false) {
  7899. module.verbose('Deny callback returned false cancelling hide');
  7900. return;
  7901. }
  7902. module.hide();
  7903. },
  7904. close: function() {
  7905. module.hide();
  7906. },
  7907. click: function(event) {
  7908. var
  7909. $target = $(event.target),
  7910. isInModal = ($target.closest(selector.modal).length > 0),
  7911. isInDOM = $.contains(document.documentElement, event.target)
  7912. ;
  7913. if(!isInModal && isInDOM) {
  7914. module.debug('Dimmer clicked, hiding all modals');
  7915. if( module.is.active() ) {
  7916. module.remove.clickaway();
  7917. if(settings.allowMultiple) {
  7918. module.hide();
  7919. }
  7920. else {
  7921. module.hideAll();
  7922. }
  7923. }
  7924. }
  7925. },
  7926. debounce: function(method, delay) {
  7927. clearTimeout(module.timer);
  7928. module.timer = setTimeout(method, delay);
  7929. },
  7930. keyboard: function(event) {
  7931. var
  7932. keyCode = event.which,
  7933. escapeKey = 27
  7934. ;
  7935. if(keyCode == escapeKey) {
  7936. if(settings.closable) {
  7937. module.debug('Escape key pressed hiding modal');
  7938. module.hide();
  7939. }
  7940. else {
  7941. module.debug('Escape key pressed, but closable is set to false');
  7942. }
  7943. event.preventDefault();
  7944. }
  7945. },
  7946. resize: function() {
  7947. if( $dimmable.dimmer('is active') ) {
  7948. requestAnimationFrame(module.refresh);
  7949. }
  7950. }
  7951. },
  7952. toggle: function() {
  7953. if( module.is.active() || module.is.animating() ) {
  7954. module.hide();
  7955. }
  7956. else {
  7957. module.show();
  7958. }
  7959. },
  7960. show: function(callback) {
  7961. callback = $.isFunction(callback)
  7962. ? callback
  7963. : function(){}
  7964. ;
  7965. module.refreshModals();
  7966. module.showModal(callback);
  7967. },
  7968. hide: function(callback) {
  7969. callback = $.isFunction(callback)
  7970. ? callback
  7971. : function(){}
  7972. ;
  7973. module.refreshModals();
  7974. module.hideModal(callback);
  7975. },
  7976. showModal: function(callback) {
  7977. callback = $.isFunction(callback)
  7978. ? callback
  7979. : function(){}
  7980. ;
  7981. if( module.is.animating() || !module.is.active() ) {
  7982. module.showDimmer();
  7983. module.cacheSizes();
  7984. module.set.position();
  7985. module.set.screenHeight();
  7986. module.set.type();
  7987. module.set.clickaway();
  7988. if( !settings.allowMultiple && module.others.active() ) {
  7989. module.hideOthers(module.showModal);
  7990. }
  7991. else {
  7992. settings.onShow.call(element);
  7993. if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  7994. module.debug('Showing modal with css animations');
  7995. $module
  7996. .transition({
  7997. debug : settings.debug,
  7998. animation : settings.transition + ' in',
  7999. queue : settings.queue,
  8000. duration : settings.duration,
  8001. useFailSafe : true,
  8002. onComplete : function() {
  8003. settings.onVisible.apply(element);
  8004. module.add.keyboardShortcuts();
  8005. module.save.focus();
  8006. module.set.active();
  8007. if(settings.autofocus) {
  8008. module.set.autofocus();
  8009. }
  8010. callback();
  8011. }
  8012. })
  8013. ;
  8014. }
  8015. else {
  8016. module.error(error.noTransition);
  8017. }
  8018. }
  8019. }
  8020. else {
  8021. module.debug('Modal is already visible');
  8022. }
  8023. },
  8024. hideModal: function(callback, keepDimmed) {
  8025. callback = $.isFunction(callback)
  8026. ? callback
  8027. : function(){}
  8028. ;
  8029. module.debug('Hiding modal');
  8030. settings.onHide.call(element);
  8031. if( module.is.animating() || module.is.active() ) {
  8032. if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  8033. module.remove.active();
  8034. $module
  8035. .transition({
  8036. debug : settings.debug,
  8037. animation : settings.transition + ' out',
  8038. queue : settings.queue,
  8039. duration : settings.duration,
  8040. useFailSafe : true,
  8041. onStart : function() {
  8042. if(!module.others.active() && !keepDimmed) {
  8043. module.hideDimmer();
  8044. }
  8045. module.remove.keyboardShortcuts();
  8046. },
  8047. onComplete : function() {
  8048. settings.onHidden.call(element);
  8049. module.restore.focus();
  8050. callback();
  8051. }
  8052. })
  8053. ;
  8054. }
  8055. else {
  8056. module.error(error.noTransition);
  8057. }
  8058. }
  8059. },
  8060. showDimmer: function() {
  8061. if($dimmable.dimmer('is animating') || !$dimmable.dimmer('is active') ) {
  8062. module.debug('Showing dimmer');
  8063. $dimmable.dimmer('show');
  8064. }
  8065. else {
  8066. module.debug('Dimmer already visible');
  8067. }
  8068. },
  8069. hideDimmer: function() {
  8070. if( $dimmable.dimmer('is animating') || ($dimmable.dimmer('is active')) ) {
  8071. $dimmable.dimmer('hide', function() {
  8072. module.remove.clickaway();
  8073. module.remove.screenHeight();
  8074. });
  8075. }
  8076. else {
  8077. module.debug('Dimmer is not visible cannot hide');
  8078. return;
  8079. }
  8080. },
  8081. hideAll: function(callback) {
  8082. var
  8083. $visibleModals = $allModals.filter('.' + className.active + ', .' + className.animating)
  8084. ;
  8085. callback = $.isFunction(callback)
  8086. ? callback
  8087. : function(){}
  8088. ;
  8089. if( $visibleModals.length > 0 ) {
  8090. module.debug('Hiding all visible modals');
  8091. module.hideDimmer();
  8092. $visibleModals
  8093. .modal('hide modal', callback)
  8094. ;
  8095. }
  8096. },
  8097. hideOthers: function(callback) {
  8098. var
  8099. $visibleModals = $otherModals.filter('.' + className.active + ', .' + className.animating)
  8100. ;
  8101. callback = $.isFunction(callback)
  8102. ? callback
  8103. : function(){}
  8104. ;
  8105. if( $visibleModals.length > 0 ) {
  8106. module.debug('Hiding other modals', $otherModals);
  8107. $visibleModals
  8108. .modal('hide modal', callback, true)
  8109. ;
  8110. }
  8111. },
  8112. others: {
  8113. active: function() {
  8114. return ($otherModals.filter('.' + className.active).length > 0);
  8115. },
  8116. animating: function() {
  8117. return ($otherModals.filter('.' + className.animating).length > 0);
  8118. }
  8119. },
  8120. add: {
  8121. keyboardShortcuts: function() {
  8122. module.verbose('Adding keyboard shortcuts');
  8123. $document
  8124. .on('keyup' + eventNamespace, module.event.keyboard)
  8125. ;
  8126. }
  8127. },
  8128. save: {
  8129. focus: function() {
  8130. $focusedElement = $(document.activeElement).blur();
  8131. }
  8132. },
  8133. restore: {
  8134. focus: function() {
  8135. if($focusedElement && $focusedElement.length > 0) {
  8136. $focusedElement.focus();
  8137. }
  8138. }
  8139. },
  8140. remove: {
  8141. active: function() {
  8142. $module.removeClass(className.active);
  8143. },
  8144. clickaway: function() {
  8145. if(settings.closable) {
  8146. $dimmer
  8147. .off('click' + elementNamespace)
  8148. ;
  8149. }
  8150. },
  8151. bodyStyle: function() {
  8152. if($body.attr('style') === '') {
  8153. module.verbose('Removing style attribute');
  8154. $body.removeAttr('style');
  8155. }
  8156. },
  8157. screenHeight: function() {
  8158. module.debug('Removing page height');
  8159. $body
  8160. .css('height', '')
  8161. ;
  8162. },
  8163. keyboardShortcuts: function() {
  8164. module.verbose('Removing keyboard shortcuts');
  8165. $document
  8166. .off('keyup' + eventNamespace)
  8167. ;
  8168. },
  8169. scrolling: function() {
  8170. $dimmable.removeClass(className.scrolling);
  8171. $module.removeClass(className.scrolling);
  8172. }
  8173. },
  8174. cacheSizes: function() {
  8175. var
  8176. modalHeight = $module.outerHeight()
  8177. ;
  8178. if(module.cache === undefined || modalHeight !== 0) {
  8179. module.cache = {
  8180. pageHeight : $(document).outerHeight(),
  8181. height : modalHeight + settings.offset,
  8182. contextHeight : (settings.context == 'body')
  8183. ? $(window).height()
  8184. : $dimmable.height()
  8185. };
  8186. }
  8187. module.debug('Caching modal and container sizes', module.cache);
  8188. },
  8189. can: {
  8190. fit: function() {
  8191. return ( ( module.cache.height + (settings.padding * 2) ) < module.cache.contextHeight);
  8192. }
  8193. },
  8194. is: {
  8195. active: function() {
  8196. return $module.hasClass(className.active);
  8197. },
  8198. animating: function() {
  8199. return $module.transition('is supported')
  8200. ? $module.transition('is animating')
  8201. : $module.is(':visible')
  8202. ;
  8203. },
  8204. scrolling: function() {
  8205. return $dimmable.hasClass(className.scrolling);
  8206. },
  8207. modernBrowser: function() {
  8208. // appName for IE11 reports 'Netscape' can no longer use
  8209. return !(window.ActiveXObject || "ActiveXObject" in window);
  8210. }
  8211. },
  8212. set: {
  8213. autofocus: function() {
  8214. var
  8215. $inputs = $module.find(':input').filter(':visible'),
  8216. $autofocus = $inputs.filter('[autofocus]'),
  8217. $input = ($autofocus.length > 0)
  8218. ? $autofocus.first()
  8219. : $inputs.first()
  8220. ;
  8221. if($input.length > 0) {
  8222. $input.focus();
  8223. }
  8224. },
  8225. clickaway: function() {
  8226. if(settings.closable) {
  8227. $dimmer
  8228. .on('click' + elementNamespace, module.event.click)
  8229. ;
  8230. }
  8231. },
  8232. screenHeight: function() {
  8233. if( module.can.fit() ) {
  8234. $body.css('height', '');
  8235. }
  8236. else {
  8237. module.debug('Modal is taller than page content, resizing page height');
  8238. $body
  8239. .css('height', module.cache.height + (settings.padding * 2) )
  8240. ;
  8241. }
  8242. },
  8243. active: function() {
  8244. $module.addClass(className.active);
  8245. },
  8246. scrolling: function() {
  8247. $dimmable.addClass(className.scrolling);
  8248. $module.addClass(className.scrolling);
  8249. },
  8250. type: function() {
  8251. if(module.can.fit()) {
  8252. module.verbose('Modal fits on screen');
  8253. if(!module.others.active() && !module.others.animating()) {
  8254. module.remove.scrolling();
  8255. }
  8256. }
  8257. else {
  8258. module.verbose('Modal cannot fit on screen setting to scrolling');
  8259. module.set.scrolling();
  8260. }
  8261. },
  8262. position: function() {
  8263. module.verbose('Centering modal on page', module.cache);
  8264. if(module.can.fit()) {
  8265. $module
  8266. .css({
  8267. top: '',
  8268. marginTop: -(module.cache.height / 2)
  8269. })
  8270. ;
  8271. }
  8272. else {
  8273. $module
  8274. .css({
  8275. marginTop : '',
  8276. top : $document.scrollTop()
  8277. })
  8278. ;
  8279. }
  8280. },
  8281. undetached: function() {
  8282. $dimmable.addClass(className.undetached);
  8283. }
  8284. },
  8285. setting: function(name, value) {
  8286. module.debug('Changing setting', name, value);
  8287. if( $.isPlainObject(name) ) {
  8288. $.extend(true, settings, name);
  8289. }
  8290. else if(value !== undefined) {
  8291. settings[name] = value;
  8292. }
  8293. else {
  8294. return settings[name];
  8295. }
  8296. },
  8297. internal: function(name, value) {
  8298. if( $.isPlainObject(name) ) {
  8299. $.extend(true, module, name);
  8300. }
  8301. else if(value !== undefined) {
  8302. module[name] = value;
  8303. }
  8304. else {
  8305. return module[name];
  8306. }
  8307. },
  8308. debug: function() {
  8309. if(settings.debug) {
  8310. if(settings.performance) {
  8311. module.performance.log(arguments);
  8312. }
  8313. else {
  8314. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  8315. module.debug.apply(console, arguments);
  8316. }
  8317. }
  8318. },
  8319. verbose: function() {
  8320. if(settings.verbose && settings.debug) {
  8321. if(settings.performance) {
  8322. module.performance.log(arguments);
  8323. }
  8324. else {
  8325. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  8326. module.verbose.apply(console, arguments);
  8327. }
  8328. }
  8329. },
  8330. error: function() {
  8331. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  8332. module.error.apply(console, arguments);
  8333. },
  8334. performance: {
  8335. log: function(message) {
  8336. var
  8337. currentTime,
  8338. executionTime,
  8339. previousTime
  8340. ;
  8341. if(settings.performance) {
  8342. currentTime = new Date().getTime();
  8343. previousTime = time || currentTime;
  8344. executionTime = currentTime - previousTime;
  8345. time = currentTime;
  8346. performance.push({
  8347. 'Name' : message[0],
  8348. 'Arguments' : [].slice.call(message, 1) || '',
  8349. 'Element' : element,
  8350. 'Execution Time' : executionTime
  8351. });
  8352. }
  8353. clearTimeout(module.performance.timer);
  8354. module.performance.timer = setTimeout(module.performance.display, 500);
  8355. },
  8356. display: function() {
  8357. var
  8358. title = settings.name + ':',
  8359. totalTime = 0
  8360. ;
  8361. time = false;
  8362. clearTimeout(module.performance.timer);
  8363. $.each(performance, function(index, data) {
  8364. totalTime += data['Execution Time'];
  8365. });
  8366. title += ' ' + totalTime + 'ms';
  8367. if(moduleSelector) {
  8368. title += ' \'' + moduleSelector + '\'';
  8369. }
  8370. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  8371. console.groupCollapsed(title);
  8372. if(console.table) {
  8373. console.table(performance);
  8374. }
  8375. else {
  8376. $.each(performance, function(index, data) {
  8377. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  8378. });
  8379. }
  8380. console.groupEnd();
  8381. }
  8382. performance = [];
  8383. }
  8384. },
  8385. invoke: function(query, passedArguments, context) {
  8386. var
  8387. object = instance,
  8388. maxDepth,
  8389. found,
  8390. response
  8391. ;
  8392. passedArguments = passedArguments || queryArguments;
  8393. context = element || context;
  8394. if(typeof query == 'string' && object !== undefined) {
  8395. query = query.split(/[\. ]/);
  8396. maxDepth = query.length - 1;
  8397. $.each(query, function(depth, value) {
  8398. var camelCaseValue = (depth != maxDepth)
  8399. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  8400. : query
  8401. ;
  8402. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  8403. object = object[camelCaseValue];
  8404. }
  8405. else if( object[camelCaseValue] !== undefined ) {
  8406. found = object[camelCaseValue];
  8407. return false;
  8408. }
  8409. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  8410. object = object[value];
  8411. }
  8412. else if( object[value] !== undefined ) {
  8413. found = object[value];
  8414. return false;
  8415. }
  8416. else {
  8417. return false;
  8418. }
  8419. });
  8420. }
  8421. if ( $.isFunction( found ) ) {
  8422. response = found.apply(context, passedArguments);
  8423. }
  8424. else if(found !== undefined) {
  8425. response = found;
  8426. }
  8427. if($.isArray(returnedValue)) {
  8428. returnedValue.push(response);
  8429. }
  8430. else if(returnedValue !== undefined) {
  8431. returnedValue = [returnedValue, response];
  8432. }
  8433. else if(response !== undefined) {
  8434. returnedValue = response;
  8435. }
  8436. return found;
  8437. }
  8438. };
  8439. if(methodInvoked) {
  8440. if(instance === undefined) {
  8441. module.initialize();
  8442. }
  8443. module.invoke(query);
  8444. }
  8445. else {
  8446. if(instance !== undefined) {
  8447. instance.invoke('destroy');
  8448. }
  8449. module.initialize();
  8450. }
  8451. })
  8452. ;
  8453. return (returnedValue !== undefined)
  8454. ? returnedValue
  8455. : this
  8456. ;
  8457. };
  8458. $.fn.modal.settings = {
  8459. name : 'Modal',
  8460. namespace : 'modal',
  8461. debug : false,
  8462. verbose : false,
  8463. performance : true,
  8464. observeChanges : false,
  8465. allowMultiple : false,
  8466. detachable : true,
  8467. closable : true,
  8468. autofocus : true,
  8469. inverted : false,
  8470. blurring : false,
  8471. dimmerSettings : {
  8472. closable : false,
  8473. useCSS : true
  8474. },
  8475. context : 'body',
  8476. queue : false,
  8477. duration : 500,
  8478. offset : 0,
  8479. transition : 'scale',
  8480. // padding with edge of page
  8481. padding : 50,
  8482. // called before show animation
  8483. onShow : function(){},
  8484. // called after show animation
  8485. onVisible : function(){},
  8486. // called before hide animation
  8487. onHide : function(){},
  8488. // called after hide animation
  8489. onHidden : function(){},
  8490. // called after approve selector match
  8491. onApprove : function(){ return true; },
  8492. // called after deny selector match
  8493. onDeny : function(){ return true; },
  8494. selector : {
  8495. close : '> .close',
  8496. approve : '.actions .positive, .actions .approve, .actions .ok',
  8497. deny : '.actions .negative, .actions .deny, .actions .cancel',
  8498. modal : '.ui.modal'
  8499. },
  8500. error : {
  8501. dimmer : 'UI Dimmer, a required component is not included in this page',
  8502. method : 'The method you called is not defined.',
  8503. notFound : 'The element you specified could not be found'
  8504. },
  8505. className : {
  8506. active : 'active',
  8507. animating : 'animating',
  8508. blurring : 'blurring',
  8509. scrolling : 'scrolling',
  8510. undetached : 'undetached'
  8511. }
  8512. };
  8513. })( jQuery, window , document );
  8514. /*!
  8515. * # Semantic UI 2.1.4 - Nag
  8516. * http://github.com/semantic-org/semantic-ui/
  8517. *
  8518. *
  8519. * Copyright 2015 Contributors
  8520. * Released under the MIT license
  8521. * http://opensource.org/licenses/MIT
  8522. *
  8523. */
  8524. ;(function ($, window, document, undefined) {
  8525. "use strict";
  8526. $.fn.nag = function(parameters) {
  8527. var
  8528. $allModules = $(this),
  8529. moduleSelector = $allModules.selector || '',
  8530. time = new Date().getTime(),
  8531. performance = [],
  8532. query = arguments[0],
  8533. methodInvoked = (typeof query == 'string'),
  8534. queryArguments = [].slice.call(arguments, 1),
  8535. returnedValue
  8536. ;
  8537. $allModules
  8538. .each(function() {
  8539. var
  8540. settings = ( $.isPlainObject(parameters) )
  8541. ? $.extend(true, {}, $.fn.nag.settings, parameters)
  8542. : $.extend({}, $.fn.nag.settings),
  8543. className = settings.className,
  8544. selector = settings.selector,
  8545. error = settings.error,
  8546. namespace = settings.namespace,
  8547. eventNamespace = '.' + namespace,
  8548. moduleNamespace = namespace + '-module',
  8549. $module = $(this),
  8550. $close = $module.find(selector.close),
  8551. $context = (settings.context)
  8552. ? $(settings.context)
  8553. : $('body'),
  8554. element = this,
  8555. instance = $module.data(moduleNamespace),
  8556. moduleOffset,
  8557. moduleHeight,
  8558. contextWidth,
  8559. contextHeight,
  8560. contextOffset,
  8561. yOffset,
  8562. yPosition,
  8563. timer,
  8564. module,
  8565. requestAnimationFrame = window.requestAnimationFrame
  8566. || window.mozRequestAnimationFrame
  8567. || window.webkitRequestAnimationFrame
  8568. || window.msRequestAnimationFrame
  8569. || function(callback) { setTimeout(callback, 0); }
  8570. ;
  8571. module = {
  8572. initialize: function() {
  8573. module.verbose('Initializing element');
  8574. $module
  8575. .on('click' + eventNamespace, selector.close, module.dismiss)
  8576. .data(moduleNamespace, module)
  8577. ;
  8578. if(settings.detachable && $module.parent()[0] !== $context[0]) {
  8579. $module
  8580. .detach()
  8581. .prependTo($context)
  8582. ;
  8583. }
  8584. if(settings.displayTime > 0) {
  8585. setTimeout(module.hide, settings.displayTime);
  8586. }
  8587. module.show();
  8588. },
  8589. destroy: function() {
  8590. module.verbose('Destroying instance');
  8591. $module
  8592. .removeData(moduleNamespace)
  8593. .off(eventNamespace)
  8594. ;
  8595. },
  8596. show: function() {
  8597. if( module.should.show() && !$module.is(':visible') ) {
  8598. module.debug('Showing nag', settings.animation.show);
  8599. if(settings.animation.show == 'fade') {
  8600. $module
  8601. .fadeIn(settings.duration, settings.easing)
  8602. ;
  8603. }
  8604. else {
  8605. $module
  8606. .slideDown(settings.duration, settings.easing)
  8607. ;
  8608. }
  8609. }
  8610. },
  8611. hide: function() {
  8612. module.debug('Showing nag', settings.animation.hide);
  8613. if(settings.animation.show == 'fade') {
  8614. $module
  8615. .fadeIn(settings.duration, settings.easing)
  8616. ;
  8617. }
  8618. else {
  8619. $module
  8620. .slideUp(settings.duration, settings.easing)
  8621. ;
  8622. }
  8623. },
  8624. onHide: function() {
  8625. module.debug('Removing nag', settings.animation.hide);
  8626. $module.remove();
  8627. if (settings.onHide) {
  8628. settings.onHide();
  8629. }
  8630. },
  8631. dismiss: function(event) {
  8632. if(settings.storageMethod) {
  8633. module.storage.set(settings.key, settings.value);
  8634. }
  8635. module.hide();
  8636. event.stopImmediatePropagation();
  8637. event.preventDefault();
  8638. },
  8639. should: {
  8640. show: function() {
  8641. if(settings.persist) {
  8642. module.debug('Persistent nag is set, can show nag');
  8643. return true;
  8644. }
  8645. if( module.storage.get(settings.key) != settings.value.toString() ) {
  8646. module.debug('Stored value is not set, can show nag', module.storage.get(settings.key));
  8647. return true;
  8648. }
  8649. module.debug('Stored value is set, cannot show nag', module.storage.get(settings.key));
  8650. return false;
  8651. }
  8652. },
  8653. get: {
  8654. storageOptions: function() {
  8655. var
  8656. options = {}
  8657. ;
  8658. if(settings.expires) {
  8659. options.expires = settings.expires;
  8660. }
  8661. if(settings.domain) {
  8662. options.domain = settings.domain;
  8663. }
  8664. if(settings.path) {
  8665. options.path = settings.path;
  8666. }
  8667. return options;
  8668. }
  8669. },
  8670. clear: function() {
  8671. module.storage.remove(settings.key);
  8672. },
  8673. storage: {
  8674. set: function(key, value) {
  8675. var
  8676. options = module.get.storageOptions()
  8677. ;
  8678. if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) {
  8679. window.localStorage.setItem(key, value);
  8680. module.debug('Value stored using local storage', key, value);
  8681. }
  8682. else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) {
  8683. window.sessionStorage.setItem(key, value);
  8684. module.debug('Value stored using session storage', key, value);
  8685. }
  8686. else if($.cookie !== undefined) {
  8687. $.cookie(key, value, options);
  8688. module.debug('Value stored using cookie', key, value, options);
  8689. }
  8690. else {
  8691. module.error(error.noCookieStorage);
  8692. return;
  8693. }
  8694. },
  8695. get: function(key, value) {
  8696. var
  8697. storedValue
  8698. ;
  8699. if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) {
  8700. storedValue = window.localStorage.getItem(key);
  8701. }
  8702. else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) {
  8703. storedValue = window.sessionStorage.getItem(key);
  8704. }
  8705. // get by cookie
  8706. else if($.cookie !== undefined) {
  8707. storedValue = $.cookie(key);
  8708. }
  8709. else {
  8710. module.error(error.noCookieStorage);
  8711. }
  8712. if(storedValue == 'undefined' || storedValue == 'null' || storedValue === undefined || storedValue === null) {
  8713. storedValue = undefined;
  8714. }
  8715. return storedValue;
  8716. },
  8717. remove: function(key) {
  8718. var
  8719. options = module.get.storageOptions()
  8720. ;
  8721. if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) {
  8722. window.localStorage.removeItem(key);
  8723. }
  8724. else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) {
  8725. window.sessionStorage.removeItem(key);
  8726. }
  8727. // store by cookie
  8728. else if($.cookie !== undefined) {
  8729. $.removeCookie(key, options);
  8730. }
  8731. else {
  8732. module.error(error.noStorage);
  8733. }
  8734. }
  8735. },
  8736. setting: function(name, value) {
  8737. module.debug('Changing setting', name, value);
  8738. if( $.isPlainObject(name) ) {
  8739. $.extend(true, settings, name);
  8740. }
  8741. else if(value !== undefined) {
  8742. settings[name] = value;
  8743. }
  8744. else {
  8745. return settings[name];
  8746. }
  8747. },
  8748. internal: function(name, value) {
  8749. if( $.isPlainObject(name) ) {
  8750. $.extend(true, module, name);
  8751. }
  8752. else if(value !== undefined) {
  8753. module[name] = value;
  8754. }
  8755. else {
  8756. return module[name];
  8757. }
  8758. },
  8759. debug: function() {
  8760. if(settings.debug) {
  8761. if(settings.performance) {
  8762. module.performance.log(arguments);
  8763. }
  8764. else {
  8765. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  8766. module.debug.apply(console, arguments);
  8767. }
  8768. }
  8769. },
  8770. verbose: function() {
  8771. if(settings.verbose && settings.debug) {
  8772. if(settings.performance) {
  8773. module.performance.log(arguments);
  8774. }
  8775. else {
  8776. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  8777. module.verbose.apply(console, arguments);
  8778. }
  8779. }
  8780. },
  8781. error: function() {
  8782. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  8783. module.error.apply(console, arguments);
  8784. },
  8785. performance: {
  8786. log: function(message) {
  8787. var
  8788. currentTime,
  8789. executionTime,
  8790. previousTime
  8791. ;
  8792. if(settings.performance) {
  8793. currentTime = new Date().getTime();
  8794. previousTime = time || currentTime;
  8795. executionTime = currentTime - previousTime;
  8796. time = currentTime;
  8797. performance.push({
  8798. 'Name' : message[0],
  8799. 'Arguments' : [].slice.call(message, 1) || '',
  8800. 'Element' : element,
  8801. 'Execution Time' : executionTime
  8802. });
  8803. }
  8804. clearTimeout(module.performance.timer);
  8805. module.performance.timer = setTimeout(module.performance.display, 500);
  8806. },
  8807. display: function() {
  8808. var
  8809. title = settings.name + ':',
  8810. totalTime = 0
  8811. ;
  8812. time = false;
  8813. clearTimeout(module.performance.timer);
  8814. $.each(performance, function(index, data) {
  8815. totalTime += data['Execution Time'];
  8816. });
  8817. title += ' ' + totalTime + 'ms';
  8818. if(moduleSelector) {
  8819. title += ' \'' + moduleSelector + '\'';
  8820. }
  8821. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  8822. console.groupCollapsed(title);
  8823. if(console.table) {
  8824. console.table(performance);
  8825. }
  8826. else {
  8827. $.each(performance, function(index, data) {
  8828. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  8829. });
  8830. }
  8831. console.groupEnd();
  8832. }
  8833. performance = [];
  8834. }
  8835. },
  8836. invoke: function(query, passedArguments, context) {
  8837. var
  8838. object = instance,
  8839. maxDepth,
  8840. found,
  8841. response
  8842. ;
  8843. passedArguments = passedArguments || queryArguments;
  8844. context = element || context;
  8845. if(typeof query == 'string' && object !== undefined) {
  8846. query = query.split(/[\. ]/);
  8847. maxDepth = query.length - 1;
  8848. $.each(query, function(depth, value) {
  8849. var camelCaseValue = (depth != maxDepth)
  8850. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  8851. : query
  8852. ;
  8853. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  8854. object = object[camelCaseValue];
  8855. }
  8856. else if( object[camelCaseValue] !== undefined ) {
  8857. found = object[camelCaseValue];
  8858. return false;
  8859. }
  8860. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  8861. object = object[value];
  8862. }
  8863. else if( object[value] !== undefined ) {
  8864. found = object[value];
  8865. return false;
  8866. }
  8867. else {
  8868. module.error(error.method, query);
  8869. return false;
  8870. }
  8871. });
  8872. }
  8873. if ( $.isFunction( found ) ) {
  8874. response = found.apply(context, passedArguments);
  8875. }
  8876. else if(found !== undefined) {
  8877. response = found;
  8878. }
  8879. if($.isArray(returnedValue)) {
  8880. returnedValue.push(response);
  8881. }
  8882. else if(returnedValue !== undefined) {
  8883. returnedValue = [returnedValue, response];
  8884. }
  8885. else if(response !== undefined) {
  8886. returnedValue = response;
  8887. }
  8888. return found;
  8889. }
  8890. };
  8891. if(methodInvoked) {
  8892. if(instance === undefined) {
  8893. module.initialize();
  8894. }
  8895. module.invoke(query);
  8896. }
  8897. else {
  8898. if(instance !== undefined) {
  8899. instance.invoke('destroy');
  8900. }
  8901. module.initialize();
  8902. }
  8903. })
  8904. ;
  8905. return (returnedValue !== undefined)
  8906. ? returnedValue
  8907. : this
  8908. ;
  8909. };
  8910. $.fn.nag.settings = {
  8911. name : 'Nag',
  8912. debug : false,
  8913. verbose : false,
  8914. performance : true,
  8915. namespace : 'Nag',
  8916. // allows cookie to be overriden
  8917. persist : false,
  8918. // set to zero to require manually dismissal, otherwise hides on its own
  8919. displayTime : 0,
  8920. animation : {
  8921. show : 'slide',
  8922. hide : 'slide'
  8923. },
  8924. context : false,
  8925. detachable : false,
  8926. expires : 30,
  8927. domain : false,
  8928. path : '/',
  8929. // type of storage to use
  8930. storageMethod : 'cookie',
  8931. // value to store in dismissed localstorage/cookie
  8932. key : 'nag',
  8933. value : 'dismiss',
  8934. error: {
  8935. noCookieStorage : '$.cookie is not included. A storage solution is required.',
  8936. noStorage : 'Neither $.cookie or store is defined. A storage solution is required for storing state',
  8937. method : 'The method you called is not defined.'
  8938. },
  8939. className : {
  8940. bottom : 'bottom',
  8941. fixed : 'fixed'
  8942. },
  8943. selector : {
  8944. close : '.close.icon'
  8945. },
  8946. speed : 500,
  8947. easing : 'easeOutQuad',
  8948. onHide: function() {}
  8949. };
  8950. })( jQuery, window , document );
  8951. /*!
  8952. * # Semantic UI 2.1.4 - Popup
  8953. * http://github.com/semantic-org/semantic-ui/
  8954. *
  8955. *
  8956. * Copyright 2015 Contributors
  8957. * Released under the MIT license
  8958. * http://opensource.org/licenses/MIT
  8959. *
  8960. */
  8961. ;(function ($, window, document, undefined) {
  8962. "use strict";
  8963. $.fn.popup = function(parameters) {
  8964. var
  8965. $allModules = $(this),
  8966. $document = $(document),
  8967. $window = $(window),
  8968. $body = $('body'),
  8969. moduleSelector = $allModules.selector || '',
  8970. hasTouch = (true),
  8971. time = new Date().getTime(),
  8972. performance = [],
  8973. query = arguments[0],
  8974. methodInvoked = (typeof query == 'string'),
  8975. queryArguments = [].slice.call(arguments, 1),
  8976. returnedValue
  8977. ;
  8978. $allModules
  8979. .each(function() {
  8980. var
  8981. settings = ( $.isPlainObject(parameters) )
  8982. ? $.extend(true, {}, $.fn.popup.settings, parameters)
  8983. : $.extend({}, $.fn.popup.settings),
  8984. selector = settings.selector,
  8985. className = settings.className,
  8986. error = settings.error,
  8987. metadata = settings.metadata,
  8988. namespace = settings.namespace,
  8989. eventNamespace = '.' + settings.namespace,
  8990. moduleNamespace = 'module-' + namespace,
  8991. $module = $(this),
  8992. $context = $(settings.context),
  8993. $target = (settings.target)
  8994. ? $(settings.target)
  8995. : $module,
  8996. $popup,
  8997. $offsetParent,
  8998. searchDepth = 0,
  8999. triedPositions = false,
  9000. openedWithTouch = false,
  9001. element = this,
  9002. instance = $module.data(moduleNamespace),
  9003. elementNamespace,
  9004. id,
  9005. module
  9006. ;
  9007. module = {
  9008. // binds events
  9009. initialize: function() {
  9010. module.debug('Initializing', $module);
  9011. module.createID();
  9012. module.bind.events();
  9013. if( !module.exists() && settings.preserve) {
  9014. module.create();
  9015. }
  9016. module.instantiate();
  9017. },
  9018. instantiate: function() {
  9019. module.verbose('Storing instance', module);
  9020. instance = module;
  9021. $module
  9022. .data(moduleNamespace, instance)
  9023. ;
  9024. },
  9025. refresh: function() {
  9026. if(settings.popup) {
  9027. $popup = $(settings.popup).eq(0);
  9028. }
  9029. else {
  9030. if(settings.inline) {
  9031. $popup = $target.nextAll(selector.popup).eq(0);
  9032. settings.popup = $popup;
  9033. }
  9034. }
  9035. if(settings.popup) {
  9036. $popup.addClass(className.loading);
  9037. $offsetParent = module.get.offsetParent();
  9038. $popup.removeClass(className.loading);
  9039. if(settings.movePopup && module.has.popup() && module.get.offsetParent($popup)[0] !== $offsetParent[0]) {
  9040. module.debug('Moving popup to the same offset parent as activating element');
  9041. $popup
  9042. .detach()
  9043. .appendTo($offsetParent)
  9044. ;
  9045. }
  9046. }
  9047. else {
  9048. $offsetParent = (settings.inline)
  9049. ? module.get.offsetParent($target)
  9050. : module.has.popup()
  9051. ? module.get.offsetParent($popup)
  9052. : $body
  9053. ;
  9054. }
  9055. if( $offsetParent.is('html') && $offsetParent[0] !== $body[0] ) {
  9056. module.debug('Setting page as offset parent');
  9057. $offsetParent = $body;
  9058. }
  9059. if( module.get.variation() ) {
  9060. module.set.variation();
  9061. }
  9062. },
  9063. reposition: function() {
  9064. module.refresh();
  9065. module.set.position();
  9066. },
  9067. destroy: function() {
  9068. module.debug('Destroying previous module');
  9069. // remove element only if was created dynamically
  9070. if($popup && !settings.preserve) {
  9071. module.removePopup();
  9072. }
  9073. // clear all timeouts
  9074. clearTimeout(module.hideTimer);
  9075. clearTimeout(module.showTimer);
  9076. // remove events
  9077. $window.off(elementNamespace);
  9078. $module
  9079. .off(eventNamespace)
  9080. .removeData(moduleNamespace)
  9081. ;
  9082. },
  9083. event: {
  9084. start: function(event) {
  9085. var
  9086. delay = ($.isPlainObject(settings.delay))
  9087. ? settings.delay.show
  9088. : settings.delay
  9089. ;
  9090. clearTimeout(module.hideTimer);
  9091. if(!openedWithTouch) {
  9092. module.showTimer = setTimeout(module.show, delay);
  9093. }
  9094. },
  9095. end: function() {
  9096. var
  9097. delay = ($.isPlainObject(settings.delay))
  9098. ? settings.delay.hide
  9099. : settings.delay
  9100. ;
  9101. clearTimeout(module.showTimer);
  9102. module.hideTimer = setTimeout(module.hide, delay);
  9103. },
  9104. touchstart: function(event) {
  9105. openedWithTouch = true;
  9106. module.show();
  9107. },
  9108. resize: function() {
  9109. if( module.is.visible() ) {
  9110. module.set.position();
  9111. }
  9112. },
  9113. hideGracefully: function(event) {
  9114. // don't close on clicks inside popup
  9115. if(event && $(event.target).closest(selector.popup).length === 0) {
  9116. module.debug('Click occurred outside popup hiding popup');
  9117. module.hide();
  9118. }
  9119. else {
  9120. module.debug('Click was inside popup, keeping popup open');
  9121. }
  9122. }
  9123. },
  9124. // generates popup html from metadata
  9125. create: function() {
  9126. var
  9127. html = module.get.html(),
  9128. title = module.get.title(),
  9129. content = module.get.content()
  9130. ;
  9131. if(html || content || title) {
  9132. module.debug('Creating pop-up html');
  9133. if(!html) {
  9134. html = settings.templates.popup({
  9135. title : title,
  9136. content : content
  9137. });
  9138. }
  9139. $popup = $('<div/>')
  9140. .addClass(className.popup)
  9141. .data(metadata.activator, $module)
  9142. .html(html)
  9143. ;
  9144. if(settings.inline) {
  9145. module.verbose('Inserting popup element inline', $popup);
  9146. $popup
  9147. .insertAfter($module)
  9148. ;
  9149. }
  9150. else {
  9151. module.verbose('Appending popup element to body', $popup);
  9152. $popup
  9153. .appendTo( $context )
  9154. ;
  9155. }
  9156. module.refresh();
  9157. module.set.variation();
  9158. if(settings.hoverable) {
  9159. module.bind.popup();
  9160. }
  9161. settings.onCreate.call($popup, element);
  9162. }
  9163. else if($target.next(selector.popup).length !== 0) {
  9164. module.verbose('Pre-existing popup found');
  9165. settings.inline = true;
  9166. settings.popups = $target.next(selector.popup).data(metadata.activator, $module);
  9167. module.refresh();
  9168. if(settings.hoverable) {
  9169. module.bind.popup();
  9170. }
  9171. }
  9172. else if(settings.popup) {
  9173. $(settings.popup).data(metadata.activator, $module);
  9174. module.verbose('Used popup specified in settings');
  9175. module.refresh();
  9176. if(settings.hoverable) {
  9177. module.bind.popup();
  9178. }
  9179. }
  9180. else {
  9181. module.debug('No content specified skipping display', element);
  9182. }
  9183. },
  9184. createID: function() {
  9185. id = (Math.random().toString(16) + '000000000').substr(2,8);
  9186. elementNamespace = '.' + id;
  9187. module.verbose('Creating unique id for element', id);
  9188. },
  9189. // determines popup state
  9190. toggle: function() {
  9191. module.debug('Toggling pop-up');
  9192. if( module.is.hidden() ) {
  9193. module.debug('Popup is hidden, showing pop-up');
  9194. module.unbind.close();
  9195. module.show();
  9196. }
  9197. else {
  9198. module.debug('Popup is visible, hiding pop-up');
  9199. module.hide();
  9200. }
  9201. },
  9202. show: function(callback) {
  9203. callback = callback || function(){};
  9204. module.debug('Showing pop-up', settings.transition);
  9205. if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) {
  9206. if( !module.exists() ) {
  9207. module.create();
  9208. }
  9209. if(settings.onShow.call($popup, element) === false) {
  9210. module.debug('onShow callback returned false, cancelling popup animation');
  9211. return;
  9212. }
  9213. else if(!settings.preserve && !settings.popup) {
  9214. module.refresh();
  9215. }
  9216. if( $popup && module.set.position() ) {
  9217. module.save.conditions();
  9218. if(settings.exclusive) {
  9219. module.hideAll();
  9220. }
  9221. module.animate.show(callback);
  9222. }
  9223. }
  9224. },
  9225. hide: function(callback) {
  9226. callback = callback || function(){};
  9227. if( module.is.visible() || module.is.animating() ) {
  9228. if(settings.onHide.call($popup, element) === false) {
  9229. module.debug('onHide callback returned false, cancelling popup animation');
  9230. return;
  9231. }
  9232. module.remove.visible();
  9233. module.unbind.close();
  9234. module.restore.conditions();
  9235. module.animate.hide(callback);
  9236. }
  9237. },
  9238. hideAll: function() {
  9239. $(selector.popup)
  9240. .filter('.' + className.visible)
  9241. .each(function() {
  9242. $(this)
  9243. .data(metadata.activator)
  9244. .popup('hide')
  9245. ;
  9246. })
  9247. ;
  9248. },
  9249. exists: function() {
  9250. if(!$popup) {
  9251. return false;
  9252. }
  9253. if(settings.inline || settings.popup) {
  9254. return ( module.has.popup() );
  9255. }
  9256. else {
  9257. return ( $popup.closest($context).length >= 1 )
  9258. ? true
  9259. : false
  9260. ;
  9261. }
  9262. },
  9263. removePopup: function() {
  9264. if( module.has.popup() && !settings.popup) {
  9265. module.debug('Removing popup', $popup);
  9266. $popup.remove();
  9267. $popup = undefined;
  9268. settings.onRemove.call($popup, element);
  9269. }
  9270. },
  9271. save: {
  9272. conditions: function() {
  9273. module.cache = {
  9274. title: $module.attr('title')
  9275. };
  9276. if (module.cache.title) {
  9277. $module.removeAttr('title');
  9278. }
  9279. module.verbose('Saving original attributes', module.cache.title);
  9280. }
  9281. },
  9282. restore: {
  9283. conditions: function() {
  9284. if(module.cache && module.cache.title) {
  9285. $module.attr('title', module.cache.title);
  9286. module.verbose('Restoring original attributes', module.cache.title);
  9287. }
  9288. return true;
  9289. }
  9290. },
  9291. animate: {
  9292. show: function(callback) {
  9293. callback = $.isFunction(callback) ? callback : function(){};
  9294. if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  9295. module.set.visible();
  9296. $popup
  9297. .transition({
  9298. animation : settings.transition + ' in',
  9299. queue : false,
  9300. debug : settings.debug,
  9301. verbose : settings.verbose,
  9302. duration : settings.duration,
  9303. onComplete : function() {
  9304. module.bind.close();
  9305. callback.call($popup, element);
  9306. settings.onVisible.call($popup, element);
  9307. }
  9308. })
  9309. ;
  9310. }
  9311. else {
  9312. module.error(error.noTransition);
  9313. }
  9314. },
  9315. hide: function(callback) {
  9316. callback = $.isFunction(callback) ? callback : function(){};
  9317. module.debug('Hiding pop-up');
  9318. if(settings.onHide.call($popup, element) === false) {
  9319. module.debug('onHide callback returned false, cancelling popup animation');
  9320. return;
  9321. }
  9322. if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  9323. $popup
  9324. .transition({
  9325. animation : settings.transition + ' out',
  9326. queue : false,
  9327. duration : settings.duration,
  9328. debug : settings.debug,
  9329. verbose : settings.verbose,
  9330. onComplete : function() {
  9331. module.reset();
  9332. callback.call($popup, element);
  9333. settings.onHidden.call($popup, element);
  9334. }
  9335. })
  9336. ;
  9337. }
  9338. else {
  9339. module.error(error.noTransition);
  9340. }
  9341. }
  9342. },
  9343. get: {
  9344. html: function() {
  9345. $module.removeData(metadata.html);
  9346. return $module.data(metadata.html) || settings.html;
  9347. },
  9348. title: function() {
  9349. $module.removeData(metadata.title);
  9350. return $module.data(metadata.title) || settings.title;
  9351. },
  9352. content: function() {
  9353. $module.removeData(metadata.content);
  9354. return $module.data(metadata.content) || $module.attr('title') || settings.content;
  9355. },
  9356. variation: function() {
  9357. $module.removeData(metadata.variation);
  9358. return $module.data(metadata.variation) || settings.variation;
  9359. },
  9360. popupOffset: function() {
  9361. return $popup.offset();
  9362. },
  9363. calculations: function() {
  9364. var
  9365. targetElement = $target[0],
  9366. targetPosition = (settings.inline || settings.popup)
  9367. ? $target.position()
  9368. : $target.offset(),
  9369. calculations = {},
  9370. screen
  9371. ;
  9372. calculations = {
  9373. // element which is launching popup
  9374. target : {
  9375. element : $target[0],
  9376. width : $target.outerWidth(),
  9377. height : $target.outerHeight(),
  9378. top : targetPosition.top,
  9379. left : targetPosition.left,
  9380. margin : {}
  9381. },
  9382. // popup itself
  9383. popup : {
  9384. width : $popup.outerWidth(),
  9385. height : $popup.outerHeight()
  9386. },
  9387. // offset container (or 3d context)
  9388. parent : {
  9389. width : $offsetParent.outerWidth(),
  9390. height : $offsetParent.outerHeight()
  9391. },
  9392. // screen boundaries
  9393. screen : {
  9394. scroll: {
  9395. top : $window.scrollTop(),
  9396. left : $window.scrollLeft()
  9397. },
  9398. width : $window.width(),
  9399. height : $window.height()
  9400. }
  9401. };
  9402. // add in container calcs if fluid
  9403. if( settings.setFluidWidth && module.is.fluid() ) {
  9404. calculations.container = {
  9405. width: $popup.parent().outerWidth()
  9406. };
  9407. calculations.popup.width = calculations.container.width;
  9408. }
  9409. // add in margins if inline
  9410. calculations.target.margin.top = (settings.inline)
  9411. ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10)
  9412. : 0
  9413. ;
  9414. calculations.target.margin.left = (settings.inline)
  9415. ? module.is.rtl()
  9416. ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-right'), 10)
  9417. : parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-left') , 10)
  9418. : 0
  9419. ;
  9420. // calculate screen boundaries
  9421. screen = calculations.screen;
  9422. calculations.boundary = {
  9423. top : screen.scroll.top,
  9424. bottom : screen.scroll.top + screen.height,
  9425. left : screen.scroll.left,
  9426. right : screen.scroll.left + screen.width
  9427. };
  9428. return calculations;
  9429. },
  9430. id: function() {
  9431. return id;
  9432. },
  9433. startEvent: function() {
  9434. if(settings.on == 'hover') {
  9435. return 'mouseenter';
  9436. }
  9437. else if(settings.on == 'focus') {
  9438. return 'focus';
  9439. }
  9440. return false;
  9441. },
  9442. scrollEvent: function() {
  9443. return 'scroll';
  9444. },
  9445. endEvent: function() {
  9446. if(settings.on == 'hover') {
  9447. return 'mouseleave';
  9448. }
  9449. else if(settings.on == 'focus') {
  9450. return 'blur';
  9451. }
  9452. return false;
  9453. },
  9454. distanceFromBoundary: function(offset, calculations) {
  9455. var
  9456. distanceFromBoundary = {},
  9457. popup,
  9458. boundary
  9459. ;
  9460. offset = offset || module.get.offset();
  9461. calculations = calculations || module.get.calculations();
  9462. // shorthand
  9463. popup = calculations.popup;
  9464. boundary = calculations.boundary;
  9465. if(offset) {
  9466. distanceFromBoundary = {
  9467. top : (offset.top - boundary.top),
  9468. left : (offset.left - boundary.left),
  9469. right : (boundary.right - (offset.left + popup.width) ),
  9470. bottom : (boundary.bottom - (offset.top + popup.height) )
  9471. };
  9472. module.verbose('Distance from boundaries determined', offset, distanceFromBoundary);
  9473. }
  9474. return distanceFromBoundary;
  9475. },
  9476. offsetParent: function($target) {
  9477. var
  9478. element = ($target !== undefined)
  9479. ? $target[0]
  9480. : $module[0],
  9481. parentNode = element.parentNode,
  9482. $node = $(parentNode)
  9483. ;
  9484. if(parentNode) {
  9485. var
  9486. is2D = ($node.css('transform') === 'none'),
  9487. isStatic = ($node.css('position') === 'static'),
  9488. isHTML = $node.is('html')
  9489. ;
  9490. while(parentNode && !isHTML && isStatic && is2D) {
  9491. parentNode = parentNode.parentNode;
  9492. $node = $(parentNode);
  9493. is2D = ($node.css('transform') === 'none');
  9494. isStatic = ($node.css('position') === 'static');
  9495. isHTML = $node.is('html');
  9496. }
  9497. }
  9498. return ($node && $node.length > 0)
  9499. ? $node
  9500. : $()
  9501. ;
  9502. },
  9503. positions: function() {
  9504. return {
  9505. 'top left' : false,
  9506. 'top center' : false,
  9507. 'top right' : false,
  9508. 'bottom left' : false,
  9509. 'bottom center' : false,
  9510. 'bottom right' : false,
  9511. 'left center' : false,
  9512. 'right center' : false
  9513. };
  9514. },
  9515. nextPosition: function(position) {
  9516. var
  9517. positions = position.split(' '),
  9518. verticalPosition = positions[0],
  9519. horizontalPosition = positions[1],
  9520. opposite = {
  9521. top : 'bottom',
  9522. bottom : 'top',
  9523. left : 'right',
  9524. right : 'left'
  9525. },
  9526. adjacent = {
  9527. left : 'center',
  9528. center : 'right',
  9529. right : 'left'
  9530. },
  9531. backup = {
  9532. 'top left' : 'top center',
  9533. 'top center' : 'top right',
  9534. 'top right' : 'right center',
  9535. 'right center' : 'bottom right',
  9536. 'bottom right' : 'bottom center',
  9537. 'bottom center' : 'bottom left',
  9538. 'bottom left' : 'left center',
  9539. 'left center' : 'top left'
  9540. },
  9541. adjacentsAvailable = (verticalPosition == 'top' || verticalPosition == 'bottom'),
  9542. oppositeTried = false,
  9543. adjacentTried = false,
  9544. nextPosition = false
  9545. ;
  9546. if(!triedPositions) {
  9547. module.verbose('All available positions available');
  9548. triedPositions = module.get.positions();
  9549. }
  9550. module.debug('Recording last position tried', position);
  9551. triedPositions[position] = true;
  9552. if(settings.prefer === 'opposite') {
  9553. nextPosition = [opposite[verticalPosition], horizontalPosition];
  9554. nextPosition = nextPosition.join(' ');
  9555. oppositeTried = (triedPositions[nextPosition] === true);
  9556. module.debug('Trying opposite strategy', nextPosition);
  9557. }
  9558. if((settings.prefer === 'adjacent') && adjacentsAvailable ) {
  9559. nextPosition = [verticalPosition, adjacent[horizontalPosition]];
  9560. nextPosition = nextPosition.join(' ');
  9561. adjacentTried = (triedPositions[nextPosition] === true);
  9562. module.debug('Trying adjacent strategy', nextPosition);
  9563. }
  9564. if(adjacentTried || oppositeTried) {
  9565. module.debug('Using backup position', nextPosition);
  9566. nextPosition = backup[position];
  9567. }
  9568. return nextPosition;
  9569. }
  9570. },
  9571. set: {
  9572. position: function(position, calculations) {
  9573. // exit conditions
  9574. if($target.length === 0 || $popup.length === 0) {
  9575. module.error(error.notFound);
  9576. return;
  9577. }
  9578. var
  9579. offset,
  9580. distanceAway,
  9581. target,
  9582. popup,
  9583. parent,
  9584. positioning,
  9585. popupOffset,
  9586. distanceFromBoundary
  9587. ;
  9588. calculations = calculations || module.get.calculations();
  9589. position = position || $module.data(metadata.position) || settings.position;
  9590. offset = $module.data(metadata.offset) || settings.offset;
  9591. distanceAway = settings.distanceAway;
  9592. // shorthand
  9593. target = calculations.target;
  9594. popup = calculations.popup;
  9595. parent = calculations.parent;
  9596. if(target.width === 0 && target.height === 0) {
  9597. module.debug('Popup target is hidden, no action taken');
  9598. return false;
  9599. }
  9600. if(settings.inline) {
  9601. module.debug('Adding margin to calculation', target.margin);
  9602. if(position == 'left center' || position == 'right center') {
  9603. offset += target.margin.top;
  9604. distanceAway += -target.margin.left;
  9605. }
  9606. else if (position == 'top left' || position == 'top center' || position == 'top right') {
  9607. offset += target.margin.left;
  9608. distanceAway -= target.margin.top;
  9609. }
  9610. else {
  9611. offset += target.margin.left;
  9612. distanceAway += target.margin.top;
  9613. }
  9614. }
  9615. module.debug('Determining popup position from calculations', position, calculations);
  9616. if (module.is.rtl()) {
  9617. position = position.replace(/left|right/g, function (match) {
  9618. return (match == 'left')
  9619. ? 'right'
  9620. : 'left'
  9621. ;
  9622. });
  9623. module.debug('RTL: Popup position updated', position);
  9624. }
  9625. // if last attempt use specified last resort position
  9626. if(searchDepth == settings.maxSearchDepth && typeof settings.lastResort === 'string') {
  9627. position = settings.lastResort;
  9628. }
  9629. switch (position) {
  9630. case 'top left':
  9631. positioning = {
  9632. top : 'auto',
  9633. bottom : parent.height - target.top + distanceAway,
  9634. left : target.left + offset,
  9635. right : 'auto'
  9636. };
  9637. break;
  9638. case 'top center':
  9639. positioning = {
  9640. bottom : parent.height - target.top + distanceAway,
  9641. left : target.left + (target.width / 2) - (popup.width / 2) + offset,
  9642. top : 'auto',
  9643. right : 'auto'
  9644. };
  9645. break;
  9646. case 'top right':
  9647. positioning = {
  9648. bottom : parent.height - target.top + distanceAway,
  9649. right : parent.width - target.left - target.width - offset,
  9650. top : 'auto',
  9651. left : 'auto'
  9652. };
  9653. break;
  9654. case 'left center':
  9655. positioning = {
  9656. top : target.top + (target.height / 2) - (popup.height / 2) + offset,
  9657. right : parent.width - target.left + distanceAway,
  9658. left : 'auto',
  9659. bottom : 'auto'
  9660. };
  9661. break;
  9662. case 'right center':
  9663. positioning = {
  9664. top : target.top + (target.height / 2) - (popup.height / 2) + offset,
  9665. left : target.left + target.width + distanceAway,
  9666. bottom : 'auto',
  9667. right : 'auto'
  9668. };
  9669. break;
  9670. case 'bottom left':
  9671. positioning = {
  9672. top : target.top + target.height + distanceAway,
  9673. left : target.left + offset,
  9674. bottom : 'auto',
  9675. right : 'auto'
  9676. };
  9677. break;
  9678. case 'bottom center':
  9679. positioning = {
  9680. top : target.top + target.height + distanceAway,
  9681. left : target.left + (target.width / 2) - (popup.width / 2) + offset,
  9682. bottom : 'auto',
  9683. right : 'auto'
  9684. };
  9685. break;
  9686. case 'bottom right':
  9687. positioning = {
  9688. top : target.top + target.height + distanceAway,
  9689. right : parent.width - target.left - target.width - offset,
  9690. left : 'auto',
  9691. bottom : 'auto'
  9692. };
  9693. break;
  9694. }
  9695. if(positioning === undefined) {
  9696. module.error(error.invalidPosition, position);
  9697. }
  9698. module.debug('Calculated popup positioning values', positioning);
  9699. // tentatively place on stage
  9700. $popup
  9701. .css(positioning)
  9702. .removeClass(className.position)
  9703. .addClass(position)
  9704. .addClass(className.loading)
  9705. ;
  9706. popupOffset = module.get.popupOffset();
  9707. // see if any boundaries are surpassed with this tentative position
  9708. distanceFromBoundary = module.get.distanceFromBoundary(popupOffset, calculations);
  9709. if( module.is.offstage(distanceFromBoundary, position) ) {
  9710. module.debug('Position is outside viewport', position);
  9711. if(searchDepth < settings.maxSearchDepth) {
  9712. searchDepth++;
  9713. position = module.get.nextPosition(position);
  9714. module.debug('Trying new position', position);
  9715. return ($popup)
  9716. ? module.set.position(position, calculations)
  9717. : false
  9718. ;
  9719. }
  9720. else {
  9721. if(settings.lastResort) {
  9722. module.debug('No position found, showing with last position');
  9723. }
  9724. else {
  9725. module.debug('Popup could not find a position to display', $popup);
  9726. module.error(error.cannotPlace, element);
  9727. module.remove.attempts();
  9728. module.remove.loading();
  9729. module.reset();
  9730. return false;
  9731. }
  9732. }
  9733. }
  9734. module.debug('Position is on stage', position);
  9735. module.remove.attempts();
  9736. module.remove.loading();
  9737. if( settings.setFluidWidth && module.is.fluid() ) {
  9738. module.set.fluidWidth(calculations);
  9739. }
  9740. return true;
  9741. },
  9742. fluidWidth: function(calculations) {
  9743. calculations = calculations || module.get.calculations();
  9744. module.debug('Automatically setting element width to parent width', calculations.parent.width);
  9745. $popup.css('width', calculations.container.width);
  9746. },
  9747. variation: function(variation) {
  9748. variation = variation || module.get.variation();
  9749. if(variation && module.has.popup() ) {
  9750. module.verbose('Adding variation to popup', variation);
  9751. $popup.addClass(variation);
  9752. }
  9753. },
  9754. visible: function() {
  9755. $module.addClass(className.visible);
  9756. }
  9757. },
  9758. remove: {
  9759. loading: function() {
  9760. $popup.removeClass(className.loading);
  9761. },
  9762. variation: function(variation) {
  9763. variation = variation || module.get.variation();
  9764. if(variation) {
  9765. module.verbose('Removing variation', variation);
  9766. $popup.removeClass(variation);
  9767. }
  9768. },
  9769. visible: function() {
  9770. $module.removeClass(className.visible);
  9771. },
  9772. attempts: function() {
  9773. module.verbose('Resetting all searched positions');
  9774. searchDepth = 0;
  9775. triedPositions = false;
  9776. }
  9777. },
  9778. bind: {
  9779. events: function() {
  9780. module.debug('Binding popup events to module');
  9781. if(settings.on == 'click') {
  9782. $module
  9783. .on('click' + eventNamespace, module.toggle)
  9784. ;
  9785. }
  9786. if(settings.on == 'hover' && hasTouch) {
  9787. $module
  9788. .on('touchstart' + eventNamespace, module.event.touchstart)
  9789. ;
  9790. }
  9791. if( module.get.startEvent() ) {
  9792. $module
  9793. .on(module.get.startEvent() + eventNamespace, module.event.start)
  9794. .on(module.get.endEvent() + eventNamespace, module.event.end)
  9795. ;
  9796. }
  9797. if(settings.target) {
  9798. module.debug('Target set to element', $target);
  9799. }
  9800. $window.on('resize' + elementNamespace, module.event.resize);
  9801. },
  9802. popup: function() {
  9803. module.verbose('Allowing hover events on popup to prevent closing');
  9804. if( $popup && module.has.popup() ) {
  9805. $popup
  9806. .on('mouseenter' + eventNamespace, module.event.start)
  9807. .on('mouseleave' + eventNamespace, module.event.end)
  9808. ;
  9809. }
  9810. },
  9811. close: function() {
  9812. if(settings.hideOnScroll === true || (settings.hideOnScroll == 'auto' && settings.on != 'click')) {
  9813. $document
  9814. .one(module.get.scrollEvent() + elementNamespace, module.event.hideGracefully)
  9815. ;
  9816. $context
  9817. .one(module.get.scrollEvent() + elementNamespace, module.event.hideGracefully)
  9818. ;
  9819. }
  9820. if(settings.on == 'hover' && openedWithTouch) {
  9821. module.verbose('Binding popup close event to document');
  9822. $document
  9823. .on('touchstart' + elementNamespace, function(event) {
  9824. module.verbose('Touched away from popup');
  9825. module.event.hideGracefully.call(element, event);
  9826. })
  9827. ;
  9828. }
  9829. if(settings.on == 'click' && settings.closable) {
  9830. module.verbose('Binding popup close event to document');
  9831. $document
  9832. .on('click' + elementNamespace, function(event) {
  9833. module.verbose('Clicked away from popup');
  9834. module.event.hideGracefully.call(element, event);
  9835. })
  9836. ;
  9837. }
  9838. }
  9839. },
  9840. unbind: {
  9841. close: function() {
  9842. if(settings.hideOnScroll === true || (settings.hideOnScroll == 'auto' && settings.on != 'click')) {
  9843. $document
  9844. .off('scroll' + elementNamespace, module.hide)
  9845. ;
  9846. $context
  9847. .off('scroll' + elementNamespace, module.hide)
  9848. ;
  9849. }
  9850. if(settings.on == 'hover' && openedWithTouch) {
  9851. $document
  9852. .off('touchstart' + elementNamespace)
  9853. ;
  9854. openedWithTouch = false;
  9855. }
  9856. if(settings.on == 'click' && settings.closable) {
  9857. module.verbose('Removing close event from document');
  9858. $document
  9859. .off('click' + elementNamespace)
  9860. ;
  9861. }
  9862. }
  9863. },
  9864. has: {
  9865. popup: function() {
  9866. return ($popup && $popup.length > 0);
  9867. }
  9868. },
  9869. is: {
  9870. offstage: function(distanceFromBoundary, position) {
  9871. var
  9872. offstage = []
  9873. ;
  9874. // return boundaries that have been surpassed
  9875. $.each(distanceFromBoundary, function(direction, distance) {
  9876. if(distance < -settings.jitter) {
  9877. module.debug('Position exceeds allowable distance from edge', direction, distance, position);
  9878. offstage.push(direction);
  9879. }
  9880. });
  9881. if(offstage.length > 0) {
  9882. return true;
  9883. }
  9884. else {
  9885. return false;
  9886. }
  9887. },
  9888. active: function() {
  9889. return $module.hasClass(className.active);
  9890. },
  9891. animating: function() {
  9892. return ( $popup && $popup.hasClass(className.animating) );
  9893. },
  9894. fluid: function() {
  9895. return ( $popup && $popup.hasClass(className.fluid));
  9896. },
  9897. visible: function() {
  9898. return $popup && $popup.hasClass(className.visible);
  9899. },
  9900. dropdown: function() {
  9901. return $module.hasClass(className.dropdown);
  9902. },
  9903. hidden: function() {
  9904. return !module.is.visible();
  9905. },
  9906. rtl: function () {
  9907. return $module.css('direction') == 'rtl';
  9908. }
  9909. },
  9910. reset: function() {
  9911. module.remove.visible();
  9912. if(settings.preserve) {
  9913. if($.fn.transition !== undefined) {
  9914. $popup
  9915. .transition('remove transition')
  9916. ;
  9917. }
  9918. }
  9919. else {
  9920. module.removePopup();
  9921. }
  9922. },
  9923. setting: function(name, value) {
  9924. if( $.isPlainObject(name) ) {
  9925. $.extend(true, settings, name);
  9926. }
  9927. else if(value !== undefined) {
  9928. settings[name] = value;
  9929. }
  9930. else {
  9931. return settings[name];
  9932. }
  9933. },
  9934. internal: function(name, value) {
  9935. if( $.isPlainObject(name) ) {
  9936. $.extend(true, module, name);
  9937. }
  9938. else if(value !== undefined) {
  9939. module[name] = value;
  9940. }
  9941. else {
  9942. return module[name];
  9943. }
  9944. },
  9945. debug: function() {
  9946. if(settings.debug) {
  9947. if(settings.performance) {
  9948. module.performance.log(arguments);
  9949. }
  9950. else {
  9951. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  9952. module.debug.apply(console, arguments);
  9953. }
  9954. }
  9955. },
  9956. verbose: function() {
  9957. if(settings.verbose && settings.debug) {
  9958. if(settings.performance) {
  9959. module.performance.log(arguments);
  9960. }
  9961. else {
  9962. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  9963. module.verbose.apply(console, arguments);
  9964. }
  9965. }
  9966. },
  9967. error: function() {
  9968. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  9969. module.error.apply(console, arguments);
  9970. },
  9971. performance: {
  9972. log: function(message) {
  9973. var
  9974. currentTime,
  9975. executionTime,
  9976. previousTime
  9977. ;
  9978. if(settings.performance) {
  9979. currentTime = new Date().getTime();
  9980. previousTime = time || currentTime;
  9981. executionTime = currentTime - previousTime;
  9982. time = currentTime;
  9983. performance.push({
  9984. 'Name' : message[0],
  9985. 'Arguments' : [].slice.call(message, 1) || '',
  9986. 'Element' : element,
  9987. 'Execution Time' : executionTime
  9988. });
  9989. }
  9990. clearTimeout(module.performance.timer);
  9991. module.performance.timer = setTimeout(module.performance.display, 500);
  9992. },
  9993. display: function() {
  9994. var
  9995. title = settings.name + ':',
  9996. totalTime = 0
  9997. ;
  9998. time = false;
  9999. clearTimeout(module.performance.timer);
  10000. $.each(performance, function(index, data) {
  10001. totalTime += data['Execution Time'];
  10002. });
  10003. title += ' ' + totalTime + 'ms';
  10004. if(moduleSelector) {
  10005. title += ' \'' + moduleSelector + '\'';
  10006. }
  10007. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  10008. console.groupCollapsed(title);
  10009. if(console.table) {
  10010. console.table(performance);
  10011. }
  10012. else {
  10013. $.each(performance, function(index, data) {
  10014. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  10015. });
  10016. }
  10017. console.groupEnd();
  10018. }
  10019. performance = [];
  10020. }
  10021. },
  10022. invoke: function(query, passedArguments, context) {
  10023. var
  10024. object = instance,
  10025. maxDepth,
  10026. found,
  10027. response
  10028. ;
  10029. passedArguments = passedArguments || queryArguments;
  10030. context = element || context;
  10031. if(typeof query == 'string' && object !== undefined) {
  10032. query = query.split(/[\. ]/);
  10033. maxDepth = query.length - 1;
  10034. $.each(query, function(depth, value) {
  10035. var camelCaseValue = (depth != maxDepth)
  10036. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  10037. : query
  10038. ;
  10039. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  10040. object = object[camelCaseValue];
  10041. }
  10042. else if( object[camelCaseValue] !== undefined ) {
  10043. found = object[camelCaseValue];
  10044. return false;
  10045. }
  10046. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  10047. object = object[value];
  10048. }
  10049. else if( object[value] !== undefined ) {
  10050. found = object[value];
  10051. return false;
  10052. }
  10053. else {
  10054. return false;
  10055. }
  10056. });
  10057. }
  10058. if ( $.isFunction( found ) ) {
  10059. response = found.apply(context, passedArguments);
  10060. }
  10061. else if(found !== undefined) {
  10062. response = found;
  10063. }
  10064. if($.isArray(returnedValue)) {
  10065. returnedValue.push(response);
  10066. }
  10067. else if(returnedValue !== undefined) {
  10068. returnedValue = [returnedValue, response];
  10069. }
  10070. else if(response !== undefined) {
  10071. returnedValue = response;
  10072. }
  10073. return found;
  10074. }
  10075. };
  10076. if(methodInvoked) {
  10077. if(instance === undefined) {
  10078. module.initialize();
  10079. }
  10080. module.invoke(query);
  10081. }
  10082. else {
  10083. if(instance !== undefined) {
  10084. instance.invoke('destroy');
  10085. }
  10086. module.initialize();
  10087. }
  10088. })
  10089. ;
  10090. return (returnedValue !== undefined)
  10091. ? returnedValue
  10092. : this
  10093. ;
  10094. };
  10095. $.fn.popup.settings = {
  10096. name : 'Popup',
  10097. // module settings
  10098. debug : false,
  10099. verbose : false,
  10100. performance : true,
  10101. namespace : 'popup',
  10102. // callback only when element added to dom
  10103. onCreate : function(){},
  10104. // callback before element removed from dom
  10105. onRemove : function(){},
  10106. // callback before show animation
  10107. onShow : function(){},
  10108. // callback after show animation
  10109. onVisible : function(){},
  10110. // callback before hide animation
  10111. onHide : function(){},
  10112. // callback after hide animation
  10113. onHidden : function(){},
  10114. // when to show popup
  10115. on : 'hover',
  10116. // whether to add touchstart events when using hover
  10117. addTouchEvents : true,
  10118. // default position relative to element
  10119. position : 'top left',
  10120. // name of variation to use
  10121. variation : '',
  10122. // whether popup should be moved to context
  10123. movePopup : true,
  10124. // element which popup should be relative to
  10125. target : false,
  10126. // jq selector or element that should be used as popup
  10127. popup : false,
  10128. // popup should remain inline next to activator
  10129. inline : false,
  10130. // popup should be removed from page on hide
  10131. preserve : false,
  10132. // popup should not close when being hovered on
  10133. hoverable : false,
  10134. // explicitly set content
  10135. content : false,
  10136. // explicitly set html
  10137. html : false,
  10138. // explicitly set title
  10139. title : false,
  10140. // whether automatically close on clickaway when on click
  10141. closable : true,
  10142. // automatically hide on scroll
  10143. hideOnScroll : 'auto',
  10144. // hide other popups on show
  10145. exclusive : false,
  10146. // context to attach popups
  10147. context : 'body',
  10148. // position to prefer when calculating new position
  10149. prefer : 'opposite',
  10150. // specify position to appear even if it doesn't fit
  10151. lastResort : false,
  10152. // delay used to prevent accidental refiring of animations due to user error
  10153. delay : {
  10154. show : 50,
  10155. hide : 70
  10156. },
  10157. // whether fluid variation should assign width explicitly
  10158. setFluidWidth : true,
  10159. // transition settings
  10160. duration : 200,
  10161. transition : 'scale',
  10162. // distance away from activating element in px
  10163. distanceAway : 0,
  10164. // number of pixels an element is allowed to be "offstage" for a position to be chosen (allows for rounding)
  10165. jitter : 2,
  10166. // offset on aligning axis from calculated position
  10167. offset : 0,
  10168. // maximum times to look for a position before failing (9 positions total)
  10169. maxSearchDepth : 15,
  10170. error: {
  10171. invalidPosition : 'The position you specified is not a valid position',
  10172. cannotPlace : 'Popup does not fit within the boundaries of the viewport',
  10173. method : 'The method you called is not defined.',
  10174. noTransition : 'This module requires ui transitions <https://github.com/Semantic-Org/UI-Transition>',
  10175. notFound : 'The target or popup you specified does not exist on the page'
  10176. },
  10177. metadata: {
  10178. activator : 'activator',
  10179. content : 'content',
  10180. html : 'html',
  10181. offset : 'offset',
  10182. position : 'position',
  10183. title : 'title',
  10184. variation : 'variation'
  10185. },
  10186. className : {
  10187. active : 'active',
  10188. animating : 'animating',
  10189. dropdown : 'dropdown',
  10190. fluid : 'fluid',
  10191. loading : 'loading',
  10192. popup : 'ui popup',
  10193. position : 'top left center bottom right',
  10194. visible : 'visible'
  10195. },
  10196. selector : {
  10197. popup : '.ui.popup'
  10198. },
  10199. templates: {
  10200. escape: function(string) {
  10201. var
  10202. badChars = /[&<>"'`]/g,
  10203. shouldEscape = /[&<>"'`]/,
  10204. escape = {
  10205. "&": "&amp;",
  10206. "<": "&lt;",
  10207. ">": "&gt;",
  10208. '"': "&quot;",
  10209. "'": "&#x27;",
  10210. "`": "&#x60;"
  10211. },
  10212. escapedChar = function(chr) {
  10213. return escape[chr];
  10214. }
  10215. ;
  10216. if(shouldEscape.test(string)) {
  10217. return string.replace(badChars, escapedChar);
  10218. }
  10219. return string;
  10220. },
  10221. popup: function(text) {
  10222. var
  10223. html = '',
  10224. escape = $.fn.popup.settings.templates.escape
  10225. ;
  10226. if(typeof text !== undefined) {
  10227. if(typeof text.title !== undefined && text.title) {
  10228. text.title = escape(text.title);
  10229. html += '<div class="header">' + text.title + '</div>';
  10230. }
  10231. if(typeof text.content !== undefined && text.content) {
  10232. text.content = escape(text.content);
  10233. html += '<div class="content">' + text.content + '</div>';
  10234. }
  10235. }
  10236. return html;
  10237. }
  10238. }
  10239. };
  10240. })( jQuery, window , document );
  10241. /*!
  10242. * # Semantic UI 2.1.4 - Progress
  10243. * http://github.com/semantic-org/semantic-ui/
  10244. *
  10245. *
  10246. * Copyright 2015 Contributors
  10247. * Released under the MIT license
  10248. * http://opensource.org/licenses/MIT
  10249. *
  10250. */
  10251. ;(function ( $, window, document, undefined ) {
  10252. "use strict";
  10253. $.fn.progress = function(parameters) {
  10254. var
  10255. $allModules = $(this),
  10256. moduleSelector = $allModules.selector || '',
  10257. time = new Date().getTime(),
  10258. performance = [],
  10259. query = arguments[0],
  10260. methodInvoked = (typeof query == 'string'),
  10261. queryArguments = [].slice.call(arguments, 1),
  10262. returnedValue
  10263. ;
  10264. $allModules
  10265. .each(function() {
  10266. var
  10267. settings = ( $.isPlainObject(parameters) )
  10268. ? $.extend(true, {}, $.fn.progress.settings, parameters)
  10269. : $.extend({}, $.fn.progress.settings),
  10270. className = settings.className,
  10271. metadata = settings.metadata,
  10272. namespace = settings.namespace,
  10273. selector = settings.selector,
  10274. error = settings.error,
  10275. eventNamespace = '.' + namespace,
  10276. moduleNamespace = 'module-' + namespace,
  10277. $module = $(this),
  10278. $bar = $(this).find(selector.bar),
  10279. $progress = $(this).find(selector.progress),
  10280. $label = $(this).find(selector.label),
  10281. element = this,
  10282. instance = $module.data(moduleNamespace),
  10283. animating = false,
  10284. transitionEnd,
  10285. module
  10286. ;
  10287. module = {
  10288. initialize: function() {
  10289. module.debug('Initializing progress bar', settings);
  10290. module.set.duration();
  10291. module.set.transitionEvent();
  10292. module.read.metadata();
  10293. module.read.settings();
  10294. module.instantiate();
  10295. },
  10296. instantiate: function() {
  10297. module.verbose('Storing instance of progress', module);
  10298. instance = module;
  10299. $module
  10300. .data(moduleNamespace, module)
  10301. ;
  10302. },
  10303. destroy: function() {
  10304. module.verbose('Destroying previous progress for', $module);
  10305. clearInterval(instance.interval);
  10306. module.remove.state();
  10307. $module.removeData(moduleNamespace);
  10308. instance = undefined;
  10309. },
  10310. reset: function() {
  10311. module.set.percent(0);
  10312. },
  10313. complete: function() {
  10314. if(module.percent === undefined || module.percent < 100) {
  10315. module.set.percent(100);
  10316. }
  10317. },
  10318. read: {
  10319. metadata: function() {
  10320. var
  10321. data = {
  10322. percent : $module.data(metadata.percent),
  10323. total : $module.data(metadata.total),
  10324. value : $module.data(metadata.value)
  10325. }
  10326. ;
  10327. if(data.percent) {
  10328. module.debug('Current percent value set from metadata', data.percent);
  10329. module.set.percent(data.percent);
  10330. }
  10331. if(data.total) {
  10332. module.debug('Total value set from metadata', data.total);
  10333. module.set.total(data.total);
  10334. }
  10335. if(data.value) {
  10336. module.debug('Current value set from metadata', data.value);
  10337. module.set.value(data.value);
  10338. module.set.progress(data.value);
  10339. }
  10340. },
  10341. settings: function() {
  10342. if(settings.total !== false) {
  10343. module.debug('Current total set in settings', settings.total);
  10344. module.set.total(settings.total);
  10345. }
  10346. if(settings.value !== false) {
  10347. module.debug('Current value set in settings', settings.value);
  10348. module.set.value(settings.value);
  10349. module.set.progress(module.value);
  10350. }
  10351. if(settings.percent !== false) {
  10352. module.debug('Current percent set in settings', settings.percent);
  10353. module.set.percent(settings.percent);
  10354. }
  10355. }
  10356. },
  10357. increment: function(incrementValue) {
  10358. var
  10359. maxValue,
  10360. startValue,
  10361. newValue
  10362. ;
  10363. if( module.has.total() ) {
  10364. startValue = module.get.value();
  10365. incrementValue = incrementValue || 1;
  10366. newValue = startValue + incrementValue;
  10367. maxValue = module.get.total();
  10368. module.debug('Incrementing value', startValue, newValue, maxValue);
  10369. if(newValue > maxValue ) {
  10370. module.debug('Value cannot increment above total', maxValue);
  10371. newValue = maxValue;
  10372. }
  10373. }
  10374. else {
  10375. startValue = module.get.percent();
  10376. incrementValue = incrementValue || module.get.randomValue();
  10377. newValue = startValue + incrementValue;
  10378. maxValue = 100;
  10379. module.debug('Incrementing percentage by', startValue, newValue);
  10380. if(newValue > maxValue ) {
  10381. module.debug('Value cannot increment above 100 percent');
  10382. newValue = maxValue;
  10383. }
  10384. }
  10385. module.set.progress(newValue);
  10386. },
  10387. decrement: function(decrementValue) {
  10388. var
  10389. total = module.get.total(),
  10390. startValue,
  10391. newValue
  10392. ;
  10393. if(total) {
  10394. startValue = module.get.value();
  10395. decrementValue = decrementValue || 1;
  10396. newValue = startValue - decrementValue;
  10397. module.debug('Decrementing value by', decrementValue, startValue);
  10398. }
  10399. else {
  10400. startValue = module.get.percent();
  10401. decrementValue = decrementValue || module.get.randomValue();
  10402. newValue = startValue - decrementValue;
  10403. module.debug('Decrementing percentage by', decrementValue, startValue);
  10404. }
  10405. if(newValue < 0) {
  10406. module.debug('Value cannot decrement below 0');
  10407. newValue = 0;
  10408. }
  10409. module.set.progress(newValue);
  10410. },
  10411. has: {
  10412. total: function() {
  10413. return (module.get.total() !== false);
  10414. }
  10415. },
  10416. get: {
  10417. text: function(templateText) {
  10418. var
  10419. value = module.value || 0,
  10420. total = module.total || 0,
  10421. percent = (animating)
  10422. ? module.get.displayPercent()
  10423. : module.percent || 0,
  10424. left = (module.total > 0)
  10425. ? (total - value)
  10426. : (100 - percent)
  10427. ;
  10428. templateText = templateText || '';
  10429. templateText = templateText
  10430. .replace('{value}', value)
  10431. .replace('{total}', total)
  10432. .replace('{left}', left)
  10433. .replace('{percent}', percent)
  10434. ;
  10435. module.debug('Adding variables to progress bar text', templateText);
  10436. return templateText;
  10437. },
  10438. randomValue: function() {
  10439. module.debug('Generating random increment percentage');
  10440. return Math.floor((Math.random() * settings.random.max) + settings.random.min);
  10441. },
  10442. numericValue: function(value) {
  10443. return (typeof value === 'string')
  10444. ? (value.replace(/[^\d.]/g, '') !== '')
  10445. ? +(value.replace(/[^\d.]/g, ''))
  10446. : false
  10447. : value
  10448. ;
  10449. },
  10450. transitionEnd: function() {
  10451. var
  10452. element = document.createElement('element'),
  10453. transitions = {
  10454. 'transition' :'transitionend',
  10455. 'OTransition' :'oTransitionEnd',
  10456. 'MozTransition' :'transitionend',
  10457. 'WebkitTransition' :'webkitTransitionEnd'
  10458. },
  10459. transition
  10460. ;
  10461. for(transition in transitions){
  10462. if( element.style[transition] !== undefined ){
  10463. return transitions[transition];
  10464. }
  10465. }
  10466. },
  10467. // gets current displayed percentage (if animating values this is the intermediary value)
  10468. displayPercent: function() {
  10469. var
  10470. barWidth = $bar.width(),
  10471. totalWidth = $module.width(),
  10472. minDisplay = parseInt($bar.css('min-width'), 10),
  10473. displayPercent = (barWidth > minDisplay)
  10474. ? (barWidth / totalWidth * 100)
  10475. : module.percent
  10476. ;
  10477. return (settings.precision > 0)
  10478. ? Math.round(displayPercent * (10 * settings.precision)) / (10 * settings.precision)
  10479. : Math.round(displayPercent)
  10480. ;
  10481. },
  10482. percent: function() {
  10483. return module.percent || 0;
  10484. },
  10485. value: function() {
  10486. return module.value || 0;
  10487. },
  10488. total: function() {
  10489. return module.total || false;
  10490. }
  10491. },
  10492. is: {
  10493. success: function() {
  10494. return $module.hasClass(className.success);
  10495. },
  10496. warning: function() {
  10497. return $module.hasClass(className.warning);
  10498. },
  10499. error: function() {
  10500. return $module.hasClass(className.error);
  10501. },
  10502. active: function() {
  10503. return $module.hasClass(className.active);
  10504. },
  10505. visible: function() {
  10506. return $module.is(':visible');
  10507. }
  10508. },
  10509. remove: {
  10510. state: function() {
  10511. module.verbose('Removing stored state');
  10512. delete module.total;
  10513. delete module.percent;
  10514. delete module.value;
  10515. },
  10516. active: function() {
  10517. module.verbose('Removing active state');
  10518. $module.removeClass(className.active);
  10519. },
  10520. success: function() {
  10521. module.verbose('Removing success state');
  10522. $module.removeClass(className.success);
  10523. },
  10524. warning: function() {
  10525. module.verbose('Removing warning state');
  10526. $module.removeClass(className.warning);
  10527. },
  10528. error: function() {
  10529. module.verbose('Removing error state');
  10530. $module.removeClass(className.error);
  10531. }
  10532. },
  10533. set: {
  10534. barWidth: function(value) {
  10535. if(value > 100) {
  10536. module.error(error.tooHigh, value);
  10537. }
  10538. else if (value < 0) {
  10539. module.error(error.tooLow, value);
  10540. }
  10541. else {
  10542. $bar
  10543. .css('width', value + '%')
  10544. ;
  10545. $module
  10546. .attr('data-percent', parseInt(value, 10))
  10547. ;
  10548. }
  10549. },
  10550. duration: function(duration) {
  10551. duration = duration || settings.duration;
  10552. duration = (typeof duration == 'number')
  10553. ? duration + 'ms'
  10554. : duration
  10555. ;
  10556. module.verbose('Setting progress bar transition duration', duration);
  10557. $bar
  10558. .css({
  10559. 'transition-duration': duration
  10560. })
  10561. ;
  10562. },
  10563. percent: function(percent) {
  10564. percent = (typeof percent == 'string')
  10565. ? +(percent.replace('%', ''))
  10566. : percent
  10567. ;
  10568. // round display percentage
  10569. percent = (settings.precision > 0)
  10570. ? Math.round(percent * (10 * settings.precision)) / (10 * settings.precision)
  10571. : Math.round(percent)
  10572. ;
  10573. module.percent = percent;
  10574. if( !module.has.total() ) {
  10575. module.value = (settings.precision > 0)
  10576. ? Math.round( (percent / 100) * module.total * (10 * settings.precision)) / (10 * settings.precision)
  10577. : Math.round( (percent / 100) * module.total * 10) / 10
  10578. ;
  10579. if(settings.limitValues) {
  10580. module.value = (module.value > 100)
  10581. ? 100
  10582. : (module.value < 0)
  10583. ? 0
  10584. : module.value
  10585. ;
  10586. }
  10587. }
  10588. module.set.barWidth(percent);
  10589. module.set.labelInterval();
  10590. module.set.labels();
  10591. settings.onChange.call(element, percent, module.value, module.total);
  10592. },
  10593. labelInterval: function() {
  10594. var
  10595. animationCallback = function() {
  10596. module.verbose('Bar finished animating, removing continuous label updates');
  10597. clearInterval(module.interval);
  10598. animating = false;
  10599. module.set.labels();
  10600. }
  10601. ;
  10602. clearInterval(module.interval);
  10603. $bar.one(transitionEnd + eventNamespace, animationCallback);
  10604. module.timer = setTimeout(animationCallback, settings.duration + 100);
  10605. animating = true;
  10606. module.interval = setInterval(module.set.labels, settings.framerate);
  10607. },
  10608. labels: function() {
  10609. module.verbose('Setting both bar progress and outer label text');
  10610. module.set.barLabel();
  10611. module.set.state();
  10612. },
  10613. label: function(text) {
  10614. text = text || '';
  10615. if(text) {
  10616. text = module.get.text(text);
  10617. module.debug('Setting label to text', text);
  10618. $label.text(text);
  10619. }
  10620. },
  10621. state: function(percent) {
  10622. percent = (percent !== undefined)
  10623. ? percent
  10624. : module.percent
  10625. ;
  10626. if(percent === 100) {
  10627. if(settings.autoSuccess && !(module.is.warning() || module.is.error())) {
  10628. module.set.success();
  10629. module.debug('Automatically triggering success at 100%');
  10630. }
  10631. else {
  10632. module.verbose('Reached 100% removing active state');
  10633. module.remove.active();
  10634. }
  10635. }
  10636. else if(percent > 0) {
  10637. module.verbose('Adjusting active progress bar label', percent);
  10638. module.set.active();
  10639. }
  10640. else {
  10641. module.remove.active();
  10642. module.set.label(settings.text.active);
  10643. }
  10644. },
  10645. barLabel: function(text) {
  10646. if(text !== undefined) {
  10647. $progress.text( module.get.text(text) );
  10648. }
  10649. else if(settings.label == 'ratio' && module.total) {
  10650. module.debug('Adding ratio to bar label');
  10651. $progress.text( module.get.text(settings.text.ratio) );
  10652. }
  10653. else if(settings.label == 'percent') {
  10654. module.debug('Adding percentage to bar label');
  10655. $progress.text( module.get.text(settings.text.percent) );
  10656. }
  10657. },
  10658. active: function(text) {
  10659. text = text || settings.text.active;
  10660. module.debug('Setting active state');
  10661. if(settings.showActivity && !module.is.active() ) {
  10662. $module.addClass(className.active);
  10663. }
  10664. module.remove.warning();
  10665. module.remove.error();
  10666. module.remove.success();
  10667. if(text) {
  10668. module.set.label(text);
  10669. }
  10670. settings.onActive.call(element, module.value, module.total);
  10671. },
  10672. success : function(text) {
  10673. text = text || settings.text.success;
  10674. module.debug('Setting success state');
  10675. $module.addClass(className.success);
  10676. module.remove.active();
  10677. module.remove.warning();
  10678. module.remove.error();
  10679. module.complete();
  10680. if(text) {
  10681. module.set.label(text);
  10682. }
  10683. settings.onSuccess.call(element, module.total);
  10684. },
  10685. warning : function(text) {
  10686. text = text || settings.text.warning;
  10687. module.debug('Setting warning state');
  10688. $module.addClass(className.warning);
  10689. module.remove.active();
  10690. module.remove.success();
  10691. module.remove.error();
  10692. module.complete();
  10693. if(text) {
  10694. module.set.label(text);
  10695. }
  10696. settings.onWarning.call(element, module.value, module.total);
  10697. },
  10698. error : function(text) {
  10699. text = text || settings.text.error;
  10700. module.debug('Setting error state');
  10701. $module.addClass(className.error);
  10702. module.remove.active();
  10703. module.remove.success();
  10704. module.remove.warning();
  10705. module.complete();
  10706. if(text) {
  10707. module.set.label(text);
  10708. }
  10709. settings.onError.call(element, module.value, module.total);
  10710. },
  10711. transitionEvent: function() {
  10712. transitionEnd = module.get.transitionEnd();
  10713. },
  10714. total: function(totalValue) {
  10715. module.total = totalValue;
  10716. },
  10717. value: function(value) {
  10718. module.value = value;
  10719. },
  10720. progress: function(value) {
  10721. var
  10722. numericValue = module.get.numericValue(value),
  10723. percentComplete
  10724. ;
  10725. if(numericValue === false) {
  10726. module.error(error.nonNumeric, value);
  10727. }
  10728. if( module.has.total() ) {
  10729. module.set.value(numericValue);
  10730. percentComplete = (numericValue / module.total) * 100;
  10731. module.debug('Calculating percent complete from total', percentComplete);
  10732. module.set.percent( percentComplete );
  10733. }
  10734. else {
  10735. percentComplete = numericValue;
  10736. module.debug('Setting value to exact percentage value', percentComplete);
  10737. module.set.percent( percentComplete );
  10738. }
  10739. }
  10740. },
  10741. setting: function(name, value) {
  10742. module.debug('Changing setting', name, value);
  10743. if( $.isPlainObject(name) ) {
  10744. $.extend(true, settings, name);
  10745. }
  10746. else if(value !== undefined) {
  10747. settings[name] = value;
  10748. }
  10749. else {
  10750. return settings[name];
  10751. }
  10752. },
  10753. internal: function(name, value) {
  10754. if( $.isPlainObject(name) ) {
  10755. $.extend(true, module, name);
  10756. }
  10757. else if(value !== undefined) {
  10758. module[name] = value;
  10759. }
  10760. else {
  10761. return module[name];
  10762. }
  10763. },
  10764. debug: function() {
  10765. if(settings.debug) {
  10766. if(settings.performance) {
  10767. module.performance.log(arguments);
  10768. }
  10769. else {
  10770. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  10771. module.debug.apply(console, arguments);
  10772. }
  10773. }
  10774. },
  10775. verbose: function() {
  10776. if(settings.verbose && settings.debug) {
  10777. if(settings.performance) {
  10778. module.performance.log(arguments);
  10779. }
  10780. else {
  10781. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  10782. module.verbose.apply(console, arguments);
  10783. }
  10784. }
  10785. },
  10786. error: function() {
  10787. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  10788. module.error.apply(console, arguments);
  10789. },
  10790. performance: {
  10791. log: function(message) {
  10792. var
  10793. currentTime,
  10794. executionTime,
  10795. previousTime
  10796. ;
  10797. if(settings.performance) {
  10798. currentTime = new Date().getTime();
  10799. previousTime = time || currentTime;
  10800. executionTime = currentTime - previousTime;
  10801. time = currentTime;
  10802. performance.push({
  10803. 'Name' : message[0],
  10804. 'Arguments' : [].slice.call(message, 1) || '',
  10805. 'Element' : element,
  10806. 'Execution Time' : executionTime
  10807. });
  10808. }
  10809. clearTimeout(module.performance.timer);
  10810. module.performance.timer = setTimeout(module.performance.display, 500);
  10811. },
  10812. display: function() {
  10813. var
  10814. title = settings.name + ':',
  10815. totalTime = 0
  10816. ;
  10817. time = false;
  10818. clearTimeout(module.performance.timer);
  10819. $.each(performance, function(index, data) {
  10820. totalTime += data['Execution Time'];
  10821. });
  10822. title += ' ' + totalTime + 'ms';
  10823. if(moduleSelector) {
  10824. title += ' \'' + moduleSelector + '\'';
  10825. }
  10826. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  10827. console.groupCollapsed(title);
  10828. if(console.table) {
  10829. console.table(performance);
  10830. }
  10831. else {
  10832. $.each(performance, function(index, data) {
  10833. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  10834. });
  10835. }
  10836. console.groupEnd();
  10837. }
  10838. performance = [];
  10839. }
  10840. },
  10841. invoke: function(query, passedArguments, context) {
  10842. var
  10843. object = instance,
  10844. maxDepth,
  10845. found,
  10846. response
  10847. ;
  10848. passedArguments = passedArguments || queryArguments;
  10849. context = element || context;
  10850. if(typeof query == 'string' && object !== undefined) {
  10851. query = query.split(/[\. ]/);
  10852. maxDepth = query.length - 1;
  10853. $.each(query, function(depth, value) {
  10854. var camelCaseValue = (depth != maxDepth)
  10855. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  10856. : query
  10857. ;
  10858. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  10859. object = object[camelCaseValue];
  10860. }
  10861. else if( object[camelCaseValue] !== undefined ) {
  10862. found = object[camelCaseValue];
  10863. return false;
  10864. }
  10865. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  10866. object = object[value];
  10867. }
  10868. else if( object[value] !== undefined ) {
  10869. found = object[value];
  10870. return false;
  10871. }
  10872. else {
  10873. module.error(error.method, query);
  10874. return false;
  10875. }
  10876. });
  10877. }
  10878. if ( $.isFunction( found ) ) {
  10879. response = found.apply(context, passedArguments);
  10880. }
  10881. else if(found !== undefined) {
  10882. response = found;
  10883. }
  10884. if($.isArray(returnedValue)) {
  10885. returnedValue.push(response);
  10886. }
  10887. else if(returnedValue !== undefined) {
  10888. returnedValue = [returnedValue, response];
  10889. }
  10890. else if(response !== undefined) {
  10891. returnedValue = response;
  10892. }
  10893. return found;
  10894. }
  10895. };
  10896. if(methodInvoked) {
  10897. if(instance === undefined) {
  10898. module.initialize();
  10899. }
  10900. module.invoke(query);
  10901. }
  10902. else {
  10903. if(instance !== undefined) {
  10904. instance.invoke('destroy');
  10905. }
  10906. module.initialize();
  10907. }
  10908. })
  10909. ;
  10910. return (returnedValue !== undefined)
  10911. ? returnedValue
  10912. : this
  10913. ;
  10914. };
  10915. $.fn.progress.settings = {
  10916. name : 'Progress',
  10917. namespace : 'progress',
  10918. debug : false,
  10919. verbose : false,
  10920. performance : true,
  10921. random : {
  10922. min : 2,
  10923. max : 5
  10924. },
  10925. duration : 300,
  10926. autoSuccess : true,
  10927. showActivity : true,
  10928. limitValues : true,
  10929. label : 'percent',
  10930. precision : 0,
  10931. framerate : (1000 / 30), /// 30 fps
  10932. percent : false,
  10933. total : false,
  10934. value : false,
  10935. onChange : function(percent, value, total){},
  10936. onSuccess : function(total){},
  10937. onActive : function(value, total){},
  10938. onError : function(value, total){},
  10939. onWarning : function(value, total){},
  10940. error : {
  10941. method : 'The method you called is not defined.',
  10942. nonNumeric : 'Progress value is non numeric',
  10943. tooHigh : 'Value specified is above 100%',
  10944. tooLow : 'Value specified is below 0%'
  10945. },
  10946. regExp: {
  10947. variable: /\{\$*[A-z0-9]+\}/g
  10948. },
  10949. metadata: {
  10950. percent : 'percent',
  10951. total : 'total',
  10952. value : 'value'
  10953. },
  10954. selector : {
  10955. bar : '> .bar',
  10956. label : '> .label',
  10957. progress : '.bar > .progress'
  10958. },
  10959. text : {
  10960. active : false,
  10961. error : false,
  10962. success : false,
  10963. warning : false,
  10964. percent : '{percent}%',
  10965. ratio : '{value} of {total}'
  10966. },
  10967. className : {
  10968. active : 'active',
  10969. error : 'error',
  10970. success : 'success',
  10971. warning : 'warning'
  10972. }
  10973. };
  10974. })( jQuery, window , document );
  10975. /*!
  10976. * # Semantic UI 2.1.4 - Rating
  10977. * http://github.com/semantic-org/semantic-ui/
  10978. *
  10979. *
  10980. * Copyright 2015 Contributors
  10981. * Released under the MIT license
  10982. * http://opensource.org/licenses/MIT
  10983. *
  10984. */
  10985. ;(function ($, window, document, undefined) {
  10986. "use strict";
  10987. $.fn.rating = function(parameters) {
  10988. var
  10989. $allModules = $(this),
  10990. moduleSelector = $allModules.selector || '',
  10991. time = new Date().getTime(),
  10992. performance = [],
  10993. query = arguments[0],
  10994. methodInvoked = (typeof query == 'string'),
  10995. queryArguments = [].slice.call(arguments, 1),
  10996. returnedValue
  10997. ;
  10998. $allModules
  10999. .each(function() {
  11000. var
  11001. settings = ( $.isPlainObject(parameters) )
  11002. ? $.extend(true, {}, $.fn.rating.settings, parameters)
  11003. : $.extend({}, $.fn.rating.settings),
  11004. namespace = settings.namespace,
  11005. className = settings.className,
  11006. metadata = settings.metadata,
  11007. selector = settings.selector,
  11008. error = settings.error,
  11009. eventNamespace = '.' + namespace,
  11010. moduleNamespace = 'module-' + namespace,
  11011. element = this,
  11012. instance = $(this).data(moduleNamespace),
  11013. $module = $(this),
  11014. $icon = $module.find(selector.icon),
  11015. module
  11016. ;
  11017. module = {
  11018. initialize: function() {
  11019. module.verbose('Initializing rating module', settings);
  11020. if($icon.length === 0) {
  11021. module.setup.layout();
  11022. }
  11023. if(settings.interactive) {
  11024. module.enable();
  11025. }
  11026. else {
  11027. module.disable();
  11028. }
  11029. module.set.rating( module.get.initialRating() );
  11030. module.instantiate();
  11031. },
  11032. instantiate: function() {
  11033. module.verbose('Instantiating module', settings);
  11034. instance = module;
  11035. $module
  11036. .data(moduleNamespace, module)
  11037. ;
  11038. },
  11039. destroy: function() {
  11040. module.verbose('Destroying previous instance', instance);
  11041. module.remove.events();
  11042. $module
  11043. .removeData(moduleNamespace)
  11044. ;
  11045. },
  11046. refresh: function() {
  11047. $icon = $module.find(selector.icon);
  11048. },
  11049. setup: {
  11050. layout: function() {
  11051. var
  11052. maxRating = module.get.maxRating(),
  11053. html = $.fn.rating.settings.templates.icon(maxRating)
  11054. ;
  11055. module.debug('Generating icon html dynamically');
  11056. $module
  11057. .html(html)
  11058. ;
  11059. module.refresh();
  11060. }
  11061. },
  11062. event: {
  11063. mouseenter: function() {
  11064. var
  11065. $activeIcon = $(this)
  11066. ;
  11067. $activeIcon
  11068. .nextAll()
  11069. .removeClass(className.selected)
  11070. ;
  11071. $module
  11072. .addClass(className.selected)
  11073. ;
  11074. $activeIcon
  11075. .addClass(className.selected)
  11076. .prevAll()
  11077. .addClass(className.selected)
  11078. ;
  11079. },
  11080. mouseleave: function() {
  11081. $module
  11082. .removeClass(className.selected)
  11083. ;
  11084. $icon
  11085. .removeClass(className.selected)
  11086. ;
  11087. },
  11088. click: function() {
  11089. var
  11090. $activeIcon = $(this),
  11091. currentRating = module.get.rating(),
  11092. rating = $icon.index($activeIcon) + 1,
  11093. canClear = (settings.clearable == 'auto')
  11094. ? ($icon.length === 1)
  11095. : settings.clearable
  11096. ;
  11097. if(canClear && currentRating == rating) {
  11098. module.clearRating();
  11099. }
  11100. else {
  11101. module.set.rating( rating );
  11102. }
  11103. }
  11104. },
  11105. clearRating: function() {
  11106. module.debug('Clearing current rating');
  11107. module.set.rating(0);
  11108. },
  11109. bind: {
  11110. events: function() {
  11111. module.verbose('Binding events');
  11112. $module
  11113. .on('mouseenter' + eventNamespace, selector.icon, module.event.mouseenter)
  11114. .on('mouseleave' + eventNamespace, selector.icon, module.event.mouseleave)
  11115. .on('click' + eventNamespace, selector.icon, module.event.click)
  11116. ;
  11117. }
  11118. },
  11119. remove: {
  11120. events: function() {
  11121. module.verbose('Removing events');
  11122. $module
  11123. .off(eventNamespace)
  11124. ;
  11125. }
  11126. },
  11127. enable: function() {
  11128. module.debug('Setting rating to interactive mode');
  11129. module.bind.events();
  11130. $module
  11131. .removeClass(className.disabled)
  11132. ;
  11133. },
  11134. disable: function() {
  11135. module.debug('Setting rating to read-only mode');
  11136. module.remove.events();
  11137. $module
  11138. .addClass(className.disabled)
  11139. ;
  11140. },
  11141. get: {
  11142. initialRating: function() {
  11143. if($module.data(metadata.rating) !== undefined) {
  11144. $module.removeData(metadata.rating);
  11145. return $module.data(metadata.rating);
  11146. }
  11147. return settings.initialRating;
  11148. },
  11149. maxRating: function() {
  11150. if($module.data(metadata.maxRating) !== undefined) {
  11151. $module.removeData(metadata.maxRating);
  11152. return $module.data(metadata.maxRating);
  11153. }
  11154. return settings.maxRating;
  11155. },
  11156. rating: function() {
  11157. var
  11158. currentRating = $icon.filter('.' + className.active).length
  11159. ;
  11160. module.verbose('Current rating retrieved', currentRating);
  11161. return currentRating;
  11162. }
  11163. },
  11164. set: {
  11165. rating: function(rating) {
  11166. var
  11167. ratingIndex = (rating - 1 >= 0)
  11168. ? (rating - 1)
  11169. : 0,
  11170. $activeIcon = $icon.eq(ratingIndex)
  11171. ;
  11172. $module
  11173. .removeClass(className.selected)
  11174. ;
  11175. $icon
  11176. .removeClass(className.selected)
  11177. .removeClass(className.active)
  11178. ;
  11179. if(rating > 0) {
  11180. module.verbose('Setting current rating to', rating);
  11181. $activeIcon
  11182. .prevAll()
  11183. .andSelf()
  11184. .addClass(className.active)
  11185. ;
  11186. }
  11187. settings.onRate.call(element, rating);
  11188. }
  11189. },
  11190. setting: function(name, value) {
  11191. module.debug('Changing setting', name, value);
  11192. if( $.isPlainObject(name) ) {
  11193. $.extend(true, settings, name);
  11194. }
  11195. else if(value !== undefined) {
  11196. settings[name] = value;
  11197. }
  11198. else {
  11199. return settings[name];
  11200. }
  11201. },
  11202. internal: function(name, value) {
  11203. if( $.isPlainObject(name) ) {
  11204. $.extend(true, module, name);
  11205. }
  11206. else if(value !== undefined) {
  11207. module[name] = value;
  11208. }
  11209. else {
  11210. return module[name];
  11211. }
  11212. },
  11213. debug: function() {
  11214. if(settings.debug) {
  11215. if(settings.performance) {
  11216. module.performance.log(arguments);
  11217. }
  11218. else {
  11219. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  11220. module.debug.apply(console, arguments);
  11221. }
  11222. }
  11223. },
  11224. verbose: function() {
  11225. if(settings.verbose && settings.debug) {
  11226. if(settings.performance) {
  11227. module.performance.log(arguments);
  11228. }
  11229. else {
  11230. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  11231. module.verbose.apply(console, arguments);
  11232. }
  11233. }
  11234. },
  11235. error: function() {
  11236. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  11237. module.error.apply(console, arguments);
  11238. },
  11239. performance: {
  11240. log: function(message) {
  11241. var
  11242. currentTime,
  11243. executionTime,
  11244. previousTime
  11245. ;
  11246. if(settings.performance) {
  11247. currentTime = new Date().getTime();
  11248. previousTime = time || currentTime;
  11249. executionTime = currentTime - previousTime;
  11250. time = currentTime;
  11251. performance.push({
  11252. 'Name' : message[0],
  11253. 'Arguments' : [].slice.call(message, 1) || '',
  11254. 'Element' : element,
  11255. 'Execution Time' : executionTime
  11256. });
  11257. }
  11258. clearTimeout(module.performance.timer);
  11259. module.performance.timer = setTimeout(module.performance.display, 500);
  11260. },
  11261. display: function() {
  11262. var
  11263. title = settings.name + ':',
  11264. totalTime = 0
  11265. ;
  11266. time = false;
  11267. clearTimeout(module.performance.timer);
  11268. $.each(performance, function(index, data) {
  11269. totalTime += data['Execution Time'];
  11270. });
  11271. title += ' ' + totalTime + 'ms';
  11272. if(moduleSelector) {
  11273. title += ' \'' + moduleSelector + '\'';
  11274. }
  11275. if($allModules.length > 1) {
  11276. title += ' ' + '(' + $allModules.length + ')';
  11277. }
  11278. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  11279. console.groupCollapsed(title);
  11280. if(console.table) {
  11281. console.table(performance);
  11282. }
  11283. else {
  11284. $.each(performance, function(index, data) {
  11285. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  11286. });
  11287. }
  11288. console.groupEnd();
  11289. }
  11290. performance = [];
  11291. }
  11292. },
  11293. invoke: function(query, passedArguments, context) {
  11294. var
  11295. object = instance,
  11296. maxDepth,
  11297. found,
  11298. response
  11299. ;
  11300. passedArguments = passedArguments || queryArguments;
  11301. context = element || context;
  11302. if(typeof query == 'string' && object !== undefined) {
  11303. query = query.split(/[\. ]/);
  11304. maxDepth = query.length - 1;
  11305. $.each(query, function(depth, value) {
  11306. var camelCaseValue = (depth != maxDepth)
  11307. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  11308. : query
  11309. ;
  11310. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  11311. object = object[camelCaseValue];
  11312. }
  11313. else if( object[camelCaseValue] !== undefined ) {
  11314. found = object[camelCaseValue];
  11315. return false;
  11316. }
  11317. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  11318. object = object[value];
  11319. }
  11320. else if( object[value] !== undefined ) {
  11321. found = object[value];
  11322. return false;
  11323. }
  11324. else {
  11325. return false;
  11326. }
  11327. });
  11328. }
  11329. if ( $.isFunction( found ) ) {
  11330. response = found.apply(context, passedArguments);
  11331. }
  11332. else if(found !== undefined) {
  11333. response = found;
  11334. }
  11335. if($.isArray(returnedValue)) {
  11336. returnedValue.push(response);
  11337. }
  11338. else if(returnedValue !== undefined) {
  11339. returnedValue = [returnedValue, response];
  11340. }
  11341. else if(response !== undefined) {
  11342. returnedValue = response;
  11343. }
  11344. return found;
  11345. }
  11346. };
  11347. if(methodInvoked) {
  11348. if(instance === undefined) {
  11349. module.initialize();
  11350. }
  11351. module.invoke(query);
  11352. }
  11353. else {
  11354. if(instance !== undefined) {
  11355. instance.invoke('destroy');
  11356. }
  11357. module.initialize();
  11358. }
  11359. })
  11360. ;
  11361. return (returnedValue !== undefined)
  11362. ? returnedValue
  11363. : this
  11364. ;
  11365. };
  11366. $.fn.rating.settings = {
  11367. name : 'Rating',
  11368. namespace : 'rating',
  11369. debug : false,
  11370. verbose : false,
  11371. performance : true,
  11372. initialRating : 0,
  11373. interactive : true,
  11374. maxRating : 4,
  11375. clearable : 'auto',
  11376. onRate : function(rating){},
  11377. error : {
  11378. method : 'The method you called is not defined',
  11379. noMaximum : 'No maximum rating specified. Cannot generate HTML automatically'
  11380. },
  11381. metadata: {
  11382. rating : 'rating',
  11383. maxRating : 'maxRating'
  11384. },
  11385. className : {
  11386. active : 'active',
  11387. disabled : 'disabled',
  11388. selected : 'selected',
  11389. loading : 'loading'
  11390. },
  11391. selector : {
  11392. icon : '.icon'
  11393. },
  11394. templates: {
  11395. icon: function(maxRating) {
  11396. var
  11397. icon = 1,
  11398. html = ''
  11399. ;
  11400. while(icon <= maxRating) {
  11401. html += '<i class="icon"></i>';
  11402. icon++;
  11403. }
  11404. return html;
  11405. }
  11406. }
  11407. };
  11408. })( jQuery, window , document );
  11409. /*!
  11410. * # Semantic UI 2.1.4 - Search
  11411. * http://github.com/semantic-org/semantic-ui/
  11412. *
  11413. *
  11414. * Copyright 2015 Contributors
  11415. * Released under the MIT license
  11416. * http://opensource.org/licenses/MIT
  11417. *
  11418. */
  11419. ;(function ($, window, document, undefined) {
  11420. "use strict";
  11421. $.fn.search = function(parameters) {
  11422. var
  11423. $allModules = $(this),
  11424. moduleSelector = $allModules.selector || '',
  11425. time = new Date().getTime(),
  11426. performance = [],
  11427. query = arguments[0],
  11428. methodInvoked = (typeof query == 'string'),
  11429. queryArguments = [].slice.call(arguments, 1),
  11430. returnedValue
  11431. ;
  11432. $(this)
  11433. .each(function() {
  11434. var
  11435. settings = ( $.isPlainObject(parameters) )
  11436. ? $.extend(true, {}, $.fn.search.settings, parameters)
  11437. : $.extend({}, $.fn.search.settings),
  11438. className = settings.className,
  11439. metadata = settings.metadata,
  11440. regExp = settings.regExp,
  11441. fields = settings.fields,
  11442. selector = settings.selector,
  11443. error = settings.error,
  11444. namespace = settings.namespace,
  11445. eventNamespace = '.' + namespace,
  11446. moduleNamespace = namespace + '-module',
  11447. $module = $(this),
  11448. $prompt = $module.find(selector.prompt),
  11449. $searchButton = $module.find(selector.searchButton),
  11450. $results = $module.find(selector.results),
  11451. $result = $module.find(selector.result),
  11452. $category = $module.find(selector.category),
  11453. element = this,
  11454. instance = $module.data(moduleNamespace),
  11455. module
  11456. ;
  11457. module = {
  11458. initialize: function() {
  11459. module.verbose('Initializing module');
  11460. module.determine.searchFields();
  11461. module.bind.events();
  11462. module.set.type();
  11463. module.create.results();
  11464. module.instantiate();
  11465. },
  11466. instantiate: function() {
  11467. module.verbose('Storing instance of module', module);
  11468. instance = module;
  11469. $module
  11470. .data(moduleNamespace, module)
  11471. ;
  11472. },
  11473. destroy: function() {
  11474. module.verbose('Destroying instance');
  11475. $module
  11476. .off(eventNamespace)
  11477. .removeData(moduleNamespace)
  11478. ;
  11479. },
  11480. bind: {
  11481. events: function() {
  11482. module.verbose('Binding events to search');
  11483. if(settings.automatic) {
  11484. $module
  11485. .on(module.get.inputEvent() + eventNamespace, selector.prompt, module.event.input)
  11486. ;
  11487. $prompt
  11488. .attr('autocomplete', 'off')
  11489. ;
  11490. }
  11491. $module
  11492. // prompt
  11493. .on('focus' + eventNamespace, selector.prompt, module.event.focus)
  11494. .on('blur' + eventNamespace, selector.prompt, module.event.blur)
  11495. .on('keydown' + eventNamespace, selector.prompt, module.handleKeyboard)
  11496. // search button
  11497. .on('click' + eventNamespace, selector.searchButton, module.query)
  11498. // results
  11499. .on('mousedown' + eventNamespace, selector.results, module.event.result.mousedown)
  11500. .on('mouseup' + eventNamespace, selector.results, module.event.result.mouseup)
  11501. .on('click' + eventNamespace, selector.result, module.event.result.click)
  11502. ;
  11503. }
  11504. },
  11505. determine: {
  11506. searchFields: function() {
  11507. // this makes sure $.extend does not add specified search fields to default fields
  11508. // this is the only setting which should not extend defaults
  11509. if(parameters && parameters.searchFields !== undefined) {
  11510. settings.searchFields = parameters.searchFields;
  11511. }
  11512. }
  11513. },
  11514. event: {
  11515. input: function() {
  11516. clearTimeout(module.timer);
  11517. module.timer = setTimeout(module.query, settings.searchDelay);
  11518. },
  11519. focus: function() {
  11520. module.set.focus();
  11521. if( module.has.minimumCharacters() ) {
  11522. module.query();
  11523. if( module.can.show() ) {
  11524. module.showResults();
  11525. }
  11526. }
  11527. },
  11528. blur: function(event) {
  11529. var
  11530. pageLostFocus = (document.activeElement === this)
  11531. ;
  11532. if(!pageLostFocus && !module.resultsClicked) {
  11533. module.cancel.query();
  11534. module.remove.focus();
  11535. module.timer = setTimeout(module.hideResults, settings.hideDelay);
  11536. }
  11537. },
  11538. result: {
  11539. mousedown: function() {
  11540. module.resultsClicked = true;
  11541. },
  11542. mouseup: function() {
  11543. module.resultsClicked = false;
  11544. },
  11545. click: function(event) {
  11546. module.debug('Search result selected');
  11547. var
  11548. $result = $(this),
  11549. $title = $result.find(selector.title).eq(0),
  11550. $link = $result.find('a[href]').eq(0),
  11551. href = $link.attr('href') || false,
  11552. target = $link.attr('target') || false,
  11553. title = $title.html(),
  11554. // title is used for result lookup
  11555. value = ($title.length > 0)
  11556. ? $title.text()
  11557. : false,
  11558. results = module.get.results(),
  11559. result = $result.data(metadata.result) || module.get.result(value, results),
  11560. returnedValue
  11561. ;
  11562. if( $.isFunction(settings.onSelect) ) {
  11563. if(settings.onSelect.call(element, result, results) === false) {
  11564. module.debug('Custom onSelect callback cancelled default select action');
  11565. return;
  11566. }
  11567. }
  11568. module.hideResults();
  11569. if(value) {
  11570. module.set.value(value);
  11571. }
  11572. if(href) {
  11573. module.verbose('Opening search link found in result', $link);
  11574. if(target == '_blank' || event.ctrlKey) {
  11575. window.open(href);
  11576. }
  11577. else {
  11578. window.location.href = (href);
  11579. }
  11580. }
  11581. }
  11582. }
  11583. },
  11584. handleKeyboard: function(event) {
  11585. var
  11586. // force selector refresh
  11587. $result = $module.find(selector.result),
  11588. $category = $module.find(selector.category),
  11589. currentIndex = $result.index( $result.filter('.' + className.active) ),
  11590. resultSize = $result.length,
  11591. keyCode = event.which,
  11592. keys = {
  11593. backspace : 8,
  11594. enter : 13,
  11595. escape : 27,
  11596. upArrow : 38,
  11597. downArrow : 40
  11598. },
  11599. newIndex
  11600. ;
  11601. // search shortcuts
  11602. if(keyCode == keys.escape) {
  11603. module.verbose('Escape key pressed, blurring search field');
  11604. $prompt
  11605. .trigger('blur')
  11606. ;
  11607. }
  11608. if( module.is.visible() ) {
  11609. if(keyCode == keys.enter) {
  11610. module.verbose('Enter key pressed, selecting active result');
  11611. if( $result.filter('.' + className.active).length > 0 ) {
  11612. module.event.result.click.call($result.filter('.' + className.active), event);
  11613. event.preventDefault();
  11614. return false;
  11615. }
  11616. }
  11617. else if(keyCode == keys.upArrow) {
  11618. module.verbose('Up key pressed, changing active result');
  11619. newIndex = (currentIndex - 1 < 0)
  11620. ? currentIndex
  11621. : currentIndex - 1
  11622. ;
  11623. $category
  11624. .removeClass(className.active)
  11625. ;
  11626. $result
  11627. .removeClass(className.active)
  11628. .eq(newIndex)
  11629. .addClass(className.active)
  11630. .closest($category)
  11631. .addClass(className.active)
  11632. ;
  11633. event.preventDefault();
  11634. }
  11635. else if(keyCode == keys.downArrow) {
  11636. module.verbose('Down key pressed, changing active result');
  11637. newIndex = (currentIndex + 1 >= resultSize)
  11638. ? currentIndex
  11639. : currentIndex + 1
  11640. ;
  11641. $category
  11642. .removeClass(className.active)
  11643. ;
  11644. $result
  11645. .removeClass(className.active)
  11646. .eq(newIndex)
  11647. .addClass(className.active)
  11648. .closest($category)
  11649. .addClass(className.active)
  11650. ;
  11651. event.preventDefault();
  11652. }
  11653. }
  11654. else {
  11655. // query shortcuts
  11656. if(keyCode == keys.enter) {
  11657. module.verbose('Enter key pressed, executing query');
  11658. module.query();
  11659. module.set.buttonPressed();
  11660. $prompt.one('keyup', module.remove.buttonFocus);
  11661. }
  11662. }
  11663. },
  11664. setup: {
  11665. api: function() {
  11666. var
  11667. apiSettings = {
  11668. debug : settings.debug,
  11669. on : false,
  11670. cache : 'local',
  11671. action : 'search',
  11672. onError : module.error
  11673. },
  11674. searchHTML
  11675. ;
  11676. module.verbose('First request, initializing API');
  11677. $module.api(apiSettings);
  11678. }
  11679. },
  11680. can: {
  11681. useAPI: function() {
  11682. return $.fn.api !== undefined;
  11683. },
  11684. show: function() {
  11685. return module.is.focused() && !module.is.visible() && !module.is.empty();
  11686. },
  11687. transition: function() {
  11688. return settings.transition && $.fn.transition !== undefined && $module.transition('is supported');
  11689. }
  11690. },
  11691. is: {
  11692. empty: function() {
  11693. return ($results.html() === '');
  11694. },
  11695. visible: function() {
  11696. return ($results.filter(':visible').length > 0);
  11697. },
  11698. focused: function() {
  11699. return ($prompt.filter(':focus').length > 0);
  11700. }
  11701. },
  11702. get: {
  11703. inputEvent: function() {
  11704. var
  11705. prompt = $prompt[0],
  11706. inputEvent = (prompt !== undefined && prompt.oninput !== undefined)
  11707. ? 'input'
  11708. : (prompt !== undefined && prompt.onpropertychange !== undefined)
  11709. ? 'propertychange'
  11710. : 'keyup'
  11711. ;
  11712. return inputEvent;
  11713. },
  11714. value: function() {
  11715. return $prompt.val();
  11716. },
  11717. results: function() {
  11718. var
  11719. results = $module.data(metadata.results)
  11720. ;
  11721. return results;
  11722. },
  11723. result: function(value, results) {
  11724. var
  11725. lookupFields = ['title', 'id'],
  11726. result = false
  11727. ;
  11728. value = (value !== undefined)
  11729. ? value
  11730. : module.get.value()
  11731. ;
  11732. results = (results !== undefined)
  11733. ? results
  11734. : module.get.results()
  11735. ;
  11736. if(settings.type === 'category') {
  11737. module.debug('Finding result that matches', value);
  11738. $.each(results, function(index, category) {
  11739. if($.isArray(category.results)) {
  11740. result = module.search.object(value, category.results, lookupFields)[0];
  11741. // don't continue searching if a result is found
  11742. if(result) {
  11743. return false;
  11744. }
  11745. }
  11746. });
  11747. }
  11748. else {
  11749. module.debug('Finding result in results object', value);
  11750. result = module.search.object(value, results, lookupFields)[0];
  11751. }
  11752. return result || false;
  11753. },
  11754. },
  11755. set: {
  11756. focus: function() {
  11757. $module.addClass(className.focus);
  11758. },
  11759. loading: function() {
  11760. $module.addClass(className.loading);
  11761. },
  11762. value: function(value) {
  11763. module.verbose('Setting search input value', value);
  11764. $prompt
  11765. .val(value)
  11766. ;
  11767. },
  11768. type: function(type) {
  11769. type = type || settings.type;
  11770. if(settings.type == 'category') {
  11771. $module.addClass(settings.type);
  11772. }
  11773. },
  11774. buttonPressed: function() {
  11775. $searchButton.addClass(className.pressed);
  11776. }
  11777. },
  11778. remove: {
  11779. loading: function() {
  11780. $module.removeClass(className.loading);
  11781. },
  11782. focus: function() {
  11783. $module.removeClass(className.focus);
  11784. },
  11785. buttonPressed: function() {
  11786. $searchButton.removeClass(className.pressed);
  11787. }
  11788. },
  11789. query: function() {
  11790. var
  11791. searchTerm = module.get.value(),
  11792. cache = module.read.cache(searchTerm)
  11793. ;
  11794. if( module.has.minimumCharacters() ) {
  11795. if(cache) {
  11796. module.debug('Reading result from cache', searchTerm);
  11797. module.save.results(cache.results);
  11798. module.addResults(cache.html);
  11799. module.inject.id(cache.results);
  11800. }
  11801. else {
  11802. module.debug('Querying for', searchTerm);
  11803. if($.isPlainObject(settings.source) || $.isArray(settings.source)) {
  11804. module.search.local(searchTerm);
  11805. }
  11806. else if( module.can.useAPI() ) {
  11807. module.search.remote(searchTerm);
  11808. }
  11809. else {
  11810. module.error(error.source);
  11811. }
  11812. settings.onSearchQuery.call(element, searchTerm);
  11813. }
  11814. }
  11815. else {
  11816. module.hideResults();
  11817. }
  11818. },
  11819. search: {
  11820. local: function(searchTerm) {
  11821. var
  11822. results = module.search.object(searchTerm, settings.content),
  11823. searchHTML
  11824. ;
  11825. module.set.loading();
  11826. module.save.results(results);
  11827. module.debug('Returned local search results', results);
  11828. searchHTML = module.generateResults({
  11829. results: results
  11830. });
  11831. module.remove.loading();
  11832. module.addResults(searchHTML);
  11833. module.inject.id(results);
  11834. module.write.cache(searchTerm, {
  11835. html : searchHTML,
  11836. results : results
  11837. });
  11838. },
  11839. remote: function(searchTerm) {
  11840. var
  11841. apiSettings = {
  11842. onSuccess : function(response) {
  11843. module.parse.response.call(element, response, searchTerm);
  11844. },
  11845. onFailure: function() {
  11846. module.displayMessage(error.serverError);
  11847. },
  11848. urlData: {
  11849. query: searchTerm
  11850. }
  11851. }
  11852. ;
  11853. if( !$module.api('get request') ) {
  11854. module.setup.api();
  11855. }
  11856. $.extend(true, apiSettings, settings.apiSettings);
  11857. module.debug('Executing search', apiSettings);
  11858. module.cancel.query();
  11859. $module
  11860. .api('setting', apiSettings)
  11861. .api('query')
  11862. ;
  11863. },
  11864. object: function(searchTerm, source, searchFields) {
  11865. var
  11866. results = [],
  11867. fuzzyResults = [],
  11868. searchExp = searchTerm.toString().replace(regExp.escape, '\\$&'),
  11869. matchRegExp = new RegExp(regExp.beginsWith + searchExp, 'i'),
  11870. // avoid duplicates when pushing results
  11871. addResult = function(array, result) {
  11872. var
  11873. notResult = ($.inArray(result, results) == -1),
  11874. notFuzzyResult = ($.inArray(result, fuzzyResults) == -1)
  11875. ;
  11876. if(notResult && notFuzzyResult) {
  11877. array.push(result);
  11878. }
  11879. }
  11880. ;
  11881. source = source || settings.source;
  11882. searchFields = (searchFields !== undefined)
  11883. ? searchFields
  11884. : settings.searchFields
  11885. ;
  11886. // search fields should be array to loop correctly
  11887. if(!$.isArray(searchFields)) {
  11888. searchFields = [searchFields];
  11889. }
  11890. // exit conditions if no source
  11891. if(source === undefined || source === false) {
  11892. module.error(error.source);
  11893. return [];
  11894. }
  11895. // iterate through search fields looking for matches
  11896. $.each(searchFields, function(index, field) {
  11897. $.each(source, function(label, content) {
  11898. var
  11899. fieldExists = (typeof content[field] == 'string')
  11900. ;
  11901. if(fieldExists) {
  11902. if( content[field].search(matchRegExp) !== -1) {
  11903. // content starts with value (first in results)
  11904. addResult(results, content);
  11905. }
  11906. else if(settings.searchFullText && module.fuzzySearch(searchTerm, content[field]) ) {
  11907. // content fuzzy matches (last in results)
  11908. addResult(fuzzyResults, content);
  11909. }
  11910. }
  11911. });
  11912. });
  11913. return $.merge(results, fuzzyResults);
  11914. }
  11915. },
  11916. fuzzySearch: function(query, term) {
  11917. var
  11918. termLength = term.length,
  11919. queryLength = query.length
  11920. ;
  11921. if(typeof query !== 'string') {
  11922. return false;
  11923. }
  11924. query = query.toLowerCase();
  11925. term = term.toLowerCase();
  11926. if(queryLength > termLength) {
  11927. return false;
  11928. }
  11929. if(queryLength === termLength) {
  11930. return (query === term);
  11931. }
  11932. search: for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) {
  11933. var
  11934. queryCharacter = query.charCodeAt(characterIndex)
  11935. ;
  11936. while(nextCharacterIndex < termLength) {
  11937. if(term.charCodeAt(nextCharacterIndex++) === queryCharacter) {
  11938. continue search;
  11939. }
  11940. }
  11941. return false;
  11942. }
  11943. return true;
  11944. },
  11945. parse: {
  11946. response: function(response, searchTerm) {
  11947. var
  11948. searchHTML = module.generateResults(response)
  11949. ;
  11950. module.verbose('Parsing server response', response);
  11951. if(response !== undefined) {
  11952. if(searchTerm !== undefined && response[fields.results] !== undefined) {
  11953. module.addResults(searchHTML);
  11954. module.inject.id(response[fields.results]);
  11955. module.write.cache(searchTerm, {
  11956. html : searchHTML,
  11957. results : response[fields.results]
  11958. });
  11959. module.save.results(response[fields.results]);
  11960. }
  11961. }
  11962. }
  11963. },
  11964. cancel: {
  11965. query: function() {
  11966. if( module.can.useAPI() ) {
  11967. $module.api('abort');
  11968. }
  11969. }
  11970. },
  11971. has: {
  11972. minimumCharacters: function() {
  11973. var
  11974. searchTerm = module.get.value(),
  11975. numCharacters = searchTerm.length
  11976. ;
  11977. return (numCharacters >= settings.minCharacters);
  11978. }
  11979. },
  11980. clear: {
  11981. cache: function(value) {
  11982. var
  11983. cache = $module.data(metadata.cache)
  11984. ;
  11985. if(!value) {
  11986. module.debug('Clearing cache', value);
  11987. $module.removeData(metadata.cache);
  11988. }
  11989. else if(value && cache && cache[value]) {
  11990. module.debug('Removing value from cache', value);
  11991. delete cache[value];
  11992. $module.data(metadata.cache, cache);
  11993. }
  11994. }
  11995. },
  11996. read: {
  11997. cache: function(name) {
  11998. var
  11999. cache = $module.data(metadata.cache)
  12000. ;
  12001. if(settings.cache) {
  12002. module.verbose('Checking cache for generated html for query', name);
  12003. return (typeof cache == 'object') && (cache[name] !== undefined)
  12004. ? cache[name]
  12005. : false
  12006. ;
  12007. }
  12008. return false;
  12009. }
  12010. },
  12011. create: {
  12012. id: function(resultIndex, categoryIndex) {
  12013. var
  12014. resultID = (resultIndex + 1), // not zero indexed
  12015. categoryID = (categoryIndex + 1),
  12016. firstCharCode,
  12017. letterID,
  12018. id
  12019. ;
  12020. if(categoryIndex !== undefined) {
  12021. // start char code for "A"
  12022. letterID = String.fromCharCode(97 + categoryIndex);
  12023. id = letterID + resultID;
  12024. module.verbose('Creating category result id', id);
  12025. }
  12026. else {
  12027. id = resultID;
  12028. module.verbose('Creating result id', id);
  12029. }
  12030. return id;
  12031. },
  12032. results: function() {
  12033. if($results.length === 0) {
  12034. $results = $('<div />')
  12035. .addClass(className.results)
  12036. .appendTo($module)
  12037. ;
  12038. }
  12039. }
  12040. },
  12041. inject: {
  12042. result: function(result, resultIndex, categoryIndex) {
  12043. module.verbose('Injecting result into results');
  12044. var
  12045. $selectedResult = (categoryIndex !== undefined)
  12046. ? $results
  12047. .children().eq(categoryIndex)
  12048. .children(selector.result).eq(resultIndex)
  12049. : $results
  12050. .children(selector.result).eq(resultIndex)
  12051. ;
  12052. module.verbose('Injecting results metadata', $selectedResult);
  12053. $selectedResult
  12054. .data(metadata.result, result)
  12055. ;
  12056. },
  12057. id: function(results) {
  12058. module.debug('Injecting unique ids into results');
  12059. var
  12060. // since results may be object, we must use counters
  12061. categoryIndex = 0,
  12062. resultIndex = 0
  12063. ;
  12064. if(settings.type === 'category') {
  12065. // iterate through each category result
  12066. $.each(results, function(index, category) {
  12067. resultIndex = 0;
  12068. $.each(category.results, function(index, value) {
  12069. var
  12070. result = category.results[index]
  12071. ;
  12072. if(result.id === undefined) {
  12073. result.id = module.create.id(resultIndex, categoryIndex);
  12074. }
  12075. module.inject.result(result, resultIndex, categoryIndex);
  12076. resultIndex++;
  12077. });
  12078. categoryIndex++;
  12079. });
  12080. }
  12081. else {
  12082. // top level
  12083. $.each(results, function(index, value) {
  12084. var
  12085. result = results[index]
  12086. ;
  12087. if(result.id === undefined) {
  12088. result.id = module.create.id(resultIndex);
  12089. }
  12090. module.inject.result(result, resultIndex);
  12091. resultIndex++;
  12092. });
  12093. }
  12094. return results;
  12095. }
  12096. },
  12097. save: {
  12098. results: function(results) {
  12099. module.verbose('Saving current search results to metadata', results);
  12100. $module.data(metadata.results, results);
  12101. }
  12102. },
  12103. write: {
  12104. cache: function(name, value) {
  12105. var
  12106. cache = ($module.data(metadata.cache) !== undefined)
  12107. ? $module.data(metadata.cache)
  12108. : {}
  12109. ;
  12110. if(settings.cache) {
  12111. module.verbose('Writing generated html to cache', name, value);
  12112. cache[name] = value;
  12113. $module
  12114. .data(metadata.cache, cache)
  12115. ;
  12116. }
  12117. }
  12118. },
  12119. addResults: function(html) {
  12120. if( $.isFunction(settings.onResultsAdd) ) {
  12121. if( settings.onResultsAdd.call($results, html) === false ) {
  12122. module.debug('onResultsAdd callback cancelled default action');
  12123. return false;
  12124. }
  12125. }
  12126. $results
  12127. .html(html)
  12128. ;
  12129. if( module.can.show() ) {
  12130. module.showResults();
  12131. }
  12132. },
  12133. showResults: function() {
  12134. if(!module.is.visible()) {
  12135. if( module.can.transition() ) {
  12136. module.debug('Showing results with css animations');
  12137. $results
  12138. .transition({
  12139. animation : settings.transition + ' in',
  12140. debug : settings.debug,
  12141. verbose : settings.verbose,
  12142. duration : settings.duration,
  12143. queue : true
  12144. })
  12145. ;
  12146. }
  12147. else {
  12148. module.debug('Showing results with javascript');
  12149. $results
  12150. .stop()
  12151. .fadeIn(settings.duration, settings.easing)
  12152. ;
  12153. }
  12154. settings.onResultsOpen.call($results);
  12155. }
  12156. },
  12157. hideResults: function() {
  12158. if( module.is.visible() ) {
  12159. if( module.can.transition() ) {
  12160. module.debug('Hiding results with css animations');
  12161. $results
  12162. .transition({
  12163. animation : settings.transition + ' out',
  12164. debug : settings.debug,
  12165. verbose : settings.verbose,
  12166. duration : settings.duration,
  12167. queue : true
  12168. })
  12169. ;
  12170. }
  12171. else {
  12172. module.debug('Hiding results with javascript');
  12173. $results
  12174. .stop()
  12175. .fadeOut(settings.duration, settings.easing)
  12176. ;
  12177. }
  12178. settings.onResultsClose.call($results);
  12179. }
  12180. },
  12181. generateResults: function(response) {
  12182. module.debug('Generating html from response', response);
  12183. var
  12184. template = settings.templates[settings.type],
  12185. isProperObject = ($.isPlainObject(response[fields.results]) && !$.isEmptyObject(response[fields.results])),
  12186. isProperArray = ($.isArray(response[fields.results]) && response[fields.results].length > 0),
  12187. html = ''
  12188. ;
  12189. if(isProperObject || isProperArray ) {
  12190. if(settings.maxResults > 0) {
  12191. if(isProperObject) {
  12192. if(settings.type == 'standard') {
  12193. module.error(error.maxResults);
  12194. }
  12195. }
  12196. else {
  12197. response[fields.results] = response[fields.results].slice(0, settings.maxResults);
  12198. }
  12199. }
  12200. if($.isFunction(template)) {
  12201. html = template(response, fields);
  12202. }
  12203. else {
  12204. module.error(error.noTemplate, false);
  12205. }
  12206. }
  12207. else {
  12208. html = module.displayMessage(error.noResults, 'empty');
  12209. }
  12210. settings.onResults.call(element, response);
  12211. return html;
  12212. },
  12213. displayMessage: function(text, type) {
  12214. type = type || 'standard';
  12215. module.debug('Displaying message', text, type);
  12216. module.addResults( settings.templates.message(text, type) );
  12217. return settings.templates.message(text, type);
  12218. },
  12219. setting: function(name, value) {
  12220. if( $.isPlainObject(name) ) {
  12221. $.extend(true, settings, name);
  12222. }
  12223. else if(value !== undefined) {
  12224. settings[name] = value;
  12225. }
  12226. else {
  12227. return settings[name];
  12228. }
  12229. },
  12230. internal: function(name, value) {
  12231. if( $.isPlainObject(name) ) {
  12232. $.extend(true, module, name);
  12233. }
  12234. else if(value !== undefined) {
  12235. module[name] = value;
  12236. }
  12237. else {
  12238. return module[name];
  12239. }
  12240. },
  12241. debug: function() {
  12242. if(settings.debug) {
  12243. if(settings.performance) {
  12244. module.performance.log(arguments);
  12245. }
  12246. else {
  12247. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  12248. module.debug.apply(console, arguments);
  12249. }
  12250. }
  12251. },
  12252. verbose: function() {
  12253. if(settings.verbose && settings.debug) {
  12254. if(settings.performance) {
  12255. module.performance.log(arguments);
  12256. }
  12257. else {
  12258. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  12259. module.verbose.apply(console, arguments);
  12260. }
  12261. }
  12262. },
  12263. error: function() {
  12264. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  12265. module.error.apply(console, arguments);
  12266. },
  12267. performance: {
  12268. log: function(message) {
  12269. var
  12270. currentTime,
  12271. executionTime,
  12272. previousTime
  12273. ;
  12274. if(settings.performance) {
  12275. currentTime = new Date().getTime();
  12276. previousTime = time || currentTime;
  12277. executionTime = currentTime - previousTime;
  12278. time = currentTime;
  12279. performance.push({
  12280. 'Name' : message[0],
  12281. 'Arguments' : [].slice.call(message, 1) || '',
  12282. 'Element' : element,
  12283. 'Execution Time' : executionTime
  12284. });
  12285. }
  12286. clearTimeout(module.performance.timer);
  12287. module.performance.timer = setTimeout(module.performance.display, 500);
  12288. },
  12289. display: function() {
  12290. var
  12291. title = settings.name + ':',
  12292. totalTime = 0
  12293. ;
  12294. time = false;
  12295. clearTimeout(module.performance.timer);
  12296. $.each(performance, function(index, data) {
  12297. totalTime += data['Execution Time'];
  12298. });
  12299. title += ' ' + totalTime + 'ms';
  12300. if(moduleSelector) {
  12301. title += ' \'' + moduleSelector + '\'';
  12302. }
  12303. if($allModules.length > 1) {
  12304. title += ' ' + '(' + $allModules.length + ')';
  12305. }
  12306. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  12307. console.groupCollapsed(title);
  12308. if(console.table) {
  12309. console.table(performance);
  12310. }
  12311. else {
  12312. $.each(performance, function(index, data) {
  12313. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  12314. });
  12315. }
  12316. console.groupEnd();
  12317. }
  12318. performance = [];
  12319. }
  12320. },
  12321. invoke: function(query, passedArguments, context) {
  12322. var
  12323. object = instance,
  12324. maxDepth,
  12325. found,
  12326. response
  12327. ;
  12328. passedArguments = passedArguments || queryArguments;
  12329. context = element || context;
  12330. if(typeof query == 'string' && object !== undefined) {
  12331. query = query.split(/[\. ]/);
  12332. maxDepth = query.length - 1;
  12333. $.each(query, function(depth, value) {
  12334. var camelCaseValue = (depth != maxDepth)
  12335. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  12336. : query
  12337. ;
  12338. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  12339. object = object[camelCaseValue];
  12340. }
  12341. else if( object[camelCaseValue] !== undefined ) {
  12342. found = object[camelCaseValue];
  12343. return false;
  12344. }
  12345. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  12346. object = object[value];
  12347. }
  12348. else if( object[value] !== undefined ) {
  12349. found = object[value];
  12350. return false;
  12351. }
  12352. else {
  12353. return false;
  12354. }
  12355. });
  12356. }
  12357. if( $.isFunction( found ) ) {
  12358. response = found.apply(context, passedArguments);
  12359. }
  12360. else if(found !== undefined) {
  12361. response = found;
  12362. }
  12363. if($.isArray(returnedValue)) {
  12364. returnedValue.push(response);
  12365. }
  12366. else if(returnedValue !== undefined) {
  12367. returnedValue = [returnedValue, response];
  12368. }
  12369. else if(response !== undefined) {
  12370. returnedValue = response;
  12371. }
  12372. return found;
  12373. }
  12374. };
  12375. if(methodInvoked) {
  12376. if(instance === undefined) {
  12377. module.initialize();
  12378. }
  12379. module.invoke(query);
  12380. }
  12381. else {
  12382. if(instance !== undefined) {
  12383. instance.invoke('destroy');
  12384. }
  12385. module.initialize();
  12386. }
  12387. })
  12388. ;
  12389. return (returnedValue !== undefined)
  12390. ? returnedValue
  12391. : this
  12392. ;
  12393. };
  12394. $.fn.search.settings = {
  12395. name : 'Search',
  12396. namespace : 'search',
  12397. debug : false,
  12398. verbose : false,
  12399. performance : true,
  12400. type : 'standard',
  12401. // template to use (specified in settings.templates)
  12402. minCharacters : 1,
  12403. // minimum characters required to search
  12404. apiSettings : false,
  12405. // API config
  12406. source : false,
  12407. // object to search
  12408. searchFields : [
  12409. 'title',
  12410. 'description'
  12411. ],
  12412. // fields to search
  12413. displayField : '',
  12414. // field to display in standard results template
  12415. searchFullText : true,
  12416. // whether to include fuzzy results in local search
  12417. automatic : true,
  12418. // whether to add events to prompt automatically
  12419. hideDelay : 0,
  12420. // delay before hiding menu after blur
  12421. searchDelay : 200,
  12422. // delay before searching
  12423. maxResults : 7,
  12424. // maximum results returned from local
  12425. cache : true,
  12426. // whether to store lookups in local cache
  12427. // transition settings
  12428. transition : 'scale',
  12429. duration : 200,
  12430. easing : 'easeOutExpo',
  12431. // callbacks
  12432. onSelect : false,
  12433. onResultsAdd : false,
  12434. onSearchQuery : function(query){},
  12435. onResults : function(response){},
  12436. onResultsOpen : function(){},
  12437. onResultsClose : function(){},
  12438. className: {
  12439. active : 'active',
  12440. empty : 'empty',
  12441. focus : 'focus',
  12442. loading : 'loading',
  12443. results : 'results',
  12444. pressed : 'down'
  12445. },
  12446. error : {
  12447. source : 'Cannot search. No source used, and Semantic API module was not included',
  12448. noResults : 'Your search returned no results',
  12449. logging : 'Error in debug logging, exiting.',
  12450. noEndpoint : 'No search endpoint was specified',
  12451. noTemplate : 'A valid template name was not specified.',
  12452. serverError : 'There was an issue querying the server.',
  12453. maxResults : 'Results must be an array to use maxResults setting',
  12454. method : 'The method you called is not defined.'
  12455. },
  12456. metadata: {
  12457. cache : 'cache',
  12458. results : 'results',
  12459. result : 'result'
  12460. },
  12461. regExp: {
  12462. escape : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,
  12463. beginsWith : '(?:\s|^)'
  12464. },
  12465. // maps api response attributes to internal representation
  12466. fields: {
  12467. categories : 'results', // array of categories (category view)
  12468. categoryName : 'name', // name of category (category view)
  12469. categoryResults : 'results', // array of results (category view)
  12470. description : 'description', // result description
  12471. image : 'image', // result image
  12472. price : 'price', // result price
  12473. results : 'results', // array of results (standard)
  12474. title : 'title', // result title
  12475. action : 'action', // "view more" object name
  12476. actionText : 'text', // "view more" text
  12477. actionURL : 'url' // "view more" url
  12478. },
  12479. selector : {
  12480. prompt : '.prompt',
  12481. searchButton : '.search.button',
  12482. results : '.results',
  12483. category : '.category',
  12484. result : '.result',
  12485. title : '.title, .name'
  12486. },
  12487. templates: {
  12488. escape: function(string) {
  12489. var
  12490. badChars = /[&<>"'`]/g,
  12491. shouldEscape = /[&<>"'`]/,
  12492. escape = {
  12493. "&": "&amp;",
  12494. "<": "&lt;",
  12495. ">": "&gt;",
  12496. '"': "&quot;",
  12497. "'": "&#x27;",
  12498. "`": "&#x60;"
  12499. },
  12500. escapedChar = function(chr) {
  12501. return escape[chr];
  12502. }
  12503. ;
  12504. if(shouldEscape.test(string)) {
  12505. return string.replace(badChars, escapedChar);
  12506. }
  12507. return string;
  12508. },
  12509. message: function(message, type) {
  12510. var
  12511. html = ''
  12512. ;
  12513. if(message !== undefined && type !== undefined) {
  12514. html += ''
  12515. + '<div class="message ' + type + '">'
  12516. ;
  12517. // message type
  12518. if(type == 'empty') {
  12519. html += ''
  12520. + '<div class="header">No Results</div class="header">'
  12521. + '<div class="description">' + message + '</div class="description">'
  12522. ;
  12523. }
  12524. else {
  12525. html += ' <div class="description">' + message + '</div>';
  12526. }
  12527. html += '</div>';
  12528. }
  12529. return html;
  12530. },
  12531. category: function(response, fields) {
  12532. var
  12533. html = '',
  12534. escape = $.fn.search.settings.templates.escape
  12535. ;
  12536. if(response[fields.categoryResults] !== undefined) {
  12537. // each category
  12538. $.each(response[fields.categoryResults], function(index, category) {
  12539. if(category[fields.results] !== undefined && category.results.length > 0) {
  12540. html += '<div class="category">';
  12541. if(category[fields.categoryName] !== undefined) {
  12542. html += '<div class="name">' + category[fields.categoryName] + '</div>';
  12543. }
  12544. // each item inside category
  12545. $.each(category.results, function(index, result) {
  12546. if(response[fields.url]) {
  12547. html += '<a class="result" href="' + response[fields.url] + '">';
  12548. }
  12549. else {
  12550. html += '<a class="result">';
  12551. }
  12552. if(result[fields.image] !== undefined) {
  12553. html += ''
  12554. + '<div class="image">'
  12555. + ' <img src="' + result[fields.image] + '">'
  12556. + '</div>'
  12557. ;
  12558. }
  12559. html += '<div class="content">';
  12560. if(result[fields.price] !== undefined) {
  12561. html += '<div class="price">' + result[fields.price] + '</div>';
  12562. }
  12563. if(result[fields.title] !== undefined) {
  12564. html += '<div class="title">' + result[fields.title] + '</div>';
  12565. }
  12566. if(result[fields.description] !== undefined) {
  12567. html += '<div class="description">' + result[fields.description] + '</div>';
  12568. }
  12569. html += ''
  12570. + '</div>'
  12571. ;
  12572. html += '</a>';
  12573. });
  12574. html += ''
  12575. + '</div>'
  12576. ;
  12577. }
  12578. });
  12579. if(response[fields.action]) {
  12580. html += ''
  12581. + '<a href="' + response[fields.action][fields.actionURL] + '" class="action">'
  12582. + response[fields.action][fields.actionText]
  12583. + '</a>';
  12584. }
  12585. return html;
  12586. }
  12587. return false;
  12588. },
  12589. standard: function(response, fields) {
  12590. var
  12591. html = ''
  12592. ;
  12593. if(response[fields.results] !== undefined) {
  12594. // each result
  12595. $.each(response[fields.results], function(index, result) {
  12596. if(response[fields.url]) {
  12597. html += '<a class="result" href="' + response[fields.url] + '">';
  12598. }
  12599. else {
  12600. html += '<a class="result">';
  12601. }
  12602. if(result[fields.image] !== undefined) {
  12603. html += ''
  12604. + '<div class="image">'
  12605. + ' <img src="' + result[fields.image] + '">'
  12606. + '</div>'
  12607. ;
  12608. }
  12609. html += '<div class="content">';
  12610. if(result[fields.price] !== undefined) {
  12611. html += '<div class="price">' + result[fields.price] + '</div>';
  12612. }
  12613. if(result[fields.title] !== undefined) {
  12614. html += '<div class="title">' + result[fields.title] + '</div>';
  12615. }
  12616. if(result[fields.description] !== undefined) {
  12617. html += '<div class="description">' + result[fields.description] + '</div>';
  12618. }
  12619. html += ''
  12620. + '</div>'
  12621. ;
  12622. html += '</a>';
  12623. });
  12624. if(response[fields.action]) {
  12625. html += ''
  12626. + '<a href="' + response[fields.action][fields.actionURL] + '" class="action">'
  12627. + response[fields.action][fields.actionText]
  12628. + '</a>';
  12629. }
  12630. return html;
  12631. }
  12632. return false;
  12633. }
  12634. }
  12635. };
  12636. })( jQuery, window , document );
  12637. /*!
  12638. * # Semantic UI 2.1.4 - Shape
  12639. * http://github.com/semantic-org/semantic-ui/
  12640. *
  12641. *
  12642. * Copyright 2015 Contributors
  12643. * Released under the MIT license
  12644. * http://opensource.org/licenses/MIT
  12645. *
  12646. */
  12647. ;(function ( $, window, document, undefined ) {
  12648. "use strict";
  12649. $.fn.shape = function(parameters) {
  12650. var
  12651. $allModules = $(this),
  12652. $body = $('body'),
  12653. time = new Date().getTime(),
  12654. performance = [],
  12655. query = arguments[0],
  12656. methodInvoked = (typeof query == 'string'),
  12657. queryArguments = [].slice.call(arguments, 1),
  12658. requestAnimationFrame = window.requestAnimationFrame
  12659. || window.mozRequestAnimationFrame
  12660. || window.webkitRequestAnimationFrame
  12661. || window.msRequestAnimationFrame
  12662. || function(callback) { setTimeout(callback, 0); },
  12663. returnedValue
  12664. ;
  12665. $allModules
  12666. .each(function() {
  12667. var
  12668. moduleSelector = $allModules.selector || '',
  12669. settings = ( $.isPlainObject(parameters) )
  12670. ? $.extend(true, {}, $.fn.shape.settings, parameters)
  12671. : $.extend({}, $.fn.shape.settings),
  12672. // internal aliases
  12673. namespace = settings.namespace,
  12674. selector = settings.selector,
  12675. error = settings.error,
  12676. className = settings.className,
  12677. // define namespaces for modules
  12678. eventNamespace = '.' + namespace,
  12679. moduleNamespace = 'module-' + namespace,
  12680. // selector cache
  12681. $module = $(this),
  12682. $sides = $module.find(selector.sides),
  12683. $side = $module.find(selector.side),
  12684. // private variables
  12685. nextIndex = false,
  12686. $activeSide,
  12687. $nextSide,
  12688. // standard module
  12689. element = this,
  12690. instance = $module.data(moduleNamespace),
  12691. module
  12692. ;
  12693. module = {
  12694. initialize: function() {
  12695. module.verbose('Initializing module for', element);
  12696. module.set.defaultSide();
  12697. module.instantiate();
  12698. },
  12699. instantiate: function() {
  12700. module.verbose('Storing instance of module', module);
  12701. instance = module;
  12702. $module
  12703. .data(moduleNamespace, instance)
  12704. ;
  12705. },
  12706. destroy: function() {
  12707. module.verbose('Destroying previous module for', element);
  12708. $module
  12709. .removeData(moduleNamespace)
  12710. .off(eventNamespace)
  12711. ;
  12712. },
  12713. refresh: function() {
  12714. module.verbose('Refreshing selector cache for', element);
  12715. $module = $(element);
  12716. $sides = $(this).find(selector.shape);
  12717. $side = $(this).find(selector.side);
  12718. },
  12719. repaint: function() {
  12720. module.verbose('Forcing repaint event');
  12721. var
  12722. shape = $sides[0] || document.createElement('div'),
  12723. fakeAssignment = shape.offsetWidth
  12724. ;
  12725. },
  12726. animate: function(propertyObject, callback) {
  12727. module.verbose('Animating box with properties', propertyObject);
  12728. callback = callback || function(event) {
  12729. module.verbose('Executing animation callback');
  12730. if(event !== undefined) {
  12731. event.stopPropagation();
  12732. }
  12733. module.reset();
  12734. module.set.active();
  12735. };
  12736. settings.beforeChange.call($nextSide[0]);
  12737. if(module.get.transitionEvent()) {
  12738. module.verbose('Starting CSS animation');
  12739. $module
  12740. .addClass(className.animating)
  12741. ;
  12742. $sides
  12743. .css(propertyObject)
  12744. .one(module.get.transitionEvent(), callback)
  12745. ;
  12746. module.set.duration(settings.duration);
  12747. requestAnimationFrame(function() {
  12748. $module
  12749. .addClass(className.animating)
  12750. ;
  12751. $activeSide
  12752. .addClass(className.hidden)
  12753. ;
  12754. });
  12755. }
  12756. else {
  12757. callback();
  12758. }
  12759. },
  12760. queue: function(method) {
  12761. module.debug('Queueing animation of', method);
  12762. $sides
  12763. .one(module.get.transitionEvent(), function() {
  12764. module.debug('Executing queued animation');
  12765. setTimeout(function(){
  12766. $module.shape(method);
  12767. }, 0);
  12768. })
  12769. ;
  12770. },
  12771. reset: function() {
  12772. module.verbose('Animating states reset');
  12773. $module
  12774. .removeClass(className.animating)
  12775. .attr('style', '')
  12776. .removeAttr('style')
  12777. ;
  12778. // removeAttr style does not consistently work in safari
  12779. $sides
  12780. .attr('style', '')
  12781. .removeAttr('style')
  12782. ;
  12783. $side
  12784. .attr('style', '')
  12785. .removeAttr('style')
  12786. .removeClass(className.hidden)
  12787. ;
  12788. $nextSide
  12789. .removeClass(className.animating)
  12790. .attr('style', '')
  12791. .removeAttr('style')
  12792. ;
  12793. },
  12794. is: {
  12795. complete: function() {
  12796. return ($side.filter('.' + className.active)[0] == $nextSide[0]);
  12797. },
  12798. animating: function() {
  12799. return $module.hasClass(className.animating);
  12800. }
  12801. },
  12802. set: {
  12803. defaultSide: function() {
  12804. $activeSide = $module.find('.' + settings.className.active);
  12805. $nextSide = ( $activeSide.next(selector.side).length > 0 )
  12806. ? $activeSide.next(selector.side)
  12807. : $module.find(selector.side).first()
  12808. ;
  12809. nextIndex = false;
  12810. module.verbose('Active side set to', $activeSide);
  12811. module.verbose('Next side set to', $nextSide);
  12812. },
  12813. duration: function(duration) {
  12814. duration = duration || settings.duration;
  12815. duration = (typeof duration == 'number')
  12816. ? duration + 'ms'
  12817. : duration
  12818. ;
  12819. module.verbose('Setting animation duration', duration);
  12820. if(settings.duration || settings.duration === 0) {
  12821. $sides.add($side)
  12822. .css({
  12823. '-webkit-transition-duration': duration,
  12824. '-moz-transition-duration': duration,
  12825. '-ms-transition-duration': duration,
  12826. '-o-transition-duration': duration,
  12827. 'transition-duration': duration
  12828. })
  12829. ;
  12830. }
  12831. },
  12832. currentStageSize: function() {
  12833. var
  12834. $activeSide = $module.find('.' + settings.className.active),
  12835. width = $activeSide.outerWidth(true),
  12836. height = $activeSide.outerHeight(true)
  12837. ;
  12838. $module
  12839. .css({
  12840. width: width,
  12841. height: height
  12842. })
  12843. ;
  12844. },
  12845. stageSize: function() {
  12846. var
  12847. $clone = $module.clone().addClass(className.loading),
  12848. $activeSide = $clone.find('.' + settings.className.active),
  12849. $nextSide = (nextIndex)
  12850. ? $clone.find(selector.side).eq(nextIndex)
  12851. : ( $activeSide.next(selector.side).length > 0 )
  12852. ? $activeSide.next(selector.side)
  12853. : $clone.find(selector.side).first(),
  12854. newSize = {}
  12855. ;
  12856. module.set.currentStageSize();
  12857. $activeSide.removeClass(className.active);
  12858. $nextSide.addClass(className.active);
  12859. $clone.insertAfter($module);
  12860. newSize = {
  12861. width : $nextSide.outerWidth(true),
  12862. height : $nextSide.outerHeight(true)
  12863. };
  12864. $clone.remove();
  12865. $module
  12866. .css(newSize)
  12867. ;
  12868. module.verbose('Resizing stage to fit new content', newSize);
  12869. },
  12870. nextSide: function(selector) {
  12871. nextIndex = selector;
  12872. $nextSide = $side.filter(selector);
  12873. nextIndex = $side.index($nextSide);
  12874. if($nextSide.length === 0) {
  12875. module.set.defaultSide();
  12876. module.error(error.side);
  12877. }
  12878. module.verbose('Next side manually set to', $nextSide);
  12879. },
  12880. active: function() {
  12881. module.verbose('Setting new side to active', $nextSide);
  12882. $side
  12883. .removeClass(className.active)
  12884. ;
  12885. $nextSide
  12886. .addClass(className.active)
  12887. ;
  12888. settings.onChange.call($nextSide[0]);
  12889. module.set.defaultSide();
  12890. }
  12891. },
  12892. flip: {
  12893. up: function() {
  12894. if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
  12895. module.debug('Side already visible', $nextSide);
  12896. return;
  12897. }
  12898. if( !module.is.animating()) {
  12899. module.debug('Flipping up', $nextSide);
  12900. module.set.stageSize();
  12901. module.stage.above();
  12902. module.animate( module.get.transform.up() );
  12903. }
  12904. else {
  12905. module.queue('flip up');
  12906. }
  12907. },
  12908. down: function() {
  12909. if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
  12910. module.debug('Side already visible', $nextSide);
  12911. return;
  12912. }
  12913. if( !module.is.animating()) {
  12914. module.debug('Flipping down', $nextSide);
  12915. module.set.stageSize();
  12916. module.stage.below();
  12917. module.animate( module.get.transform.down() );
  12918. }
  12919. else {
  12920. module.queue('flip down');
  12921. }
  12922. },
  12923. left: function() {
  12924. if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
  12925. module.debug('Side already visible', $nextSide);
  12926. return;
  12927. }
  12928. if( !module.is.animating()) {
  12929. module.debug('Flipping left', $nextSide);
  12930. module.set.stageSize();
  12931. module.stage.left();
  12932. module.animate(module.get.transform.left() );
  12933. }
  12934. else {
  12935. module.queue('flip left');
  12936. }
  12937. },
  12938. right: function() {
  12939. if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
  12940. module.debug('Side already visible', $nextSide);
  12941. return;
  12942. }
  12943. if( !module.is.animating()) {
  12944. module.debug('Flipping right', $nextSide);
  12945. module.set.stageSize();
  12946. module.stage.right();
  12947. module.animate(module.get.transform.right() );
  12948. }
  12949. else {
  12950. module.queue('flip right');
  12951. }
  12952. },
  12953. over: function() {
  12954. if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
  12955. module.debug('Side already visible', $nextSide);
  12956. return;
  12957. }
  12958. if( !module.is.animating()) {
  12959. module.debug('Flipping over', $nextSide);
  12960. module.set.stageSize();
  12961. module.stage.behind();
  12962. module.animate(module.get.transform.over() );
  12963. }
  12964. else {
  12965. module.queue('flip over');
  12966. }
  12967. },
  12968. back: function() {
  12969. if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
  12970. module.debug('Side already visible', $nextSide);
  12971. return;
  12972. }
  12973. if( !module.is.animating()) {
  12974. module.debug('Flipping back', $nextSide);
  12975. module.set.stageSize();
  12976. module.stage.behind();
  12977. module.animate(module.get.transform.back() );
  12978. }
  12979. else {
  12980. module.queue('flip back');
  12981. }
  12982. }
  12983. },
  12984. get: {
  12985. transform: {
  12986. up: function() {
  12987. var
  12988. translate = {
  12989. y: -(($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2),
  12990. z: -($activeSide.outerHeight(true) / 2)
  12991. }
  12992. ;
  12993. return {
  12994. transform: 'translateY(' + translate.y + 'px) translateZ('+ translate.z + 'px) rotateX(-90deg)'
  12995. };
  12996. },
  12997. down: function() {
  12998. var
  12999. translate = {
  13000. y: -(($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2),
  13001. z: -($activeSide.outerHeight(true) / 2)
  13002. }
  13003. ;
  13004. return {
  13005. transform: 'translateY(' + translate.y + 'px) translateZ('+ translate.z + 'px) rotateX(90deg)'
  13006. };
  13007. },
  13008. left: function() {
  13009. var
  13010. translate = {
  13011. x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2),
  13012. z : -($activeSide.outerWidth(true) / 2)
  13013. }
  13014. ;
  13015. return {
  13016. transform: 'translateX(' + translate.x + 'px) translateZ(' + translate.z + 'px) rotateY(90deg)'
  13017. };
  13018. },
  13019. right: function() {
  13020. var
  13021. translate = {
  13022. x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2),
  13023. z : -($activeSide.outerWidth(true) / 2)
  13024. }
  13025. ;
  13026. return {
  13027. transform: 'translateX(' + translate.x + 'px) translateZ(' + translate.z + 'px) rotateY(-90deg)'
  13028. };
  13029. },
  13030. over: function() {
  13031. var
  13032. translate = {
  13033. x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2)
  13034. }
  13035. ;
  13036. return {
  13037. transform: 'translateX(' + translate.x + 'px) rotateY(180deg)'
  13038. };
  13039. },
  13040. back: function() {
  13041. var
  13042. translate = {
  13043. x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2)
  13044. }
  13045. ;
  13046. return {
  13047. transform: 'translateX(' + translate.x + 'px) rotateY(-180deg)'
  13048. };
  13049. }
  13050. },
  13051. transitionEvent: function() {
  13052. var
  13053. element = document.createElement('element'),
  13054. transitions = {
  13055. 'transition' :'transitionend',
  13056. 'OTransition' :'oTransitionEnd',
  13057. 'MozTransition' :'transitionend',
  13058. 'WebkitTransition' :'webkitTransitionEnd'
  13059. },
  13060. transition
  13061. ;
  13062. for(transition in transitions){
  13063. if( element.style[transition] !== undefined ){
  13064. return transitions[transition];
  13065. }
  13066. }
  13067. },
  13068. nextSide: function() {
  13069. return ( $activeSide.next(selector.side).length > 0 )
  13070. ? $activeSide.next(selector.side)
  13071. : $module.find(selector.side).first()
  13072. ;
  13073. }
  13074. },
  13075. stage: {
  13076. above: function() {
  13077. var
  13078. box = {
  13079. origin : (($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2),
  13080. depth : {
  13081. active : ($nextSide.outerHeight(true) / 2),
  13082. next : ($activeSide.outerHeight(true) / 2)
  13083. }
  13084. }
  13085. ;
  13086. module.verbose('Setting the initial animation position as above', $nextSide, box);
  13087. $sides
  13088. .css({
  13089. 'transform' : 'translateZ(-' + box.depth.active + 'px)'
  13090. })
  13091. ;
  13092. $activeSide
  13093. .css({
  13094. 'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
  13095. })
  13096. ;
  13097. $nextSide
  13098. .addClass(className.animating)
  13099. .css({
  13100. 'top' : box.origin + 'px',
  13101. 'transform' : 'rotateX(90deg) translateZ(' + box.depth.next + 'px)'
  13102. })
  13103. ;
  13104. },
  13105. below: function() {
  13106. var
  13107. box = {
  13108. origin : (($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2),
  13109. depth : {
  13110. active : ($nextSide.outerHeight(true) / 2),
  13111. next : ($activeSide.outerHeight(true) / 2)
  13112. }
  13113. }
  13114. ;
  13115. module.verbose('Setting the initial animation position as below', $nextSide, box);
  13116. $sides
  13117. .css({
  13118. 'transform' : 'translateZ(-' + box.depth.active + 'px)'
  13119. })
  13120. ;
  13121. $activeSide
  13122. .css({
  13123. 'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
  13124. })
  13125. ;
  13126. $nextSide
  13127. .addClass(className.animating)
  13128. .css({
  13129. 'top' : box.origin + 'px',
  13130. 'transform' : 'rotateX(-90deg) translateZ(' + box.depth.next + 'px)'
  13131. })
  13132. ;
  13133. },
  13134. left: function() {
  13135. var
  13136. height = {
  13137. active : $activeSide.outerWidth(true),
  13138. next : $nextSide.outerWidth(true)
  13139. },
  13140. box = {
  13141. origin : ( ( height.active - height.next ) / 2),
  13142. depth : {
  13143. active : (height.next / 2),
  13144. next : (height.active / 2)
  13145. }
  13146. }
  13147. ;
  13148. module.verbose('Setting the initial animation position as left', $nextSide, box);
  13149. $sides
  13150. .css({
  13151. 'transform' : 'translateZ(-' + box.depth.active + 'px)'
  13152. })
  13153. ;
  13154. $activeSide
  13155. .css({
  13156. 'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
  13157. })
  13158. ;
  13159. $nextSide
  13160. .addClass(className.animating)
  13161. .css({
  13162. 'left' : box.origin + 'px',
  13163. 'transform' : 'rotateY(-90deg) translateZ(' + box.depth.next + 'px)'
  13164. })
  13165. ;
  13166. },
  13167. right: function() {
  13168. var
  13169. height = {
  13170. active : $activeSide.outerWidth(true),
  13171. next : $nextSide.outerWidth(true)
  13172. },
  13173. box = {
  13174. origin : ( ( height.active - height.next ) / 2),
  13175. depth : {
  13176. active : (height.next / 2),
  13177. next : (height.active / 2)
  13178. }
  13179. }
  13180. ;
  13181. module.verbose('Setting the initial animation position as left', $nextSide, box);
  13182. $sides
  13183. .css({
  13184. 'transform' : 'translateZ(-' + box.depth.active + 'px)'
  13185. })
  13186. ;
  13187. $activeSide
  13188. .css({
  13189. 'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
  13190. })
  13191. ;
  13192. $nextSide
  13193. .addClass(className.animating)
  13194. .css({
  13195. 'left' : box.origin + 'px',
  13196. 'transform' : 'rotateY(90deg) translateZ(' + box.depth.next + 'px)'
  13197. })
  13198. ;
  13199. },
  13200. behind: function() {
  13201. var
  13202. height = {
  13203. active : $activeSide.outerWidth(true),
  13204. next : $nextSide.outerWidth(true)
  13205. },
  13206. box = {
  13207. origin : ( ( height.active - height.next ) / 2),
  13208. depth : {
  13209. active : (height.next / 2),
  13210. next : (height.active / 2)
  13211. }
  13212. }
  13213. ;
  13214. module.verbose('Setting the initial animation position as behind', $nextSide, box);
  13215. $activeSide
  13216. .css({
  13217. 'transform' : 'rotateY(0deg)'
  13218. })
  13219. ;
  13220. $nextSide
  13221. .addClass(className.animating)
  13222. .css({
  13223. 'left' : box.origin + 'px',
  13224. 'transform' : 'rotateY(-180deg)'
  13225. })
  13226. ;
  13227. }
  13228. },
  13229. setting: function(name, value) {
  13230. module.debug('Changing setting', name, value);
  13231. if( $.isPlainObject(name) ) {
  13232. $.extend(true, settings, name);
  13233. }
  13234. else if(value !== undefined) {
  13235. settings[name] = value;
  13236. }
  13237. else {
  13238. return settings[name];
  13239. }
  13240. },
  13241. internal: function(name, value) {
  13242. if( $.isPlainObject(name) ) {
  13243. $.extend(true, module, name);
  13244. }
  13245. else if(value !== undefined) {
  13246. module[name] = value;
  13247. }
  13248. else {
  13249. return module[name];
  13250. }
  13251. },
  13252. debug: function() {
  13253. if(settings.debug) {
  13254. if(settings.performance) {
  13255. module.performance.log(arguments);
  13256. }
  13257. else {
  13258. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  13259. module.debug.apply(console, arguments);
  13260. }
  13261. }
  13262. },
  13263. verbose: function() {
  13264. if(settings.verbose && settings.debug) {
  13265. if(settings.performance) {
  13266. module.performance.log(arguments);
  13267. }
  13268. else {
  13269. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  13270. module.verbose.apply(console, arguments);
  13271. }
  13272. }
  13273. },
  13274. error: function() {
  13275. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  13276. module.error.apply(console, arguments);
  13277. },
  13278. performance: {
  13279. log: function(message) {
  13280. var
  13281. currentTime,
  13282. executionTime,
  13283. previousTime
  13284. ;
  13285. if(settings.performance) {
  13286. currentTime = new Date().getTime();
  13287. previousTime = time || currentTime;
  13288. executionTime = currentTime - previousTime;
  13289. time = currentTime;
  13290. performance.push({
  13291. 'Name' : message[0],
  13292. 'Arguments' : [].slice.call(message, 1) || '',
  13293. 'Element' : element,
  13294. 'Execution Time' : executionTime
  13295. });
  13296. }
  13297. clearTimeout(module.performance.timer);
  13298. module.performance.timer = setTimeout(module.performance.display, 500);
  13299. },
  13300. display: function() {
  13301. var
  13302. title = settings.name + ':',
  13303. totalTime = 0
  13304. ;
  13305. time = false;
  13306. clearTimeout(module.performance.timer);
  13307. $.each(performance, function(index, data) {
  13308. totalTime += data['Execution Time'];
  13309. });
  13310. title += ' ' + totalTime + 'ms';
  13311. if(moduleSelector) {
  13312. title += ' \'' + moduleSelector + '\'';
  13313. }
  13314. if($allModules.length > 1) {
  13315. title += ' ' + '(' + $allModules.length + ')';
  13316. }
  13317. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  13318. console.groupCollapsed(title);
  13319. if(console.table) {
  13320. console.table(performance);
  13321. }
  13322. else {
  13323. $.each(performance, function(index, data) {
  13324. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  13325. });
  13326. }
  13327. console.groupEnd();
  13328. }
  13329. performance = [];
  13330. }
  13331. },
  13332. invoke: function(query, passedArguments, context) {
  13333. var
  13334. object = instance,
  13335. maxDepth,
  13336. found,
  13337. response
  13338. ;
  13339. passedArguments = passedArguments || queryArguments;
  13340. context = element || context;
  13341. if(typeof query == 'string' && object !== undefined) {
  13342. query = query.split(/[\. ]/);
  13343. maxDepth = query.length - 1;
  13344. $.each(query, function(depth, value) {
  13345. var camelCaseValue = (depth != maxDepth)
  13346. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  13347. : query
  13348. ;
  13349. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  13350. object = object[camelCaseValue];
  13351. }
  13352. else if( object[camelCaseValue] !== undefined ) {
  13353. found = object[camelCaseValue];
  13354. return false;
  13355. }
  13356. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  13357. object = object[value];
  13358. }
  13359. else if( object[value] !== undefined ) {
  13360. found = object[value];
  13361. return false;
  13362. }
  13363. else {
  13364. return false;
  13365. }
  13366. });
  13367. }
  13368. if ( $.isFunction( found ) ) {
  13369. response = found.apply(context, passedArguments);
  13370. }
  13371. else if(found !== undefined) {
  13372. response = found;
  13373. }
  13374. if($.isArray(returnedValue)) {
  13375. returnedValue.push(response);
  13376. }
  13377. else if(returnedValue !== undefined) {
  13378. returnedValue = [returnedValue, response];
  13379. }
  13380. else if(response !== undefined) {
  13381. returnedValue = response;
  13382. }
  13383. return found;
  13384. }
  13385. };
  13386. if(methodInvoked) {
  13387. if(instance === undefined) {
  13388. module.initialize();
  13389. }
  13390. module.invoke(query);
  13391. }
  13392. else {
  13393. if(instance !== undefined) {
  13394. instance.invoke('destroy');
  13395. }
  13396. module.initialize();
  13397. }
  13398. })
  13399. ;
  13400. return (returnedValue !== undefined)
  13401. ? returnedValue
  13402. : this
  13403. ;
  13404. };
  13405. $.fn.shape.settings = {
  13406. // module info
  13407. name : 'Shape',
  13408. // debug content outputted to console
  13409. debug : false,
  13410. // verbose debug output
  13411. verbose : false,
  13412. // performance data output
  13413. performance: true,
  13414. // event namespace
  13415. namespace : 'shape',
  13416. // callback occurs on side change
  13417. beforeChange : function() {},
  13418. onChange : function() {},
  13419. // allow animation to same side
  13420. allowRepeats: false,
  13421. // animation duration
  13422. duration : false,
  13423. // possible errors
  13424. error: {
  13425. side : 'You tried to switch to a side that does not exist.',
  13426. method : 'The method you called is not defined'
  13427. },
  13428. // classnames used
  13429. className : {
  13430. animating : 'animating',
  13431. hidden : 'hidden',
  13432. loading : 'loading',
  13433. active : 'active'
  13434. },
  13435. // selectors used
  13436. selector : {
  13437. sides : '.sides',
  13438. side : '.side'
  13439. }
  13440. };
  13441. })( jQuery, window , document );
  13442. /*!
  13443. * # Semantic UI 2.1.4 - Sidebar
  13444. * http://github.com/semantic-org/semantic-ui/
  13445. *
  13446. *
  13447. * Copyright 2015 Contributors
  13448. * Released under the MIT license
  13449. * http://opensource.org/licenses/MIT
  13450. *
  13451. */
  13452. ;(function ( $, window, document, undefined ) {
  13453. "use strict";
  13454. $.fn.sidebar = function(parameters) {
  13455. var
  13456. $allModules = $(this),
  13457. $window = $(window),
  13458. $document = $(document),
  13459. $html = $('html'),
  13460. $head = $('head'),
  13461. moduleSelector = $allModules.selector || '',
  13462. time = new Date().getTime(),
  13463. performance = [],
  13464. query = arguments[0],
  13465. methodInvoked = (typeof query == 'string'),
  13466. queryArguments = [].slice.call(arguments, 1),
  13467. requestAnimationFrame = window.requestAnimationFrame
  13468. || window.mozRequestAnimationFrame
  13469. || window.webkitRequestAnimationFrame
  13470. || window.msRequestAnimationFrame
  13471. || function(callback) { setTimeout(callback, 0); },
  13472. returnedValue
  13473. ;
  13474. $allModules
  13475. .each(function() {
  13476. var
  13477. settings = ( $.isPlainObject(parameters) )
  13478. ? $.extend(true, {}, $.fn.sidebar.settings, parameters)
  13479. : $.extend({}, $.fn.sidebar.settings),
  13480. selector = settings.selector,
  13481. className = settings.className,
  13482. namespace = settings.namespace,
  13483. regExp = settings.regExp,
  13484. error = settings.error,
  13485. eventNamespace = '.' + namespace,
  13486. moduleNamespace = 'module-' + namespace,
  13487. $module = $(this),
  13488. $context = $(settings.context),
  13489. $sidebars = $module.children(selector.sidebar),
  13490. $fixed = $context.children(selector.fixed),
  13491. $pusher = $context.children(selector.pusher),
  13492. $style,
  13493. element = this,
  13494. instance = $module.data(moduleNamespace),
  13495. elementNamespace,
  13496. id,
  13497. currentScroll,
  13498. transitionEvent,
  13499. module
  13500. ;
  13501. module = {
  13502. initialize: function() {
  13503. module.debug('Initializing sidebar', parameters);
  13504. module.create.id();
  13505. transitionEvent = module.get.transitionEvent();
  13506. if(module.is.ios()) {
  13507. module.set.ios();
  13508. }
  13509. // avoids locking rendering if initialized in onReady
  13510. if(settings.delaySetup) {
  13511. requestAnimationFrame(module.setup.layout);
  13512. }
  13513. else {
  13514. module.setup.layout();
  13515. }
  13516. requestAnimationFrame(function() {
  13517. module.setup.cache();
  13518. });
  13519. module.instantiate();
  13520. },
  13521. instantiate: function() {
  13522. module.verbose('Storing instance of module', module);
  13523. instance = module;
  13524. $module
  13525. .data(moduleNamespace, module)
  13526. ;
  13527. },
  13528. create: {
  13529. id: function() {
  13530. id = (Math.random().toString(16) + '000000000').substr(2,8);
  13531. elementNamespace = '.' + id;
  13532. module.verbose('Creating unique id for element', id);
  13533. }
  13534. },
  13535. destroy: function() {
  13536. module.verbose('Destroying previous module for', $module);
  13537. $module
  13538. .off(eventNamespace)
  13539. .removeData(moduleNamespace)
  13540. ;
  13541. if(module.is.ios()) {
  13542. module.remove.ios();
  13543. }
  13544. // bound by uuid
  13545. $context.off(elementNamespace);
  13546. $window.off(elementNamespace);
  13547. $document.off(elementNamespace);
  13548. },
  13549. event: {
  13550. clickaway: function(event) {
  13551. var
  13552. clickedInPusher = ($pusher.find(event.target).length > 0 || $pusher.is(event.target)),
  13553. clickedContext = ($context.is(event.target))
  13554. ;
  13555. if(clickedInPusher) {
  13556. module.verbose('User clicked on dimmed page');
  13557. module.hide();
  13558. }
  13559. if(clickedContext) {
  13560. module.verbose('User clicked on dimmable context (scaled out page)');
  13561. module.hide();
  13562. }
  13563. },
  13564. touch: function(event) {
  13565. //event.stopPropagation();
  13566. },
  13567. containScroll: function(event) {
  13568. if(element.scrollTop <= 0) {
  13569. element.scrollTop = 1;
  13570. }
  13571. if((element.scrollTop + element.offsetHeight) >= element.scrollHeight) {
  13572. element.scrollTop = element.scrollHeight - element.offsetHeight - 1;
  13573. }
  13574. },
  13575. scroll: function(event) {
  13576. if( $(event.target).closest(selector.sidebar).length === 0 ) {
  13577. event.preventDefault();
  13578. }
  13579. }
  13580. },
  13581. bind: {
  13582. clickaway: function() {
  13583. module.verbose('Adding clickaway events to context', $context);
  13584. if(settings.closable) {
  13585. $context
  13586. .on('click' + elementNamespace, module.event.clickaway)
  13587. .on('touchend' + elementNamespace, module.event.clickaway)
  13588. ;
  13589. }
  13590. },
  13591. scrollLock: function() {
  13592. if(settings.scrollLock) {
  13593. module.debug('Disabling page scroll');
  13594. $window
  13595. .on('DOMMouseScroll' + elementNamespace, module.event.scroll)
  13596. ;
  13597. }
  13598. module.verbose('Adding events to contain sidebar scroll');
  13599. $document
  13600. .on('touchmove' + elementNamespace, module.event.touch)
  13601. ;
  13602. $module
  13603. .on('scroll' + eventNamespace, module.event.containScroll)
  13604. ;
  13605. }
  13606. },
  13607. unbind: {
  13608. clickaway: function() {
  13609. module.verbose('Removing clickaway events from context', $context);
  13610. $context.off(elementNamespace);
  13611. },
  13612. scrollLock: function() {
  13613. module.verbose('Removing scroll lock from page');
  13614. $document.off(elementNamespace);
  13615. $window.off(elementNamespace);
  13616. $module.off('scroll' + eventNamespace);
  13617. }
  13618. },
  13619. add: {
  13620. inlineCSS: function() {
  13621. var
  13622. width = module.cache.width || $module.outerWidth(),
  13623. height = module.cache.height || $module.outerHeight(),
  13624. isRTL = module.is.rtl(),
  13625. direction = module.get.direction(),
  13626. distance = {
  13627. left : width,
  13628. right : -width,
  13629. top : height,
  13630. bottom : -height
  13631. },
  13632. style
  13633. ;
  13634. if(isRTL){
  13635. module.verbose('RTL detected, flipping widths');
  13636. distance.left = -width;
  13637. distance.right = width;
  13638. }
  13639. style = '<style>';
  13640. if(direction === 'left' || direction === 'right') {
  13641. module.debug('Adding CSS rules for animation distance', width);
  13642. style += ''
  13643. + ' .ui.visible.' + direction + '.sidebar ~ .fixed,'
  13644. + ' .ui.visible.' + direction + '.sidebar ~ .pusher {'
  13645. + ' -webkit-transform: translate3d('+ distance[direction] + 'px, 0, 0);'
  13646. + ' transform: translate3d('+ distance[direction] + 'px, 0, 0);'
  13647. + ' }'
  13648. ;
  13649. }
  13650. else if(direction === 'top' || direction == 'bottom') {
  13651. style += ''
  13652. + ' .ui.visible.' + direction + '.sidebar ~ .fixed,'
  13653. + ' .ui.visible.' + direction + '.sidebar ~ .pusher {'
  13654. + ' -webkit-transform: translate3d(0, ' + distance[direction] + 'px, 0);'
  13655. + ' transform: translate3d(0, ' + distance[direction] + 'px, 0);'
  13656. + ' }'
  13657. ;
  13658. }
  13659. /* IE is only browser not to create context with transforms */
  13660. /* https://www.w3.org/Bugs/Public/show_bug.cgi?id=16328 */
  13661. if( module.is.ie() ) {
  13662. if(direction === 'left' || direction === 'right') {
  13663. module.debug('Adding CSS rules for animation distance', width);
  13664. style += ''
  13665. + ' body.pushable > .ui.visible.' + direction + '.sidebar ~ .pusher:after {'
  13666. + ' -webkit-transform: translate3d('+ distance[direction] + 'px, 0, 0);'
  13667. + ' transform: translate3d('+ distance[direction] + 'px, 0, 0);'
  13668. + ' }'
  13669. ;
  13670. }
  13671. else if(direction === 'top' || direction == 'bottom') {
  13672. style += ''
  13673. + ' body.pushable > .ui.visible.' + direction + '.sidebar ~ .pusher:after {'
  13674. + ' -webkit-transform: translate3d(0, ' + distance[direction] + 'px, 0);'
  13675. + ' transform: translate3d(0, ' + distance[direction] + 'px, 0);'
  13676. + ' }'
  13677. ;
  13678. }
  13679. /* opposite sides visible forces content overlay */
  13680. style += ''
  13681. + ' body.pushable > .ui.visible.left.sidebar ~ .ui.visible.right.sidebar ~ .pusher:after,'
  13682. + ' body.pushable > .ui.visible.right.sidebar ~ .ui.visible.left.sidebar ~ .pusher:after {'
  13683. + ' -webkit-transform: translate3d(0px, 0, 0);'
  13684. + ' transform: translate3d(0px, 0, 0);'
  13685. + ' }'
  13686. ;
  13687. }
  13688. style += '</style>';
  13689. $style = $(style)
  13690. .appendTo($head)
  13691. ;
  13692. module.debug('Adding sizing css to head', $style);
  13693. }
  13694. },
  13695. refresh: function() {
  13696. module.verbose('Refreshing selector cache');
  13697. $context = $(settings.context);
  13698. $sidebars = $context.children(selector.sidebar);
  13699. $pusher = $context.children(selector.pusher);
  13700. $fixed = $context.children(selector.fixed);
  13701. module.clear.cache();
  13702. },
  13703. refreshSidebars: function() {
  13704. module.verbose('Refreshing other sidebars');
  13705. $sidebars = $context.children(selector.sidebar);
  13706. },
  13707. repaint: function() {
  13708. module.verbose('Forcing repaint event');
  13709. element.style.display = 'none';
  13710. var ignored = element.offsetHeight;
  13711. element.scrollTop = element.scrollTop;
  13712. element.style.display = '';
  13713. },
  13714. setup: {
  13715. cache: function() {
  13716. module.cache = {
  13717. width : $module.outerWidth(),
  13718. height : $module.outerHeight(),
  13719. rtl : ($module.css('direction') == 'rtl')
  13720. };
  13721. },
  13722. layout: function() {
  13723. if( $context.children(selector.pusher).length === 0 ) {
  13724. module.debug('Adding wrapper element for sidebar');
  13725. module.error(error.pusher);
  13726. $pusher = $('<div class="pusher" />');
  13727. $context
  13728. .children()
  13729. .not(selector.omitted)
  13730. .not($sidebars)
  13731. .wrapAll($pusher)
  13732. ;
  13733. module.refresh();
  13734. }
  13735. if($module.nextAll(selector.pusher).length === 0 || $module.nextAll(selector.pusher)[0] !== $pusher[0]) {
  13736. module.debug('Moved sidebar to correct parent element');
  13737. module.error(error.movedSidebar, element);
  13738. $module.detach().prependTo($context);
  13739. module.refresh();
  13740. }
  13741. module.clear.cache();
  13742. module.set.pushable();
  13743. module.set.direction();
  13744. }
  13745. },
  13746. attachEvents: function(selector, event) {
  13747. var
  13748. $toggle = $(selector)
  13749. ;
  13750. event = $.isFunction(module[event])
  13751. ? module[event]
  13752. : module.toggle
  13753. ;
  13754. if($toggle.length > 0) {
  13755. module.debug('Attaching sidebar events to element', selector, event);
  13756. $toggle
  13757. .on('click' + eventNamespace, event)
  13758. ;
  13759. }
  13760. else {
  13761. module.error(error.notFound, selector);
  13762. }
  13763. },
  13764. show: function(callback) {
  13765. callback = $.isFunction(callback)
  13766. ? callback
  13767. : function(){}
  13768. ;
  13769. if(module.is.hidden()) {
  13770. module.refreshSidebars();
  13771. if(settings.overlay) {
  13772. module.error(error.overlay);
  13773. settings.transition = 'overlay';
  13774. }
  13775. module.refresh();
  13776. if(module.othersActive()) {
  13777. module.debug('Other sidebars currently visible');
  13778. if(settings.exclusive) {
  13779. // if not overlay queue animation after hide
  13780. if(settings.transition != 'overlay') {
  13781. module.hideOthers(module.show);
  13782. return;
  13783. }
  13784. else {
  13785. module.hideOthers();
  13786. }
  13787. }
  13788. else {
  13789. settings.transition = 'overlay';
  13790. }
  13791. }
  13792. module.pushPage(function() {
  13793. callback.call(element);
  13794. settings.onShow.call(element);
  13795. });
  13796. settings.onChange.call(element);
  13797. settings.onVisible.call(element);
  13798. }
  13799. else {
  13800. module.debug('Sidebar is already visible');
  13801. }
  13802. },
  13803. hide: function(callback) {
  13804. callback = $.isFunction(callback)
  13805. ? callback
  13806. : function(){}
  13807. ;
  13808. if(module.is.visible() || module.is.animating()) {
  13809. module.debug('Hiding sidebar', callback);
  13810. module.refreshSidebars();
  13811. module.pullPage(function() {
  13812. callback.call(element);
  13813. settings.onHidden.call(element);
  13814. });
  13815. settings.onChange.call(element);
  13816. settings.onHide.call(element);
  13817. }
  13818. },
  13819. othersAnimating: function() {
  13820. return ($sidebars.not($module).filter('.' + className.animating).length > 0);
  13821. },
  13822. othersVisible: function() {
  13823. return ($sidebars.not($module).filter('.' + className.visible).length > 0);
  13824. },
  13825. othersActive: function() {
  13826. return(module.othersVisible() || module.othersAnimating());
  13827. },
  13828. hideOthers: function(callback) {
  13829. var
  13830. $otherSidebars = $sidebars.not($module).filter('.' + className.visible),
  13831. sidebarCount = $otherSidebars.length,
  13832. callbackCount = 0
  13833. ;
  13834. callback = callback || function(){};
  13835. $otherSidebars
  13836. .sidebar('hide', function() {
  13837. callbackCount++;
  13838. if(callbackCount == sidebarCount) {
  13839. callback();
  13840. }
  13841. })
  13842. ;
  13843. },
  13844. toggle: function() {
  13845. module.verbose('Determining toggled direction');
  13846. if(module.is.hidden()) {
  13847. module.show();
  13848. }
  13849. else {
  13850. module.hide();
  13851. }
  13852. },
  13853. pushPage: function(callback) {
  13854. var
  13855. transition = module.get.transition(),
  13856. $transition = (transition === 'overlay' || module.othersActive())
  13857. ? $module
  13858. : $pusher,
  13859. animate,
  13860. dim,
  13861. transitionEnd
  13862. ;
  13863. callback = $.isFunction(callback)
  13864. ? callback
  13865. : function(){}
  13866. ;
  13867. if(settings.transition == 'scale down') {
  13868. module.scrollToTop();
  13869. }
  13870. module.set.transition(transition);
  13871. module.repaint();
  13872. animate = function() {
  13873. module.bind.clickaway();
  13874. module.add.inlineCSS();
  13875. module.set.animating();
  13876. module.set.visible();
  13877. };
  13878. dim = function() {
  13879. module.set.dimmed();
  13880. };
  13881. transitionEnd = function(event) {
  13882. if( event.target == $transition[0] ) {
  13883. $transition.off(transitionEvent + elementNamespace, transitionEnd);
  13884. module.remove.animating();
  13885. module.bind.scrollLock();
  13886. callback.call(element);
  13887. }
  13888. };
  13889. $transition.off(transitionEvent + elementNamespace);
  13890. $transition.on(transitionEvent + elementNamespace, transitionEnd);
  13891. requestAnimationFrame(animate);
  13892. if(settings.dimPage && !module.othersVisible()) {
  13893. requestAnimationFrame(dim);
  13894. }
  13895. },
  13896. pullPage: function(callback) {
  13897. var
  13898. transition = module.get.transition(),
  13899. $transition = (transition == 'overlay' || module.othersActive())
  13900. ? $module
  13901. : $pusher,
  13902. animate,
  13903. transitionEnd
  13904. ;
  13905. callback = $.isFunction(callback)
  13906. ? callback
  13907. : function(){}
  13908. ;
  13909. module.verbose('Removing context push state', module.get.direction());
  13910. module.unbind.clickaway();
  13911. module.unbind.scrollLock();
  13912. animate = function() {
  13913. module.set.transition(transition);
  13914. module.set.animating();
  13915. module.remove.visible();
  13916. if(settings.dimPage && !module.othersVisible()) {
  13917. $pusher.removeClass(className.dimmed);
  13918. }
  13919. };
  13920. transitionEnd = function(event) {
  13921. if( event.target == $transition[0] ) {
  13922. $transition.off(transitionEvent + elementNamespace, transitionEnd);
  13923. module.remove.animating();
  13924. module.remove.transition();
  13925. module.remove.inlineCSS();
  13926. if(transition == 'scale down' || (settings.returnScroll && module.is.mobile()) ) {
  13927. module.scrollBack();
  13928. }
  13929. callback.call(element);
  13930. }
  13931. };
  13932. $transition.off(transitionEvent + elementNamespace);
  13933. $transition.on(transitionEvent + elementNamespace, transitionEnd);
  13934. requestAnimationFrame(animate);
  13935. },
  13936. scrollToTop: function() {
  13937. module.verbose('Scrolling to top of page to avoid animation issues');
  13938. currentScroll = $(window).scrollTop();
  13939. $module.scrollTop(0);
  13940. window.scrollTo(0, 0);
  13941. },
  13942. scrollBack: function() {
  13943. module.verbose('Scrolling back to original page position');
  13944. window.scrollTo(0, currentScroll);
  13945. },
  13946. clear: {
  13947. cache: function() {
  13948. module.verbose('Clearing cached dimensions');
  13949. module.cache = {};
  13950. }
  13951. },
  13952. set: {
  13953. // ios only (scroll on html not document). This prevent auto-resize canvas/scroll in ios
  13954. ios: function() {
  13955. $html.addClass(className.ios);
  13956. },
  13957. // container
  13958. pushed: function() {
  13959. $context.addClass(className.pushed);
  13960. },
  13961. pushable: function() {
  13962. $context.addClass(className.pushable);
  13963. },
  13964. // pusher
  13965. dimmed: function() {
  13966. $pusher.addClass(className.dimmed);
  13967. },
  13968. // sidebar
  13969. active: function() {
  13970. $module.addClass(className.active);
  13971. },
  13972. animating: function() {
  13973. $module.addClass(className.animating);
  13974. },
  13975. transition: function(transition) {
  13976. transition = transition || module.get.transition();
  13977. $module.addClass(transition);
  13978. },
  13979. direction: function(direction) {
  13980. direction = direction || module.get.direction();
  13981. $module.addClass(className[direction]);
  13982. },
  13983. visible: function() {
  13984. $module.addClass(className.visible);
  13985. },
  13986. overlay: function() {
  13987. $module.addClass(className.overlay);
  13988. }
  13989. },
  13990. remove: {
  13991. inlineCSS: function() {
  13992. module.debug('Removing inline css styles', $style);
  13993. if($style && $style.length > 0) {
  13994. $style.remove();
  13995. }
  13996. },
  13997. // ios scroll on html not document
  13998. ios: function() {
  13999. $html.removeClass(className.ios);
  14000. },
  14001. // context
  14002. pushed: function() {
  14003. $context.removeClass(className.pushed);
  14004. },
  14005. pushable: function() {
  14006. $context.removeClass(className.pushable);
  14007. },
  14008. // sidebar
  14009. active: function() {
  14010. $module.removeClass(className.active);
  14011. },
  14012. animating: function() {
  14013. $module.removeClass(className.animating);
  14014. },
  14015. transition: function(transition) {
  14016. transition = transition || module.get.transition();
  14017. $module.removeClass(transition);
  14018. },
  14019. direction: function(direction) {
  14020. direction = direction || module.get.direction();
  14021. $module.removeClass(className[direction]);
  14022. },
  14023. visible: function() {
  14024. $module.removeClass(className.visible);
  14025. },
  14026. overlay: function() {
  14027. $module.removeClass(className.overlay);
  14028. }
  14029. },
  14030. get: {
  14031. direction: function() {
  14032. if($module.hasClass(className.top)) {
  14033. return className.top;
  14034. }
  14035. else if($module.hasClass(className.right)) {
  14036. return className.right;
  14037. }
  14038. else if($module.hasClass(className.bottom)) {
  14039. return className.bottom;
  14040. }
  14041. return className.left;
  14042. },
  14043. transition: function() {
  14044. var
  14045. direction = module.get.direction(),
  14046. transition
  14047. ;
  14048. transition = ( module.is.mobile() )
  14049. ? (settings.mobileTransition == 'auto')
  14050. ? settings.defaultTransition.mobile[direction]
  14051. : settings.mobileTransition
  14052. : (settings.transition == 'auto')
  14053. ? settings.defaultTransition.computer[direction]
  14054. : settings.transition
  14055. ;
  14056. module.verbose('Determined transition', transition);
  14057. return transition;
  14058. },
  14059. transitionEvent: function() {
  14060. var
  14061. element = document.createElement('element'),
  14062. transitions = {
  14063. 'transition' :'transitionend',
  14064. 'OTransition' :'oTransitionEnd',
  14065. 'MozTransition' :'transitionend',
  14066. 'WebkitTransition' :'webkitTransitionEnd'
  14067. },
  14068. transition
  14069. ;
  14070. for(transition in transitions){
  14071. if( element.style[transition] !== undefined ){
  14072. return transitions[transition];
  14073. }
  14074. }
  14075. }
  14076. },
  14077. is: {
  14078. ie: function() {
  14079. var
  14080. isIE11 = (!(window.ActiveXObject) && 'ActiveXObject' in window),
  14081. isIE = ('ActiveXObject' in window)
  14082. ;
  14083. return (isIE11 || isIE);
  14084. },
  14085. ios: function() {
  14086. var
  14087. userAgent = navigator.userAgent,
  14088. isIOS = userAgent.match(regExp.ios),
  14089. isMobileChrome = userAgent.match(regExp.mobileChrome)
  14090. ;
  14091. if(isIOS && !isMobileChrome) {
  14092. module.verbose('Browser was found to be iOS', userAgent);
  14093. return true;
  14094. }
  14095. else {
  14096. return false;
  14097. }
  14098. },
  14099. mobile: function() {
  14100. var
  14101. userAgent = navigator.userAgent,
  14102. isMobile = userAgent.match(regExp.mobile)
  14103. ;
  14104. if(isMobile) {
  14105. module.verbose('Browser was found to be mobile', userAgent);
  14106. return true;
  14107. }
  14108. else {
  14109. module.verbose('Browser is not mobile, using regular transition', userAgent);
  14110. return false;
  14111. }
  14112. },
  14113. hidden: function() {
  14114. return !module.is.visible();
  14115. },
  14116. visible: function() {
  14117. return $module.hasClass(className.visible);
  14118. },
  14119. // alias
  14120. open: function() {
  14121. return module.is.visible();
  14122. },
  14123. closed: function() {
  14124. return module.is.hidden();
  14125. },
  14126. vertical: function() {
  14127. return $module.hasClass(className.top);
  14128. },
  14129. animating: function() {
  14130. return $context.hasClass(className.animating);
  14131. },
  14132. rtl: function () {
  14133. if(module.cache.rtl === undefined) {
  14134. module.cache.rtl = ($module.css('direction') == 'rtl');
  14135. }
  14136. return module.cache.rtl;
  14137. }
  14138. },
  14139. setting: function(name, value) {
  14140. module.debug('Changing setting', name, value);
  14141. if( $.isPlainObject(name) ) {
  14142. $.extend(true, settings, name);
  14143. }
  14144. else if(value !== undefined) {
  14145. settings[name] = value;
  14146. }
  14147. else {
  14148. return settings[name];
  14149. }
  14150. },
  14151. internal: function(name, value) {
  14152. if( $.isPlainObject(name) ) {
  14153. $.extend(true, module, name);
  14154. }
  14155. else if(value !== undefined) {
  14156. module[name] = value;
  14157. }
  14158. else {
  14159. return module[name];
  14160. }
  14161. },
  14162. debug: function() {
  14163. if(settings.debug) {
  14164. if(settings.performance) {
  14165. module.performance.log(arguments);
  14166. }
  14167. else {
  14168. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  14169. module.debug.apply(console, arguments);
  14170. }
  14171. }
  14172. },
  14173. verbose: function() {
  14174. if(settings.verbose && settings.debug) {
  14175. if(settings.performance) {
  14176. module.performance.log(arguments);
  14177. }
  14178. else {
  14179. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  14180. module.verbose.apply(console, arguments);
  14181. }
  14182. }
  14183. },
  14184. error: function() {
  14185. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  14186. module.error.apply(console, arguments);
  14187. },
  14188. performance: {
  14189. log: function(message) {
  14190. var
  14191. currentTime,
  14192. executionTime,
  14193. previousTime
  14194. ;
  14195. if(settings.performance) {
  14196. currentTime = new Date().getTime();
  14197. previousTime = time || currentTime;
  14198. executionTime = currentTime - previousTime;
  14199. time = currentTime;
  14200. performance.push({
  14201. 'Name' : message[0],
  14202. 'Arguments' : [].slice.call(message, 1) || '',
  14203. 'Element' : element,
  14204. 'Execution Time' : executionTime
  14205. });
  14206. }
  14207. clearTimeout(module.performance.timer);
  14208. module.performance.timer = setTimeout(module.performance.display, 500);
  14209. },
  14210. display: function() {
  14211. var
  14212. title = settings.name + ':',
  14213. totalTime = 0
  14214. ;
  14215. time = false;
  14216. clearTimeout(module.performance.timer);
  14217. $.each(performance, function(index, data) {
  14218. totalTime += data['Execution Time'];
  14219. });
  14220. title += ' ' + totalTime + 'ms';
  14221. if(moduleSelector) {
  14222. title += ' \'' + moduleSelector + '\'';
  14223. }
  14224. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  14225. console.groupCollapsed(title);
  14226. if(console.table) {
  14227. console.table(performance);
  14228. }
  14229. else {
  14230. $.each(performance, function(index, data) {
  14231. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  14232. });
  14233. }
  14234. console.groupEnd();
  14235. }
  14236. performance = [];
  14237. }
  14238. },
  14239. invoke: function(query, passedArguments, context) {
  14240. var
  14241. object = instance,
  14242. maxDepth,
  14243. found,
  14244. response
  14245. ;
  14246. passedArguments = passedArguments || queryArguments;
  14247. context = element || context;
  14248. if(typeof query == 'string' && object !== undefined) {
  14249. query = query.split(/[\. ]/);
  14250. maxDepth = query.length - 1;
  14251. $.each(query, function(depth, value) {
  14252. var camelCaseValue = (depth != maxDepth)
  14253. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  14254. : query
  14255. ;
  14256. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  14257. object = object[camelCaseValue];
  14258. }
  14259. else if( object[camelCaseValue] !== undefined ) {
  14260. found = object[camelCaseValue];
  14261. return false;
  14262. }
  14263. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  14264. object = object[value];
  14265. }
  14266. else if( object[value] !== undefined ) {
  14267. found = object[value];
  14268. return false;
  14269. }
  14270. else {
  14271. module.error(error.method, query);
  14272. return false;
  14273. }
  14274. });
  14275. }
  14276. if ( $.isFunction( found ) ) {
  14277. response = found.apply(context, passedArguments);
  14278. }
  14279. else if(found !== undefined) {
  14280. response = found;
  14281. }
  14282. if($.isArray(returnedValue)) {
  14283. returnedValue.push(response);
  14284. }
  14285. else if(returnedValue !== undefined) {
  14286. returnedValue = [returnedValue, response];
  14287. }
  14288. else if(response !== undefined) {
  14289. returnedValue = response;
  14290. }
  14291. return found;
  14292. }
  14293. }
  14294. ;
  14295. if(methodInvoked) {
  14296. if(instance === undefined) {
  14297. module.initialize();
  14298. }
  14299. module.invoke(query);
  14300. }
  14301. else {
  14302. if(instance !== undefined) {
  14303. module.invoke('destroy');
  14304. }
  14305. module.initialize();
  14306. }
  14307. });
  14308. return (returnedValue !== undefined)
  14309. ? returnedValue
  14310. : this
  14311. ;
  14312. };
  14313. $.fn.sidebar.settings = {
  14314. name : 'Sidebar',
  14315. namespace : 'sidebar',
  14316. debug : false,
  14317. verbose : false,
  14318. performance : true,
  14319. transition : 'auto',
  14320. mobileTransition : 'auto',
  14321. defaultTransition : {
  14322. computer: {
  14323. left : 'uncover',
  14324. right : 'uncover',
  14325. top : 'overlay',
  14326. bottom : 'overlay'
  14327. },
  14328. mobile: {
  14329. left : 'uncover',
  14330. right : 'uncover',
  14331. top : 'overlay',
  14332. bottom : 'overlay'
  14333. }
  14334. },
  14335. context : 'body',
  14336. exclusive : false,
  14337. closable : true,
  14338. dimPage : true,
  14339. scrollLock : false,
  14340. returnScroll : false,
  14341. delaySetup : false,
  14342. duration : 500,
  14343. onChange : function(){},
  14344. onShow : function(){},
  14345. onHide : function(){},
  14346. onHidden : function(){},
  14347. onVisible : function(){},
  14348. className : {
  14349. active : 'active',
  14350. animating : 'animating',
  14351. dimmed : 'dimmed',
  14352. ios : 'ios',
  14353. pushable : 'pushable',
  14354. pushed : 'pushed',
  14355. right : 'right',
  14356. top : 'top',
  14357. left : 'left',
  14358. bottom : 'bottom',
  14359. visible : 'visible'
  14360. },
  14361. selector: {
  14362. fixed : '.fixed',
  14363. omitted : 'script, link, style, .ui.modal, .ui.dimmer, .ui.nag, .ui.fixed',
  14364. pusher : '.pusher',
  14365. sidebar : '.ui.sidebar'
  14366. },
  14367. regExp: {
  14368. ios : /(iPad|iPhone|iPod)/g,
  14369. mobileChrome : /(CriOS)/g,
  14370. 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
  14371. },
  14372. error : {
  14373. method : 'The method you called is not defined.',
  14374. pusher : 'Had to add pusher element. For optimal performance make sure body content is inside a pusher element',
  14375. movedSidebar : 'Had to move sidebar. For optimal performance make sure sidebar and pusher are direct children of your body tag',
  14376. overlay : 'The overlay setting is no longer supported, use animation: overlay',
  14377. notFound : 'There were no elements that matched the specified selector'
  14378. }
  14379. };
  14380. })( jQuery, window , document );
  14381. /*!
  14382. * # Semantic UI 2.1.4 - Sticky
  14383. * http://github.com/semantic-org/semantic-ui/
  14384. *
  14385. *
  14386. * Copyright 2015 Contributors
  14387. * Released under the MIT license
  14388. * http://opensource.org/licenses/MIT
  14389. *
  14390. */
  14391. ;(function ( $, window, document, undefined ) {
  14392. "use strict";
  14393. $.fn.sticky = function(parameters) {
  14394. var
  14395. $allModules = $(this),
  14396. moduleSelector = $allModules.selector || '',
  14397. time = new Date().getTime(),
  14398. performance = [],
  14399. query = arguments[0],
  14400. methodInvoked = (typeof query == 'string'),
  14401. queryArguments = [].slice.call(arguments, 1),
  14402. returnedValue
  14403. ;
  14404. $allModules
  14405. .each(function() {
  14406. var
  14407. settings = ( $.isPlainObject(parameters) )
  14408. ? $.extend(true, {}, $.fn.sticky.settings, parameters)
  14409. : $.extend({}, $.fn.sticky.settings),
  14410. className = settings.className,
  14411. namespace = settings.namespace,
  14412. error = settings.error,
  14413. eventNamespace = '.' + namespace,
  14414. moduleNamespace = 'module-' + namespace,
  14415. $module = $(this),
  14416. $window = $(window),
  14417. $scroll = $(settings.scrollContext),
  14418. $container,
  14419. $context,
  14420. selector = $module.selector || '',
  14421. instance = $module.data(moduleNamespace),
  14422. requestAnimationFrame = window.requestAnimationFrame
  14423. || window.mozRequestAnimationFrame
  14424. || window.webkitRequestAnimationFrame
  14425. || window.msRequestAnimationFrame
  14426. || function(callback) { setTimeout(callback, 0); },
  14427. element = this,
  14428. observer,
  14429. module
  14430. ;
  14431. module = {
  14432. initialize: function() {
  14433. module.determineContainer();
  14434. module.determineContext();
  14435. module.verbose('Initializing sticky', settings, $container);
  14436. module.save.positions();
  14437. module.checkErrors();
  14438. module.bind.events();
  14439. if(settings.observeChanges) {
  14440. module.observeChanges();
  14441. }
  14442. module.instantiate();
  14443. },
  14444. instantiate: function() {
  14445. module.verbose('Storing instance of module', module);
  14446. instance = module;
  14447. $module
  14448. .data(moduleNamespace, module)
  14449. ;
  14450. },
  14451. destroy: function() {
  14452. module.verbose('Destroying previous instance');
  14453. module.reset();
  14454. if(observer) {
  14455. observer.disconnect();
  14456. }
  14457. $window
  14458. .off('load' + eventNamespace, module.event.load)
  14459. .off('resize' + eventNamespace, module.event.resize)
  14460. ;
  14461. $scroll
  14462. .off('scrollchange' + eventNamespace, module.event.scrollchange)
  14463. ;
  14464. $module.removeData(moduleNamespace);
  14465. },
  14466. observeChanges: function() {
  14467. var
  14468. context = $context[0]
  14469. ;
  14470. if('MutationObserver' in window) {
  14471. observer = new MutationObserver(function(mutations) {
  14472. clearTimeout(module.timer);
  14473. module.timer = setTimeout(function() {
  14474. module.verbose('DOM tree modified, updating sticky menu', mutations);
  14475. module.refresh();
  14476. }, 100);
  14477. });
  14478. observer.observe(element, {
  14479. childList : true,
  14480. subtree : true
  14481. });
  14482. observer.observe(context, {
  14483. childList : true,
  14484. subtree : true
  14485. });
  14486. module.debug('Setting up mutation observer', observer);
  14487. }
  14488. },
  14489. determineContainer: function() {
  14490. $container = $module.offsetParent();
  14491. },
  14492. determineContext: function() {
  14493. if(settings.context) {
  14494. $context = $(settings.context);
  14495. }
  14496. else {
  14497. $context = $container;
  14498. }
  14499. if($context.length === 0) {
  14500. module.error(error.invalidContext, settings.context, $module);
  14501. return;
  14502. }
  14503. },
  14504. checkErrors: function() {
  14505. if( module.is.hidden() ) {
  14506. module.error(error.visible, $module);
  14507. }
  14508. if(module.cache.element.height > module.cache.context.height) {
  14509. module.reset();
  14510. module.error(error.elementSize, $module);
  14511. return;
  14512. }
  14513. },
  14514. bind: {
  14515. events: function() {
  14516. $window
  14517. .on('load' + eventNamespace, module.event.load)
  14518. .on('resize' + eventNamespace, module.event.resize)
  14519. ;
  14520. // pub/sub pattern
  14521. $scroll
  14522. .off('scroll' + eventNamespace)
  14523. .on('scroll' + eventNamespace, module.event.scroll)
  14524. .on('scrollchange' + eventNamespace, module.event.scrollchange)
  14525. ;
  14526. }
  14527. },
  14528. event: {
  14529. load: function() {
  14530. module.verbose('Page contents finished loading');
  14531. requestAnimationFrame(module.refresh);
  14532. },
  14533. resize: function() {
  14534. module.verbose('Window resized');
  14535. requestAnimationFrame(module.refresh);
  14536. },
  14537. scroll: function() {
  14538. requestAnimationFrame(function() {
  14539. $scroll.triggerHandler('scrollchange' + eventNamespace, $scroll.scrollTop() );
  14540. });
  14541. },
  14542. scrollchange: function(event, scrollPosition) {
  14543. module.stick(scrollPosition);
  14544. settings.onScroll.call(element);
  14545. }
  14546. },
  14547. refresh: function(hardRefresh) {
  14548. module.reset();
  14549. if(!settings.context) {
  14550. module.determineContext();
  14551. }
  14552. if(hardRefresh) {
  14553. module.determineContainer();
  14554. }
  14555. module.save.positions();
  14556. module.stick();
  14557. settings.onReposition.call(element);
  14558. },
  14559. supports: {
  14560. sticky: function() {
  14561. var
  14562. $element = $('<div/>'),
  14563. element = $element[0]
  14564. ;
  14565. $element.addClass(className.supported);
  14566. return($element.css('position').match('sticky'));
  14567. }
  14568. },
  14569. save: {
  14570. lastScroll: function(scroll) {
  14571. module.lastScroll = scroll;
  14572. },
  14573. elementScroll: function(scroll) {
  14574. module.elementScroll = scroll;
  14575. },
  14576. positions: function() {
  14577. var
  14578. window = {
  14579. height: $window.height()
  14580. },
  14581. element = {
  14582. margin: {
  14583. top : parseInt($module.css('margin-top'), 10),
  14584. bottom : parseInt($module.css('margin-bottom'), 10),
  14585. },
  14586. offset : $module.offset(),
  14587. width : $module.outerWidth(),
  14588. height : $module.outerHeight()
  14589. },
  14590. context = {
  14591. offset : $context.offset(),
  14592. height : $context.outerHeight()
  14593. },
  14594. container = {
  14595. height: $container.outerHeight()
  14596. }
  14597. ;
  14598. module.cache = {
  14599. fits : ( element.height < window.height ),
  14600. window: {
  14601. height: window.height
  14602. },
  14603. element: {
  14604. margin : element.margin,
  14605. top : element.offset.top - element.margin.top,
  14606. left : element.offset.left,
  14607. width : element.width,
  14608. height : element.height,
  14609. bottom : element.offset.top + element.height
  14610. },
  14611. context: {
  14612. top : context.offset.top,
  14613. height : context.height,
  14614. bottom : context.offset.top + context.height
  14615. }
  14616. };
  14617. module.set.containerSize();
  14618. module.set.size();
  14619. module.stick();
  14620. module.debug('Caching element positions', module.cache);
  14621. }
  14622. },
  14623. get: {
  14624. direction: function(scroll) {
  14625. var
  14626. direction = 'down'
  14627. ;
  14628. scroll = scroll || $scroll.scrollTop();
  14629. if(module.lastScroll !== undefined) {
  14630. if(module.lastScroll < scroll) {
  14631. direction = 'down';
  14632. }
  14633. else if(module.lastScroll > scroll) {
  14634. direction = 'up';
  14635. }
  14636. }
  14637. return direction;
  14638. },
  14639. scrollChange: function(scroll) {
  14640. scroll = scroll || $scroll.scrollTop();
  14641. return (module.lastScroll)
  14642. ? (scroll - module.lastScroll)
  14643. : 0
  14644. ;
  14645. },
  14646. currentElementScroll: function() {
  14647. if(module.elementScroll) {
  14648. return module.elementScroll;
  14649. }
  14650. return ( module.is.top() )
  14651. ? Math.abs(parseInt($module.css('top'), 10)) || 0
  14652. : Math.abs(parseInt($module.css('bottom'), 10)) || 0
  14653. ;
  14654. },
  14655. elementScroll: function(scroll) {
  14656. scroll = scroll || $scroll.scrollTop();
  14657. var
  14658. element = module.cache.element,
  14659. window = module.cache.window,
  14660. delta = module.get.scrollChange(scroll),
  14661. maxScroll = (element.height - window.height + settings.offset),
  14662. elementScroll = module.get.currentElementScroll(),
  14663. possibleScroll = (elementScroll + delta)
  14664. ;
  14665. if(module.cache.fits || possibleScroll < 0) {
  14666. elementScroll = 0;
  14667. }
  14668. else if(possibleScroll > maxScroll ) {
  14669. elementScroll = maxScroll;
  14670. }
  14671. else {
  14672. elementScroll = possibleScroll;
  14673. }
  14674. return elementScroll;
  14675. }
  14676. },
  14677. remove: {
  14678. lastScroll: function() {
  14679. delete module.lastScroll;
  14680. },
  14681. elementScroll: function(scroll) {
  14682. delete module.elementScroll;
  14683. },
  14684. offset: function() {
  14685. $module.css('margin-top', '');
  14686. }
  14687. },
  14688. set: {
  14689. offset: function() {
  14690. module.verbose('Setting offset on element', settings.offset);
  14691. $module
  14692. .css('margin-top', settings.offset)
  14693. ;
  14694. },
  14695. containerSize: function() {
  14696. var
  14697. tagName = $container.get(0).tagName
  14698. ;
  14699. if(tagName === 'HTML' || tagName == 'body') {
  14700. // this can trigger for too many reasons
  14701. //module.error(error.container, tagName, $module);
  14702. module.determineContainer();
  14703. }
  14704. else {
  14705. if( Math.abs($container.outerHeight() - module.cache.context.height) > settings.jitter) {
  14706. module.debug('Context has padding, specifying exact height for container', module.cache.context.height);
  14707. $container.css({
  14708. height: module.cache.context.height
  14709. });
  14710. }
  14711. }
  14712. },
  14713. minimumSize: function() {
  14714. var
  14715. element = module.cache.element
  14716. ;
  14717. $container
  14718. .css('min-height', element.height)
  14719. ;
  14720. },
  14721. scroll: function(scroll) {
  14722. module.debug('Setting scroll on element', scroll);
  14723. if(module.elementScroll == scroll) {
  14724. return;
  14725. }
  14726. if( module.is.top() ) {
  14727. $module
  14728. .css('bottom', '')
  14729. .css('top', -scroll)
  14730. ;
  14731. }
  14732. if( module.is.bottom() ) {
  14733. $module
  14734. .css('top', '')
  14735. .css('bottom', scroll)
  14736. ;
  14737. }
  14738. },
  14739. size: function() {
  14740. if(module.cache.element.height !== 0 && module.cache.element.width !== 0) {
  14741. element.style.setProperty('width', module.cache.element.width + 'px', 'important');
  14742. element.style.setProperty('height', module.cache.element.height + 'px', 'important');
  14743. }
  14744. }
  14745. },
  14746. is: {
  14747. top: function() {
  14748. return $module.hasClass(className.top);
  14749. },
  14750. bottom: function() {
  14751. return $module.hasClass(className.bottom);
  14752. },
  14753. initialPosition: function() {
  14754. return (!module.is.fixed() && !module.is.bound());
  14755. },
  14756. hidden: function() {
  14757. return (!$module.is(':visible'));
  14758. },
  14759. bound: function() {
  14760. return $module.hasClass(className.bound);
  14761. },
  14762. fixed: function() {
  14763. return $module.hasClass(className.fixed);
  14764. }
  14765. },
  14766. stick: function(scroll) {
  14767. var
  14768. cachedPosition = scroll || $scroll.scrollTop(),
  14769. cache = module.cache,
  14770. fits = cache.fits,
  14771. element = cache.element,
  14772. window = cache.window,
  14773. context = cache.context,
  14774. offset = (module.is.bottom() && settings.pushing)
  14775. ? settings.bottomOffset
  14776. : settings.offset,
  14777. scroll = {
  14778. top : cachedPosition + offset,
  14779. bottom : cachedPosition + offset + window.height
  14780. },
  14781. direction = module.get.direction(scroll.top),
  14782. elementScroll = (fits)
  14783. ? 0
  14784. : module.get.elementScroll(scroll.top),
  14785. // shorthand
  14786. doesntFit = !fits,
  14787. elementVisible = (element.height !== 0)
  14788. ;
  14789. if(elementVisible) {
  14790. if( module.is.initialPosition() ) {
  14791. if(scroll.top >= context.bottom) {
  14792. module.debug('Initial element position is bottom of container');
  14793. module.bindBottom();
  14794. }
  14795. else if(scroll.top > element.top) {
  14796. if( (element.height + scroll.top - elementScroll) >= context.bottom ) {
  14797. module.debug('Initial element position is bottom of container');
  14798. module.bindBottom();
  14799. }
  14800. else {
  14801. module.debug('Initial element position is fixed');
  14802. module.fixTop();
  14803. }
  14804. }
  14805. }
  14806. else if( module.is.fixed() ) {
  14807. // currently fixed top
  14808. if( module.is.top() ) {
  14809. if( scroll.top <= element.top ) {
  14810. module.debug('Fixed element reached top of container');
  14811. module.setInitialPosition();
  14812. }
  14813. else if( (element.height + scroll.top - elementScroll) >= context.bottom ) {
  14814. module.debug('Fixed element reached bottom of container');
  14815. module.bindBottom();
  14816. }
  14817. // scroll element if larger than screen
  14818. else if(doesntFit) {
  14819. module.set.scroll(elementScroll);
  14820. module.save.lastScroll(scroll.top);
  14821. module.save.elementScroll(elementScroll);
  14822. }
  14823. }
  14824. // currently fixed bottom
  14825. else if(module.is.bottom() ) {
  14826. // top edge
  14827. if( (scroll.bottom - element.height) <= element.top) {
  14828. module.debug('Bottom fixed rail has reached top of container');
  14829. module.setInitialPosition();
  14830. }
  14831. // bottom edge
  14832. else if(scroll.bottom >= context.bottom) {
  14833. module.debug('Bottom fixed rail has reached bottom of container');
  14834. module.bindBottom();
  14835. }
  14836. // scroll element if larger than screen
  14837. else if(doesntFit) {
  14838. module.set.scroll(elementScroll);
  14839. module.save.lastScroll(scroll.top);
  14840. module.save.elementScroll(elementScroll);
  14841. }
  14842. }
  14843. }
  14844. else if( module.is.bottom() ) {
  14845. if(settings.pushing) {
  14846. if(module.is.bound() && scroll.bottom <= context.bottom ) {
  14847. module.debug('Fixing bottom attached element to bottom of browser.');
  14848. module.fixBottom();
  14849. }
  14850. }
  14851. else {
  14852. if(module.is.bound() && (scroll.top <= context.bottom - element.height) ) {
  14853. module.debug('Fixing bottom attached element to top of browser.');
  14854. module.fixTop();
  14855. }
  14856. }
  14857. }
  14858. }
  14859. },
  14860. bindTop: function() {
  14861. module.debug('Binding element to top of parent container');
  14862. module.remove.offset();
  14863. $module
  14864. .css({
  14865. left : '',
  14866. top : '',
  14867. marginBottom : ''
  14868. })
  14869. .removeClass(className.fixed)
  14870. .removeClass(className.bottom)
  14871. .addClass(className.bound)
  14872. .addClass(className.top)
  14873. ;
  14874. settings.onTop.call(element);
  14875. settings.onUnstick.call(element);
  14876. },
  14877. bindBottom: function() {
  14878. module.debug('Binding element to bottom of parent container');
  14879. module.remove.offset();
  14880. $module
  14881. .css({
  14882. left : '',
  14883. top : ''
  14884. })
  14885. .removeClass(className.fixed)
  14886. .removeClass(className.top)
  14887. .addClass(className.bound)
  14888. .addClass(className.bottom)
  14889. ;
  14890. settings.onBottom.call(element);
  14891. settings.onUnstick.call(element);
  14892. },
  14893. setInitialPosition: function() {
  14894. module.debug('Returning to initial position');
  14895. module.unfix();
  14896. module.unbind();
  14897. },
  14898. fixTop: function() {
  14899. module.debug('Fixing element to top of page');
  14900. module.set.minimumSize();
  14901. module.set.offset();
  14902. $module
  14903. .css({
  14904. left : module.cache.element.left,
  14905. bottom : '',
  14906. marginBottom : ''
  14907. })
  14908. .removeClass(className.bound)
  14909. .removeClass(className.bottom)
  14910. .addClass(className.fixed)
  14911. .addClass(className.top)
  14912. ;
  14913. settings.onStick.call(element);
  14914. },
  14915. fixBottom: function() {
  14916. module.debug('Sticking element to bottom of page');
  14917. module.set.minimumSize();
  14918. module.set.offset();
  14919. $module
  14920. .css({
  14921. left : module.cache.element.left,
  14922. bottom : '',
  14923. marginBottom : ''
  14924. })
  14925. .removeClass(className.bound)
  14926. .removeClass(className.top)
  14927. .addClass(className.fixed)
  14928. .addClass(className.bottom)
  14929. ;
  14930. settings.onStick.call(element);
  14931. },
  14932. unbind: function() {
  14933. if( module.is.bound() ) {
  14934. module.debug('Removing container bound position on element');
  14935. module.remove.offset();
  14936. $module
  14937. .removeClass(className.bound)
  14938. .removeClass(className.top)
  14939. .removeClass(className.bottom)
  14940. ;
  14941. }
  14942. },
  14943. unfix: function() {
  14944. if( module.is.fixed() ) {
  14945. module.debug('Removing fixed position on element');
  14946. module.remove.offset();
  14947. $module
  14948. .removeClass(className.fixed)
  14949. .removeClass(className.top)
  14950. .removeClass(className.bottom)
  14951. ;
  14952. settings.onUnstick.call(element);
  14953. }
  14954. },
  14955. reset: function() {
  14956. module.debug('Reseting elements position');
  14957. module.unbind();
  14958. module.unfix();
  14959. module.resetCSS();
  14960. module.remove.offset();
  14961. module.remove.lastScroll();
  14962. },
  14963. resetCSS: function() {
  14964. $module
  14965. .css({
  14966. width : '',
  14967. height : ''
  14968. })
  14969. ;
  14970. $container
  14971. .css({
  14972. height: ''
  14973. })
  14974. ;
  14975. },
  14976. setting: function(name, value) {
  14977. if( $.isPlainObject(name) ) {
  14978. $.extend(true, settings, name);
  14979. }
  14980. else if(value !== undefined) {
  14981. settings[name] = value;
  14982. }
  14983. else {
  14984. return settings[name];
  14985. }
  14986. },
  14987. internal: function(name, value) {
  14988. if( $.isPlainObject(name) ) {
  14989. $.extend(true, module, name);
  14990. }
  14991. else if(value !== undefined) {
  14992. module[name] = value;
  14993. }
  14994. else {
  14995. return module[name];
  14996. }
  14997. },
  14998. debug: function() {
  14999. if(settings.debug) {
  15000. if(settings.performance) {
  15001. module.performance.log(arguments);
  15002. }
  15003. else {
  15004. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  15005. module.debug.apply(console, arguments);
  15006. }
  15007. }
  15008. },
  15009. verbose: function() {
  15010. if(settings.verbose && settings.debug) {
  15011. if(settings.performance) {
  15012. module.performance.log(arguments);
  15013. }
  15014. else {
  15015. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  15016. module.verbose.apply(console, arguments);
  15017. }
  15018. }
  15019. },
  15020. error: function() {
  15021. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  15022. module.error.apply(console, arguments);
  15023. },
  15024. performance: {
  15025. log: function(message) {
  15026. var
  15027. currentTime,
  15028. executionTime,
  15029. previousTime
  15030. ;
  15031. if(settings.performance) {
  15032. currentTime = new Date().getTime();
  15033. previousTime = time || currentTime;
  15034. executionTime = currentTime - previousTime;
  15035. time = currentTime;
  15036. performance.push({
  15037. 'Name' : message[0],
  15038. 'Arguments' : [].slice.call(message, 1) || '',
  15039. 'Element' : element,
  15040. 'Execution Time' : executionTime
  15041. });
  15042. }
  15043. clearTimeout(module.performance.timer);
  15044. module.performance.timer = setTimeout(module.performance.display, 0);
  15045. },
  15046. display: function() {
  15047. var
  15048. title = settings.name + ':',
  15049. totalTime = 0
  15050. ;
  15051. time = false;
  15052. clearTimeout(module.performance.timer);
  15053. $.each(performance, function(index, data) {
  15054. totalTime += data['Execution Time'];
  15055. });
  15056. title += ' ' + totalTime + 'ms';
  15057. if(moduleSelector) {
  15058. title += ' \'' + moduleSelector + '\'';
  15059. }
  15060. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  15061. console.groupCollapsed(title);
  15062. if(console.table) {
  15063. console.table(performance);
  15064. }
  15065. else {
  15066. $.each(performance, function(index, data) {
  15067. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  15068. });
  15069. }
  15070. console.groupEnd();
  15071. }
  15072. performance = [];
  15073. }
  15074. },
  15075. invoke: function(query, passedArguments, context) {
  15076. var
  15077. object = instance,
  15078. maxDepth,
  15079. found,
  15080. response
  15081. ;
  15082. passedArguments = passedArguments || queryArguments;
  15083. context = element || context;
  15084. if(typeof query == 'string' && object !== undefined) {
  15085. query = query.split(/[\. ]/);
  15086. maxDepth = query.length - 1;
  15087. $.each(query, function(depth, value) {
  15088. var camelCaseValue = (depth != maxDepth)
  15089. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  15090. : query
  15091. ;
  15092. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  15093. object = object[camelCaseValue];
  15094. }
  15095. else if( object[camelCaseValue] !== undefined ) {
  15096. found = object[camelCaseValue];
  15097. return false;
  15098. }
  15099. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  15100. object = object[value];
  15101. }
  15102. else if( object[value] !== undefined ) {
  15103. found = object[value];
  15104. return false;
  15105. }
  15106. else {
  15107. return false;
  15108. }
  15109. });
  15110. }
  15111. if ( $.isFunction( found ) ) {
  15112. response = found.apply(context, passedArguments);
  15113. }
  15114. else if(found !== undefined) {
  15115. response = found;
  15116. }
  15117. if($.isArray(returnedValue)) {
  15118. returnedValue.push(response);
  15119. }
  15120. else if(returnedValue !== undefined) {
  15121. returnedValue = [returnedValue, response];
  15122. }
  15123. else if(response !== undefined) {
  15124. returnedValue = response;
  15125. }
  15126. return found;
  15127. }
  15128. };
  15129. if(methodInvoked) {
  15130. if(instance === undefined) {
  15131. module.initialize();
  15132. }
  15133. module.invoke(query);
  15134. }
  15135. else {
  15136. if(instance !== undefined) {
  15137. instance.invoke('destroy');
  15138. }
  15139. module.initialize();
  15140. }
  15141. })
  15142. ;
  15143. return (returnedValue !== undefined)
  15144. ? returnedValue
  15145. : this
  15146. ;
  15147. };
  15148. $.fn.sticky.settings = {
  15149. name : 'Sticky',
  15150. namespace : 'sticky',
  15151. debug : false,
  15152. verbose : true,
  15153. performance : true,
  15154. // whether to stick in the opposite direction on scroll up
  15155. pushing : false,
  15156. context : false,
  15157. // Context to watch scroll events
  15158. scrollContext : window,
  15159. // Offset to adjust scroll
  15160. offset : 0,
  15161. // Offset to adjust scroll when attached to bottom of screen
  15162. bottomOffset : 0,
  15163. jitter : 5, // will only set container height if difference between context and container is larger than this number
  15164. // Whether to automatically observe changes with Mutation Observers
  15165. observeChanges : false,
  15166. // Called when position is recalculated
  15167. onReposition : function(){},
  15168. // Called on each scroll
  15169. onScroll : function(){},
  15170. // Called when element is stuck to viewport
  15171. onStick : function(){},
  15172. // Called when element is unstuck from viewport
  15173. onUnstick : function(){},
  15174. // Called when element reaches top of context
  15175. onTop : function(){},
  15176. // Called when element reaches bottom of context
  15177. onBottom : function(){},
  15178. error : {
  15179. container : 'Sticky element must be inside a relative container',
  15180. visible : 'Element is hidden, you must call refresh after element becomes visible',
  15181. method : 'The method you called is not defined.',
  15182. invalidContext : 'Context specified does not exist',
  15183. elementSize : 'Sticky element is larger than its container, cannot create sticky.'
  15184. },
  15185. className : {
  15186. bound : 'bound',
  15187. fixed : 'fixed',
  15188. supported : 'native',
  15189. top : 'top',
  15190. bottom : 'bottom'
  15191. }
  15192. };
  15193. })( jQuery, window , document );
  15194. /*!
  15195. * # Semantic UI 2.1.4 - Tab
  15196. * http://github.com/semantic-org/semantic-ui/
  15197. *
  15198. *
  15199. * Copyright 2015 Contributors
  15200. * Released under the MIT license
  15201. * http://opensource.org/licenses/MIT
  15202. *
  15203. */
  15204. ;(function ($, window, document, undefined) {
  15205. "use strict";
  15206. $.fn.tab = function(parameters) {
  15207. var
  15208. // use window context if none specified
  15209. $allModules = $.isFunction(this)
  15210. ? $(window)
  15211. : $(this),
  15212. moduleSelector = $allModules.selector || '',
  15213. time = new Date().getTime(),
  15214. performance = [],
  15215. query = arguments[0],
  15216. methodInvoked = (typeof query == 'string'),
  15217. queryArguments = [].slice.call(arguments, 1),
  15218. initializedHistory = false,
  15219. returnedValue
  15220. ;
  15221. $allModules
  15222. .each(function() {
  15223. var
  15224. settings = ( $.isPlainObject(parameters) )
  15225. ? $.extend(true, {}, $.fn.tab.settings, parameters)
  15226. : $.extend({}, $.fn.tab.settings),
  15227. className = settings.className,
  15228. metadata = settings.metadata,
  15229. selector = settings.selector,
  15230. error = settings.error,
  15231. eventNamespace = '.' + settings.namespace,
  15232. moduleNamespace = 'module-' + settings.namespace,
  15233. $module = $(this),
  15234. $context,
  15235. $tabs,
  15236. cache = {},
  15237. firstLoad = true,
  15238. recursionDepth = 0,
  15239. element = this,
  15240. instance = $module.data(moduleNamespace),
  15241. activeTabPath,
  15242. parameterArray,
  15243. module,
  15244. historyEvent
  15245. ;
  15246. module = {
  15247. initialize: function() {
  15248. module.debug('Initializing tab menu item', $module);
  15249. module.fix.callbacks();
  15250. module.determineTabs();
  15251. module.debug('Determining tabs', settings.context, $tabs);
  15252. // set up automatic routing
  15253. if(settings.auto) {
  15254. module.set.auto();
  15255. }
  15256. module.bind.events();
  15257. if(settings.history && !initializedHistory) {
  15258. module.initializeHistory();
  15259. initializedHistory = true;
  15260. }
  15261. module.instantiate();
  15262. },
  15263. instantiate: function () {
  15264. module.verbose('Storing instance of module', module);
  15265. instance = module;
  15266. $module
  15267. .data(moduleNamespace, module)
  15268. ;
  15269. },
  15270. destroy: function() {
  15271. module.debug('Destroying tabs', $module);
  15272. $module
  15273. .removeData(moduleNamespace)
  15274. .off(eventNamespace)
  15275. ;
  15276. },
  15277. bind: {
  15278. events: function() {
  15279. // if using $.tab don't add events
  15280. if( !$.isWindow( element ) ) {
  15281. module.debug('Attaching tab activation events to element', $module);
  15282. $module
  15283. .on('click' + eventNamespace, module.event.click)
  15284. ;
  15285. }
  15286. }
  15287. },
  15288. determineTabs: function() {
  15289. var
  15290. $reference
  15291. ;
  15292. // determine tab context
  15293. if(settings.context === 'parent') {
  15294. if($module.closest(selector.ui).length > 0) {
  15295. $reference = $module.closest(selector.ui);
  15296. module.verbose('Using closest UI element as parent', $reference);
  15297. }
  15298. else {
  15299. $reference = $module;
  15300. }
  15301. $context = $reference.parent();
  15302. module.verbose('Determined parent element for creating context', $context);
  15303. }
  15304. else if(settings.context) {
  15305. $context = $(settings.context);
  15306. module.verbose('Using selector for tab context', settings.context, $context);
  15307. }
  15308. else {
  15309. $context = $('body');
  15310. }
  15311. // find tabs
  15312. if(settings.childrenOnly) {
  15313. $tabs = $context.children(selector.tabs);
  15314. module.debug('Searching tab context children for tabs', $context, $tabs);
  15315. }
  15316. else {
  15317. $tabs = $context.find(selector.tabs);
  15318. module.debug('Searching tab context for tabs', $context, $tabs);
  15319. }
  15320. },
  15321. fix: {
  15322. callbacks: function() {
  15323. if( $.isPlainObject(parameters) && (parameters.onTabLoad || parameters.onTabInit) ) {
  15324. if(parameters.onTabLoad) {
  15325. parameters.onLoad = parameters.onTabLoad;
  15326. delete parameters.onTabLoad;
  15327. module.error(error.legacyLoad, parameters.onLoad);
  15328. }
  15329. if(parameters.onTabInit) {
  15330. parameters.onFirstLoad = parameters.onTabInit;
  15331. delete parameters.onTabInit;
  15332. module.error(error.legacyInit, parameters.onFirstLoad);
  15333. }
  15334. settings = $.extend(true, {}, $.fn.tab.settings, parameters);
  15335. }
  15336. }
  15337. },
  15338. initializeHistory: function() {
  15339. module.debug('Initializing page state');
  15340. if( $.address === undefined ) {
  15341. module.error(error.state);
  15342. return false;
  15343. }
  15344. else {
  15345. if(settings.historyType == 'state') {
  15346. module.debug('Using HTML5 to manage state');
  15347. if(settings.path !== false) {
  15348. $.address
  15349. .history(true)
  15350. .state(settings.path)
  15351. ;
  15352. }
  15353. else {
  15354. module.error(error.path);
  15355. return false;
  15356. }
  15357. }
  15358. $.address
  15359. .bind('change', module.event.history.change)
  15360. ;
  15361. }
  15362. },
  15363. event: {
  15364. click: function(event) {
  15365. var
  15366. tabPath = $(this).data(metadata.tab)
  15367. ;
  15368. if(tabPath !== undefined) {
  15369. if(settings.history) {
  15370. module.verbose('Updating page state', event);
  15371. $.address.value(tabPath);
  15372. }
  15373. else {
  15374. module.verbose('Changing tab', event);
  15375. module.changeTab(tabPath);
  15376. }
  15377. event.preventDefault();
  15378. }
  15379. else {
  15380. module.debug('No tab specified');
  15381. }
  15382. },
  15383. history: {
  15384. change: function(event) {
  15385. var
  15386. tabPath = event.pathNames.join('/') || module.get.initialPath(),
  15387. pageTitle = settings.templates.determineTitle(tabPath) || false
  15388. ;
  15389. module.performance.display();
  15390. module.debug('History change event', tabPath, event);
  15391. historyEvent = event;
  15392. if(tabPath !== undefined) {
  15393. module.changeTab(tabPath);
  15394. }
  15395. if(pageTitle) {
  15396. $.address.title(pageTitle);
  15397. }
  15398. }
  15399. }
  15400. },
  15401. refresh: function() {
  15402. if(activeTabPath) {
  15403. module.debug('Refreshing tab', activeTabPath);
  15404. module.changeTab(activeTabPath);
  15405. }
  15406. },
  15407. cache: {
  15408. read: function(cacheKey) {
  15409. return (cacheKey !== undefined)
  15410. ? cache[cacheKey]
  15411. : false
  15412. ;
  15413. },
  15414. add: function(cacheKey, content) {
  15415. cacheKey = cacheKey || activeTabPath;
  15416. module.debug('Adding cached content for', cacheKey);
  15417. cache[cacheKey] = content;
  15418. },
  15419. remove: function(cacheKey) {
  15420. cacheKey = cacheKey || activeTabPath;
  15421. module.debug('Removing cached content for', cacheKey);
  15422. delete cache[cacheKey];
  15423. }
  15424. },
  15425. set: {
  15426. auto: function() {
  15427. var
  15428. url = (typeof settings.path == 'string')
  15429. ? settings.path.replace(/\/$/, '') + '/{$tab}'
  15430. : '/{$tab}'
  15431. ;
  15432. module.verbose('Setting up automatic tab retrieval from server', url);
  15433. if($.isPlainObject(settings.apiSettings)) {
  15434. settings.apiSettings.url = url;
  15435. }
  15436. else {
  15437. settings.apiSettings = {
  15438. url: url
  15439. };
  15440. }
  15441. },
  15442. loading: function(tabPath) {
  15443. var
  15444. $tab = module.get.tabElement(tabPath),
  15445. isLoading = $tab.hasClass(className.loading)
  15446. ;
  15447. if(!isLoading) {
  15448. module.verbose('Setting loading state for', $tab);
  15449. $tab
  15450. .addClass(className.loading)
  15451. .siblings($tabs)
  15452. .removeClass(className.active + ' ' + className.loading)
  15453. ;
  15454. if($tab.length > 0) {
  15455. settings.onRequest.call($tab[0], tabPath);
  15456. }
  15457. }
  15458. },
  15459. state: function(state) {
  15460. $.address.value(state);
  15461. }
  15462. },
  15463. changeTab: function(tabPath) {
  15464. var
  15465. pushStateAvailable = (window.history && window.history.pushState),
  15466. shouldIgnoreLoad = (pushStateAvailable && settings.ignoreFirstLoad && firstLoad),
  15467. remoteContent = (settings.auto || $.isPlainObject(settings.apiSettings) ),
  15468. // only add default path if not remote content
  15469. pathArray = (remoteContent && !shouldIgnoreLoad)
  15470. ? module.utilities.pathToArray(tabPath)
  15471. : module.get.defaultPathArray(tabPath)
  15472. ;
  15473. tabPath = module.utilities.arrayToPath(pathArray);
  15474. $.each(pathArray, function(index, tab) {
  15475. var
  15476. currentPathArray = pathArray.slice(0, index + 1),
  15477. currentPath = module.utilities.arrayToPath(currentPathArray),
  15478. isTab = module.is.tab(currentPath),
  15479. isLastIndex = (index + 1 == pathArray.length),
  15480. $tab = module.get.tabElement(currentPath),
  15481. $anchor,
  15482. nextPathArray,
  15483. nextPath,
  15484. isLastTab
  15485. ;
  15486. module.verbose('Looking for tab', tab);
  15487. if(isTab) {
  15488. module.verbose('Tab was found', tab);
  15489. // scope up
  15490. activeTabPath = currentPath;
  15491. parameterArray = module.utilities.filterArray(pathArray, currentPathArray);
  15492. if(isLastIndex) {
  15493. isLastTab = true;
  15494. }
  15495. else {
  15496. nextPathArray = pathArray.slice(0, index + 2);
  15497. nextPath = module.utilities.arrayToPath(nextPathArray);
  15498. isLastTab = ( !module.is.tab(nextPath) );
  15499. if(isLastTab) {
  15500. module.verbose('Tab parameters found', nextPathArray);
  15501. }
  15502. }
  15503. if(isLastTab && remoteContent) {
  15504. if(!shouldIgnoreLoad) {
  15505. module.activate.navigation(currentPath);
  15506. module.fetch.content(currentPath, tabPath);
  15507. }
  15508. else {
  15509. module.debug('Ignoring remote content on first tab load', currentPath);
  15510. firstLoad = false;
  15511. module.cache.add(tabPath, $tab.html());
  15512. module.activate.all(currentPath);
  15513. settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
  15514. settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
  15515. }
  15516. return false;
  15517. }
  15518. else {
  15519. module.debug('Opened local tab', currentPath);
  15520. module.activate.all(currentPath);
  15521. if( !module.cache.read(currentPath) ) {
  15522. module.cache.add(currentPath, true);
  15523. module.debug('First time tab loaded calling tab init');
  15524. settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
  15525. }
  15526. settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
  15527. }
  15528. }
  15529. else if(tabPath.search('/') == -1 && tabPath !== '') {
  15530. // look for in page anchor
  15531. $anchor = $('#' + tabPath + ', a[name="' + tabPath + '"]');
  15532. currentPath = $anchor.closest('[data-tab]').data(metadata.tab);
  15533. $tab = module.get.tabElement(currentPath);
  15534. // if anchor exists use parent tab
  15535. if($anchor && $anchor.length > 0 && currentPath) {
  15536. module.debug('Anchor link used, opening parent tab', $tab, $anchor);
  15537. if( !$tab.hasClass(className.active) ) {
  15538. setTimeout(function() {
  15539. module.scrollTo($anchor);
  15540. }, 0);
  15541. }
  15542. module.activate.all(currentPath);
  15543. if( !module.cache.read(currentPath) ) {
  15544. module.cache.add(currentPath, true);
  15545. module.debug('First time tab loaded calling tab init');
  15546. settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
  15547. }
  15548. settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
  15549. return false;
  15550. }
  15551. }
  15552. else {
  15553. module.error(error.missingTab, $module, $context, currentPath);
  15554. return false;
  15555. }
  15556. });
  15557. },
  15558. scrollTo: function($element) {
  15559. var
  15560. scrollOffset = ($element && $element.length > 0)
  15561. ? $element.offset().top
  15562. : false
  15563. ;
  15564. if(scrollOffset !== false) {
  15565. module.debug('Forcing scroll to an in-page link in a hidden tab', scrollOffset, $element);
  15566. $(document).scrollTop(scrollOffset);
  15567. }
  15568. },
  15569. update: {
  15570. content: function(tabPath, html, evaluateScripts) {
  15571. var
  15572. $tab = module.get.tabElement(tabPath),
  15573. tab = $tab[0]
  15574. ;
  15575. evaluateScripts = (evaluateScripts !== undefined)
  15576. ? evaluateScripts
  15577. : settings.evaluateScripts
  15578. ;
  15579. if(evaluateScripts) {
  15580. module.debug('Updating HTML and evaluating inline scripts', tabPath, html);
  15581. $tab.html(html);
  15582. }
  15583. else {
  15584. module.debug('Updating HTML', tabPath, html);
  15585. tab.innerHTML = html;
  15586. }
  15587. }
  15588. },
  15589. fetch: {
  15590. content: function(tabPath, fullTabPath) {
  15591. var
  15592. $tab = module.get.tabElement(tabPath),
  15593. apiSettings = {
  15594. dataType : 'html',
  15595. encodeParameters : false,
  15596. on : 'now',
  15597. cache : settings.alwaysRefresh,
  15598. headers : {
  15599. 'X-Remote': true
  15600. },
  15601. onSuccess : function(response) {
  15602. module.cache.add(fullTabPath, response);
  15603. module.update.content(tabPath, response);
  15604. if(tabPath == activeTabPath) {
  15605. module.debug('Content loaded', tabPath);
  15606. module.activate.tab(tabPath);
  15607. }
  15608. else {
  15609. module.debug('Content loaded in background', tabPath);
  15610. }
  15611. settings.onFirstLoad.call($tab[0], tabPath, parameterArray, historyEvent);
  15612. settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent);
  15613. },
  15614. urlData: {
  15615. tab: fullTabPath
  15616. }
  15617. },
  15618. request = $tab.api('get request') || false,
  15619. existingRequest = ( request && request.state() === 'pending' ),
  15620. requestSettings,
  15621. cachedContent
  15622. ;
  15623. fullTabPath = fullTabPath || tabPath;
  15624. cachedContent = module.cache.read(fullTabPath);
  15625. if(settings.cache && cachedContent) {
  15626. module.activate.tab(tabPath);
  15627. module.debug('Adding cached content', fullTabPath);
  15628. if(settings.evaluateScripts == 'once') {
  15629. module.update.content(tabPath, cachedContent, false);
  15630. }
  15631. else {
  15632. module.update.content(tabPath, cachedContent);
  15633. }
  15634. settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent);
  15635. }
  15636. else if(existingRequest) {
  15637. module.set.loading(tabPath);
  15638. module.debug('Content is already loading', fullTabPath);
  15639. }
  15640. else if($.api !== undefined) {
  15641. requestSettings = $.extend(true, {}, settings.apiSettings, apiSettings);
  15642. module.debug('Retrieving remote content', fullTabPath, requestSettings);
  15643. module.set.loading(tabPath);
  15644. $tab.api(requestSettings);
  15645. }
  15646. else {
  15647. module.error(error.api);
  15648. }
  15649. }
  15650. },
  15651. activate: {
  15652. all: function(tabPath) {
  15653. module.activate.tab(tabPath);
  15654. module.activate.navigation(tabPath);
  15655. },
  15656. tab: function(tabPath) {
  15657. var
  15658. $tab = module.get.tabElement(tabPath),
  15659. isActive = $tab.hasClass(className.active)
  15660. ;
  15661. module.verbose('Showing tab content for', $tab);
  15662. if(!isActive) {
  15663. $tab
  15664. .addClass(className.active)
  15665. .siblings($tabs)
  15666. .removeClass(className.active + ' ' + className.loading)
  15667. ;
  15668. if($tab.length > 0) {
  15669. settings.onVisible.call($tab[0], tabPath);
  15670. }
  15671. }
  15672. },
  15673. navigation: function(tabPath) {
  15674. var
  15675. $navigation = module.get.navElement(tabPath),
  15676. isActive = $navigation.hasClass(className.active)
  15677. ;
  15678. module.verbose('Activating tab navigation for', $navigation, tabPath);
  15679. if(!isActive) {
  15680. $navigation
  15681. .addClass(className.active)
  15682. .siblings($allModules)
  15683. .removeClass(className.active + ' ' + className.loading)
  15684. ;
  15685. }
  15686. }
  15687. },
  15688. deactivate: {
  15689. all: function() {
  15690. module.deactivate.navigation();
  15691. module.deactivate.tabs();
  15692. },
  15693. navigation: function() {
  15694. $allModules
  15695. .removeClass(className.active)
  15696. ;
  15697. },
  15698. tabs: function() {
  15699. $tabs
  15700. .removeClass(className.active + ' ' + className.loading)
  15701. ;
  15702. }
  15703. },
  15704. is: {
  15705. tab: function(tabName) {
  15706. return (tabName !== undefined)
  15707. ? ( module.get.tabElement(tabName).length > 0 )
  15708. : false
  15709. ;
  15710. }
  15711. },
  15712. get: {
  15713. initialPath: function() {
  15714. return $allModules.eq(0).data(metadata.tab) || $tabs.eq(0).data(metadata.tab);
  15715. },
  15716. path: function() {
  15717. return $.address.value();
  15718. },
  15719. // adds default tabs to tab path
  15720. defaultPathArray: function(tabPath) {
  15721. return module.utilities.pathToArray( module.get.defaultPath(tabPath) );
  15722. },
  15723. defaultPath: function(tabPath) {
  15724. var
  15725. $defaultNav = $allModules.filter('[data-' + metadata.tab + '^="' + tabPath + '/"]').eq(0),
  15726. defaultTab = $defaultNav.data(metadata.tab) || false
  15727. ;
  15728. if( defaultTab ) {
  15729. module.debug('Found default tab', defaultTab);
  15730. if(recursionDepth < settings.maxDepth) {
  15731. recursionDepth++;
  15732. return module.get.defaultPath(defaultTab);
  15733. }
  15734. module.error(error.recursion);
  15735. }
  15736. else {
  15737. module.debug('No default tabs found for', tabPath, $tabs);
  15738. }
  15739. recursionDepth = 0;
  15740. return tabPath;
  15741. },
  15742. navElement: function(tabPath) {
  15743. tabPath = tabPath || activeTabPath;
  15744. return $allModules.filter('[data-' + metadata.tab + '="' + tabPath + '"]');
  15745. },
  15746. tabElement: function(tabPath) {
  15747. var
  15748. $fullPathTab,
  15749. $simplePathTab,
  15750. tabPathArray,
  15751. lastTab
  15752. ;
  15753. tabPath = tabPath || activeTabPath;
  15754. tabPathArray = module.utilities.pathToArray(tabPath);
  15755. lastTab = module.utilities.last(tabPathArray);
  15756. $fullPathTab = $tabs.filter('[data-' + metadata.tab + '="' + tabPath + '"]');
  15757. $simplePathTab = $tabs.filter('[data-' + metadata.tab + '="' + lastTab + '"]');
  15758. return ($fullPathTab.length > 0)
  15759. ? $fullPathTab
  15760. : $simplePathTab
  15761. ;
  15762. },
  15763. tab: function() {
  15764. return activeTabPath;
  15765. }
  15766. },
  15767. utilities: {
  15768. filterArray: function(keepArray, removeArray) {
  15769. return $.grep(keepArray, function(keepValue) {
  15770. return ( $.inArray(keepValue, removeArray) == -1);
  15771. });
  15772. },
  15773. last: function(array) {
  15774. return $.isArray(array)
  15775. ? array[ array.length - 1]
  15776. : false
  15777. ;
  15778. },
  15779. pathToArray: function(pathName) {
  15780. if(pathName === undefined) {
  15781. pathName = activeTabPath;
  15782. }
  15783. return typeof pathName == 'string'
  15784. ? pathName.split('/')
  15785. : [pathName]
  15786. ;
  15787. },
  15788. arrayToPath: function(pathArray) {
  15789. return $.isArray(pathArray)
  15790. ? pathArray.join('/')
  15791. : false
  15792. ;
  15793. }
  15794. },
  15795. setting: function(name, value) {
  15796. module.debug('Changing setting', name, value);
  15797. if( $.isPlainObject(name) ) {
  15798. $.extend(true, settings, name);
  15799. }
  15800. else if(value !== undefined) {
  15801. settings[name] = value;
  15802. }
  15803. else {
  15804. return settings[name];
  15805. }
  15806. },
  15807. internal: function(name, value) {
  15808. if( $.isPlainObject(name) ) {
  15809. $.extend(true, module, name);
  15810. }
  15811. else if(value !== undefined) {
  15812. module[name] = value;
  15813. }
  15814. else {
  15815. return module[name];
  15816. }
  15817. },
  15818. debug: function() {
  15819. if(settings.debug) {
  15820. if(settings.performance) {
  15821. module.performance.log(arguments);
  15822. }
  15823. else {
  15824. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  15825. module.debug.apply(console, arguments);
  15826. }
  15827. }
  15828. },
  15829. verbose: function() {
  15830. if(settings.verbose && settings.debug) {
  15831. if(settings.performance) {
  15832. module.performance.log(arguments);
  15833. }
  15834. else {
  15835. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  15836. module.verbose.apply(console, arguments);
  15837. }
  15838. }
  15839. },
  15840. error: function() {
  15841. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  15842. module.error.apply(console, arguments);
  15843. },
  15844. performance: {
  15845. log: function(message) {
  15846. var
  15847. currentTime,
  15848. executionTime,
  15849. previousTime
  15850. ;
  15851. if(settings.performance) {
  15852. currentTime = new Date().getTime();
  15853. previousTime = time || currentTime;
  15854. executionTime = currentTime - previousTime;
  15855. time = currentTime;
  15856. performance.push({
  15857. 'Name' : message[0],
  15858. 'Arguments' : [].slice.call(message, 1) || '',
  15859. 'Element' : element,
  15860. 'Execution Time' : executionTime
  15861. });
  15862. }
  15863. clearTimeout(module.performance.timer);
  15864. module.performance.timer = setTimeout(module.performance.display, 500);
  15865. },
  15866. display: function() {
  15867. var
  15868. title = settings.name + ':',
  15869. totalTime = 0
  15870. ;
  15871. time = false;
  15872. clearTimeout(module.performance.timer);
  15873. $.each(performance, function(index, data) {
  15874. totalTime += data['Execution Time'];
  15875. });
  15876. title += ' ' + totalTime + 'ms';
  15877. if(moduleSelector) {
  15878. title += ' \'' + moduleSelector + '\'';
  15879. }
  15880. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  15881. console.groupCollapsed(title);
  15882. if(console.table) {
  15883. console.table(performance);
  15884. }
  15885. else {
  15886. $.each(performance, function(index, data) {
  15887. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  15888. });
  15889. }
  15890. console.groupEnd();
  15891. }
  15892. performance = [];
  15893. }
  15894. },
  15895. invoke: function(query, passedArguments, context) {
  15896. var
  15897. object = instance,
  15898. maxDepth,
  15899. found,
  15900. response
  15901. ;
  15902. passedArguments = passedArguments || queryArguments;
  15903. context = element || context;
  15904. if(typeof query == 'string' && object !== undefined) {
  15905. query = query.split(/[\. ]/);
  15906. maxDepth = query.length - 1;
  15907. $.each(query, function(depth, value) {
  15908. var camelCaseValue = (depth != maxDepth)
  15909. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  15910. : query
  15911. ;
  15912. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  15913. object = object[camelCaseValue];
  15914. }
  15915. else if( object[camelCaseValue] !== undefined ) {
  15916. found = object[camelCaseValue];
  15917. return false;
  15918. }
  15919. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  15920. object = object[value];
  15921. }
  15922. else if( object[value] !== undefined ) {
  15923. found = object[value];
  15924. return false;
  15925. }
  15926. else {
  15927. module.error(error.method, query);
  15928. return false;
  15929. }
  15930. });
  15931. }
  15932. if ( $.isFunction( found ) ) {
  15933. response = found.apply(context, passedArguments);
  15934. }
  15935. else if(found !== undefined) {
  15936. response = found;
  15937. }
  15938. if($.isArray(returnedValue)) {
  15939. returnedValue.push(response);
  15940. }
  15941. else if(returnedValue !== undefined) {
  15942. returnedValue = [returnedValue, response];
  15943. }
  15944. else if(response !== undefined) {
  15945. returnedValue = response;
  15946. }
  15947. return found;
  15948. }
  15949. };
  15950. if(methodInvoked) {
  15951. if(instance === undefined) {
  15952. module.initialize();
  15953. }
  15954. module.invoke(query);
  15955. }
  15956. else {
  15957. if(instance !== undefined) {
  15958. instance.invoke('destroy');
  15959. }
  15960. module.initialize();
  15961. }
  15962. })
  15963. ;
  15964. return (returnedValue !== undefined)
  15965. ? returnedValue
  15966. : this
  15967. ;
  15968. };
  15969. // shortcut for tabbed content with no defined navigation
  15970. $.tab = function() {
  15971. $(window).tab.apply(this, arguments);
  15972. };
  15973. $.fn.tab.settings = {
  15974. name : 'Tab',
  15975. namespace : 'tab',
  15976. debug : false,
  15977. verbose : false,
  15978. performance : true,
  15979. auto : false, // uses pjax style endpoints fetching content from same url with remote-content headers
  15980. history : false, // use browser history
  15981. historyType : 'hash', // #/ or html5 state
  15982. path : false, // base path of url
  15983. context : false, // specify a context that tabs must appear inside
  15984. childrenOnly : false, // use only tabs that are children of context
  15985. maxDepth : 25, // max depth a tab can be nested
  15986. alwaysRefresh : false, // load tab content new every tab click
  15987. cache : true, // cache the content requests to pull locally
  15988. ignoreFirstLoad : false, // don't load remote content on first load
  15989. apiSettings : false, // settings for api call
  15990. evaluateScripts : 'once', // whether inline scripts should be parsed (true/false/once). Once will not re-evaluate on cached content
  15991. onFirstLoad : function(tabPath, parameterArray, historyEvent) {}, // called first time loaded
  15992. onLoad : function(tabPath, parameterArray, historyEvent) {}, // called on every load
  15993. onVisible : function(tabPath, parameterArray, historyEvent) {}, // called every time tab visible
  15994. onRequest : function(tabPath, parameterArray, historyEvent) {}, // called ever time a tab beings loading remote content
  15995. templates : {
  15996. determineTitle: function(tabArray) {} // returns page title for path
  15997. },
  15998. error: {
  15999. api : 'You attempted to load content without API module',
  16000. method : 'The method you called is not defined',
  16001. missingTab : 'Activated tab cannot be found. Tabs are case-sensitive.',
  16002. noContent : 'The tab you specified is missing a content url.',
  16003. path : 'History enabled, but no path was specified',
  16004. recursion : 'Max recursive depth reached',
  16005. legacyInit : 'onTabInit has been renamed to onFirstLoad in 2.0, please adjust your code.',
  16006. legacyLoad : 'onTabLoad has been renamed to onLoad in 2.0. Please adjust your code',
  16007. state : 'History requires Asual\'s Address library <https://github.com/asual/jquery-address>'
  16008. },
  16009. metadata : {
  16010. tab : 'tab',
  16011. loaded : 'loaded',
  16012. promise: 'promise'
  16013. },
  16014. className : {
  16015. loading : 'loading',
  16016. active : 'active'
  16017. },
  16018. selector : {
  16019. tabs : '.ui.tab',
  16020. ui : '.ui'
  16021. }
  16022. };
  16023. })( jQuery, window , document );
  16024. /*!
  16025. * # Semantic UI 2.1.4 - Transition
  16026. * http://github.com/semantic-org/semantic-ui/
  16027. *
  16028. *
  16029. * Copyright 2015 Contributors
  16030. * Released under the MIT license
  16031. * http://opensource.org/licenses/MIT
  16032. *
  16033. */
  16034. ;(function ( $, window, document, undefined ) {
  16035. "use strict";
  16036. $.fn.transition = function() {
  16037. var
  16038. $allModules = $(this),
  16039. moduleSelector = $allModules.selector || '',
  16040. time = new Date().getTime(),
  16041. performance = [],
  16042. moduleArguments = arguments,
  16043. query = moduleArguments[0],
  16044. queryArguments = [].slice.call(arguments, 1),
  16045. methodInvoked = (typeof query === 'string'),
  16046. requestAnimationFrame = window.requestAnimationFrame
  16047. || window.mozRequestAnimationFrame
  16048. || window.webkitRequestAnimationFrame
  16049. || window.msRequestAnimationFrame
  16050. || function(callback) { setTimeout(callback, 0); },
  16051. returnedValue
  16052. ;
  16053. $allModules
  16054. .each(function(index) {
  16055. var
  16056. $module = $(this),
  16057. element = this,
  16058. // set at run time
  16059. settings,
  16060. instance,
  16061. error,
  16062. className,
  16063. metadata,
  16064. animationEnd,
  16065. animationName,
  16066. namespace,
  16067. moduleNamespace,
  16068. eventNamespace,
  16069. module
  16070. ;
  16071. module = {
  16072. initialize: function() {
  16073. // get full settings
  16074. settings = module.get.settings.apply(element, moduleArguments);
  16075. // shorthand
  16076. className = settings.className;
  16077. error = settings.error;
  16078. metadata = settings.metadata;
  16079. // define namespace
  16080. eventNamespace = '.' + settings.namespace;
  16081. moduleNamespace = 'module-' + settings.namespace;
  16082. instance = $module.data(moduleNamespace) || module;
  16083. // get vendor specific events
  16084. animationEnd = module.get.animationEndEvent();
  16085. if(methodInvoked) {
  16086. methodInvoked = module.invoke(query);
  16087. }
  16088. // method not invoked, lets run an animation
  16089. if(methodInvoked === false) {
  16090. module.verbose('Converted arguments into settings object', settings);
  16091. if(settings.interval) {
  16092. module.delay(settings.animate);
  16093. }
  16094. else {
  16095. module.animate();
  16096. }
  16097. module.instantiate();
  16098. }
  16099. },
  16100. instantiate: function() {
  16101. module.verbose('Storing instance of module', module);
  16102. instance = module;
  16103. $module
  16104. .data(moduleNamespace, instance)
  16105. ;
  16106. },
  16107. destroy: function() {
  16108. module.verbose('Destroying previous module for', element);
  16109. $module
  16110. .removeData(moduleNamespace)
  16111. ;
  16112. },
  16113. refresh: function() {
  16114. module.verbose('Refreshing display type on next animation');
  16115. delete module.displayType;
  16116. },
  16117. forceRepaint: function() {
  16118. module.verbose('Forcing element repaint');
  16119. var
  16120. $parentElement = $module.parent(),
  16121. $nextElement = $module.next()
  16122. ;
  16123. if($nextElement.length === 0) {
  16124. $module.detach().appendTo($parentElement);
  16125. }
  16126. else {
  16127. $module.detach().insertBefore($nextElement);
  16128. }
  16129. },
  16130. repaint: function() {
  16131. module.verbose('Repainting element');
  16132. var
  16133. fakeAssignment = element.offsetWidth
  16134. ;
  16135. },
  16136. delay: function(interval) {
  16137. var
  16138. direction = module.get.animationDirection(),
  16139. shouldReverse,
  16140. delay
  16141. ;
  16142. if(!direction) {
  16143. direction = module.can.transition()
  16144. ? module.get.direction()
  16145. : 'static'
  16146. ;
  16147. }
  16148. interval = (interval !== undefined)
  16149. ? interval
  16150. : settings.interval
  16151. ;
  16152. shouldReverse = (settings.reverse == 'auto' && direction == className.outward);
  16153. delay = (shouldReverse || settings.reverse == true)
  16154. ? ($allModules.length - index) * settings.interval
  16155. : index * settings.interval
  16156. ;
  16157. module.debug('Delaying animation by', delay);
  16158. setTimeout(module.animate, delay);
  16159. },
  16160. animate: function(overrideSettings) {
  16161. settings = overrideSettings || settings;
  16162. if(!module.is.supported()) {
  16163. module.error(error.support);
  16164. return false;
  16165. }
  16166. module.debug('Preparing animation', settings.animation);
  16167. if(module.is.animating()) {
  16168. if(settings.queue) {
  16169. if(!settings.allowRepeats && module.has.direction() && module.is.occurring() && module.queuing !== true) {
  16170. module.debug('Animation is currently occurring, preventing queueing same animation', settings.animation);
  16171. }
  16172. else {
  16173. module.queue(settings.animation);
  16174. }
  16175. return false;
  16176. }
  16177. else if(!settings.allowRepeats && module.is.occurring()) {
  16178. module.debug('Animation is already occurring, will not execute repeated animation', settings.animation);
  16179. return false;
  16180. }
  16181. else {
  16182. module.debug('New animation started, completing previous early', settings.animation);
  16183. instance.complete();
  16184. }
  16185. }
  16186. if( module.can.animate() ) {
  16187. module.set.animating(settings.animation);
  16188. }
  16189. else {
  16190. module.error(error.noAnimation, settings.animation, element);
  16191. }
  16192. },
  16193. reset: function() {
  16194. module.debug('Resetting animation to beginning conditions');
  16195. module.remove.animationCallbacks();
  16196. module.restore.conditions();
  16197. module.remove.animating();
  16198. },
  16199. queue: function(animation) {
  16200. module.debug('Queueing animation of', animation);
  16201. module.queuing = true;
  16202. $module
  16203. .one(animationEnd + '.queue' + eventNamespace, function() {
  16204. module.queuing = false;
  16205. module.repaint();
  16206. module.animate.apply(this, settings);
  16207. })
  16208. ;
  16209. },
  16210. complete: function (event) {
  16211. module.debug('Animation complete', settings.animation);
  16212. module.remove.completeCallback();
  16213. module.remove.failSafe();
  16214. if(!module.is.looping()) {
  16215. if( module.is.outward() ) {
  16216. module.verbose('Animation is outward, hiding element');
  16217. module.restore.conditions();
  16218. module.hide();
  16219. }
  16220. else if( module.is.inward() ) {
  16221. module.verbose('Animation is outward, showing element');
  16222. module.restore.conditions();
  16223. module.show();
  16224. }
  16225. else {
  16226. module.restore.conditions();
  16227. }
  16228. }
  16229. },
  16230. force: {
  16231. visible: function() {
  16232. var
  16233. style = $module.attr('style'),
  16234. userStyle = module.get.userStyle(),
  16235. displayType = module.get.displayType(),
  16236. overrideStyle = userStyle + 'display: ' + displayType + ' !important;',
  16237. currentDisplay = $module.css('display'),
  16238. emptyStyle = (style === undefined || style === '')
  16239. ;
  16240. if(currentDisplay !== displayType) {
  16241. module.verbose('Overriding default display to show element', displayType);
  16242. $module
  16243. .attr('style', overrideStyle)
  16244. ;
  16245. }
  16246. else if(emptyStyle) {
  16247. $module.removeAttr('style');
  16248. }
  16249. },
  16250. hidden: function() {
  16251. var
  16252. style = $module.attr('style'),
  16253. currentDisplay = $module.css('display'),
  16254. emptyStyle = (style === undefined || style === '')
  16255. ;
  16256. if(currentDisplay !== 'none' && !module.is.hidden()) {
  16257. module.verbose('Overriding default display to hide element');
  16258. $module
  16259. .css('display', 'none')
  16260. ;
  16261. }
  16262. else if(emptyStyle) {
  16263. $module
  16264. .removeAttr('style')
  16265. ;
  16266. }
  16267. }
  16268. },
  16269. has: {
  16270. direction: function(animation) {
  16271. var
  16272. hasDirection = false
  16273. ;
  16274. animation = animation || settings.animation;
  16275. if(typeof animation === 'string') {
  16276. animation = animation.split(' ');
  16277. $.each(animation, function(index, word){
  16278. if(word === className.inward || word === className.outward) {
  16279. hasDirection = true;
  16280. }
  16281. });
  16282. }
  16283. return hasDirection;
  16284. },
  16285. inlineDisplay: function() {
  16286. var
  16287. style = $module.attr('style') || ''
  16288. ;
  16289. return $.isArray(style.match(/display.*?;/, ''));
  16290. }
  16291. },
  16292. set: {
  16293. animating: function(animation) {
  16294. var
  16295. animationClass,
  16296. direction
  16297. ;
  16298. // remove previous callbacks
  16299. module.remove.completeCallback();
  16300. // determine exact animation
  16301. animation = animation || settings.animation;
  16302. animationClass = module.get.animationClass(animation);
  16303. // save animation class in cache to restore class names
  16304. module.save.animation(animationClass);
  16305. // override display if necessary so animation appears visibly
  16306. module.force.visible();
  16307. module.remove.hidden();
  16308. module.remove.direction();
  16309. module.start.animation(animationClass);
  16310. },
  16311. duration: function(animationName, duration) {
  16312. duration = duration || settings.duration;
  16313. duration = (typeof duration == 'number')
  16314. ? duration + 'ms'
  16315. : duration
  16316. ;
  16317. if(duration || duration === 0) {
  16318. module.verbose('Setting animation duration', duration);
  16319. $module
  16320. .css({
  16321. 'animation-duration': duration
  16322. })
  16323. ;
  16324. }
  16325. },
  16326. direction: function(direction) {
  16327. direction = direction || module.get.direction();
  16328. if(direction == className.inward) {
  16329. module.set.inward();
  16330. }
  16331. else {
  16332. module.set.outward();
  16333. }
  16334. },
  16335. looping: function() {
  16336. module.debug('Transition set to loop');
  16337. $module
  16338. .addClass(className.looping)
  16339. ;
  16340. },
  16341. hidden: function() {
  16342. $module
  16343. .addClass(className.transition)
  16344. .addClass(className.hidden)
  16345. ;
  16346. },
  16347. inward: function() {
  16348. module.debug('Setting direction to inward');
  16349. $module
  16350. .removeClass(className.outward)
  16351. .addClass(className.inward)
  16352. ;
  16353. },
  16354. outward: function() {
  16355. module.debug('Setting direction to outward');
  16356. $module
  16357. .removeClass(className.inward)
  16358. .addClass(className.outward)
  16359. ;
  16360. },
  16361. visible: function() {
  16362. $module
  16363. .addClass(className.transition)
  16364. .addClass(className.visible)
  16365. ;
  16366. }
  16367. },
  16368. start: {
  16369. animation: function(animationClass) {
  16370. animationClass = animationClass || module.get.animationClass();
  16371. module.debug('Starting tween', animationClass);
  16372. $module
  16373. .addClass(animationClass)
  16374. .one(animationEnd + '.complete' + eventNamespace, module.complete)
  16375. ;
  16376. if(settings.useFailSafe) {
  16377. module.add.failSafe();
  16378. }
  16379. module.set.duration(settings.duration);
  16380. settings.onStart.call(element);
  16381. }
  16382. },
  16383. save: {
  16384. animation: function(animation) {
  16385. if(!module.cache) {
  16386. module.cache = {};
  16387. }
  16388. module.cache.animation = animation;
  16389. },
  16390. displayType: function(displayType) {
  16391. if(displayType !== 'none') {
  16392. $module.data(metadata.displayType, displayType);
  16393. }
  16394. },
  16395. transitionExists: function(animation, exists) {
  16396. $.fn.transition.exists[animation] = exists;
  16397. module.verbose('Saving existence of transition', animation, exists);
  16398. }
  16399. },
  16400. restore: {
  16401. conditions: function() {
  16402. var
  16403. animation = module.get.currentAnimation()
  16404. ;
  16405. if(animation) {
  16406. $module
  16407. .removeClass(animation)
  16408. ;
  16409. module.verbose('Removing animation class', module.cache);
  16410. }
  16411. module.remove.duration();
  16412. }
  16413. },
  16414. add: {
  16415. failSafe: function() {
  16416. var
  16417. duration = module.get.duration()
  16418. ;
  16419. module.timer = setTimeout(function() {
  16420. $module.triggerHandler(animationEnd);
  16421. }, duration + settings.failSafeDelay);
  16422. module.verbose('Adding fail safe timer', module.timer);
  16423. }
  16424. },
  16425. remove: {
  16426. animating: function() {
  16427. $module.removeClass(className.animating);
  16428. },
  16429. animationCallbacks: function() {
  16430. module.remove.queueCallback();
  16431. module.remove.completeCallback();
  16432. },
  16433. queueCallback: function() {
  16434. $module.off('.queue' + eventNamespace);
  16435. },
  16436. completeCallback: function() {
  16437. $module.off('.complete' + eventNamespace);
  16438. },
  16439. display: function() {
  16440. $module.css('display', '');
  16441. },
  16442. direction: function() {
  16443. $module
  16444. .removeClass(className.inward)
  16445. .removeClass(className.outward)
  16446. ;
  16447. },
  16448. duration: function() {
  16449. $module
  16450. .css('animation-duration', '')
  16451. ;
  16452. },
  16453. failSafe: function() {
  16454. module.verbose('Removing fail safe timer', module.timer);
  16455. if(module.timer) {
  16456. clearTimeout(module.timer);
  16457. }
  16458. },
  16459. hidden: function() {
  16460. $module.removeClass(className.hidden);
  16461. },
  16462. visible: function() {
  16463. $module.removeClass(className.visible);
  16464. },
  16465. looping: function() {
  16466. module.debug('Transitions are no longer looping');
  16467. if( module.is.looping() ) {
  16468. module.reset();
  16469. $module
  16470. .removeClass(className.looping)
  16471. ;
  16472. }
  16473. },
  16474. transition: function() {
  16475. $module
  16476. .removeClass(className.visible)
  16477. .removeClass(className.hidden)
  16478. ;
  16479. }
  16480. },
  16481. get: {
  16482. settings: function(animation, duration, onComplete) {
  16483. // single settings object
  16484. if(typeof animation == 'object') {
  16485. return $.extend(true, {}, $.fn.transition.settings, animation);
  16486. }
  16487. // all arguments provided
  16488. else if(typeof onComplete == 'function') {
  16489. return $.extend({}, $.fn.transition.settings, {
  16490. animation : animation,
  16491. onComplete : onComplete,
  16492. duration : duration
  16493. });
  16494. }
  16495. // only duration provided
  16496. else if(typeof duration == 'string' || typeof duration == 'number') {
  16497. return $.extend({}, $.fn.transition.settings, {
  16498. animation : animation,
  16499. duration : duration
  16500. });
  16501. }
  16502. // duration is actually settings object
  16503. else if(typeof duration == 'object') {
  16504. return $.extend({}, $.fn.transition.settings, duration, {
  16505. animation : animation
  16506. });
  16507. }
  16508. // duration is actually callback
  16509. else if(typeof duration == 'function') {
  16510. return $.extend({}, $.fn.transition.settings, {
  16511. animation : animation,
  16512. onComplete : duration
  16513. });
  16514. }
  16515. // only animation provided
  16516. else {
  16517. return $.extend({}, $.fn.transition.settings, {
  16518. animation : animation
  16519. });
  16520. }
  16521. return $.fn.transition.settings;
  16522. },
  16523. animationClass: function(animation) {
  16524. var
  16525. animationClass = animation || settings.animation,
  16526. directionClass = (module.can.transition() && !module.has.direction())
  16527. ? module.get.direction() + ' '
  16528. : ''
  16529. ;
  16530. return className.animating + ' '
  16531. + className.transition + ' '
  16532. + directionClass
  16533. + animationClass
  16534. ;
  16535. },
  16536. currentAnimation: function() {
  16537. return (module.cache && module.cache.animation !== undefined)
  16538. ? module.cache.animation
  16539. : false
  16540. ;
  16541. },
  16542. currentDirection: function() {
  16543. return module.is.inward()
  16544. ? className.inward
  16545. : className.outward
  16546. ;
  16547. },
  16548. direction: function() {
  16549. return module.is.hidden() || !module.is.visible()
  16550. ? className.inward
  16551. : className.outward
  16552. ;
  16553. },
  16554. animationDirection: function(animation) {
  16555. var
  16556. direction
  16557. ;
  16558. animation = animation || settings.animation;
  16559. if(typeof animation === 'string') {
  16560. animation = animation.split(' ');
  16561. // search animation name for out/in class
  16562. $.each(animation, function(index, word){
  16563. if(word === className.inward) {
  16564. direction = className.inward;
  16565. }
  16566. else if(word === className.outward) {
  16567. direction = className.outward;
  16568. }
  16569. });
  16570. }
  16571. // return found direction
  16572. if(direction) {
  16573. return direction;
  16574. }
  16575. return false;
  16576. },
  16577. duration: function(duration) {
  16578. duration = duration || settings.duration;
  16579. if(duration === false) {
  16580. duration = $module.css('animation-duration') || 0;
  16581. }
  16582. return (typeof duration === 'string')
  16583. ? (duration.indexOf('ms') > -1)
  16584. ? parseFloat(duration)
  16585. : parseFloat(duration) * 1000
  16586. : duration
  16587. ;
  16588. },
  16589. displayType: function() {
  16590. if(settings.displayType) {
  16591. return settings.displayType;
  16592. }
  16593. if($module.data(metadata.displayType) === undefined) {
  16594. // create fake element to determine display state
  16595. module.can.transition(true);
  16596. }
  16597. return $module.data(metadata.displayType);
  16598. },
  16599. userStyle: function(style) {
  16600. style = style || $module.attr('style') || '';
  16601. return style.replace(/display.*?;/, '');
  16602. },
  16603. transitionExists: function(animation) {
  16604. return $.fn.transition.exists[animation];
  16605. },
  16606. animationStartEvent: function() {
  16607. var
  16608. element = document.createElement('div'),
  16609. animations = {
  16610. 'animation' :'animationstart',
  16611. 'OAnimation' :'oAnimationStart',
  16612. 'MozAnimation' :'mozAnimationStart',
  16613. 'WebkitAnimation' :'webkitAnimationStart'
  16614. },
  16615. animation
  16616. ;
  16617. for(animation in animations){
  16618. if( element.style[animation] !== undefined ){
  16619. return animations[animation];
  16620. }
  16621. }
  16622. return false;
  16623. },
  16624. animationEndEvent: function() {
  16625. var
  16626. element = document.createElement('div'),
  16627. animations = {
  16628. 'animation' :'animationend',
  16629. 'OAnimation' :'oAnimationEnd',
  16630. 'MozAnimation' :'mozAnimationEnd',
  16631. 'WebkitAnimation' :'webkitAnimationEnd'
  16632. },
  16633. animation
  16634. ;
  16635. for(animation in animations){
  16636. if( element.style[animation] !== undefined ){
  16637. return animations[animation];
  16638. }
  16639. }
  16640. return false;
  16641. }
  16642. },
  16643. can: {
  16644. transition: function(forced) {
  16645. var
  16646. animation = settings.animation,
  16647. transitionExists = module.get.transitionExists(animation),
  16648. elementClass,
  16649. tagName,
  16650. $clone,
  16651. currentAnimation,
  16652. inAnimation,
  16653. directionExists,
  16654. displayType
  16655. ;
  16656. if( transitionExists === undefined || forced) {
  16657. module.verbose('Determining whether animation exists');
  16658. elementClass = $module.attr('class');
  16659. tagName = $module.prop('tagName');
  16660. $clone = $('<' + tagName + ' />').addClass( elementClass ).insertAfter($module);
  16661. currentAnimation = $clone
  16662. .addClass(animation)
  16663. .removeClass(className.inward)
  16664. .removeClass(className.outward)
  16665. .addClass(className.animating)
  16666. .addClass(className.transition)
  16667. .css('animationName')
  16668. ;
  16669. inAnimation = $clone
  16670. .addClass(className.inward)
  16671. .css('animationName')
  16672. ;
  16673. displayType = $clone
  16674. .attr('class', elementClass)
  16675. .removeAttr('style')
  16676. .removeClass(className.hidden)
  16677. .removeClass(className.visible)
  16678. .show()
  16679. .css('display')
  16680. ;
  16681. module.verbose('Determining final display state', displayType);
  16682. module.save.displayType(displayType);
  16683. $clone.remove();
  16684. if(currentAnimation != inAnimation) {
  16685. module.debug('Direction exists for animation', animation);
  16686. directionExists = true;
  16687. }
  16688. else if(currentAnimation == 'none' || !currentAnimation) {
  16689. module.debug('No animation defined in css', animation);
  16690. return;
  16691. }
  16692. else {
  16693. module.debug('Static animation found', animation, displayType);
  16694. directionExists = false;
  16695. }
  16696. module.save.transitionExists(animation, directionExists);
  16697. }
  16698. return (transitionExists !== undefined)
  16699. ? transitionExists
  16700. : directionExists
  16701. ;
  16702. },
  16703. animate: function() {
  16704. // can transition does not return a value if animation does not exist
  16705. return (module.can.transition() !== undefined);
  16706. }
  16707. },
  16708. is: {
  16709. animating: function() {
  16710. return $module.hasClass(className.animating);
  16711. },
  16712. inward: function() {
  16713. return $module.hasClass(className.inward);
  16714. },
  16715. outward: function() {
  16716. return $module.hasClass(className.outward);
  16717. },
  16718. looping: function() {
  16719. return $module.hasClass(className.looping);
  16720. },
  16721. occurring: function(animation) {
  16722. animation = animation || settings.animation;
  16723. animation = '.' + animation.replace(' ', '.');
  16724. return ( $module.filter(animation).length > 0 );
  16725. },
  16726. visible: function() {
  16727. return $module.is(':visible');
  16728. },
  16729. hidden: function() {
  16730. return $module.css('visibility') === 'hidden';
  16731. },
  16732. supported: function() {
  16733. return(animationEnd !== false);
  16734. }
  16735. },
  16736. hide: function() {
  16737. module.verbose('Hiding element');
  16738. if( module.is.animating() ) {
  16739. module.reset();
  16740. }
  16741. element.blur(); // IE will trigger focus change if element is not blurred before hiding
  16742. module.remove.display();
  16743. module.remove.visible();
  16744. module.set.hidden();
  16745. module.force.hidden();
  16746. settings.onHide.call(element);
  16747. settings.onComplete.call(element);
  16748. // module.repaint();
  16749. },
  16750. show: function(display) {
  16751. module.verbose('Showing element', display);
  16752. module.remove.hidden();
  16753. module.set.visible();
  16754. module.force.visible();
  16755. settings.onShow.call(element);
  16756. settings.onComplete.call(element);
  16757. // module.repaint();
  16758. },
  16759. toggle: function() {
  16760. if( module.is.visible() ) {
  16761. module.hide();
  16762. }
  16763. else {
  16764. module.show();
  16765. }
  16766. },
  16767. stop: function() {
  16768. module.debug('Stopping current animation');
  16769. $module.triggerHandler(animationEnd);
  16770. },
  16771. stopAll: function() {
  16772. module.debug('Stopping all animation');
  16773. module.remove.queueCallback();
  16774. $module.triggerHandler(animationEnd);
  16775. },
  16776. clear: {
  16777. queue: function() {
  16778. module.debug('Clearing animation queue');
  16779. module.remove.queueCallback();
  16780. }
  16781. },
  16782. enable: function() {
  16783. module.verbose('Starting animation');
  16784. $module.removeClass(className.disabled);
  16785. },
  16786. disable: function() {
  16787. module.debug('Stopping animation');
  16788. $module.addClass(className.disabled);
  16789. },
  16790. setting: function(name, value) {
  16791. module.debug('Changing setting', name, value);
  16792. if( $.isPlainObject(name) ) {
  16793. $.extend(true, settings, name);
  16794. }
  16795. else if(value !== undefined) {
  16796. settings[name] = value;
  16797. }
  16798. else {
  16799. return settings[name];
  16800. }
  16801. },
  16802. internal: function(name, value) {
  16803. if( $.isPlainObject(name) ) {
  16804. $.extend(true, module, name);
  16805. }
  16806. else if(value !== undefined) {
  16807. module[name] = value;
  16808. }
  16809. else {
  16810. return module[name];
  16811. }
  16812. },
  16813. debug: function() {
  16814. if(settings.debug) {
  16815. if(settings.performance) {
  16816. module.performance.log(arguments);
  16817. }
  16818. else {
  16819. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  16820. module.debug.apply(console, arguments);
  16821. }
  16822. }
  16823. },
  16824. verbose: function() {
  16825. if(settings.verbose && settings.debug) {
  16826. if(settings.performance) {
  16827. module.performance.log(arguments);
  16828. }
  16829. else {
  16830. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  16831. module.verbose.apply(console, arguments);
  16832. }
  16833. }
  16834. },
  16835. error: function() {
  16836. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  16837. module.error.apply(console, arguments);
  16838. },
  16839. performance: {
  16840. log: function(message) {
  16841. var
  16842. currentTime,
  16843. executionTime,
  16844. previousTime
  16845. ;
  16846. if(settings.performance) {
  16847. currentTime = new Date().getTime();
  16848. previousTime = time || currentTime;
  16849. executionTime = currentTime - previousTime;
  16850. time = currentTime;
  16851. performance.push({
  16852. 'Name' : message[0],
  16853. 'Arguments' : [].slice.call(message, 1) || '',
  16854. 'Element' : element,
  16855. 'Execution Time' : executionTime
  16856. });
  16857. }
  16858. clearTimeout(module.performance.timer);
  16859. module.performance.timer = setTimeout(module.performance.display, 500);
  16860. },
  16861. display: function() {
  16862. var
  16863. title = settings.name + ':',
  16864. totalTime = 0
  16865. ;
  16866. time = false;
  16867. clearTimeout(module.performance.timer);
  16868. $.each(performance, function(index, data) {
  16869. totalTime += data['Execution Time'];
  16870. });
  16871. title += ' ' + totalTime + 'ms';
  16872. if(moduleSelector) {
  16873. title += ' \'' + moduleSelector + '\'';
  16874. }
  16875. if($allModules.length > 1) {
  16876. title += ' ' + '(' + $allModules.length + ')';
  16877. }
  16878. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  16879. console.groupCollapsed(title);
  16880. if(console.table) {
  16881. console.table(performance);
  16882. }
  16883. else {
  16884. $.each(performance, function(index, data) {
  16885. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  16886. });
  16887. }
  16888. console.groupEnd();
  16889. }
  16890. performance = [];
  16891. }
  16892. },
  16893. // modified for transition to return invoke success
  16894. invoke: function(query, passedArguments, context) {
  16895. var
  16896. object = instance,
  16897. maxDepth,
  16898. found,
  16899. response
  16900. ;
  16901. passedArguments = passedArguments || queryArguments;
  16902. context = element || context;
  16903. if(typeof query == 'string' && object !== undefined) {
  16904. query = query.split(/[\. ]/);
  16905. maxDepth = query.length - 1;
  16906. $.each(query, function(depth, value) {
  16907. var camelCaseValue = (depth != maxDepth)
  16908. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  16909. : query
  16910. ;
  16911. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  16912. object = object[camelCaseValue];
  16913. }
  16914. else if( object[camelCaseValue] !== undefined ) {
  16915. found = object[camelCaseValue];
  16916. return false;
  16917. }
  16918. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  16919. object = object[value];
  16920. }
  16921. else if( object[value] !== undefined ) {
  16922. found = object[value];
  16923. return false;
  16924. }
  16925. else {
  16926. return false;
  16927. }
  16928. });
  16929. }
  16930. if ( $.isFunction( found ) ) {
  16931. response = found.apply(context, passedArguments);
  16932. }
  16933. else if(found !== undefined) {
  16934. response = found;
  16935. }
  16936. if($.isArray(returnedValue)) {
  16937. returnedValue.push(response);
  16938. }
  16939. else if(returnedValue !== undefined) {
  16940. returnedValue = [returnedValue, response];
  16941. }
  16942. else if(response !== undefined) {
  16943. returnedValue = response;
  16944. }
  16945. return (found !== undefined)
  16946. ? found
  16947. : false
  16948. ;
  16949. }
  16950. };
  16951. module.initialize();
  16952. })
  16953. ;
  16954. return (returnedValue !== undefined)
  16955. ? returnedValue
  16956. : this
  16957. ;
  16958. };
  16959. // Records if CSS transition is available
  16960. $.fn.transition.exists = {};
  16961. $.fn.transition.settings = {
  16962. // module info
  16963. name : 'Transition',
  16964. // debug content outputted to console
  16965. debug : false,
  16966. // verbose debug output
  16967. verbose : false,
  16968. // performance data output
  16969. performance : true,
  16970. // event namespace
  16971. namespace : 'transition',
  16972. // delay between animations in group
  16973. interval : 0,
  16974. // whether group animations should be reversed
  16975. reverse : 'auto',
  16976. // animation callback event
  16977. onStart : function() {},
  16978. onComplete : function() {},
  16979. onShow : function() {},
  16980. onHide : function() {},
  16981. // whether timeout should be used to ensure callback fires in cases animationend does not
  16982. useFailSafe : true,
  16983. // delay in ms for fail safe
  16984. failSafeDelay : 100,
  16985. // whether EXACT animation can occur twice in a row
  16986. allowRepeats : false,
  16987. // Override final display type on visible
  16988. displayType : false,
  16989. // animation duration
  16990. animation : 'fade',
  16991. duration : false,
  16992. // new animations will occur after previous ones
  16993. queue : true,
  16994. metadata : {
  16995. displayType: 'display'
  16996. },
  16997. className : {
  16998. animating : 'animating',
  16999. disabled : 'disabled',
  17000. hidden : 'hidden',
  17001. inward : 'in',
  17002. loading : 'loading',
  17003. looping : 'looping',
  17004. outward : 'out',
  17005. transition : 'transition',
  17006. visible : 'visible'
  17007. },
  17008. // possible errors
  17009. error: {
  17010. noAnimation : 'There is no css animation matching the one you specified. Please make sure your css is vendor prefixed, and you have included transition css.',
  17011. repeated : 'That animation is already occurring, cancelling repeated animation',
  17012. method : 'The method you called is not defined',
  17013. support : 'This browser does not support CSS animations'
  17014. }
  17015. };
  17016. })( jQuery, window , document );
  17017. /*!
  17018. * # Semantic UI 2.1.4 - API
  17019. * http://github.com/semantic-org/semantic-ui/
  17020. *
  17021. *
  17022. * Copyright 2015 Contributors
  17023. * Released under the MIT license
  17024. * http://opensource.org/licenses/MIT
  17025. *
  17026. */
  17027. ;(function ( $, window, document, undefined ) {
  17028. "use strict";
  17029. $.api = $.fn.api = function(parameters) {
  17030. var
  17031. // use window context if none specified
  17032. $allModules = $.isFunction(this)
  17033. ? $(window)
  17034. : $(this),
  17035. moduleSelector = $allModules.selector || '',
  17036. time = new Date().getTime(),
  17037. performance = [],
  17038. query = arguments[0],
  17039. methodInvoked = (typeof query == 'string'),
  17040. queryArguments = [].slice.call(arguments, 1),
  17041. returnedValue
  17042. ;
  17043. $allModules
  17044. .each(function() {
  17045. var
  17046. settings = ( $.isPlainObject(parameters) )
  17047. ? $.extend(true, {}, $.fn.api.settings, parameters)
  17048. : $.extend({}, $.fn.api.settings),
  17049. // internal aliases
  17050. namespace = settings.namespace,
  17051. metadata = settings.metadata,
  17052. selector = settings.selector,
  17053. error = settings.error,
  17054. className = settings.className,
  17055. // define namespaces for modules
  17056. eventNamespace = '.' + namespace,
  17057. moduleNamespace = 'module-' + namespace,
  17058. // element that creates request
  17059. $module = $(this),
  17060. $form = $module.closest(selector.form),
  17061. // context used for state
  17062. $context = (settings.stateContext)
  17063. ? $(settings.stateContext)
  17064. : $module,
  17065. // request details
  17066. ajaxSettings,
  17067. requestSettings,
  17068. url,
  17069. data,
  17070. requestStartTime,
  17071. // standard module
  17072. element = this,
  17073. context = $context[0],
  17074. instance = $module.data(moduleNamespace),
  17075. module
  17076. ;
  17077. module = {
  17078. initialize: function() {
  17079. if(!methodInvoked) {
  17080. module.bind.events();
  17081. }
  17082. module.instantiate();
  17083. },
  17084. instantiate: function() {
  17085. module.verbose('Storing instance of module', module);
  17086. instance = module;
  17087. $module
  17088. .data(moduleNamespace, instance)
  17089. ;
  17090. },
  17091. destroy: function() {
  17092. module.verbose('Destroying previous module for', element);
  17093. $module
  17094. .removeData(moduleNamespace)
  17095. .off(eventNamespace)
  17096. ;
  17097. },
  17098. bind: {
  17099. events: function() {
  17100. var
  17101. triggerEvent = module.get.event()
  17102. ;
  17103. if( triggerEvent ) {
  17104. module.verbose('Attaching API events to element', triggerEvent);
  17105. $module
  17106. .on(triggerEvent + eventNamespace, module.event.trigger)
  17107. ;
  17108. }
  17109. else if(settings.on == 'now') {
  17110. module.debug('Querying API endpoint immediately');
  17111. module.query();
  17112. }
  17113. }
  17114. },
  17115. decode: {
  17116. json: function(response) {
  17117. if(response !== undefined && typeof response == 'string') {
  17118. try {
  17119. response = JSON.parse(response);
  17120. }
  17121. catch(e) {
  17122. // isnt json string
  17123. }
  17124. }
  17125. return response;
  17126. }
  17127. },
  17128. read: {
  17129. cachedResponse: function(url) {
  17130. var
  17131. response
  17132. ;
  17133. if(window.Storage === undefined) {
  17134. module.error(error.noStorage);
  17135. return;
  17136. }
  17137. response = sessionStorage.getItem(url);
  17138. module.debug('Using cached response', url, response);
  17139. response = module.decode.json(response);
  17140. return false;
  17141. }
  17142. },
  17143. write: {
  17144. cachedResponse: function(url, response) {
  17145. if(response && response === '') {
  17146. module.debug('Response empty, not caching', response);
  17147. return;
  17148. }
  17149. if(window.Storage === undefined) {
  17150. module.error(error.noStorage);
  17151. return;
  17152. }
  17153. if( $.isPlainObject(response) ) {
  17154. response = JSON.stringify(response);
  17155. }
  17156. sessionStorage.setItem(url, response);
  17157. module.verbose('Storing cached response for url', url, response);
  17158. }
  17159. },
  17160. query: function() {
  17161. if(module.is.disabled()) {
  17162. module.debug('Element is disabled API request aborted');
  17163. return;
  17164. }
  17165. if(module.is.loading()) {
  17166. if(settings.interruptRequests) {
  17167. module.debug('Interrupting previous request');
  17168. module.abort();
  17169. }
  17170. else {
  17171. module.debug('Cancelling request, previous request is still pending');
  17172. return;
  17173. }
  17174. }
  17175. // pass element metadata to url (value, text)
  17176. if(settings.defaultData) {
  17177. $.extend(true, settings.urlData, module.get.defaultData());
  17178. }
  17179. // Add form content
  17180. if(settings.serializeForm) {
  17181. settings.data = module.add.formData(settings.data);
  17182. }
  17183. // call beforesend and get any settings changes
  17184. requestSettings = module.get.settings();
  17185. // check if before send cancelled request
  17186. if(requestSettings === false) {
  17187. module.cancelled = true;
  17188. module.error(error.beforeSend);
  17189. return;
  17190. }
  17191. else {
  17192. module.cancelled = false;
  17193. }
  17194. // get url
  17195. url = module.get.templatedURL();
  17196. if(!url && !module.is.mocked()) {
  17197. module.error(error.missingURL);
  17198. return;
  17199. }
  17200. // replace variables
  17201. url = module.add.urlData( url );
  17202. // missing url parameters
  17203. if( !url && !module.is.mocked()) {
  17204. return;
  17205. }
  17206. // look for jQuery ajax parameters in settings
  17207. ajaxSettings = $.extend(true, {}, settings, {
  17208. type : settings.method || settings.type,
  17209. data : data,
  17210. url : settings.base + url,
  17211. beforeSend : settings.beforeXHR,
  17212. success : function() {},
  17213. failure : function() {},
  17214. complete : function() {}
  17215. });
  17216. module.debug('Querying URL', ajaxSettings.url);
  17217. module.verbose('Using AJAX settings', ajaxSettings);
  17218. if(settings.cache === 'local' && module.read.cachedResponse(url)) {
  17219. module.debug('Response returned from local cache');
  17220. module.request = module.create.request();
  17221. module.request.resolveWith(context, [ module.read.cachedResponse(url) ]);
  17222. return;
  17223. }
  17224. if( !settings.throttle ) {
  17225. module.debug('Sending request', data, ajaxSettings.method);
  17226. module.send.request();
  17227. }
  17228. else {
  17229. if(!settings.throttleFirstRequest && !module.timer) {
  17230. module.debug('Sending request', data, ajaxSettings.method);
  17231. module.send.request();
  17232. module.timer = setTimeout(function(){}, settings.throttle);
  17233. }
  17234. else {
  17235. module.debug('Throttling request', settings.throttle);
  17236. clearTimeout(module.timer);
  17237. module.timer = setTimeout(function() {
  17238. if(module.timer) {
  17239. delete module.timer;
  17240. }
  17241. module.debug('Sending throttled request', data, ajaxSettings.method);
  17242. module.send.request();
  17243. }, settings.throttle);
  17244. }
  17245. }
  17246. },
  17247. should: {
  17248. removeError: function() {
  17249. return ( settings.hideError === true || (settings.hideError === 'auto' && !module.is.form()) );
  17250. }
  17251. },
  17252. is: {
  17253. disabled: function() {
  17254. return ($module.filter(selector.disabled).length > 0);
  17255. },
  17256. form: function() {
  17257. return $module.is('form') || $context.is('form');
  17258. },
  17259. mocked: function() {
  17260. return (settings.mockResponse || settings.mockResponseAsync);
  17261. },
  17262. input: function() {
  17263. return $module.is('input');
  17264. },
  17265. loading: function() {
  17266. return (module.request && module.request.state() == 'pending');
  17267. },
  17268. abortedRequest: function(xhr) {
  17269. if(xhr && xhr.readyState !== undefined && xhr.readyState === 0) {
  17270. module.verbose('XHR request determined to be aborted');
  17271. return true;
  17272. }
  17273. else {
  17274. module.verbose('XHR request was not aborted');
  17275. return false;
  17276. }
  17277. },
  17278. validResponse: function(response) {
  17279. if( (settings.dataType !== 'json' && settings.dataType !== 'jsonp') || !$.isFunction(settings.successTest) ) {
  17280. module.verbose('Response is not JSON, skipping validation', settings.successTest, response);
  17281. return true;
  17282. }
  17283. module.debug('Checking JSON returned success', settings.successTest, response);
  17284. if( settings.successTest(response) ) {
  17285. module.debug('Response passed success test', response);
  17286. return true;
  17287. }
  17288. else {
  17289. module.debug('Response failed success test', response);
  17290. return false;
  17291. }
  17292. }
  17293. },
  17294. was: {
  17295. cancelled: function() {
  17296. return (module.cancelled || false);
  17297. },
  17298. succesful: function() {
  17299. return (module.request && module.request.state() == 'resolved');
  17300. },
  17301. failure: function() {
  17302. return (module.request && module.request.state() == 'rejected');
  17303. },
  17304. complete: function() {
  17305. return (module.request && (module.request.state() == 'resolved' || module.request.state() == 'rejected') );
  17306. }
  17307. },
  17308. add: {
  17309. urlData: function(url, urlData) {
  17310. var
  17311. requiredVariables,
  17312. optionalVariables
  17313. ;
  17314. if(url) {
  17315. requiredVariables = url.match(settings.regExp.required);
  17316. optionalVariables = url.match(settings.regExp.optional);
  17317. urlData = urlData || settings.urlData;
  17318. if(requiredVariables) {
  17319. module.debug('Looking for required URL variables', requiredVariables);
  17320. $.each(requiredVariables, function(index, templatedString) {
  17321. var
  17322. // allow legacy {$var} style
  17323. variable = (templatedString.indexOf('$') !== -1)
  17324. ? templatedString.substr(2, templatedString.length - 3)
  17325. : templatedString.substr(1, templatedString.length - 2),
  17326. value = ($.isPlainObject(urlData) && urlData[variable] !== undefined)
  17327. ? urlData[variable]
  17328. : ($module.data(variable) !== undefined)
  17329. ? $module.data(variable)
  17330. : ($context.data(variable) !== undefined)
  17331. ? $context.data(variable)
  17332. : urlData[variable]
  17333. ;
  17334. // remove value
  17335. if(value === undefined) {
  17336. module.error(error.requiredParameter, variable, url);
  17337. url = false;
  17338. return false;
  17339. }
  17340. else {
  17341. module.verbose('Found required variable', variable, value);
  17342. value = (settings.encodeParameters)
  17343. ? module.get.urlEncodedValue(value)
  17344. : value
  17345. ;
  17346. url = url.replace(templatedString, value);
  17347. }
  17348. });
  17349. }
  17350. if(optionalVariables) {
  17351. module.debug('Looking for optional URL variables', requiredVariables);
  17352. $.each(optionalVariables, function(index, templatedString) {
  17353. var
  17354. // allow legacy {/$var} style
  17355. variable = (templatedString.indexOf('$') !== -1)
  17356. ? templatedString.substr(3, templatedString.length - 4)
  17357. : templatedString.substr(2, templatedString.length - 3),
  17358. value = ($.isPlainObject(urlData) && urlData[variable] !== undefined)
  17359. ? urlData[variable]
  17360. : ($module.data(variable) !== undefined)
  17361. ? $module.data(variable)
  17362. : ($context.data(variable) !== undefined)
  17363. ? $context.data(variable)
  17364. : urlData[variable]
  17365. ;
  17366. // optional replacement
  17367. if(value !== undefined) {
  17368. module.verbose('Optional variable Found', variable, value);
  17369. url = url.replace(templatedString, value);
  17370. }
  17371. else {
  17372. module.verbose('Optional variable not found', variable);
  17373. // remove preceding slash if set
  17374. if(url.indexOf('/' + templatedString) !== -1) {
  17375. url = url.replace('/' + templatedString, '');
  17376. }
  17377. else {
  17378. url = url.replace(templatedString, '');
  17379. }
  17380. }
  17381. });
  17382. }
  17383. }
  17384. return url;
  17385. },
  17386. formData: function(data) {
  17387. var
  17388. canSerialize = ($.fn.serializeObject !== undefined),
  17389. formData = (canSerialize)
  17390. ? $form.serializeObject()
  17391. : $form.serialize(),
  17392. hasOtherData
  17393. ;
  17394. data = data || settings.data;
  17395. hasOtherData = $.isPlainObject(data);
  17396. if(hasOtherData) {
  17397. if(canSerialize) {
  17398. module.debug('Extending existing data with form data', data, formData);
  17399. data = $.extend(true, {}, data, formData);
  17400. }
  17401. else {
  17402. module.error(error.missingSerialize);
  17403. module.debug('Cant extend data. Replacing data with form data', data, formData);
  17404. data = formData;
  17405. }
  17406. }
  17407. else {
  17408. module.debug('Adding form data', formData);
  17409. data = formData;
  17410. }
  17411. return data;
  17412. }
  17413. },
  17414. send: {
  17415. request: function() {
  17416. module.set.loading();
  17417. module.request = module.create.request();
  17418. if( module.is.mocked() ) {
  17419. module.mockedXHR = module.create.mockedXHR();
  17420. }
  17421. else {
  17422. module.xhr = module.create.xhr();
  17423. }
  17424. settings.onRequest.call(context, module.request, module.xhr);
  17425. }
  17426. },
  17427. event: {
  17428. trigger: function(event) {
  17429. module.query();
  17430. if(event.type == 'submit' || event.type == 'click') {
  17431. event.preventDefault();
  17432. }
  17433. },
  17434. xhr: {
  17435. always: function() {
  17436. // nothing special
  17437. },
  17438. done: function(response, textStatus, xhr) {
  17439. var
  17440. context = this,
  17441. elapsedTime = (new Date().getTime() - requestStartTime),
  17442. timeLeft = (settings.loadingDuration - elapsedTime),
  17443. translatedResponse = ( $.isFunction(settings.onResponse) )
  17444. ? settings.onResponse.call(context, $.extend(true, {}, response))
  17445. : false
  17446. ;
  17447. timeLeft = (timeLeft > 0)
  17448. ? timeLeft
  17449. : 0
  17450. ;
  17451. if(translatedResponse) {
  17452. module.debug('Modified API response in onResponse callback', settings.onResponse, translatedResponse, response);
  17453. response = translatedResponse;
  17454. }
  17455. if(timeLeft > 0) {
  17456. module.debug('Response completed early delaying state change by', timeLeft);
  17457. }
  17458. setTimeout(function() {
  17459. if( module.is.validResponse(response) ) {
  17460. module.request.resolveWith(context, [response, xhr]);
  17461. }
  17462. else {
  17463. module.request.rejectWith(context, [xhr, 'invalid']);
  17464. }
  17465. }, timeLeft);
  17466. },
  17467. fail: function(xhr, status, httpMessage) {
  17468. var
  17469. context = this,
  17470. elapsedTime = (new Date().getTime() - requestStartTime),
  17471. timeLeft = (settings.loadingDuration - elapsedTime)
  17472. ;
  17473. timeLeft = (timeLeft > 0)
  17474. ? timeLeft
  17475. : 0
  17476. ;
  17477. if(timeLeft > 0) {
  17478. module.debug('Response completed early delaying state change by', timeLeft);
  17479. }
  17480. setTimeout(function() {
  17481. if( module.is.abortedRequest(xhr) ) {
  17482. module.request.rejectWith(context, [xhr, 'aborted', httpMessage]);
  17483. }
  17484. else {
  17485. module.request.rejectWith(context, [xhr, 'error', status, httpMessage]);
  17486. }
  17487. }, timeLeft);
  17488. }
  17489. },
  17490. request: {
  17491. done: function(response, xhr) {
  17492. module.debug('Successful API Response', response);
  17493. if(settings.cache === 'local' && url) {
  17494. module.write.cachedResponse(url, response);
  17495. module.debug('Saving server response locally', module.cache);
  17496. }
  17497. settings.onSuccess.call(context, response, $module, xhr);
  17498. },
  17499. complete: function(firstParameter, secondParameter) {
  17500. var
  17501. xhr,
  17502. response
  17503. ;
  17504. // have to guess callback parameters based on request success
  17505. if( module.was.succesful() ) {
  17506. response = firstParameter;
  17507. xhr = secondParameter;
  17508. }
  17509. else {
  17510. xhr = firstParameter;
  17511. response = module.get.responseFromXHR(xhr);
  17512. }
  17513. module.remove.loading();
  17514. settings.onComplete.call(context, response, $module, xhr);
  17515. },
  17516. fail: function(xhr, status, httpMessage) {
  17517. var
  17518. // pull response from xhr if available
  17519. response = module.get.responseFromXHR(xhr),
  17520. errorMessage = module.get.errorFromRequest(response, status, httpMessage)
  17521. ;
  17522. if(status == 'aborted') {
  17523. module.debug('XHR Aborted (Most likely caused by page navigation or CORS Policy)', status, httpMessage);
  17524. settings.onAbort.call(context, status, $module, xhr);
  17525. }
  17526. else if(status == 'invalid') {
  17527. module.debug('JSON did not pass success test. A server-side error has most likely occurred', response);
  17528. }
  17529. else if(status == 'error') {
  17530. if(xhr !== undefined) {
  17531. module.debug('XHR produced a server error', status, httpMessage);
  17532. // make sure we have an error to display to console
  17533. if( xhr.status != 200 && httpMessage !== undefined && httpMessage !== '') {
  17534. module.error(error.statusMessage + httpMessage, ajaxSettings.url);
  17535. }
  17536. settings.onError.call(context, errorMessage, $module, xhr);
  17537. }
  17538. }
  17539. if(settings.errorDuration && status !== 'aborted') {
  17540. module.debug('Adding error state');
  17541. module.set.error();
  17542. if( module.should.removeError() ) {
  17543. setTimeout(module.remove.error, settings.errorDuration);
  17544. }
  17545. }
  17546. module.debug('API Request failed', errorMessage, xhr);
  17547. settings.onFailure.call(context, response, $module, xhr);
  17548. }
  17549. }
  17550. },
  17551. create: {
  17552. request: function() {
  17553. // api request promise
  17554. return $.Deferred()
  17555. .always(module.event.request.complete)
  17556. .done(module.event.request.done)
  17557. .fail(module.event.request.fail)
  17558. ;
  17559. },
  17560. mockedXHR: function () {
  17561. var
  17562. // xhr does not simulate these properties of xhr but must return them
  17563. textStatus = false,
  17564. status = false,
  17565. httpMessage = false,
  17566. asyncCallback,
  17567. response,
  17568. mockedXHR
  17569. ;
  17570. mockedXHR = $.Deferred()
  17571. .always(module.event.xhr.complete)
  17572. .done(module.event.xhr.done)
  17573. .fail(module.event.xhr.fail)
  17574. ;
  17575. if(settings.mockResponse) {
  17576. if( $.isFunction(settings.mockResponse) ) {
  17577. module.debug('Using mocked callback returning response', settings.mockResponse);
  17578. response = settings.mockResponse.call(context, settings);
  17579. }
  17580. else {
  17581. module.debug('Using specified response', settings.mockResponse);
  17582. response = settings.mockResponse;
  17583. }
  17584. // simulating response
  17585. mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]);
  17586. }
  17587. else if( $.isFunction(settings.mockResponseAsync) ) {
  17588. asyncCallback = function(response) {
  17589. module.debug('Async callback returned response', response);
  17590. if(response) {
  17591. mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]);
  17592. }
  17593. else {
  17594. mockedXHR.rejectWith(context, [{ responseText: response }, status, httpMessage]);
  17595. }
  17596. };
  17597. module.debug('Using async mocked response', settings.mockResponseAsync);
  17598. settings.mockResponseAsync.call(context, settings, asyncCallback);
  17599. }
  17600. return mockedXHR;
  17601. },
  17602. xhr: function() {
  17603. var
  17604. xhr
  17605. ;
  17606. // ajax request promise
  17607. xhr = $.ajax(ajaxSettings)
  17608. .always(module.event.xhr.always)
  17609. .done(module.event.xhr.done)
  17610. .fail(module.event.xhr.fail)
  17611. ;
  17612. module.verbose('Created server request', xhr);
  17613. return xhr;
  17614. }
  17615. },
  17616. set: {
  17617. error: function() {
  17618. module.verbose('Adding error state to element', $context);
  17619. $context.addClass(className.error);
  17620. },
  17621. loading: function() {
  17622. module.verbose('Adding loading state to element', $context);
  17623. $context.addClass(className.loading);
  17624. requestStartTime = new Date().getTime();
  17625. }
  17626. },
  17627. remove: {
  17628. error: function() {
  17629. module.verbose('Removing error state from element', $context);
  17630. $context.removeClass(className.error);
  17631. },
  17632. loading: function() {
  17633. module.verbose('Removing loading state from element', $context);
  17634. $context.removeClass(className.loading);
  17635. }
  17636. },
  17637. get: {
  17638. responseFromXHR: function(xhr) {
  17639. return $.isPlainObject(xhr)
  17640. ? (settings.dataType == 'json' || settings.dataType == 'jsonp')
  17641. ? module.decode.json(xhr.responseText)
  17642. : xhr.responseText
  17643. : false
  17644. ;
  17645. },
  17646. errorFromRequest: function(response, status, httpMessage) {
  17647. return ($.isPlainObject(response) && response.error !== undefined)
  17648. ? response.error // use json error message
  17649. : (settings.error[status] !== undefined) // use server error message
  17650. ? settings.error[status]
  17651. : httpMessage
  17652. ;
  17653. },
  17654. request: function() {
  17655. return module.request || false;
  17656. },
  17657. xhr: function() {
  17658. return module.xhr || false;
  17659. },
  17660. settings: function() {
  17661. var
  17662. runSettings
  17663. ;
  17664. runSettings = settings.beforeSend.call(context, settings);
  17665. if(runSettings) {
  17666. if(runSettings.success !== undefined) {
  17667. module.debug('Legacy success callback detected', runSettings);
  17668. module.error(error.legacyParameters, runSettings.success);
  17669. runSettings.onSuccess = runSettings.success;
  17670. }
  17671. if(runSettings.failure !== undefined) {
  17672. module.debug('Legacy failure callback detected', runSettings);
  17673. module.error(error.legacyParameters, runSettings.failure);
  17674. runSettings.onFailure = runSettings.failure;
  17675. }
  17676. if(runSettings.complete !== undefined) {
  17677. module.debug('Legacy complete callback detected', runSettings);
  17678. module.error(error.legacyParameters, runSettings.complete);
  17679. runSettings.onComplete = runSettings.complete;
  17680. }
  17681. }
  17682. if(runSettings === undefined) {
  17683. module.error(error.noReturnedValue);
  17684. }
  17685. return (runSettings !== undefined)
  17686. ? runSettings
  17687. : settings
  17688. ;
  17689. },
  17690. urlEncodedValue: function(value) {
  17691. var
  17692. decodedValue = window.decodeURIComponent(value),
  17693. encodedValue = window.encodeURIComponent(value),
  17694. alreadyEncoded = (decodedValue !== value)
  17695. ;
  17696. if(alreadyEncoded) {
  17697. module.debug('URL value is already encoded, avoiding double encoding', value);
  17698. return value;
  17699. }
  17700. module.verbose('Encoding value using encodeURIComponent', value, encodedValue);
  17701. return encodedValue;
  17702. },
  17703. defaultData: function() {
  17704. var
  17705. data = {}
  17706. ;
  17707. if( !$.isWindow(element) ) {
  17708. if( module.is.input() ) {
  17709. data.value = $module.val();
  17710. }
  17711. else if( !module.is.form() ) {
  17712. }
  17713. else {
  17714. data.text = $module.text();
  17715. }
  17716. }
  17717. return data;
  17718. },
  17719. event: function() {
  17720. if( $.isWindow(element) || settings.on == 'now' ) {
  17721. module.debug('API called without element, no events attached');
  17722. return false;
  17723. }
  17724. else if(settings.on == 'auto') {
  17725. if( $module.is('input') ) {
  17726. return (element.oninput !== undefined)
  17727. ? 'input'
  17728. : (element.onpropertychange !== undefined)
  17729. ? 'propertychange'
  17730. : 'keyup'
  17731. ;
  17732. }
  17733. else if( $module.is('form') ) {
  17734. return 'submit';
  17735. }
  17736. else {
  17737. return 'click';
  17738. }
  17739. }
  17740. else {
  17741. return settings.on;
  17742. }
  17743. },
  17744. templatedURL: function(action) {
  17745. action = action || $module.data(metadata.action) || settings.action || false;
  17746. url = $module.data(metadata.url) || settings.url || false;
  17747. if(url) {
  17748. module.debug('Using specified url', url);
  17749. return url;
  17750. }
  17751. if(action) {
  17752. module.debug('Looking up url for action', action, settings.api);
  17753. if(settings.api[action] === undefined && !module.is.mocked()) {
  17754. module.error(error.missingAction, settings.action, settings.api);
  17755. return;
  17756. }
  17757. url = settings.api[action];
  17758. }
  17759. else if( module.is.form() ) {
  17760. url = $module.attr('action') || $context.attr('action') || false;
  17761. module.debug('No url or action specified, defaulting to form action', url);
  17762. }
  17763. return url;
  17764. }
  17765. },
  17766. abort: function() {
  17767. var
  17768. xhr = module.get.xhr()
  17769. ;
  17770. if( xhr && xhr.state() !== 'resolved') {
  17771. module.debug('Cancelling API request');
  17772. xhr.abort();
  17773. }
  17774. },
  17775. // reset state
  17776. reset: function() {
  17777. module.remove.error();
  17778. module.remove.loading();
  17779. },
  17780. setting: function(name, value) {
  17781. module.debug('Changing setting', name, value);
  17782. if( $.isPlainObject(name) ) {
  17783. $.extend(true, settings, name);
  17784. }
  17785. else if(value !== undefined) {
  17786. settings[name] = value;
  17787. }
  17788. else {
  17789. return settings[name];
  17790. }
  17791. },
  17792. internal: function(name, value) {
  17793. if( $.isPlainObject(name) ) {
  17794. $.extend(true, module, name);
  17795. }
  17796. else if(value !== undefined) {
  17797. module[name] = value;
  17798. }
  17799. else {
  17800. return module[name];
  17801. }
  17802. },
  17803. debug: function() {
  17804. if(settings.debug) {
  17805. if(settings.performance) {
  17806. module.performance.log(arguments);
  17807. }
  17808. else {
  17809. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  17810. module.debug.apply(console, arguments);
  17811. }
  17812. }
  17813. },
  17814. verbose: function() {
  17815. if(settings.verbose && settings.debug) {
  17816. if(settings.performance) {
  17817. module.performance.log(arguments);
  17818. }
  17819. else {
  17820. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  17821. module.verbose.apply(console, arguments);
  17822. }
  17823. }
  17824. },
  17825. error: function() {
  17826. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  17827. module.error.apply(console, arguments);
  17828. },
  17829. performance: {
  17830. log: function(message) {
  17831. var
  17832. currentTime,
  17833. executionTime,
  17834. previousTime
  17835. ;
  17836. if(settings.performance) {
  17837. currentTime = new Date().getTime();
  17838. previousTime = time || currentTime;
  17839. executionTime = currentTime - previousTime;
  17840. time = currentTime;
  17841. performance.push({
  17842. 'Name' : message[0],
  17843. 'Arguments' : [].slice.call(message, 1) || '',
  17844. //'Element' : element,
  17845. 'Execution Time' : executionTime
  17846. });
  17847. }
  17848. clearTimeout(module.performance.timer);
  17849. module.performance.timer = setTimeout(module.performance.display, 500);
  17850. },
  17851. display: function() {
  17852. var
  17853. title = settings.name + ':',
  17854. totalTime = 0
  17855. ;
  17856. time = false;
  17857. clearTimeout(module.performance.timer);
  17858. $.each(performance, function(index, data) {
  17859. totalTime += data['Execution Time'];
  17860. });
  17861. title += ' ' + totalTime + 'ms';
  17862. if(moduleSelector) {
  17863. title += ' \'' + moduleSelector + '\'';
  17864. }
  17865. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  17866. console.groupCollapsed(title);
  17867. if(console.table) {
  17868. console.table(performance);
  17869. }
  17870. else {
  17871. $.each(performance, function(index, data) {
  17872. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  17873. });
  17874. }
  17875. console.groupEnd();
  17876. }
  17877. performance = [];
  17878. }
  17879. },
  17880. invoke: function(query, passedArguments, context) {
  17881. var
  17882. object = instance,
  17883. maxDepth,
  17884. found,
  17885. response
  17886. ;
  17887. passedArguments = passedArguments || queryArguments;
  17888. context = element || context;
  17889. if(typeof query == 'string' && object !== undefined) {
  17890. query = query.split(/[\. ]/);
  17891. maxDepth = query.length - 1;
  17892. $.each(query, function(depth, value) {
  17893. var camelCaseValue = (depth != maxDepth)
  17894. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  17895. : query
  17896. ;
  17897. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  17898. object = object[camelCaseValue];
  17899. }
  17900. else if( object[camelCaseValue] !== undefined ) {
  17901. found = object[camelCaseValue];
  17902. return false;
  17903. }
  17904. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  17905. object = object[value];
  17906. }
  17907. else if( object[value] !== undefined ) {
  17908. found = object[value];
  17909. return false;
  17910. }
  17911. else {
  17912. module.error(error.method, query);
  17913. return false;
  17914. }
  17915. });
  17916. }
  17917. if ( $.isFunction( found ) ) {
  17918. response = found.apply(context, passedArguments);
  17919. }
  17920. else if(found !== undefined) {
  17921. response = found;
  17922. }
  17923. if($.isArray(returnedValue)) {
  17924. returnedValue.push(response);
  17925. }
  17926. else if(returnedValue !== undefined) {
  17927. returnedValue = [returnedValue, response];
  17928. }
  17929. else if(response !== undefined) {
  17930. returnedValue = response;
  17931. }
  17932. return found;
  17933. }
  17934. };
  17935. if(methodInvoked) {
  17936. if(instance === undefined) {
  17937. module.initialize();
  17938. }
  17939. module.invoke(query);
  17940. }
  17941. else {
  17942. if(instance !== undefined) {
  17943. instance.invoke('destroy');
  17944. }
  17945. module.initialize();
  17946. }
  17947. })
  17948. ;
  17949. return (returnedValue !== undefined)
  17950. ? returnedValue
  17951. : this
  17952. ;
  17953. };
  17954. $.api.settings = {
  17955. name : 'API',
  17956. namespace : 'api',
  17957. debug : false,
  17958. verbose : false,
  17959. performance : true,
  17960. // object containing all templates endpoints
  17961. api : {},
  17962. // whether to cache responses
  17963. cache : true,
  17964. // whether new requests should abort previous requests
  17965. interruptRequests : true,
  17966. // event binding
  17967. on : 'auto',
  17968. // context for applying state classes
  17969. stateContext : false,
  17970. // duration for loading state
  17971. loadingDuration : 0,
  17972. // whether to hide errors after a period of time
  17973. hideError : 'auto',
  17974. // duration for error state
  17975. errorDuration : 2000,
  17976. // whether parameters should be encoded with encodeURIComponent
  17977. encodeParameters : true,
  17978. // API action to use
  17979. action : false,
  17980. // templated URL to use
  17981. url : false,
  17982. // base URL to apply to all endpoints
  17983. base : '',
  17984. // data that will
  17985. urlData : {},
  17986. // whether to add default data to url data
  17987. defaultData : true,
  17988. // whether to serialize closest form
  17989. serializeForm : false,
  17990. // how long to wait before request should occur
  17991. throttle : 0,
  17992. // whether to throttle first request or only repeated
  17993. throttleFirstRequest : true,
  17994. // standard ajax settings
  17995. method : 'get',
  17996. data : {},
  17997. dataType : 'json',
  17998. // mock response
  17999. mockResponse : false,
  18000. mockResponseAsync : false,
  18001. // callbacks before request
  18002. beforeSend : function(settings) { return settings; },
  18003. beforeXHR : function(xhr) {},
  18004. onRequest : function(promise, xhr) {},
  18005. // after request
  18006. onResponse : false, // function(response) { },
  18007. // response was successful, if JSON passed validation
  18008. onSuccess : function(response, $module) {},
  18009. // request finished without aborting
  18010. onComplete : function(response, $module) {},
  18011. // failed JSON success test
  18012. onFailure : function(response, $module) {},
  18013. // server error
  18014. onError : function(errorMessage, $module) {},
  18015. // request aborted
  18016. onAbort : function(errorMessage, $module) {},
  18017. successTest : false,
  18018. // errors
  18019. error : {
  18020. beforeSend : 'The before send function has aborted the request',
  18021. error : 'There was an error with your request',
  18022. exitConditions : 'API Request Aborted. Exit conditions met',
  18023. JSONParse : 'JSON could not be parsed during error handling',
  18024. legacyParameters : 'You are using legacy API success callback names',
  18025. method : 'The method you called is not defined',
  18026. missingAction : 'API action used but no url was defined',
  18027. missingSerialize : 'jquery-serialize-object is required to add form data to an existing data object',
  18028. missingURL : 'No URL specified for api event',
  18029. noReturnedValue : 'The beforeSend callback must return a settings object, beforeSend ignored.',
  18030. noStorage : 'Caching responses locally requires session storage',
  18031. parseError : 'There was an error parsing your request',
  18032. requiredParameter : 'Missing a required URL parameter: ',
  18033. statusMessage : 'Server gave an error: ',
  18034. timeout : 'Your request timed out'
  18035. },
  18036. regExp : {
  18037. required : /\{\$*[A-z0-9]+\}/g,
  18038. optional : /\{\/\$*[A-z0-9]+\}/g,
  18039. },
  18040. className: {
  18041. loading : 'loading',
  18042. error : 'error'
  18043. },
  18044. selector: {
  18045. disabled : '.disabled',
  18046. form : 'form'
  18047. },
  18048. metadata: {
  18049. action : 'action',
  18050. url : 'url'
  18051. }
  18052. };
  18053. })( jQuery, window , document );
  18054. /*!
  18055. * # Semantic UI 2.1.4 - State
  18056. * http://github.com/semantic-org/semantic-ui/
  18057. *
  18058. *
  18059. * Copyright 2015 Contributors
  18060. * Released under the MIT license
  18061. * http://opensource.org/licenses/MIT
  18062. *
  18063. */
  18064. ;(function ( $, window, document, undefined ) {
  18065. "use strict";
  18066. $.fn.state = function(parameters) {
  18067. var
  18068. $allModules = $(this),
  18069. moduleSelector = $allModules.selector || '',
  18070. hasTouch = ('ontouchstart' in document.documentElement),
  18071. time = new Date().getTime(),
  18072. performance = [],
  18073. query = arguments[0],
  18074. methodInvoked = (typeof query == 'string'),
  18075. queryArguments = [].slice.call(arguments, 1),
  18076. returnedValue
  18077. ;
  18078. $allModules
  18079. .each(function() {
  18080. var
  18081. settings = ( $.isPlainObject(parameters) )
  18082. ? $.extend(true, {}, $.fn.state.settings, parameters)
  18083. : $.extend({}, $.fn.state.settings),
  18084. error = settings.error,
  18085. metadata = settings.metadata,
  18086. className = settings.className,
  18087. namespace = settings.namespace,
  18088. states = settings.states,
  18089. text = settings.text,
  18090. eventNamespace = '.' + namespace,
  18091. moduleNamespace = namespace + '-module',
  18092. $module = $(this),
  18093. element = this,
  18094. instance = $module.data(moduleNamespace),
  18095. module
  18096. ;
  18097. module = {
  18098. initialize: function() {
  18099. module.verbose('Initializing module');
  18100. // allow module to guess desired state based on element
  18101. if(settings.automatic) {
  18102. module.add.defaults();
  18103. }
  18104. // bind events with delegated events
  18105. if(settings.context && moduleSelector !== '') {
  18106. $(settings.context)
  18107. .on(moduleSelector, 'mouseenter' + eventNamespace, module.change.text)
  18108. .on(moduleSelector, 'mouseleave' + eventNamespace, module.reset.text)
  18109. .on(moduleSelector, 'click' + eventNamespace, module.toggle.state)
  18110. ;
  18111. }
  18112. else {
  18113. $module
  18114. .on('mouseenter' + eventNamespace, module.change.text)
  18115. .on('mouseleave' + eventNamespace, module.reset.text)
  18116. .on('click' + eventNamespace, module.toggle.state)
  18117. ;
  18118. }
  18119. module.instantiate();
  18120. },
  18121. instantiate: function() {
  18122. module.verbose('Storing instance of module', module);
  18123. instance = module;
  18124. $module
  18125. .data(moduleNamespace, module)
  18126. ;
  18127. },
  18128. destroy: function() {
  18129. module.verbose('Destroying previous module', instance);
  18130. $module
  18131. .off(eventNamespace)
  18132. .removeData(moduleNamespace)
  18133. ;
  18134. },
  18135. refresh: function() {
  18136. module.verbose('Refreshing selector cache');
  18137. $module = $(element);
  18138. },
  18139. add: {
  18140. defaults: function() {
  18141. var
  18142. userStates = parameters && $.isPlainObject(parameters.states)
  18143. ? parameters.states
  18144. : {}
  18145. ;
  18146. $.each(settings.defaults, function(type, typeStates) {
  18147. if( module.is[type] !== undefined && module.is[type]() ) {
  18148. module.verbose('Adding default states', type, element);
  18149. $.extend(settings.states, typeStates, userStates);
  18150. }
  18151. });
  18152. }
  18153. },
  18154. is: {
  18155. active: function() {
  18156. return $module.hasClass(className.active);
  18157. },
  18158. loading: function() {
  18159. return $module.hasClass(className.loading);
  18160. },
  18161. inactive: function() {
  18162. return !( $module.hasClass(className.active) );
  18163. },
  18164. state: function(state) {
  18165. if(className[state] === undefined) {
  18166. return false;
  18167. }
  18168. return $module.hasClass( className[state] );
  18169. },
  18170. enabled: function() {
  18171. return !( $module.is(settings.filter.active) );
  18172. },
  18173. disabled: function() {
  18174. return ( $module.is(settings.filter.active) );
  18175. },
  18176. textEnabled: function() {
  18177. return !( $module.is(settings.filter.text) );
  18178. },
  18179. // definitions for automatic type detection
  18180. button: function() {
  18181. return $module.is('.button:not(a, .submit)');
  18182. },
  18183. input: function() {
  18184. return $module.is('input');
  18185. },
  18186. progress: function() {
  18187. return $module.is('.ui.progress');
  18188. }
  18189. },
  18190. allow: function(state) {
  18191. module.debug('Now allowing state', state);
  18192. states[state] = true;
  18193. },
  18194. disallow: function(state) {
  18195. module.debug('No longer allowing', state);
  18196. states[state] = false;
  18197. },
  18198. allows: function(state) {
  18199. return states[state] || false;
  18200. },
  18201. enable: function() {
  18202. $module.removeClass(className.disabled);
  18203. },
  18204. disable: function() {
  18205. $module.addClass(className.disabled);
  18206. },
  18207. setState: function(state) {
  18208. if(module.allows(state)) {
  18209. $module.addClass( className[state] );
  18210. }
  18211. },
  18212. removeState: function(state) {
  18213. if(module.allows(state)) {
  18214. $module.removeClass( className[state] );
  18215. }
  18216. },
  18217. toggle: {
  18218. state: function() {
  18219. var
  18220. apiRequest,
  18221. requestCancelled
  18222. ;
  18223. if( module.allows('active') && module.is.enabled() ) {
  18224. module.refresh();
  18225. if($.fn.api !== undefined) {
  18226. apiRequest = $module.api('get request');
  18227. requestCancelled = $module.api('was cancelled');
  18228. if( requestCancelled ) {
  18229. module.debug('API Request cancelled by beforesend');
  18230. settings.activateTest = function(){ return false; };
  18231. settings.deactivateTest = function(){ return false; };
  18232. }
  18233. else if(apiRequest) {
  18234. module.listenTo(apiRequest);
  18235. return;
  18236. }
  18237. }
  18238. module.change.state();
  18239. }
  18240. }
  18241. },
  18242. listenTo: function(apiRequest) {
  18243. module.debug('API request detected, waiting for state signal', apiRequest);
  18244. if(apiRequest) {
  18245. if(text.loading) {
  18246. module.update.text(text.loading);
  18247. }
  18248. $.when(apiRequest)
  18249. .then(function() {
  18250. if(apiRequest.state() == 'resolved') {
  18251. module.debug('API request succeeded');
  18252. settings.activateTest = function(){ return true; };
  18253. settings.deactivateTest = function(){ return true; };
  18254. }
  18255. else {
  18256. module.debug('API request failed');
  18257. settings.activateTest = function(){ return false; };
  18258. settings.deactivateTest = function(){ return false; };
  18259. }
  18260. module.change.state();
  18261. })
  18262. ;
  18263. }
  18264. },
  18265. // checks whether active/inactive state can be given
  18266. change: {
  18267. state: function() {
  18268. module.debug('Determining state change direction');
  18269. // inactive to active change
  18270. if( module.is.inactive() ) {
  18271. module.activate();
  18272. }
  18273. else {
  18274. module.deactivate();
  18275. }
  18276. if(settings.sync) {
  18277. module.sync();
  18278. }
  18279. settings.onChange.call(element);
  18280. },
  18281. text: function() {
  18282. if( module.is.textEnabled() ) {
  18283. if(module.is.disabled() ) {
  18284. module.verbose('Changing text to disabled text', text.hover);
  18285. module.update.text(text.disabled);
  18286. }
  18287. else if( module.is.active() ) {
  18288. if(text.hover) {
  18289. module.verbose('Changing text to hover text', text.hover);
  18290. module.update.text(text.hover);
  18291. }
  18292. else if(text.deactivate) {
  18293. module.verbose('Changing text to deactivating text', text.deactivate);
  18294. module.update.text(text.deactivate);
  18295. }
  18296. }
  18297. else {
  18298. if(text.hover) {
  18299. module.verbose('Changing text to hover text', text.hover);
  18300. module.update.text(text.hover);
  18301. }
  18302. else if(text.activate){
  18303. module.verbose('Changing text to activating text', text.activate);
  18304. module.update.text(text.activate);
  18305. }
  18306. }
  18307. }
  18308. }
  18309. },
  18310. activate: function() {
  18311. if( settings.activateTest.call(element) ) {
  18312. module.debug('Setting state to active');
  18313. $module
  18314. .addClass(className.active)
  18315. ;
  18316. module.update.text(text.active);
  18317. settings.onActivate.call(element);
  18318. }
  18319. },
  18320. deactivate: function() {
  18321. if( settings.deactivateTest.call(element) ) {
  18322. module.debug('Setting state to inactive');
  18323. $module
  18324. .removeClass(className.active)
  18325. ;
  18326. module.update.text(text.inactive);
  18327. settings.onDeactivate.call(element);
  18328. }
  18329. },
  18330. sync: function() {
  18331. module.verbose('Syncing other buttons to current state');
  18332. if( module.is.active() ) {
  18333. $allModules
  18334. .not($module)
  18335. .state('activate');
  18336. }
  18337. else {
  18338. $allModules
  18339. .not($module)
  18340. .state('deactivate')
  18341. ;
  18342. }
  18343. },
  18344. get: {
  18345. text: function() {
  18346. return (settings.selector.text)
  18347. ? $module.find(settings.selector.text).text()
  18348. : $module.html()
  18349. ;
  18350. },
  18351. textFor: function(state) {
  18352. return text[state] || false;
  18353. }
  18354. },
  18355. flash: {
  18356. text: function(text, duration, callback) {
  18357. var
  18358. previousText = module.get.text()
  18359. ;
  18360. module.debug('Flashing text message', text, duration);
  18361. text = text || settings.text.flash;
  18362. duration = duration || settings.flashDuration;
  18363. callback = callback || function() {};
  18364. module.update.text(text);
  18365. setTimeout(function(){
  18366. module.update.text(previousText);
  18367. callback.call(element);
  18368. }, duration);
  18369. }
  18370. },
  18371. reset: {
  18372. // on mouseout sets text to previous value
  18373. text: function() {
  18374. var
  18375. activeText = text.active || $module.data(metadata.storedText),
  18376. inactiveText = text.inactive || $module.data(metadata.storedText)
  18377. ;
  18378. if( module.is.textEnabled() ) {
  18379. if( module.is.active() && activeText) {
  18380. module.verbose('Resetting active text', activeText);
  18381. module.update.text(activeText);
  18382. }
  18383. else if(inactiveText) {
  18384. module.verbose('Resetting inactive text', activeText);
  18385. module.update.text(inactiveText);
  18386. }
  18387. }
  18388. }
  18389. },
  18390. update: {
  18391. text: function(text) {
  18392. var
  18393. currentText = module.get.text()
  18394. ;
  18395. if(text && text !== currentText) {
  18396. module.debug('Updating text', text);
  18397. if(settings.selector.text) {
  18398. $module
  18399. .data(metadata.storedText, text)
  18400. .find(settings.selector.text)
  18401. .text(text)
  18402. ;
  18403. }
  18404. else {
  18405. $module
  18406. .data(metadata.storedText, text)
  18407. .html(text)
  18408. ;
  18409. }
  18410. }
  18411. else {
  18412. module.debug('Text is already set, ignoring update', text);
  18413. }
  18414. }
  18415. },
  18416. setting: function(name, value) {
  18417. module.debug('Changing setting', name, value);
  18418. if( $.isPlainObject(name) ) {
  18419. $.extend(true, settings, name);
  18420. }
  18421. else if(value !== undefined) {
  18422. settings[name] = value;
  18423. }
  18424. else {
  18425. return settings[name];
  18426. }
  18427. },
  18428. internal: function(name, value) {
  18429. if( $.isPlainObject(name) ) {
  18430. $.extend(true, module, name);
  18431. }
  18432. else if(value !== undefined) {
  18433. module[name] = value;
  18434. }
  18435. else {
  18436. return module[name];
  18437. }
  18438. },
  18439. debug: function() {
  18440. if(settings.debug) {
  18441. if(settings.performance) {
  18442. module.performance.log(arguments);
  18443. }
  18444. else {
  18445. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  18446. module.debug.apply(console, arguments);
  18447. }
  18448. }
  18449. },
  18450. verbose: function() {
  18451. if(settings.verbose && settings.debug) {
  18452. if(settings.performance) {
  18453. module.performance.log(arguments);
  18454. }
  18455. else {
  18456. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  18457. module.verbose.apply(console, arguments);
  18458. }
  18459. }
  18460. },
  18461. error: function() {
  18462. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  18463. module.error.apply(console, arguments);
  18464. },
  18465. performance: {
  18466. log: function(message) {
  18467. var
  18468. currentTime,
  18469. executionTime,
  18470. previousTime
  18471. ;
  18472. if(settings.performance) {
  18473. currentTime = new Date().getTime();
  18474. previousTime = time || currentTime;
  18475. executionTime = currentTime - previousTime;
  18476. time = currentTime;
  18477. performance.push({
  18478. 'Name' : message[0],
  18479. 'Arguments' : [].slice.call(message, 1) || '',
  18480. 'Element' : element,
  18481. 'Execution Time' : executionTime
  18482. });
  18483. }
  18484. clearTimeout(module.performance.timer);
  18485. module.performance.timer = setTimeout(module.performance.display, 500);
  18486. },
  18487. display: function() {
  18488. var
  18489. title = settings.name + ':',
  18490. totalTime = 0
  18491. ;
  18492. time = false;
  18493. clearTimeout(module.performance.timer);
  18494. $.each(performance, function(index, data) {
  18495. totalTime += data['Execution Time'];
  18496. });
  18497. title += ' ' + totalTime + 'ms';
  18498. if(moduleSelector) {
  18499. title += ' \'' + moduleSelector + '\'';
  18500. }
  18501. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  18502. console.groupCollapsed(title);
  18503. if(console.table) {
  18504. console.table(performance);
  18505. }
  18506. else {
  18507. $.each(performance, function(index, data) {
  18508. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  18509. });
  18510. }
  18511. console.groupEnd();
  18512. }
  18513. performance = [];
  18514. }
  18515. },
  18516. invoke: function(query, passedArguments, context) {
  18517. var
  18518. object = instance,
  18519. maxDepth,
  18520. found,
  18521. response
  18522. ;
  18523. passedArguments = passedArguments || queryArguments;
  18524. context = element || context;
  18525. if(typeof query == 'string' && object !== undefined) {
  18526. query = query.split(/[\. ]/);
  18527. maxDepth = query.length - 1;
  18528. $.each(query, function(depth, value) {
  18529. var camelCaseValue = (depth != maxDepth)
  18530. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  18531. : query
  18532. ;
  18533. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  18534. object = object[camelCaseValue];
  18535. }
  18536. else if( object[camelCaseValue] !== undefined ) {
  18537. found = object[camelCaseValue];
  18538. return false;
  18539. }
  18540. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  18541. object = object[value];
  18542. }
  18543. else if( object[value] !== undefined ) {
  18544. found = object[value];
  18545. return false;
  18546. }
  18547. else {
  18548. module.error(error.method, query);
  18549. return false;
  18550. }
  18551. });
  18552. }
  18553. if ( $.isFunction( found ) ) {
  18554. response = found.apply(context, passedArguments);
  18555. }
  18556. else if(found !== undefined) {
  18557. response = found;
  18558. }
  18559. if($.isArray(returnedValue)) {
  18560. returnedValue.push(response);
  18561. }
  18562. else if(returnedValue !== undefined) {
  18563. returnedValue = [returnedValue, response];
  18564. }
  18565. else if(response !== undefined) {
  18566. returnedValue = response;
  18567. }
  18568. return found;
  18569. }
  18570. };
  18571. if(methodInvoked) {
  18572. if(instance === undefined) {
  18573. module.initialize();
  18574. }
  18575. module.invoke(query);
  18576. }
  18577. else {
  18578. if(instance !== undefined) {
  18579. instance.invoke('destroy');
  18580. }
  18581. module.initialize();
  18582. }
  18583. })
  18584. ;
  18585. return (returnedValue !== undefined)
  18586. ? returnedValue
  18587. : this
  18588. ;
  18589. };
  18590. $.fn.state.settings = {
  18591. // module info
  18592. name : 'State',
  18593. // debug output
  18594. debug : false,
  18595. // verbose debug output
  18596. verbose : false,
  18597. // namespace for events
  18598. namespace : 'state',
  18599. // debug data includes performance
  18600. performance : true,
  18601. // callback occurs on state change
  18602. onActivate : function() {},
  18603. onDeactivate : function() {},
  18604. onChange : function() {},
  18605. // state test functions
  18606. activateTest : function() { return true; },
  18607. deactivateTest : function() { return true; },
  18608. // whether to automatically map default states
  18609. automatic : true,
  18610. // activate / deactivate changes all elements instantiated at same time
  18611. sync : false,
  18612. // default flash text duration, used for temporarily changing text of an element
  18613. flashDuration : 1000,
  18614. // selector filter
  18615. filter : {
  18616. text : '.loading, .disabled',
  18617. active : '.disabled'
  18618. },
  18619. context : false,
  18620. // error
  18621. error: {
  18622. beforeSend : 'The before send function has cancelled state change',
  18623. method : 'The method you called is not defined.'
  18624. },
  18625. // metadata
  18626. metadata: {
  18627. promise : 'promise',
  18628. storedText : 'stored-text'
  18629. },
  18630. // change class on state
  18631. className: {
  18632. active : 'active',
  18633. disabled : 'disabled',
  18634. error : 'error',
  18635. loading : 'loading',
  18636. success : 'success',
  18637. warning : 'warning'
  18638. },
  18639. selector: {
  18640. // selector for text node
  18641. text: false
  18642. },
  18643. defaults : {
  18644. input: {
  18645. disabled : true,
  18646. loading : true,
  18647. active : true
  18648. },
  18649. button: {
  18650. disabled : true,
  18651. loading : true,
  18652. active : true,
  18653. },
  18654. progress: {
  18655. active : true,
  18656. success : true,
  18657. warning : true,
  18658. error : true
  18659. }
  18660. },
  18661. states : {
  18662. active : true,
  18663. disabled : true,
  18664. error : true,
  18665. loading : true,
  18666. success : true,
  18667. warning : true
  18668. },
  18669. text : {
  18670. disabled : false,
  18671. flash : false,
  18672. hover : false,
  18673. active : false,
  18674. inactive : false,
  18675. activate : false,
  18676. deactivate : false
  18677. }
  18678. };
  18679. })( jQuery, window , document );
  18680. /*!
  18681. * # Semantic UI 2.1.4 - Visibility
  18682. * http://github.com/semantic-org/semantic-ui/
  18683. *
  18684. *
  18685. * Copyright 2015 Contributors
  18686. * Released under the MIT license
  18687. * http://opensource.org/licenses/MIT
  18688. *
  18689. */
  18690. ;(function ( $, window, document, undefined ) {
  18691. "use strict";
  18692. $.fn.visibility = function(parameters) {
  18693. var
  18694. $allModules = $(this),
  18695. moduleSelector = $allModules.selector || '',
  18696. time = new Date().getTime(),
  18697. performance = [],
  18698. query = arguments[0],
  18699. methodInvoked = (typeof query == 'string'),
  18700. queryArguments = [].slice.call(arguments, 1),
  18701. returnedValue
  18702. ;
  18703. $allModules
  18704. .each(function() {
  18705. var
  18706. settings = ( $.isPlainObject(parameters) )
  18707. ? $.extend(true, {}, $.fn.visibility.settings, parameters)
  18708. : $.extend({}, $.fn.visibility.settings),
  18709. className = settings.className,
  18710. namespace = settings.namespace,
  18711. error = settings.error,
  18712. metadata = settings.metadata,
  18713. eventNamespace = '.' + namespace,
  18714. moduleNamespace = 'module-' + namespace,
  18715. $window = $(window),
  18716. $module = $(this),
  18717. $context = $(settings.context),
  18718. $placeholder,
  18719. selector = $module.selector || '',
  18720. instance = $module.data(moduleNamespace),
  18721. requestAnimationFrame = window.requestAnimationFrame
  18722. || window.mozRequestAnimationFrame
  18723. || window.webkitRequestAnimationFrame
  18724. || window.msRequestAnimationFrame
  18725. || function(callback) { setTimeout(callback, 0); },
  18726. element = this,
  18727. disabled = false,
  18728. observer,
  18729. module
  18730. ;
  18731. module = {
  18732. initialize: function() {
  18733. module.debug('Initializing', settings);
  18734. module.setup.cache();
  18735. if( module.should.trackChanges() ) {
  18736. if(settings.type == 'image') {
  18737. module.setup.image();
  18738. }
  18739. if(settings.type == 'fixed') {
  18740. module.setup.fixed();
  18741. }
  18742. if(settings.observeChanges) {
  18743. module.observeChanges();
  18744. }
  18745. module.bind.events();
  18746. }
  18747. module.save.position();
  18748. if( !module.is.visible() ) {
  18749. module.error(error.visible, $module);
  18750. }
  18751. if(settings.initialCheck) {
  18752. module.checkVisibility();
  18753. }
  18754. module.instantiate();
  18755. },
  18756. instantiate: function() {
  18757. module.debug('Storing instance', module);
  18758. $module
  18759. .data(moduleNamespace, module)
  18760. ;
  18761. instance = module;
  18762. },
  18763. destroy: function() {
  18764. module.verbose('Destroying previous module');
  18765. if(observer) {
  18766. observer.disconnect();
  18767. }
  18768. $window
  18769. .off('load' + eventNamespace, module.event.load)
  18770. .off('resize' + eventNamespace, module.event.resize)
  18771. ;
  18772. $context
  18773. .off('scrollchange' + eventNamespace, module.event.scrollchange)
  18774. ;
  18775. $module
  18776. .off(eventNamespace)
  18777. .removeData(moduleNamespace)
  18778. ;
  18779. },
  18780. observeChanges: function() {
  18781. if('MutationObserver' in window) {
  18782. observer = new MutationObserver(function(mutations) {
  18783. module.verbose('DOM tree modified, updating visibility calculations');
  18784. module.timer = setTimeout(function() {
  18785. module.verbose('DOM tree modified, updating sticky menu');
  18786. module.refresh();
  18787. }, 100);
  18788. });
  18789. observer.observe(element, {
  18790. childList : true,
  18791. subtree : true
  18792. });
  18793. module.debug('Setting up mutation observer', observer);
  18794. }
  18795. },
  18796. bind: {
  18797. events: function() {
  18798. module.verbose('Binding visibility events to scroll and resize');
  18799. if(settings.refreshOnLoad) {
  18800. $window
  18801. .on('load' + eventNamespace, module.event.load)
  18802. ;
  18803. }
  18804. $window
  18805. .on('resize' + eventNamespace, module.event.resize)
  18806. ;
  18807. // pub/sub pattern
  18808. $context
  18809. .off('scroll' + eventNamespace)
  18810. .on('scroll' + eventNamespace, module.event.scroll)
  18811. .on('scrollchange' + eventNamespace, module.event.scrollchange)
  18812. ;
  18813. }
  18814. },
  18815. event: {
  18816. resize: function() {
  18817. module.debug('Window resized');
  18818. if(settings.refreshOnResize) {
  18819. requestAnimationFrame(module.refresh);
  18820. }
  18821. },
  18822. load: function() {
  18823. module.debug('Page finished loading');
  18824. requestAnimationFrame(module.refresh);
  18825. },
  18826. // publishes scrollchange event on one scroll
  18827. scroll: function() {
  18828. if(settings.throttle) {
  18829. clearTimeout(module.timer);
  18830. module.timer = setTimeout(function() {
  18831. $context.triggerHandler('scrollchange' + eventNamespace, [ $context.scrollTop() ]);
  18832. }, settings.throttle);
  18833. }
  18834. else {
  18835. requestAnimationFrame(function() {
  18836. $context.triggerHandler('scrollchange' + eventNamespace, [ $context.scrollTop() ]);
  18837. });
  18838. }
  18839. },
  18840. // subscribes to scrollchange
  18841. scrollchange: function(event, scrollPosition) {
  18842. module.checkVisibility(scrollPosition);
  18843. },
  18844. },
  18845. precache: function(images, callback) {
  18846. if (!(images instanceof Array)) {
  18847. images = [images];
  18848. }
  18849. var
  18850. imagesLength = images.length,
  18851. loadedCounter = 0,
  18852. cache = [],
  18853. cacheImage = document.createElement('img'),
  18854. handleLoad = function() {
  18855. loadedCounter++;
  18856. if (loadedCounter >= images.length) {
  18857. if ($.isFunction(callback)) {
  18858. callback();
  18859. }
  18860. }
  18861. }
  18862. ;
  18863. while (imagesLength--) {
  18864. cacheImage = document.createElement('img');
  18865. cacheImage.onload = handleLoad;
  18866. cacheImage.onerror = handleLoad;
  18867. cacheImage.src = images[imagesLength];
  18868. cache.push(cacheImage);
  18869. }
  18870. },
  18871. enableCallbacks: function() {
  18872. module.debug('Allowing callbacks to occur');
  18873. disabled = false;
  18874. },
  18875. disableCallbacks: function() {
  18876. module.debug('Disabling all callbacks temporarily');
  18877. disabled = true;
  18878. },
  18879. should: {
  18880. trackChanges: function() {
  18881. if(methodInvoked) {
  18882. module.debug('One time query, no need to bind events');
  18883. return false;
  18884. }
  18885. module.debug('Callbacks being attached');
  18886. return true;
  18887. }
  18888. },
  18889. setup: {
  18890. cache: function() {
  18891. module.cache = {
  18892. occurred : {},
  18893. screen : {},
  18894. element : {},
  18895. };
  18896. },
  18897. image: function() {
  18898. var
  18899. src = $module.data(metadata.src)
  18900. ;
  18901. if(src) {
  18902. module.verbose('Lazy loading image', src);
  18903. settings.once = true;
  18904. settings.observeChanges = false;
  18905. // show when top visible
  18906. settings.onOnScreen = function() {
  18907. module.debug('Image on screen', element);
  18908. module.precache(src, function() {
  18909. module.set.image(src);
  18910. });
  18911. };
  18912. }
  18913. },
  18914. fixed: function() {
  18915. module.debug('Setting up fixed');
  18916. settings.once = false;
  18917. settings.observeChanges = false;
  18918. settings.initialCheck = true;
  18919. settings.refreshOnLoad = true;
  18920. if(!parameters.transition) {
  18921. settings.transition = false;
  18922. }
  18923. module.create.placeholder();
  18924. module.debug('Added placeholder', $placeholder);
  18925. settings.onTopPassed = function() {
  18926. module.debug('Element passed, adding fixed position', $module);
  18927. module.show.placeholder();
  18928. module.set.fixed();
  18929. if(settings.transition) {
  18930. if($.fn.transition !== undefined) {
  18931. $module.transition(settings.transition, settings.duration);
  18932. }
  18933. }
  18934. };
  18935. settings.onTopPassedReverse = function() {
  18936. module.debug('Element returned to position, removing fixed', $module);
  18937. module.hide.placeholder();
  18938. module.remove.fixed();
  18939. };
  18940. }
  18941. },
  18942. create: {
  18943. placeholder: function() {
  18944. module.verbose('Creating fixed position placeholder');
  18945. $placeholder = $module
  18946. .clone(false)
  18947. .css('display', 'none')
  18948. .addClass(className.placeholder)
  18949. .insertAfter($module)
  18950. ;
  18951. }
  18952. },
  18953. show: {
  18954. placeholder: function() {
  18955. module.verbose('Showing placeholder');
  18956. $placeholder
  18957. .css('display', 'block')
  18958. .css('visibility', 'hidden')
  18959. ;
  18960. }
  18961. },
  18962. hide: {
  18963. placeholder: function() {
  18964. module.verbose('Hiding placeholder');
  18965. $placeholder
  18966. .css('display', 'none')
  18967. .css('visibility', '')
  18968. ;
  18969. }
  18970. },
  18971. set: {
  18972. fixed: function() {
  18973. module.verbose('Setting element to fixed position');
  18974. $module
  18975. .addClass(className.fixed)
  18976. .css({
  18977. position : 'fixed',
  18978. top : settings.offset + 'px',
  18979. left : 'auto',
  18980. zIndex : '1'
  18981. })
  18982. ;
  18983. },
  18984. image: function(src) {
  18985. $module
  18986. .attr('src', src)
  18987. ;
  18988. if(settings.transition) {
  18989. if( $.fn.transition !== undefined ) {
  18990. $module.transition(settings.transition, settings.duration);
  18991. }
  18992. else {
  18993. $module.fadeIn(settings.duration);
  18994. }
  18995. }
  18996. else {
  18997. $module.show();
  18998. }
  18999. }
  19000. },
  19001. is: {
  19002. onScreen: function() {
  19003. var
  19004. calculations = module.get.elementCalculations()
  19005. ;
  19006. return calculations.onScreen;
  19007. },
  19008. offScreen: function() {
  19009. var
  19010. calculations = module.get.elementCalculations()
  19011. ;
  19012. return calculations.offScreen;
  19013. },
  19014. visible: function() {
  19015. if(module.cache && module.cache.element) {
  19016. return !(module.cache.element.width === 0 && module.cache.element.offset.top === 0);
  19017. }
  19018. return false;
  19019. }
  19020. },
  19021. refresh: function() {
  19022. module.debug('Refreshing constants (width/height)');
  19023. if(settings.type == 'fixed') {
  19024. module.remove.fixed();
  19025. module.remove.occurred();
  19026. }
  19027. module.reset();
  19028. module.save.position();
  19029. if(settings.checkOnRefresh) {
  19030. module.checkVisibility();
  19031. }
  19032. settings.onRefresh.call(element);
  19033. },
  19034. reset: function() {
  19035. module.verbose('Reseting all cached values');
  19036. if( $.isPlainObject(module.cache) ) {
  19037. module.cache.screen = {};
  19038. module.cache.element = {};
  19039. }
  19040. },
  19041. checkVisibility: function(scroll) {
  19042. module.verbose('Checking visibility of element', module.cache.element);
  19043. if( !disabled && module.is.visible() ) {
  19044. // save scroll position
  19045. module.save.scroll(scroll);
  19046. // update calculations derived from scroll
  19047. module.save.calculations();
  19048. // percentage
  19049. module.passed();
  19050. // reverse (must be first)
  19051. module.passingReverse();
  19052. module.topVisibleReverse();
  19053. module.bottomVisibleReverse();
  19054. module.topPassedReverse();
  19055. module.bottomPassedReverse();
  19056. // one time
  19057. module.onScreen();
  19058. module.offScreen();
  19059. module.passing();
  19060. module.topVisible();
  19061. module.bottomVisible();
  19062. module.topPassed();
  19063. module.bottomPassed();
  19064. // on update callback
  19065. if(settings.onUpdate) {
  19066. settings.onUpdate.call(element, module.get.elementCalculations());
  19067. }
  19068. }
  19069. },
  19070. passed: function(amount, newCallback) {
  19071. var
  19072. calculations = module.get.elementCalculations(),
  19073. amountInPixels
  19074. ;
  19075. // assign callback
  19076. if(amount && newCallback) {
  19077. settings.onPassed[amount] = newCallback;
  19078. }
  19079. else if(amount !== undefined) {
  19080. return (module.get.pixelsPassed(amount) > calculations.pixelsPassed);
  19081. }
  19082. else if(calculations.passing) {
  19083. $.each(settings.onPassed, function(amount, callback) {
  19084. if(calculations.bottomVisible || calculations.pixelsPassed > module.get.pixelsPassed(amount)) {
  19085. module.execute(callback, amount);
  19086. }
  19087. else if(!settings.once) {
  19088. module.remove.occurred(callback);
  19089. }
  19090. });
  19091. }
  19092. },
  19093. onScreen: function(newCallback) {
  19094. var
  19095. calculations = module.get.elementCalculations(),
  19096. callback = newCallback || settings.onOnScreen,
  19097. callbackName = 'onScreen'
  19098. ;
  19099. if(newCallback) {
  19100. module.debug('Adding callback for onScreen', newCallback);
  19101. settings.onOnScreen = newCallback;
  19102. }
  19103. if(calculations.onScreen) {
  19104. module.execute(callback, callbackName);
  19105. }
  19106. else if(!settings.once) {
  19107. module.remove.occurred(callbackName);
  19108. }
  19109. if(newCallback !== undefined) {
  19110. return calculations.onOnScreen;
  19111. }
  19112. },
  19113. offScreen: function(newCallback) {
  19114. var
  19115. calculations = module.get.elementCalculations(),
  19116. callback = newCallback || settings.onOffScreen,
  19117. callbackName = 'offScreen'
  19118. ;
  19119. if(newCallback) {
  19120. module.debug('Adding callback for offScreen', newCallback);
  19121. settings.onOffScreen = newCallback;
  19122. }
  19123. if(calculations.offScreen) {
  19124. module.execute(callback, callbackName);
  19125. }
  19126. else if(!settings.once) {
  19127. module.remove.occurred(callbackName);
  19128. }
  19129. if(newCallback !== undefined) {
  19130. return calculations.onOffScreen;
  19131. }
  19132. },
  19133. passing: function(newCallback) {
  19134. var
  19135. calculations = module.get.elementCalculations(),
  19136. callback = newCallback || settings.onPassing,
  19137. callbackName = 'passing'
  19138. ;
  19139. if(newCallback) {
  19140. module.debug('Adding callback for passing', newCallback);
  19141. settings.onPassing = newCallback;
  19142. }
  19143. if(calculations.passing) {
  19144. module.execute(callback, callbackName);
  19145. }
  19146. else if(!settings.once) {
  19147. module.remove.occurred(callbackName);
  19148. }
  19149. if(newCallback !== undefined) {
  19150. return calculations.passing;
  19151. }
  19152. },
  19153. topVisible: function(newCallback) {
  19154. var
  19155. calculations = module.get.elementCalculations(),
  19156. callback = newCallback || settings.onTopVisible,
  19157. callbackName = 'topVisible'
  19158. ;
  19159. if(newCallback) {
  19160. module.debug('Adding callback for top visible', newCallback);
  19161. settings.onTopVisible = newCallback;
  19162. }
  19163. if(calculations.topVisible) {
  19164. module.execute(callback, callbackName);
  19165. }
  19166. else if(!settings.once) {
  19167. module.remove.occurred(callbackName);
  19168. }
  19169. if(newCallback === undefined) {
  19170. return calculations.topVisible;
  19171. }
  19172. },
  19173. bottomVisible: function(newCallback) {
  19174. var
  19175. calculations = module.get.elementCalculations(),
  19176. callback = newCallback || settings.onBottomVisible,
  19177. callbackName = 'bottomVisible'
  19178. ;
  19179. if(newCallback) {
  19180. module.debug('Adding callback for bottom visible', newCallback);
  19181. settings.onBottomVisible = newCallback;
  19182. }
  19183. if(calculations.bottomVisible) {
  19184. module.execute(callback, callbackName);
  19185. }
  19186. else if(!settings.once) {
  19187. module.remove.occurred(callbackName);
  19188. }
  19189. if(newCallback === undefined) {
  19190. return calculations.bottomVisible;
  19191. }
  19192. },
  19193. topPassed: function(newCallback) {
  19194. var
  19195. calculations = module.get.elementCalculations(),
  19196. callback = newCallback || settings.onTopPassed,
  19197. callbackName = 'topPassed'
  19198. ;
  19199. if(newCallback) {
  19200. module.debug('Adding callback for top passed', newCallback);
  19201. settings.onTopPassed = newCallback;
  19202. }
  19203. if(calculations.topPassed) {
  19204. module.execute(callback, callbackName);
  19205. }
  19206. else if(!settings.once) {
  19207. module.remove.occurred(callbackName);
  19208. }
  19209. if(newCallback === undefined) {
  19210. return calculations.topPassed;
  19211. }
  19212. },
  19213. bottomPassed: function(newCallback) {
  19214. var
  19215. calculations = module.get.elementCalculations(),
  19216. callback = newCallback || settings.onBottomPassed,
  19217. callbackName = 'bottomPassed'
  19218. ;
  19219. if(newCallback) {
  19220. module.debug('Adding callback for bottom passed', newCallback);
  19221. settings.onBottomPassed = newCallback;
  19222. }
  19223. if(calculations.bottomPassed) {
  19224. module.execute(callback, callbackName);
  19225. }
  19226. else if(!settings.once) {
  19227. module.remove.occurred(callbackName);
  19228. }
  19229. if(newCallback === undefined) {
  19230. return calculations.bottomPassed;
  19231. }
  19232. },
  19233. passingReverse: function(newCallback) {
  19234. var
  19235. calculations = module.get.elementCalculations(),
  19236. callback = newCallback || settings.onPassingReverse,
  19237. callbackName = 'passingReverse'
  19238. ;
  19239. if(newCallback) {
  19240. module.debug('Adding callback for passing reverse', newCallback);
  19241. settings.onPassingReverse = newCallback;
  19242. }
  19243. if(!calculations.passing) {
  19244. if(module.get.occurred('passing')) {
  19245. module.execute(callback, callbackName);
  19246. }
  19247. }
  19248. else if(!settings.once) {
  19249. module.remove.occurred(callbackName);
  19250. }
  19251. if(newCallback !== undefined) {
  19252. return !calculations.passing;
  19253. }
  19254. },
  19255. topVisibleReverse: function(newCallback) {
  19256. var
  19257. calculations = module.get.elementCalculations(),
  19258. callback = newCallback || settings.onTopVisibleReverse,
  19259. callbackName = 'topVisibleReverse'
  19260. ;
  19261. if(newCallback) {
  19262. module.debug('Adding callback for top visible reverse', newCallback);
  19263. settings.onTopVisibleReverse = newCallback;
  19264. }
  19265. if(!calculations.topVisible) {
  19266. if(module.get.occurred('topVisible')) {
  19267. module.execute(callback, callbackName);
  19268. }
  19269. }
  19270. else if(!settings.once) {
  19271. module.remove.occurred(callbackName);
  19272. }
  19273. if(newCallback === undefined) {
  19274. return !calculations.topVisible;
  19275. }
  19276. },
  19277. bottomVisibleReverse: function(newCallback) {
  19278. var
  19279. calculations = module.get.elementCalculations(),
  19280. callback = newCallback || settings.onBottomVisibleReverse,
  19281. callbackName = 'bottomVisibleReverse'
  19282. ;
  19283. if(newCallback) {
  19284. module.debug('Adding callback for bottom visible reverse', newCallback);
  19285. settings.onBottomVisibleReverse = newCallback;
  19286. }
  19287. if(!calculations.bottomVisible) {
  19288. if(module.get.occurred('bottomVisible')) {
  19289. module.execute(callback, callbackName);
  19290. }
  19291. }
  19292. else if(!settings.once) {
  19293. module.remove.occurred(callbackName);
  19294. }
  19295. if(newCallback === undefined) {
  19296. return !calculations.bottomVisible;
  19297. }
  19298. },
  19299. topPassedReverse: function(newCallback) {
  19300. var
  19301. calculations = module.get.elementCalculations(),
  19302. callback = newCallback || settings.onTopPassedReverse,
  19303. callbackName = 'topPassedReverse'
  19304. ;
  19305. if(newCallback) {
  19306. module.debug('Adding callback for top passed reverse', newCallback);
  19307. settings.onTopPassedReverse = newCallback;
  19308. }
  19309. if(!calculations.topPassed) {
  19310. if(module.get.occurred('topPassed')) {
  19311. module.execute(callback, callbackName);
  19312. }
  19313. }
  19314. else if(!settings.once) {
  19315. module.remove.occurred(callbackName);
  19316. }
  19317. if(newCallback === undefined) {
  19318. return !calculations.onTopPassed;
  19319. }
  19320. },
  19321. bottomPassedReverse: function(newCallback) {
  19322. var
  19323. calculations = module.get.elementCalculations(),
  19324. callback = newCallback || settings.onBottomPassedReverse,
  19325. callbackName = 'bottomPassedReverse'
  19326. ;
  19327. if(newCallback) {
  19328. module.debug('Adding callback for bottom passed reverse', newCallback);
  19329. settings.onBottomPassedReverse = newCallback;
  19330. }
  19331. if(!calculations.bottomPassed) {
  19332. if(module.get.occurred('bottomPassed')) {
  19333. module.execute(callback, callbackName);
  19334. }
  19335. }
  19336. else if(!settings.once) {
  19337. module.remove.occurred(callbackName);
  19338. }
  19339. if(newCallback === undefined) {
  19340. return !calculations.bottomPassed;
  19341. }
  19342. },
  19343. execute: function(callback, callbackName) {
  19344. var
  19345. calculations = module.get.elementCalculations(),
  19346. screen = module.get.screenCalculations()
  19347. ;
  19348. callback = callback || false;
  19349. if(callback) {
  19350. if(settings.continuous) {
  19351. module.debug('Callback being called continuously', callbackName, calculations);
  19352. callback.call(element, calculations, screen);
  19353. }
  19354. else if(!module.get.occurred(callbackName)) {
  19355. module.debug('Conditions met', callbackName, calculations);
  19356. callback.call(element, calculations, screen);
  19357. }
  19358. }
  19359. module.save.occurred(callbackName);
  19360. },
  19361. remove: {
  19362. fixed: function() {
  19363. module.debug('Removing fixed position');
  19364. $module
  19365. .removeClass(className.fixed)
  19366. .css({
  19367. position : '',
  19368. top : '',
  19369. left : '',
  19370. zIndex : ''
  19371. })
  19372. ;
  19373. },
  19374. occurred: function(callback) {
  19375. if(callback) {
  19376. var
  19377. occurred = module.cache.occurred
  19378. ;
  19379. if(occurred[callback] !== undefined && occurred[callback] === true) {
  19380. module.debug('Callback can now be called again', callback);
  19381. module.cache.occurred[callback] = false;
  19382. }
  19383. }
  19384. else {
  19385. module.cache.occurred = {};
  19386. }
  19387. }
  19388. },
  19389. save: {
  19390. calculations: function() {
  19391. module.verbose('Saving all calculations necessary to determine positioning');
  19392. module.save.direction();
  19393. module.save.screenCalculations();
  19394. module.save.elementCalculations();
  19395. },
  19396. occurred: function(callback) {
  19397. if(callback) {
  19398. if(module.cache.occurred[callback] === undefined || (module.cache.occurred[callback] !== true)) {
  19399. module.verbose('Saving callback occurred', callback);
  19400. module.cache.occurred[callback] = true;
  19401. }
  19402. }
  19403. },
  19404. scroll: function(scrollPosition) {
  19405. scrollPosition = scrollPosition + settings.offset || $context.scrollTop() + settings.offset;
  19406. module.cache.scroll = scrollPosition;
  19407. },
  19408. direction: function() {
  19409. var
  19410. scroll = module.get.scroll(),
  19411. lastScroll = module.get.lastScroll(),
  19412. direction
  19413. ;
  19414. if(scroll > lastScroll && lastScroll) {
  19415. direction = 'down';
  19416. }
  19417. else if(scroll < lastScroll && lastScroll) {
  19418. direction = 'up';
  19419. }
  19420. else {
  19421. direction = 'static';
  19422. }
  19423. module.cache.direction = direction;
  19424. return module.cache.direction;
  19425. },
  19426. elementPosition: function() {
  19427. var
  19428. element = module.cache.element,
  19429. screen = module.get.screenSize()
  19430. ;
  19431. module.verbose('Saving element position');
  19432. // (quicker than $.extend)
  19433. element.fits = (element.height < screen.height);
  19434. element.offset = $module.offset();
  19435. element.width = $module.outerWidth();
  19436. element.height = $module.outerHeight();
  19437. // store
  19438. module.cache.element = element;
  19439. return element;
  19440. },
  19441. elementCalculations: function() {
  19442. var
  19443. screen = module.get.screenCalculations(),
  19444. element = module.get.elementPosition()
  19445. ;
  19446. // offset
  19447. if(settings.includeMargin) {
  19448. element.margin = {};
  19449. element.margin.top = parseInt($module.css('margin-top'), 10);
  19450. element.margin.bottom = parseInt($module.css('margin-bottom'), 10);
  19451. element.top = element.offset.top - element.margin.top;
  19452. element.bottom = element.offset.top + element.height + element.margin.bottom;
  19453. }
  19454. else {
  19455. element.top = element.offset.top;
  19456. element.bottom = element.offset.top + element.height;
  19457. }
  19458. // visibility
  19459. element.topVisible = (screen.bottom >= element.top);
  19460. element.topPassed = (screen.top >= element.top);
  19461. element.bottomVisible = (screen.bottom >= element.bottom);
  19462. element.bottomPassed = (screen.top >= element.bottom);
  19463. element.pixelsPassed = 0;
  19464. element.percentagePassed = 0;
  19465. // meta calculations
  19466. element.onScreen = (element.topVisible && !element.bottomPassed);
  19467. element.passing = (element.topPassed && !element.bottomPassed);
  19468. element.offScreen = (!element.onScreen);
  19469. // passing calculations
  19470. if(element.passing) {
  19471. element.pixelsPassed = (screen.top - element.top);
  19472. element.percentagePassed = (screen.top - element.top) / element.height;
  19473. }
  19474. module.cache.element = element;
  19475. module.verbose('Updated element calculations', element);
  19476. return element;
  19477. },
  19478. screenCalculations: function() {
  19479. var
  19480. scroll = module.get.scroll()
  19481. ;
  19482. module.save.direction();
  19483. module.cache.screen.top = scroll;
  19484. module.cache.screen.bottom = scroll + module.cache.screen.height;
  19485. return module.cache.screen;
  19486. },
  19487. screenSize: function() {
  19488. module.verbose('Saving window position');
  19489. module.cache.screen = {
  19490. height: $context.height()
  19491. };
  19492. },
  19493. position: function() {
  19494. module.save.screenSize();
  19495. module.save.elementPosition();
  19496. }
  19497. },
  19498. get: {
  19499. pixelsPassed: function(amount) {
  19500. var
  19501. element = module.get.elementCalculations()
  19502. ;
  19503. if(amount.search('%') > -1) {
  19504. return ( element.height * (parseInt(amount, 10) / 100) );
  19505. }
  19506. return parseInt(amount, 10);
  19507. },
  19508. occurred: function(callback) {
  19509. return (module.cache.occurred !== undefined)
  19510. ? module.cache.occurred[callback] || false
  19511. : false
  19512. ;
  19513. },
  19514. direction: function() {
  19515. if(module.cache.direction === undefined) {
  19516. module.save.direction();
  19517. }
  19518. return module.cache.direction;
  19519. },
  19520. elementPosition: function() {
  19521. if(module.cache.element === undefined) {
  19522. module.save.elementPosition();
  19523. }
  19524. return module.cache.element;
  19525. },
  19526. elementCalculations: function() {
  19527. if(module.cache.element === undefined) {
  19528. module.save.elementCalculations();
  19529. }
  19530. return module.cache.element;
  19531. },
  19532. screenCalculations: function() {
  19533. if(module.cache.screen === undefined) {
  19534. module.save.screenCalculations();
  19535. }
  19536. return module.cache.screen;
  19537. },
  19538. screenSize: function() {
  19539. if(module.cache.screen === undefined) {
  19540. module.save.screenSize();
  19541. }
  19542. return module.cache.screen;
  19543. },
  19544. scroll: function() {
  19545. if(module.cache.scroll === undefined) {
  19546. module.save.scroll();
  19547. }
  19548. return module.cache.scroll;
  19549. },
  19550. lastScroll: function() {
  19551. if(module.cache.screen === undefined) {
  19552. module.debug('First scroll event, no last scroll could be found');
  19553. return false;
  19554. }
  19555. return module.cache.screen.top;
  19556. }
  19557. },
  19558. setting: function(name, value) {
  19559. if( $.isPlainObject(name) ) {
  19560. $.extend(true, settings, name);
  19561. }
  19562. else if(value !== undefined) {
  19563. settings[name] = value;
  19564. }
  19565. else {
  19566. return settings[name];
  19567. }
  19568. },
  19569. internal: function(name, value) {
  19570. if( $.isPlainObject(name) ) {
  19571. $.extend(true, module, name);
  19572. }
  19573. else if(value !== undefined) {
  19574. module[name] = value;
  19575. }
  19576. else {
  19577. return module[name];
  19578. }
  19579. },
  19580. debug: function() {
  19581. if(settings.debug) {
  19582. if(settings.performance) {
  19583. module.performance.log(arguments);
  19584. }
  19585. else {
  19586. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  19587. module.debug.apply(console, arguments);
  19588. }
  19589. }
  19590. },
  19591. verbose: function() {
  19592. if(settings.verbose && settings.debug) {
  19593. if(settings.performance) {
  19594. module.performance.log(arguments);
  19595. }
  19596. else {
  19597. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  19598. module.verbose.apply(console, arguments);
  19599. }
  19600. }
  19601. },
  19602. error: function() {
  19603. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  19604. module.error.apply(console, arguments);
  19605. },
  19606. performance: {
  19607. log: function(message) {
  19608. var
  19609. currentTime,
  19610. executionTime,
  19611. previousTime
  19612. ;
  19613. if(settings.performance) {
  19614. currentTime = new Date().getTime();
  19615. previousTime = time || currentTime;
  19616. executionTime = currentTime - previousTime;
  19617. time = currentTime;
  19618. performance.push({
  19619. 'Name' : message[0],
  19620. 'Arguments' : [].slice.call(message, 1) || '',
  19621. 'Element' : element,
  19622. 'Execution Time' : executionTime
  19623. });
  19624. }
  19625. clearTimeout(module.performance.timer);
  19626. module.performance.timer = setTimeout(module.performance.display, 500);
  19627. },
  19628. display: function() {
  19629. var
  19630. title = settings.name + ':',
  19631. totalTime = 0
  19632. ;
  19633. time = false;
  19634. clearTimeout(module.performance.timer);
  19635. $.each(performance, function(index, data) {
  19636. totalTime += data['Execution Time'];
  19637. });
  19638. title += ' ' + totalTime + 'ms';
  19639. if(moduleSelector) {
  19640. title += ' \'' + moduleSelector + '\'';
  19641. }
  19642. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  19643. console.groupCollapsed(title);
  19644. if(console.table) {
  19645. console.table(performance);
  19646. }
  19647. else {
  19648. $.each(performance, function(index, data) {
  19649. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  19650. });
  19651. }
  19652. console.groupEnd();
  19653. }
  19654. performance = [];
  19655. }
  19656. },
  19657. invoke: function(query, passedArguments, context) {
  19658. var
  19659. object = instance,
  19660. maxDepth,
  19661. found,
  19662. response
  19663. ;
  19664. passedArguments = passedArguments || queryArguments;
  19665. context = element || context;
  19666. if(typeof query == 'string' && object !== undefined) {
  19667. query = query.split(/[\. ]/);
  19668. maxDepth = query.length - 1;
  19669. $.each(query, function(depth, value) {
  19670. var camelCaseValue = (depth != maxDepth)
  19671. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  19672. : query
  19673. ;
  19674. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  19675. object = object[camelCaseValue];
  19676. }
  19677. else if( object[camelCaseValue] !== undefined ) {
  19678. found = object[camelCaseValue];
  19679. return false;
  19680. }
  19681. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  19682. object = object[value];
  19683. }
  19684. else if( object[value] !== undefined ) {
  19685. found = object[value];
  19686. return false;
  19687. }
  19688. else {
  19689. module.error(error.method, query);
  19690. return false;
  19691. }
  19692. });
  19693. }
  19694. if ( $.isFunction( found ) ) {
  19695. response = found.apply(context, passedArguments);
  19696. }
  19697. else if(found !== undefined) {
  19698. response = found;
  19699. }
  19700. if($.isArray(returnedValue)) {
  19701. returnedValue.push(response);
  19702. }
  19703. else if(returnedValue !== undefined) {
  19704. returnedValue = [returnedValue, response];
  19705. }
  19706. else if(response !== undefined) {
  19707. returnedValue = response;
  19708. }
  19709. return found;
  19710. }
  19711. };
  19712. if(methodInvoked) {
  19713. if(instance === undefined) {
  19714. module.initialize();
  19715. }
  19716. instance.save.scroll();
  19717. instance.save.calculations();
  19718. module.invoke(query);
  19719. }
  19720. else {
  19721. if(instance !== undefined) {
  19722. instance.invoke('destroy');
  19723. }
  19724. module.initialize();
  19725. }
  19726. })
  19727. ;
  19728. return (returnedValue !== undefined)
  19729. ? returnedValue
  19730. : this
  19731. ;
  19732. };
  19733. $.fn.visibility.settings = {
  19734. name : 'Visibility',
  19735. namespace : 'visibility',
  19736. debug : false,
  19737. verbose : false,
  19738. performance : true,
  19739. // whether to use mutation observers to follow changes
  19740. observeChanges : true,
  19741. // check position immediately on init
  19742. initialCheck : true,
  19743. // whether to refresh calculations after all page images load
  19744. refreshOnLoad : true,
  19745. // whether to refresh calculations after page resize event
  19746. refreshOnResize : true,
  19747. // should call callbacks on refresh event (resize, etc)
  19748. checkOnRefresh : true,
  19749. // callback should only occur one time
  19750. once : true,
  19751. // callback should fire continuously whe evaluates to true
  19752. continuous : false,
  19753. // offset to use with scroll top
  19754. offset : 0,
  19755. // whether to include margin in elements position
  19756. includeMargin : false,
  19757. // scroll context for visibility checks
  19758. context : window,
  19759. // visibility check delay in ms (defaults to animationFrame)
  19760. throttle : false,
  19761. // special visibility type (image, fixed)
  19762. type : false,
  19763. // image only animation settings
  19764. transition : 'fade in',
  19765. duration : 1000,
  19766. // array of callbacks for percentage
  19767. onPassed : {},
  19768. // standard callbacks
  19769. onOnScreen : false,
  19770. onOffScreen : false,
  19771. onPassing : false,
  19772. onTopVisible : false,
  19773. onBottomVisible : false,
  19774. onTopPassed : false,
  19775. onBottomPassed : false,
  19776. // reverse callbacks
  19777. onPassingReverse : false,
  19778. onTopVisibleReverse : false,
  19779. onBottomVisibleReverse : false,
  19780. onTopPassedReverse : false,
  19781. onBottomPassedReverse : false,
  19782. // utility callbacks
  19783. onUpdate : false, // disabled by default for performance
  19784. onRefresh : function(){},
  19785. metadata : {
  19786. src: 'src'
  19787. },
  19788. className: {
  19789. fixed : 'fixed',
  19790. placeholder : 'placeholder'
  19791. },
  19792. error : {
  19793. method : 'The method you called is not defined.',
  19794. visible : 'Element is hidden, you must call refresh after element becomes visible'
  19795. }
  19796. };
  19797. })( jQuery, window , document );