diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b2de9cc --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/whois +/whois/* \ No newline at end of file diff --git a/CHANGES b/classes/CHANGES similarity index 96% rename from CHANGES rename to classes/CHANGES index 20cce4b..1b7e176 100644 --- a/CHANGES +++ b/classes/CHANGES @@ -1,1063 +1,1063 @@ -2011/07/09 - - html & cosmetic changes in examples - - released version 4.2.2 - -2011/07/08 - - fixes for arin (bug #3339783) - - fixed .nl handler (bug #3314404) - - fixed .ae whois server (bug #3354286) - - fixed bug #3333558 - - .uk handler improvement (partial patch #3314417) - - added support for .gt domains (request #3353926) - - cosmetic fixes to many handlers (removed unuseful - spaces, removed change history, regyinfo position - unification,...) - - cira.ca,nicline are non UTF8 - -2011/06/26 - - added handler for gandi (request #3155752) - - added handler for .cl - - corrected utf-8 support for .hu, .br and ripe - - fixes for .pl, .org.za, .be, .cz, .de, .fj, .it, .ch - handlers - - nameservers are automatically searched if missing - -2011/06/24 - - fixed .be handler (bug #3307363) - - fixed ip.lacnic handler array handling - - fixed .eu hanlder (bug #3297823) - - fixed .ae handler (bug #3181964) - - fixed .uk handler (partial patch # 3314417) - - fixed .ru handler (bug #3178123) - - added handler for .ir - -2011/01/26 - - fixed .se handler (bug #3165639) - -2011/01/24 - - fixed .pe server (bug #3164251) - -2011/01/17 - - fixed .co handler (bug #3159317) - - fixed .ca handler (bug #3141475) - -2010/12/06 - - fixed .ca handler - -2010/12/03 - - fixed .pl handler - -2010/11/29 - - fixed .de handler - -2010/11/22 - - added handler for corporatedomains (Kyle Brost) - -2010/11/05 - - added support for .ke domains - -2010/09/20 - - released version 4.2.1 - - provided default object data for unsupported domains - -2010/09/16 - - fixed .si handler - -2010/08/26 - - UseServer can now be used for ip addresses - -2010/08/24 - - removed dangerous exec call - -2010/08/23 - - improved extra whois parameters for better - support of .jp whois - - added handler for .jp - - added handler for .co - - added ipv6 support - -2010/08/10 - - joined common whois field list - - some minor fixes - - testsuite can now test specific handlers - - fixed iana handler - - improved generic_parser_b - - removed .es handler - -2010/07/27 - - better AS support - - ip handlers rewritten - -2010/07/21 - - added dnssec info to domain object - - parser improved - - better support for some non utf-8 servers - - removed buydomains handler - - added afternic handler - - fixes for many handlers - -2010/07/20 - - fixed arin new query format - - better ip refferal whois follow-up - - avoid double rwhois queries - -2010/05/20 - - added gtld handlers for domainpeople,dremhost,fastdomain, - marmonitor & names4ever (by Brandon Whaley) - -2010/04/28 - - fixed gtld handler: some registrars give no information - on pendingdelete domains that could appear as unregistered - - fixed bug #2991358 (owner not correctly set for .at domains) - - fixed bug #2991270 (added extra incorrect nameserver - on .eu domains) - - fixed bug #2991265 (.org organization not parsed) - -2010/04/13 - - added .ly handler - - added .fj handler - -2009/12/29 - - released version 4.2.0 - - added handler for .tel - - new easy_parser funtion applied to many handlers - - fixes for several handlers - - stargateinc handler moved to namevault - - itsyourdomain seems to be now tucows - - domainbank is now handled by dotster - - domaincontender is now assorted - - fixed bug #2888773 validip function uses undefined variable - - improved .eu domain registration status detection - - fixes for html nice output and utf-8 support - -2008/10/10 - - fixed bug #2153003 - - fixed bug #2153380 Bad info for joker.com domain owners - -2008/09/07 - - check network nserver too - - added suport for spanish dates - - fixed ws handler - -2008/08/29 - - fixed 'bold' regex and removed extra - blank lines in showHTML result - -2008/08/28 - - fixed namespace in whois.ip.lib.php - - allow to specify full url in showHTML result - -2008/08/20 - - added .ve handler by jlchafardet - - fixed some handlers reporting 'bill' instead of 'billing' - - added helper functions for some handlers - - fixed .au handler - -2008/08/11 - - fixed .es handler - -2008/07/08 - - added handler for .su - -2008/06/30 - - added handler for .fi - -2008/06/26 - - added handler for .asia - -2008/06/25 - - fixed hangup bug on some non-responding rwhois - servers (read result changed to non-blocking) - -2008/06/16 - - added support & handler for .me - -2008/06/16 - - fixed .fr handler - -2008/06/11 - - fixed .cz handler registered date - - fixed .fr handler - - added .ro handler - -2008/05/28 - - added handler for .it - - added handler for .fr - -2008/05/17 - - Added support for .ve - - Released version 4.1.3 - -2008/05/11 - - fixed whois.museum - -2008/05/09 - - do not use handlers on error - -2008/05/04 - - improved nameserver detection (again) - - fixed whois.pl, whois.gtld.nominalia, - whois.gtld.onlinenic, whois.ovh - - removed test for informe.ws - - minor fix to whois.gtld.enom - - minor chages to other handlers - -2008/04/29 - - improved nameserver detection (again) - - fixes & improvements on whois.mx - -2008/04/28 - - whois.za.php renamed to whois.zanet.php - - added support & handler for .org.za - - added handler for .co.za - - minor improvemts on whois.client.php to allow - handlers for second level domains - - improved nameserver detection - - minor fix to .ie handler - -2008/03/05 - - dotregistrar is now part of dotster - - fixes in date parser - - .cz handler update - - fixed .ch whois server detection - -2007/12/21 - - fixed uninitialized variable in example.php - - fixes in publicdomainregistry and uk handlers - - improved regex for html output - - added support for centralnic domains - - added handler for .pt and .ae (pacth #1709470) - - fixed bug #1761156 - - applied patch #1749389 - -2007/05/30 - - removed support for .gr domains - -2007/05/24 - - uniform way to specify query array - -2007/05/09 - - fixed reporting of ip query information - -2007/05/04 - - fixes to ip handler and APNIC ip handler - -2007/05/03 - - minox fix in whois.gtld.publicdomainregistry.php - - removed unused handler whois.gtld.directi.php - -2007/04/30 - - fixed tucows/opensrs gtld handler detection - - more improvements and cleanup of whois.parser.php - - added gtld handler for Fabulous - -2007/04/29 - - several improvments on whois.parser - - several handlers fixed to work with improved parser - - added gtld handler for NameKing - -2007/04/27 - - rearranged regyinfo array - - better info reporting on ip whois - -2007/04/26 - - restrict .com/.net searches to domains - - regyinfo now contains a list of all servers - servers contacted in key 'servers' - - improvements in contact data detection in - whois.parser - - added gtld handler for OnlineNIC - -2007/04/24 - - added gtld handler for Wild West Domains - - utf8 fixes in example.php - -2007/04/23 - - added gtld handler for RRPPROXY - -2007/04/21 - - added gtld handler for NICCO - -2007/04/20 - - fixes and improvments in .pl handler - - improved IDNA support - -2007/04/18 - - fixed warnings in nicline and tmagnic gtld handlers - - added support for IDNA (internationalized) domains names - as defined in RFC3490, RFC3491, RFC3492 and RFC3454 - using Matthias Sommerfeld idna_convert class - -2007/04/17 - - allow easy plugin for new gtld handlers - - minor improvement to testsuite.php - - fixed .se handler - - namesdirect has joined with dotster - - fixed tmagnic gtld handler - -2007/04/16 - - added basic support for .bz - - whois.info.php cosmetic changes - - added .ru handler - - support for multiple status lines in whois.org.php and - whois.gtl.php - - removed whois.gtld.chdom handler - - allow easy plugin for new country handlers - - minor improvement to whois.client.php and - whois.parser.php - - added gtld handler for OVH - -2007/04/06 - - fixed error in whois.ip.php - -2007/03/30 - - minor fix on whois.ip.php - -2007/03/28 - - some handlers where not seeting rawdata - -2007/03/19 - - Fixed nic.br ip handler detection - -2007/03/05 - - fixed .cat registered yes/no detection - -2007/03/02 - - minor fix to .eu handler - - fixes in arin ip handler - -2007/02/06 - - changed the way gTLD handlers are detected - -2006/12/21 - - fix/improvement for register.com handler - -2006/12/20 - - Released version 4.1.2 - -2006/12/19 - - minor fixes to testsuite.php, whois.parser.php, - whois.gtld.joker.php, whois.gtld.enom.php and - whois.gtld.tvcorp.php - - updated .nl handler - - enom has mixed with bulregister, so bulkr - gtl handler has been removed - -2006/12/18 - - minor fixes to whois.ca.php, whois.es.php, - whois.gtld.iana.php, whois.gtld.opensrsnet.php, - whois.ip.apnic.php, whois.biz.php, - whois.gtld.psiusa.php, whois.parser.php, - and whois.ch.php - - updated .lthandler - - added support and handler for .jobs - -2006/09/29 David Saez - - Fixed .in whois server name - - Added handler for .in - - Added gtld handler for psiusa (Patch #1539553) - - Fixed .za.net handler - - testsuite domain listed updated - - ip handler improvments from bug #1533099 - -2006/09/07 David Saez - - Fixed register.com owner detection - -2006/08/02 David Saez - - Fixed bug #1495871: failed to open stream - -2006/07/25 David Saez - - enabled again .es handler - -2006/06/23 David Saez - - fixed warning in whois.ip.afrinic - - added handler for .nz - - disabled .es handler - - Released version 4.1.1 - -2006/06/19 David Saez - - better handling of errors in whois.ip.php - -2006/06/12 David Saez - - More PHP5 friendly (from Bug #1502777) - - rawdata reflects all rwhois output - - added suport and handler for .mobi - -2006/05/31 David Saez - - Fixed bug #1495389 - -2006/05/16 David Saez - - added handler for .sc (thanx to - Hans-Peter Kohnle) - -2006/05/08 David Saez - - fixed exmaple.php - - fixed .pl and .de handler - -2006/04/29 David Saez - - improved .edu handler - - testsuite finished - - proxy support - - added template for example.php - -2006/04/28 David Saez - - fixed special non handled domains support - - added not supported domain .cy - - fixed typo in test.txt - - fixed directi handler detection - - improved whois.parser - - fixed joker handler - - minor fix to namejuice handler - - fixed krnic handler - -2006/04/08 David Saez - - Added handler for .eu - - Minor fix to example.php - - Improved HTML output - -2006/04/05 David Saez - - Added support for EPP status (bug #1463866) - -2006/04/03 David Saez - - fixed timestamp style date detection - -2006/03/29 David Saez - - fixed bad rwhois server/port detection - - added optional suport for non ICANN tld's - -2006/03/24 David Saez - - added handler for NAMESDIRECT - - fixed register.com handler - -2006/03/21 David Saez - - Fixed problems with some domains registered - at enom - -2006/03/20 David Saez - - Aplied fix to bug #1453935 - -2006/03/19 David Saez - - added gtld handler for namejuice - (thanx to Robert Apgood ) - - example.php is now XHTML 1.0 compliant - -2006/03/14 David Saez - - fixed case detection on whois.parser.php - -2006/03/10 David Saez - - added handler for .edu - -2006/03/07 David Saez - - added gtld handler for alldomains - - more improvemnts on whois.parser.php - -2006/03/06 David Saez - - added gtld handler for nominalia - -2006/03/05 David Saez - - fixed .de handler - - .ca handler fixed and updated - -2006/03/03 David Saez - - added handler for gtld domaincontender.com - -2006/03/02 David Saez - - added handler for .pl and .ie - - minor fixes in whois.parser.php - -2006/02/27 David Saez - - minor fixes for non-existing .es domains - - fixed ip2long PHP5 compatibility - - fixed sponsor detection on opensrsnet handler - -2006/02/13 David Saez - - fixed nserver detection in whois.es.php - -2006/02/03 Released phpWhois 4.1.0 - -2006/02/03 David Saez - - fixed README documentation - - minor fixes to some handlers - -2006/02/01 David Saez - - fixed README documentation - - improved .au handler for user with - whois-check.ausregistry.net.au - - added testsuite for verifying handlers - -2006/01/31 David Saez - - fixed lookup error on .co.za domains - - minor fix to whois.pareser.php - -2006/01/27 David Saez - - added deep_whois feature to get faster but - less acurate results - -2006/01/24 David Saez - - minor fixes to .es handler - -2006/01/20 David Saez - - changed .es http based whois server - - added function to set specific whois servers - - updated .es handler - - formating fixes in whois.parser.php - - added handler for .cat - -2006/01/18 David Saez - - minor fixes in enom handler - -2006/01/13 David Saez - - updated .uk handler - -2005/12/11 David Saez - - fixed some warnings in .de handler and - added timeout detection - -2005/12/10 David Saez - - fixed html output broken links - -2005/12/01 David Saez - - fixed php warning with limbo domains in netsol - -2005/11/21 David Saez - - added support for .pr domains - - fixed warning in whois.ip.afrinic.php - - added detection for netblocks transferred - from RIPE to AFRINIC - -2005/11/17 David Saez - - added support for .mt domains - -2005/11/14 David Saez - - avoid some warnings on whois.gtld.bulkr.php - -2005/11/11 David Saez - - removed support for .es domains - - some fixes in .uk handler - -2005/11/07 David Saez - - added handler for .int domains - - added support for some other domains - -2005/11/06 David Saez - - added support & handler for .travel - - showHTML made a bit more flexible - -2005/10/31 David Saez - - better windows based php detection - - fixed registro.br detection - -2005/10/21 David Saez - - added handler for Directi - - added handler for .cz domains - -2005/10/20 David Saez - - added handler for gtld IANA - - updated .org handler - -2005/10/15 David Saez - - added missing example for .ag and .name - - added multiple abuse email address detection - in arin ip queries - - avoid adding empty fields in whois.parser.php - - added support and handler for .pro domains - -2005/10/14 David Saez - - clean some messy ripe records - - added handler for .name - -2005/10/12 David Saez - - added compatibility with PHP versions prior 4.3.0 - -2005/10/11 David Saez - - fixed warning for non-existant .es domains - -2005/10/10 David Saez - - fixed some short tags in example.php, - fixed queries to .net whois server, - added support for .pe domains, - fixed .se registration detection, - added requirements section in README, - fix to let it work with PHP 4.1.0 - 4.3.1, - installation clarified - thanx to Speedywise - -2005/10/09 Released phpWhois 4.0.1 - - some files where missing !! - -2005/10/04 David Saez - - fix for address reporting - - added handler for .coop - -2005/09/30 David Saez - - fix for .museum handler - - added handler for .aero - - minor fix for date extraction in whois.parser.php - -2005/09/29 David Saez - - added handler for .museum - -2005/09/27 David Saez - - minor formating fix - - added handler for .lt - -2005/09/13 David Saez - - better error handling in whois.gtld - -2005/09/05 David Saez - - minor code cleaup on whois.gtld.php - - added better support for errors - - added hanlder for .ag - - added ip detection for HTML output - - country tld revision [ax-bx] - -2005/09/01 Released phpWhois 4.0.0 - -2005/08/31 David Saez - - changed behaviour of whois.utils.php - - changed url disclaimer - - added GPL license file - - whois.gtld.bulkr.php rewritten - - last minute fixes - -2005/08/30 David Saez - - changed generic_whois_b item parameter array - - fixes & improvments for rwhois - - AS detection, added regyinfo.type subkey - - added abuse contact detection for ripe - - fixes for .se - -2005/08/29 David Saez - - changed gif icon for a new png one - - recovered better example.php from old - distribution - - utils.whois renamed to whois.utils.php - - removed obsolete FAQ item - - added nice HTML output capabilities to - whois.utils.php - - fixed whois.ip.php - - added extra abuse email address detection - for whois.ip.php - - addeed rwhois recognition for afrinic - -2005/08/26 David Saez - - code cleanup and formatting - - added support form Referral Whois (rwhois) - as per RFC 1714/2167, support is limited, non - recursive and only for ARIN ip space - -2005/08/19 David Saez - - fixed some bad includes - -2005/07/29 David Saez - - fixed problem with lastest changes in whois.ip - -2005/07/28 David Saez - - modified $query parameter for parse function - -2005/07/27 David Saez - - genutil, generic2 and getdate moved to - whois.parser.php - - cli_example.php renamed to example.cli.php - - added handler.template.php - - disclaimer updated - - updated README file - - some improvments for AS queries - - some handlers reported zcode instead of pcode - - added support for AfriNIC (ip whois) - - updated HANDLERS documentation - - added support for CHINESEDOMAINS - -2005/07/26 David Saez - - added handler for za.org & za.net, thanx to - luca@clamav.net - - generic3.whois code moved to whois.parser.php - -2005/07/25 David Saez - - removed unused file denic.whois - - added support for za.net and za.org, thanx - to luca@clamav.net - - rewritte of .uk handler - - whois client code moved to whois.client.php - - class inheritence revised - - generic.whois moved to whois.parser.php - -2005/07/22 David Saez - - added CDIR to inetnum conversion for ip whois and - fixed brnic detection - - changed naming schema for gtld handlers - -2005/07/19 David Saez - - changes on methods and variables of Whois class - -2005/07/17 David Saez - - changed naming schema for country handlers - -2005/07/16 David Saez - - normalized expired/created/chaged dates - - report non existant dns servers - - improved getdate.whois - - fixed benic.whois - - improvements to genric whois handling - - improvments & fixes to esnic, denic and brnic - handlers - - added configurable timeout for sockec communications - - changed naming schema for ip handlers - -2005/04/28 David Saez - - Fixed .fm handling - - normalized expired/created/chaged dates - - changed the way nservers are normalized - - some fixes - - adde CLI mode example - -2005/03/14 David Saez - - added handler for TV CORPORATION - -2005/03/03 David Saez - - minor fix to main.whois - - added some object fields when not set - - fixed handling of .tv - -2005/03/02 David Saez - - fixed SRSPlus detection - - applied patch [ 981413 ] Whois Parameter Array - thanx to mwelters - - added better reporting on nameservers - - better email reporting on generic3.whois - -2005/03/01 David Saez - - fixed Network Solutions detection - - ordered list of handlers in gtld.whois - - added handler for Moniker - - added handler for Innerwise - - added handler for Stargate - - added handler for Cronon - - added handler for Joker - - fixed scripts using php short tags - thanx to rpm@keynetics.com - - added handler for Schlund - -2004/08/06 David Saez - - fixed denic.whois when domain does not - exist, thanx to bjoern@xrow.de - -2004/04/24 David Saez - - added .is handler - - added some notes about generic support functions - in HANDLERS - -2004/04/23 David Saez - - Fixed ending tag in all files - -2004/04/22 David Saez - - added handler for .us , thanx to - snguyen@mbaassociation.org - - correctly sets regyinfo.whois - - added hack for .net.au , thanx to - thill@gumnut.com.au - - implemented request id 757465 - - fixed bug 690623 - - fixed bug 804595 - - added feature request 759788 - - added .bg http whois mserver - - added .hu handler - -2004/04/21 David Saez - - fixed small bug in netsol.whois - - improvments and fixes to gtld.whois, thanx to - snguyen@mbaassociation.org - -2004/02/11 David Saez - - handles R120-LROR, thanx to DavHolle - -2003/11/22 David Saez - - fix for .tv domains - -2003/10/27 David Saez - - minor improvments to main.whois - - fix for .in domains - -2003/10/01 Ross Golder - - Released phpWhois version 3.0.6 - -2003/09/20 David Saez - - minor improvment to esnic.whois - -2003/09/13 David Saez - - minor improvment to org.whois - -2003/09/12 David Saez - - added gtld handler for Arsys nicline - thanx to cgalvez@espaciowww.com - - minor fixes to main.whois and gtld.whois - -2003/09/09 David Saez - - fixed some warning when ip is banned - on domainbank.whois - - main.whois also sets regyinfo.whois on http - queries - - rewrite of esnic.whois - -2003/09/08 David Saez - - rewrite of cnnic.whois - - some fixes to wsnic.whois - - some fixes to gtld.whois and generic3.whois - - added handler for Godady and Domain Bank - - minor improvment to main.whois and generic2.whois - - added handler for .org - -2003/09/06 David Saez - - Added handlers for .cn and .ws - thanx to zingfharn@fastmail.fm - - Fixed main.whois to allow https queries - - Enabled .es queries but handler remains - disabled because needs total rewrite - -2003/08/04 David Saez - - Temporary deactivation of .es handler due to - changes in .es registry whois system - - Fixed denic.whois, thanks to - Gulibert@NetGameZone.de - -2003/06/30 David Saez - - added handler for .be, thanx to - onveilig@hotmail.com - -2003/06/04 Ross Golder - - Removed a blank line preventing headers from - being sent. - -2003/04/25 David Saez - - added support for web based whois for - .tc, .vg, .ms, .gs and .tf domains - -2003/04/19 David Saez - - fixed problem with whois.crsnic.net which - causes some domains like hotmail.com and - yahoo.com not to resolve, thanx to - asajith@users.sourceforge.net for reporting - this issue, also some improvments have been - made to help diagnose problems like that in - the future - -2003/04/11 David Saez - - added gtld handler for SRSPlus - -2003/04/07 Mark Jeftovic - - fix for missing checkdnsrr function in windows - -2003/04/04 David Saez - - added handler for .fm - -2003/03/30 David Saez - - recovered 'powered by phpWhois' logo - - added handlers for directnic and buydomains - - minor improvment to generic3.whois - - minor fixes to bripw.whois - -2003/03/26 David Saez - - some improvments on generic3.whois - - added handler for ascio (com/org) - -2003/03/22 David Saez - - referrer correction and normalization in some handlers - - removed unused handler cdnnet.whois - -2003/03/22 Ross Golder - - Release 3.0.4 available now - -2003/03/17 David Saez - - chnic.whois & nlnic.whois rewritten - - minor fix and improvment on generic3.whois - - added nameserver detection to dotregistrar.whois - - minor fix on info.whois - - fixed bripw.whois - - bulkregstercom.whois fixed and updated to common - object model - -2003/03/16 David Saez - - mxnic.whois updated to common object model - - recovered brnic.whois and added bripw.whois - which was implemented over brnic.whois by - mistake - - fixed netsol.whois - -2003/03/12 Ross Golder - - Minor corrections and a note about coding style - on HANDLERS - -2003/03/07 David Saez - - added lacnic.whois - - added file HANDLERS - - minor fixes to README - -2003/03/05 David Saez - - implemented krnic.whois - - minor improvments to generic3.whois - -2003/03/04 David Saez - - improvments on ripe.whois - - implemented arin.whois and brnic.whois - - added ip's for testing on ipw.whois - -2003/03/03 David Saez - - some fixes to ip whois - - some fixes to uknic.whois - - implemented ripe.whois - - improved code for html2text for web based whois - -2003/02/26 David Saez - - common object model changes in some handlers - - removed warning in gtld.whois when domain does not exist - - core.whois fixed and updated to common object model - - added corenic .org handle to gtld.whois - -2003/02/25 David Saez - - added interdomain .org handle - - interdomain.whois updated to common object model - -2003/02/19 David Saez - - added dotregistrar .org handle - - some improvments to generic3.whois - - registercom.whois updated to common object model - -2003/02/18 David Saez - - added dotster .org handle - - some improvments to generic3.whois - - dotster.whois & registercom.whois updated to common object model - -2003/02/16 David Saez - - improved generic.whois, update all handlers that use it - - now it's possible to also query http based whois - - added .es handler (http) - - some improvments on generic3.whois - - enom.whois fixed and updated to common object model - - added enom .org handle to gtld.whois - -2003/02/15 David Saez - - added generic3.whois with functions to parse whois output - - added disclaimer to generic.whois and generic2.whois - - opensrsnet.whois updated to common object model - - added mxnic.whois, thanx to torfinn@nome.no - -2003/02/10 David Saez - - inwwcom.whois updated to common object model - - added inwwcom org handle to gtld.whois - - gtld.whois now can get the name of the org registrar - - minor fixes to generic2.whois - -2003/02/09 Ross Golder - - updated to do a 'whois-servers.net' DNS lookup to determine - the tld whois server to query - - David Saez - - netsol.whois & gtld.whois updated to common object model - - fixed some warnings in main.whois - -2003/01/29 David Saez - - fixed nicse.whois and updated to common object model - -2003/01/27 David Saez - - fixed nunames.whois and updated to common object model - -2003/01/26 David Saez - - fixed lunic.whois and updated to common object model - - neulevel.whois changed to use generic2.whois - - some minor fixes on info.whois - -2003/01/25 David Saez - - info.whois updated to common object model - -2003/01/19 David Saez - - fixed denic.whois - -2003/01/18 David Saez - - added nlnic.whois, thanx to Matthijs Koot - - fixed some warnings on generic.whois - - fixed double processing on atnic.whois - -2002/12/16 David Saez - - updated aunic.whois - - improved generic.whois & generic2.whois - - fixed uninitialized variable in utils.whois - -2002/10/16 David Saez - - Updated uknic handler to new Nominet UK whois output - - Added handler for .biz - - Added support to ipw.whois for BRNIC, KRNIC, TWNIC and LACNIC - - Some handlers updated to new common object model - - Added generic.whois and generic2.whois with parse functions - for two kinds of whois output commonly used - -2002/10/11 Ross Golder - - Merged in as many useful patches as possible (supplied by Mark) - - Re-indented the classes for clarity - - Attempted to add comments to as much code as possible - -2001/02/28 - -batch add of many updates - -uknic.whois updated by David Saez Padros - -added dotster and chnic for .ch and .li, also by David Saez Padros - -.at whois server now whois.nic.at - -2000/12/12 -v2.3 -PHP4 BUG IS FIXED!!!! Very special thanks to all who submitted - fixes, used one provided by Stephen Leavitt - as it was the easiest and backwards - compatible to PHP3 - -added Enom handler, also by Stephen Leavitt - - -changed .ca whois to whois.cira.ca, using same handler for now. -2000/08/14 - -added brnic.whois country handler - -major revision of servers.whois, many adds (crossreferenced - against geektools list at - http://www.geektools.com/dist/whoislist.gz) - -dropped all ORSC TLD's, either their whois servers weren't - working or it was clear there was no functioning registry - if they were. (From here on in we stick to the IANA - legacy root TLD's) -2000/08/07 -v2.2-3 -gtld.whois, "TUCOWS.COM INC." now, "TUCOWS.COM, INC." - an unannounced change by the NSI registry once again - breaks scripts all over the world...(thanks to - Fred Andrews for the report - and fix on this) - -servers.whois, added .ke Kenyan whois server, thanks - to "Peter Anampiu" for digging that up.:x - -2000/05/27 -v2.2-2 -ouch! params in implode() are backwards - -2000/04/06 -v2.2-1 -new classes for bulkregister, openSRS and melbourneIT - by Jeremiah Bellomy - -2000/03/16 -v2.1-4 -servers.whois, added .st - -2000/03/08 -v2.1-4 -servers.whois, fixed .no address, added .as - -2000/01/26 -v2.1-4 -main.whois -fixed Connect() so it wouldn't attempt to connect - to an unset server (Query["server"] is null on - pass 2 if domain isn't in the registry whois) - -added rudimentry "not found" code to sample script - -2000/01/02 -v2.1-3 -main.whois -fixed GetTld() so "churchuk.com" 's tld wouldn't - mistakenly be set to nominet's "uk.com" tld. - -fixed Lookup() was always using char by char reads - regardless of $this->BUFFER value -servers.whois -added nominet's se.com, se.net and no.com - -2000/01/01 -2.1-2 -main.whois -fixed Process() so it would only include the handler if - it wasn't already defined. Trying queries inside a loop - would fail on the second iteration. - +2011/07/09 + - html & cosmetic changes in examples + - released version 4.2.2 + +2011/07/08 + - fixes for arin (bug #3339783) + - fixed .nl handler (bug #3314404) + - fixed .ae whois server (bug #3354286) + - fixed bug #3333558 + - .uk handler improvement (partial patch #3314417) + - added support for .gt domains (request #3353926) + - cosmetic fixes to many handlers (removed unuseful + spaces, removed change history, regyinfo position + unification,...) + - cira.ca,nicline are non UTF8 + +2011/06/26 + - added handler for gandi (request #3155752) + - added handler for .cl + - corrected utf-8 support for .hu, .br and ripe + - fixes for .pl, .org.za, .be, .cz, .de, .fj, .it, .ch + handlers + - nameservers are automatically searched if missing + +2011/06/24 + - fixed .be handler (bug #3307363) + - fixed ip.lacnic handler array handling + - fixed .eu hanlder (bug #3297823) + - fixed .ae handler (bug #3181964) + - fixed .uk handler (partial patch # 3314417) + - fixed .ru handler (bug #3178123) + - added handler for .ir + +2011/01/26 + - fixed .se handler (bug #3165639) + +2011/01/24 + - fixed .pe server (bug #3164251) + +2011/01/17 + - fixed .co handler (bug #3159317) + - fixed .ca handler (bug #3141475) + +2010/12/06 + - fixed .ca handler + +2010/12/03 + - fixed .pl handler + +2010/11/29 + - fixed .de handler + +2010/11/22 + - added handler for corporatedomains (Kyle Brost) + +2010/11/05 + - added support for .ke domains + +2010/09/20 + - released version 4.2.1 + - provided default object data for unsupported domains + +2010/09/16 + - fixed .si handler + +2010/08/26 + - UseServer can now be used for ip addresses + +2010/08/24 + - removed dangerous exec call + +2010/08/23 + - improved extra whois parameters for better + support of .jp whois + - added handler for .jp + - added handler for .co + - added ipv6 support + +2010/08/10 + - joined common whois field list + - some minor fixes + - testsuite can now test specific handlers + - fixed iana handler + - improved generic_parser_b + - removed .es handler + +2010/07/27 + - better AS support + - ip handlers rewritten + +2010/07/21 + - added dnssec info to domain object + - parser improved + - better support for some non utf-8 servers + - removed buydomains handler + - added afternic handler + - fixes for many handlers + +2010/07/20 + - fixed arin new query format + - better ip refferal whois follow-up + - avoid double rwhois queries + +2010/05/20 + - added gtld handlers for domainpeople,dremhost,fastdomain, + marmonitor & names4ever (by Brandon Whaley) + +2010/04/28 + - fixed gtld handler: some registrars give no information + on pendingdelete domains that could appear as unregistered + - fixed bug #2991358 (owner not correctly set for .at domains) + - fixed bug #2991270 (added extra incorrect nameserver + on .eu domains) + - fixed bug #2991265 (.org organization not parsed) + +2010/04/13 + - added .ly handler + - added .fj handler + +2009/12/29 + - released version 4.2.0 + - added handler for .tel + - new easy_parser funtion applied to many handlers + - fixes for several handlers + - stargateinc handler moved to namevault + - itsyourdomain seems to be now tucows + - domainbank is now handled by dotster + - domaincontender is now assorted + - fixed bug #2888773 validip function uses undefined variable + - improved .eu domain registration status detection + - fixes for html nice output and utf-8 support + +2008/10/10 + - fixed bug #2153003 + - fixed bug #2153380 Bad info for joker.com domain owners + +2008/09/07 + - check network nserver too + - added suport for spanish dates + - fixed ws handler + +2008/08/29 + - fixed 'bold' regex and removed extra + blank lines in showHTML result + +2008/08/28 + - fixed namespace in whois.ip.lib.php + - allow to specify full url in showHTML result + +2008/08/20 + - added .ve handler by jlchafardet + - fixed some handlers reporting 'bill' instead of 'billing' + - added helper functions for some handlers + - fixed .au handler + +2008/08/11 + - fixed .es handler + +2008/07/08 + - added handler for .su + +2008/06/30 + - added handler for .fi + +2008/06/26 + - added handler for .asia + +2008/06/25 + - fixed hangup bug on some non-responding rwhois + servers (read result changed to non-blocking) + +2008/06/16 + - added support & handler for .me + +2008/06/16 + - fixed .fr handler + +2008/06/11 + - fixed .cz handler registered date + - fixed .fr handler + - added .ro handler + +2008/05/28 + - added handler for .it + - added handler for .fr + +2008/05/17 + - Added support for .ve + - Released version 4.1.3 + +2008/05/11 + - fixed whois.museum + +2008/05/09 + - do not use handlers on error + +2008/05/04 + - improved nameserver detection (again) + - fixed whois.pl, whois.gtld.nominalia, + whois.gtld.onlinenic, whois.ovh + - removed test for informe.ws + - minor fix to whois.gtld.enom + - minor chages to other handlers + +2008/04/29 + - improved nameserver detection (again) + - fixes & improvements on whois.mx + +2008/04/28 + - whois.za.php renamed to whois.zanet.php + - added support & handler for .org.za + - added handler for .co.za + - minor improvemts on whois.client.php to allow + handlers for second level domains + - improved nameserver detection + - minor fix to .ie handler + +2008/03/05 + - dotregistrar is now part of dotster + - fixes in date parser + - .cz handler update + - fixed .ch whois server detection + +2007/12/21 + - fixed uninitialized variable in example.php + - fixes in publicdomainregistry and uk handlers + - improved regex for html output + - added support for centralnic domains + - added handler for .pt and .ae (pacth #1709470) + - fixed bug #1761156 + - applied patch #1749389 + +2007/05/30 + - removed support for .gr domains + +2007/05/24 + - uniform way to specify query array + +2007/05/09 + - fixed reporting of ip query information + +2007/05/04 + - fixes to ip handler and APNIC ip handler + +2007/05/03 + - minox fix in whois.gtld.publicdomainregistry.php + - removed unused handler whois.gtld.directi.php + +2007/04/30 + - fixed tucows/opensrs gtld handler detection + - more improvements and cleanup of whois.parser.php + - added gtld handler for Fabulous + +2007/04/29 + - several improvments on whois.parser + - several handlers fixed to work with improved parser + - added gtld handler for NameKing + +2007/04/27 + - rearranged regyinfo array + - better info reporting on ip whois + +2007/04/26 + - restrict .com/.net searches to domains + - regyinfo now contains a list of all servers + servers contacted in key 'servers' + - improvements in contact data detection in + whois.parser + - added gtld handler for OnlineNIC + +2007/04/24 + - added gtld handler for Wild West Domains + - utf8 fixes in example.php + +2007/04/23 + - added gtld handler for RRPPROXY + +2007/04/21 + - added gtld handler for NICCO + +2007/04/20 + - fixes and improvments in .pl handler + - improved IDNA support + +2007/04/18 + - fixed warnings in nicline and tmagnic gtld handlers + - added support for IDNA (internationalized) domains names + as defined in RFC3490, RFC3491, RFC3492 and RFC3454 + using Matthias Sommerfeld idna_convert class + +2007/04/17 + - allow easy plugin for new gtld handlers + - minor improvement to testsuite.php + - fixed .se handler + - namesdirect has joined with dotster + - fixed tmagnic gtld handler + +2007/04/16 + - added basic support for .bz + - whois.info.php cosmetic changes + - added .ru handler + - support for multiple status lines in whois.org.php and + whois.gtl.php + - removed whois.gtld.chdom handler + - allow easy plugin for new country handlers + - minor improvement to whois.client.php and + whois.parser.php + - added gtld handler for OVH + +2007/04/06 + - fixed error in whois.ip.php + +2007/03/30 + - minor fix on whois.ip.php + +2007/03/28 + - some handlers where not seeting rawdata + +2007/03/19 + - Fixed nic.br ip handler detection + +2007/03/05 + - fixed .cat registered yes/no detection + +2007/03/02 + - minor fix to .eu handler + - fixes in arin ip handler + +2007/02/06 + - changed the way gTLD handlers are detected + +2006/12/21 + - fix/improvement for register.com handler + +2006/12/20 + - Released version 4.1.2 + +2006/12/19 + - minor fixes to testsuite.php, whois.parser.php, + whois.gtld.joker.php, whois.gtld.enom.php and + whois.gtld.tvcorp.php + - updated .nl handler + - enom has mixed with bulregister, so bulkr + gtl handler has been removed + +2006/12/18 + - minor fixes to whois.ca.php, whois.es.php, + whois.gtld.iana.php, whois.gtld.opensrsnet.php, + whois.ip.apnic.php, whois.biz.php, + whois.gtld.psiusa.php, whois.parser.php, + and whois.ch.php + - updated .lthandler + - added support and handler for .jobs + +2006/09/29 David Saez + - Fixed .in whois server name + - Added handler for .in + - Added gtld handler for psiusa (Patch #1539553) + - Fixed .za.net handler + - testsuite domain listed updated + - ip handler improvments from bug #1533099 + +2006/09/07 David Saez + - Fixed register.com owner detection + +2006/08/02 David Saez + - Fixed bug #1495871: failed to open stream + +2006/07/25 David Saez + - enabled again .es handler + +2006/06/23 David Saez + - fixed warning in whois.ip.afrinic + - added handler for .nz + - disabled .es handler + - Released version 4.1.1 + +2006/06/19 David Saez + - better handling of errors in whois.ip.php + +2006/06/12 David Saez + - More PHP5 friendly (from Bug #1502777) + - rawdata reflects all rwhois output + - added suport and handler for .mobi + +2006/05/31 David Saez + - Fixed bug #1495389 + +2006/05/16 David Saez + - added handler for .sc (thanx to + Hans-Peter Kohnle) + +2006/05/08 David Saez + - fixed exmaple.php + - fixed .pl and .de handler + +2006/04/29 David Saez + - improved .edu handler + - testsuite finished + - proxy support + - added template for example.php + +2006/04/28 David Saez + - fixed special non handled domains support + - added not supported domain .cy + - fixed typo in test.txt + - fixed directi handler detection + - improved whois.parser + - fixed joker handler + - minor fix to namejuice handler + - fixed krnic handler + +2006/04/08 David Saez + - Added handler for .eu + - Minor fix to example.php + - Improved HTML output + +2006/04/05 David Saez + - Added support for EPP status (bug #1463866) + +2006/04/03 David Saez + - fixed timestamp style date detection + +2006/03/29 David Saez + - fixed bad rwhois server/port detection + - added optional suport for non ICANN tld's + +2006/03/24 David Saez + - added handler for NAMESDIRECT + - fixed register.com handler + +2006/03/21 David Saez + - Fixed problems with some domains registered + at enom + +2006/03/20 David Saez + - Aplied fix to bug #1453935 + +2006/03/19 David Saez + - added gtld handler for namejuice + (thanx to Robert Apgood ) + - example.php is now XHTML 1.0 compliant + +2006/03/14 David Saez + - fixed case detection on whois.parser.php + +2006/03/10 David Saez + - added handler for .edu + +2006/03/07 David Saez + - added gtld handler for alldomains + - more improvemnts on whois.parser.php + +2006/03/06 David Saez + - added gtld handler for nominalia + +2006/03/05 David Saez + - fixed .de handler + - .ca handler fixed and updated + +2006/03/03 David Saez + - added handler for gtld domaincontender.com + +2006/03/02 David Saez + - added handler for .pl and .ie + - minor fixes in whois.parser.php + +2006/02/27 David Saez + - minor fixes for non-existing .es domains + - fixed ip2long PHP5 compatibility + - fixed sponsor detection on opensrsnet handler + +2006/02/13 David Saez + - fixed nserver detection in whois.es.php + +2006/02/03 Released phpWhois 4.1.0 + +2006/02/03 David Saez + - fixed README documentation + - minor fixes to some handlers + +2006/02/01 David Saez + - fixed README documentation + - improved .au handler for user with + whois-check.ausregistry.net.au + - added testsuite for verifying handlers + +2006/01/31 David Saez + - fixed lookup error on .co.za domains + - minor fix to whois.pareser.php + +2006/01/27 David Saez + - added deep_whois feature to get faster but + less acurate results + +2006/01/24 David Saez + - minor fixes to .es handler + +2006/01/20 David Saez + - changed .es http based whois server + - added function to set specific whois servers + - updated .es handler + - formating fixes in whois.parser.php + - added handler for .cat + +2006/01/18 David Saez + - minor fixes in enom handler + +2006/01/13 David Saez + - updated .uk handler + +2005/12/11 David Saez + - fixed some warnings in .de handler and + added timeout detection + +2005/12/10 David Saez + - fixed html output broken links + +2005/12/01 David Saez + - fixed php warning with limbo domains in netsol + +2005/11/21 David Saez + - added support for .pr domains + - fixed warning in whois.ip.afrinic.php + - added detection for netblocks transferred + from RIPE to AFRINIC + +2005/11/17 David Saez + - added support for .mt domains + +2005/11/14 David Saez + - avoid some warnings on whois.gtld.bulkr.php + +2005/11/11 David Saez + - removed support for .es domains + - some fixes in .uk handler + +2005/11/07 David Saez + - added handler for .int domains + - added support for some other domains + +2005/11/06 David Saez + - added support & handler for .travel + - showHTML made a bit more flexible + +2005/10/31 David Saez + - better windows based php detection + - fixed registro.br detection + +2005/10/21 David Saez + - added handler for Directi + - added handler for .cz domains + +2005/10/20 David Saez + - added handler for gtld IANA + - updated .org handler + +2005/10/15 David Saez + - added missing example for .ag and .name + - added multiple abuse email address detection + in arin ip queries + - avoid adding empty fields in whois.parser.php + - added support and handler for .pro domains + +2005/10/14 David Saez + - clean some messy ripe records + - added handler for .name + +2005/10/12 David Saez + - added compatibility with PHP versions prior 4.3.0 + +2005/10/11 David Saez + - fixed warning for non-existant .es domains + +2005/10/10 David Saez + - fixed some short tags in example.php, + fixed queries to .net whois server, + added support for .pe domains, + fixed .se registration detection, + added requirements section in README, + fix to let it work with PHP 4.1.0 - 4.3.1, + installation clarified + thanx to Speedywise + +2005/10/09 Released phpWhois 4.0.1 + - some files where missing !! + +2005/10/04 David Saez + - fix for address reporting + - added handler for .coop + +2005/09/30 David Saez + - fix for .museum handler + - added handler for .aero + - minor fix for date extraction in whois.parser.php + +2005/09/29 David Saez + - added handler for .museum + +2005/09/27 David Saez + - minor formating fix + - added handler for .lt + +2005/09/13 David Saez + - better error handling in whois.gtld + +2005/09/05 David Saez + - minor code cleaup on whois.gtld.php + - added better support for errors + - added hanlder for .ag + - added ip detection for HTML output + - country tld revision [ax-bx] + +2005/09/01 Released phpWhois 4.0.0 + +2005/08/31 David Saez + - changed behaviour of whois.utils.php + - changed url disclaimer + - added GPL license file + - whois.gtld.bulkr.php rewritten + - last minute fixes + +2005/08/30 David Saez + - changed generic_whois_b item parameter array + - fixes & improvments for rwhois + - AS detection, added regyinfo.type subkey + - added abuse contact detection for ripe + - fixes for .se + +2005/08/29 David Saez + - changed gif icon for a new png one + - recovered better example.php from old + distribution + - utils.whois renamed to whois.utils.php + - removed obsolete FAQ item + - added nice HTML output capabilities to + whois.utils.php + - fixed whois.ip.php + - added extra abuse email address detection + for whois.ip.php + - addeed rwhois recognition for afrinic + +2005/08/26 David Saez + - code cleanup and formatting + - added support form Referral Whois (rwhois) + as per RFC 1714/2167, support is limited, non + recursive and only for ARIN ip space + +2005/08/19 David Saez + - fixed some bad includes + +2005/07/29 David Saez + - fixed problem with lastest changes in whois.ip + +2005/07/28 David Saez + - modified $query parameter for parse function + +2005/07/27 David Saez + - genutil, generic2 and getdate moved to + whois.parser.php + - cli_example.php renamed to example.cli.php + - added handler.template.php + - disclaimer updated + - updated README file + - some improvments for AS queries + - some handlers reported zcode instead of pcode + - added support for AfriNIC (ip whois) + - updated HANDLERS documentation + - added support for CHINESEDOMAINS + +2005/07/26 David Saez + - added handler for za.org & za.net, thanx to + luca@clamav.net + - generic3.whois code moved to whois.parser.php + +2005/07/25 David Saez + - removed unused file denic.whois + - added support for za.net and za.org, thanx + to luca@clamav.net + - rewritte of .uk handler + - whois client code moved to whois.client.php + - class inheritence revised + - generic.whois moved to whois.parser.php + +2005/07/22 David Saez + - added CDIR to inetnum conversion for ip whois and + fixed brnic detection + - changed naming schema for gtld handlers + +2005/07/19 David Saez + - changes on methods and variables of Whois class + +2005/07/17 David Saez + - changed naming schema for country handlers + +2005/07/16 David Saez + - normalized expired/created/chaged dates + - report non existant dns servers + - improved getdate.whois + - fixed benic.whois + - improvements to genric whois handling + - improvments & fixes to esnic, denic and brnic + handlers + - added configurable timeout for sockec communications + - changed naming schema for ip handlers + +2005/04/28 David Saez + - Fixed .fm handling + - normalized expired/created/chaged dates + - changed the way nservers are normalized + - some fixes + - adde CLI mode example + +2005/03/14 David Saez + - added handler for TV CORPORATION + +2005/03/03 David Saez + - minor fix to main.whois + - added some object fields when not set + - fixed handling of .tv + +2005/03/02 David Saez + - fixed SRSPlus detection + - applied patch [ 981413 ] Whois Parameter Array + thanx to mwelters + - added better reporting on nameservers + - better email reporting on generic3.whois + +2005/03/01 David Saez + - fixed Network Solutions detection + - ordered list of handlers in gtld.whois + - added handler for Moniker + - added handler for Innerwise + - added handler for Stargate + - added handler for Cronon + - added handler for Joker + - fixed scripts using php short tags + thanx to rpm@keynetics.com + - added handler for Schlund + +2004/08/06 David Saez + - fixed denic.whois when domain does not + exist, thanx to bjoern@xrow.de + +2004/04/24 David Saez + - added .is handler + - added some notes about generic support functions + in HANDLERS + +2004/04/23 David Saez + - Fixed ending tag in all files + +2004/04/22 David Saez + - added handler for .us , thanx to + snguyen@mbaassociation.org + - correctly sets regyinfo.whois + - added hack for .net.au , thanx to + thill@gumnut.com.au + - implemented request id 757465 + - fixed bug 690623 + - fixed bug 804595 + - added feature request 759788 + - added .bg http whois mserver + - added .hu handler + +2004/04/21 David Saez + - fixed small bug in netsol.whois + - improvments and fixes to gtld.whois, thanx to + snguyen@mbaassociation.org + +2004/02/11 David Saez + - handles R120-LROR, thanx to DavHolle + +2003/11/22 David Saez + - fix for .tv domains + +2003/10/27 David Saez + - minor improvments to main.whois + - fix for .in domains + +2003/10/01 Ross Golder + - Released phpWhois version 3.0.6 + +2003/09/20 David Saez + - minor improvment to esnic.whois + +2003/09/13 David Saez + - minor improvment to org.whois + +2003/09/12 David Saez + - added gtld handler for Arsys nicline + thanx to cgalvez@espaciowww.com + - minor fixes to main.whois and gtld.whois + +2003/09/09 David Saez + - fixed some warning when ip is banned + on domainbank.whois + - main.whois also sets regyinfo.whois on http + queries + - rewrite of esnic.whois + +2003/09/08 David Saez + - rewrite of cnnic.whois + - some fixes to wsnic.whois + - some fixes to gtld.whois and generic3.whois + - added handler for Godady and Domain Bank + - minor improvment to main.whois and generic2.whois + - added handler for .org + +2003/09/06 David Saez + - Added handlers for .cn and .ws + thanx to zingfharn@fastmail.fm + - Fixed main.whois to allow https queries + - Enabled .es queries but handler remains + disabled because needs total rewrite + +2003/08/04 David Saez + - Temporary deactivation of .es handler due to + changes in .es registry whois system + - Fixed denic.whois, thanks to + Gulibert@NetGameZone.de + +2003/06/30 David Saez + - added handler for .be, thanx to + onveilig@hotmail.com + +2003/06/04 Ross Golder + - Removed a blank line preventing headers from + being sent. + +2003/04/25 David Saez + - added support for web based whois for + .tc, .vg, .ms, .gs and .tf domains + +2003/04/19 David Saez + - fixed problem with whois.crsnic.net which + causes some domains like hotmail.com and + yahoo.com not to resolve, thanx to + asajith@users.sourceforge.net for reporting + this issue, also some improvments have been + made to help diagnose problems like that in + the future + +2003/04/11 David Saez + - added gtld handler for SRSPlus + +2003/04/07 Mark Jeftovic + - fix for missing checkdnsrr function in windows + +2003/04/04 David Saez + - added handler for .fm + +2003/03/30 David Saez + - recovered 'powered by phpWhois' logo + - added handlers for directnic and buydomains + - minor improvment to generic3.whois + - minor fixes to bripw.whois + +2003/03/26 David Saez + - some improvments on generic3.whois + - added handler for ascio (com/org) + +2003/03/22 David Saez + - referrer correction and normalization in some handlers + - removed unused handler cdnnet.whois + +2003/03/22 Ross Golder + - Release 3.0.4 available now + +2003/03/17 David Saez + - chnic.whois & nlnic.whois rewritten + - minor fix and improvment on generic3.whois + - added nameserver detection to dotregistrar.whois + - minor fix on info.whois + - fixed bripw.whois + - bulkregstercom.whois fixed and updated to common + object model + +2003/03/16 David Saez + - mxnic.whois updated to common object model + - recovered brnic.whois and added bripw.whois + which was implemented over brnic.whois by + mistake + - fixed netsol.whois + +2003/03/12 Ross Golder + - Minor corrections and a note about coding style + on HANDLERS + +2003/03/07 David Saez + - added lacnic.whois + - added file HANDLERS + - minor fixes to README + +2003/03/05 David Saez + - implemented krnic.whois + - minor improvments to generic3.whois + +2003/03/04 David Saez + - improvments on ripe.whois + - implemented arin.whois and brnic.whois + - added ip's for testing on ipw.whois + +2003/03/03 David Saez + - some fixes to ip whois + - some fixes to uknic.whois + - implemented ripe.whois + - improved code for html2text for web based whois + +2003/02/26 David Saez + - common object model changes in some handlers + - removed warning in gtld.whois when domain does not exist + - core.whois fixed and updated to common object model + - added corenic .org handle to gtld.whois + +2003/02/25 David Saez + - added interdomain .org handle + - interdomain.whois updated to common object model + +2003/02/19 David Saez + - added dotregistrar .org handle + - some improvments to generic3.whois + - registercom.whois updated to common object model + +2003/02/18 David Saez + - added dotster .org handle + - some improvments to generic3.whois + - dotster.whois & registercom.whois updated to common object model + +2003/02/16 David Saez + - improved generic.whois, update all handlers that use it + - now it's possible to also query http based whois + - added .es handler (http) + - some improvments on generic3.whois + - enom.whois fixed and updated to common object model + - added enom .org handle to gtld.whois + +2003/02/15 David Saez + - added generic3.whois with functions to parse whois output + - added disclaimer to generic.whois and generic2.whois + - opensrsnet.whois updated to common object model + - added mxnic.whois, thanx to torfinn@nome.no + +2003/02/10 David Saez + - inwwcom.whois updated to common object model + - added inwwcom org handle to gtld.whois + - gtld.whois now can get the name of the org registrar + - minor fixes to generic2.whois + +2003/02/09 Ross Golder + - updated to do a 'whois-servers.net' DNS lookup to determine + the tld whois server to query + + David Saez + - netsol.whois & gtld.whois updated to common object model + - fixed some warnings in main.whois + +2003/01/29 David Saez + - fixed nicse.whois and updated to common object model + +2003/01/27 David Saez + - fixed nunames.whois and updated to common object model + +2003/01/26 David Saez + - fixed lunic.whois and updated to common object model + - neulevel.whois changed to use generic2.whois + - some minor fixes on info.whois + +2003/01/25 David Saez + - info.whois updated to common object model + +2003/01/19 David Saez + - fixed denic.whois + +2003/01/18 David Saez + - added nlnic.whois, thanx to Matthijs Koot + - fixed some warnings on generic.whois + - fixed double processing on atnic.whois + +2002/12/16 David Saez + - updated aunic.whois + - improved generic.whois & generic2.whois + - fixed uninitialized variable in utils.whois + +2002/10/16 David Saez + - Updated uknic handler to new Nominet UK whois output + - Added handler for .biz + - Added support to ipw.whois for BRNIC, KRNIC, TWNIC and LACNIC + - Some handlers updated to new common object model + - Added generic.whois and generic2.whois with parse functions + for two kinds of whois output commonly used + +2002/10/11 Ross Golder + - Merged in as many useful patches as possible (supplied by Mark) + - Re-indented the classes for clarity + - Attempted to add comments to as much code as possible + +2001/02/28 + -batch add of many updates + -uknic.whois updated by David Saez Padros + -added dotster and chnic for .ch and .li, also by David Saez Padros + -.at whois server now whois.nic.at + +2000/12/12 +v2.3 -PHP4 BUG IS FIXED!!!! Very special thanks to all who submitted + fixes, used one provided by Stephen Leavitt + as it was the easiest and backwards + compatible to PHP3 + -added Enom handler, also by Stephen Leavitt + + -changed .ca whois to whois.cira.ca, using same handler for now. +2000/08/14 + -added brnic.whois country handler + -major revision of servers.whois, many adds (crossreferenced + against geektools list at + http://www.geektools.com/dist/whoislist.gz) + -dropped all ORSC TLD's, either their whois servers weren't + working or it was clear there was no functioning registry + if they were. (From here on in we stick to the IANA + legacy root TLD's) +2000/08/07 +v2.2-3 -gtld.whois, "TUCOWS.COM INC." now, "TUCOWS.COM, INC." + an unannounced change by the NSI registry once again + breaks scripts all over the world...(thanks to + Fred Andrews for the report + and fix on this) + -servers.whois, added .ke Kenyan whois server, thanks + to "Peter Anampiu" for digging that up.:x + +2000/05/27 +v2.2-2 -ouch! params in implode() are backwards + +2000/04/06 +v2.2-1 -new classes for bulkregister, openSRS and melbourneIT + by Jeremiah Bellomy + +2000/03/16 +v2.1-4 -servers.whois, added .st + +2000/03/08 +v2.1-4 -servers.whois, fixed .no address, added .as + +2000/01/26 +v2.1-4 +main.whois -fixed Connect() so it wouldn't attempt to connect + to an unset server (Query["server"] is null on + pass 2 if domain isn't in the registry whois) + -added rudimentry "not found" code to sample script + +2000/01/02 +v2.1-3 +main.whois -fixed GetTld() so "churchuk.com" 's tld wouldn't + mistakenly be set to nominet's "uk.com" tld. + -fixed Lookup() was always using char by char reads + regardless of $this->BUFFER value +servers.whois -added nominet's se.com, se.net and no.com + +2000/01/01 +2.1-2 +main.whois -fixed Process() so it would only include the handler if + it wasn't already defined. Trying queries inside a loop + would fail on the second iteration. + diff --git a/FAQ b/classes/FAQ similarity index 97% rename from FAQ rename to classes/FAQ index 9bffead..b1ea3c5 100644 --- a/FAQ +++ b/classes/FAQ @@ -1,53 +1,53 @@ - -Whois2 FAQ v1.2 June 06/00 Mark Jeftovic - -Q's - -1.0 How do I tell if a domain is available or not? -1.1 I'm getting "Fatal error: Call to unsupported or undefined function - preg_replace()" why? -1.2 whois2 breaks under PHP4, I get $result["rawdata"] = Array now instead - of the actual data! - -Q & A's - -1.0 How do I tell if a domain is available or not? - -The big difference between this and version 1 is the absence of the -FOUND flag. - -Anyways, for .com/.net/.org you can tell that a domain is available -or not if the regyinfo array is empty. - -$whois = new Whois("test.com"); -$result = $whois->Lookup(); - -if(empty($result["regyinfo"])) { - // available -} else { - // taken -} - -Keep in mind that this isn't 100% surefire. A domain can be dropped from -the registry for nonpayment, and remain in limbo for up to 5 days where -it still cannot be registered. Also, whois servers can lag behind the root -servers by as much as 24 or even 48 hours in extreme cases. - -You can also check if there are any nameserver RR's defined (and thus infer -that the domain is in the root servers) by calling ns_rr_defined($domain) -in the utils extended class. - -For other TLD's it's up to you to either grep the results for what you know -to be a "not found" string, or write an extended handler that does a cleaner -job of it, which you can then submit to this project and immortalize yourself :) - - -1.1 I'm getting "Fatal error: Call to unsupported or undefined function - preg_replace()" why? - -All that means is that the version of PHP you're using doesn't have -the perl regular expression module. You can either upgrade or in -the meantime just move netsol.whois out of the php_include_path, -you won't get nicely parsed output for netsol domains but you -will still at least get the raw output then. - + +Whois2 FAQ v1.2 June 06/00 Mark Jeftovic + +Q's + +1.0 How do I tell if a domain is available or not? +1.1 I'm getting "Fatal error: Call to unsupported or undefined function + preg_replace()" why? +1.2 whois2 breaks under PHP4, I get $result["rawdata"] = Array now instead + of the actual data! + +Q & A's + +1.0 How do I tell if a domain is available or not? + +The big difference between this and version 1 is the absence of the +FOUND flag. + +Anyways, for .com/.net/.org you can tell that a domain is available +or not if the regyinfo array is empty. + +$whois = new Whois("test.com"); +$result = $whois->Lookup(); + +if(empty($result["regyinfo"])) { + // available +} else { + // taken +} + +Keep in mind that this isn't 100% surefire. A domain can be dropped from +the registry for nonpayment, and remain in limbo for up to 5 days where +it still cannot be registered. Also, whois servers can lag behind the root +servers by as much as 24 or even 48 hours in extreme cases. + +You can also check if there are any nameserver RR's defined (and thus infer +that the domain is in the root servers) by calling ns_rr_defined($domain) +in the utils extended class. + +For other TLD's it's up to you to either grep the results for what you know +to be a "not found" string, or write an extended handler that does a cleaner +job of it, which you can then submit to this project and immortalize yourself :) + + +1.1 I'm getting "Fatal error: Call to unsupported or undefined function + preg_replace()" why? + +All that means is that the version of PHP you're using doesn't have +the perl regular expression module. You can either upgrade or in +the meantime just move netsol.whois out of the php_include_path, +you won't get nicely parsed output for netsol domains but you +will still at least get the raw output then. + diff --git a/HANDLERS b/classes/HANDLERS similarity index 97% rename from HANDLERS rename to classes/HANDLERS index 0c2c2e8..3477190 100644 --- a/HANDLERS +++ b/classes/HANDLERS @@ -1,356 +1,356 @@ -Introduction ------------- - -Handlers are pieces of code that parse the raw whois output and try -to add some keys to the result returned by phpWhois. In previous -versions there was no standard about how these keys should be named -and organized, which make them registry specific. Now all handlers -have been standarized so they return a known set of keys. This is what -we call 'Common Object Model'. - - -Common Object Model -------------------- - -The keys that you could find in the result array returned by phpWhois -are 'rawdata' , 'regyinfo' and 'regrinfo'. - -rawdata is always returned as it's filled by phpWhois itself. It -contains the raw text output returned by the whois server. - -regyinfo contains information about the registry who returned that -information. It has four subkeys: 'servers' which is an array with -one entry for each whois server who returned the data, 'referrer' the -web address of the registry, 'registar' the company name of the registry -and 'type' which can be 'domain', 'ip' or 'AS'. The 'servers' array -has subkeys 'server' the whois server, 'port' the whois server port and -'args' the query sent to the server. - -regrinfo holds the information about the domain itself. It could have -the following subkeys: - - disclaimer - ---------- - Contains the disclaimer returned by the registry. - - registered - ---------- - Contains Yes or No and indicates if the domain or ip - address has been found (it exists). - - domain - ------ - Only when dealing with domains. Could contain the - following subkeys: - - name -> domain name - desc -> description of the domain - nserver -> array where the key is the canonical name - of each nameserver and the value is the - ip adresss (if none) of the server. - status -> status of the domain (registry dependant) - changed -> date of last change - created -> creation date - expires -> expire date - sponsor -> registry partner where the domain was - registered - referer -> sponsor's URL - handle -> domain handle - source -> who gives this information - dnssec -> domains has dnssec (boolean) - - network - ------- - Only when dealing with ip addresses. Could contain the - following subkeys: - - name -> network/AS name - inetnum -> network ip address range - desc -> network description - mnt-by -> who provided that network - mnt-lower> who provided that network - nserver -> name servers in listed order that - provide inverse resolution for that net - status -> status of the network (registry dependant) - remarks -> remarks provided by the registry - changed -> date of last change - created -> creation date - handle -> network/AS handle - source -> who gives this information - - AS - -- - - Only when dealing with Autonomus systems, could contain - the same subkeys as network. - - owner,admin,tech,zone,billing,abuse - ----------------------------------- - - All of these possible keys hold information about the different - contacts of the domain or ip address. They all could have the - same subkeys, that are: - - organization -> organization name - name -> organization responsible - type -> type of contact - address -> array containing the address, the - keys of that array could be just - numbers, could have predefined - subkeys or could be amix of numbers - and predefined subkeys. Predefined - subkeys are street, city, - state, pcode and country - phone -> phone, could also be an array of - phone numers - fax -> fax, same behaviour as phone - email -> email, same behaviour as phone - handle -> contact handle - mnt-by -> who provided that contact - created -> creation date - changed -> last change date - source -> who provided that information - remarks -> remarks - - When information is requested on ip addresses any of those - keys could be an array which will contain all data found on - different whois or rwhois servers (each owner, admin, tech, - etc ... found in each query). - -Not all handlers fill values in each of the keys defined by the -Common Object Model as not all registries return the same amount -of data about a domain or ip address. Also there are some differences -on the format returned for some keys. - -Dates (created/changed/expires) are always returned in the format -yyyy-mm-dd when a handler is defined for the returned data. - - -Writing handlers ----------------- - -Writing handlers is easy, just look at how some of them are coded. -If you write a new handler, please try to map as many as possible -returned data to keys defined by the 'Common Object Model'. You can -create new keys if need, but please do not do create new keys where -existing predefined keys exists. Nevertheless all handlers submited -will be checked before they are added to phpWhois distribution. - -If some tld needs special parameters or can be queried in -another whois servers or web base whois servers you can setup -rules in whois.servers.php so phpWhois can do the right thing. - -There is also a naming schema that must be followed, country -handlers are named whois.XX.php, where XX is the iso country -code. The handler must also define __XX_HANDLER__ and implement -a class named xx_handler with a function named parse that takes -two arguments: $data_str and $query. $data_str['rawdata'] -contains the raw output of the query and is what need to be parsed -in order to generate the Common Object Model. $query contains -the domain, ip adrress or AS that it's being queried. That function -must return an array with any available result in the format defined -by this document. Country handlers need not to be defined in -the file whois.servers.php, only when you want to use some handler -for several different country domains you need to add it to the array -DATA where the key is the iso country code and the value the handler -name (xx). - -Handlers for .com/.net/.tv domains are handled by whois.gtld.php -and named whois.gtld.xxx.php where xxx is the 'midname' (for example, -for whois.srsplus.com, the midname is srsplus) of the whois server who -provides information for that domains. If you want to reuse another -handler of your handler 'midname' conflicts with any existing gtld -handler you could define the handler name in the array WHOIS_GTLD_HANDLER -in the file whois.servers.php. It must be implemented the same way as -country handlers. - -Some useful utility functions have been written to aid in developing -handlers. They are contained in whois.parser.php. Almost all handlers -use functions provided by that file. You can see how they work by -looking into the code. You also have a handler.template.php file -with the squeleton of a handler. - -Please try to mimic the coding style of the other handlers, as this -will make it easier for other people to understand and maintain. - -Some support functions have been developed to help you write new -handlers, those functions are stored on the following files: - -- generic_parser_a: - - contains code to parse whois outputs in RPSL format, like this one. - You could take a look at whois.at.php to see how you could use it: - - domain: nic.at - registrant: NAIV1117337-NICAT - admin-c: NAR567002-NICAT - tech-c: GW502425-NICAT - zone-c: GW502425-NICAT - nserver: ns3ext.univie.ac.at - nserver: ns4ext.univie.ac.at - nserver: ns5.univie.ac.at - nserver: ns9.univie.ac.at - changed: 20030616 12:54:18 - source: AT-DOM - - personname: - organization: NIC.AT Internet Verwaltungs- und Betriebsges.m.b.H. - street address: Jakob-Haringerstrasse 8 - postal code: A-5020 - city: Salzburg - country: Austria - phone: +43662466920 - fax-no: +43662466929 - e-mail: office@nic.at - nic-hdl: NAIV1117337-NICAT - changed: 20020614 17:29:04 - source: AT-DOM - - personname: NIC.AT Role - organization: - street address: NIC.AT Internet Verwaltungs- und Betriebsgesellschaft m.b.H. - street address: Jakob-Haringerstrasse 8 - street address: A-5020 Salzburg - street address: Austria - postal code: - city: - country: - phone: +43 662 4669 0 - fax-no: +43 662 4669 19 - e-mail: nic-at@nic.at - nic-hdl: NAR567002-NICAT - changed: 20010223 12:52:13 - source: AT-DOM - - personname: Gerhard Winkler - organization: - street address: Vienna University - street address: Computer Center - ACOnet - street address: Universitaetsstrasse 7 - street address: A-1010 Vienna - street address: Austria - postal code: - city: - country: - phone: +43 1 4277 140 35 - fax-no: +43 1 4277 9140 - e-mail: gerhard.winkler@univie.ac.at - nic-hdl: GW502425-NICAT - changed: 20001205 14:06:15 - source: AT-DOM - -- generic_parser_b: - - contains code to parse whois outputs like this one, you could - take a look at whois.neulevel.php to see how you could use it: - - Domain Name: NIC.BIZ - Domain ID: D714-BIZ - Sponsoring Registrar: REGISTRY REGISTRAR - Domain Status: clientDeleteProhibited - Domain Status: clientTransferProhibited - Domain Status: clientUpdateProhibited - Domain Status: serverDeleteProhibited - Domain Status: serverTransferProhibited - Domain Status: serverUpdateProhibited - Registrant ID: NEULEVEL1 - Registrant Name: Customer Support - Registrant Address1: Loudoun Tech Center - Registrant Address2: 45980 Center Oak Plaza - Registrant City: Sterling - Registrant State/Province: Virginia - Registrant Postal Code: 20166 - Registrant Country: United States - Registrant Country Code: US - Registrant Phone Number: +1.5714345757 - Registrant Facsimile Number: +1.5714345758 - Registrant Email: support@neulevel.biz - Administrative Contact ID: NEULEVEL1 - Administrative Contact Name: Customer Support - Administrative Contact Address1: Loudoun Tech Center - Administrative Contact Address2: 45980 Center Oak Plaza - Administrative Contact City: Sterling - Administrative Contact State/Province: Virginia - Administrative Contact Postal Code: 20166 - Administrative Contact Country: United States - Administrative Contact Country Code: US - Administrative Contact Phone Number: +1.5714345757 - Administrative Contact Facsimile Number: +1.5714345758 - Administrative Contact Email: support@neulevel.biz - Billing Contact ID: NEULEVEL1 - Billing Contact Name: Customer Support - Billing Contact Address1: Loudoun Tech Center - Billing Contact Address2: 45980 Center Oak Plaza - Billing Contact City: Sterling - Billing Contact State/Province: Virginia - Billing Contact Postal Code: 20166 - Billing Contact Country: United States - Billing Contact Country Code: US - Billing Contact Phone Number: +1.5714345757 - Billing Contact Facsimile Number: +1.5714345758 - Billing Contact Email: support@neulevel.biz - Technical Contact ID: NEULEVEL1 - Technical Contact Name: Customer Support - Technical Contact Address1: Loudoun Tech Center - Technical Contact Address2: 45980 Center Oak Plaza - Technical Contact City: Sterling - Technical Contact State/Province: Virginia - Technical Contact Postal Code: 20166 - Technical Contact Country: United States - Technical Contact Country Code: US - Technical Contact Phone Number: +1.5714345757 - Technical Contact Facsimile Number: +1.5714345758 - Technical Contact Email: support@neulevel.biz - Name Server: NS1.NEULEVEL.BIZ - Name Server: NS2.NEULEVEL.BIZ - Name Server: NS4.NEULEVEL.BIZ - Name Server: NS3.NEULEVEL.BIZ - Created by Registrar: REGISTRY REGISTRAR - Last Updated by Registrar: NEULEVELCSR - Domain Registration Date: Wed Nov 07 00:01:00 GMT 2001 - Domain Expiration Date: Sat Nov 06 23:59:00 GMT 2004 - Domain Last Updated Date: Fri Nov 07 18:59:11 GMT 2003 - -- get_blocks/get_contacts: - - contains code to parse whois outputs like this one, you could - take a look at whois.ch.php to see how you could use it: - - Domain name: - nic.ch - - Holder of domain name: - SWITCH Internet Domains - Dana Djurdjevic - Neumühlequai 6 - CH-8001 Zürich - Switzerland - hostmaster@switch.ch - Contractual Language: English - - Technical contact: - SWITCH Geschäftsstelle - Andrea Tognola - Network - Limmatquai 138 - CH-8001 Zürich - Switzerland - hostmaster@switch.ch - - Name servers: - merapi.switch.ch [130.59.211.10] - scsnms.switch.ch [130.59.1.30] - scsnms.switch.ch [130.59.10.30] - - Date of last registration: - 31.12.1995 - - Date of last modification: - 22.12.2003 - -Credits -------- - -Mark Jeftovic -David Saez Padros -Ross Golder +Introduction +------------ + +Handlers are pieces of code that parse the raw whois output and try +to add some keys to the result returned by phpWhois. In previous +versions there was no standard about how these keys should be named +and organized, which make them registry specific. Now all handlers +have been standarized so they return a known set of keys. This is what +we call 'Common Object Model'. + + +Common Object Model +------------------- + +The keys that you could find in the result array returned by phpWhois +are 'rawdata' , 'regyinfo' and 'regrinfo'. + +rawdata is always returned as it's filled by phpWhois itself. It +contains the raw text output returned by the whois server. + +regyinfo contains information about the registry who returned that +information. It has four subkeys: 'servers' which is an array with +one entry for each whois server who returned the data, 'referrer' the +web address of the registry, 'registar' the company name of the registry +and 'type' which can be 'domain', 'ip' or 'AS'. The 'servers' array +has subkeys 'server' the whois server, 'port' the whois server port and +'args' the query sent to the server. + +regrinfo holds the information about the domain itself. It could have +the following subkeys: + + disclaimer + ---------- + Contains the disclaimer returned by the registry. + + registered + ---------- + Contains Yes or No and indicates if the domain or ip + address has been found (it exists). + + domain + ------ + Only when dealing with domains. Could contain the + following subkeys: + + name -> domain name + desc -> description of the domain + nserver -> array where the key is the canonical name + of each nameserver and the value is the + ip adresss (if none) of the server. + status -> status of the domain (registry dependant) + changed -> date of last change + created -> creation date + expires -> expire date + sponsor -> registry partner where the domain was + registered + referer -> sponsor's URL + handle -> domain handle + source -> who gives this information + dnssec -> domains has dnssec (boolean) + + network + ------- + Only when dealing with ip addresses. Could contain the + following subkeys: + + name -> network/AS name + inetnum -> network ip address range + desc -> network description + mnt-by -> who provided that network + mnt-lower> who provided that network + nserver -> name servers in listed order that + provide inverse resolution for that net + status -> status of the network (registry dependant) + remarks -> remarks provided by the registry + changed -> date of last change + created -> creation date + handle -> network/AS handle + source -> who gives this information + + AS + -- + + Only when dealing with Autonomus systems, could contain + the same subkeys as network. + + owner,admin,tech,zone,billing,abuse + ----------------------------------- + + All of these possible keys hold information about the different + contacts of the domain or ip address. They all could have the + same subkeys, that are: + + organization -> organization name + name -> organization responsible + type -> type of contact + address -> array containing the address, the + keys of that array could be just + numbers, could have predefined + subkeys or could be amix of numbers + and predefined subkeys. Predefined + subkeys are street, city, + state, pcode and country + phone -> phone, could also be an array of + phone numers + fax -> fax, same behaviour as phone + email -> email, same behaviour as phone + handle -> contact handle + mnt-by -> who provided that contact + created -> creation date + changed -> last change date + source -> who provided that information + remarks -> remarks + + When information is requested on ip addresses any of those + keys could be an array which will contain all data found on + different whois or rwhois servers (each owner, admin, tech, + etc ... found in each query). + +Not all handlers fill values in each of the keys defined by the +Common Object Model as not all registries return the same amount +of data about a domain or ip address. Also there are some differences +on the format returned for some keys. + +Dates (created/changed/expires) are always returned in the format +yyyy-mm-dd when a handler is defined for the returned data. + + +Writing handlers +---------------- + +Writing handlers is easy, just look at how some of them are coded. +If you write a new handler, please try to map as many as possible +returned data to keys defined by the 'Common Object Model'. You can +create new keys if need, but please do not do create new keys where +existing predefined keys exists. Nevertheless all handlers submited +will be checked before they are added to phpWhois distribution. + +If some tld needs special parameters or can be queried in +another whois servers or web base whois servers you can setup +rules in whois.servers.php so phpWhois can do the right thing. + +There is also a naming schema that must be followed, country +handlers are named whois.XX.php, where XX is the iso country +code. The handler must also define __XX_HANDLER__ and implement +a class named xx_handler with a function named parse that takes +two arguments: $data_str and $query. $data_str['rawdata'] +contains the raw output of the query and is what need to be parsed +in order to generate the Common Object Model. $query contains +the domain, ip adrress or AS that it's being queried. That function +must return an array with any available result in the format defined +by this document. Country handlers need not to be defined in +the file whois.servers.php, only when you want to use some handler +for several different country domains you need to add it to the array +DATA where the key is the iso country code and the value the handler +name (xx). + +Handlers for .com/.net/.tv domains are handled by whois.gtld.php +and named whois.gtld.xxx.php where xxx is the 'midname' (for example, +for whois.srsplus.com, the midname is srsplus) of the whois server who +provides information for that domains. If you want to reuse another +handler of your handler 'midname' conflicts with any existing gtld +handler you could define the handler name in the array WHOIS_GTLD_HANDLER +in the file whois.servers.php. It must be implemented the same way as +country handlers. + +Some useful utility functions have been written to aid in developing +handlers. They are contained in whois.parser.php. Almost all handlers +use functions provided by that file. You can see how they work by +looking into the code. You also have a handler.template.php file +with the squeleton of a handler. + +Please try to mimic the coding style of the other handlers, as this +will make it easier for other people to understand and maintain. + +Some support functions have been developed to help you write new +handlers, those functions are stored on the following files: + +- generic_parser_a: + + contains code to parse whois outputs in RPSL format, like this one. + You could take a look at whois.at.php to see how you could use it: + + domain: nic.at + registrant: NAIV1117337-NICAT + admin-c: NAR567002-NICAT + tech-c: GW502425-NICAT + zone-c: GW502425-NICAT + nserver: ns3ext.univie.ac.at + nserver: ns4ext.univie.ac.at + nserver: ns5.univie.ac.at + nserver: ns9.univie.ac.at + changed: 20030616 12:54:18 + source: AT-DOM + + personname: + organization: NIC.AT Internet Verwaltungs- und Betriebsges.m.b.H. + street address: Jakob-Haringerstrasse 8 + postal code: A-5020 + city: Salzburg + country: Austria + phone: +43662466920 + fax-no: +43662466929 + e-mail: office@nic.at + nic-hdl: NAIV1117337-NICAT + changed: 20020614 17:29:04 + source: AT-DOM + + personname: NIC.AT Role + organization: + street address: NIC.AT Internet Verwaltungs- und Betriebsgesellschaft m.b.H. + street address: Jakob-Haringerstrasse 8 + street address: A-5020 Salzburg + street address: Austria + postal code: + city: + country: + phone: +43 662 4669 0 + fax-no: +43 662 4669 19 + e-mail: nic-at@nic.at + nic-hdl: NAR567002-NICAT + changed: 20010223 12:52:13 + source: AT-DOM + + personname: Gerhard Winkler + organization: + street address: Vienna University + street address: Computer Center - ACOnet + street address: Universitaetsstrasse 7 + street address: A-1010 Vienna + street address: Austria + postal code: + city: + country: + phone: +43 1 4277 140 35 + fax-no: +43 1 4277 9140 + e-mail: gerhard.winkler@univie.ac.at + nic-hdl: GW502425-NICAT + changed: 20001205 14:06:15 + source: AT-DOM + +- generic_parser_b: + + contains code to parse whois outputs like this one, you could + take a look at whois.neulevel.php to see how you could use it: + + Domain Name: NIC.BIZ + Domain ID: D714-BIZ + Sponsoring Registrar: REGISTRY REGISTRAR + Domain Status: clientDeleteProhibited + Domain Status: clientTransferProhibited + Domain Status: clientUpdateProhibited + Domain Status: serverDeleteProhibited + Domain Status: serverTransferProhibited + Domain Status: serverUpdateProhibited + Registrant ID: NEULEVEL1 + Registrant Name: Customer Support + Registrant Address1: Loudoun Tech Center + Registrant Address2: 45980 Center Oak Plaza + Registrant City: Sterling + Registrant State/Province: Virginia + Registrant Postal Code: 20166 + Registrant Country: United States + Registrant Country Code: US + Registrant Phone Number: +1.5714345757 + Registrant Facsimile Number: +1.5714345758 + Registrant Email: support@neulevel.biz + Administrative Contact ID: NEULEVEL1 + Administrative Contact Name: Customer Support + Administrative Contact Address1: Loudoun Tech Center + Administrative Contact Address2: 45980 Center Oak Plaza + Administrative Contact City: Sterling + Administrative Contact State/Province: Virginia + Administrative Contact Postal Code: 20166 + Administrative Contact Country: United States + Administrative Contact Country Code: US + Administrative Contact Phone Number: +1.5714345757 + Administrative Contact Facsimile Number: +1.5714345758 + Administrative Contact Email: support@neulevel.biz + Billing Contact ID: NEULEVEL1 + Billing Contact Name: Customer Support + Billing Contact Address1: Loudoun Tech Center + Billing Contact Address2: 45980 Center Oak Plaza + Billing Contact City: Sterling + Billing Contact State/Province: Virginia + Billing Contact Postal Code: 20166 + Billing Contact Country: United States + Billing Contact Country Code: US + Billing Contact Phone Number: +1.5714345757 + Billing Contact Facsimile Number: +1.5714345758 + Billing Contact Email: support@neulevel.biz + Technical Contact ID: NEULEVEL1 + Technical Contact Name: Customer Support + Technical Contact Address1: Loudoun Tech Center + Technical Contact Address2: 45980 Center Oak Plaza + Technical Contact City: Sterling + Technical Contact State/Province: Virginia + Technical Contact Postal Code: 20166 + Technical Contact Country: United States + Technical Contact Country Code: US + Technical Contact Phone Number: +1.5714345757 + Technical Contact Facsimile Number: +1.5714345758 + Technical Contact Email: support@neulevel.biz + Name Server: NS1.NEULEVEL.BIZ + Name Server: NS2.NEULEVEL.BIZ + Name Server: NS4.NEULEVEL.BIZ + Name Server: NS3.NEULEVEL.BIZ + Created by Registrar: REGISTRY REGISTRAR + Last Updated by Registrar: NEULEVELCSR + Domain Registration Date: Wed Nov 07 00:01:00 GMT 2001 + Domain Expiration Date: Sat Nov 06 23:59:00 GMT 2004 + Domain Last Updated Date: Fri Nov 07 18:59:11 GMT 2003 + +- get_blocks/get_contacts: + + contains code to parse whois outputs like this one, you could + take a look at whois.ch.php to see how you could use it: + + Domain name: + nic.ch + + Holder of domain name: + SWITCH Internet Domains + Dana Djurdjevic + Neumühlequai 6 + CH-8001 Zürich + Switzerland + hostmaster@switch.ch + Contractual Language: English + + Technical contact: + SWITCH Geschäftsstelle + Andrea Tognola + Network + Limmatquai 138 + CH-8001 Zürich + Switzerland + hostmaster@switch.ch + + Name servers: + merapi.switch.ch [130.59.211.10] + scsnms.switch.ch [130.59.1.30] + scsnms.switch.ch [130.59.10.30] + + Date of last registration: + 31.12.1995 + + Date of last modification: + 22.12.2003 + +Credits +------- + +Mark Jeftovic +David Saez Padros +Ross Golder diff --git a/LICENSE b/classes/LICENSE old mode 100755 new mode 100644 similarity index 98% rename from LICENSE rename to classes/LICENSE index 3912109..b860267 --- a/LICENSE +++ b/classes/LICENSE @@ -1,340 +1,340 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/README b/classes/README similarity index 97% rename from README rename to classes/README index 0c78016..dac0076 100644 --- a/README +++ b/classes/README @@ -1,211 +1,211 @@ - -$Id: README,v 1.22 2010/08/26 10:23:39 sparc Exp $ - -Introduction ------------- - -This package contains a Whois (RFC954) library for PHP. It allows -a PHP program to create a Whois object, and obtain the output of -a whois query with the Lookup function. - -The response is an array containing, at least, an element 'rawdata', -containing the raw output from the whois request. - -In addition, if the domain belongs to a registrar for which a special -handler exists, the special handler will parse the output and make -additional elements available in the response. The keys of these -additional elements are described in the file HANDLERS. - -It fully supports IDNA (internationalized) domains names as -defined in RFC3490, RFC3491, RFC3492 and RFC3454. - -It also supports ip/AS whois queries which are very useful to trace -SPAM. You just only need to pass the doted quad ip address or the -AS (Autonomus System) handle instead of the domain name. Limited, -non-recursive support for Referral Whois (RFC 1714/2167) is also -provided. - -Requirements ------------- - -phpWhois requires PHP 4.3.0 or better with OpenSSL support to -work properly. Without SSL support you will not be able to -query domains which do not have a whois server but that have -a https based whois. Also, you can run it in lower PHP versions -but without timeout control. phpWhois will not work with PHP -versions below 4.1.0 - -Installation ------------- - -Basically, untar the distribution somewhere outside your server's -document root and make sure the directory is listed in 'include_path' -in your php.ini file, server configuration or in an .htaccess file. -If you want to test it using a web browser just copy example.php , -example.html and whois.icon.png anywhere on your server's document -root and try it. - -phpWhois is not a PHP aplication is a class that can be used in -applications. There is no need to make the installation folder -accesible to anyone but PHP, nevertheless you can install it inside -your server's document root if you like, it will work without -problems or security risks. - -Example usage -------------- - -(see example.php) - -include('whois.main.php'); - -$whois = new Whois(); -$query = 'example.com'; -$result = $whois->Lookup($query,false); -echo "
";
-print_r($result);
-echo "
"; - -If you provide the domain name to query in UTF8, then you -must use: - -$result = $whois->Lookup($query); - -If the query string is not in UTF8 then it must be in -ISO-8859-1 or IDNA support will not work. - -What you can query ------------------- - -You can use phpWhois to query domain names, ip addresses and -other information like AS, i.e, both of the following examples -work: - -$whois = new Whois(); -$result = $whois->Lookup('example.com'); - -$whois = new Whois(); -$result = $whois->Lookup('62.97.102.115'); - -$whois = new Whois(); -$result = $whois->Lookup('AS220'); - -Using special whois server --------------------------- - -Some registrars can give special access to registered whois gateways -in order to have more fine control against abusing the whois services. -The currently known whois services that offer special acccess are: - -- ripe - - The new ripe whois server software support some special parameters - that allow to pass the real client ip address. This feature is only - available to registered gateways. If you are registered you can use - this service when querying ripe ip addresses that way: - - $whois = new Whois(); - $whois->UseServer('uk','whois.ripe.net?-V{version},{ip} {query}'); - $result = $whois->Lookup('62.97.102.115'); - -- whois.isoc.org.il - - This server is also using the new ripe whois server software and - thus works the same way. If you are registered you can use this service - when querying .il domains that way: - - $whois = new Whois(); - $whois->UseServer('uk','whois.isoc.org.il?-V{version},{ip} {query}'); - $result = $whois->Lookup('example.co.uk'); - -- whois.nic.uk - - They offer what they call WHOIS2 (see http://www.nominet.org.uk/go/whois2 ) - to registered users (usually Nominet members) with a higher amount of - permited queries by hour. If you are registered you can use this service - when querying .uk domains that way: - - $whois = new Whois(); - $whois->UseServer('uk','whois.nic.uk:1043?{hname} {ip} {query}'); - $result = $whois->Lookup('example.co.uk'); - -This new feature also allows you to use a different whois server than -the preconfigured or discovered one by just calling whois->UseServer -and passing the tld and the server and args to use for the named tld. -For example you could use another whois server for .au domains that -does not limit the number of requests (but provides no owner -information) using this: - - $whois = new Whois(); - $whois->UseServer('au','whois-check.ausregistry.net.au'); - -or: - - $whois = new Whois(); - $whois->UseServer('be','whois.tucows.com'); - -to avoid the restrictions imposed by the .be whois server - -or: - - $whois = new Whois(); - $whois->UseServer('ip','whois.apnic.net'); - -to lookup an ip address at specific whois server (but loosing the -ability to get the results parsed by the appropiate handler) - -UseServer can be called as many times as necessary. Please note that -if there is a handler for that domain it will also be called but -returned data from the whois server may be different than the data -expected by the handler, and thus results could be different. - -Getting results faster ----------------------- - -If you just want to know if a domain is registered or not but do not -care about getting the real owner information you can set: - -$whois->deep_whois = false; - -this will tell phpWhois to just query one whois server. For .com, .net -and .tv domains and ip addresses this will prevent phpWhois to ask more -than one whois server, you will just know if the donmain is registered -or not and which is the registrar but not the owner information. - -UTF-8 ------ - -PHPWhois will assume that all whois servers resturn UTF-8 encoded output, -if some whois server does not return UTF-8 data, you can include it in -the NON_UTF8 array in whois.servers.php - -Notes ------ - -There is an extended class called "whois.utils.php" which contains a -debugging function called showObject(), if you showObject($result) -it will output the total layout of the returned object to the -web browser. - -The latest version of the package and a demo script resides at - - -There is also be an article describing the package on devshed.com -at - - -Support/Patches ---------------- - -If you're really stuck and can't figure something out, or you want -to contribute an extended class for one of the TLD's, file a patch -or support request in the SourceForge tracker. One of the developers -will get around to applying or responding. - - - -Credits -------- - -Mark Jeftovic -David Saez Padros -Ross Golder + +$Id: README,v 1.22 2010/08/26 10:23:39 sparc Exp $ + +Introduction +------------ + +This package contains a Whois (RFC954) library for PHP. It allows +a PHP program to create a Whois object, and obtain the output of +a whois query with the Lookup function. + +The response is an array containing, at least, an element 'rawdata', +containing the raw output from the whois request. + +In addition, if the domain belongs to a registrar for which a special +handler exists, the special handler will parse the output and make +additional elements available in the response. The keys of these +additional elements are described in the file HANDLERS. + +It fully supports IDNA (internationalized) domains names as +defined in RFC3490, RFC3491, RFC3492 and RFC3454. + +It also supports ip/AS whois queries which are very useful to trace +SPAM. You just only need to pass the doted quad ip address or the +AS (Autonomus System) handle instead of the domain name. Limited, +non-recursive support for Referral Whois (RFC 1714/2167) is also +provided. + +Requirements +------------ + +phpWhois requires PHP 4.3.0 or better with OpenSSL support to +work properly. Without SSL support you will not be able to +query domains which do not have a whois server but that have +a https based whois. Also, you can run it in lower PHP versions +but without timeout control. phpWhois will not work with PHP +versions below 4.1.0 + +Installation +------------ + +Basically, untar the distribution somewhere outside your server's +document root and make sure the directory is listed in 'include_path' +in your php.ini file, server configuration or in an .htaccess file. +If you want to test it using a web browser just copy example.php , +example.html and whois.icon.png anywhere on your server's document +root and try it. + +phpWhois is not a PHP aplication is a class that can be used in +applications. There is no need to make the installation folder +accesible to anyone but PHP, nevertheless you can install it inside +your server's document root if you like, it will work without +problems or security risks. + +Example usage +------------- + +(see example.php) + +include('whois.main.php'); + +$whois = new Whois(); +$query = 'example.com'; +$result = $whois->Lookup($query,false); +echo "
";
+print_r($result);
+echo "
"; + +If you provide the domain name to query in UTF8, then you +must use: + +$result = $whois->Lookup($query); + +If the query string is not in UTF8 then it must be in +ISO-8859-1 or IDNA support will not work. + +What you can query +------------------ + +You can use phpWhois to query domain names, ip addresses and +other information like AS, i.e, both of the following examples +work: + +$whois = new Whois(); +$result = $whois->Lookup('example.com'); + +$whois = new Whois(); +$result = $whois->Lookup('62.97.102.115'); + +$whois = new Whois(); +$result = $whois->Lookup('AS220'); + +Using special whois server +-------------------------- + +Some registrars can give special access to registered whois gateways +in order to have more fine control against abusing the whois services. +The currently known whois services that offer special acccess are: + +- ripe + + The new ripe whois server software support some special parameters + that allow to pass the real client ip address. This feature is only + available to registered gateways. If you are registered you can use + this service when querying ripe ip addresses that way: + + $whois = new Whois(); + $whois->UseServer('uk','whois.ripe.net?-V{version},{ip} {query}'); + $result = $whois->Lookup('62.97.102.115'); + +- whois.isoc.org.il + + This server is also using the new ripe whois server software and + thus works the same way. If you are registered you can use this service + when querying .il domains that way: + + $whois = new Whois(); + $whois->UseServer('uk','whois.isoc.org.il?-V{version},{ip} {query}'); + $result = $whois->Lookup('example.co.uk'); + +- whois.nic.uk + + They offer what they call WHOIS2 (see http://www.nominet.org.uk/go/whois2 ) + to registered users (usually Nominet members) with a higher amount of + permited queries by hour. If you are registered you can use this service + when querying .uk domains that way: + + $whois = new Whois(); + $whois->UseServer('uk','whois.nic.uk:1043?{hname} {ip} {query}'); + $result = $whois->Lookup('example.co.uk'); + +This new feature also allows you to use a different whois server than +the preconfigured or discovered one by just calling whois->UseServer +and passing the tld and the server and args to use for the named tld. +For example you could use another whois server for .au domains that +does not limit the number of requests (but provides no owner +information) using this: + + $whois = new Whois(); + $whois->UseServer('au','whois-check.ausregistry.net.au'); + +or: + + $whois = new Whois(); + $whois->UseServer('be','whois.tucows.com'); + +to avoid the restrictions imposed by the .be whois server + +or: + + $whois = new Whois(); + $whois->UseServer('ip','whois.apnic.net'); + +to lookup an ip address at specific whois server (but loosing the +ability to get the results parsed by the appropiate handler) + +UseServer can be called as many times as necessary. Please note that +if there is a handler for that domain it will also be called but +returned data from the whois server may be different than the data +expected by the handler, and thus results could be different. + +Getting results faster +---------------------- + +If you just want to know if a domain is registered or not but do not +care about getting the real owner information you can set: + +$whois->deep_whois = false; + +this will tell phpWhois to just query one whois server. For .com, .net +and .tv domains and ip addresses this will prevent phpWhois to ask more +than one whois server, you will just know if the donmain is registered +or not and which is the registrar but not the owner information. + +UTF-8 +----- + +PHPWhois will assume that all whois servers resturn UTF-8 encoded output, +if some whois server does not return UTF-8 data, you can include it in +the NON_UTF8 array in whois.servers.php + +Notes +----- + +There is an extended class called "whois.utils.php" which contains a +debugging function called showObject(), if you showObject($result) +it will output the total layout of the returned object to the +web browser. + +The latest version of the package and a demo script resides at + + +There is also be an article describing the package on devshed.com +at + + +Support/Patches +--------------- + +If you're really stuck and can't figure something out, or you want +to contribute an extended class for one of the TLD's, file a patch +or support request in the SourceForge tracker. One of the developers +will get around to applying or responding. + + + +Credits +------- + +Mark Jeftovic +David Saez Padros +Ross Golder diff --git a/composer.json b/classes/composer.json similarity index 96% rename from composer.json rename to classes/composer.json index 4e87ad5..246ca62 100644 --- a/composer.json +++ b/classes/composer.json @@ -1,12 +1,12 @@ -{ - "name": "simple-updates/phpwhois", - "type": "library", - "description": "This package contains a Whois (RFC954) library for PHP. It allows a PHP program to create a Whois object, and obtain the output of a whois query with the Lookup function.", - "license": "GPLv2", - "require": { - "php": ">=4.3.0" - }, - "autoload": { - "files": ["whois.main.php", "whois.utils.php"] - } -} +{ + "name": "simple-updates/phpwhois", + "type": "library", + "description": "This package contains a Whois (RFC954) library for PHP. It allows a PHP program to create a Whois object, and obtain the output of a whois query with the Lookup function.", + "license": "GPLv2", + "require": { + "php": ">=4.3.0" + }, + "autoload": { + "files": ["whois.main.php", "whois.utils.php"] + } +} diff --git a/example.cli.php b/classes/example.cli.php similarity index 96% rename from example.cli.php rename to classes/example.cli.php index e519806..3b41dc3 100644 --- a/example.cli.php +++ b/classes/example.cli.php @@ -1,40 +1,40 @@ -#!/usr/local/bin/php -n -Lookup($domain); - -print_r($result); +#!/usr/local/bin/php -n +Lookup($domain); + +print_r($result); ?> \ No newline at end of file diff --git a/handler.template.php b/classes/handler.template.php old mode 100755 new mode 100644 similarity index 96% rename from handler.template.php rename to classes/handler.template.php index 6e0b6b9..b2a87a4 --- a/handler.template.php +++ b/classes/handler.template.php @@ -1,40 +1,40 @@ - \ No newline at end of file diff --git a/npdata.ser b/classes/npdata.ser similarity index 100% rename from npdata.ser rename to classes/npdata.ser diff --git a/test.txt b/classes/test.txt similarity index 94% rename from test.txt rename to classes/test.txt index cdcae0d..277ff91 100644 --- a/test.txt +++ b/classes/test.txt @@ -1,139 +1,139 @@ -// Country domains - -ae nic.ae -ag nic.ag -am isoc.am -at nic.at -au telstra.com.au -be nic.be -bh nic.bh -br registro.br -ca cira.ca -ch creart.ch blaueskreuz.ch -cn china.cn -co nic.co -cz nic.cz -de 4ever.de ks2-hanau.de -fi ficora.fi -fj usp.ac.fj -fm dot.fm -fr nic.fr lemonade.fr -hu nic.hu -ie domainregistry.ie -il tapuz.co.il -in registry.in -is isnic.is -it nic.it -jp google.co.jp jprs.jp -li nic.li -lt domreg.lt -lu dns.lu -ly nic.ly -mx nic.mx -nl domain-registry.nl -nu nunames.nu -nz dnc.org.nz -pl nic.pl -pt dns.pt -ru nic.ru -sc nic.sc -se nic-se.se -si arnes.si -su news.su -uk olsns.co.uk -us neustar.us -ve nic.ve -ws samoanic.ws surf.ws -co.za sex.co.za -org.za sex.org.za - -// Punicode - -xn--p1ai xn--c1ad6a.xn--p1ai - -// .com/.net/.tv/.jobs - -alldomains alldomains.com -ascio ascio.com -corenic corenic.com -directnic directnic.com -domainbank domainbank.com -domaincontender domaincontender.com -afternic buydomains.com -domainpeople domainpeople.com -dotster dotster.com namesdirect.com dotregistrar.com -dreamhost dreamhost.com -encirca encirca.com -enom enom.com -fabulous fabulous.com -fastdomain fastdomain.com -gandi gandi.net -godaddy godaddy.com -iana example.com -interdomain interdominio.com -joker joker.com -markmonitor markmonitor.com -melbourneit inww.com -moniker moniker.com -name name.com -nameintel domaintools.com -namejuice namejuice.com -nameking nameking.com -names4ever names4ever.com -networksolutions networksolutions.com -nicco nicco.com -nicline nicline.com -nominalia nominalia.com -onlinenic onlinenic.com -opensrs tucows.com -ovh ovh.com -publicdomainregistry directi.com -psiusa urllog.net -register register.com -rrpproxy rrpproxy.net -schlund schlund.com -srsplus olsns.com -namevault namevault.com -tmagnic antiquea.com -tvcorp www.tv -wwdomains wildwestdomains.com -corporatedomains cscglobal.com - -// Other - -aero nic.aero -asia nic.asia -biz neulevel.biz -cat dominis.cat -coop smile.coop nic.coop -edu berkeley.edu -eu eurid.eu -info afilias.info -int who.int -me domain.me -mobi mtld.mobi -museum nic.museum -name peter.morgan.name -org example.org -pro registrypro.pro -tel nic.tel -travel whois.travel -xxx nic.xxx -za.net sex.za.net - -// IP whois - -afrinic 66.18.70.6 -apnic 218.165.121.114 -arin 207.217.120.54 -arin+rwhois 70.84.47.210 -arin+whois 63.95.254.3 -krnic 210.178.148.129 -lacnic 200.44.33.31 -lacnic(br) 200.165.206.74 -ripe 62.97.102.115 151.99.187.181 2001:630:d0:f111:203:93ff:fed1:f454 - -// ASN - -arin AS220 -krnic AS9700 +// Country domains + +ae nic.ae +ag nic.ag +am isoc.am +at nic.at +au telstra.com.au +be nic.be +bh nic.bh +br registro.br +ca cira.ca +ch creart.ch blaueskreuz.ch +cn china.cn +co nic.co +cz nic.cz +de 4ever.de ks2-hanau.de +fi ficora.fi +fj usp.ac.fj +fm dot.fm +fr nic.fr lemonade.fr +hu nic.hu +ie domainregistry.ie +il tapuz.co.il +in registry.in +is isnic.is +it nic.it +jp google.co.jp jprs.jp +li nic.li +lt domreg.lt +lu dns.lu +ly nic.ly +mx nic.mx +nl domain-registry.nl +nu nunames.nu +nz dnc.org.nz +pl nic.pl +pt dns.pt +ru nic.ru +sc nic.sc +se nic-se.se +si arnes.si +su news.su +uk olsns.co.uk +us neustar.us +ve nic.ve +ws samoanic.ws surf.ws +co.za sex.co.za +org.za sex.org.za + +// Punicode + +xn--p1ai xn--c1ad6a.xn--p1ai + +// .com/.net/.tv/.jobs + +alldomains alldomains.com +ascio ascio.com +corenic corenic.com +directnic directnic.com +domainbank domainbank.com +domaincontender domaincontender.com +afternic buydomains.com +domainpeople domainpeople.com +dotster dotster.com namesdirect.com dotregistrar.com +dreamhost dreamhost.com +encirca encirca.com +enom enom.com +fabulous fabulous.com +fastdomain fastdomain.com +gandi gandi.net +godaddy godaddy.com +iana example.com +interdomain interdominio.com +joker joker.com +markmonitor markmonitor.com +melbourneit inww.com +moniker moniker.com +name name.com +nameintel domaintools.com +namejuice namejuice.com +nameking nameking.com +names4ever names4ever.com +networksolutions networksolutions.com +nicco nicco.com +nicline nicline.com +nominalia nominalia.com +onlinenic onlinenic.com +opensrs tucows.com +ovh ovh.com +publicdomainregistry directi.com +psiusa urllog.net +register register.com +rrpproxy rrpproxy.net +schlund schlund.com +srsplus olsns.com +namevault namevault.com +tmagnic antiquea.com +tvcorp www.tv +wwdomains wildwestdomains.com +corporatedomains cscglobal.com + +// Other + +aero nic.aero +asia nic.asia +biz neulevel.biz +cat dominis.cat +coop smile.coop nic.coop +edu berkeley.edu +eu eurid.eu +info afilias.info +int who.int +me domain.me +mobi mtld.mobi +museum nic.museum +name peter.morgan.name +org example.org +pro registrypro.pro +tel nic.tel +travel whois.travel +xxx nic.xxx +za.net sex.za.net + +// IP whois + +afrinic 66.18.70.6 +apnic 218.165.121.114 +arin 207.217.120.54 +arin+rwhois 70.84.47.210 +arin+whois 63.95.254.3 +krnic 210.178.148.129 +lacnic 200.44.33.31 +lacnic(br) 200.165.206.74 +ripe 62.97.102.115 151.99.187.181 2001:630:d0:f111:203:93ff:fed1:f454 + +// ASN + +arin AS220 +krnic AS9700 diff --git a/testsuite.php b/classes/testsuite.php old mode 100755 new mode 100644 similarity index 95% rename from testsuite.php rename to classes/testsuite.php index 1f63f05..ad389f6 --- a/testsuite.php +++ b/classes/testsuite.php @@ -1,213 +1,213 @@ -#!/usr/local/bin/php -n -Lookup($domain); - - unset($result['rawdata']); - - if (!isset($results[$domain])) - { - print_r($result); - $res = get_answer("Add result for $domain"); - - if ($res) - { - // Add as it is - unset($result['regrinfo']['disclaimer']); - $results[$domain] = $result; - save_results(); - } - - } - else - { - // Compare with previous result - unset($result['regrinfo']['disclaimer']); - unset($results[$domain]['regrinfo']['disclaimer']); - - if (empty($result)) - echo "!! empty result\n"; - else - { - $diff = array_diff_assoc_recursive($result,$results[$domain]); - - if (is_array($diff)) - { - print_r($diff); - $res = get_answer("Accept differences for $domain"); - - if ($res) - { - // Add as it is - $results[$domain] = $result; - save_results(); - } - } - else - echo "Handler for domain $domain gives same results as before ...\n"; - } - } - } - -save_results(); - -//-------------------------------------------------------------------------- - -function save_results() -{ -global $results; - -$fp = fopen('testsuite.txt','wt'); -fputs($fp, serialize($results)); -fclose($fp); -} - -//-------------------------------------------------------------------------- - -function get_answer($question) -{ -echo "\n------ $question ? (y/n/a/c) "; - -while (true) - { - $res = trim(fgetc(STDIN)); - - if ($res=='a') exit(); - - if ($res=='c') - { - save_results(); - exit(); - } - if ($res=='y') return true; - if ($res=='n') return false; - } -} - -//-------------------------------------------------------------------------- - -function array_diff_assoc_recursive($array1, $array2) -{ -foreach($array1 as $key => $value) - { - if (is_array($value)) - { - if (!is_array($array2[$key])) - { - $difference[$key] = array( 'previous' => $array2[$key], 'actual' => $value); - } - else - { - $new_diff = array_diff_assoc_recursive($value, $array2[$key]); - - if ($new_diff != false) - { - $difference[$key] = $new_diff; - } - } - } - else - if (!isset($array2[$key]) || $array2[$key] != $value) - { - $difference[$key] = array( 'previous' => $array2[$key], 'actual' => $value); - } - } - -// Search missing items - -foreach($array2 as $key => $value) - { - if (!isset($array1[$key])) - $difference[$key] = array( 'previous' => $value, 'actual' => '(missing)'); - } - -return !isset($difference) ? false : $difference; -} - +#!/usr/local/bin/php -n +Lookup($domain); + + unset($result['rawdata']); + + if (!isset($results[$domain])) + { + print_r($result); + $res = get_answer("Add result for $domain"); + + if ($res) + { + // Add as it is + unset($result['regrinfo']['disclaimer']); + $results[$domain] = $result; + save_results(); + } + + } + else + { + // Compare with previous result + unset($result['regrinfo']['disclaimer']); + unset($results[$domain]['regrinfo']['disclaimer']); + + if (empty($result)) + echo "!! empty result\n"; + else + { + $diff = array_diff_assoc_recursive($result,$results[$domain]); + + if (is_array($diff)) + { + print_r($diff); + $res = get_answer("Accept differences for $domain"); + + if ($res) + { + // Add as it is + $results[$domain] = $result; + save_results(); + } + } + else + echo "Handler for domain $domain gives same results as before ...\n"; + } + } + } + +save_results(); + +//-------------------------------------------------------------------------- + +function save_results() +{ +global $results; + +$fp = fopen('testsuite.txt','wt'); +fputs($fp, serialize($results)); +fclose($fp); +} + +//-------------------------------------------------------------------------- + +function get_answer($question) +{ +echo "\n------ $question ? (y/n/a/c) "; + +while (true) + { + $res = trim(fgetc(STDIN)); + + if ($res=='a') exit(); + + if ($res=='c') + { + save_results(); + exit(); + } + if ($res=='y') return true; + if ($res=='n') return false; + } +} + +//-------------------------------------------------------------------------- + +function array_diff_assoc_recursive($array1, $array2) +{ +foreach($array1 as $key => $value) + { + if (is_array($value)) + { + if (!is_array($array2[$key])) + { + $difference[$key] = array( 'previous' => $array2[$key], 'actual' => $value); + } + else + { + $new_diff = array_diff_assoc_recursive($value, $array2[$key]); + + if ($new_diff != false) + { + $difference[$key] = $new_diff; + } + } + } + else + if (!isset($array2[$key]) || $array2[$key] != $value) + { + $difference[$key] = array( 'previous' => $array2[$key], 'actual' => $value); + } + } + +// Search missing items + +foreach($array2 as $key => $value) + { + if (!isset($array1[$key])) + $difference[$key] = array( 'previous' => $value, 'actual' => '(missing)'); + } + +return !isset($difference) ? false : $difference; +} + ?> \ No newline at end of file diff --git a/testsuite.txt b/classes/testsuite.txt similarity index 100% rename from testsuite.txt rename to classes/testsuite.txt diff --git a/whois.ae.php b/classes/whois.ae.php similarity index 96% rename from whois.ae.php rename to classes/whois.ae.php index fca86c0..a935b2e 100644 --- a/whois.ae.php +++ b/classes/whois.ae.php @@ -1,58 +1,58 @@ - 'domain.name', - 'Registrar Name:' => 'domain.sponsor', - 'Status:' => 'domain.status', - 'Registrant Contact ID:' => 'owner.handle', - 'Registrant Contact Name:' => 'owner.name', - 'Tech Contact Name:' => 'tech.name', - 'Tech Contact ID:' => 'tech.handle', - 'Name Server:' => 'domain.nserver.' - ); - - $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items, 'ymd'); - - $r['regyinfo'] = array( - 'referrer' => 'http://www.nic.ae', - 'registrar' => 'UAENIC' - ); - - return $r; - } - } -?> + 'domain.name', + 'Registrar Name:' => 'domain.sponsor', + 'Status:' => 'domain.status', + 'Registrant Contact ID:' => 'owner.handle', + 'Registrant Contact Name:' => 'owner.name', + 'Tech Contact Name:' => 'tech.name', + 'Tech Contact ID:' => 'tech.handle', + 'Name Server:' => 'domain.nserver.' + ); + + $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items, 'ymd'); + + $r['regyinfo'] = array( + 'referrer' => 'http://www.nic.ae', + 'registrar' => 'UAENIC' + ); + + return $r; + } + } +?> diff --git a/whois.aero.php b/classes/whois.aero.php old mode 100755 new mode 100644 similarity index 96% rename from whois.aero.php rename to classes/whois.aero.php index 963a4a1..cc73409 --- a/whois.aero.php +++ b/classes/whois.aero.php @@ -1,45 +1,45 @@ - 'http://www.nic.aero', - 'registrar' => 'Societe Internationale de Telecommunications Aeronautiques SC' - ); - return $r; - } - } + 'http://www.nic.aero', + 'registrar' => 'Societe Internationale de Telecommunications Aeronautiques SC' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.ag.php b/classes/whois.ag.php old mode 100755 new mode 100644 similarity index 96% rename from whois.ag.php rename to classes/whois.ag.php index 3f663fe..044b138 --- a/whois.ag.php +++ b/classes/whois.ag.php @@ -1,45 +1,45 @@ - 'http://www.nic.ag', - 'registrar' => 'Nic AG' - ); - return $r; - } - } + 'http://www.nic.ag', + 'registrar' => 'Nic AG' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.am.php b/classes/whois.am.php similarity index 100% rename from whois.am.php rename to classes/whois.am.php diff --git a/whois.asia.php b/classes/whois.asia.php similarity index 96% rename from whois.asia.php rename to classes/whois.asia.php index c9fa918..b7a2623 100644 --- a/whois.asia.php +++ b/classes/whois.asia.php @@ -1,44 +1,44 @@ -'http://www.dotasia.org/', - 'registrar' => 'DotAsia' - ); - return $r; - } - } +'http://www.dotasia.org/', + 'registrar' => 'DotAsia' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.at.php b/classes/whois.at.php similarity index 96% rename from whois.at.php rename to classes/whois.at.php index 639c267..eb63376 100644 --- a/whois.at.php +++ b/classes/whois.at.php @@ -1,102 +1,102 @@ - 'fax', - 'e-mail' => 'email', - 'nic-hdl' => 'handle', - 'person' => 'name', - 'personname' => 'name', - 'street address' => 'address.street', - 'city' => 'address.city', - 'postal code' => 'address.pcode', - 'country' => 'address.country' - ); - - $contacts = array( - 'registrant' => 'owner', - 'admin-c' => 'admin', - 'tech-c' => 'tech', - 'billing-c' => 'billing', - 'zone-c' => 'zone' - ); - - $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain', 'Ymd'); - - if (isset($reg['domain']['remarks'])) - unset($reg['domain']['remarks']); - - if (isset($reg['domain']['descr'])) - { - while (list($key, $val) = each($reg['domain']['descr'])) - { - $v = trim(substr(strstr($val, ':'), 1)); - if (strstr($val, '[organization]:')) - { - $reg['owner']['organization'] = $v; - continue; - } - if (strstr($val, '[phone]:')) - { - $reg['owner']['phone'] = $v; - continue; - } - if (strstr($val, '[fax-no]:')) - { - $reg['owner']['fax'] = $v; - continue; - } - if (strstr($val, '[e-mail]:')) - { - $reg['owner']['email'] = $v; - continue; - } - - $reg['owner']['address'][$key] = $v; - } - - if (isset($reg['domain']['descr'])) unset($reg['domain']['descr']); - } - - $r['regrinfo'] = $reg; - $r['regyinfo'] = array( - 'referrer' => 'http://www.nic.at', - 'registrar' => 'NIC-AT' - ); - return $r; - } - } -?> + 'fax', + 'e-mail' => 'email', + 'nic-hdl' => 'handle', + 'person' => 'name', + 'personname' => 'name', + 'street address' => 'address.street', + 'city' => 'address.city', + 'postal code' => 'address.pcode', + 'country' => 'address.country' + ); + + $contacts = array( + 'registrant' => 'owner', + 'admin-c' => 'admin', + 'tech-c' => 'tech', + 'billing-c' => 'billing', + 'zone-c' => 'zone' + ); + + $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain', 'Ymd'); + + if (isset($reg['domain']['remarks'])) + unset($reg['domain']['remarks']); + + if (isset($reg['domain']['descr'])) + { + while (list($key, $val) = each($reg['domain']['descr'])) + { + $v = trim(substr(strstr($val, ':'), 1)); + if (strstr($val, '[organization]:')) + { + $reg['owner']['organization'] = $v; + continue; + } + if (strstr($val, '[phone]:')) + { + $reg['owner']['phone'] = $v; + continue; + } + if (strstr($val, '[fax-no]:')) + { + $reg['owner']['fax'] = $v; + continue; + } + if (strstr($val, '[e-mail]:')) + { + $reg['owner']['email'] = $v; + continue; + } + + $reg['owner']['address'][$key] = $v; + } + + if (isset($reg['domain']['descr'])) unset($reg['domain']['descr']); + } + + $r['regrinfo'] = $reg; + $r['regyinfo'] = array( + 'referrer' => 'http://www.nic.at', + 'registrar' => 'NIC-AT' + ); + return $r; + } + } +?> diff --git a/whois.au.php b/classes/whois.au.php similarity index 97% rename from whois.au.php rename to classes/whois.au.php index ae28c6a..c813db0 100644 --- a/whois.au.php +++ b/classes/whois.au.php @@ -1,63 +1,63 @@ - 'domain.name', - 'Last Modified:' => 'domain.changed', - 'Registrar Name:' => 'domain.sponsor', - 'Status:' => 'domain.status', - 'Domain ROID:' => 'domain.handle', - 'Registrant:' => 'owner.organization', - 'Registrant Contact ID:' => 'owner.handle', - 'Registrant Contact Email:' => 'owner.email', - 'Registrant Contact Name:' => 'owner.name', - 'Tech Contact Name:' => 'tech.name', - 'Tech Contact Email:' => 'tech.email', - 'Tech Contact ID:' => 'tech.handle', - 'Name Server:' => 'domain.nserver.' - ); - - $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items); - $r['regyinfo'] = array( - 'referrer' => 'http://www.aunic.net', - 'registrar' => 'AU-NIC' - ); - return $r; - } - } - -?> + 'domain.name', + 'Last Modified:' => 'domain.changed', + 'Registrar Name:' => 'domain.sponsor', + 'Status:' => 'domain.status', + 'Domain ROID:' => 'domain.handle', + 'Registrant:' => 'owner.organization', + 'Registrant Contact ID:' => 'owner.handle', + 'Registrant Contact Email:' => 'owner.email', + 'Registrant Contact Name:' => 'owner.name', + 'Tech Contact Name:' => 'tech.name', + 'Tech Contact Email:' => 'tech.email', + 'Tech Contact ID:' => 'tech.handle', + 'Name Server:' => 'domain.nserver.' + ); + + $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items); + $r['regyinfo'] = array( + 'referrer' => 'http://www.aunic.net', + 'registrar' => 'AU-NIC' + ); + return $r; + } + } + +?> diff --git a/whois.be.php b/classes/whois.be.php similarity index 96% rename from whois.be.php rename to classes/whois.be.php index 0fb5994..86b8c18 100644 --- a/whois.be.php +++ b/classes/whois.be.php @@ -1,77 +1,77 @@ - 'Domain:', - 'domain.status' => 'Status:', - 'domain.nserver' => 'Nameservers:', - 'domain.created' => 'Registered:', - 'owner' => 'Licensee:', - 'admin' => 'Onsite Contacts:', - 'tech' => 'Registrar Technical Contacts:', - 'agent' => 'Registrar:', - 'agent.uri' => 'Website:' - ); - - $trans = array( - 'company name2:' => '' - ); - - $r['regrinfo'] = get_blocks($data['rawdata'], $items); - - if ($r['regrinfo']['domain']['status'] != 'AVAILABLE') - { - $r['regrinfo']['registered'] = 'yes'; - $r['regrinfo'] = get_contacts($r['regrinfo'],$trans); - - if (isset($r['regrinfo']['agent'])) - { - $sponsor = get_contact($r['regrinfo']['agent'],$trans); - unset($r['regrinfo']['agent']); - $r['regrinfo']['domain']['sponsor'] = $sponsor; - } - - $r = format_dates($r, '-mdy'); - } - else - $r['regrinfo']['registered'] = 'no'; - - $r['regyinfo']['referrer'] = 'http://www.domain-registry.nl'; - $r['regyinfo']['registrar'] = 'DNS Belgium'; - return $r; - } - } -?> + 'Domain:', + 'domain.status' => 'Status:', + 'domain.nserver' => 'Nameservers:', + 'domain.created' => 'Registered:', + 'owner' => 'Licensee:', + 'admin' => 'Onsite Contacts:', + 'tech' => 'Registrar Technical Contacts:', + 'agent' => 'Registrar:', + 'agent.uri' => 'Website:' + ); + + $trans = array( + 'company name2:' => '' + ); + + $r['regrinfo'] = get_blocks($data['rawdata'], $items); + + if ($r['regrinfo']['domain']['status'] != 'AVAILABLE') + { + $r['regrinfo']['registered'] = 'yes'; + $r['regrinfo'] = get_contacts($r['regrinfo'],$trans); + + if (isset($r['regrinfo']['agent'])) + { + $sponsor = get_contact($r['regrinfo']['agent'],$trans); + unset($r['regrinfo']['agent']); + $r['regrinfo']['domain']['sponsor'] = $sponsor; + } + + $r = format_dates($r, '-mdy'); + } + else + $r['regrinfo']['registered'] = 'no'; + + $r['regyinfo']['referrer'] = 'http://www.domain-registry.nl'; + $r['regyinfo']['registrar'] = 'DNS Belgium'; + return $r; + } + } +?> diff --git a/whois.bh.php b/classes/whois.bh.php similarity index 97% rename from whois.bh.php rename to classes/whois.bh.php index 937c36e..14de69f 100644 --- a/whois.bh.php +++ b/classes/whois.bh.php @@ -1,59 +1,59 @@ - - -Maintained by David Saez - -For the most recent version of this package visit: - -http://www.phpwhois.org - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -if (!defined('__BH_HANDLER__')) - define('__BH_HANDLER__', 1); - -require_once('whois.parser.php'); - -class bh_handler - { - function parse($data_str, $query) - { - $items = array( - 'Sponsoring Registrar Name:' => 'domain.sponsor.name', - 'Sponsoring Registrar Email:' => 'domain.sponsor.email', - 'Sponsoring Registrar Uri:' => 'domain.sponsor.uri', - 'Sponsoring Registrar Phone:' => 'domain.sponsor.phone' - ); - $i = generic_parser_b($data_str['rawdata'], $items); - $r['regrinfo'] = generic_parser_b($data_str['rawdata']); - if (isset($r['regrinfo']['domain']) - && is_array($r['regrinfo']['domain'])) - $r['regrinfo']['domain']['sponsor'] = $i['domain']['sponsor']; - if (empty($r['regrinfo']['domain']['created'])) - $r['regrinfo']['registered'] = 'no'; - else - $r['regrinfo']['registered'] = 'yes'; - $r['regyinfo'] = array( - 'referrer' => 'http://www.nic.bh/', - 'registrar' => 'NIC-BH' - ); - return $r; - } - } + + +Maintained by David Saez + +For the most recent version of this package visit: + +http://www.phpwhois.org + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +if (!defined('__BH_HANDLER__')) + define('__BH_HANDLER__', 1); + +require_once('whois.parser.php'); + +class bh_handler + { + function parse($data_str, $query) + { + $items = array( + 'Sponsoring Registrar Name:' => 'domain.sponsor.name', + 'Sponsoring Registrar Email:' => 'domain.sponsor.email', + 'Sponsoring Registrar Uri:' => 'domain.sponsor.uri', + 'Sponsoring Registrar Phone:' => 'domain.sponsor.phone' + ); + $i = generic_parser_b($data_str['rawdata'], $items); + $r['regrinfo'] = generic_parser_b($data_str['rawdata']); + if (isset($r['regrinfo']['domain']) + && is_array($r['regrinfo']['domain'])) + $r['regrinfo']['domain']['sponsor'] = $i['domain']['sponsor']; + if (empty($r['regrinfo']['domain']['created'])) + $r['regrinfo']['registered'] = 'no'; + else + $r['regrinfo']['registered'] = 'yes'; + $r['regyinfo'] = array( + 'referrer' => 'http://www.nic.bh/', + 'registrar' => 'NIC-BH' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.biz.php b/classes/whois.biz.php similarity index 96% rename from whois.biz.php rename to classes/whois.biz.php index 7e28b18..74ccba1 100644 --- a/whois.biz.php +++ b/classes/whois.biz.php @@ -1,45 +1,45 @@ - 'http://www.neulevel.biz', - 'registrar' => 'NEULEVEL' - ); - return $r; - } - } -?> + 'http://www.neulevel.biz', + 'registrar' => 'NEULEVEL' + ); + return $r; + } + } +?> diff --git a/whois.br.php b/classes/whois.br.php similarity index 96% rename from whois.br.php rename to classes/whois.br.php index 63d96d1..7055798 100644 --- a/whois.br.php +++ b/classes/whois.br.php @@ -1,84 +1,84 @@ - 'fax', - 'e-mail' => 'email', - 'nic-hdl-br' => 'handle', - 'person' => 'name', - 'netname' => 'name', - 'domain' => 'name', - 'updated' => '' - ); - - $contacts = array( - 'owner-c' => 'owner', - 'tech-c' => 'tech', - 'admin-c' => 'admin', - 'billing-c' => 'billing' - ); - - $r = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain', 'Ymd'); - - if (in_array('Permission denied.', $r['disclaimer'])) - { - $r['registered'] = 'unknown'; - return $r; - } - - if (isset($r['domain']['nsstat'])) unset($r['domain']['nsstat']); - if (isset($r['domain']['nslastaa'])) unset($r['domain']['nslastaa']); - - if (isset($r['domain']['owner'])) - { - $r['owner']['organization'] = $r['domain']['owner']; - unset($r['domain']['owner']); - } - - if (isset($r['domain']['responsible'])) unset($r['domain']['responsible']); - if (isset($r['domain']['address'])) unset($r['domain']['address']); - if (isset($r['domain']['phone'])) unset($r['domain']['phone']); - - $a['regrinfo'] = $r; - $a['regyinfo'] = array( - 'registrar' => 'BR-NIC', - 'referrer' => 'http://www.nic.br' - ); - return $a; - } - } -?> + 'fax', + 'e-mail' => 'email', + 'nic-hdl-br' => 'handle', + 'person' => 'name', + 'netname' => 'name', + 'domain' => 'name', + 'updated' => '' + ); + + $contacts = array( + 'owner-c' => 'owner', + 'tech-c' => 'tech', + 'admin-c' => 'admin', + 'billing-c' => 'billing' + ); + + $r = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain', 'Ymd'); + + if (in_array('Permission denied.', $r['disclaimer'])) + { + $r['registered'] = 'unknown'; + return $r; + } + + if (isset($r['domain']['nsstat'])) unset($r['domain']['nsstat']); + if (isset($r['domain']['nslastaa'])) unset($r['domain']['nslastaa']); + + if (isset($r['domain']['owner'])) + { + $r['owner']['organization'] = $r['domain']['owner']; + unset($r['domain']['owner']); + } + + if (isset($r['domain']['responsible'])) unset($r['domain']['responsible']); + if (isset($r['domain']['address'])) unset($r['domain']['address']); + if (isset($r['domain']['phone'])) unset($r['domain']['phone']); + + $a['regrinfo'] = $r; + $a['regyinfo'] = array( + 'registrar' => 'BR-NIC', + 'referrer' => 'http://www.nic.br' + ); + return $a; + } + } +?> diff --git a/whois.ca.php b/classes/whois.ca.php similarity index 96% rename from whois.ca.php rename to classes/whois.ca.php index 92049a7..7b2f4ce 100644 --- a/whois.ca.php +++ b/classes/whois.ca.php @@ -1,76 +1,76 @@ - 'Registrant:', - 'admin' => 'Administrative contact:', - 'tech' => 'Technical contact:', - 'domain.sponsor' => 'Registrar:', - 'domain.nserver' => 'Name servers:', - 'domain.status' => 'Domain status:', - 'domain.created' => 'Creation date:', - 'domain.expires' => 'Expiry date:', - 'domain.changed' => 'Updated date:' - ); - - $extra = array( - 'postal address:' => 'address.0', - 'job title:' => '', - 'number:' => 'handle', - 'description:' => 'organization' - ); - - $r['regrinfo'] = easy_parser($data_str['rawdata'],$items,'ymd',$extra); - - if (!empty($r['regrinfo']['domain']['sponsor'])) - { - list($v,$reg) = explode(':',$r['regrinfo']['domain']['sponsor'][0]); - $r['regrinfo']['domain']['sponsor'] = trim($reg); - } - - if (empty($r['regrinfo']['domain']['status']) || $r['regrinfo']['domain']['status'] == 'available') - $r['regrinfo']['registered'] = 'no'; - else - $r['regrinfo']['registered'] = 'yes'; - - $r['regyinfo'] = array( - 'registrar' => 'CIRA', - 'referrer' => 'http://www.cira.ca/' - ); - return $r; - } - } + 'Registrant:', + 'admin' => 'Administrative contact:', + 'tech' => 'Technical contact:', + 'domain.sponsor' => 'Registrar:', + 'domain.nserver' => 'Name servers:', + 'domain.status' => 'Domain status:', + 'domain.created' => 'Creation date:', + 'domain.expires' => 'Expiry date:', + 'domain.changed' => 'Updated date:' + ); + + $extra = array( + 'postal address:' => 'address.0', + 'job title:' => '', + 'number:' => 'handle', + 'description:' => 'organization' + ); + + $r['regrinfo'] = easy_parser($data_str['rawdata'],$items,'ymd',$extra); + + if (!empty($r['regrinfo']['domain']['sponsor'])) + { + list($v,$reg) = explode(':',$r['regrinfo']['domain']['sponsor'][0]); + $r['regrinfo']['domain']['sponsor'] = trim($reg); + } + + if (empty($r['regrinfo']['domain']['status']) || $r['regrinfo']['domain']['status'] == 'available') + $r['regrinfo']['registered'] = 'no'; + else + $r['regrinfo']['registered'] = 'yes'; + + $r['regyinfo'] = array( + 'registrar' => 'CIRA', + 'referrer' => 'http://www.cira.ca/' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.cat.php b/classes/whois.cat.php old mode 100755 new mode 100644 similarity index 96% rename from whois.cat.php rename to classes/whois.cat.php index c107cf9..b89a492 --- a/whois.cat.php +++ b/classes/whois.cat.php @@ -1,47 +1,47 @@ - \ No newline at end of file diff --git a/whois.ch.php b/classes/whois.ch.php similarity index 96% rename from whois.ch.php rename to classes/whois.ch.php index 90f6c36..1aa4f5e 100644 --- a/whois.ch.php +++ b/classes/whois.ch.php @@ -1,82 +1,82 @@ - 'Holder of domain name:', - 'domain.name' => 'Domain name:', - 'domain.created' => 'Date of last registration:', - 'domain.changed' => 'Date of last modification:', - 'tech' => 'Technical contact:', - 'domain.nserver' => 'Name servers:', - 'domain.dnssec' => 'DNSSEC:' - ); - - $trans = array( - 'contractual language:' => 'language' - ); - - $r['regrinfo'] = get_blocks($data_str['rawdata'], $items); - - if (!empty($r['regrinfo']['domain']['name'])) - { - $r['regrinfo'] = get_contacts($r['regrinfo'],$trans); - - $r['regrinfo']['domain']['name'] = $r['regrinfo']['domain']['name'][0]; - - if (isset($r['regrinfo']['domain']['changed'][0])) - $r['regrinfo']['domain']['changed'] = get_date($r['regrinfo']['domain']['changed'][0], 'dmy'); - - if (isset($r['regrinfo']['domain']['created'][0])) - $r['regrinfo']['domain']['created'] = get_date($r['regrinfo']['domain']['created'][0], 'dmy'); - - $r['regrinfo']['registered'] = 'yes'; - } - else - { - $r = ''; - $r['regrinfo']['registered'] = 'no'; - } - - $r['regyinfo'] = array( - 'referrer' => 'http://www.nic.ch', - 'registrar' => 'SWITCH Domain Name Registration' - ); - return $r; - } - } -?> + 'Holder of domain name:', + 'domain.name' => 'Domain name:', + 'domain.created' => 'Date of last registration:', + 'domain.changed' => 'Date of last modification:', + 'tech' => 'Technical contact:', + 'domain.nserver' => 'Name servers:', + 'domain.dnssec' => 'DNSSEC:' + ); + + $trans = array( + 'contractual language:' => 'language' + ); + + $r['regrinfo'] = get_blocks($data_str['rawdata'], $items); + + if (!empty($r['regrinfo']['domain']['name'])) + { + $r['regrinfo'] = get_contacts($r['regrinfo'],$trans); + + $r['regrinfo']['domain']['name'] = $r['regrinfo']['domain']['name'][0]; + + if (isset($r['regrinfo']['domain']['changed'][0])) + $r['regrinfo']['domain']['changed'] = get_date($r['regrinfo']['domain']['changed'][0], 'dmy'); + + if (isset($r['regrinfo']['domain']['created'][0])) + $r['regrinfo']['domain']['created'] = get_date($r['regrinfo']['domain']['created'][0], 'dmy'); + + $r['regrinfo']['registered'] = 'yes'; + } + else + { + $r = ''; + $r['regrinfo']['registered'] = 'no'; + } + + $r['regyinfo'] = array( + 'referrer' => 'http://www.nic.ch', + 'registrar' => 'SWITCH Domain Name Registration' + ); + return $r; + } + } +?> diff --git a/whois.cl.php b/classes/whois.cl.php similarity index 96% rename from whois.cl.php rename to classes/whois.cl.php index f6874d7..d296f57 100644 --- a/whois.cl.php +++ b/classes/whois.cl.php @@ -1,56 +1,56 @@ - '(Administrative Contact)', - 'tech' => 'Contacto Técnico (Technical Contact):', - 'domain.nserver' => 'Servidores de nombre (Domain servers):', - 'domain.changed' => '(Database last updated on):' - ); - - $trans = array( - 'organización:' => 'organization', - 'nombre :' => 'name'); - - $r['regrinfo'] = easy_parser($data_str['rawdata'], $items, 'd-m-y', $trans); - $r['regyinfo'] = array( - 'referrer' => 'http://www.nic.cl', - 'registrar' => 'NIC Chile' - ); - return $r; - } - } -?> + '(Administrative Contact)', + 'tech' => 'Contacto Técnico (Technical Contact):', + 'domain.nserver' => 'Servidores de nombre (Domain servers):', + 'domain.changed' => '(Database last updated on):' + ); + + $trans = array( + 'organización:' => 'organization', + 'nombre :' => 'name'); + + $r['regrinfo'] = easy_parser($data_str['rawdata'], $items, 'd-m-y', $trans); + $r['regyinfo'] = array( + 'referrer' => 'http://www.nic.cl', + 'registrar' => 'NIC Chile' + ); + return $r; + } + } +?> diff --git a/whois.client.php b/classes/whois.client.php old mode 100755 new mode 100644 similarity index 100% rename from whois.client.php rename to classes/whois.client.php diff --git a/whois.cn.php b/classes/whois.cn.php similarity index 97% rename from whois.cn.php rename to classes/whois.cn.php index 9c9a736..913720a 100644 --- a/whois.cn.php +++ b/classes/whois.cn.php @@ -1,91 +1,91 @@ - 'domain.name', - 'Domain Status:' => 'domain.status.', - 'ROID:' => 'domain.handle', - 'Name Server:' => 'domain.nserver.', - 'Registration Date:' => 'domain.created', - 'Expiration Date:' => 'domain.expires', - 'Sponsoring Registrar:' => 'domain.sponsor', - 'Registrant Name:' => 'owner.name', - 'Registrant Organization:' => 'owner.organization', - 'Registrant Address:' => 'owner.address.address', - 'Registrant Postal Code:' => 'owner.address.pcode', - 'Registrant City:' => 'owner.address.city', - 'Registrant Country Code:' => 'owner.address.country', - 'Registrant Email:' => 'owner.email', - 'Registrant Phone Number:' => 'owner.phone', - 'Registrant Fax:' => 'owner.fax', - 'Administrative Name:' => 'admin.name', - 'Administrative Organization:' => 'admin.organization', - 'Administrative Address:' => 'admin.address.address', - 'Administrative Postal Code:' => 'admin.address.pcode', - 'Administrative City:' => 'admin.address.city', - 'Administrative Country Code:' => 'admin.address.country', - 'Administrative Email:' => 'admin.email', - 'Administrative Phone Number:' => 'admin.phone', - 'Administrative Fax:' => 'admin.fax', - 'Technical Name:' => 'tech.name', - 'Technical Organization:' => 'tech.organization', - 'Technical Address:' => 'tech.address.address', - 'Technical Postal Code:' => 'tech.address.pcode', - 'Technical City:' => 'tech.address.city', - 'tec-country:' => 'tech.address.country', - 'Technical Email:' => 'tech.email', - 'Technical Phone Number:' => 'tech.phone', - 'Technical Fax:' => 'tech.fax', - 'Billing Name:' => 'billing.name', - 'Billing Organization:' => 'billing.organization', - 'Billing Address:' => 'billing.address.address', - 'Billing Postal Code:' => 'billing.address.pcode', - 'Billing City:' => 'billing.address.city', - 'Billing Country Code:' => 'billing.address.country', - 'Billing Email:' => 'billing.email', - 'Billing Phone Number:' => 'billing.phone', - 'Billing Fax:' => 'billing.fax' - ); - - $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items, 'ymd'); - $r['regyinfo'] = array( - 'referrer' => 'http://www.cnnic.net.cn', - 'registrar' => 'China NIC' - ); - return $r; - } - } + 'domain.name', + 'Domain Status:' => 'domain.status.', + 'ROID:' => 'domain.handle', + 'Name Server:' => 'domain.nserver.', + 'Registration Date:' => 'domain.created', + 'Expiration Date:' => 'domain.expires', + 'Sponsoring Registrar:' => 'domain.sponsor', + 'Registrant Name:' => 'owner.name', + 'Registrant Organization:' => 'owner.organization', + 'Registrant Address:' => 'owner.address.address', + 'Registrant Postal Code:' => 'owner.address.pcode', + 'Registrant City:' => 'owner.address.city', + 'Registrant Country Code:' => 'owner.address.country', + 'Registrant Email:' => 'owner.email', + 'Registrant Phone Number:' => 'owner.phone', + 'Registrant Fax:' => 'owner.fax', + 'Administrative Name:' => 'admin.name', + 'Administrative Organization:' => 'admin.organization', + 'Administrative Address:' => 'admin.address.address', + 'Administrative Postal Code:' => 'admin.address.pcode', + 'Administrative City:' => 'admin.address.city', + 'Administrative Country Code:' => 'admin.address.country', + 'Administrative Email:' => 'admin.email', + 'Administrative Phone Number:' => 'admin.phone', + 'Administrative Fax:' => 'admin.fax', + 'Technical Name:' => 'tech.name', + 'Technical Organization:' => 'tech.organization', + 'Technical Address:' => 'tech.address.address', + 'Technical Postal Code:' => 'tech.address.pcode', + 'Technical City:' => 'tech.address.city', + 'tec-country:' => 'tech.address.country', + 'Technical Email:' => 'tech.email', + 'Technical Phone Number:' => 'tech.phone', + 'Technical Fax:' => 'tech.fax', + 'Billing Name:' => 'billing.name', + 'Billing Organization:' => 'billing.organization', + 'Billing Address:' => 'billing.address.address', + 'Billing Postal Code:' => 'billing.address.pcode', + 'Billing City:' => 'billing.address.city', + 'Billing Country Code:' => 'billing.address.country', + 'Billing Email:' => 'billing.email', + 'Billing Phone Number:' => 'billing.phone', + 'Billing Fax:' => 'billing.fax' + ); + + $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items, 'ymd'); + $r['regyinfo'] = array( + 'referrer' => 'http://www.cnnic.net.cn', + 'registrar' => 'China NIC' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.co.php b/classes/whois.co.php similarity index 96% rename from whois.co.php rename to classes/whois.co.php index f7751d7..2ff0bd3 100644 --- a/whois.co.php +++ b/classes/whois.co.php @@ -1,43 +1,43 @@ - \ No newline at end of file diff --git a/whois.co.za.php b/classes/whois.co.za.php similarity index 97% rename from whois.co.za.php rename to classes/whois.co.za.php index bd73225..3e79755 100644 --- a/whois.co.za.php +++ b/classes/whois.co.za.php @@ -1,73 +1,73 @@ - 'domain.changed', - '1a. domain :' => 'domain.name', - '2b. registrantpostaladdress:' => 'owner.address.address.0', - '2f. billingaccount :' => 'billing.name', - '2g. billingemail :' => 'billing.email', - '2i. invoiceaddress :' => 'billing.address', - '2j. registrantphone :' => 'owner.phone', - '2k. registrantfax :' => 'owner.fax', - '2l. registrantemail :' => 'owner.email', - '4a. admin :' => 'admin.name', - '4c. admincompany :' => 'admin.organization', - '4d. adminpostaladdr :' => 'admin.address', - '4e. adminphone :' => 'admin.phone', - '4f. adminfax :' => 'admin.fax', - '4g. adminemail :' => 'admin.email', - '5a. tec :' => 'tech.name', - '5c. teccompany :' => 'tech.organization', - '5d. tecpostaladdr :' => 'tech.address', - '5e. tecphone :' => 'tech.phone', - '5f. tecfax :' => 'tech.fax', - '5g. tecemail :' => 'tech.email', - '6a. primnsfqdn :' => 'domain.nserver.0', - '6e. secns1fqdn :' => 'domain.nserver.1', - '6i. secns2fqdn :' => 'domain.nserver.2', - '6m. secns3fqdn :' => 'domain.nserver.3', - '6q. secns4fqdn :' => 'domain.nserver.4' - ); - - $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items); - - $r['regyinfo']['referrer'] = 'http://www.co.za'; - $r['regyinfo']['registrar'] = 'UniForum Association'; - return $r; - } - } + 'domain.changed', + '1a. domain :' => 'domain.name', + '2b. registrantpostaladdress:' => 'owner.address.address.0', + '2f. billingaccount :' => 'billing.name', + '2g. billingemail :' => 'billing.email', + '2i. invoiceaddress :' => 'billing.address', + '2j. registrantphone :' => 'owner.phone', + '2k. registrantfax :' => 'owner.fax', + '2l. registrantemail :' => 'owner.email', + '4a. admin :' => 'admin.name', + '4c. admincompany :' => 'admin.organization', + '4d. adminpostaladdr :' => 'admin.address', + '4e. adminphone :' => 'admin.phone', + '4f. adminfax :' => 'admin.fax', + '4g. adminemail :' => 'admin.email', + '5a. tec :' => 'tech.name', + '5c. teccompany :' => 'tech.organization', + '5d. tecpostaladdr :' => 'tech.address', + '5e. tecphone :' => 'tech.phone', + '5f. tecfax :' => 'tech.fax', + '5g. tecemail :' => 'tech.email', + '6a. primnsfqdn :' => 'domain.nserver.0', + '6e. secns1fqdn :' => 'domain.nserver.1', + '6i. secns2fqdn :' => 'domain.nserver.2', + '6m. secns3fqdn :' => 'domain.nserver.3', + '6q. secns4fqdn :' => 'domain.nserver.4' + ); + + $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items); + + $r['regyinfo']['referrer'] = 'http://www.co.za'; + $r['regyinfo']['registrar'] = 'UniForum Association'; + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.coop.php b/classes/whois.coop.php old mode 100755 new mode 100644 similarity index 96% rename from whois.coop.php rename to classes/whois.coop.php index f16a7ef..135d5ab --- a/whois.coop.php +++ b/classes/whois.coop.php @@ -1,106 +1,106 @@ - 'Contact Type: registrant', - 'admin' => 'Contact Type: admin', - 'tech' => 'Contact Type: tech', - 'billing' => 'Contact Type: billing', - 'domain.name' => 'Domain Name:', - 'domain.handle' => 'Domain ID:', - 'domain.expires' => 'Expiry Date:', - 'domain.created' => 'Created:', - 'domain.changed' => 'Last updated:', - 'domain.status' => 'Domain Status:', - 'domain.sponsor' => 'Sponsoring registrar:', - 'domain.nserver.' => 'Host Name:' - ); - - $translate = array( - 'Contact ID:' => 'handle', - 'Name:' => 'name', - 'Organisation:' => 'organization', - 'Street 1:' => 'address.street.0', - 'Street 2:' => 'address.street.1', - 'Street 3:' => 'address.street.2', - 'City:' => 'address.city', - 'State/Province:' => 'address.state', - 'Postal code:' => 'address.pcode', - 'Country:' => 'address.country', - 'Voice:' => 'phone', - 'Fax:' => 'fax', - 'Email:' => 'email' - ); - - $blocks = get_blocks($data_str['rawdata'],$items); - - $r=array(); - - if (isset($blocks['domain'])) - { - $r['regrinfo']['domain'] = format_dates($blocks['domain'],'dmy'); - $r['regrinfo']['registered'] = 'yes'; - - if (isset($blocks['owner'])) - { - $r['regrinfo']['owner'] = generic_parser_b($blocks['owner'],$translate,'dmy',false); - - if (isset($blocks['tech'])) - $r['regrinfo']['tech'] = generic_parser_b($blocks['tech'],$translate,'dmy',false); - - if (isset($blocks['admin'])) - $r['regrinfo']['admin'] = generic_parser_b($blocks['admin'],$translate,'dmy',false); - - if (isset($blocks['billing'])) - $r['regrinfo']['billing'] = generic_parser_b($blocks['billing'],$translate,'dmy',false); - } - else - { - $r['regrinfo']['owner'] = generic_parser_b($data_str['rawdata'],$translate,'dmy',false); - } - } - else - $r['regrinfo']['registered'] = 'no'; - - $r['regyinfo'] = array( - 'referrer' => 'http://www.nic.coop', - 'registrar' => '.coop registry' - ); - return $r; - } - } -?> + 'Contact Type: registrant', + 'admin' => 'Contact Type: admin', + 'tech' => 'Contact Type: tech', + 'billing' => 'Contact Type: billing', + 'domain.name' => 'Domain Name:', + 'domain.handle' => 'Domain ID:', + 'domain.expires' => 'Expiry Date:', + 'domain.created' => 'Created:', + 'domain.changed' => 'Last updated:', + 'domain.status' => 'Domain Status:', + 'domain.sponsor' => 'Sponsoring registrar:', + 'domain.nserver.' => 'Host Name:' + ); + + $translate = array( + 'Contact ID:' => 'handle', + 'Name:' => 'name', + 'Organisation:' => 'organization', + 'Street 1:' => 'address.street.0', + 'Street 2:' => 'address.street.1', + 'Street 3:' => 'address.street.2', + 'City:' => 'address.city', + 'State/Province:' => 'address.state', + 'Postal code:' => 'address.pcode', + 'Country:' => 'address.country', + 'Voice:' => 'phone', + 'Fax:' => 'fax', + 'Email:' => 'email' + ); + + $blocks = get_blocks($data_str['rawdata'],$items); + + $r=array(); + + if (isset($blocks['domain'])) + { + $r['regrinfo']['domain'] = format_dates($blocks['domain'],'dmy'); + $r['regrinfo']['registered'] = 'yes'; + + if (isset($blocks['owner'])) + { + $r['regrinfo']['owner'] = generic_parser_b($blocks['owner'],$translate,'dmy',false); + + if (isset($blocks['tech'])) + $r['regrinfo']['tech'] = generic_parser_b($blocks['tech'],$translate,'dmy',false); + + if (isset($blocks['admin'])) + $r['regrinfo']['admin'] = generic_parser_b($blocks['admin'],$translate,'dmy',false); + + if (isset($blocks['billing'])) + $r['regrinfo']['billing'] = generic_parser_b($blocks['billing'],$translate,'dmy',false); + } + else + { + $r['regrinfo']['owner'] = generic_parser_b($data_str['rawdata'],$translate,'dmy',false); + } + } + else + $r['regrinfo']['registered'] = 'no'; + + $r['regyinfo'] = array( + 'referrer' => 'http://www.nic.coop', + 'registrar' => '.coop registry' + ); + return $r; + } + } +?> diff --git a/whois.cz.php b/classes/whois.cz.php old mode 100755 new mode 100644 similarity index 96% rename from whois.cz.php rename to classes/whois.cz.php index d0367be..8d655b9 --- a/whois.cz.php +++ b/classes/whois.cz.php @@ -1,73 +1,73 @@ - 'expires', - 'registered' => 'created', - 'nserver' => 'nserver', - 'domain' => 'name', - 'contact' => 'handle', - 'reg-c' => '', - 'descr' => 'desc', - 'e-mail' => 'email', - 'person' => 'name', - 'org' => 'organization', - 'fax-no' => 'fax' - ); - - $contacts = array( - 'admin-c' => 'admin', - 'tech-c' => 'tech', - 'bill-c' => 'billing', - 'registrant' => 'owner' - ); - - $r['regrinfo'] = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain', 'dmy'); - - $r['regyinfo'] = array( - 'referrer' => 'http://www.nic.cz', - 'registrar' => 'CZ-NIC' - ); - - if ($data_str['rawdata'][0] == 'Your connection limit exceeded. Please slow down and try again later.') - { - $r['regrinfo']['registered'] = 'unknown'; - } - - return $r; - } - } + 'expires', + 'registered' => 'created', + 'nserver' => 'nserver', + 'domain' => 'name', + 'contact' => 'handle', + 'reg-c' => '', + 'descr' => 'desc', + 'e-mail' => 'email', + 'person' => 'name', + 'org' => 'organization', + 'fax-no' => 'fax' + ); + + $contacts = array( + 'admin-c' => 'admin', + 'tech-c' => 'tech', + 'bill-c' => 'billing', + 'registrant' => 'owner' + ); + + $r['regrinfo'] = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain', 'dmy'); + + $r['regyinfo'] = array( + 'referrer' => 'http://www.nic.cz', + 'registrar' => 'CZ-NIC' + ); + + if ($data_str['rawdata'][0] == 'Your connection limit exceeded. Please slow down and try again later.') + { + $r['regrinfo']['registered'] = 'unknown'; + } + + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.de.php b/classes/whois.de.php old mode 100755 new mode 100644 similarity index 100% rename from whois.de.php rename to classes/whois.de.php diff --git a/whois.edu.php b/classes/whois.edu.php old mode 100755 new mode 100644 similarity index 96% rename from whois.edu.php rename to classes/whois.edu.php index 22e6d92..ab857e2 --- a/whois.edu.php +++ b/classes/whois.edu.php @@ -1,62 +1,62 @@ - 'Domain name:', - 'domain.sponsor' => 'Registrar:', - 'domain.nserver' => 'Name Servers:', - 'domain.changed' => 'Domain record last updated:', - 'domain.created' => 'Domain record activated:', - 'owner' => 'Registrant:', - 'admin' => 'Administrative Contact:', - 'tech' => 'Technical Contact:', - 'billing' => 'Billing Contact:' - ); - - $r['regrinfo'] = easy_parser($data_str['rawdata'], $items, 'dmy'); - - if (isset($b['tech'])) - { - if ($r['regrinfo']['tech']['name'] == 'Same as above') - $r['regrinfo']['tech'] = $r['regrinfo']['admin']; - } - - $r['regyinfo']['referrer'] = 'http://whois.educause.net'; - $r['regyinfo']['registrar'] = 'EDUCASE'; - return ($r); - } - } + 'Domain name:', + 'domain.sponsor' => 'Registrar:', + 'domain.nserver' => 'Name Servers:', + 'domain.changed' => 'Domain record last updated:', + 'domain.created' => 'Domain record activated:', + 'owner' => 'Registrant:', + 'admin' => 'Administrative Contact:', + 'tech' => 'Technical Contact:', + 'billing' => 'Billing Contact:' + ); + + $r['regrinfo'] = easy_parser($data_str['rawdata'], $items, 'dmy'); + + if (isset($b['tech'])) + { + if ($r['regrinfo']['tech']['name'] == 'Same as above') + $r['regrinfo']['tech'] = $r['regrinfo']['admin']; + } + + $r['regyinfo']['referrer'] = 'http://whois.educause.net'; + $r['regyinfo']['registrar'] = 'EDUCASE'; + return ($r); + } + } ?> \ No newline at end of file diff --git a/whois.eu.php b/classes/whois.eu.php old mode 100755 new mode 100644 similarity index 96% rename from whois.eu.php rename to classes/whois.eu.php index 10627c3..d9c01ce --- a/whois.eu.php +++ b/classes/whois.eu.php @@ -1,85 +1,85 @@ - 'Domain:', - 'domain.status' => 'Status:', - 'domain.nserver' => 'Name servers:', - 'domain.created' => 'Registered:', - 'domain.registrar' => 'Registrar:', - 'tech' => 'Registrar Technical Contacts:', - 'owner' => 'Registrant:', - '' => 'Please visit' - ); - - $extra = array( - 'organisation:' => 'organization', - 'website:' => 'url' - ); - - $r['regrinfo'] = get_blocks($data['rawdata'], $items); - - if (!empty($r['regrinfo']['domain']['status'])) - switch ($r['regrinfo']['domain']['status']) - { - case 'FREE': - case 'AVAILABLE': - $r['regrinfo']['registered'] = 'no'; - break; - - case 'APPLICATION PENDING': - $r['regrinfo']['registered'] = 'pending'; - break; - - default: - $r['regrinfo']['registered'] = 'unknown'; - } - else - $r['regrinfo']['registered'] = 'yes'; - - if (isset($r['regrinfo']['tech'])) - $r['regrinfo']['tech'] = get_contact($r['regrinfo']['tech'],$extra); - - if (isset($r['regrinfo']['domain']['registrar'])) - $r['regrinfo']['domain']['registrar'] = get_contact($r['regrinfo']['domain']['registrar'],$extra); - - $r['regyinfo']['referrer'] = 'http://www.eurid.eu'; - $r['regyinfo']['registrar'] = 'EURID'; - return $r; - } - } + 'Domain:', + 'domain.status' => 'Status:', + 'domain.nserver' => 'Name servers:', + 'domain.created' => 'Registered:', + 'domain.registrar' => 'Registrar:', + 'tech' => 'Registrar Technical Contacts:', + 'owner' => 'Registrant:', + '' => 'Please visit' + ); + + $extra = array( + 'organisation:' => 'organization', + 'website:' => 'url' + ); + + $r['regrinfo'] = get_blocks($data['rawdata'], $items); + + if (!empty($r['regrinfo']['domain']['status'])) + switch ($r['regrinfo']['domain']['status']) + { + case 'FREE': + case 'AVAILABLE': + $r['regrinfo']['registered'] = 'no'; + break; + + case 'APPLICATION PENDING': + $r['regrinfo']['registered'] = 'pending'; + break; + + default: + $r['regrinfo']['registered'] = 'unknown'; + } + else + $r['regrinfo']['registered'] = 'yes'; + + if (isset($r['regrinfo']['tech'])) + $r['regrinfo']['tech'] = get_contact($r['regrinfo']['tech'],$extra); + + if (isset($r['regrinfo']['domain']['registrar'])) + $r['regrinfo']['domain']['registrar'] = get_contact($r['regrinfo']['domain']['registrar'],$extra); + + $r['regyinfo']['referrer'] = 'http://www.eurid.eu'; + $r['regyinfo']['registrar'] = 'EURID'; + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.fi.php b/classes/whois.fi.php similarity index 96% rename from whois.fi.php rename to classes/whois.fi.php index a94d202..4f0d92c 100644 --- a/whois.fi.php +++ b/classes/whois.fi.php @@ -1,57 +1,57 @@ - 'domain.name', - 'created:' => 'domain.created', - 'expires:' => 'domain.expires', - 'status:' => 'domain.status', - 'nserver:' => 'domain.nserver.', - 'descr:' => 'owner.name.', - 'address:' => 'owner.address.', - 'phone:' => 'owner.phone', - ); - - $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items); - - $r['regyinfo'] = array( - 'referrer' => 'https://domain.ficora.fi/', - 'registrar' => 'Finnish Communications Regulatory Authority' - ); - return $r; - } - } + 'domain.name', + 'created:' => 'domain.created', + 'expires:' => 'domain.expires', + 'status:' => 'domain.status', + 'nserver:' => 'domain.nserver.', + 'descr:' => 'owner.name.', + 'address:' => 'owner.address.', + 'phone:' => 'owner.phone', + ); + + $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items); + + $r['regyinfo'] = array( + 'referrer' => 'https://domain.ficora.fi/', + 'registrar' => 'Finnish Communications Regulatory Authority' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.fj.php b/classes/whois.fj.php similarity index 96% rename from whois.fj.php rename to classes/whois.fj.php index c059954..be72fce 100644 --- a/whois.fj.php +++ b/classes/whois.fj.php @@ -1,67 +1,67 @@ - 'Registrant:', - 'domain.status' => 'Status:', - 'domain.expires' => 'Expires:', - 'domain.nserver' => 'Domain servers:' - ); - - $r['regrinfo'] = get_blocks($data_str['rawdata'], $items); - - if (!empty($r['regrinfo']['domain']['status'])) - { - $r['regrinfo'] = get_contacts($r['regrinfo']); - - date_default_timezone_set("Pacific/Fiji"); - - if (isset($r['regrinfo']['domain']['expires'])) - $r['regrinfo']['domain']['expires'] = strftime("%Y-%m-%d",strtotime($r['regrinfo']['domain']['expires'])); - - $r['regrinfo']['registered'] = 'yes'; - } - else - $r['regrinfo']['registered'] = 'no'; - - $r['regyinfo'] = array( - 'referrer' => 'http://www.domains.fj', - 'registrar' => 'FJ Domain Name Registry' - ); - return $r; - } - } + 'Registrant:', + 'domain.status' => 'Status:', + 'domain.expires' => 'Expires:', + 'domain.nserver' => 'Domain servers:' + ); + + $r['regrinfo'] = get_blocks($data_str['rawdata'], $items); + + if (!empty($r['regrinfo']['domain']['status'])) + { + $r['regrinfo'] = get_contacts($r['regrinfo']); + + date_default_timezone_set("Pacific/Fiji"); + + if (isset($r['regrinfo']['domain']['expires'])) + $r['regrinfo']['domain']['expires'] = strftime("%Y-%m-%d",strtotime($r['regrinfo']['domain']['expires'])); + + $r['regrinfo']['registered'] = 'yes'; + } + else + $r['regrinfo']['registered'] = 'no'; + + $r['regyinfo'] = array( + 'referrer' => 'http://www.domains.fj', + 'registrar' => 'FJ Domain Name Registry' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.fm.php b/classes/whois.fm.php similarity index 96% rename from whois.fm.php rename to classes/whois.fm.php index 0e34f0a..20fbb45 100644 --- a/whois.fm.php +++ b/classes/whois.fm.php @@ -1,80 +1,80 @@ - 'Registrant', - 'admin' => 'Admin', - 'tech' => 'Technical', - 'billing' => 'Billing', - 'domain.nserver' => 'Name Servers:', - 'domain.created' => 'Created:', - 'domain.expires' => 'Expires:', - 'domain.changed' => 'Modified:', - 'domain.status' => 'Status:', - 'domain.sponsor' => 'Registrar Name:' - ); - - $r['regrinfo'] = get_blocks($data['rawdata'], $items); - - $items = array( - 'phone number:' => 'phone', - 'email address:' => 'email', - 'fax number:' => 'fax', - 'organisation:' => 'organization' - ); - - if (!empty($r['regrinfo']['domain']['created'])) - { - $r['regrinfo'] = get_contacts($r['regrinfo'],$items); - - if (count($r['regrinfo']['billing']['address']) > 4) - $r['regrinfo']['billing']['address'] = array_slice($r['regrinfo']['billing']['address'],0,4); - - $r['regrinfo']['registered'] = 'yes'; - format_dates($r['regrinfo']['domain'],'dmY'); - } - else - { - $r = ''; - $r['regrinfo']['registered'] = 'no'; - } - - $r['regyinfo']['referrer'] = 'http://www.dot.dm'; - $r['regyinfo']['registrar'] = 'dotFM'; - return $r; - } - } + 'Registrant', + 'admin' => 'Admin', + 'tech' => 'Technical', + 'billing' => 'Billing', + 'domain.nserver' => 'Name Servers:', + 'domain.created' => 'Created:', + 'domain.expires' => 'Expires:', + 'domain.changed' => 'Modified:', + 'domain.status' => 'Status:', + 'domain.sponsor' => 'Registrar Name:' + ); + + $r['regrinfo'] = get_blocks($data['rawdata'], $items); + + $items = array( + 'phone number:' => 'phone', + 'email address:' => 'email', + 'fax number:' => 'fax', + 'organisation:' => 'organization' + ); + + if (!empty($r['regrinfo']['domain']['created'])) + { + $r['regrinfo'] = get_contacts($r['regrinfo'],$items); + + if (count($r['regrinfo']['billing']['address']) > 4) + $r['regrinfo']['billing']['address'] = array_slice($r['regrinfo']['billing']['address'],0,4); + + $r['regrinfo']['registered'] = 'yes'; + format_dates($r['regrinfo']['domain'],'dmY'); + } + else + { + $r = ''; + $r['regrinfo']['registered'] = 'no'; + } + + $r['regyinfo']['referrer'] = 'http://www.dot.dm'; + $r['regyinfo']['registrar'] = 'dotFM'; + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.fr.php b/classes/whois.fr.php similarity index 96% rename from whois.fr.php rename to classes/whois.fr.php index 9854248..b4ee11e 100644 --- a/whois.fr.php +++ b/classes/whois.fr.php @@ -1,78 +1,78 @@ - 'fax', - 'e-mail' => 'email', - 'nic-hdl' => 'handle', - 'ns-list' => 'handle', - 'person' => 'name', - 'address' => 'address.', - 'descr' => 'desc', - 'anniversary' => '', - 'domain' => '', - 'last-update' => 'changed', - 'registered' => 'created', - 'country' => 'address.country', - 'registrar' => 'sponsor', - 'role' => 'organization' - ); - - $contacts = array( - 'admin-c' => 'admin', - 'tech-c' => 'tech', - 'zone-c' => 'zone', - 'holder-c' => 'owner', - 'nsl-id' => 'nserver' - ); - - $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain','dmY'); - - if (isset($reg['nserver'])) - { - $reg['domain'] = array_merge($reg['domain'],$reg['nserver']); - unset($reg['nserver']); - } - - $r['regrinfo'] = $reg; - $r['regyinfo'] = array( - 'referrer' => 'http://www.nic.fr', - 'registrar' => 'AFNIC' - ); - return $r; - } - } + 'fax', + 'e-mail' => 'email', + 'nic-hdl' => 'handle', + 'ns-list' => 'handle', + 'person' => 'name', + 'address' => 'address.', + 'descr' => 'desc', + 'anniversary' => '', + 'domain' => '', + 'last-update' => 'changed', + 'registered' => 'created', + 'country' => 'address.country', + 'registrar' => 'sponsor', + 'role' => 'organization' + ); + + $contacts = array( + 'admin-c' => 'admin', + 'tech-c' => 'tech', + 'zone-c' => 'zone', + 'holder-c' => 'owner', + 'nsl-id' => 'nserver' + ); + + $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain','dmY'); + + if (isset($reg['nserver'])) + { + $reg['domain'] = array_merge($reg['domain'],$reg['nserver']); + unset($reg['nserver']); + } + + $r['regrinfo'] = $reg; + $r['regyinfo'] = array( + 'referrer' => 'http://www.nic.fr', + 'registrar' => 'AFNIC' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.gtld.afternic.php b/classes/whois.gtld.afternic.php similarity index 96% rename from whois.gtld.afternic.php rename to classes/whois.gtld.afternic.php index 94ffe26..5438045 100644 --- a/whois.gtld.afternic.php +++ b/classes/whois.gtld.afternic.php @@ -1,51 +1,51 @@ - 'Registrant:', - 'admin' => 'Administrative Contact', - 'tech' => 'Technical Contact', - 'zone' => 'Zone Contact', - 'domain.name' => 'Domain Name:', - 'domain.changed' => 'Last updated on', - 'domain.created' => 'Domain created on', - 'domain.expires' => 'Domain expires on' - ); - - return easy_parser($data_str, $items, 'dmy', false, false, true); - } - } + 'Registrant:', + 'admin' => 'Administrative Contact', + 'tech' => 'Technical Contact', + 'zone' => 'Zone Contact', + 'domain.name' => 'Domain Name:', + 'domain.changed' => 'Last updated on', + 'domain.created' => 'Domain created on', + 'domain.expires' => 'Domain expires on' + ); + + return easy_parser($data_str, $items, 'dmy', false, false, true); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.alldomains.php b/classes/whois.gtld.alldomains.php old mode 100755 new mode 100644 similarity index 96% rename from whois.gtld.alldomains.php rename to classes/whois.gtld.alldomains.php index 01c7728..8d016a3 --- a/whois.gtld.alldomains.php +++ b/classes/whois.gtld.alldomains.php @@ -1,49 +1,49 @@ - 'Registrant:', - 'admin' => 'Administrative', - 'tech' => 'Technical', - 'domain.name' => 'Domain name:', - 'domain.sponsor' => 'Registrar:', - 'domain.nserver.' => 'Domain servers in listed order:' - ); - - return easy_parser($data_str, $items, 'ymd'); - } - } + 'Registrant:', + 'admin' => 'Administrative', + 'tech' => 'Technical', + 'domain.name' => 'Domain name:', + 'domain.sponsor' => 'Registrar:', + 'domain.nserver.' => 'Domain servers in listed order:' + ); + + return easy_parser($data_str, $items, 'ymd'); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.ascio.php b/classes/whois.gtld.ascio.php similarity index 96% rename from whois.gtld.ascio.php rename to classes/whois.gtld.ascio.php index 44fc19f..0f0ed5d 100644 --- a/whois.gtld.ascio.php +++ b/classes/whois.gtld.ascio.php @@ -1,51 +1,51 @@ - 'Registrant:', - 'admin' => 'Administrative ', - 'tech' => 'Technical ', - 'domain.name' => 'Domain name:', - 'domain.nserver.' => 'Domain servers in listed order:', - 'domain.created' => 'Record created:', - 'domain.expires' => 'Record expires:', - 'domain.changed' => 'Record last updated:' - ); - - return easy_parser($data_str, $items, 'ymd',false,false,true); - } - } + 'Registrant:', + 'admin' => 'Administrative ', + 'tech' => 'Technical ', + 'domain.name' => 'Domain name:', + 'domain.nserver.' => 'Domain servers in listed order:', + 'domain.created' => 'Record created:', + 'domain.expires' => 'Record expires:', + 'domain.changed' => 'Record last updated:' + ); + + return easy_parser($data_str, $items, 'ymd',false,false,true); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.assorted.php b/classes/whois.gtld.assorted.php similarity index 97% rename from whois.gtld.assorted.php rename to classes/whois.gtld.assorted.php index a6e30f6..16c4592 100644 --- a/whois.gtld.assorted.php +++ b/classes/whois.gtld.assorted.php @@ -1,51 +1,51 @@ - 'Registrant:', - 'admin' => 'Administrative Contact:', - 'tech' => 'Technical Contact:', - 'domain.name' => 'Domain Name:', - 'domain.nserver.' => 'Domain servers in listed order:', - 'domain.created' => 'Record created on', - 'domain.expires' => 'Record expires on', - 'domain.changed' => 'Record last updated' - ); - - return easy_parser($data_str, $items, 'ymd',false,false,true); - } - } + 'Registrant:', + 'admin' => 'Administrative Contact:', + 'tech' => 'Technical Contact:', + 'domain.name' => 'Domain Name:', + 'domain.nserver.' => 'Domain servers in listed order:', + 'domain.created' => 'Record created on', + 'domain.expires' => 'Record expires on', + 'domain.changed' => 'Record last updated' + ); + + return easy_parser($data_str, $items, 'ymd',false,false,true); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.corporatedomains.php b/classes/whois.gtld.corporatedomains.php similarity index 97% rename from whois.gtld.corporatedomains.php rename to classes/whois.gtld.corporatedomains.php index ad229d7..46e17c3 100644 --- a/whois.gtld.corporatedomains.php +++ b/classes/whois.gtld.corporatedomains.php @@ -1,53 +1,53 @@ - 'Registrant:', - 'admin' => 'Administrative Contact', - 'tech' => 'Technical Contact', - 'zone' => 'Zone Contact', - 'domain.name' => 'Domain Name:', - 'domain.changed' => 'Last updated on', - 'domain.created' => 'Domain created on', - 'domain.expires' => 'Domain expires on', - 'domain.sponsor' => 'Registrar Name....:', - 'domain.nserver' => 'DNS Servers:' - ); - - return easy_parser($data_str, $items, 'dmy', false, false, true); - } - } + 'Registrant:', + 'admin' => 'Administrative Contact', + 'tech' => 'Technical Contact', + 'zone' => 'Zone Contact', + 'domain.name' => 'Domain Name:', + 'domain.changed' => 'Last updated on', + 'domain.created' => 'Domain created on', + 'domain.expires' => 'Domain expires on', + 'domain.sponsor' => 'Registrar Name....:', + 'domain.nserver' => 'DNS Servers:' + ); + + return easy_parser($data_str, $items, 'dmy', false, false, true); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.directnic.php b/classes/whois.gtld.directnic.php similarity index 97% rename from whois.gtld.directnic.php rename to classes/whois.gtld.directnic.php index 511755e..7a8c2d5 100644 --- a/whois.gtld.directnic.php +++ b/classes/whois.gtld.directnic.php @@ -1,53 +1,53 @@ - 'Registrant:', - 'admin' => 'Administrative Contact', - 'tech' => 'Technical Contact', - 'domain.name' => 'Domain Name:', - 'domain.sponsor' => 'Registration Service Provider:', - 'domain.nserver' => 'Domain servers in listed order:', - 'domain.changed' => 'Record last updated ', - 'domain.created' => 'Record created on ', - 'domain.expires' => 'Record expires on ', - '' => 'By submitting a WHOIS query' - ); - - return easy_parser($data_str, $items, 'mdy',false,false,true); - } - } + 'Registrant:', + 'admin' => 'Administrative Contact', + 'tech' => 'Technical Contact', + 'domain.name' => 'Domain Name:', + 'domain.sponsor' => 'Registration Service Provider:', + 'domain.nserver' => 'Domain servers in listed order:', + 'domain.changed' => 'Record last updated ', + 'domain.created' => 'Record created on ', + 'domain.expires' => 'Record expires on ', + '' => 'By submitting a WHOIS query' + ); + + return easy_parser($data_str, $items, 'mdy',false,false,true); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.domaindiscover.php b/classes/whois.gtld.domaindiscover.php similarity index 97% rename from whois.gtld.domaindiscover.php rename to classes/whois.gtld.domaindiscover.php index 00f3d0f..cc1f87d 100644 --- a/whois.gtld.domaindiscover.php +++ b/classes/whois.gtld.domaindiscover.php @@ -1,51 +1,51 @@ - 'Registrant:', - 'admin' => 'Administrative Contact', - 'tech' => 'Technical Contact', - 'zone' => 'Zone Contact', - 'domain.name' => 'Domain Name:', - 'domain.changed' => 'Last updated on', - 'domain.created' => 'Domain created on', - 'domain.expires' => 'Domain expires on' - ); - - return easy_parser($data_str, $items, 'dmy', false, false, true); - } - } + 'Registrant:', + 'admin' => 'Administrative Contact', + 'tech' => 'Technical Contact', + 'zone' => 'Zone Contact', + 'domain.name' => 'Domain Name:', + 'domain.changed' => 'Last updated on', + 'domain.created' => 'Domain created on', + 'domain.expires' => 'Domain expires on' + ); + + return easy_parser($data_str, $items, 'dmy', false, false, true); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.domainpeople.php b/classes/whois.gtld.domainpeople.php similarity index 97% rename from whois.gtld.domainpeople.php rename to classes/whois.gtld.domainpeople.php index c9ee5c3..07be546 100644 --- a/whois.gtld.domainpeople.php +++ b/classes/whois.gtld.domainpeople.php @@ -1,59 +1,59 @@ - 'Registrant Contact:', - 'admin' => 'Administrative Contact:', - 'tech' => 'Technical Contact:', - 'domain.name' => 'Domain name:', - 'domain.sponsor' => 'Registration Service Provided By:', - 'domain.referrer' => 'Contact:', - 'domain.nserver.' => 'Name Servers:', - 'domain.created' => 'Creation date:', - 'domain.expires' => 'Expiration date:', -// 'domain.changed' => 'Record last updated on', - 'domain.status' => 'Status:' - ); - - $r = easy_parser($data_str, $items, 'dmy', false, false, true); - if (isset($r['domain']['sponsor']) && is_array($r['domain']['sponsor'])) - $r['domain']['sponsor'] = $r['domain']['sponsor'][0]; - return $r; - } - } + 'Registrant Contact:', + 'admin' => 'Administrative Contact:', + 'tech' => 'Technical Contact:', + 'domain.name' => 'Domain name:', + 'domain.sponsor' => 'Registration Service Provided By:', + 'domain.referrer' => 'Contact:', + 'domain.nserver.' => 'Name Servers:', + 'domain.created' => 'Creation date:', + 'domain.expires' => 'Expiration date:', +// 'domain.changed' => 'Record last updated on', + 'domain.status' => 'Status:' + ); + + $r = easy_parser($data_str, $items, 'dmy', false, false, true); + if (isset($r['domain']['sponsor']) && is_array($r['domain']['sponsor'])) + $r['domain']['sponsor'] = $r['domain']['sponsor'][0]; + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.gtld.dotster.php b/classes/whois.gtld.dotster.php similarity index 96% rename from whois.gtld.dotster.php rename to classes/whois.gtld.dotster.php index eec492a..6d78a89 100644 --- a/whois.gtld.dotster.php +++ b/classes/whois.gtld.dotster.php @@ -1,53 +1,53 @@ - 'Registrant:', - 'admin' => 'Administrative', - 'tech' => 'Technical', - 'domain.nserver' => - 'Domain servers in listed order:', - 'domain.name' => 'Domain name:', - 'domain.created' => 'Created on:', - 'domain.expires' => 'Expires on:', - 'domain.changed' => 'Last Updated on:', - 'domain.sponsor' => 'Registrar:' - ); - - return easy_parser($data_str, $items, 'dmy'); - } - } + 'Registrant:', + 'admin' => 'Administrative', + 'tech' => 'Technical', + 'domain.nserver' => + 'Domain servers in listed order:', + 'domain.name' => 'Domain name:', + 'domain.created' => 'Created on:', + 'domain.expires' => 'Expires on:', + 'domain.changed' => 'Last Updated on:', + 'domain.sponsor' => 'Registrar:' + ); + + return easy_parser($data_str, $items, 'dmy'); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.dreamhost.php b/classes/whois.gtld.dreamhost.php similarity index 97% rename from whois.gtld.dreamhost.php rename to classes/whois.gtld.dreamhost.php index 38455cd..1150b5e 100644 --- a/whois.gtld.dreamhost.php +++ b/classes/whois.gtld.dreamhost.php @@ -1,54 +1,54 @@ - 'Registrant Contact:', - 'admin' => 'Administrative Contact:', - 'tech' => 'Technical Contact:', - 'billing' => 'Billing Contact:', - 'domain.name' => 'Domain Name:', - 'domain.nserver' => 'Domain servers in listed order:', - 'domain.created' => 'Record created on', - 'domain.expires' => 'Record expires on' - ); - - $r = easy_parser($data_str, $items, 'dmy', false, false, true); - if (isset($r['domain']['sponsor']) && is_array($r['domain']['sponsor'])) - $r['domain']['sponsor'] = $r['domain']['sponsor'][0]; - return $r; - } - } -?> + 'Registrant Contact:', + 'admin' => 'Administrative Contact:', + 'tech' => 'Technical Contact:', + 'billing' => 'Billing Contact:', + 'domain.name' => 'Domain Name:', + 'domain.nserver' => 'Domain servers in listed order:', + 'domain.created' => 'Record created on', + 'domain.expires' => 'Record expires on' + ); + + $r = easy_parser($data_str, $items, 'dmy', false, false, true); + if (isset($r['domain']['sponsor']) && is_array($r['domain']['sponsor'])) + $r['domain']['sponsor'] = $r['domain']['sponsor'][0]; + return $r; + } + } +?> diff --git a/whois.gtld.enom.php b/classes/whois.gtld.enom.php similarity index 97% rename from whois.gtld.enom.php rename to classes/whois.gtld.enom.php index 0510bcc..2a23580 100644 --- a/whois.gtld.enom.php +++ b/classes/whois.gtld.enom.php @@ -1,62 +1,62 @@ - 'Registrant Contact', - 'owner#1' => 'REGISTRANT Contact:', - 'admin#0' => 'Administrative Contact', - 'admin#1' => 'ADMINISTRATIVE Contact:', - 'tech#0' => 'Technical Contact', - 'tech#1' => 'TECHNICAL Contact:', - 'billing#0' => 'Billing Contact', - 'billing#1' => 'BILLING Contact:', - 'domain.nserver' => 'Nameservers', - 'domain.name#0' => 'Domain name:', - 'domain.name#1' => 'Domain name-', - 'domain.sponsor' => 'Registration Service Provided By:', - 'domain.status' => 'Status:', - 'domain.created#0' => 'Creation date:', - 'domain.expires#0' => 'Expiration date:', - 'domain.created#1' => 'Created:', - 'domain.expires#1' => 'Expires:', - 'domain.created#2' => 'Start of registration-', - 'domain.expires#2' => 'Registered through-' - ); - - return easy_parser($data_str, $items, 'dmy', false, false, true); - } - } + 'Registrant Contact', + 'owner#1' => 'REGISTRANT Contact:', + 'admin#0' => 'Administrative Contact', + 'admin#1' => 'ADMINISTRATIVE Contact:', + 'tech#0' => 'Technical Contact', + 'tech#1' => 'TECHNICAL Contact:', + 'billing#0' => 'Billing Contact', + 'billing#1' => 'BILLING Contact:', + 'domain.nserver' => 'Nameservers', + 'domain.name#0' => 'Domain name:', + 'domain.name#1' => 'Domain name-', + 'domain.sponsor' => 'Registration Service Provided By:', + 'domain.status' => 'Status:', + 'domain.created#0' => 'Creation date:', + 'domain.expires#0' => 'Expiration date:', + 'domain.created#1' => 'Created:', + 'domain.expires#1' => 'Expires:', + 'domain.created#2' => 'Start of registration-', + 'domain.expires#2' => 'Registered through-' + ); + + return easy_parser($data_str, $items, 'dmy', false, false, true); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.fabulous.php b/classes/whois.gtld.fabulous.php similarity index 96% rename from whois.gtld.fabulous.php rename to classes/whois.gtld.fabulous.php index d7094b8..8a03c7b 100644 --- a/whois.gtld.fabulous.php +++ b/classes/whois.gtld.fabulous.php @@ -1,54 +1,54 @@ - 'Domain '.$query.':', - 'admin' => 'Administrative contact:', - 'tech' => 'Technical contact:', - 'billing' => 'Billing contact:', - '' => 'Record dates:' - ); - - $r = easy_parser($data_str, $items, 'mdy',false,false,true); - - if (!isset($r['tech'])) $r['tech'] = $r['billing']; - - if (!isset($r['admin'])) $r['admin'] = $r['tech']; - - return $r; - } - } + 'Domain '.$query.':', + 'admin' => 'Administrative contact:', + 'tech' => 'Technical contact:', + 'billing' => 'Billing contact:', + '' => 'Record dates:' + ); + + $r = easy_parser($data_str, $items, 'mdy',false,false,true); + + if (!isset($r['tech'])) $r['tech'] = $r['billing']; + + if (!isset($r['admin'])) $r['admin'] = $r['tech']; + + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.gtld.fastdomain.php b/classes/whois.gtld.fastdomain.php similarity index 96% rename from whois.gtld.fastdomain.php rename to classes/whois.gtld.fastdomain.php index 819083c..27520d9 100644 --- a/whois.gtld.fastdomain.php +++ b/classes/whois.gtld.fastdomain.php @@ -1,78 +1,78 @@ - 'Registrant Info:', - 'admin' => 'Administrative Info:', - 'tech' => 'Technical Info:', - 'domain.name' => 'Domain Name:', - 'domain.sponsor' => 'Provider Name....:', - 'domain.referrer' => 'Provider Homepage:', - 'domain.nserver' => 'Domain servers in listed order:', - 'domain.created' => 'Created on..............:', - 'domain.expires' => 'Expires on..............:', - 'domain.changed' => 'Last modified on........:', - 'domain.status' => 'Status:' - ); - - while (list($key, $val) = each($data_str)) - { - $faststr = strpos($val, ' (FAST-'); - if ($faststr) - $data_str[$key] = substr($val, 0, $faststr); - } - - $r = easy_parser($data_str, $items, 'dmy', false, false, true); - - if (isset($r['domain']['sponsor']) && is_array($r['domain']['sponsor'])) - - $r['domain']['sponsor'] = $r['domain']['sponsor'][0]; - - if (isset($r['domain']['nserver'])) - { - reset($r['domain']['nserver']); - $endnserver = false; - while (list($key, $val) = each($r['domain']['nserver'])) - { - if ($val == '=-=-=-=') - unset($r['domain']['nserver'][$key]); - } - } - - return $r; - } - } + 'Registrant Info:', + 'admin' => 'Administrative Info:', + 'tech' => 'Technical Info:', + 'domain.name' => 'Domain Name:', + 'domain.sponsor' => 'Provider Name....:', + 'domain.referrer' => 'Provider Homepage:', + 'domain.nserver' => 'Domain servers in listed order:', + 'domain.created' => 'Created on..............:', + 'domain.expires' => 'Expires on..............:', + 'domain.changed' => 'Last modified on........:', + 'domain.status' => 'Status:' + ); + + while (list($key, $val) = each($data_str)) + { + $faststr = strpos($val, ' (FAST-'); + if ($faststr) + $data_str[$key] = substr($val, 0, $faststr); + } + + $r = easy_parser($data_str, $items, 'dmy', false, false, true); + + if (isset($r['domain']['sponsor']) && is_array($r['domain']['sponsor'])) + + $r['domain']['sponsor'] = $r['domain']['sponsor'][0]; + + if (isset($r['domain']['nserver'])) + { + reset($r['domain']['nserver']); + $endnserver = false; + while (list($key, $val) = each($r['domain']['nserver'])) + { + if ($val == '=-=-=-=') + unset($r['domain']['nserver'][$key]); + } + } + + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.gtld.gandi.php b/classes/whois.gtld.gandi.php similarity index 96% rename from whois.gtld.gandi.php rename to classes/whois.gtld.gandi.php index bb513db..f1f9af5 100644 --- a/whois.gtld.gandi.php +++ b/classes/whois.gtld.gandi.php @@ -1,56 +1,56 @@ - 'owner-c', - 'admin' => 'admin-c', - 'tech' => 'tech-c', - 'billing' => 'bill-c' - ); - - $trans = array( - 'nic-hdl:' => 'handle', - 'person:' => 'name', - 'zipcode:' => 'address.pcode', - 'city:' => 'address.city', - 'lastupdated:' => 'changed', - 'owner-name:' => '' - ); - - return easy_parser($data_str, $items, 'dmy', $trans); - } - } + 'owner-c', + 'admin' => 'admin-c', + 'tech' => 'tech-c', + 'billing' => 'bill-c' + ); + + $trans = array( + 'nic-hdl:' => 'handle', + 'person:' => 'name', + 'zipcode:' => 'address.pcode', + 'city:' => 'address.city', + 'lastupdated:' => 'changed', + 'owner-name:' => '' + ); + + return easy_parser($data_str, $items, 'dmy', $trans); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.genericb.php b/classes/whois.gtld.genericb.php similarity index 96% rename from whois.gtld.genericb.php rename to classes/whois.gtld.genericb.php index 9c240f0..a50ea9a 100644 --- a/whois.gtld.genericb.php +++ b/classes/whois.gtld.genericb.php @@ -1,40 +1,40 @@ - \ No newline at end of file diff --git a/whois.gtld.godaddy.php b/classes/whois.gtld.godaddy.php similarity index 97% rename from whois.gtld.godaddy.php rename to classes/whois.gtld.godaddy.php index 5ede66a..ddb8792 100644 --- a/whois.gtld.godaddy.php +++ b/classes/whois.gtld.godaddy.php @@ -1,56 +1,56 @@ - 'Registrant:', - 'admin' => 'Administrative Contact', - 'tech' => 'Technical Contact', - 'domain.name' => 'Domain Name:', - 'domain.nserver.' => 'Domain servers in listed order:', - 'domain.created' => 'Created on:', - 'domain.expires' => 'Expires on:', - 'domain.changed' => 'Last Updated on:', - 'domain.sponsor' => 'Registered through:' - ); - - $r = get_blocks($data_str, $items); - $r['owner'] = get_contact($r['owner']); - $r['admin'] = get_contact($r['admin'],false,true); - $r['tech'] = get_contact($r['tech'],false,true); - return format_dates($r, 'dmy'); - } - } + 'Registrant:', + 'admin' => 'Administrative Contact', + 'tech' => 'Technical Contact', + 'domain.name' => 'Domain Name:', + 'domain.nserver.' => 'Domain servers in listed order:', + 'domain.created' => 'Created on:', + 'domain.expires' => 'Expires on:', + 'domain.changed' => 'Last Updated on:', + 'domain.sponsor' => 'Registered through:' + ); + + $r = get_blocks($data_str, $items); + $r['owner'] = get_contact($r['owner']); + $r['admin'] = get_contact($r['admin'],false,true); + $r['tech'] = get_contact($r['tech'],false,true); + return format_dates($r, 'dmy'); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.iana.php b/classes/whois.gtld.iana.php old mode 100755 new mode 100644 similarity index 96% rename from whois.gtld.iana.php rename to classes/whois.gtld.iana.php index 3f8694f..085a2ac --- a/whois.gtld.iana.php +++ b/classes/whois.gtld.iana.php @@ -1,51 +1,51 @@ - 'contact: administrative', - 'tech' => 'contact: technical', - 'domain.nserver.' => 'nserver:', - 'domain.created' => 'created:', - 'domain.changed' => 'changed:', - 'domain.source' => 'source:', - 'domain.name' => 'domain:', - 'disclaimer.' => '% ' - ); - - return easy_parser($data_str,$items,'Ymd',false,false,false,'owner'); - } - } + 'contact: administrative', + 'tech' => 'contact: technical', + 'domain.nserver.' => 'nserver:', + 'domain.created' => 'created:', + 'domain.changed' => 'changed:', + 'domain.source' => 'source:', + 'domain.name' => 'domain:', + 'disclaimer.' => '% ' + ); + + return easy_parser($data_str,$items,'Ymd',false,false,false,'owner'); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.interdomain.php b/classes/whois.gtld.interdomain.php similarity index 97% rename from whois.gtld.interdomain.php rename to classes/whois.gtld.interdomain.php index 1197b87..75e6ec9 100644 --- a/whois.gtld.interdomain.php +++ b/classes/whois.gtld.interdomain.php @@ -1,80 +1,80 @@ - 'domain.name', - 'Creation Date............' => 'domain.created', - 'Expiry Date..............' => 'domain.expires', - 'Last Update Date.........' => 'domain.changed', - 'Name Server.............' => 'domain.nserver.', - 'Organization Name........' => 'owner.name', - 'Organization Org.........' => 'owner.organization', - 'Organization Street......' => 'owner.address.street', - 'Organization City........' => 'owner.address.city', - 'Organization State.......' => 'owner.address.state', - 'Organization PC..........' => 'owner.address.pcode', - 'Organization Country.....' => 'owner.address.country', - 'Organization Phone.......' => 'owner.phone', - 'Organization e-mail......' => 'owner.email', - 'Organization Contact Id....' => 'owner.handle', - 'Administrative Contact Id..' => 'admin.handle', - 'Administrative Name......' => 'admin.name', - 'Administrative Org.......' => 'admin.organization', - 'Administrative Street....' => 'admin.address.street', - 'Administrative City......' => 'admin.address.city', - 'Administrative State.....' => 'admin.address.state', - 'Administrative PC........' => 'admin.address.pcode', - 'Administrative Country...' => 'admin.address.country', - 'Administrative Phone.....' => 'admin.phone', - 'Administrative e-mail....' => 'admin.email', - 'Administrative Fax.......' => 'admin.fax', - 'Technical Contact Id.......' => 'tech.handle', - 'Technical Name...........' => 'tech.name', - 'Technical Org............' => 'tech.organization', - 'Technical Street.........' => 'tech.address.street', - 'Technical City...........' => 'tech.address.city', - 'Technical State..........' => 'tech.address.state', - 'Technical PC.............' => 'tech.address.pcode', - 'Technical Country........' => 'tech.address.country', - 'Technical Phone..........' => 'tech.phone', - 'Technical e-mail.........' => 'tech.email', - 'Technical Fax............' => 'tech.fax' - ); - - return generic_parser_b($data_str, $items, 'dmy'); - } - } + 'domain.name', + 'Creation Date............' => 'domain.created', + 'Expiry Date..............' => 'domain.expires', + 'Last Update Date.........' => 'domain.changed', + 'Name Server.............' => 'domain.nserver.', + 'Organization Name........' => 'owner.name', + 'Organization Org.........' => 'owner.organization', + 'Organization Street......' => 'owner.address.street', + 'Organization City........' => 'owner.address.city', + 'Organization State.......' => 'owner.address.state', + 'Organization PC..........' => 'owner.address.pcode', + 'Organization Country.....' => 'owner.address.country', + 'Organization Phone.......' => 'owner.phone', + 'Organization e-mail......' => 'owner.email', + 'Organization Contact Id....' => 'owner.handle', + 'Administrative Contact Id..' => 'admin.handle', + 'Administrative Name......' => 'admin.name', + 'Administrative Org.......' => 'admin.organization', + 'Administrative Street....' => 'admin.address.street', + 'Administrative City......' => 'admin.address.city', + 'Administrative State.....' => 'admin.address.state', + 'Administrative PC........' => 'admin.address.pcode', + 'Administrative Country...' => 'admin.address.country', + 'Administrative Phone.....' => 'admin.phone', + 'Administrative e-mail....' => 'admin.email', + 'Administrative Fax.......' => 'admin.fax', + 'Technical Contact Id.......' => 'tech.handle', + 'Technical Name...........' => 'tech.name', + 'Technical Org............' => 'tech.organization', + 'Technical Street.........' => 'tech.address.street', + 'Technical City...........' => 'tech.address.city', + 'Technical State..........' => 'tech.address.state', + 'Technical PC.............' => 'tech.address.pcode', + 'Technical Country........' => 'tech.address.country', + 'Technical Phone..........' => 'tech.phone', + 'Technical e-mail.........' => 'tech.email', + 'Technical Fax............' => 'tech.fax' + ); + + return generic_parser_b($data_str, $items, 'dmy'); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.itsyourdomain.php b/classes/whois.gtld.itsyourdomain.php similarity index 96% rename from whois.gtld.itsyourdomain.php rename to classes/whois.gtld.itsyourdomain.php index 7d20253..aa15330 100644 --- a/whois.gtld.itsyourdomain.php +++ b/classes/whois.gtld.itsyourdomain.php @@ -1,52 +1,52 @@ - 'Registrant', - 'admin' => 'Administrative', - 'tech' => 'Technical', - 'billing' => 'Billing', - 'domain.name' => 'Domain:', - 'domain.nserver.' => 'Domain Name Servers:', - 'domain.created' => 'Record created on ', - 'domain.expires' => 'Record expires on ', - 'domain.changed' => 'Record last updated on ' - ); - - return easy_parser($data_str, $items, 'mdy'); - } - } + 'Registrant', + 'admin' => 'Administrative', + 'tech' => 'Technical', + 'billing' => 'Billing', + 'domain.name' => 'Domain:', + 'domain.nserver.' => 'Domain Name Servers:', + 'domain.created' => 'Record created on ', + 'domain.expires' => 'Record expires on ', + 'domain.changed' => 'Record last updated on ' + ); + + return easy_parser($data_str, $items, 'mdy'); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.joker.php b/classes/whois.gtld.joker.php similarity index 96% rename from whois.gtld.joker.php rename to classes/whois.gtld.joker.php index 9168e90..33c5cbb 100644 --- a/whois.gtld.joker.php +++ b/classes/whois.gtld.joker.php @@ -1,78 +1,78 @@ - 'handle', - 'modified' => 'changed', - 'reseller' => 'sponsor', - 'address' => 'address.street', - 'postal-code' => 'address.pcode', - 'city' => 'address.city', - 'state' => 'address.state', - 'country' => 'address.country', - 'person' => 'name', - 'domain' => 'name' - ); - - $contacts = array( - 'admin-c' => 'admin', - 'tech-c' => 'tech', - 'billing-c' => 'billing' - ); - - $items = array( - 'owner' => 'name', - 'organization' => 'organization', - 'email' => 'email', - 'phone' => 'phone', - 'address' => 'address', - ); - - $r = generic_parser_a($data_str, $translate, $contacts, 'domain', 'Ymd'); - - foreach($items as $tag => $convert) - { - if (isset($r['domain'][$tag])) - { - $r['owner'][$convert] = $r['domain'][$tag]; - unset($r['domain'][$tag]); - } - } - - return $r; - } - } + 'handle', + 'modified' => 'changed', + 'reseller' => 'sponsor', + 'address' => 'address.street', + 'postal-code' => 'address.pcode', + 'city' => 'address.city', + 'state' => 'address.state', + 'country' => 'address.country', + 'person' => 'name', + 'domain' => 'name' + ); + + $contacts = array( + 'admin-c' => 'admin', + 'tech-c' => 'tech', + 'billing-c' => 'billing' + ); + + $items = array( + 'owner' => 'name', + 'organization' => 'organization', + 'email' => 'email', + 'phone' => 'phone', + 'address' => 'address', + ); + + $r = generic_parser_a($data_str, $translate, $contacts, 'domain', 'Ymd'); + + foreach($items as $tag => $convert) + { + if (isset($r['domain'][$tag])) + { + $r['owner'][$convert] = $r['domain'][$tag]; + unset($r['domain'][$tag]); + } + } + + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.gtld.markmonitor.php b/classes/whois.gtld.markmonitor.php similarity index 97% rename from whois.gtld.markmonitor.php rename to classes/whois.gtld.markmonitor.php index 8dc00bb..4f18cfe 100644 --- a/whois.gtld.markmonitor.php +++ b/classes/whois.gtld.markmonitor.php @@ -1,65 +1,65 @@ - 'Registrant:', - 'admin' => 'Administrative Contact:', - 'tech' => 'Technical Contact, Zone Contact:', - 'domain.name' => 'Domain Name:', - 'domain.sponsor' => 'Registrar Name:', - 'domain.nserver' => 'Domain servers in listed order:', - 'domain.created' => 'Created on..............:', - 'domain.expires' => 'Expires on..............:', - 'domain.changed' => 'Record last updated on..:' - ); - - $r = easy_parser($data_str, $items, 'dmy', false, false, true); - - if (isset($r['domain']['sponsor']) && is_array($r['domain']['sponsor'])) - $r['domain']['sponsor'] = $r['domain']['sponsor'][0]; - - foreach($r as $key => $part) - { - if (isset($part['address'])) - { - $r[$key]['organization'] = array_shift($r[$key]['address']); - $r[$key]['address']['country'] = array_pop($r[$key]['address']); - } - } - return $r; - } - } -?> + 'Registrant:', + 'admin' => 'Administrative Contact:', + 'tech' => 'Technical Contact, Zone Contact:', + 'domain.name' => 'Domain Name:', + 'domain.sponsor' => 'Registrar Name:', + 'domain.nserver' => 'Domain servers in listed order:', + 'domain.created' => 'Created on..............:', + 'domain.expires' => 'Expires on..............:', + 'domain.changed' => 'Record last updated on..:' + ); + + $r = easy_parser($data_str, $items, 'dmy', false, false, true); + + if (isset($r['domain']['sponsor']) && is_array($r['domain']['sponsor'])) + $r['domain']['sponsor'] = $r['domain']['sponsor'][0]; + + foreach($r as $key => $part) + { + if (isset($part['address'])) + { + $r[$key]['organization'] = array_shift($r[$key]['address']); + $r[$key]['address']['country'] = array_pop($r[$key]['address']); + } + } + return $r; + } + } +?> diff --git a/whois.gtld.melbourneit.php b/classes/whois.gtld.melbourneit.php similarity index 97% rename from whois.gtld.melbourneit.php rename to classes/whois.gtld.melbourneit.php index bbddd4c..f0966aa 100644 --- a/whois.gtld.melbourneit.php +++ b/classes/whois.gtld.melbourneit.php @@ -1,59 +1,59 @@ - 'domain.name', - 'Registration Date....' => 'domain.created', - 'Expiry Date..........' => 'domain.expires', - 'Organisation Name....' => 'owner.name', - 'Organisation Address.' => 'owner.address.', - 'Admin Name...........' => 'admin.name', - 'Admin Address........' => 'admin.address.', - 'Admin Email..........' => 'admin.email', - 'Admin Phone..........' => 'admin.phone', - 'Admin Fax............' => 'admin.fax', - 'Tech Name............' => 'tech.name', - 'Tech Address.........' => 'tech.address.', - 'Tech Email...........' => 'tech.email', - 'Tech Phone...........' => 'tech.phone', - 'Tech Fax.............' => 'tech.fax', - 'Name Server..........' => 'domain.nserver.' - ); - - return generic_parser_b($data_str, $items, 'ymd'); - } - } + 'domain.name', + 'Registration Date....' => 'domain.created', + 'Expiry Date..........' => 'domain.expires', + 'Organisation Name....' => 'owner.name', + 'Organisation Address.' => 'owner.address.', + 'Admin Name...........' => 'admin.name', + 'Admin Address........' => 'admin.address.', + 'Admin Email..........' => 'admin.email', + 'Admin Phone..........' => 'admin.phone', + 'Admin Fax............' => 'admin.fax', + 'Tech Name............' => 'tech.name', + 'Tech Address.........' => 'tech.address.', + 'Tech Email...........' => 'tech.email', + 'Tech Phone...........' => 'tech.phone', + 'Tech Fax.............' => 'tech.fax', + 'Name Server..........' => 'domain.nserver.' + ); + + return generic_parser_b($data_str, $items, 'ymd'); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.moniker.php b/classes/whois.gtld.moniker.php similarity index 97% rename from whois.gtld.moniker.php rename to classes/whois.gtld.moniker.php index 0824f9e..a8028f0 100644 --- a/whois.gtld.moniker.php +++ b/classes/whois.gtld.moniker.php @@ -1,52 +1,52 @@ - 'Registrant', - 'admin' => 'Administrative ', - 'tech' => 'Technical ', - 'billing' => 'Billing ', - 'domain.name' => 'Domain Name:', - 'domain.nserver.' => 'Domain servers in listed order:', - 'domain.created' => 'Record created on: ', - 'domain.expires' => 'Domain Expires on: ', - 'domain.changed' => 'Database last updated on: ' - ); - - return easy_parser($data_str, $items, 'ymd'); - } - } + 'Registrant', + 'admin' => 'Administrative ', + 'tech' => 'Technical ', + 'billing' => 'Billing ', + 'domain.name' => 'Domain Name:', + 'domain.nserver.' => 'Domain servers in listed order:', + 'domain.created' => 'Record created on: ', + 'domain.expires' => 'Domain Expires on: ', + 'domain.changed' => 'Database last updated on: ' + ); + + return easy_parser($data_str, $items, 'ymd'); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.name.php b/classes/whois.gtld.name.php similarity index 96% rename from whois.gtld.name.php rename to classes/whois.gtld.name.php index be0a51d..666c686 100644 --- a/whois.gtld.name.php +++ b/classes/whois.gtld.name.php @@ -1,56 +1,56 @@ - 'REGISTRANT CONTACT INFO', - 'admin' => 'ADMINISTRATIVE CONTACT INFO', - 'tech' => 'TECHNICAL CONTACT INFO', - 'billing' => 'BILLING CONTACT INFO', - 'domain.name' => 'Domain Name:', - 'domain.sponsor' => 'Registrar', - 'domain.created' => 'Creation Date:', - 'domain.expires' => 'Expiration Date:' - ); - - $extra = array( - 'phone:' => 'phone', - 'email address:' => 'email' - ); - - return easy_parser($data_str, $items, 'y-m-d', $extra, false, true); - } - } + 'REGISTRANT CONTACT INFO', + 'admin' => 'ADMINISTRATIVE CONTACT INFO', + 'tech' => 'TECHNICAL CONTACT INFO', + 'billing' => 'BILLING CONTACT INFO', + 'domain.name' => 'Domain Name:', + 'domain.sponsor' => 'Registrar', + 'domain.created' => 'Creation Date:', + 'domain.expires' => 'Expiration Date:' + ); + + $extra = array( + 'phone:' => 'phone', + 'email address:' => 'email' + ); + + return easy_parser($data_str, $items, 'y-m-d', $extra, false, true); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.nameintel.php b/classes/whois.gtld.nameintel.php similarity index 96% rename from whois.gtld.nameintel.php rename to classes/whois.gtld.nameintel.php index d103715..be3610e 100644 --- a/whois.gtld.nameintel.php +++ b/classes/whois.gtld.nameintel.php @@ -1,64 +1,64 @@ - 'Registrant Contact:', - 'admin' => 'Administrative Contact:', - 'tech' => 'Technical Contact', - 'domain.name' => 'Domain Name:', - 'domain.status' => 'Status:', - 'domain.nserver' => 'Name Server:', - 'domain.created' => 'Creation Date:', - 'domain.expires' => 'Expiration Date:' - ); - - $r = easy_parser($data_str, $items, 'dmy', false, false, true); - - if (isset($r['domain']['sponsor']) && is_array($r['domain']['sponsor'])) - $r['domain']['sponsor'] = $r['domain']['sponsor'][0]; - - foreach($r as $key => $part) - { - if (isset($part['address'])) - { - $r[$key]['organization'] = array_shift($r[$key]['address']); - $r[$key]['address']['country'] = array_pop($r[$key]['address']); - } - } - return $r; - } - } -?> + 'Registrant Contact:', + 'admin' => 'Administrative Contact:', + 'tech' => 'Technical Contact', + 'domain.name' => 'Domain Name:', + 'domain.status' => 'Status:', + 'domain.nserver' => 'Name Server:', + 'domain.created' => 'Creation Date:', + 'domain.expires' => 'Expiration Date:' + ); + + $r = easy_parser($data_str, $items, 'dmy', false, false, true); + + if (isset($r['domain']['sponsor']) && is_array($r['domain']['sponsor'])) + $r['domain']['sponsor'] = $r['domain']['sponsor'][0]; + + foreach($r as $key => $part) + { + if (isset($part['address'])) + { + $r[$key]['organization'] = array_shift($r[$key]['address']); + $r[$key]['address']['country'] = array_pop($r[$key]['address']); + } + } + return $r; + } + } +?> diff --git a/whois.gtld.namejuice.php b/classes/whois.gtld.namejuice.php old mode 100755 new mode 100644 similarity index 100% rename from whois.gtld.namejuice.php rename to classes/whois.gtld.namejuice.php diff --git a/whois.gtld.nameking.php b/classes/whois.gtld.nameking.php similarity index 96% rename from whois.gtld.nameking.php rename to classes/whois.gtld.nameking.php index 49680a1..b9cad3a 100644 --- a/whois.gtld.nameking.php +++ b/classes/whois.gtld.nameking.php @@ -1,70 +1,70 @@ - 'Registrant', - 'admin' => 'Admin Contact', - 'tech' => 'Tech Contact', - 'billing' => 'Billing Contact', - 'domain.sponsor' => 'Registration Provided By:', - 'domain.created' => 'Creation Date:', - 'domain.expires' => 'Expiration Date:', - ); - - $extra = array( - 'tel--' => 'phone', - 'tel:' => 'phone', - 'tel --:' => 'phone', - 'email-:' => 'email', - 'email:' => 'email', - 'mail:' => 'email', - 'name--' => 'name', - 'org:' => 'organization', - 'zipcode:' => 'address.pcode', - 'postcode:' => 'address.pcode', - 'address:' => 'address.street', - 'city:' => 'address.city', - 'province:' => 'address.city.', - ',province:' => '', - ',country:' => 'address.country', - 'organization:' => 'organization', - 'city, province, post code:' => 'address.city' - ); - - return easy_parser($data_str, $items, 'mdy', $extra, false, true); - } - } + 'Registrant', + 'admin' => 'Admin Contact', + 'tech' => 'Tech Contact', + 'billing' => 'Billing Contact', + 'domain.sponsor' => 'Registration Provided By:', + 'domain.created' => 'Creation Date:', + 'domain.expires' => 'Expiration Date:', + ); + + $extra = array( + 'tel--' => 'phone', + 'tel:' => 'phone', + 'tel --:' => 'phone', + 'email-:' => 'email', + 'email:' => 'email', + 'mail:' => 'email', + 'name--' => 'name', + 'org:' => 'organization', + 'zipcode:' => 'address.pcode', + 'postcode:' => 'address.pcode', + 'address:' => 'address.street', + 'city:' => 'address.city', + 'province:' => 'address.city.', + ',province:' => '', + ',country:' => 'address.country', + 'organization:' => 'organization', + 'city, province, post code:' => 'address.city' + ); + + return easy_parser($data_str, $items, 'mdy', $extra, false, true); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.names4ever.php b/classes/whois.gtld.names4ever.php similarity index 97% rename from whois.gtld.names4ever.php rename to classes/whois.gtld.names4ever.php index 3cd046e..84f61a9 100644 --- a/whois.gtld.names4ever.php +++ b/classes/whois.gtld.names4ever.php @@ -1,54 +1,54 @@ - 'Registrant:', - 'admin' => 'Administrative Contact', - 'tech' => 'Technical Contact', - 'domain.name' => 'Domain Name:', - 'domain.sponsor' => 'Registrar Name....:', - 'domain.referrer' => 'Registrar Homepage:', - 'domain.nserver' => 'DNS Servers:', - 'domain.created' => 'Record created on', - 'domain.expires' => 'Record expires on', - 'domain.changed' => 'Record last updated on', - 'domain.status' => 'Domain status:' - ); - - return easy_parser($data_str, $items, 'dmy', false, false, true); - } - } + 'Registrant:', + 'admin' => 'Administrative Contact', + 'tech' => 'Technical Contact', + 'domain.name' => 'Domain Name:', + 'domain.sponsor' => 'Registrar Name....:', + 'domain.referrer' => 'Registrar Homepage:', + 'domain.nserver' => 'DNS Servers:', + 'domain.created' => 'Record created on', + 'domain.expires' => 'Record expires on', + 'domain.changed' => 'Record last updated on', + 'domain.status' => 'Domain status:' + ); + + return easy_parser($data_str, $items, 'dmy', false, false, true); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.namevault.php b/classes/whois.gtld.namevault.php similarity index 96% rename from whois.gtld.namevault.php rename to classes/whois.gtld.namevault.php index a8199cf..100a7e8 100644 --- a/whois.gtld.namevault.php +++ b/classes/whois.gtld.namevault.php @@ -1,52 +1,52 @@ - 'Registrant', - 'admin' => 'Administrative Contact:', - 'tech' => 'Technical Contact:', - 'billing' => 'Billing Contact:', - 'domain.name' => 'Domain Name:', - 'domain.nserver.' => 'Name Servers', - 'domain.created' => 'Creation Date:', - 'domain.expires' => 'Expiration Date:', - 'domain.status' => 'Status:' - ); - - return easy_parser($data_str, $items, 'dmy', false, true, true); - } - } + 'Registrant', + 'admin' => 'Administrative Contact:', + 'tech' => 'Technical Contact:', + 'billing' => 'Billing Contact:', + 'domain.name' => 'Domain Name:', + 'domain.nserver.' => 'Name Servers', + 'domain.created' => 'Creation Date:', + 'domain.expires' => 'Expiration Date:', + 'domain.status' => 'Status:' + ); + + return easy_parser($data_str, $items, 'dmy', false, true, true); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.networksolutions.php b/classes/whois.gtld.networksolutions.php similarity index 97% rename from whois.gtld.networksolutions.php rename to classes/whois.gtld.networksolutions.php index c5ec38f..c8fbb00 100644 --- a/whois.gtld.networksolutions.php +++ b/classes/whois.gtld.networksolutions.php @@ -1,50 +1,50 @@ - 'Registrant:', - 'admin' => 'Administrative Contact', - 'tech' => 'Technical Contact', - 'domain.name' => 'Domain Name:', - 'domain.nserver.' => 'Domain servers in listed order:', - 'domain.created' => 'Record created on', - 'domain.expires' => 'Record expires on' - ); - - return easy_parser($data_str, $items, 'dmy',false,true,true); - } - } + 'Registrant:', + 'admin' => 'Administrative Contact', + 'tech' => 'Technical Contact', + 'domain.name' => 'Domain Name:', + 'domain.nserver.' => 'Domain servers in listed order:', + 'domain.created' => 'Record created on', + 'domain.expires' => 'Record expires on' + ); + + return easy_parser($data_str, $items, 'dmy',false,true,true); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.nicco.php b/classes/whois.gtld.nicco.php similarity index 96% rename from whois.gtld.nicco.php rename to classes/whois.gtld.nicco.php index dc1fd4b..7d89126 100644 --- a/whois.gtld.nicco.php +++ b/classes/whois.gtld.nicco.php @@ -1,62 +1,62 @@ - 'Holder Contact', - 'admin' => 'Admin Contact', - 'tech' => 'Tech. Contact', - 'domain.nserver.' => 'Nameservers', - 'domain.created' => 'Creation Date:', - 'domain.expires' => 'Expiration Date:' - ); - - $translate = array( - 'city:' => 'address.city', - 'org. name:' => 'organization', - 'address1:' => 'address.street.', - 'address2:' => 'address.street.', - 'state:' => 'address.state', - 'postal code:' => 'address.zip' - ); - - $r = get_blocks($data_str, $items, true); - $r['owner'] = get_contact($r['owner'],$translate); - $r['admin'] = get_contact($r['admin'],$translate,true); - $r['tech'] = get_contact($r['tech'],$translate,true); - return format_dates($r, 'dmy'); - } - } + 'Holder Contact', + 'admin' => 'Admin Contact', + 'tech' => 'Tech. Contact', + 'domain.nserver.' => 'Nameservers', + 'domain.created' => 'Creation Date:', + 'domain.expires' => 'Expiration Date:' + ); + + $translate = array( + 'city:' => 'address.city', + 'org. name:' => 'organization', + 'address1:' => 'address.street.', + 'address2:' => 'address.street.', + 'state:' => 'address.state', + 'postal code:' => 'address.zip' + ); + + $r = get_blocks($data_str, $items, true); + $r['owner'] = get_contact($r['owner'],$translate); + $r['admin'] = get_contact($r['admin'],$translate,true); + $r['tech'] = get_contact($r['tech'],$translate,true); + return format_dates($r, 'dmy'); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.nicline.php b/classes/whois.gtld.nicline.php similarity index 96% rename from whois.gtld.nicline.php rename to classes/whois.gtld.nicline.php index 77bbbfd..4f8200b 100644 --- a/whois.gtld.nicline.php +++ b/classes/whois.gtld.nicline.php @@ -1,51 +1,51 @@ - 'Registrant:', - 'admin' => 'Administrative contact:', - 'tech' => 'Technical contact:', - 'domain.name' => 'Domain name:', - 'domain.nserver.' => 'Domain servers in listed order:', - 'domain.created' => 'Created:', - 'domain.expires' => 'Expires:', - 'domain.changed' => 'Last updated:' - ); - - return easy_parser($data_str, $items, 'dmy'); - } - } + 'Registrant:', + 'admin' => 'Administrative contact:', + 'tech' => 'Technical contact:', + 'domain.name' => 'Domain name:', + 'domain.nserver.' => 'Domain servers in listed order:', + 'domain.created' => 'Created:', + 'domain.expires' => 'Expires:', + 'domain.changed' => 'Last updated:' + ); + + return easy_parser($data_str, $items, 'dmy'); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.onlinenic.php b/classes/whois.gtld.onlinenic.php similarity index 96% rename from whois.gtld.onlinenic.php rename to classes/whois.gtld.onlinenic.php index 8bfe88d..0846d88 100644 --- a/whois.gtld.onlinenic.php +++ b/classes/whois.gtld.onlinenic.php @@ -1,83 +1,83 @@ - 'Registrant:', - 'admin' => 'Administrator:', - 'tech' => 'Technical Contactor:', - 'billing' => 'Billing Contactor:', - 'domain.name' => 'Domain name:', - 'domain.name#' => 'Domain Name:', - 'domain.nserver' => 'Domain servers in listed order:', - 'domain.created' => 'Record created on ', - 'domain.expires' => 'Record expired on ', - 'domain.changed' => 'Record last updated at ' - ); - - $extra = array( - 'tel--' => 'phone', - 'tel:' => 'phone', - 'tel --:' => 'phone', - 'email-:' => 'email', - 'email:' => 'email', - 'mail:' => 'email', - 'name--' => 'name', - 'org:' => 'organization', - 'zipcode:' => 'address.pcode', - 'postcode:' => 'address.pcode', - 'address:' => 'address.street', - 'city:' => 'address.city', - 'province:' => '', - ',province:' => '', - ',country:' => 'address.country' - ); - - $r = easy_parser($data_str, $items, 'mdy',$extra,false,true); - - foreach($r as $key => $part) - if (isset($part['email'])) - { - @list($email,$phone) = explode(' ',$part['email']); - $email = str_replace('(','',$email); - $email = str_replace(')','',$email); - $r[$key]['email'] = $email; - if ($phone != '') $r[$key]['phone'] = $phone; - } - - return $r; - } - } + 'Registrant:', + 'admin' => 'Administrator:', + 'tech' => 'Technical Contactor:', + 'billing' => 'Billing Contactor:', + 'domain.name' => 'Domain name:', + 'domain.name#' => 'Domain Name:', + 'domain.nserver' => 'Domain servers in listed order:', + 'domain.created' => 'Record created on ', + 'domain.expires' => 'Record expired on ', + 'domain.changed' => 'Record last updated at ' + ); + + $extra = array( + 'tel--' => 'phone', + 'tel:' => 'phone', + 'tel --:' => 'phone', + 'email-:' => 'email', + 'email:' => 'email', + 'mail:' => 'email', + 'name--' => 'name', + 'org:' => 'organization', + 'zipcode:' => 'address.pcode', + 'postcode:' => 'address.pcode', + 'address:' => 'address.street', + 'city:' => 'address.city', + 'province:' => '', + ',province:' => '', + ',country:' => 'address.country' + ); + + $r = easy_parser($data_str, $items, 'mdy',$extra,false,true); + + foreach($r as $key => $part) + if (isset($part['email'])) + { + @list($email,$phone) = explode(' ',$part['email']); + $email = str_replace('(','',$email); + $email = str_replace(')','',$email); + $r[$key]['email'] = $email; + if ($phone != '') $r[$key]['phone'] = $phone; + } + + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.gtld.opensrs.php b/classes/whois.gtld.opensrs.php old mode 100755 new mode 100644 similarity index 97% rename from whois.gtld.opensrs.php rename to classes/whois.gtld.opensrs.php index cdf21a5..fd23fe9 --- a/whois.gtld.opensrs.php +++ b/classes/whois.gtld.opensrs.php @@ -1,58 +1,58 @@ - 'Registrant:', - 'admin' => 'Administrative Contact', - 'tech' => 'Technical Contact', - 'domain.name' => 'Domain name:', - '' => 'Registration Service Provider:', - 'domain.nserver' => 'Domain servers in listed order:', - 'domain.changed' => 'Record last updated on', - 'domain.created' => 'Record created on', - 'domain.expires' => 'Record expires on', - 'domain.sponsor' => 'Registrar of Record:' - ); - - $r = easy_parser($data_str, $items, 'dmy', false, false, true); - - if (isset($r['domain']['sponsor']) && is_array($r['domain']['sponsor'])) - $r['domain']['sponsor'] = $r['domain']['sponsor'][0]; - - return $r; - } - } + 'Registrant:', + 'admin' => 'Administrative Contact', + 'tech' => 'Technical Contact', + 'domain.name' => 'Domain name:', + '' => 'Registration Service Provider:', + 'domain.nserver' => 'Domain servers in listed order:', + 'domain.changed' => 'Record last updated on', + 'domain.created' => 'Record created on', + 'domain.expires' => 'Record expires on', + 'domain.sponsor' => 'Registrar of Record:' + ); + + $r = easy_parser($data_str, $items, 'dmy', false, false, true); + + if (isset($r['domain']['sponsor']) && is_array($r['domain']['sponsor'])) + $r['domain']['sponsor'] = $r['domain']['sponsor'][0]; + + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.gtld.ovh.php b/classes/whois.gtld.ovh.php similarity index 96% rename from whois.gtld.ovh.php rename to classes/whois.gtld.ovh.php index df6ee71..f6a7d5f 100644 --- a/whois.gtld.ovh.php +++ b/classes/whois.gtld.ovh.php @@ -1,51 +1,51 @@ - 'Registrant:', - 'admin' => 'Administrative Contact:', - 'tech' => 'Technical Contact:', - 'billing' => 'Billing Contact:', - 'domain.sponsor' => 'Registrar of Record:', - 'domain.changed' => 'Record last updated on', - 'domain.expires' => 'Record expires on', - 'domain.created' => 'Record created on' - ); - - return easy_parser($data_str, $items, 'mdy',false,false,true); - } - } + 'Registrant:', + 'admin' => 'Administrative Contact:', + 'tech' => 'Technical Contact:', + 'billing' => 'Billing Contact:', + 'domain.sponsor' => 'Registrar of Record:', + 'domain.changed' => 'Record last updated on', + 'domain.expires' => 'Record expires on', + 'domain.created' => 'Record created on' + ); + + return easy_parser($data_str, $items, 'mdy',false,false,true); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.php b/classes/whois.gtld.php old mode 100755 new mode 100644 similarity index 97% rename from whois.gtld.php rename to classes/whois.gtld.php index 6f46bc2..301c184 --- a/whois.gtld.php +++ b/classes/whois.gtld.php @@ -1,84 +1,84 @@ - 'regrinfo.domain.name', - 'Registrar:' => 'regyinfo.registrar', - 'Whois Server:' => 'regyinfo.whois', - 'Referral URL:' => 'regyinfo.referrer', - 'Name Server:' => 'regrinfo.domain.nserver.', // identical descriptors - 'Updated Date:' => 'regrinfo.domain.changed', - 'Last Updated On:' => 'regrinfo.domain.changed', - 'EPP Status:' => 'regrinfo.domain.epp_status.', - 'Status:' => 'regrinfo.domain.status.', - 'Creation Date:' => 'regrinfo.domain.created', - 'Created On:' => 'regrinfo.domain.created', - 'Expiration Date:' => 'regrinfo.domain.expires', - 'Updated Date:' => 'regrinfo.domain.changed', - 'No match for ' => 'nodomain' - ); - - function parse($data, $query) - { - $this->Query = array(); - if ( is_array( $query ) and array_key_exists( 'handler', $query ) ) - { - $this->SUBVERSION = sprintf('%s-%s', $query['handler'], $this->HANDLER_VERSION); - } - $this->result = generic_parser_b($data['rawdata'], $this->REG_FIELDS, 'dmy'); - - unset($this->result['registered']); - - if (isset($this->result['nodomain'])) - { - unset($this->result['nodomain']); - $this->result['regrinfo']['registered'] = 'no'; - return $this->result; - } - - if ($this->deep_whois) $this->result = $this->DeepWhois($query,$this->result); - - // Next server could fail to return data - if (empty($this->result['rawdata']) || count($this->result['rawdata']) < 3) - $this->result['rawdata'] = $data['rawdata']; - - // Domain is registered no matter what next server says - $this->result['regrinfo']['registered'] = 'yes'; - - return $this->result; - } - } -?> + 'regrinfo.domain.name', + 'Registrar:' => 'regyinfo.registrar', + 'Whois Server:' => 'regyinfo.whois', + 'Referral URL:' => 'regyinfo.referrer', + 'Name Server:' => 'regrinfo.domain.nserver.', // identical descriptors + 'Updated Date:' => 'regrinfo.domain.changed', + 'Last Updated On:' => 'regrinfo.domain.changed', + 'EPP Status:' => 'regrinfo.domain.epp_status.', + 'Status:' => 'regrinfo.domain.status.', + 'Creation Date:' => 'regrinfo.domain.created', + 'Created On:' => 'regrinfo.domain.created', + 'Expiration Date:' => 'regrinfo.domain.expires', + 'Updated Date:' => 'regrinfo.domain.changed', + 'No match for ' => 'nodomain' + ); + + function parse($data, $query) + { + $this->Query = array(); + if ( is_array( $query ) and array_key_exists( 'handler', $query ) ) + { + $this->SUBVERSION = sprintf('%s-%s', $query['handler'], $this->HANDLER_VERSION); + } + $this->result = generic_parser_b($data['rawdata'], $this->REG_FIELDS, 'dmy'); + + unset($this->result['registered']); + + if (isset($this->result['nodomain'])) + { + unset($this->result['nodomain']); + $this->result['regrinfo']['registered'] = 'no'; + return $this->result; + } + + if ($this->deep_whois) $this->result = $this->DeepWhois($query,$this->result); + + // Next server could fail to return data + if (empty($this->result['rawdata']) || count($this->result['rawdata']) < 3) + $this->result['rawdata'] = $data['rawdata']; + + // Domain is registered no matter what next server says + $this->result['regrinfo']['registered'] = 'yes'; + + return $this->result; + } + } +?> diff --git a/whois.gtld.psiusa.php b/classes/whois.gtld.psiusa.php old mode 100755 new mode 100644 similarity index 97% rename from whois.gtld.psiusa.php rename to classes/whois.gtld.psiusa.php index 6a266a8..79047a2 --- a/whois.gtld.psiusa.php +++ b/classes/whois.gtld.psiusa.php @@ -1,90 +1,90 @@ - 'domain.created', - 'last-changed:' => 'domain.changed', - 'status:' => 'domain.status', - '[owner-c] fname:' => 'owner.name.first', - '[owner-c] lname:' => 'owner.name.last', - '[owner-c] org:' => 'owner.organization', - '[owner-c] address:' => 'owner.address.street', - '[owner-c] city:' => 'owner.address.city', - '[owner-c] pcode:' => 'owner.address.pcode', - '[owner-c] country:' => 'owner.address.country', - '[owner-c] state:' => 'owner.address.state', - '[owner-c] phone:' => 'owner.phone', - '[owner-c] fax:' => 'owner.fax', - '[owner-c] email:' => 'owner.email', - '[admin-c] fname:' => 'admin.name.first', - '[admin-c] lname:' => 'admin.name.last', - '[admin-c] org:' => 'admin.organization', - '[admin-c] address:' => 'admin.address.street', - '[admin-c] city:' => 'admin.address.city', - '[admin-c] pcode:' => 'admin.address.pcode', - '[admin-c] country:' => 'admin.address.country', - '[admin-c] state:' => 'admin.address.state', - '[admin-c] phone:' => 'admin.phone', - '[admin-c] fax:' => 'admin.fax', - '[admin-c] email:' => 'admin.email', - '[tech-c] fname:' => 'tech.name.first', - '[tech-c] lname:' => 'tech.name.last', - '[tech-c] org:' => 'tech.organization', - '[tech-c] address:' => 'tech.address.street', - '[tech-c] city:' => 'tech.address.city', - '[tech-c] pcode:' => 'tech.address.pcode', - '[tech-c] country:' => 'tech.address.country', - '[tech-c] state:' => 'tech.address.state', - '[tech-c] phone:' => 'tech.phone', - '[tech-c] fax:' => 'tech.fax', - '[tech-c] email:' => 'tech.email', - '[zone-c] fname:' => 'zone.name.first', - '[zone-c] lname:' => 'zone.name.last', - '[zone-c] org:' => 'zone.organization', - '[zone-c] address:' => 'zone.address.street', - '[zone-c] city:' => 'zone.address.city', - '[zone-c] pcode:' => 'zone.address.pcode', - '[zone-c] country:' => 'zone.address.country', - '[zone-c] state:' => 'zone.address.state', - '[zone-c] phone:' => 'zone.phone', - '[zone-c] fax:' => 'zone.fax', - '[zone-c] email:' => 'zone.email', - ); - - return generic_parser_b($data_str, $items); - } - } + 'domain.created', + 'last-changed:' => 'domain.changed', + 'status:' => 'domain.status', + '[owner-c] fname:' => 'owner.name.first', + '[owner-c] lname:' => 'owner.name.last', + '[owner-c] org:' => 'owner.organization', + '[owner-c] address:' => 'owner.address.street', + '[owner-c] city:' => 'owner.address.city', + '[owner-c] pcode:' => 'owner.address.pcode', + '[owner-c] country:' => 'owner.address.country', + '[owner-c] state:' => 'owner.address.state', + '[owner-c] phone:' => 'owner.phone', + '[owner-c] fax:' => 'owner.fax', + '[owner-c] email:' => 'owner.email', + '[admin-c] fname:' => 'admin.name.first', + '[admin-c] lname:' => 'admin.name.last', + '[admin-c] org:' => 'admin.organization', + '[admin-c] address:' => 'admin.address.street', + '[admin-c] city:' => 'admin.address.city', + '[admin-c] pcode:' => 'admin.address.pcode', + '[admin-c] country:' => 'admin.address.country', + '[admin-c] state:' => 'admin.address.state', + '[admin-c] phone:' => 'admin.phone', + '[admin-c] fax:' => 'admin.fax', + '[admin-c] email:' => 'admin.email', + '[tech-c] fname:' => 'tech.name.first', + '[tech-c] lname:' => 'tech.name.last', + '[tech-c] org:' => 'tech.organization', + '[tech-c] address:' => 'tech.address.street', + '[tech-c] city:' => 'tech.address.city', + '[tech-c] pcode:' => 'tech.address.pcode', + '[tech-c] country:' => 'tech.address.country', + '[tech-c] state:' => 'tech.address.state', + '[tech-c] phone:' => 'tech.phone', + '[tech-c] fax:' => 'tech.fax', + '[tech-c] email:' => 'tech.email', + '[zone-c] fname:' => 'zone.name.first', + '[zone-c] lname:' => 'zone.name.last', + '[zone-c] org:' => 'zone.organization', + '[zone-c] address:' => 'zone.address.street', + '[zone-c] city:' => 'zone.address.city', + '[zone-c] pcode:' => 'zone.address.pcode', + '[zone-c] country:' => 'zone.address.country', + '[zone-c] state:' => 'zone.address.state', + '[zone-c] phone:' => 'zone.phone', + '[zone-c] fax:' => 'zone.fax', + '[zone-c] email:' => 'zone.email', + ); + + return generic_parser_b($data_str, $items); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.publicdomainregistry.php b/classes/whois.gtld.publicdomainregistry.php similarity index 97% rename from whois.gtld.publicdomainregistry.php rename to classes/whois.gtld.publicdomainregistry.php index 3982552..1e8ddb6 100644 --- a/whois.gtld.publicdomainregistry.php +++ b/classes/whois.gtld.publicdomainregistry.php @@ -1,57 +1,57 @@ - 'Registrant:', - 'owner#' => '(Registrant):', - 'admin' => 'Administrative Contact', - 'tech' => 'Technical Contact', - 'billing' => 'Billing Contact', - 'domain.name' => 'Domain name:', - 'domain.sponsor' => 'Registration Service Provided By:', - 'domain.nserver' => 'Domain servers in listed order:', - 'domain.changed' => 'Record last updated ', - 'domain.created' => 'Record created on', - 'domain.created#' => 'Creation Date:', - 'domain.expires' => 'Record expires on', - 'domain.expires#' => 'Expiration Date:', - 'domain.status' => 'Status:' - ); - - return easy_parser($data_str, $items, 'mdy', false, true, true); - } - } + 'Registrant:', + 'owner#' => '(Registrant):', + 'admin' => 'Administrative Contact', + 'tech' => 'Technical Contact', + 'billing' => 'Billing Contact', + 'domain.name' => 'Domain name:', + 'domain.sponsor' => 'Registration Service Provided By:', + 'domain.nserver' => 'Domain servers in listed order:', + 'domain.changed' => 'Record last updated ', + 'domain.created' => 'Record created on', + 'domain.created#' => 'Creation Date:', + 'domain.expires' => 'Record expires on', + 'domain.expires#' => 'Expiration Date:', + 'domain.status' => 'Status:' + ); + + return easy_parser($data_str, $items, 'mdy', false, true, true); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.register.php b/classes/whois.gtld.register.php old mode 100755 new mode 100644 similarity index 97% rename from whois.gtld.register.php rename to classes/whois.gtld.register.php index 51f3169..2d865b6 --- a/whois.gtld.register.php +++ b/classes/whois.gtld.register.php @@ -1,62 +1,62 @@ - 'Registrant Info:', - 'owner#1' => 'Organization:', - 'owner#2' => 'Registrant:', - 'owner#3' => 'Registrant Contact:', - 'admin' => 'Administrative', - 'tech' => 'Technical', - 'zone' => 'Zone', - 'domain.sponsor#0' => 'Registrar Name....:', - 'domain.sponsor#1' => 'Registration Service Provided By:', - 'domain.referrer' => 'Registrar Homepage:', - 'domain.nserver' => 'Domain servers in listed order:', - 'domain.nserver' => 'DNS Servers:', - 'domain.name' => 'Domain name:', - 'domain.created#0' => 'Created on..............:', - 'domain.created#1' => 'Creation date:', - 'domain.expires#0' => 'Expires on..............:', - 'domain.expires#1' => 'Expiration date:', - 'domain.changed' => 'Record last updated on..:', - 'domain.status' => 'Status:' - ); - - return easy_parser($data_str, $items, 'ymd'); - } - } + 'Registrant Info:', + 'owner#1' => 'Organization:', + 'owner#2' => 'Registrant:', + 'owner#3' => 'Registrant Contact:', + 'admin' => 'Administrative', + 'tech' => 'Technical', + 'zone' => 'Zone', + 'domain.sponsor#0' => 'Registrar Name....:', + 'domain.sponsor#1' => 'Registration Service Provided By:', + 'domain.referrer' => 'Registrar Homepage:', + 'domain.nserver' => 'Domain servers in listed order:', + 'domain.nserver' => 'DNS Servers:', + 'domain.name' => 'Domain name:', + 'domain.created#0' => 'Created on..............:', + 'domain.created#1' => 'Creation date:', + 'domain.expires#0' => 'Expires on..............:', + 'domain.expires#1' => 'Expiration date:', + 'domain.changed' => 'Record last updated on..:', + 'domain.status' => 'Status:' + ); + + return easy_parser($data_str, $items, 'ymd'); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.rrpproxy.php b/classes/whois.gtld.rrpproxy.php similarity index 97% rename from whois.gtld.rrpproxy.php rename to classes/whois.gtld.rrpproxy.php index 2a81430..832599b 100644 --- a/whois.gtld.rrpproxy.php +++ b/classes/whois.gtld.rrpproxy.php @@ -1,92 +1,92 @@ - 'domain.created', - 'updated-date:' => 'domain.changed', - 'registration-expiration-date:' => 'domain.expires', - 'RSP:' => 'domain.sponsor', - 'URL:' => 'domain.referrer', - 'owner-nom.contact:' => 'owner.handle', - 'owner-fname:' => 'owner.name.first', - 'owner-lname:' => 'owner.name.last', - 'owner-organization:' => 'owner.organization', - 'owner-street:' => 'owner.address.street', - 'owner-city:' => 'owner.address.city', - 'owner-zip:' => 'owner.address.pcode', - 'owner-country:' => 'owner.address.country', - 'owner-phone:' => 'owner.phone', - 'owner-fax:' => 'owner.fax', - 'owner-email:' => 'owner.email', - 'admin-nom.contact:' => 'admin.handle', - 'admin-fname:' => 'admin.name.first', - 'admin-lname:' => 'admin.name.last', - 'admin-organization:' => 'admin.organization', - 'admin-street:' => 'admin.address.street', - 'admin-city:' => 'admin.address.city', - 'admin-zip:' => 'admin.address.pcode', - 'admin-country:' => 'admin.address.country', - 'admin-phone:' => 'admin.phone', - 'admin-fax:' => 'admin.fax', - 'admin-email:' => 'admin.email', - 'tech-nom.contact:' => 'tech.handle', - 'tech-fname:' => 'tech.name.first', - 'tech-lname:' => 'tech.name.last', - 'tech-organization:' => 'tech.organization', - 'tech-street:' => 'tech.address.street', - 'tech-city:' => 'tech.address.city', - 'tech-zip:' => 'tech.address.pcode', - 'tech-country:' => 'tech.address.country', - 'tech-phone:' => 'tech.phone', - 'tech-fax:' => 'tech.fax', - 'tech-email:' => 'tech.email', - 'billing-nom.contact:' => 'billing.handle', - 'billing-fname:' => 'billing.name.first', - 'billing-lname:' => 'billing.name.last', - 'billing-organization:' => 'billing.organization', - 'billing-street:' => 'billing.address.street', - 'billing-city:' => 'billing.address.city', - 'billing-zip:' => 'billing.address.pcode', - 'billing-country:' => 'billing.address.country', - 'billing-phone:' => 'billing.phone', - 'billing-fax:' => 'billing.fax', - 'billing-email:' => 'billing.email' - ); - - return generic_parser_b($data_str, $items); - } - } + 'domain.created', + 'updated-date:' => 'domain.changed', + 'registration-expiration-date:' => 'domain.expires', + 'RSP:' => 'domain.sponsor', + 'URL:' => 'domain.referrer', + 'owner-nom.contact:' => 'owner.handle', + 'owner-fname:' => 'owner.name.first', + 'owner-lname:' => 'owner.name.last', + 'owner-organization:' => 'owner.organization', + 'owner-street:' => 'owner.address.street', + 'owner-city:' => 'owner.address.city', + 'owner-zip:' => 'owner.address.pcode', + 'owner-country:' => 'owner.address.country', + 'owner-phone:' => 'owner.phone', + 'owner-fax:' => 'owner.fax', + 'owner-email:' => 'owner.email', + 'admin-nom.contact:' => 'admin.handle', + 'admin-fname:' => 'admin.name.first', + 'admin-lname:' => 'admin.name.last', + 'admin-organization:' => 'admin.organization', + 'admin-street:' => 'admin.address.street', + 'admin-city:' => 'admin.address.city', + 'admin-zip:' => 'admin.address.pcode', + 'admin-country:' => 'admin.address.country', + 'admin-phone:' => 'admin.phone', + 'admin-fax:' => 'admin.fax', + 'admin-email:' => 'admin.email', + 'tech-nom.contact:' => 'tech.handle', + 'tech-fname:' => 'tech.name.first', + 'tech-lname:' => 'tech.name.last', + 'tech-organization:' => 'tech.organization', + 'tech-street:' => 'tech.address.street', + 'tech-city:' => 'tech.address.city', + 'tech-zip:' => 'tech.address.pcode', + 'tech-country:' => 'tech.address.country', + 'tech-phone:' => 'tech.phone', + 'tech-fax:' => 'tech.fax', + 'tech-email:' => 'tech.email', + 'billing-nom.contact:' => 'billing.handle', + 'billing-fname:' => 'billing.name.first', + 'billing-lname:' => 'billing.name.last', + 'billing-organization:' => 'billing.organization', + 'billing-street:' => 'billing.address.street', + 'billing-city:' => 'billing.address.city', + 'billing-zip:' => 'billing.address.pcode', + 'billing-country:' => 'billing.address.country', + 'billing-phone:' => 'billing.phone', + 'billing-fax:' => 'billing.fax', + 'billing-email:' => 'billing.email' + ); + + return generic_parser_b($data_str, $items); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.schlund.php b/classes/whois.gtld.schlund.php similarity index 97% rename from whois.gtld.schlund.php rename to classes/whois.gtld.schlund.php index 3de3fe6..eb77dc0 100644 --- a/whois.gtld.schlund.php +++ b/classes/whois.gtld.schlund.php @@ -1,86 +1,86 @@ - 'domain.created', - 'last-changed:' => 'domain.changed', - 'status:' => 'domain.status', - 'registrant-firstname:' => 'owner.name.first', - 'registrant-lastname:' => 'owner.name.last', - 'registrant-organization:' => 'owner.organization', - 'registrant-street1:' => 'owner.address.street.', - 'registrant-street2:' => 'owner.address.street.', - 'registrant-pcode:' => 'owner.address.pcode', - 'registrant-city:' => 'owner.address.city', - 'registrant-ccode:' => 'owner.address.country', - 'registrant-phone:' => 'owner.phone', - 'registrant-email:' => 'owner.email', - 'admin-c-firstname:' => 'admin.name.first', - 'admin-c-lastname:' => 'admin.name.last', - 'admin-c-organization:' => 'admin.organization', - 'admin-c-street1:' => 'admin.address.street.', - 'admin-c-street2:' => 'admin.address.street.', - 'admin-c-pcode:' => 'admin.address.pcode', - 'admin-c-city:' => 'admin.address.city', - 'admin-c-ccode:' => 'admin.address.country', - 'admin-c-phone:' => 'admin.phone', - 'admin-c-email:' => 'admin.email', - 'tech-c-firstname:' => 'tech.name.first', - 'tech-c-lastname:' => 'tech.name.last', - 'tech-c-organization:' => 'tech.organization', - 'tech-c-street1:' => 'tech.address.street.', - 'tech-c-street2:' => 'tech.address.street.', - 'tech-c-pcode:' => 'tech.address.pcode', - 'tech-c-city:' => 'tech.address.city', - 'tech-c-ccode:' => 'tech.address.country', - 'tech-c-phone:' => 'tech.phone', - 'tech-c-email:' => 'tech.email', - 'bill-c-firstname:' => 'billing.name.first', - 'bill-c-lastname:' => 'billing.name.last', - 'bill-c-organization:' => 'billing.organization', - 'bill-c-street1:' => 'billing.address.street.', - 'bill-c-street2:' => 'billing.address.street.', - 'bill-c-pcode:' => 'billing.address.pcode', - 'bill-c-city:' => 'billing.address.city', - 'bill-c-ccode:' => 'billing.address.country', - 'bill-c-phone:' => 'billing.phone', - 'bill-c-email:' => 'billing.email' - ); - - return generic_parser_b($data_str, $items); - } - } + 'domain.created', + 'last-changed:' => 'domain.changed', + 'status:' => 'domain.status', + 'registrant-firstname:' => 'owner.name.first', + 'registrant-lastname:' => 'owner.name.last', + 'registrant-organization:' => 'owner.organization', + 'registrant-street1:' => 'owner.address.street.', + 'registrant-street2:' => 'owner.address.street.', + 'registrant-pcode:' => 'owner.address.pcode', + 'registrant-city:' => 'owner.address.city', + 'registrant-ccode:' => 'owner.address.country', + 'registrant-phone:' => 'owner.phone', + 'registrant-email:' => 'owner.email', + 'admin-c-firstname:' => 'admin.name.first', + 'admin-c-lastname:' => 'admin.name.last', + 'admin-c-organization:' => 'admin.organization', + 'admin-c-street1:' => 'admin.address.street.', + 'admin-c-street2:' => 'admin.address.street.', + 'admin-c-pcode:' => 'admin.address.pcode', + 'admin-c-city:' => 'admin.address.city', + 'admin-c-ccode:' => 'admin.address.country', + 'admin-c-phone:' => 'admin.phone', + 'admin-c-email:' => 'admin.email', + 'tech-c-firstname:' => 'tech.name.first', + 'tech-c-lastname:' => 'tech.name.last', + 'tech-c-organization:' => 'tech.organization', + 'tech-c-street1:' => 'tech.address.street.', + 'tech-c-street2:' => 'tech.address.street.', + 'tech-c-pcode:' => 'tech.address.pcode', + 'tech-c-city:' => 'tech.address.city', + 'tech-c-ccode:' => 'tech.address.country', + 'tech-c-phone:' => 'tech.phone', + 'tech-c-email:' => 'tech.email', + 'bill-c-firstname:' => 'billing.name.first', + 'bill-c-lastname:' => 'billing.name.last', + 'bill-c-organization:' => 'billing.organization', + 'bill-c-street1:' => 'billing.address.street.', + 'bill-c-street2:' => 'billing.address.street.', + 'bill-c-pcode:' => 'billing.address.pcode', + 'bill-c-city:' => 'billing.address.city', + 'bill-c-ccode:' => 'billing.address.country', + 'bill-c-phone:' => 'billing.phone', + 'bill-c-email:' => 'billing.email' + ); + + return generic_parser_b($data_str, $items); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.srsplus.php b/classes/whois.gtld.srsplus.php similarity index 96% rename from whois.gtld.srsplus.php rename to classes/whois.gtld.srsplus.php index 1ab2c4e..3cd8c01 100644 --- a/whois.gtld.srsplus.php +++ b/classes/whois.gtld.srsplus.php @@ -1,51 +1,51 @@ - 'Registrant:', - 'admin' => 'Administrative', - 'tech' => 'Technical', - 'billing' => 'Billing', - 'domain.name' => 'Domain Name:', - 'domain.nserver' => 'Domain servers:', - 'domain.created' => 'Record created on', - 'domain.expires' => 'Record expires on' - ); - - return easy_parser($data_str, $items, 'ymd',false,true,true); - } - } + 'Registrant:', + 'admin' => 'Administrative', + 'tech' => 'Technical', + 'billing' => 'Billing', + 'domain.name' => 'Domain Name:', + 'domain.nserver' => 'Domain servers:', + 'domain.created' => 'Record created on', + 'domain.expires' => 'Record expires on' + ); + + return easy_parser($data_str, $items, 'ymd',false,true,true); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.tmagnic.php b/classes/whois.gtld.tmagnic.php similarity index 96% rename from whois.gtld.tmagnic.php rename to classes/whois.gtld.tmagnic.php index 0df7bed..08ea9dc 100644 --- a/whois.gtld.tmagnic.php +++ b/classes/whois.gtld.tmagnic.php @@ -1,52 +1,52 @@ - 'Owner Contact:', - 'admin' => 'Admin Contact', - 'tech' => 'Technical Contact', - 'domain.name' => 'Domain Name:', - 'domain.nserver.' => 'Domain servers in listed order:', - 'domain.expires' => 'Record expires on: ', - 'domain.changed' => 'Record last updated on: ', - '' => 'Zone Contact', - '#' => 'Punycode Name:' - ); - - return easy_parser($data_str, $items, 'ymd',false,false,true); - } - } + 'Owner Contact:', + 'admin' => 'Admin Contact', + 'tech' => 'Technical Contact', + 'domain.name' => 'Domain Name:', + 'domain.nserver.' => 'Domain servers in listed order:', + 'domain.expires' => 'Record expires on: ', + 'domain.changed' => 'Record last updated on: ', + '' => 'Zone Contact', + '#' => 'Punycode Name:' + ); + + return easy_parser($data_str, $items, 'ymd',false,false,true); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.tvcorp.php b/classes/whois.gtld.tvcorp.php similarity index 96% rename from whois.gtld.tvcorp.php rename to classes/whois.gtld.tvcorp.php index ee842e0..23bd863 100644 --- a/whois.gtld.tvcorp.php +++ b/classes/whois.gtld.tvcorp.php @@ -1,50 +1,50 @@ - 'Registrant', - 'admin' => 'Admin', - 'tech' => 'Technical', - 'billing' => 'Billing', - 'domain.nserver.' => 'Domain servers:', - 'domain.created' => 'Record created on', - 'domain.expires' => 'Record expires on' - ); - - return easy_parser($data_str, $items, 'mdy'); - } - } + 'Registrant', + 'admin' => 'Admin', + 'tech' => 'Technical', + 'billing' => 'Billing', + 'domain.nserver.' => 'Domain servers:', + 'domain.created' => 'Record created on', + 'domain.expires' => 'Record expires on' + ); + + return easy_parser($data_str, $items, 'mdy'); + } + } ?> \ No newline at end of file diff --git a/whois.gtld.wildwestdomains.php b/classes/whois.gtld.wildwestdomains.php similarity index 97% rename from whois.gtld.wildwestdomains.php rename to classes/whois.gtld.wildwestdomains.php index 22e692d..588acdf 100644 --- a/whois.gtld.wildwestdomains.php +++ b/classes/whois.gtld.wildwestdomains.php @@ -1,52 +1,52 @@ - 'Registrant:', - 'admin' => 'Administrative Contact:', - 'tech' => 'Technical Contact:', - 'domain.name' => 'Domain name:', - 'domain.sponsor'=> 'Registered through:', - 'domain.nserver' => 'Domain servers in listed order:', - 'domain.created' => 'Created on:', - 'domain.expires' => 'Expires on:', - 'domain.changed' => 'Last Updated on:' - ); - - return easy_parser($data_str, $items, 'mdy'); - } - } + 'Registrant:', + 'admin' => 'Administrative Contact:', + 'tech' => 'Technical Contact:', + 'domain.name' => 'Domain name:', + 'domain.sponsor'=> 'Registered through:', + 'domain.nserver' => 'Domain servers in listed order:', + 'domain.created' => 'Created on:', + 'domain.expires' => 'Expires on:', + 'domain.changed' => 'Last Updated on:' + ); + + return easy_parser($data_str, $items, 'mdy'); + } + } ?> \ No newline at end of file diff --git a/whois.hu.php b/classes/whois.hu.php similarity index 96% rename from whois.hu.php rename to classes/whois.hu.php index 3ae2fb6..ea528e3 100644 --- a/whois.hu.php +++ b/classes/whois.hu.php @@ -1,53 +1,53 @@ - 'domain.name', - 'record created:' => 'domain.created' - ); - - $r['regrinfo'] = generic_parser_b($data_str['rawdata'],$items,'ymd'); - - if (isset($r['regrinfo']['domain'])) - $r['regrinfo']['registered'] = 'yes'; - else - $r['regrinfo']['registered'] = 'no'; - - $r['regyinfo'] = array('referrer'=>'http://www.nic.hu','registrar'=>'HUNIC'); - return $r; - } - } + 'domain.name', + 'record created:' => 'domain.created' + ); + + $r['regrinfo'] = generic_parser_b($data_str['rawdata'],$items,'ymd'); + + if (isset($r['regrinfo']['domain'])) + $r['regrinfo']['registered'] = 'yes'; + else + $r['regrinfo']['registered'] = 'no'; + + $r['regyinfo'] = array('referrer'=>'http://www.nic.hu','registrar'=>'HUNIC'); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.idna.php b/classes/whois.idna.php similarity index 97% rename from whois.idna.php rename to classes/whois.idna.php index ed2bae2..c3e806c 100644 --- a/whois.idna.php +++ b/classes/whois.idna.php @@ -1,969 +1,969 @@ - - * @copyright 2004-2007 phlyLabs Berlin, http://phlylabs.de - * @version 0.5.1 - * - */ -class idna_convert -{ - /** - * Holds all relevant mapping tables, loaded from a seperate file on construct - * See RFC3454 for details - * - * @var array - * @access private - */ - var $NP = array(); - - // Internal settings, do not mess with them - var $_punycode_prefix = 'xn--'; - var $_invalid_ucs = 0x80000000; - var $_max_ucs = 0x10FFFF; - var $_base = 36; - var $_tmin = 1; - var $_tmax = 26; - var $_skew = 38; - var $_damp = 700; - var $_initial_bias = 72; - var $_initial_n = 0x80; - var $_sbase = 0xAC00; - var $_lbase = 0x1100; - var $_vbase = 0x1161; - var $_tbase = 0x11A7; - var $_lcount = 19; - var $_vcount = 21; - var $_tcount = 28; - var $_ncount = 588; // _vcount * _tcount - var $_scount = 11172; // _lcount * _tcount * _vcount - var $_error = false; - - // See {@link set_paramter()} for details of how to change the following - // settings from within your script / application - var $_api_encoding = 'utf8'; // Default input charset is UTF-8 - var $_allow_overlong = false; // Overlong UTF-8 encodings are forbidden - var $_strict_mode = false; // Behave strict or not - - // The constructor - function idna_convert($options = false) - { - $this->slast = $this->_sbase + $this->_lcount * $this->_vcount * $this->_tcount; - if (function_exists('file_get_contents')) { - $this->NP = unserialize(file_get_contents(dirname(__FILE__).'/npdata.ser')); - } else { - $this->NP = unserialize(join('', file(dirname(__FILE__).'/npdata.ser'))); - } - // If parameters are given, pass these to the respective method - if (is_array($options)) { - return $this->set_parameter($options); - } - return true; - } - - /** - * Sets a new option value. Available options and values: - * [encoding - Use either UTF-8, UCS4 as array or UCS4 as string as input ('utf8' for UTF-8, - * 'ucs4_string' and 'ucs4_array' respectively for UCS4); The output is always UTF-8] - * [overlong - Unicode does not allow unnecessarily long encodings of chars, - * to allow this, set this parameter to true, else to false; - * default is false.] - * [strict - true: strict mode, good for registration purposes - Causes errors - * on failures; false: loose mode, ideal for "wildlife" applications - * by silently ignoring errors and returning the original input instead - * - * @param mixed Parameter to set (string: single parameter; array of Parameter => Value pairs) - * @param string Value to use (if parameter 1 is a string) - * @return boolean true on success, false otherwise - * @access public - */ - function set_parameter($option, $value = false) - { - if (!is_array($option)) { - $option = array($option => $value); - } - foreach ($option as $k => $v) { - switch ($k) { - case 'encoding': - switch ($v) { - case 'utf8': - case 'ucs4_string': - case 'ucs4_array': - $this->_api_encoding = $v; - break; - default: - $this->_error('Set Parameter: Unknown parameter '.$v.' for option '.$k); - return false; - } - break; - case 'overlong': - $this->_allow_overlong = ($v) ? true : false; - break; - case 'strict': - $this->_strict_mode = ($v) ? true : false; - break; - default: - $this->_error('Set Parameter: Unknown option '.$k); - return false; - } - } - return true; - } - - /** - * Decode a given ACE domain name - * @param string Domain name (ACE string) - * [@param string Desired output encoding, see {@link set_parameter}] - * @return string Decoded Domain name (UTF-8 or UCS-4) - * @access public - */ - function decode($input, $one_time_encoding = false) - { - // Optionally set - if ($one_time_encoding) { - switch ($one_time_encoding) { - case 'utf8': - case 'ucs4_string': - case 'ucs4_array': - break; - default: - $this->_error('Unknown encoding '.$one_time_encoding); - return false; - } - } - // Make sure to drop any newline characters around - $input = trim($input); - - // Negotiate input and try to determine, whether it is a plain string, - // an email address or something like a complete URL - if (strpos($input, '@')) { // Maybe it is an email address - // No no in strict mode - if ($this->_strict_mode) { - $this->_error('Only simple domain name parts can be handled in strict mode'); - return false; - } - list ($email_pref, $input) = explode('@', $input, 2); - $arr = explode('.', $input); - foreach ($arr as $k => $v) { - if (preg_match('!^'.preg_quote($this->_punycode_prefix, '!').'!', $v)) { - $conv = $this->_decode($v); - if ($conv) $arr[$k] = $conv; - } - } - $input = join('.', $arr); - $arr = explode('.', $email_pref); - foreach ($arr as $k => $v) { - if (preg_match('!^'.preg_quote($this->_punycode_prefix, '!').'!', $v)) { - $conv = $this->_decode($v); - if ($conv) $arr[$k] = $conv; - } - } - $email_pref = join('.', $arr); - $return = $email_pref . '@' . $input; - } elseif (preg_match('![:\./]!', $input)) { // Or a complete domain name (with or without paths / parameters) - // No no in strict mode - if ($this->_strict_mode) { - $this->_error('Only simple domain name parts can be handled in strict mode'); - return false; - } - $parsed = parse_url($input); - if (isset($parsed['host'])) { - $arr = explode('.', $parsed['host']); - foreach ($arr as $k => $v) { - $conv = $this->_decode($v); - if ($conv) $arr[$k] = $conv; - } - $parsed['host'] = join('.', $arr); - $return = - (empty($parsed['scheme']) ? '' : $parsed['scheme'].(strtolower($parsed['scheme']) == 'mailto' ? ':' : '://')) - .(empty($parsed['user']) ? '' : $parsed['user'].(empty($parsed['pass']) ? '' : ':'.$parsed['pass']).'@') - .$parsed['host'] - .(empty($parsed['port']) ? '' : ':'.$parsed['port']) - .(empty($parsed['path']) ? '' : $parsed['path']) - .(empty($parsed['query']) ? '' : '?'.$parsed['query']) - .(empty($parsed['fragment']) ? '' : '#'.$parsed['fragment']); - } else { // parse_url seems to have failed, try without it - $arr = explode('.', $input); - foreach ($arr as $k => $v) { - $conv = $this->_decode($v); - $arr[$k] = ($conv) ? $conv : $v; - } - $return = join('.', $arr); - } - } else { // Otherwise we consider it being a pure domain name string - $return = $this->_decode($input); - if (!$return) $return = $input; - } - // The output is UTF-8 by default, other output formats need conversion here - // If one time encoding is given, use this, else the objects property - switch (($one_time_encoding) ? $one_time_encoding : $this->_api_encoding) { - case 'utf8': - return $return; - break; - case 'ucs4_string': - return $this->_ucs4_to_ucs4_string($this->_utf8_to_ucs4($return)); - break; - case 'ucs4_array': - return $this->_utf8_to_ucs4($return); - break; - default: - $this->_error('Unsupported output format'); - return false; - } - } - - /** - * Encode a given UTF-8 domain name - * @param string Domain name (UTF-8 or UCS-4) - * [@param string Desired input encoding, see {@link set_parameter}] - * @return string Encoded Domain name (ACE string) - * @access public - */ - function encode($decoded, $one_time_encoding = false) - { - // Forcing conversion of input to UCS4 array - // If one time encoding is given, use this, else the objects property - switch ($one_time_encoding ? $one_time_encoding : $this->_api_encoding) { - case 'utf8': - $decoded = $this->_utf8_to_ucs4($decoded); - break; - case 'ucs4_string': - $decoded = $this->_ucs4_string_to_ucs4($decoded); - case 'ucs4_array': - break; - default: - $this->_error('Unsupported input format: '.($one_time_encoding ? $one_time_encoding : $this->_api_encoding)); - return false; - } - - // No input, no output, what else did you expect? - if (empty($decoded)) return ''; - - // Anchors for iteration - $last_begin = 0; - // Output string - $output = ''; - foreach ($decoded as $k => $v) { - // Make sure to use just the plain dot - switch($v) { - case 0x3002: - case 0xFF0E: - case 0xFF61: - $decoded[$k] = 0x2E; - // Right, no break here, the above are converted to dots anyway - // Stumbling across an anchoring character - case 0x2E: - case 0x2F: - case 0x3A: - case 0x3F: - case 0x40: - // Neither email addresses nor URLs allowed in strict mode - if ($this->_strict_mode) { - $this->_error('Neither email addresses nor URLs are allowed in strict mode.'); - return false; - } else { - // Skip first char - if ($k) { - $encoded = ''; - $encoded = $this->_encode(array_slice($decoded, $last_begin, (($k)-$last_begin))); - if ($encoded) { - $output .= $encoded; - } else { - $output .= $this->_ucs4_to_utf8(array_slice($decoded, $last_begin, (($k)-$last_begin))); - } - $output .= chr($decoded[$k]); - } - $last_begin = $k + 1; - } - } - } - // Catch the rest of the string - if ($last_begin) { - $inp_len = sizeof($decoded); - $encoded = ''; - $encoded = $this->_encode(array_slice($decoded, $last_begin, (($inp_len)-$last_begin))); - if ($encoded) { - $output .= $encoded; - } else { - $output .= $this->_ucs4_to_utf8(array_slice($decoded, $last_begin, (($inp_len)-$last_begin))); - } - return $output; - } else { - if ($output = $this->_encode($decoded)) { - return $output; - } else { - return $this->_ucs4_to_utf8($decoded); - } - } - } - - /** - * Use this method to get the last error ocurred - * @param void - * @return string The last error, that occured - * @access public - */ - function get_last_error() - { - return $this->_error; - } - - /** - * The actual decoding algorithm - * @access private - */ - function _decode($encoded) - { - // We do need to find the Punycode prefix - if (!preg_match('!^'.preg_quote($this->_punycode_prefix, '!').'!', $encoded)) { - $this->_error('This is not a punycode string'); - return false; - } - $encode_test = preg_replace('!^'.preg_quote($this->_punycode_prefix, '!').'!', '', $encoded); - // If nothing left after removing the prefix, it is hopeless - if (!$encode_test) { - $this->_error('The given encoded string was empty'); - return false; - } - // Find last occurence of the delimiter - $delim_pos = strrpos($encoded, '-'); - if ($delim_pos > strlen($this->_punycode_prefix)) { - for ($k = strlen($this->_punycode_prefix); $k < $delim_pos; ++$k) { - $decoded[] = ord($encoded{$k}); - } - } else { - $decoded = array(); - } - $deco_len = count($decoded); - $enco_len = strlen($encoded); - - // Wandering through the strings; init - $is_first = true; - $bias = $this->_initial_bias; - $idx = 0; - $char = $this->_initial_n; - - for ($enco_idx = ($delim_pos) ? ($delim_pos + 1) : 0; $enco_idx < $enco_len; ++$deco_len) { - for ($old_idx = $idx, $w = 1, $k = $this->_base; 1 ; $k += $this->_base) { - $digit = $this->_decode_digit($encoded{$enco_idx++}); - $idx += $digit * $w; - $t = ($k <= $bias) ? $this->_tmin : - (($k >= $bias + $this->_tmax) ? $this->_tmax : ($k - $bias)); - if ($digit < $t) break; - $w = (int) ($w * ($this->_base - $t)); - } - $bias = $this->_adapt($idx - $old_idx, $deco_len + 1, $is_first); - $is_first = false; - $char += (int) ($idx / ($deco_len + 1)); - $idx %= ($deco_len + 1); - if ($deco_len > 0) { - // Make room for the decoded char - for ($i = $deco_len; $i > $idx; $i--) { - $decoded[$i] = $decoded[($i - 1)]; - } - } - $decoded[$idx++] = $char; - } - return $this->_ucs4_to_utf8($decoded); - } - - /** - * The actual encoding algorithm - * @access private - */ - function _encode($decoded) - { - // We cannot encode a domain name containing the Punycode prefix - $extract = strlen($this->_punycode_prefix); - $check_pref = $this->_utf8_to_ucs4($this->_punycode_prefix); - $check_deco = array_slice($decoded, 0, $extract); - - if ($check_pref == $check_deco) { - $this->_error('This is already a punycode string'); - return false; - } - // We will not try to encode strings consisting of basic code points only - $encodable = false; - foreach ($decoded as $k => $v) { - if ($v > 0x7a) { - $encodable = true; - break; - } - } - if (!$encodable) { - $this->_error('The given string does not contain encodable chars'); - return false; - } - - // Do NAMEPREP - $decoded = $this->_nameprep($decoded); - if (!$decoded || !is_array($decoded)) return false; // NAMEPREP failed - - $deco_len = count($decoded); - if (!$deco_len) return false; // Empty array - - $codecount = 0; // How many chars have been consumed - - $encoded = ''; - // Copy all basic code points to output - for ($i = 0; $i < $deco_len; ++$i) { - $test = $decoded[$i]; - // Will match [-0-9a-zA-Z] - if ((0x2F < $test && $test < 0x40) || (0x40 < $test && $test < 0x5B) - || (0x60 < $test && $test <= 0x7B) || (0x2D == $test)) { - $encoded .= chr($decoded[$i]); - $codecount++; - } - } - if ($codecount == $deco_len) return $encoded; // All codepoints were basic ones - - // Start with the prefix; copy it to output - $encoded = $this->_punycode_prefix.$encoded; - - // If we have basic code points in output, add an hyphen to the end - if ($codecount) $encoded .= '-'; - - // Now find and encode all non-basic code points - $is_first = true; - $cur_code = $this->_initial_n; - $bias = $this->_initial_bias; - $delta = 0; - while ($codecount < $deco_len) { - // Find the smallest code point >= the current code point and - // remember the last ouccrence of it in the input - for ($i = 0, $next_code = $this->_max_ucs; $i < $deco_len; $i++) { - if ($decoded[$i] >= $cur_code && $decoded[$i] <= $next_code) { - $next_code = $decoded[$i]; - } - } - - $delta += ($next_code - $cur_code) * ($codecount + 1); - $cur_code = $next_code; - - // Scan input again and encode all characters whose code point is $cur_code - for ($i = 0; $i < $deco_len; $i++) { - if ($decoded[$i] < $cur_code) { - $delta++; - } elseif ($decoded[$i] == $cur_code) { - for ($q = $delta, $k = $this->_base; 1; $k += $this->_base) { - $t = ($k <= $bias) ? $this->_tmin : - (($k >= $bias + $this->_tmax) ? $this->_tmax : $k - $bias); - if ($q < $t) break; - $encoded .= $this->_encode_digit(intval($t + (($q - $t) % ($this->_base - $t)))); //v0.4.5 Changed from ceil() to intval() - $q = (int) (($q - $t) / ($this->_base - $t)); - } - $encoded .= $this->_encode_digit($q); - $bias = $this->_adapt($delta, $codecount+1, $is_first); - $codecount++; - $delta = 0; - $is_first = false; - } - } - $delta++; - $cur_code++; - } - return $encoded; - } - - /** - * Adapt the bias according to the current code point and position - * @access private - */ - function _adapt($delta, $npoints, $is_first) - { - $delta = intval($is_first ? ($delta / $this->_damp) : ($delta / 2)); - $delta += intval($delta / $npoints); - for ($k = 0; $delta > (($this->_base - $this->_tmin) * $this->_tmax) / 2; $k += $this->_base) { - $delta = intval($delta / ($this->_base - $this->_tmin)); - } - return intval($k + ($this->_base - $this->_tmin + 1) * $delta / ($delta + $this->_skew)); - } - - /** - * Encoding a certain digit - * @access private - */ - function _encode_digit($d) - { - return chr($d + 22 + 75 * ($d < 26)); - } - - /** - * Decode a certain digit - * @access private - */ - function _decode_digit($cp) - { - $cp = ord($cp); - return ($cp - 48 < 10) ? $cp - 22 : (($cp - 65 < 26) ? $cp - 65 : (($cp - 97 < 26) ? $cp - 97 : $this->_base)); - } - - /** - * Internal error handling method - * @access private - */ - function _error($error = '') - { - $this->_error = $error; - } - - /** - * Do Nameprep according to RFC3491 and RFC3454 - * @param array Unicode Characters - * @return string Unicode Characters, Nameprep'd - * @access private - */ - function _nameprep($input) - { - $output = array(); - $error = false; - // - // Mapping - // Walking through the input array, performing the required steps on each of - // the input chars and putting the result into the output array - // While mapping required chars we apply the cannonical ordering - foreach ($input as $v) { - // Map to nothing == skip that code point - if (in_array($v, $this->NP['map_nothing'])) continue; - - // Try to find prohibited input - if (in_array($v, $this->NP['prohibit']) || in_array($v, $this->NP['general_prohibited'])) { - $this->_error('NAMEPREP: Prohibited input U+'.sprintf('%08X', $v)); - return false; - } - foreach ($this->NP['prohibit_ranges'] as $range) { - if ($range[0] <= $v && $v <= $range[1]) { - $this->_error('NAMEPREP: Prohibited input U+'.sprintf('%08X', $v)); - return false; - } - } - // - // Hangul syllable decomposition - if (0xAC00 <= $v && $v <= 0xD7AF) { - foreach ($this->_hangul_decompose($v) as $out) { - $output[] = (int) $out; - } - // There's a decomposition mapping for that code point - } elseif (isset($this->NP['replacemaps'][$v])) { - foreach ($this->_apply_cannonical_ordering($this->NP['replacemaps'][$v]) as $out) { - $output[] = (int) $out; - } - } else { - $output[] = (int) $v; - } - } - // Before applying any Combining, try to rearrange any Hangul syllables - $output = $this->_hangul_compose($output); - // - // Combine code points - // - $last_class = 0; - $last_starter = 0; - $out_len = count($output); - for ($i = 0; $i < $out_len; ++$i) { - $class = $this->_get_combining_class($output[$i]); - if ((!$last_class || $last_class > $class) && $class) { - // Try to match - $seq_len = $i - $last_starter; - $out = $this->_combine(array_slice($output, $last_starter, $seq_len)); - // On match: Replace the last starter with the composed character and remove - // the now redundant non-starter(s) - if ($out) { - $output[$last_starter] = $out; - if (count($out) != $seq_len) { - for ($j = $i+1; $j < $out_len; ++$j) { - $output[$j-1] = $output[$j]; - } - unset($output[$out_len]); - } - // Rewind the for loop by one, since there can be more possible compositions - $i--; - $out_len--; - $last_class = ($i == $last_starter) ? 0 : $this->_get_combining_class($output[$i-1]); - continue; - } - } - // The current class is 0 - if (!$class) $last_starter = $i; - $last_class = $class; - } - return $output; - } - - /** - * Decomposes a Hangul syllable - * (see http://www.unicode.org/unicode/reports/tr15/#Hangul - * @param integer 32bit UCS4 code point - * @return array Either Hangul Syllable decomposed or original 32bit value as one value array - * @access private - */ - function _hangul_decompose($char) - { - $sindex = (int) $char - $this->_sbase; - if ($sindex < 0 || $sindex >= $this->_scount) { - return array($char); - } - $result = array(); - $result[] = (int) $this->_lbase + $sindex / $this->_ncount; - $result[] = (int) $this->_vbase + ($sindex % $this->_ncount) / $this->_tcount; - $T = intval($this->_tbase + $sindex % $this->_tcount); - if ($T != $this->_tbase) $result[] = $T; - return $result; - } - /** - * Ccomposes a Hangul syllable - * (see http://www.unicode.org/unicode/reports/tr15/#Hangul - * @param array Decomposed UCS4 sequence - * @return array UCS4 sequence with syllables composed - * @access private - */ - function _hangul_compose($input) - { - $inp_len = count($input); - if (!$inp_len) return array(); - $result = array(); - $last = (int) $input[0]; - $result[] = $last; // copy first char from input to output - - for ($i = 1; $i < $inp_len; ++$i) { - $char = (int) $input[$i]; - $sindex = $last - $this->_sbase; - $lindex = $last - $this->_lbase; - $vindex = $char - $this->_vbase; - $tindex = $char - $this->_tbase; - // Find out, whether two current characters are LV and T - if (0 <= $sindex && $sindex < $this->_scount && ($sindex % $this->_tcount == 0) - && 0 <= $tindex && $tindex <= $this->_tcount) { - // create syllable of form LVT - $last += $tindex; - $result[(count($result) - 1)] = $last; // reset last - continue; // discard char - } - // Find out, whether two current characters form L and V - if (0 <= $lindex && $lindex < $this->_lcount && 0 <= $vindex && $vindex < $this->_vcount) { - // create syllable of form LV - $last = (int) $this->_sbase + ($lindex * $this->_vcount + $vindex) * $this->_tcount; - $result[(count($result) - 1)] = $last; // reset last - continue; // discard char - } - // if neither case was true, just add the character - $last = $char; - $result[] = $char; - } - return $result; - } - - /** - * Returns the combining class of a certain wide char - * @param integer Wide char to check (32bit integer) - * @return integer Combining class if found, else 0 - * @access private - */ - function _get_combining_class($char) - { - return isset($this->NP['norm_combcls'][$char]) ? $this->NP['norm_combcls'][$char] : 0; - } - - /** - * Apllies the cannonical ordering of a decomposed UCS4 sequence - * @param array Decomposed UCS4 sequence - * @return array Ordered USC4 sequence - * @access private - */ - function _apply_cannonical_ordering($input) - { - $swap = true; - $size = count($input); - while ($swap) { - $swap = false; - $last = $this->_get_combining_class(intval($input[0])); - for ($i = 0; $i < $size-1; ++$i) { - $next = $this->_get_combining_class(intval($input[$i+1])); - if ($next != 0 && $last > $next) { - // Move item leftward until it fits - for ($j = $i + 1; $j > 0; --$j) { - if ($this->_get_combining_class(intval($input[$j-1])) <= $next) break; - $t = intval($input[$j]); - $input[$j] = intval($input[$j-1]); - $input[$j-1] = $t; - $swap = true; - } - // Reentering the loop looking at the old character again - $next = $last; - } - $last = $next; - } - } - return $input; - } - - /** - * Do composition of a sequence of starter and non-starter - * @param array UCS4 Decomposed sequence - * @return array Ordered USC4 sequence - * @access private - */ - function _combine($input) - { - $inp_len = count($input); - foreach ($this->NP['replacemaps'] as $np_src => $np_target) { - if ($np_target[0] != $input[0]) continue; - if (count($np_target) != $inp_len) continue; - $hit = false; - foreach ($input as $k2 => $v2) { - if ($v2 == $np_target[$k2]) { - $hit = true; - } else { - $hit = false; - break; - } - } - if ($hit) return $np_src; - } - return false; - } - - /** - * This converts an UTF-8 encoded string to its UCS-4 representation - * By talking about UCS-4 "strings" we mean arrays of 32bit integers representing - * each of the "chars". This is due to PHP not being able to handle strings with - * bit depth different from 8. This apllies to the reverse method _ucs4_to_utf8(), too. - * The following UTF-8 encodings are supported: - * bytes bits representation - * 1 7 0xxxxxxx - * 2 11 110xxxxx 10xxxxxx - * 3 16 1110xxxx 10xxxxxx 10xxxxxx - * 4 21 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - * 5 26 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - * 6 31 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - * Each x represents a bit that can be used to store character data. - * The five and six byte sequences are part of Annex D of ISO/IEC 10646-1:2000 - * @access private - */ - function _utf8_to_ucs4($input) - { - $output = array(); - $out_len = 0; - $inp_len = strlen($input); - $mode = 'next'; - $test = 'none'; - for ($k = 0; $k < $inp_len; ++$k) { - $v = ord($input{$k}); // Extract byte from input string - - if ($v < 128) { // We found an ASCII char - put into stirng as is - $output[$out_len] = $v; - ++$out_len; - if ('add' == $mode) { - $this->_error('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k); - return false; - } - continue; - } - if ('next' == $mode) { // Try to find the next start byte; determine the width of the Unicode char - $start_byte = $v; - $mode = 'add'; - $test = 'range'; - if ($v >> 5 == 6) { // &110xxxxx 10xxxxx - $next_byte = 0; // Tells, how many times subsequent bitmasks must rotate 6bits to the left - $v = ($v - 192) << 6; - } elseif ($v >> 4 == 14) { // &1110xxxx 10xxxxxx 10xxxxxx - $next_byte = 1; - $v = ($v - 224) << 12; - } elseif ($v >> 3 == 30) { // &11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - $next_byte = 2; - $v = ($v - 240) << 18; - } elseif ($v >> 2 == 62) { // &111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - $next_byte = 3; - $v = ($v - 248) << 24; - } elseif ($v >> 1 == 126) { // &1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - $next_byte = 4; - $v = ($v - 252) << 30; - } else { - $this->_error('This might be UTF-8, but I don\'t understand it at byte '.$k); - return false; - } - if ('add' == $mode) { - $output[$out_len] = (int) $v; - ++$out_len; - continue; - } - } - if ('add' == $mode) { - if (!$this->_allow_overlong && $test == 'range') { - $test = 'none'; - if (($v < 0xA0 && $start_byte == 0xE0) || ($v < 0x90 && $start_byte == 0xF0) || ($v > 0x8F && $start_byte == 0xF4)) { - $this->_error('Bogus UTF-8 character detected (out of legal range) at byte '.$k); - return false; - } - } - if ($v >> 6 == 2) { // Bit mask must be 10xxxxxx - $v = ($v - 128) << ($next_byte * 6); - $output[($out_len - 1)] += $v; - --$next_byte; - } else { - $this->_error('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k); - return false; - } - if ($next_byte < 0) { - $mode = 'next'; - } - } - } // for - return $output; - } - - /** - * Convert UCS-4 string into UTF-8 string - * See _utf8_to_ucs4() for details - * @access private - */ - function _ucs4_to_utf8($input) - { - $output = ''; - $k = 0; - foreach ($input as $v) { - ++$k; - // $v = ord($v); - if ($v < 128) { // 7bit are transferred literally - $output .= chr($v); - } elseif ($v < (1 << 11)) { // 2 bytes - $output .= chr(192 + ($v >> 6)) . chr(128 + ($v & 63)); - } elseif ($v < (1 << 16)) { // 3 bytes - $output .= chr(224 + ($v >> 12)) . chr(128 + (($v >> 6) & 63)) . chr(128 + ($v & 63)); - } elseif ($v < (1 << 21)) { // 4 bytes - $output .= chr(240 + ($v >> 18)) . chr(128 + (($v >> 12) & 63)) - . chr(128 + (($v >> 6) & 63)) . chr(128 + ($v & 63)); - } elseif ($v < (1 << 26)) { // 5 bytes - $output .= chr(248 + ($v >> 24)) . chr(128 + (($v >> 18) & 63)) - . chr(128 + (($v >> 12) & 63)) . chr(128 + (($v >> 6) & 63)) - . chr(128 + ($v & 63)); - } elseif ($v < (1 << 31)) { // 6 bytes - $output .= chr(252 + ($v >> 30)) . chr(128 + (($v >> 24) & 63)) - . chr(128 + (($v >> 18) & 63)) . chr(128 + (($v >> 12) & 63)) - . chr(128 + (($v >> 6) & 63)) . chr(128 + ($v & 63)); - } else { - $this->_error('Conversion from UCS-4 to UTF-8 failed: malformed input at byte '.$k); - return false; - } - } - return $output; - } - - /** - * Convert UCS-4 array into UCS-4 string - * - * @access private - */ - function _ucs4_to_ucs4_string($input) - { - $output = ''; - // Take array values and split output to 4 bytes per value - // The bit mask is 255, which reads &11111111 - foreach ($input as $v) { - $output .= chr(($v >> 24) & 255).chr(($v >> 16) & 255).chr(($v >> 8) & 255).chr($v & 255); - } - return $output; - } - - /** - * Convert UCS-4 strin into UCS-4 garray - * - * @access private - */ - function _ucs4_string_to_ucs4($input) - { - $output = array(); - $inp_len = strlen($input); - // Input length must be dividable by 4 - if ($inp_len % 4) { - $this->_error('Input UCS4 string is broken'); - return false; - } - // Empty input - return empty output - if (!$inp_len) return $output; - for ($i = 0, $out_len = -1; $i < $inp_len; ++$i) { - // Increment output position every 4 input bytes - if (!($i % 4)) { - $out_len++; - $output[$out_len] = 0; - } - $output[$out_len] += ord($input{$i}) << (8 * (3 - ($i % 4) ) ); - } - return $output; - } -} - -/** -* Adapter class for aligning the API of idna_convert with that of Net_IDNA -* @author Matthias Sommerfeld -*/ -class Net_IDNA_php4 extends idna_convert -{ - /** - * Sets a new option value. Available options and values: - * [encoding - Use either UTF-8, UCS4 as array or UCS4 as string as input ('utf8' for UTF-8, - * 'ucs4_string' and 'ucs4_array' respectively for UCS4); The output is always UTF-8] - * [overlong - Unicode does not allow unnecessarily long encodings of chars, - * to allow this, set this parameter to true, else to false; - * default is false.] - * [strict - true: strict mode, good for registration purposes - Causes errors - * on failures; false: loose mode, ideal for "wildlife" applications - * by silently ignoring errors and returning the original input instead - * - * @param mixed Parameter to set (string: single parameter; array of Parameter => Value pairs) - * @param string Value to use (if parameter 1 is a string) - * @return boolean true on success, false otherwise - * @access public - */ - function setParams($option, $param = false) - { - return $this->IC->set_parameters($option, $param); - } -} - + + * @copyright 2004-2007 phlyLabs Berlin, http://phlylabs.de + * @version 0.5.1 + * + */ +class idna_convert +{ + /** + * Holds all relevant mapping tables, loaded from a seperate file on construct + * See RFC3454 for details + * + * @var array + * @access private + */ + var $NP = array(); + + // Internal settings, do not mess with them + var $_punycode_prefix = 'xn--'; + var $_invalid_ucs = 0x80000000; + var $_max_ucs = 0x10FFFF; + var $_base = 36; + var $_tmin = 1; + var $_tmax = 26; + var $_skew = 38; + var $_damp = 700; + var $_initial_bias = 72; + var $_initial_n = 0x80; + var $_sbase = 0xAC00; + var $_lbase = 0x1100; + var $_vbase = 0x1161; + var $_tbase = 0x11A7; + var $_lcount = 19; + var $_vcount = 21; + var $_tcount = 28; + var $_ncount = 588; // _vcount * _tcount + var $_scount = 11172; // _lcount * _tcount * _vcount + var $_error = false; + + // See {@link set_paramter()} for details of how to change the following + // settings from within your script / application + var $_api_encoding = 'utf8'; // Default input charset is UTF-8 + var $_allow_overlong = false; // Overlong UTF-8 encodings are forbidden + var $_strict_mode = false; // Behave strict or not + + // The constructor + function idna_convert($options = false) + { + $this->slast = $this->_sbase + $this->_lcount * $this->_vcount * $this->_tcount; + if (function_exists('file_get_contents')) { + $this->NP = unserialize(file_get_contents(dirname(__FILE__).'/npdata.ser')); + } else { + $this->NP = unserialize(join('', file(dirname(__FILE__).'/npdata.ser'))); + } + // If parameters are given, pass these to the respective method + if (is_array($options)) { + return $this->set_parameter($options); + } + return true; + } + + /** + * Sets a new option value. Available options and values: + * [encoding - Use either UTF-8, UCS4 as array or UCS4 as string as input ('utf8' for UTF-8, + * 'ucs4_string' and 'ucs4_array' respectively for UCS4); The output is always UTF-8] + * [overlong - Unicode does not allow unnecessarily long encodings of chars, + * to allow this, set this parameter to true, else to false; + * default is false.] + * [strict - true: strict mode, good for registration purposes - Causes errors + * on failures; false: loose mode, ideal for "wildlife" applications + * by silently ignoring errors and returning the original input instead + * + * @param mixed Parameter to set (string: single parameter; array of Parameter => Value pairs) + * @param string Value to use (if parameter 1 is a string) + * @return boolean true on success, false otherwise + * @access public + */ + function set_parameter($option, $value = false) + { + if (!is_array($option)) { + $option = array($option => $value); + } + foreach ($option as $k => $v) { + switch ($k) { + case 'encoding': + switch ($v) { + case 'utf8': + case 'ucs4_string': + case 'ucs4_array': + $this->_api_encoding = $v; + break; + default: + $this->_error('Set Parameter: Unknown parameter '.$v.' for option '.$k); + return false; + } + break; + case 'overlong': + $this->_allow_overlong = ($v) ? true : false; + break; + case 'strict': + $this->_strict_mode = ($v) ? true : false; + break; + default: + $this->_error('Set Parameter: Unknown option '.$k); + return false; + } + } + return true; + } + + /** + * Decode a given ACE domain name + * @param string Domain name (ACE string) + * [@param string Desired output encoding, see {@link set_parameter}] + * @return string Decoded Domain name (UTF-8 or UCS-4) + * @access public + */ + function decode($input, $one_time_encoding = false) + { + // Optionally set + if ($one_time_encoding) { + switch ($one_time_encoding) { + case 'utf8': + case 'ucs4_string': + case 'ucs4_array': + break; + default: + $this->_error('Unknown encoding '.$one_time_encoding); + return false; + } + } + // Make sure to drop any newline characters around + $input = trim($input); + + // Negotiate input and try to determine, whether it is a plain string, + // an email address or something like a complete URL + if (strpos($input, '@')) { // Maybe it is an email address + // No no in strict mode + if ($this->_strict_mode) { + $this->_error('Only simple domain name parts can be handled in strict mode'); + return false; + } + list ($email_pref, $input) = explode('@', $input, 2); + $arr = explode('.', $input); + foreach ($arr as $k => $v) { + if (preg_match('!^'.preg_quote($this->_punycode_prefix, '!').'!', $v)) { + $conv = $this->_decode($v); + if ($conv) $arr[$k] = $conv; + } + } + $input = join('.', $arr); + $arr = explode('.', $email_pref); + foreach ($arr as $k => $v) { + if (preg_match('!^'.preg_quote($this->_punycode_prefix, '!').'!', $v)) { + $conv = $this->_decode($v); + if ($conv) $arr[$k] = $conv; + } + } + $email_pref = join('.', $arr); + $return = $email_pref . '@' . $input; + } elseif (preg_match('![:\./]!', $input)) { // Or a complete domain name (with or without paths / parameters) + // No no in strict mode + if ($this->_strict_mode) { + $this->_error('Only simple domain name parts can be handled in strict mode'); + return false; + } + $parsed = parse_url($input); + if (isset($parsed['host'])) { + $arr = explode('.', $parsed['host']); + foreach ($arr as $k => $v) { + $conv = $this->_decode($v); + if ($conv) $arr[$k] = $conv; + } + $parsed['host'] = join('.', $arr); + $return = + (empty($parsed['scheme']) ? '' : $parsed['scheme'].(strtolower($parsed['scheme']) == 'mailto' ? ':' : '://')) + .(empty($parsed['user']) ? '' : $parsed['user'].(empty($parsed['pass']) ? '' : ':'.$parsed['pass']).'@') + .$parsed['host'] + .(empty($parsed['port']) ? '' : ':'.$parsed['port']) + .(empty($parsed['path']) ? '' : $parsed['path']) + .(empty($parsed['query']) ? '' : '?'.$parsed['query']) + .(empty($parsed['fragment']) ? '' : '#'.$parsed['fragment']); + } else { // parse_url seems to have failed, try without it + $arr = explode('.', $input); + foreach ($arr as $k => $v) { + $conv = $this->_decode($v); + $arr[$k] = ($conv) ? $conv : $v; + } + $return = join('.', $arr); + } + } else { // Otherwise we consider it being a pure domain name string + $return = $this->_decode($input); + if (!$return) $return = $input; + } + // The output is UTF-8 by default, other output formats need conversion here + // If one time encoding is given, use this, else the objects property + switch (($one_time_encoding) ? $one_time_encoding : $this->_api_encoding) { + case 'utf8': + return $return; + break; + case 'ucs4_string': + return $this->_ucs4_to_ucs4_string($this->_utf8_to_ucs4($return)); + break; + case 'ucs4_array': + return $this->_utf8_to_ucs4($return); + break; + default: + $this->_error('Unsupported output format'); + return false; + } + } + + /** + * Encode a given UTF-8 domain name + * @param string Domain name (UTF-8 or UCS-4) + * [@param string Desired input encoding, see {@link set_parameter}] + * @return string Encoded Domain name (ACE string) + * @access public + */ + function encode($decoded, $one_time_encoding = false) + { + // Forcing conversion of input to UCS4 array + // If one time encoding is given, use this, else the objects property + switch ($one_time_encoding ? $one_time_encoding : $this->_api_encoding) { + case 'utf8': + $decoded = $this->_utf8_to_ucs4($decoded); + break; + case 'ucs4_string': + $decoded = $this->_ucs4_string_to_ucs4($decoded); + case 'ucs4_array': + break; + default: + $this->_error('Unsupported input format: '.($one_time_encoding ? $one_time_encoding : $this->_api_encoding)); + return false; + } + + // No input, no output, what else did you expect? + if (empty($decoded)) return ''; + + // Anchors for iteration + $last_begin = 0; + // Output string + $output = ''; + foreach ($decoded as $k => $v) { + // Make sure to use just the plain dot + switch($v) { + case 0x3002: + case 0xFF0E: + case 0xFF61: + $decoded[$k] = 0x2E; + // Right, no break here, the above are converted to dots anyway + // Stumbling across an anchoring character + case 0x2E: + case 0x2F: + case 0x3A: + case 0x3F: + case 0x40: + // Neither email addresses nor URLs allowed in strict mode + if ($this->_strict_mode) { + $this->_error('Neither email addresses nor URLs are allowed in strict mode.'); + return false; + } else { + // Skip first char + if ($k) { + $encoded = ''; + $encoded = $this->_encode(array_slice($decoded, $last_begin, (($k)-$last_begin))); + if ($encoded) { + $output .= $encoded; + } else { + $output .= $this->_ucs4_to_utf8(array_slice($decoded, $last_begin, (($k)-$last_begin))); + } + $output .= chr($decoded[$k]); + } + $last_begin = $k + 1; + } + } + } + // Catch the rest of the string + if ($last_begin) { + $inp_len = sizeof($decoded); + $encoded = ''; + $encoded = $this->_encode(array_slice($decoded, $last_begin, (($inp_len)-$last_begin))); + if ($encoded) { + $output .= $encoded; + } else { + $output .= $this->_ucs4_to_utf8(array_slice($decoded, $last_begin, (($inp_len)-$last_begin))); + } + return $output; + } else { + if ($output = $this->_encode($decoded)) { + return $output; + } else { + return $this->_ucs4_to_utf8($decoded); + } + } + } + + /** + * Use this method to get the last error ocurred + * @param void + * @return string The last error, that occured + * @access public + */ + function get_last_error() + { + return $this->_error; + } + + /** + * The actual decoding algorithm + * @access private + */ + function _decode($encoded) + { + // We do need to find the Punycode prefix + if (!preg_match('!^'.preg_quote($this->_punycode_prefix, '!').'!', $encoded)) { + $this->_error('This is not a punycode string'); + return false; + } + $encode_test = preg_replace('!^'.preg_quote($this->_punycode_prefix, '!').'!', '', $encoded); + // If nothing left after removing the prefix, it is hopeless + if (!$encode_test) { + $this->_error('The given encoded string was empty'); + return false; + } + // Find last occurence of the delimiter + $delim_pos = strrpos($encoded, '-'); + if ($delim_pos > strlen($this->_punycode_prefix)) { + for ($k = strlen($this->_punycode_prefix); $k < $delim_pos; ++$k) { + $decoded[] = ord($encoded{$k}); + } + } else { + $decoded = array(); + } + $deco_len = count($decoded); + $enco_len = strlen($encoded); + + // Wandering through the strings; init + $is_first = true; + $bias = $this->_initial_bias; + $idx = 0; + $char = $this->_initial_n; + + for ($enco_idx = ($delim_pos) ? ($delim_pos + 1) : 0; $enco_idx < $enco_len; ++$deco_len) { + for ($old_idx = $idx, $w = 1, $k = $this->_base; 1 ; $k += $this->_base) { + $digit = $this->_decode_digit($encoded{$enco_idx++}); + $idx += $digit * $w; + $t = ($k <= $bias) ? $this->_tmin : + (($k >= $bias + $this->_tmax) ? $this->_tmax : ($k - $bias)); + if ($digit < $t) break; + $w = (int) ($w * ($this->_base - $t)); + } + $bias = $this->_adapt($idx - $old_idx, $deco_len + 1, $is_first); + $is_first = false; + $char += (int) ($idx / ($deco_len + 1)); + $idx %= ($deco_len + 1); + if ($deco_len > 0) { + // Make room for the decoded char + for ($i = $deco_len; $i > $idx; $i--) { + $decoded[$i] = $decoded[($i - 1)]; + } + } + $decoded[$idx++] = $char; + } + return $this->_ucs4_to_utf8($decoded); + } + + /** + * The actual encoding algorithm + * @access private + */ + function _encode($decoded) + { + // We cannot encode a domain name containing the Punycode prefix + $extract = strlen($this->_punycode_prefix); + $check_pref = $this->_utf8_to_ucs4($this->_punycode_prefix); + $check_deco = array_slice($decoded, 0, $extract); + + if ($check_pref == $check_deco) { + $this->_error('This is already a punycode string'); + return false; + } + // We will not try to encode strings consisting of basic code points only + $encodable = false; + foreach ($decoded as $k => $v) { + if ($v > 0x7a) { + $encodable = true; + break; + } + } + if (!$encodable) { + $this->_error('The given string does not contain encodable chars'); + return false; + } + + // Do NAMEPREP + $decoded = $this->_nameprep($decoded); + if (!$decoded || !is_array($decoded)) return false; // NAMEPREP failed + + $deco_len = count($decoded); + if (!$deco_len) return false; // Empty array + + $codecount = 0; // How many chars have been consumed + + $encoded = ''; + // Copy all basic code points to output + for ($i = 0; $i < $deco_len; ++$i) { + $test = $decoded[$i]; + // Will match [-0-9a-zA-Z] + if ((0x2F < $test && $test < 0x40) || (0x40 < $test && $test < 0x5B) + || (0x60 < $test && $test <= 0x7B) || (0x2D == $test)) { + $encoded .= chr($decoded[$i]); + $codecount++; + } + } + if ($codecount == $deco_len) return $encoded; // All codepoints were basic ones + + // Start with the prefix; copy it to output + $encoded = $this->_punycode_prefix.$encoded; + + // If we have basic code points in output, add an hyphen to the end + if ($codecount) $encoded .= '-'; + + // Now find and encode all non-basic code points + $is_first = true; + $cur_code = $this->_initial_n; + $bias = $this->_initial_bias; + $delta = 0; + while ($codecount < $deco_len) { + // Find the smallest code point >= the current code point and + // remember the last ouccrence of it in the input + for ($i = 0, $next_code = $this->_max_ucs; $i < $deco_len; $i++) { + if ($decoded[$i] >= $cur_code && $decoded[$i] <= $next_code) { + $next_code = $decoded[$i]; + } + } + + $delta += ($next_code - $cur_code) * ($codecount + 1); + $cur_code = $next_code; + + // Scan input again and encode all characters whose code point is $cur_code + for ($i = 0; $i < $deco_len; $i++) { + if ($decoded[$i] < $cur_code) { + $delta++; + } elseif ($decoded[$i] == $cur_code) { + for ($q = $delta, $k = $this->_base; 1; $k += $this->_base) { + $t = ($k <= $bias) ? $this->_tmin : + (($k >= $bias + $this->_tmax) ? $this->_tmax : $k - $bias); + if ($q < $t) break; + $encoded .= $this->_encode_digit(intval($t + (($q - $t) % ($this->_base - $t)))); //v0.4.5 Changed from ceil() to intval() + $q = (int) (($q - $t) / ($this->_base - $t)); + } + $encoded .= $this->_encode_digit($q); + $bias = $this->_adapt($delta, $codecount+1, $is_first); + $codecount++; + $delta = 0; + $is_first = false; + } + } + $delta++; + $cur_code++; + } + return $encoded; + } + + /** + * Adapt the bias according to the current code point and position + * @access private + */ + function _adapt($delta, $npoints, $is_first) + { + $delta = intval($is_first ? ($delta / $this->_damp) : ($delta / 2)); + $delta += intval($delta / $npoints); + for ($k = 0; $delta > (($this->_base - $this->_tmin) * $this->_tmax) / 2; $k += $this->_base) { + $delta = intval($delta / ($this->_base - $this->_tmin)); + } + return intval($k + ($this->_base - $this->_tmin + 1) * $delta / ($delta + $this->_skew)); + } + + /** + * Encoding a certain digit + * @access private + */ + function _encode_digit($d) + { + return chr($d + 22 + 75 * ($d < 26)); + } + + /** + * Decode a certain digit + * @access private + */ + function _decode_digit($cp) + { + $cp = ord($cp); + return ($cp - 48 < 10) ? $cp - 22 : (($cp - 65 < 26) ? $cp - 65 : (($cp - 97 < 26) ? $cp - 97 : $this->_base)); + } + + /** + * Internal error handling method + * @access private + */ + function _error($error = '') + { + $this->_error = $error; + } + + /** + * Do Nameprep according to RFC3491 and RFC3454 + * @param array Unicode Characters + * @return string Unicode Characters, Nameprep'd + * @access private + */ + function _nameprep($input) + { + $output = array(); + $error = false; + // + // Mapping + // Walking through the input array, performing the required steps on each of + // the input chars and putting the result into the output array + // While mapping required chars we apply the cannonical ordering + foreach ($input as $v) { + // Map to nothing == skip that code point + if (in_array($v, $this->NP['map_nothing'])) continue; + + // Try to find prohibited input + if (in_array($v, $this->NP['prohibit']) || in_array($v, $this->NP['general_prohibited'])) { + $this->_error('NAMEPREP: Prohibited input U+'.sprintf('%08X', $v)); + return false; + } + foreach ($this->NP['prohibit_ranges'] as $range) { + if ($range[0] <= $v && $v <= $range[1]) { + $this->_error('NAMEPREP: Prohibited input U+'.sprintf('%08X', $v)); + return false; + } + } + // + // Hangul syllable decomposition + if (0xAC00 <= $v && $v <= 0xD7AF) { + foreach ($this->_hangul_decompose($v) as $out) { + $output[] = (int) $out; + } + // There's a decomposition mapping for that code point + } elseif (isset($this->NP['replacemaps'][$v])) { + foreach ($this->_apply_cannonical_ordering($this->NP['replacemaps'][$v]) as $out) { + $output[] = (int) $out; + } + } else { + $output[] = (int) $v; + } + } + // Before applying any Combining, try to rearrange any Hangul syllables + $output = $this->_hangul_compose($output); + // + // Combine code points + // + $last_class = 0; + $last_starter = 0; + $out_len = count($output); + for ($i = 0; $i < $out_len; ++$i) { + $class = $this->_get_combining_class($output[$i]); + if ((!$last_class || $last_class > $class) && $class) { + // Try to match + $seq_len = $i - $last_starter; + $out = $this->_combine(array_slice($output, $last_starter, $seq_len)); + // On match: Replace the last starter with the composed character and remove + // the now redundant non-starter(s) + if ($out) { + $output[$last_starter] = $out; + if (count($out) != $seq_len) { + for ($j = $i+1; $j < $out_len; ++$j) { + $output[$j-1] = $output[$j]; + } + unset($output[$out_len]); + } + // Rewind the for loop by one, since there can be more possible compositions + $i--; + $out_len--; + $last_class = ($i == $last_starter) ? 0 : $this->_get_combining_class($output[$i-1]); + continue; + } + } + // The current class is 0 + if (!$class) $last_starter = $i; + $last_class = $class; + } + return $output; + } + + /** + * Decomposes a Hangul syllable + * (see http://www.unicode.org/unicode/reports/tr15/#Hangul + * @param integer 32bit UCS4 code point + * @return array Either Hangul Syllable decomposed or original 32bit value as one value array + * @access private + */ + function _hangul_decompose($char) + { + $sindex = (int) $char - $this->_sbase; + if ($sindex < 0 || $sindex >= $this->_scount) { + return array($char); + } + $result = array(); + $result[] = (int) $this->_lbase + $sindex / $this->_ncount; + $result[] = (int) $this->_vbase + ($sindex % $this->_ncount) / $this->_tcount; + $T = intval($this->_tbase + $sindex % $this->_tcount); + if ($T != $this->_tbase) $result[] = $T; + return $result; + } + /** + * Ccomposes a Hangul syllable + * (see http://www.unicode.org/unicode/reports/tr15/#Hangul + * @param array Decomposed UCS4 sequence + * @return array UCS4 sequence with syllables composed + * @access private + */ + function _hangul_compose($input) + { + $inp_len = count($input); + if (!$inp_len) return array(); + $result = array(); + $last = (int) $input[0]; + $result[] = $last; // copy first char from input to output + + for ($i = 1; $i < $inp_len; ++$i) { + $char = (int) $input[$i]; + $sindex = $last - $this->_sbase; + $lindex = $last - $this->_lbase; + $vindex = $char - $this->_vbase; + $tindex = $char - $this->_tbase; + // Find out, whether two current characters are LV and T + if (0 <= $sindex && $sindex < $this->_scount && ($sindex % $this->_tcount == 0) + && 0 <= $tindex && $tindex <= $this->_tcount) { + // create syllable of form LVT + $last += $tindex; + $result[(count($result) - 1)] = $last; // reset last + continue; // discard char + } + // Find out, whether two current characters form L and V + if (0 <= $lindex && $lindex < $this->_lcount && 0 <= $vindex && $vindex < $this->_vcount) { + // create syllable of form LV + $last = (int) $this->_sbase + ($lindex * $this->_vcount + $vindex) * $this->_tcount; + $result[(count($result) - 1)] = $last; // reset last + continue; // discard char + } + // if neither case was true, just add the character + $last = $char; + $result[] = $char; + } + return $result; + } + + /** + * Returns the combining class of a certain wide char + * @param integer Wide char to check (32bit integer) + * @return integer Combining class if found, else 0 + * @access private + */ + function _get_combining_class($char) + { + return isset($this->NP['norm_combcls'][$char]) ? $this->NP['norm_combcls'][$char] : 0; + } + + /** + * Apllies the cannonical ordering of a decomposed UCS4 sequence + * @param array Decomposed UCS4 sequence + * @return array Ordered USC4 sequence + * @access private + */ + function _apply_cannonical_ordering($input) + { + $swap = true; + $size = count($input); + while ($swap) { + $swap = false; + $last = $this->_get_combining_class(intval($input[0])); + for ($i = 0; $i < $size-1; ++$i) { + $next = $this->_get_combining_class(intval($input[$i+1])); + if ($next != 0 && $last > $next) { + // Move item leftward until it fits + for ($j = $i + 1; $j > 0; --$j) { + if ($this->_get_combining_class(intval($input[$j-1])) <= $next) break; + $t = intval($input[$j]); + $input[$j] = intval($input[$j-1]); + $input[$j-1] = $t; + $swap = true; + } + // Reentering the loop looking at the old character again + $next = $last; + } + $last = $next; + } + } + return $input; + } + + /** + * Do composition of a sequence of starter and non-starter + * @param array UCS4 Decomposed sequence + * @return array Ordered USC4 sequence + * @access private + */ + function _combine($input) + { + $inp_len = count($input); + foreach ($this->NP['replacemaps'] as $np_src => $np_target) { + if ($np_target[0] != $input[0]) continue; + if (count($np_target) != $inp_len) continue; + $hit = false; + foreach ($input as $k2 => $v2) { + if ($v2 == $np_target[$k2]) { + $hit = true; + } else { + $hit = false; + break; + } + } + if ($hit) return $np_src; + } + return false; + } + + /** + * This converts an UTF-8 encoded string to its UCS-4 representation + * By talking about UCS-4 "strings" we mean arrays of 32bit integers representing + * each of the "chars". This is due to PHP not being able to handle strings with + * bit depth different from 8. This apllies to the reverse method _ucs4_to_utf8(), too. + * The following UTF-8 encodings are supported: + * bytes bits representation + * 1 7 0xxxxxxx + * 2 11 110xxxxx 10xxxxxx + * 3 16 1110xxxx 10xxxxxx 10xxxxxx + * 4 21 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 5 26 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 6 31 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * Each x represents a bit that can be used to store character data. + * The five and six byte sequences are part of Annex D of ISO/IEC 10646-1:2000 + * @access private + */ + function _utf8_to_ucs4($input) + { + $output = array(); + $out_len = 0; + $inp_len = strlen($input); + $mode = 'next'; + $test = 'none'; + for ($k = 0; $k < $inp_len; ++$k) { + $v = ord($input{$k}); // Extract byte from input string + + if ($v < 128) { // We found an ASCII char - put into stirng as is + $output[$out_len] = $v; + ++$out_len; + if ('add' == $mode) { + $this->_error('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k); + return false; + } + continue; + } + if ('next' == $mode) { // Try to find the next start byte; determine the width of the Unicode char + $start_byte = $v; + $mode = 'add'; + $test = 'range'; + if ($v >> 5 == 6) { // &110xxxxx 10xxxxx + $next_byte = 0; // Tells, how many times subsequent bitmasks must rotate 6bits to the left + $v = ($v - 192) << 6; + } elseif ($v >> 4 == 14) { // &1110xxxx 10xxxxxx 10xxxxxx + $next_byte = 1; + $v = ($v - 224) << 12; + } elseif ($v >> 3 == 30) { // &11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + $next_byte = 2; + $v = ($v - 240) << 18; + } elseif ($v >> 2 == 62) { // &111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + $next_byte = 3; + $v = ($v - 248) << 24; + } elseif ($v >> 1 == 126) { // &1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + $next_byte = 4; + $v = ($v - 252) << 30; + } else { + $this->_error('This might be UTF-8, but I don\'t understand it at byte '.$k); + return false; + } + if ('add' == $mode) { + $output[$out_len] = (int) $v; + ++$out_len; + continue; + } + } + if ('add' == $mode) { + if (!$this->_allow_overlong && $test == 'range') { + $test = 'none'; + if (($v < 0xA0 && $start_byte == 0xE0) || ($v < 0x90 && $start_byte == 0xF0) || ($v > 0x8F && $start_byte == 0xF4)) { + $this->_error('Bogus UTF-8 character detected (out of legal range) at byte '.$k); + return false; + } + } + if ($v >> 6 == 2) { // Bit mask must be 10xxxxxx + $v = ($v - 128) << ($next_byte * 6); + $output[($out_len - 1)] += $v; + --$next_byte; + } else { + $this->_error('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k); + return false; + } + if ($next_byte < 0) { + $mode = 'next'; + } + } + } // for + return $output; + } + + /** + * Convert UCS-4 string into UTF-8 string + * See _utf8_to_ucs4() for details + * @access private + */ + function _ucs4_to_utf8($input) + { + $output = ''; + $k = 0; + foreach ($input as $v) { + ++$k; + // $v = ord($v); + if ($v < 128) { // 7bit are transferred literally + $output .= chr($v); + } elseif ($v < (1 << 11)) { // 2 bytes + $output .= chr(192 + ($v >> 6)) . chr(128 + ($v & 63)); + } elseif ($v < (1 << 16)) { // 3 bytes + $output .= chr(224 + ($v >> 12)) . chr(128 + (($v >> 6) & 63)) . chr(128 + ($v & 63)); + } elseif ($v < (1 << 21)) { // 4 bytes + $output .= chr(240 + ($v >> 18)) . chr(128 + (($v >> 12) & 63)) + . chr(128 + (($v >> 6) & 63)) . chr(128 + ($v & 63)); + } elseif ($v < (1 << 26)) { // 5 bytes + $output .= chr(248 + ($v >> 24)) . chr(128 + (($v >> 18) & 63)) + . chr(128 + (($v >> 12) & 63)) . chr(128 + (($v >> 6) & 63)) + . chr(128 + ($v & 63)); + } elseif ($v < (1 << 31)) { // 6 bytes + $output .= chr(252 + ($v >> 30)) . chr(128 + (($v >> 24) & 63)) + . chr(128 + (($v >> 18) & 63)) . chr(128 + (($v >> 12) & 63)) + . chr(128 + (($v >> 6) & 63)) . chr(128 + ($v & 63)); + } else { + $this->_error('Conversion from UCS-4 to UTF-8 failed: malformed input at byte '.$k); + return false; + } + } + return $output; + } + + /** + * Convert UCS-4 array into UCS-4 string + * + * @access private + */ + function _ucs4_to_ucs4_string($input) + { + $output = ''; + // Take array values and split output to 4 bytes per value + // The bit mask is 255, which reads &11111111 + foreach ($input as $v) { + $output .= chr(($v >> 24) & 255).chr(($v >> 16) & 255).chr(($v >> 8) & 255).chr($v & 255); + } + return $output; + } + + /** + * Convert UCS-4 strin into UCS-4 garray + * + * @access private + */ + function _ucs4_string_to_ucs4($input) + { + $output = array(); + $inp_len = strlen($input); + // Input length must be dividable by 4 + if ($inp_len % 4) { + $this->_error('Input UCS4 string is broken'); + return false; + } + // Empty input - return empty output + if (!$inp_len) return $output; + for ($i = 0, $out_len = -1; $i < $inp_len; ++$i) { + // Increment output position every 4 input bytes + if (!($i % 4)) { + $out_len++; + $output[$out_len] = 0; + } + $output[$out_len] += ord($input{$i}) << (8 * (3 - ($i % 4) ) ); + } + return $output; + } +} + +/** +* Adapter class for aligning the API of idna_convert with that of Net_IDNA +* @author Matthias Sommerfeld +*/ +class Net_IDNA_php4 extends idna_convert +{ + /** + * Sets a new option value. Available options and values: + * [encoding - Use either UTF-8, UCS4 as array or UCS4 as string as input ('utf8' for UTF-8, + * 'ucs4_string' and 'ucs4_array' respectively for UCS4); The output is always UTF-8] + * [overlong - Unicode does not allow unnecessarily long encodings of chars, + * to allow this, set this parameter to true, else to false; + * default is false.] + * [strict - true: strict mode, good for registration purposes - Causes errors + * on failures; false: loose mode, ideal for "wildlife" applications + * by silently ignoring errors and returning the original input instead + * + * @param mixed Parameter to set (string: single parameter; array of Parameter => Value pairs) + * @param string Value to use (if parameter 1 is a string) + * @return boolean true on success, false otherwise + * @access public + */ + function setParams($option, $param = false) + { + return $this->IC->set_parameters($option, $param); + } +} + ?> \ No newline at end of file diff --git a/whois.ie.php b/classes/whois.ie.php old mode 100755 new mode 100644 similarity index 96% rename from whois.ie.php rename to classes/whois.ie.php index 936c81e..ebe18ed --- a/whois.ie.php +++ b/classes/whois.ie.php @@ -1,64 +1,64 @@ - 'handle', - 'person' => 'name', - 'renewal' => 'expires' - ); - - $contacts = array( - 'admin-c' => 'admin', - 'tech-c' => 'tech', - ); - - $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain', 'Ymd'); - - if (isset($reg['domain']['descr'])) - { - $reg['owner']['organization'] = $reg['domain']['descr'][0]; - unset($reg['domain']['descr']); - } - - $r['regrinfo'] = $reg; - $r['regyinfo'] = array( - 'referrer' => 'http://www.domainregistry.ie', - 'registrar' => 'IE Domain Registry' - ); - return $r; - } - } -?> + 'handle', + 'person' => 'name', + 'renewal' => 'expires' + ); + + $contacts = array( + 'admin-c' => 'admin', + 'tech-c' => 'tech', + ); + + $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain', 'Ymd'); + + if (isset($reg['domain']['descr'])) + { + $reg['owner']['organization'] = $reg['domain']['descr'][0]; + unset($reg['domain']['descr']); + } + + $r['regrinfo'] = $reg; + $r['regyinfo'] = array( + 'referrer' => 'http://www.domainregistry.ie', + 'registrar' => 'IE Domain Registry' + ); + return $r; + } + } +?> diff --git a/whois.il.php b/classes/whois.il.php similarity index 96% rename from whois.il.php rename to classes/whois.il.php index 2819640..acfbadb 100644 --- a/whois.il.php +++ b/classes/whois.il.php @@ -1,106 +1,106 @@ - 'fax', - 'e-mail' => 'email', - 'nic-hdl' => 'handle', - 'person' => 'name', - 'personname' => 'name', - 'address' => 'address'/*, - 'address' => 'address.city', - 'address' => 'address.pcode', - 'address' => 'address.country'*/ - ); - - $contacts = array( - 'registrant' => 'owner', - 'admin-c' => 'admin', - 'tech-c' => 'tech', - 'billing-c' => 'billing', - 'zone-c' => 'zone' - ); -//unset($data_str['rawdata'][19]); -array_splice($data_str['rawdata'],16,1); -array_splice($data_str['rawdata'],18,1); -//print_r($data_str['rawdata']); -//die; - $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain', 'Ymd'); - - if (isset($reg['domain']['remarks'])) - unset($reg['domain']['remarks']); - - if (isset($reg['domain']['descr:'])) - { - while (list($key, $val) = each($reg['domain']['descr:'])) - { - $v = trim(substr(strstr($val, ':'), 1)); - if (strstr($val, '[organization]:')) - { - $reg['owner']['organization'] = $v; - continue; - } - if (strstr($val, '[phone]:')) - { - $reg['owner']['phone'] = $v; - continue; - } - if (strstr($val, '[fax-no]:')) - { - $reg['owner']['fax'] = $v; - continue; - } - if (strstr($val, '[e-mail]:')) - { - $reg['owner']['email'] = $v; - continue; - } - - $reg['owner']['address'][$key] = $v; - } - - if (isset($reg['domain']['descr:'])) unset($reg['domain']['descr:']); - } - - $r['regrinfo'] = $reg; - $r['regyinfo'] = array( - 'referrer' => 'http://www.isoc.org.il/', - 'registrar' => 'ISOC-IL' - ); - return $r; - } - } -?> + 'fax', + 'e-mail' => 'email', + 'nic-hdl' => 'handle', + 'person' => 'name', + 'personname' => 'name', + 'address' => 'address'/*, + 'address' => 'address.city', + 'address' => 'address.pcode', + 'address' => 'address.country'*/ + ); + + $contacts = array( + 'registrant' => 'owner', + 'admin-c' => 'admin', + 'tech-c' => 'tech', + 'billing-c' => 'billing', + 'zone-c' => 'zone' + ); +//unset($data_str['rawdata'][19]); +array_splice($data_str['rawdata'],16,1); +array_splice($data_str['rawdata'],18,1); +//print_r($data_str['rawdata']); +//die; + $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain', 'Ymd'); + + if (isset($reg['domain']['remarks'])) + unset($reg['domain']['remarks']); + + if (isset($reg['domain']['descr:'])) + { + while (list($key, $val) = each($reg['domain']['descr:'])) + { + $v = trim(substr(strstr($val, ':'), 1)); + if (strstr($val, '[organization]:')) + { + $reg['owner']['organization'] = $v; + continue; + } + if (strstr($val, '[phone]:')) + { + $reg['owner']['phone'] = $v; + continue; + } + if (strstr($val, '[fax-no]:')) + { + $reg['owner']['fax'] = $v; + continue; + } + if (strstr($val, '[e-mail]:')) + { + $reg['owner']['email'] = $v; + continue; + } + + $reg['owner']['address'][$key] = $v; + } + + if (isset($reg['domain']['descr:'])) unset($reg['domain']['descr:']); + } + + $r['regrinfo'] = $reg; + $r['regyinfo'] = array( + 'referrer' => 'http://www.isoc.org.il/', + 'registrar' => 'ISOC-IL' + ); + return $r; + } + } +?> diff --git a/whois.in.php b/classes/whois.in.php old mode 100755 new mode 100644 similarity index 96% rename from whois.in.php rename to classes/whois.in.php index 438d6fc..f36477e --- a/whois.in.php +++ b/classes/whois.in.php @@ -1,45 +1,45 @@ - 'http://whois.registry.in', - 'registrar' => 'INRegistry' - ); - return $r; - } - } + 'http://whois.registry.in', + 'registrar' => 'INRegistry' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.info.php b/classes/whois.info.php similarity index 96% rename from whois.info.php rename to classes/whois.info.php index 02fc903..146f10d 100644 --- a/whois.info.php +++ b/classes/whois.info.php @@ -1,45 +1,45 @@ - 'http://whois.afilias.info', - 'registrar' => 'Afilias Global Registry Services' - ); - return $r; - } - } + 'http://whois.afilias.info', + 'registrar' => 'Afilias Global Registry Services' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.int.php b/classes/whois.int.php old mode 100755 new mode 100644 similarity index 96% rename from whois.int.php rename to classes/whois.int.php index 1e7a783..eeb15d4 --- a/whois.int.php +++ b/classes/whois.int.php @@ -1,44 +1,44 @@ -parse($data_str['rawdata'], $query); - $r['regyinfo']['referrer'] = 'http://www.iana.org/int-dom/int.htm'; - $r['regyinfo']['registrar'] = 'Internet Assigned Numbers Authority'; - return ($r); - } - } +parse($data_str['rawdata'], $query); + $r['regyinfo']['referrer'] = 'http://www.iana.org/int-dom/int.htm'; + $r['regyinfo']['registrar'] = 'Internet Assigned Numbers Authority'; + return ($r); + } + } ?> \ No newline at end of file diff --git a/whois.ip.afrinic.php b/classes/whois.ip.afrinic.php old mode 100755 new mode 100644 similarity index 96% rename from whois.ip.afrinic.php rename to classes/whois.ip.afrinic.php index 6f66afd..b2c623d --- a/whois.ip.afrinic.php +++ b/classes/whois.ip.afrinic.php @@ -1,77 +1,77 @@ - 'fax', - 'e-mail' => 'email', - 'nic-hdl' => 'handle', - 'person' => 'name', - 'netname' => 'name', - 'organisation' => 'handle', - 'org-name' => 'organization', - 'org-type' => 'type' - ); - - $contacts = array( - 'admin-c' => 'admin', - 'tech-c' => 'tech', - 'org' => 'owner' - ); - - $r = generic_parser_a($data_str, $translate, $contacts, 'network', 'Ymd'); - - if (isset($r['network']['descr'])) - { - $r['owner']['organization'] = $r['network']['descr']; - unset($r['network']['descr']); - } - - if (isset($r['owner']['remarks']) && is_array($r['owner']['remarks'])) - while (list($key, $val) = each($r['owner']['remarks'])) - { - $pos = strpos($val,'rwhois://'); - - if ($pos!==false) - $r['rwhois'] = strtok(substr($val,$pos),' '); - } - - $r = array( 'regrinfo' => $r ); - $r['regyinfo']['type'] = 'ip'; - $r['regyinfo']['registrar'] = 'African Network Information Center'; - return $r; - } - } + 'fax', + 'e-mail' => 'email', + 'nic-hdl' => 'handle', + 'person' => 'name', + 'netname' => 'name', + 'organisation' => 'handle', + 'org-name' => 'organization', + 'org-type' => 'type' + ); + + $contacts = array( + 'admin-c' => 'admin', + 'tech-c' => 'tech', + 'org' => 'owner' + ); + + $r = generic_parser_a($data_str, $translate, $contacts, 'network', 'Ymd'); + + if (isset($r['network']['descr'])) + { + $r['owner']['organization'] = $r['network']['descr']; + unset($r['network']['descr']); + } + + if (isset($r['owner']['remarks']) && is_array($r['owner']['remarks'])) + while (list($key, $val) = each($r['owner']['remarks'])) + { + $pos = strpos($val,'rwhois://'); + + if ($pos!==false) + $r['rwhois'] = strtok(substr($val,$pos),' '); + } + + $r = array( 'regrinfo' => $r ); + $r['regyinfo']['type'] = 'ip'; + $r['regyinfo']['registrar'] = 'African Network Information Center'; + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.ip.apnic.php b/classes/whois.ip.apnic.php similarity index 96% rename from whois.ip.apnic.php rename to classes/whois.ip.apnic.php index 7a09fb6..f0f767b 100644 --- a/whois.ip.apnic.php +++ b/classes/whois.ip.apnic.php @@ -1,123 +1,123 @@ - 'fax', - 'e-mail' => 'email', - 'nic-hdl' => 'handle', - 'person' => 'name', - 'country' => 'address', - 'netname' => 'name', - 'descr' => 'desc', - 'aut-num' => 'handle', - 'country' => 'country' - ); - - $contacts = array ( - 'admin-c' => 'admin', - 'tech-c' => 'tech' - ); - - $blocks = generic_parser_a_blocks($data_str,$translate,$disclaimer); - - if (isset($disclaimer) && is_array($disclaimer)) $r['disclaimer'] = $disclaimer; - - if (empty($blocks) || !is_array($blocks['main'])) - { - $r['registered'] = 'no'; - } - else - { - if (isset($blocks[$query])) - { - $as = true; - $rb = $blocks[$query]; - } - else - { - $rb = $blocks['main']; - $as = false; - } - - $r['registered'] = 'yes'; - - while (list($key,$val) = each($contacts)) - if (isset($rb[$key])) - { - if (is_array($rb[$key])) - $blk = $rb[$key][count($rb[$key])-1]; - else - $blk = $rb[$key]; - - //$blk = strtoupper(strtok($blk,' ')); - if (isset($blocks[$blk])) $r[$val] = $blocks[$blk]; - unset($rb[$key]); - } - - $r['network'] = $rb; - format_dates($r,'Ymd'); - - if (isset($r['network']['desc'])) - { - if (is_array($r['network']['desc'])) - { - $r['owner']['organization'] = array_shift($r['network']['desc']); - $r['owner']['address'] = $r['network']['desc']; - } - else - $r['owner']['organization'] = $r['network']['desc']; - - unset($r['network']['desc']); - } - - if (isset($r['network']['address'])) - { - if (isset($r['owner']['address'])) - $r['owner']['address'][] = $r['network']['address']; - else - $r['owner']['address'] = $r['network']['address']; - - unset($r['network']['address']); - } - } - - $r = array( 'regrinfo' => $r ); - $r['regyinfo']['type'] ='ip'; - $r['regyinfo']['registrar'] = 'Asia Pacific Network Information Centre'; - return $r; - } -} -?> + 'fax', + 'e-mail' => 'email', + 'nic-hdl' => 'handle', + 'person' => 'name', + 'country' => 'address', + 'netname' => 'name', + 'descr' => 'desc', + 'aut-num' => 'handle', + 'country' => 'country' + ); + + $contacts = array ( + 'admin-c' => 'admin', + 'tech-c' => 'tech' + ); + + $blocks = generic_parser_a_blocks($data_str,$translate,$disclaimer); + + if (isset($disclaimer) && is_array($disclaimer)) $r['disclaimer'] = $disclaimer; + + if (empty($blocks) || !is_array($blocks['main'])) + { + $r['registered'] = 'no'; + } + else + { + if (isset($blocks[$query])) + { + $as = true; + $rb = $blocks[$query]; + } + else + { + $rb = $blocks['main']; + $as = false; + } + + $r['registered'] = 'yes'; + + while (list($key,$val) = each($contacts)) + if (isset($rb[$key])) + { + if (is_array($rb[$key])) + $blk = $rb[$key][count($rb[$key])-1]; + else + $blk = $rb[$key]; + + //$blk = strtoupper(strtok($blk,' ')); + if (isset($blocks[$blk])) $r[$val] = $blocks[$blk]; + unset($rb[$key]); + } + + $r['network'] = $rb; + format_dates($r,'Ymd'); + + if (isset($r['network']['desc'])) + { + if (is_array($r['network']['desc'])) + { + $r['owner']['organization'] = array_shift($r['network']['desc']); + $r['owner']['address'] = $r['network']['desc']; + } + else + $r['owner']['organization'] = $r['network']['desc']; + + unset($r['network']['desc']); + } + + if (isset($r['network']['address'])) + { + if (isset($r['owner']['address'])) + $r['owner']['address'][] = $r['network']['address']; + else + $r['owner']['address'] = $r['network']['address']; + + unset($r['network']['address']); + } + } + + $r = array( 'regrinfo' => $r ); + $r['regyinfo']['type'] ='ip'; + $r['regyinfo']['registrar'] = 'Asia Pacific Network Information Centre'; + return $r; + } +} +?> diff --git a/whois.ip.arin.php b/classes/whois.ip.arin.php similarity index 97% rename from whois.ip.arin.php rename to classes/whois.ip.arin.php index f214aca..82ab726 100644 --- a/whois.ip.arin.php +++ b/classes/whois.ip.arin.php @@ -1,78 +1,78 @@ - 'owner.organization', - 'CustName:' => 'owner.organization', - 'OrgId:' => 'owner.handle', - 'Address:' => 'owner.address.street.', - 'City:' => 'owner.address.city', - 'StateProv:' => 'owner.address.state', - 'PostalCode:' => 'owner.address.pcode', - 'Country:' => 'owner.address.country', - 'NetRange:' => 'network.inetnum', - 'NetName:' => 'network.name', - 'NetHandle:' => 'network.handle', - 'NetType:' => 'network.status', - 'NameServer:' => 'network.nserver.', - 'Comment:' => 'network.desc.', - 'RegDate:' => 'network.created', - 'Updated:' => 'network.changed', - 'ASHandle:' => 'network.handle', - 'ASName:' => 'network.name', - 'NetHandle:' => 'network.handle', - 'NetName:' => 'network.name', - 'TechHandle:' => 'tech.handle', - 'TechName:' => 'tech.name', - 'TechPhone:' => 'tech.phone', - 'TechEmail:' => 'tech.email', - 'OrgAbuseName:' => 'abuse.name', - 'OrgAbuseHandle:' => 'abuse.handle', - 'OrgAbusePhone:' => 'abuse.phone', - 'OrgAbuseEmail:' => 'abuse.email.', - 'ReferralServer:' => 'rwhois' - ); - - $r = generic_parser_b($data_str, $items, 'ymd', false, true); - - if (@isset($r['abuse']['email'])) - $r['abuse']['email'] = implode(',',$r['abuse']['email']); - - return array( 'regrinfo' => $r ); - } - } + 'owner.organization', + 'CustName:' => 'owner.organization', + 'OrgId:' => 'owner.handle', + 'Address:' => 'owner.address.street.', + 'City:' => 'owner.address.city', + 'StateProv:' => 'owner.address.state', + 'PostalCode:' => 'owner.address.pcode', + 'Country:' => 'owner.address.country', + 'NetRange:' => 'network.inetnum', + 'NetName:' => 'network.name', + 'NetHandle:' => 'network.handle', + 'NetType:' => 'network.status', + 'NameServer:' => 'network.nserver.', + 'Comment:' => 'network.desc.', + 'RegDate:' => 'network.created', + 'Updated:' => 'network.changed', + 'ASHandle:' => 'network.handle', + 'ASName:' => 'network.name', + 'NetHandle:' => 'network.handle', + 'NetName:' => 'network.name', + 'TechHandle:' => 'tech.handle', + 'TechName:' => 'tech.name', + 'TechPhone:' => 'tech.phone', + 'TechEmail:' => 'tech.email', + 'OrgAbuseName:' => 'abuse.name', + 'OrgAbuseHandle:' => 'abuse.handle', + 'OrgAbusePhone:' => 'abuse.phone', + 'OrgAbuseEmail:' => 'abuse.email.', + 'ReferralServer:' => 'rwhois' + ); + + $r = generic_parser_b($data_str, $items, 'ymd', false, true); + + if (@isset($r['abuse']['email'])) + $r['abuse']['email'] = implode(',',$r['abuse']['email']); + + return array( 'regrinfo' => $r ); + } + } ?> \ No newline at end of file diff --git a/whois.ip.krnic.php b/classes/whois.ip.krnic.php similarity index 97% rename from whois.ip.krnic.php rename to classes/whois.ip.krnic.php index 71bc12f..d02eda8 100644 --- a/whois.ip.krnic.php +++ b/classes/whois.ip.krnic.php @@ -1,112 +1,112 @@ - '[ Organization Information ]', - 'tech1' => '[ Technical Contact Information ]', - - 'owner2' => '[ ISP Organization Information ]', - 'admin2' => '[ ISP IP Admin Contact Information ]', - 'tech2' => '[ ISP IP Tech Contact Information ]', - - 'admin3' => '[ ISP IPv4 Admin Contact Information ]', - 'tech3' => '[ ISP IPv4 Tech Contact Information ]', - - 'abuse' => '[ ISP Network Abuse Contact Information ]', - - 'network.inetnum' => 'IPv4 Address :', - 'network.name' => 'Network Name :', - 'network.mnt-by' => 'Connect ISP Name :', - 'network.created' => 'Registration Date :' - ); - - $items = array( - 'Orgnization ID :' => 'handle', - 'Org Name :' => 'organization', - 'Org Name :' => 'organization', - 'Name :' => 'name', - 'Name :' => 'name', - 'Org Address :' => 'address.street', - 'Zip Code :' => 'address.pcode', - 'State :' => 'address.state', - 'Address :' => 'address.street', - 'Zip Code :' => 'address.pcode', - 'Phone :' => 'phone', - 'Phone :' => 'phone', - 'Fax :' => 'fax', - 'E-Mail :' => 'email', - 'E-Mail :' => 'email' - ); - - $b = get_blocks($data_str, $blocks); - - if (isset($b['network'])) - $r['network'] = $b['network']; - - if (isset($b['owner1'])) - $r['owner'] = generic_parser_b($b['owner1'], $items, 'Ymd', false); - else - if (isset($b['owner2'])) - $r['owner'] = generic_parser_b($b['owner2'], $items, 'Ymd', false); - - if (isset($b['admin2'])) - $r['admin'] = generic_parser_b($b['admin2'], $items, 'Ymd', false); - else - if (isset($b['admin3'])) - $r['admin'] = generic_parser_b($b['admin3'], $items, 'Ymd', false); - - if (isset($b['tech1'])) - $r['tech'] = generic_parser_b($b['tech1'], $items, 'Ymd', false); - else - if (isset($b['tech2'])) - $r['tech'] = generic_parser_b($b['tech2'], $items, 'Ymd', false); - else - if (isset($b['tech3'])) - $r['tech'] = generic_parser_b($b['tech3'], $items, 'Ymd', false); - - if (isset($b['abuse'])) - $r['abuse'] = generic_parser_b($b['abuse'], $items, 'Ymd', false); - - $r = format_dates($r, 'Ymd'); - - $r = array( 'regrinfo' => $r ); - $r['regyinfo']['type'] ='ip'; - $r['regyinfo']['registrar'] = 'Korean Network Information Centre'; - - return $r; - } - } + '[ Organization Information ]', + 'tech1' => '[ Technical Contact Information ]', + + 'owner2' => '[ ISP Organization Information ]', + 'admin2' => '[ ISP IP Admin Contact Information ]', + 'tech2' => '[ ISP IP Tech Contact Information ]', + + 'admin3' => '[ ISP IPv4 Admin Contact Information ]', + 'tech3' => '[ ISP IPv4 Tech Contact Information ]', + + 'abuse' => '[ ISP Network Abuse Contact Information ]', + + 'network.inetnum' => 'IPv4 Address :', + 'network.name' => 'Network Name :', + 'network.mnt-by' => 'Connect ISP Name :', + 'network.created' => 'Registration Date :' + ); + + $items = array( + 'Orgnization ID :' => 'handle', + 'Org Name :' => 'organization', + 'Org Name :' => 'organization', + 'Name :' => 'name', + 'Name :' => 'name', + 'Org Address :' => 'address.street', + 'Zip Code :' => 'address.pcode', + 'State :' => 'address.state', + 'Address :' => 'address.street', + 'Zip Code :' => 'address.pcode', + 'Phone :' => 'phone', + 'Phone :' => 'phone', + 'Fax :' => 'fax', + 'E-Mail :' => 'email', + 'E-Mail :' => 'email' + ); + + $b = get_blocks($data_str, $blocks); + + if (isset($b['network'])) + $r['network'] = $b['network']; + + if (isset($b['owner1'])) + $r['owner'] = generic_parser_b($b['owner1'], $items, 'Ymd', false); + else + if (isset($b['owner2'])) + $r['owner'] = generic_parser_b($b['owner2'], $items, 'Ymd', false); + + if (isset($b['admin2'])) + $r['admin'] = generic_parser_b($b['admin2'], $items, 'Ymd', false); + else + if (isset($b['admin3'])) + $r['admin'] = generic_parser_b($b['admin3'], $items, 'Ymd', false); + + if (isset($b['tech1'])) + $r['tech'] = generic_parser_b($b['tech1'], $items, 'Ymd', false); + else + if (isset($b['tech2'])) + $r['tech'] = generic_parser_b($b['tech2'], $items, 'Ymd', false); + else + if (isset($b['tech3'])) + $r['tech'] = generic_parser_b($b['tech3'], $items, 'Ymd', false); + + if (isset($b['abuse'])) + $r['abuse'] = generic_parser_b($b['abuse'], $items, 'Ymd', false); + + $r = format_dates($r, 'Ymd'); + + $r = array( 'regrinfo' => $r ); + $r['regyinfo']['type'] ='ip'; + $r['regyinfo']['registrar'] = 'Korean Network Information Centre'; + + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.ip.lacnic.php b/classes/whois.ip.lacnic.php similarity index 96% rename from whois.ip.lacnic.php rename to classes/whois.ip.lacnic.php index 5490bce..9471641 100644 --- a/whois.ip.lacnic.php +++ b/classes/whois.ip.lacnic.php @@ -1,79 +1,79 @@ - 'fax', - 'e-mail' => 'email', - 'nic-hdl-br' => 'handle', - 'nic-hdl' => 'handle', - 'person' => 'name', - 'netname' => 'name', - 'descr' => 'desc', - 'country' => 'address.country' - ); - - $contacts = array( - 'owner-c' => 'owner', - 'tech-c' => 'tech', - 'abuse-c' => 'abuse', - 'admin-c' => 'admin' - ); - - $r = generic_parser_a($data_str, $translate, $contacts, 'network'); - - unset($r['network']['owner']); - unset($r['network']['ownerid']); - unset($r['network']['responsible']); - unset($r['network']['address']); - unset($r['network']['phone']); - unset($r['network']['aut-num']); - unset($r['network']['nsstat']); - unset($r['network']['nslastaa']); - unset($r['network']['inetrev']); - - if (!empty($r['network']['aut-num'])) - $r['network']['handle'] = $r['network']['aut-num']; - - if (isset($r['network']['nserver'])) - $r['network']['nserver'] = array_unique($r['network']['nserver']); - - $r = array( 'regrinfo' => $r ); - $r['regyinfo']['type'] ='ip'; - $r['regyinfo']['registrar'] = 'Latin American and Caribbean IP address Regional Registry'; - return $r; - } - } + 'fax', + 'e-mail' => 'email', + 'nic-hdl-br' => 'handle', + 'nic-hdl' => 'handle', + 'person' => 'name', + 'netname' => 'name', + 'descr' => 'desc', + 'country' => 'address.country' + ); + + $contacts = array( + 'owner-c' => 'owner', + 'tech-c' => 'tech', + 'abuse-c' => 'abuse', + 'admin-c' => 'admin' + ); + + $r = generic_parser_a($data_str, $translate, $contacts, 'network'); + + unset($r['network']['owner']); + unset($r['network']['ownerid']); + unset($r['network']['responsible']); + unset($r['network']['address']); + unset($r['network']['phone']); + unset($r['network']['aut-num']); + unset($r['network']['nsstat']); + unset($r['network']['nslastaa']); + unset($r['network']['inetrev']); + + if (!empty($r['network']['aut-num'])) + $r['network']['handle'] = $r['network']['aut-num']; + + if (isset($r['network']['nserver'])) + $r['network']['nserver'] = array_unique($r['network']['nserver']); + + $r = array( 'regrinfo' => $r ); + $r['regyinfo']['type'] ='ip'; + $r['regyinfo']['registrar'] = 'Latin American and Caribbean IP address Regional Registry'; + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.ip.lib.php b/classes/whois.ip.lib.php old mode 100755 new mode 100644 similarity index 100% rename from whois.ip.lib.php rename to classes/whois.ip.lib.php diff --git a/whois.ip.php b/classes/whois.ip.php similarity index 100% rename from whois.ip.php rename to classes/whois.ip.php diff --git a/whois.ip.ripe.php b/classes/whois.ip.ripe.php similarity index 96% rename from whois.ip.ripe.php rename to classes/whois.ip.ripe.php index 6ac51cb..fe8343a 100644 --- a/whois.ip.ripe.php +++ b/classes/whois.ip.ripe.php @@ -1,85 +1,85 @@ - 'fax', - 'e-mail' => 'email', - 'nic-hdl' => 'handle', - 'person' => 'name', - 'netname' => 'name', - 'descr' => 'desc' - ); - - $contacts = array( - 'admin-c' => 'admin', - 'tech-c' => 'tech' - ); - - if (!empty($data_str['rawdata'])) $data_str = $data_str['rawdata']; - - $r = generic_parser_a($data_str, $translate, $contacts, 'network'); - - if (isset($r['network']['desc'])) - { - $r['owner']['organization'] = $r['network']['desc']; - unset($r['network']['desc']); - } - - if (isset($r['admin']['abuse-mailbox'])) - { - $r['abuse']['email'] = $r['admin']['abuse-mailbox']; - unset($r['admin']['abuse-mailbox']); - } - - if (isset($r['tech']['abuse-mailbox'])) - { - $r['abuse']['email'] = $r['tech']['abuse-mailbox']; - unset($r['tech']['abuse-mailbox']); - } - - // Clean mess - if (isset($r['tech']['tech-c'])) unset($r['tech']['tech-c']); - if (isset($r['tech']['admin-c'])) unset($r['tech']['admin-c']); - if (isset($r['admin']['tech-c'])) unset($r['admin']['tech-c']); - if (isset($r['admin']['admin-c'])) unset($r['admin']['admin-c']); - - $r = array( 'regrinfo' => $r ); - $r['regyinfo']['type'] ='ip'; - $r['regyinfo']['registrar'] = 'RIPE Network Coordination Centre'; - return $r; - } - } + 'fax', + 'e-mail' => 'email', + 'nic-hdl' => 'handle', + 'person' => 'name', + 'netname' => 'name', + 'descr' => 'desc' + ); + + $contacts = array( + 'admin-c' => 'admin', + 'tech-c' => 'tech' + ); + + if (!empty($data_str['rawdata'])) $data_str = $data_str['rawdata']; + + $r = generic_parser_a($data_str, $translate, $contacts, 'network'); + + if (isset($r['network']['desc'])) + { + $r['owner']['organization'] = $r['network']['desc']; + unset($r['network']['desc']); + } + + if (isset($r['admin']['abuse-mailbox'])) + { + $r['abuse']['email'] = $r['admin']['abuse-mailbox']; + unset($r['admin']['abuse-mailbox']); + } + + if (isset($r['tech']['abuse-mailbox'])) + { + $r['abuse']['email'] = $r['tech']['abuse-mailbox']; + unset($r['tech']['abuse-mailbox']); + } + + // Clean mess + if (isset($r['tech']['tech-c'])) unset($r['tech']['tech-c']); + if (isset($r['tech']['admin-c'])) unset($r['tech']['admin-c']); + if (isset($r['admin']['tech-c'])) unset($r['admin']['tech-c']); + if (isset($r['admin']['admin-c'])) unset($r['admin']['admin-c']); + + $r = array( 'regrinfo' => $r ); + $r['regyinfo']['type'] ='ip'; + $r['regyinfo']['registrar'] = 'RIPE Network Coordination Centre'; + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.ir.php b/classes/whois.ir.php similarity index 96% rename from whois.ir.php rename to classes/whois.ir.php index b7632cb..a6aed48 100644 --- a/whois.ir.php +++ b/classes/whois.ir.php @@ -1,60 +1,60 @@ -. - */ - -// Define the handler flag. -if (!defined('__IR_HANDLER__')) - define('__IR_HANDLER__', 1); - -// Loadup the parser. -require_once('whois.parser.php'); - -/** - * IR Domain names lookup handler class. - */ -class ir_handler - { - function parse($data_str, $query) - { - $translate = array( - 'nic-hdl' => 'handle', - 'org' => 'organization', - 'e-mail' => 'email', - 'person' => 'name', - 'fax-no' => 'fax', - 'domain' => 'name' - ); - - $contacts = array( - 'admin-c' => 'admin', - 'tech-c' => 'tech', - 'holder-c' => 'owner' - ); - - $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain', 'Ymd'); - - $r['regrinfo'] = $reg; - $r['regyinfo'] = array( - 'referrer'=>'http://whois.nic.ir/', - 'registrar' => 'NIC-IR' - ); - return $r; - } - } +. + */ + +// Define the handler flag. +if (!defined('__IR_HANDLER__')) + define('__IR_HANDLER__', 1); + +// Loadup the parser. +require_once('whois.parser.php'); + +/** + * IR Domain names lookup handler class. + */ +class ir_handler + { + function parse($data_str, $query) + { + $translate = array( + 'nic-hdl' => 'handle', + 'org' => 'organization', + 'e-mail' => 'email', + 'person' => 'name', + 'fax-no' => 'fax', + 'domain' => 'name' + ); + + $contacts = array( + 'admin-c' => 'admin', + 'tech-c' => 'tech', + 'holder-c' => 'owner' + ); + + $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain', 'Ymd'); + + $r['regrinfo'] = $reg; + $r['regyinfo'] = array( + 'referrer'=>'http://whois.nic.ir/', + 'registrar' => 'NIC-IR' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.is.php b/classes/whois.is.php similarity index 96% rename from whois.is.php rename to classes/whois.is.php index b9902d6..ba4f697 100644 --- a/whois.is.php +++ b/classes/whois.is.php @@ -1,69 +1,69 @@ - 'fax', - 'e-mail' => 'email', - 'nic-hdl' => 'handle', - 'person' => 'name' - ); - - $contacts = array( - 'owner-c' => 'owner', - 'admin-c' => 'admin', - 'tech-c' => 'tech', - 'billing-c' => 'billing', - 'zone-c' => 'zone' - ); - - $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain', 'mdy'); - - if (isset($reg['domain']['descr'])) - { - $reg['owner']['name'] = array_shift($reg['domain']['descr']); - $reg['owner']['address'] = $reg['domain']['descr']; - unset($reg['domain']['descr']); - } - - $r['regrinfo'] = $reg; - $r['regyinfo'] = array( - 'referrer' => 'http://www.isnic.is', - 'registrar' => 'ISNIC' - ); - return $r; - } - } + 'fax', + 'e-mail' => 'email', + 'nic-hdl' => 'handle', + 'person' => 'name' + ); + + $contacts = array( + 'owner-c' => 'owner', + 'admin-c' => 'admin', + 'tech-c' => 'tech', + 'billing-c' => 'billing', + 'zone-c' => 'zone' + ); + + $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain', 'mdy'); + + if (isset($reg['domain']['descr'])) + { + $reg['owner']['name'] = array_shift($reg['domain']['descr']); + $reg['owner']['address'] = $reg['domain']['descr']; + unset($reg['domain']['descr']); + } + + $r['regrinfo'] = $reg; + $r['regyinfo'] = array( + 'referrer' => 'http://www.isnic.is', + 'registrar' => 'ISNIC' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.it.php b/classes/whois.it.php similarity index 96% rename from whois.it.php rename to classes/whois.it.php index 08538d7..790c573 100644 --- a/whois.it.php +++ b/classes/whois.it.php @@ -1,78 +1,78 @@ - array -- ContactID in address -*/ - -if (!defined('__IT_HANDLER__')) - define('__IT_HANDLER__', 1); - -require_once('whois.parser.php'); - -class it_handler - { - function parse($data_str, $query) - { - $items = array( - 'domain.name' => 'Domain:', - 'domain.nserver' => 'Nameservers', - 'domain.status' => 'Status:', - 'domain.expires' => 'Expire Date:', - 'owner' => 'Registrant', - 'admin' => 'Admin Contact', - 'tech' => 'Technical Contacts', - 'registrar' => 'Registrar' - ); - - $extra = array( - 'address:' => 'address.', - 'contactid:' => 'handle', - 'organization:' => 'organization', - 'created:' => 'created', - 'last update:' => 'changed', - 'web:' => 'web' - ); - - $r['regrinfo'] = easy_parser($data_str['rawdata'], $items, 'ymd',$extra); - - if (isset($r['regrinfo']['registrar'])) - { - $r['regrinfo']['domain']['registrar'] = $r['regrinfo']['registrar']; - unset($r['regrinfo']['registrar']); - } - - $r['regyinfo'] = array( - 'registrar' => 'IT-Nic', - 'referrer' => 'http://www.nic.it/' - ); - return $r; - } - } + array +- ContactID in address +*/ + +if (!defined('__IT_HANDLER__')) + define('__IT_HANDLER__', 1); + +require_once('whois.parser.php'); + +class it_handler + { + function parse($data_str, $query) + { + $items = array( + 'domain.name' => 'Domain:', + 'domain.nserver' => 'Nameservers', + 'domain.status' => 'Status:', + 'domain.expires' => 'Expire Date:', + 'owner' => 'Registrant', + 'admin' => 'Admin Contact', + 'tech' => 'Technical Contacts', + 'registrar' => 'Registrar' + ); + + $extra = array( + 'address:' => 'address.', + 'contactid:' => 'handle', + 'organization:' => 'organization', + 'created:' => 'created', + 'last update:' => 'changed', + 'web:' => 'web' + ); + + $r['regrinfo'] = easy_parser($data_str['rawdata'], $items, 'ymd',$extra); + + if (isset($r['regrinfo']['registrar'])) + { + $r['regrinfo']['domain']['registrar'] = $r['regrinfo']['registrar']; + unset($r['regrinfo']['registrar']); + } + + $r['regyinfo'] = array( + 'registrar' => 'IT-Nic', + 'referrer' => 'http://www.nic.it/' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.jp.php b/classes/whois.jp.php similarity index 96% rename from whois.jp.php rename to classes/whois.jp.php index d5f12bb..ebd9685 100644 --- a/whois.jp.php +++ b/classes/whois.jp.php @@ -1,111 +1,111 @@ - 'domain.status', - '[Status]' => 'domain.status', - '[Registered Date]' => 'domain.created', - '[Created on]' => 'domain.created', - '[Expires on]' => 'domain.expires', - '[Last Updated]' => 'domain.changed', - '[Last Update]' => 'domain.changed', - '[Organization]' => 'owner.organization', - '[Name]' => 'owner.name', - '[Email]' => 'owner.email', - '[Postal code]' => 'owner.address.pcode', - '[Postal Address]' => 'owner.address.street', - '[Phone]' => 'owner.phone', - '[Fax]' => 'owner.fax', - '[Administrative Contact]' => 'admin.handle', - '[Technical Contact]' => 'tech.handle', - '[Name Server]' => 'domain.nserver.' - ); - - $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items, 'ymd'); - - $r['regyinfo'] = array( - 'referrer' => 'http://www.jprs.jp', - 'registrar' => 'Japan Registry Services' - ); - - if (!$this->deep_whois) return $r; - - $r['rawdata'] = $data_str['rawdata']; - - $items = array( - 'a. [JPNIC Handle]' => 'handle', - 'c. [Last, First]' => 'name', - 'd. [E-Mail]' => 'email', - 'g. [Organization]' => 'organization', - 'o. [TEL]' => 'phone', - 'p. [FAX]' => 'fax', - '[Last Update]' => 'changed' - ); - - $this->Query['server'] = 'jp.whois-servers.net'; - - if (!empty($r['regrinfo']['admin']['handle'])) - { - $rwdata = $this->GetRawData('CONTACT '.$r['regrinfo']['admin']['handle'].'/e'); - $r['rawdata'][] = ''; - $r['rawdata'] = array_merge($r['rawdata'],$rwdata); - $r['regrinfo']['admin'] = generic_parser_b($rwdata,$items,'ymd',false); - $r = $this->set_whois_info($r); - } - - if (!empty($r['regrinfo']['tech']['handle'])) - { - if (!empty($r['regrinfo']['admin']['handle']) && - $r['regrinfo']['admin']['handle'] == $r['regrinfo']['tech']['handle']) - { - $r['regrinfo']['tech'] = $r['regrinfo']['admin']; - } - else - { - unset($this->Query); - $this->Query['server'] = 'jp.whois-servers.net'; - $rwdata = $this->GetRawData('CONTACT '.$r['regrinfo']['tech']['handle'].'/e'); - $r['rawdata'][] = ''; - $r['rawdata'] = array_merge($r['rawdata'],$rwdata); - $r['regrinfo']['tech'] = generic_parser_b($rwdata,$items,'ymd',false); - $r = $this->set_whois_info($r); - } - } - - return $r; - } - } + 'domain.status', + '[Status]' => 'domain.status', + '[Registered Date]' => 'domain.created', + '[Created on]' => 'domain.created', + '[Expires on]' => 'domain.expires', + '[Last Updated]' => 'domain.changed', + '[Last Update]' => 'domain.changed', + '[Organization]' => 'owner.organization', + '[Name]' => 'owner.name', + '[Email]' => 'owner.email', + '[Postal code]' => 'owner.address.pcode', + '[Postal Address]' => 'owner.address.street', + '[Phone]' => 'owner.phone', + '[Fax]' => 'owner.fax', + '[Administrative Contact]' => 'admin.handle', + '[Technical Contact]' => 'tech.handle', + '[Name Server]' => 'domain.nserver.' + ); + + $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items, 'ymd'); + + $r['regyinfo'] = array( + 'referrer' => 'http://www.jprs.jp', + 'registrar' => 'Japan Registry Services' + ); + + if (!$this->deep_whois) return $r; + + $r['rawdata'] = $data_str['rawdata']; + + $items = array( + 'a. [JPNIC Handle]' => 'handle', + 'c. [Last, First]' => 'name', + 'd. [E-Mail]' => 'email', + 'g. [Organization]' => 'organization', + 'o. [TEL]' => 'phone', + 'p. [FAX]' => 'fax', + '[Last Update]' => 'changed' + ); + + $this->Query['server'] = 'jp.whois-servers.net'; + + if (!empty($r['regrinfo']['admin']['handle'])) + { + $rwdata = $this->GetRawData('CONTACT '.$r['regrinfo']['admin']['handle'].'/e'); + $r['rawdata'][] = ''; + $r['rawdata'] = array_merge($r['rawdata'],$rwdata); + $r['regrinfo']['admin'] = generic_parser_b($rwdata,$items,'ymd',false); + $r = $this->set_whois_info($r); + } + + if (!empty($r['regrinfo']['tech']['handle'])) + { + if (!empty($r['regrinfo']['admin']['handle']) && + $r['regrinfo']['admin']['handle'] == $r['regrinfo']['tech']['handle']) + { + $r['regrinfo']['tech'] = $r['regrinfo']['admin']; + } + else + { + unset($this->Query); + $this->Query['server'] = 'jp.whois-servers.net'; + $rwdata = $this->GetRawData('CONTACT '.$r['regrinfo']['tech']['handle'].'/e'); + $r['rawdata'][] = ''; + $r['rawdata'] = array_merge($r['rawdata'],$rwdata); + $r['regrinfo']['tech'] = generic_parser_b($rwdata,$items,'ymd',false); + $r = $this->set_whois_info($r); + } + } + + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.lt.php b/classes/whois.lt.php old mode 100755 new mode 100644 similarity index 96% rename from whois.lt.php rename to classes/whois.lt.php index 15c1133..aa8f297 --- a/whois.lt.php +++ b/classes/whois.lt.php @@ -1,64 +1,64 @@ - 'handle', - 'contact name:' => 'name' - ); - - $items = array( - 'admin' => 'Contact type: Admin', - 'tech' => 'Contact type: Tech', - 'zone' => 'Contact type: Zone', - 'owner.name' => 'Registrar:', - 'owner.email' => 'Registrar email:', - 'domain.status' => 'Status:', - 'domain.created' => 'Registered:', - 'domain.changed' => 'Last updated:', - 'domain.nserver.' => 'NS:', - '' => '%' - ); - - $r['regrinfo'] = easy_parser($data_str['rawdata'], $items, 'ymd', $translate); - - $r['regyinfo'] = array( - 'referrer' => 'http://www.domreg.lt', - 'registrar' => 'DOMREG.LT' - ); - return $r; - } - } + 'handle', + 'contact name:' => 'name' + ); + + $items = array( + 'admin' => 'Contact type: Admin', + 'tech' => 'Contact type: Tech', + 'zone' => 'Contact type: Zone', + 'owner.name' => 'Registrar:', + 'owner.email' => 'Registrar email:', + 'domain.status' => 'Status:', + 'domain.created' => 'Registered:', + 'domain.changed' => 'Last updated:', + 'domain.nserver.' => 'NS:', + '' => '%' + ); + + $r['regrinfo'] = easy_parser($data_str['rawdata'], $items, 'ymd', $translate); + + $r['regyinfo'] = array( + 'referrer' => 'http://www.domreg.lt', + 'registrar' => 'DOMREG.LT' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.lu.php b/classes/whois.lu.php similarity index 97% rename from whois.lu.php rename to classes/whois.lu.php index ff7287e..19a2f38 100644 --- a/whois.lu.php +++ b/classes/whois.lu.php @@ -1,78 +1,78 @@ - 'domain.name', - 'domaintype:' => 'domain.status', - 'nserver:' => 'domain.nserver.', - 'registered:' => 'domain.created', - 'source:' => 'domain.source', - 'ownertype:' => 'owner.type', - 'org-name:' => 'owner.organization', - 'org-address:' => 'owner.address.', - 'org-zipcode:' => 'owner.address.pcode', - 'org-city:' => 'owner.address.city', - 'org-country:' => 'owner.address.country', - 'adm-name:' => 'admin.name', - 'adm-address:' => 'admin.address.', - 'adm-zipcode:' => 'admin.address.pcode', - 'adm-city:' => 'admin.address.city', - 'adm-country:' => 'admin.address.country', - 'adm-email:' => 'admin.email', - 'tec-name:' => 'tech.name', - 'tec-address:' => 'tech.address.', - 'tec-zipcode:' => 'tech.address.pcode', - 'tec-city:' => 'tech.address.city', - 'tec-country:' => 'tech.address.country', - 'tec-email:' => 'tech.email', - 'bil-name:' => 'billing.name', - 'bil-address:' => 'billing.address.', - 'bil-zipcode:' => 'billing.address.pcode', - 'bil-city:' => 'billing.address.city', - 'bil-country:' => 'billing.address.country', - 'bil-email:' => 'billing.email' - ); - - $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items, 'dmy'); - - $r['regyinfo'] = array( - 'referrer' => 'http://www.dns.lu', - 'registrar' => 'DNS-LU' - ); - return $r; - } - } + 'domain.name', + 'domaintype:' => 'domain.status', + 'nserver:' => 'domain.nserver.', + 'registered:' => 'domain.created', + 'source:' => 'domain.source', + 'ownertype:' => 'owner.type', + 'org-name:' => 'owner.organization', + 'org-address:' => 'owner.address.', + 'org-zipcode:' => 'owner.address.pcode', + 'org-city:' => 'owner.address.city', + 'org-country:' => 'owner.address.country', + 'adm-name:' => 'admin.name', + 'adm-address:' => 'admin.address.', + 'adm-zipcode:' => 'admin.address.pcode', + 'adm-city:' => 'admin.address.city', + 'adm-country:' => 'admin.address.country', + 'adm-email:' => 'admin.email', + 'tec-name:' => 'tech.name', + 'tec-address:' => 'tech.address.', + 'tec-zipcode:' => 'tech.address.pcode', + 'tec-city:' => 'tech.address.city', + 'tec-country:' => 'tech.address.country', + 'tec-email:' => 'tech.email', + 'bil-name:' => 'billing.name', + 'bil-address:' => 'billing.address.', + 'bil-zipcode:' => 'billing.address.pcode', + 'bil-city:' => 'billing.address.city', + 'bil-country:' => 'billing.address.country', + 'bil-email:' => 'billing.email' + ); + + $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items, 'dmy'); + + $r['regyinfo'] = array( + 'referrer' => 'http://www.dns.lu', + 'registrar' => 'DNS-LU' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.ly.php b/classes/whois.ly.php similarity index 96% rename from whois.ly.php rename to classes/whois.ly.php index 0ed85d2..f90b079 100644 --- a/whois.ly.php +++ b/classes/whois.ly.php @@ -1,72 +1,72 @@ - 'Registrant:', - 'admin' => 'Administrative Contact:', - 'tech' => 'Technical Contact:', - 'domain.name' => 'Domain Name:', - 'domain.status' => 'Domain Status:', - 'domain.created' => 'Created:', - 'domain.changed' => 'Updated:', - 'domain.expires' => 'Expired:', - 'domain.nserver' => 'Domain servers in listed order:' - ); - - $extra = array( 'zip/postal code:' => 'address.pcode' ); - - $r['regrinfo'] = get_blocks($data_str['rawdata'], $items); - - if (!empty($r['regrinfo']['domain']['name'])) - { - $r['regrinfo'] = get_contacts($r['regrinfo'],$extra); - $r['regrinfo']['domain']['name'] = $r['regrinfo']['domain']['name'][0]; - $r['regrinfo']['registered'] = 'yes'; - } - else - { - $r = ''; - $r['regrinfo']['registered'] = 'no'; - } - - $r['regyinfo'] = array( - 'referrer' => 'http://www.nic.ly', - 'registrar' => 'Libya ccTLD' - ); - return $r; - } - } + 'Registrant:', + 'admin' => 'Administrative Contact:', + 'tech' => 'Technical Contact:', + 'domain.name' => 'Domain Name:', + 'domain.status' => 'Domain Status:', + 'domain.created' => 'Created:', + 'domain.changed' => 'Updated:', + 'domain.expires' => 'Expired:', + 'domain.nserver' => 'Domain servers in listed order:' + ); + + $extra = array( 'zip/postal code:' => 'address.pcode' ); + + $r['regrinfo'] = get_blocks($data_str['rawdata'], $items); + + if (!empty($r['regrinfo']['domain']['name'])) + { + $r['regrinfo'] = get_contacts($r['regrinfo'],$extra); + $r['regrinfo']['domain']['name'] = $r['regrinfo']['domain']['name'][0]; + $r['regrinfo']['registered'] = 'yes'; + } + else + { + $r = ''; + $r['regrinfo']['registered'] = 'no'; + } + + $r['regyinfo'] = array( + 'referrer' => 'http://www.nic.ly', + 'registrar' => 'Libya ccTLD' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.main.php b/classes/whois.main.php old mode 100755 new mode 100644 similarity index 100% rename from whois.main.php rename to classes/whois.main.php diff --git a/whois.me.php b/classes/whois.me.php similarity index 96% rename from whois.me.php rename to classes/whois.me.php index 09f518d..6bf4436 100644 --- a/whois.me.php +++ b/classes/whois.me.php @@ -1,45 +1,45 @@ - 'http://domain.me', - 'registrar' => 'doMEn' - ); - return $r; - } - } + 'http://domain.me', + 'registrar' => 'doMEn' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.mobi.php b/classes/whois.mobi.php old mode 100755 new mode 100644 similarity index 100% rename from whois.mobi.php rename to classes/whois.mobi.php diff --git a/whois.museum.php b/classes/whois.museum.php old mode 100755 new mode 100644 similarity index 96% rename from whois.museum.php rename to classes/whois.museum.php index 658a07c..cf0a769 --- a/whois.museum.php +++ b/classes/whois.museum.php @@ -1,45 +1,45 @@ - 'http://musedoma.museum', - 'registrar' => 'Museum Domain Management Association' - ); - return $r; - } - } + 'http://musedoma.museum', + 'registrar' => 'Museum Domain Management Association' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.mx.php b/classes/whois.mx.php similarity index 96% rename from whois.mx.php rename to classes/whois.mx.php index 882c2c5..1564746 100644 --- a/whois.mx.php +++ b/classes/whois.mx.php @@ -1,70 +1,70 @@ - 'Registrant:', - 'admin' => 'Administrative Contact:', - 'tech' => 'Technical Contact:', - 'billing' => 'Billing Contact:', - 'domain.nserver' => 'Name Servers:', - 'domain.created' => 'Created On:', - 'domain.expires' => 'Expiration Date:', - 'domain.changed' => 'Last Updated On:', - 'domain.sponsor' => 'Registrar:' - ); - - $extra = array( - 'city:' => 'address.city', - 'state:' => 'address.state', - 'dns:' => '0' - ); - - $r['regrinfo'] = easy_parser($data_str['rawdata'],$items,'dmy',$extra); - - $r['regyinfo'] = array( - 'registrar' => 'NIC Mexico', - 'referrer' => 'http://www.nic.mx/' - ); - - if (empty($r['regrinfo']['domain']['created'])) - $r['regrinfo']['registered'] = 'no'; - else - $r['regrinfo']['registered'] = 'yes'; - - return $r; - } - } + 'Registrant:', + 'admin' => 'Administrative Contact:', + 'tech' => 'Technical Contact:', + 'billing' => 'Billing Contact:', + 'domain.nserver' => 'Name Servers:', + 'domain.created' => 'Created On:', + 'domain.expires' => 'Expiration Date:', + 'domain.changed' => 'Last Updated On:', + 'domain.sponsor' => 'Registrar:' + ); + + $extra = array( + 'city:' => 'address.city', + 'state:' => 'address.state', + 'dns:' => '0' + ); + + $r['regrinfo'] = easy_parser($data_str['rawdata'],$items,'dmy',$extra); + + $r['regyinfo'] = array( + 'registrar' => 'NIC Mexico', + 'referrer' => 'http://www.nic.mx/' + ); + + if (empty($r['regrinfo']['domain']['created'])) + $r['regrinfo']['registered'] = 'no'; + else + $r['regrinfo']['registered'] = 'yes'; + + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.name.php b/classes/whois.name.php old mode 100755 new mode 100644 similarity index 96% rename from whois.name.php rename to classes/whois.name.php index db2d695..0b81e1e --- a/whois.name.php +++ b/classes/whois.name.php @@ -1,45 +1,45 @@ - 'http://www.nic.name/', - 'registrar' => 'Global Name Registry' - ); - return $r; - } - } + 'http://www.nic.name/', + 'registrar' => 'Global Name Registry' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.nl.php b/classes/whois.nl.php similarity index 100% rename from whois.nl.php rename to classes/whois.nl.php diff --git a/whois.nu.php b/classes/whois.nu.php similarity index 96% rename from whois.nu.php rename to classes/whois.nu.php index addb471..0645545 100644 --- a/whois.nu.php +++ b/classes/whois.nu.php @@ -1,90 +1,90 @@ - 'Domain Name (UTF-8):', - 'created' => 'Record created on', - 'expires' => 'Record expires on', - 'changed' => 'Record last updated on', - 'status' => 'Record status:', - 'handle' => 'Record ID:' - ); - - while (list($key, $val) = each($data_str['rawdata'])) - { - $val = trim($val); - - if ($val != '') - { - if ($val == 'Domain servers in listed order:') - { - while (list($key, $val) = each($data_str['rawdata'])) - { - $val = trim($val); - if ($val == '') - break; - $r['regrinfo']['domain']['nserver'][] = $val; - } - break; - } - - reset($items); - - while (list($field, $match) = each($items)) - if (strstr($val, $match)) - { - $r['regrinfo']['domain'][$field] = trim(substr($val, strlen($match))); - break; - } - } - } - - if (isset($r['regrinfo']['domain'])) - $r['regrinfo']['registered'] = 'yes'; - else - $r['regrinfo']['registered'] = 'no'; - - $r['regyinfo'] = array( - 'whois' => 'whois.nic.nu', - 'referrer' => 'http://www.nunames.nu', - 'registrar' => '.NU Domain, Ltd' - ); - - format_dates($r, 'dmy'); - return $r; - } - } + 'Domain Name (UTF-8):', + 'created' => 'Record created on', + 'expires' => 'Record expires on', + 'changed' => 'Record last updated on', + 'status' => 'Record status:', + 'handle' => 'Record ID:' + ); + + while (list($key, $val) = each($data_str['rawdata'])) + { + $val = trim($val); + + if ($val != '') + { + if ($val == 'Domain servers in listed order:') + { + while (list($key, $val) = each($data_str['rawdata'])) + { + $val = trim($val); + if ($val == '') + break; + $r['regrinfo']['domain']['nserver'][] = $val; + } + break; + } + + reset($items); + + while (list($field, $match) = each($items)) + if (strstr($val, $match)) + { + $r['regrinfo']['domain'][$field] = trim(substr($val, strlen($match))); + break; + } + } + } + + if (isset($r['regrinfo']['domain'])) + $r['regrinfo']['registered'] = 'yes'; + else + $r['regrinfo']['registered'] = 'no'; + + $r['regyinfo'] = array( + 'whois' => 'whois.nic.nu', + 'referrer' => 'http://www.nunames.nu', + 'registrar' => '.NU Domain, Ltd' + ); + + format_dates($r, 'dmy'); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.nz.php b/classes/whois.nz.php old mode 100755 new mode 100644 similarity index 100% rename from whois.nz.php rename to classes/whois.nz.php diff --git a/whois.org.php b/classes/whois.org.php similarity index 100% rename from whois.org.php rename to classes/whois.org.php diff --git a/whois.org.za.php b/classes/whois.org.za.php similarity index 96% rename from whois.org.za.php rename to classes/whois.org.za.php index 13d38b0..a45416f 100644 --- a/whois.org.za.php +++ b/classes/whois.org.za.php @@ -1,64 +1,64 @@ - 'Status:', - 'domain.nserver' => 'Domain name servers in listed order:', - 'domain.changed' => 'Record last updated on', - 'owner' => 'rwhois search on', - 'admin' => 'Administrative Contact:', - 'tech' => 'Technical Contact:', - 'billing' => 'Billing Contact:', - '#' => 'Search Again' - ); - - $r['regrinfo'] = get_blocks($data['rawdata'], $items); - - if (isset($r['regrinfo']['domain']['status'])) - { - $r['regrinfo']['registered'] = 'yes'; - $r['regrinfo']['domain']['handler'] = strtok(array_shift($r['regrinfo']['owner']),' '); - $r['regrinfo'] = get_contacts($r['regrinfo']); - } - else - $r['regrinfo']['registered'] = 'no'; - - $r['regyinfo']['referrer'] = 'http://www.org.za'; - $r['regyinfo']['registrar'] = 'The ORG.ZA Domain'; - return $r; - } - } + 'Status:', + 'domain.nserver' => 'Domain name servers in listed order:', + 'domain.changed' => 'Record last updated on', + 'owner' => 'rwhois search on', + 'admin' => 'Administrative Contact:', + 'tech' => 'Technical Contact:', + 'billing' => 'Billing Contact:', + '#' => 'Search Again' + ); + + $r['regrinfo'] = get_blocks($data['rawdata'], $items); + + if (isset($r['regrinfo']['domain']['status'])) + { + $r['regrinfo']['registered'] = 'yes'; + $r['regrinfo']['domain']['handler'] = strtok(array_shift($r['regrinfo']['owner']),' '); + $r['regrinfo'] = get_contacts($r['regrinfo']); + } + else + $r['regrinfo']['registered'] = 'no'; + + $r['regyinfo']['referrer'] = 'http://www.org.za'; + $r['regyinfo']['registrar'] = 'The ORG.ZA Domain'; + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.parser.php b/classes/whois.parser.php old mode 100755 new mode 100644 similarity index 100% rename from whois.parser.php rename to classes/whois.parser.php diff --git a/whois.pl.php b/classes/whois.pl.php old mode 100755 new mode 100644 similarity index 96% rename from whois.pl.php rename to classes/whois.pl.php index 5228954..1a1f0e2 --- a/whois.pl.php +++ b/classes/whois.pl.php @@ -1,54 +1,54 @@ - 'created:', - 'domain.changed' => 'last modified:', - 'domain.sponsor' => 'REGISTRAR:', - '#' => 'WHOIS displays data with a delay not exceeding 15 minutes in relation to the .pl Registry system' - - ); - - $r['regrinfo'] = easy_parser($data_str['rawdata'], $items, 'ymd'); - - $r['regyinfo'] = array( - 'referrer' => 'http://www.dns.pl/english/index.html', - 'registrar' => 'NASK' - ); - return $r; - } - } + 'created:', + 'domain.changed' => 'last modified:', + 'domain.sponsor' => 'REGISTRAR:', + '#' => 'WHOIS displays data with a delay not exceeding 15 minutes in relation to the .pl Registry system' + + ); + + $r['regrinfo'] = easy_parser($data_str['rawdata'], $items, 'ymd'); + + $r['regyinfo'] = array( + 'referrer' => 'http://www.dns.pl/english/index.html', + 'registrar' => 'NASK' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.pm.php b/classes/whois.pm.php similarity index 96% rename from whois.pm.php rename to classes/whois.pm.php index 4d9654c..13bd3b9 100644 --- a/whois.pm.php +++ b/classes/whois.pm.php @@ -1,78 +1,78 @@ - 'fax', - 'e-mail' => 'email', - 'nic-hdl' => 'handle', - 'ns-list' => 'handle', - 'person' => 'name', - 'address' => 'address.', - 'descr' => 'desc', - 'anniversary' => '', - 'domain' => '', - 'last-update' => 'changed', - 'registered' => 'created', - 'country' => 'address.country', - 'registrar' => 'sponsor', - 'role' => 'organization' - ); - - $contacts = array( - 'admin-c' => 'admin', - 'tech-c' => 'tech', - 'zone-c' => 'zone', - 'holder-c' => 'owner', - 'nsl-id' => 'nserver' - ); - - $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain','dmY'); - - if (isset($reg['nserver'])) - { - $reg['domain'] = array_merge($reg['domain'],$reg['nserver']); - unset($reg['nserver']); - } - - $r['regrinfo'] = $reg; - $r['regyinfo'] = array( - 'referrer' => 'http://www.nic.fr', - 'registrar' => 'AFNIC' - ); - return $r; - } - } + 'fax', + 'e-mail' => 'email', + 'nic-hdl' => 'handle', + 'ns-list' => 'handle', + 'person' => 'name', + 'address' => 'address.', + 'descr' => 'desc', + 'anniversary' => '', + 'domain' => '', + 'last-update' => 'changed', + 'registered' => 'created', + 'country' => 'address.country', + 'registrar' => 'sponsor', + 'role' => 'organization' + ); + + $contacts = array( + 'admin-c' => 'admin', + 'tech-c' => 'tech', + 'zone-c' => 'zone', + 'holder-c' => 'owner', + 'nsl-id' => 'nserver' + ); + + $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain','dmY'); + + if (isset($reg['nserver'])) + { + $reg['domain'] = array_merge($reg['domain'],$reg['nserver']); + unset($reg['nserver']); + } + + $r['regrinfo'] = $reg; + $r['regyinfo'] = array( + 'referrer' => 'http://www.nic.fr', + 'registrar' => 'AFNIC' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.pro.php b/classes/whois.pro.php old mode 100755 new mode 100644 similarity index 96% rename from whois.pro.php rename to classes/whois.pro.php index 7c09bd4..2e6c738 --- a/whois.pro.php +++ b/classes/whois.pro.php @@ -1,43 +1,43 @@ - \ No newline at end of file diff --git a/whois.pt.php b/classes/whois.pt.php similarity index 96% rename from whois.pt.php rename to classes/whois.pt.php index ddda050..162ef84 100644 --- a/whois.pt.php +++ b/classes/whois.pt.php @@ -1,81 +1,81 @@ - ' / Domain Name:', - 'domain.created' => 'Data de registo / Creation Date (dd/mm/yyyy):', - 'domain.nserver.' => 'Nameserver:', - 'domain.status' => 'Estado / Status:', - 'owner' => 'Titular / Registrant', - 'billing' => 'Entidade Gestora / Billing Contact', - 'admin' => 'Responsável Administrativo / Admin Contact', - 'tech' => 'Responsável Técnico / Tech Contact', - '#' => 'Nameserver Information' - ); - - $r['regrinfo'] = get_blocks($data['rawdata'], $items); - - if (empty($r['regrinfo']['domain']['name'])) - { - print_r($r['regrinfo']); - $r['regrinfo']['registered'] = 'no'; - return $r; - } - - $r['regrinfo']['domain']['created'] = get_date($r['regrinfo']['domain']['created'], 'dmy'); - - if ($r['regrinfo']['domain']['status'] == 'ACTIVE') - { - $r['regrinfo'] = get_contacts($r['regrinfo']); - $r['regrinfo']['registered'] = 'yes'; - } - else - $r['regrinfo']['registered'] = 'no'; - - $r['regyinfo'] = array( - 'referrer' => 'http://www.fccn.pt', - 'registrar' => 'FCCN' - ); - - return $r; - } - } + ' / Domain Name:', + 'domain.created' => 'Data de registo / Creation Date (dd/mm/yyyy):', + 'domain.nserver.' => 'Nameserver:', + 'domain.status' => 'Estado / Status:', + 'owner' => 'Titular / Registrant', + 'billing' => 'Entidade Gestora / Billing Contact', + 'admin' => 'Responsável Administrativo / Admin Contact', + 'tech' => 'Responsável Técnico / Tech Contact', + '#' => 'Nameserver Information' + ); + + $r['regrinfo'] = get_blocks($data['rawdata'], $items); + + if (empty($r['regrinfo']['domain']['name'])) + { + print_r($r['regrinfo']); + $r['regrinfo']['registered'] = 'no'; + return $r; + } + + $r['regrinfo']['domain']['created'] = get_date($r['regrinfo']['domain']['created'], 'dmy'); + + if ($r['regrinfo']['domain']['status'] == 'ACTIVE') + { + $r['regrinfo'] = get_contacts($r['regrinfo']); + $r['regrinfo']['registered'] = 'yes'; + } + else + $r['regrinfo']['registered'] = 'no'; + + $r['regyinfo'] = array( + 'referrer' => 'http://www.fccn.pt', + 'registrar' => 'FCCN' + ); + + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.re.php b/classes/whois.re.php similarity index 96% rename from whois.re.php rename to classes/whois.re.php index e44e957..73b1a15 100644 --- a/whois.re.php +++ b/classes/whois.re.php @@ -1,78 +1,78 @@ - 'fax', - 'e-mail' => 'email', - 'nic-hdl' => 'handle', - 'ns-list' => 'handle', - 'person' => 'name', - 'address' => 'address.', - 'descr' => 'desc', - 'anniversary' => '', - 'domain' => '', - 'last-update' => 'changed', - 'registered' => 'created', - 'country' => 'address.country', - 'registrar' => 'sponsor', - 'role' => 'organization' - ); - - $contacts = array( - 'admin-c' => 'admin', - 'tech-c' => 'tech', - 'zone-c' => 'zone', - 'holder-c' => 'owner', - 'nsl-id' => 'nserver' - ); - - $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain','dmY'); - - if (isset($reg['nserver'])) - { - $reg['domain'] = array_merge($reg['domain'],$reg['nserver']); - unset($reg['nserver']); - } - - $r['regrinfo'] = $reg; - $r['regyinfo'] = array( - 'referrer' => 'http://www.nic.fr', - 'registrar' => 'AFNIC' - ); - return $r; - } - } + 'fax', + 'e-mail' => 'email', + 'nic-hdl' => 'handle', + 'ns-list' => 'handle', + 'person' => 'name', + 'address' => 'address.', + 'descr' => 'desc', + 'anniversary' => '', + 'domain' => '', + 'last-update' => 'changed', + 'registered' => 'created', + 'country' => 'address.country', + 'registrar' => 'sponsor', + 'role' => 'organization' + ); + + $contacts = array( + 'admin-c' => 'admin', + 'tech-c' => 'tech', + 'zone-c' => 'zone', + 'holder-c' => 'owner', + 'nsl-id' => 'nserver' + ); + + $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain','dmY'); + + if (isset($reg['nserver'])) + { + $reg['domain'] = array_merge($reg['domain'],$reg['nserver']); + unset($reg['nserver']); + } + + $r['regrinfo'] = $reg; + $r['regyinfo'] = array( + 'referrer' => 'http://www.nic.fr', + 'registrar' => 'AFNIC' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.ro.php b/classes/whois.ro.php similarity index 96% rename from whois.ro.php rename to classes/whois.ro.php index 3c61775..bd6a7ad 100644 --- a/whois.ro.php +++ b/classes/whois.ro.php @@ -1,99 +1,99 @@ - 'fax', - 'e-mail' => 'email', - 'nic-hdl' => 'handle', - 'person' => 'name', - 'address' => 'address.', - 'domain-name' => '', - 'updated' => 'changed', - 'registration-date' => 'created', - 'domain-status' => 'status', - 'nameserver' => 'nserver' - ); - - $contacts = array( - 'admin-contact' => 'admin', - 'technical-contact' => 'tech', - 'zone-contact' => 'zone', - 'billing-contact' => 'billing' - ); - - $extra = array( - 'postal code:' => 'address.pcode' - ); - - $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain','Ymd'); - - if (isset($reg['domain']['description'])) - { - $reg['owner'] = get_contact($reg['domain']['description'],$extra); - unset($reg['domain']['description']); - - foreach($reg as $key => $item) - { - if (isset($item['address'])) - { - $data = $item['address']; - unset($reg[$key]['address']); - $reg[$key] = array_merge($reg[$key],get_contact($data,$extra)); - } - } - - $reg['registered'] = 'yes'; - } - else - $reg['registered'] = 'no'; - - $r['regrinfo'] = $reg; - $r['regyinfo'] = array( - 'referrer' => 'http://www.nic.ro', - 'registrar' => 'nic.ro' - ); - - return $r; - } - } + 'fax', + 'e-mail' => 'email', + 'nic-hdl' => 'handle', + 'person' => 'name', + 'address' => 'address.', + 'domain-name' => '', + 'updated' => 'changed', + 'registration-date' => 'created', + 'domain-status' => 'status', + 'nameserver' => 'nserver' + ); + + $contacts = array( + 'admin-contact' => 'admin', + 'technical-contact' => 'tech', + 'zone-contact' => 'zone', + 'billing-contact' => 'billing' + ); + + $extra = array( + 'postal code:' => 'address.pcode' + ); + + $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain','Ymd'); + + if (isset($reg['domain']['description'])) + { + $reg['owner'] = get_contact($reg['domain']['description'],$extra); + unset($reg['domain']['description']); + + foreach($reg as $key => $item) + { + if (isset($item['address'])) + { + $data = $item['address']; + unset($reg[$key]['address']); + $reg[$key] = array_merge($reg[$key],get_contact($data,$extra)); + } + } + + $reg['registered'] = 'yes'; + } + else + $reg['registered'] = 'no'; + + $r['regrinfo'] = $reg; + $r['regyinfo'] = array( + 'referrer' => 'http://www.nic.ro', + 'registrar' => 'nic.ro' + ); + + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.ru.php b/classes/whois.ru.php similarity index 96% rename from whois.ru.php rename to classes/whois.ru.php index fa82a74..9edd1dd 100644 --- a/whois.ru.php +++ b/classes/whois.ru.php @@ -1,63 +1,63 @@ - 'domain.name', - 'state:' => 'domain.status', - 'nserver:' => 'domain.nserver.', - 'source:' => 'domain.source', - 'created:' => 'domain.created', - 'paid-till:' => 'domain.expires', - 'type:' => 'owner.type', - 'org:' => 'owner.organization', - 'phone:' => 'owner.phone', - 'fax-no:' => 'owner.fax', - 'e-mail:' => 'owner.email' - ); - - $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items, 'dmy'); - - if (empty($r['regrinfo']['domain']['status'])) - $r['regrinfo']['registered'] = 'no'; - - $r['regyinfo'] = array( - 'referrer' => 'http://www.ripn.net', - 'registrar' => 'RU-CENTER-REG-RIPN' - ); - return $r; - } - } + 'domain.name', + 'state:' => 'domain.status', + 'nserver:' => 'domain.nserver.', + 'source:' => 'domain.source', + 'created:' => 'domain.created', + 'paid-till:' => 'domain.expires', + 'type:' => 'owner.type', + 'org:' => 'owner.organization', + 'phone:' => 'owner.phone', + 'fax-no:' => 'owner.fax', + 'e-mail:' => 'owner.email' + ); + + $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items, 'dmy'); + + if (empty($r['regrinfo']['domain']['status'])) + $r['regrinfo']['registered'] = 'no'; + + $r['regyinfo'] = array( + 'referrer' => 'http://www.ripn.net', + 'registrar' => 'RU-CENTER-REG-RIPN' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.rwhois.php b/classes/whois.rwhois.php old mode 100755 new mode 100644 similarity index 97% rename from whois.rwhois.php rename to classes/whois.rwhois.php index 04bc31f..8e81ad7 --- a/whois.rwhois.php +++ b/classes/whois.rwhois.php @@ -1,58 +1,58 @@ - 'owner.name', - 'network:Organization;I:' => 'owner.organization', - 'network:Organization-City:' => 'owner.address.city', - 'network:Organization-Zip:' => 'owner.address.pcode', - 'network:Organization-Country:' => 'owner.address.country', - 'network:IP-Network-Block:' => 'network.inetnum', - 'network:IP-Network:' => 'network.inetnum', - 'network:Network-Name:' => 'network.name', - 'network:ID:' => 'network.handle', - 'network:Created:' => 'network.created', - 'network:Updated:' => 'network.changed', - 'network:Tech-Contact;I:' => 'tech.email', - 'network:Admin-Contact;I:' => 'admin.email' - ); - - $res = generic_parser_b($data_str, $items, 'Ymd', false); - if (isset($res['disclaimer'])) unset($res['disclaimer']); - return array( 'regrinfo' => $res ); - } - } + 'owner.name', + 'network:Organization;I:' => 'owner.organization', + 'network:Organization-City:' => 'owner.address.city', + 'network:Organization-Zip:' => 'owner.address.pcode', + 'network:Organization-Country:' => 'owner.address.country', + 'network:IP-Network-Block:' => 'network.inetnum', + 'network:IP-Network:' => 'network.inetnum', + 'network:Network-Name:' => 'network.name', + 'network:ID:' => 'network.handle', + 'network:Created:' => 'network.created', + 'network:Updated:' => 'network.changed', + 'network:Tech-Contact;I:' => 'tech.email', + 'network:Admin-Contact;I:' => 'admin.email' + ); + + $res = generic_parser_b($data_str, $items, 'Ymd', false); + if (isset($res['disclaimer'])) unset($res['disclaimer']); + return array( 'regrinfo' => $res ); + } + } ?> \ No newline at end of file diff --git a/whois.sc.php b/classes/whois.sc.php old mode 100755 new mode 100644 similarity index 100% rename from whois.sc.php rename to classes/whois.sc.php diff --git a/whois.se.php b/classes/whois.se.php similarity index 96% rename from whois.se.php rename to classes/whois.se.php index a463382..461a037 100644 --- a/whois.se.php +++ b/classes/whois.se.php @@ -1,58 +1,58 @@ - 'domain.name', - 'state:' => 'domain.status.', - 'status:' => 'domain.status.', - 'expires:' => 'domain.expires', - 'created:' => 'domain.created', - 'nserver:' => 'domain.nserver.', - 'holder:' => 'owner.handle' - ); - - $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items, 'ymd', false); - - $r['regrinfo']['registered'] = isset($r['regrinfo']['domain']['name']) ? 'yes' : 'no'; - - $r['regyinfo'] = array( - 'referrer' => 'http://www.nic-se.se', - 'registrar' => 'NIC-SE' - ); - return $r; - } - } + 'domain.name', + 'state:' => 'domain.status.', + 'status:' => 'domain.status.', + 'expires:' => 'domain.expires', + 'created:' => 'domain.created', + 'nserver:' => 'domain.nserver.', + 'holder:' => 'owner.handle' + ); + + $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items, 'ymd', false); + + $r['regrinfo']['registered'] = isset($r['regrinfo']['domain']['name']) ? 'yes' : 'no'; + + $r['regyinfo'] = array( + 'referrer' => 'http://www.nic-se.se', + 'registrar' => 'NIC-SE' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.servers.php b/classes/whois.servers.php similarity index 100% rename from whois.servers.php rename to classes/whois.servers.php diff --git a/whois.si.php b/classes/whois.si.php similarity index 100% rename from whois.si.php rename to classes/whois.si.php diff --git a/whois.su.php b/classes/whois.su.php similarity index 96% rename from whois.su.php rename to classes/whois.su.php index 93fe793..4ab7661 100644 --- a/whois.su.php +++ b/classes/whois.su.php @@ -1,63 +1,63 @@ - 'domain.name', - 'state:' => 'domain.status', - 'person:' => 'owner.name', - 'phone:' => 'owner.phone', - 'e-mail:' => 'owner.email', - 'created:' => 'domain.created', - 'paid-till:' => 'domain.expires', -/* - 'nserver:' => 'domain.nserver.', - 'source:' => 'domain.source', - 'type:' => 'owner.type', - 'org:' => 'owner.organization', - 'fax-no:' => 'owner.fax', -*/ - ); - - $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items, 'dmy'); - - $r['regyinfo'] = array( - 'referrer' => 'http://www.ripn.net', - 'registrar' => 'RUCENTER-REG-RIPN' - ); - return $r; - } - } + 'domain.name', + 'state:' => 'domain.status', + 'person:' => 'owner.name', + 'phone:' => 'owner.phone', + 'e-mail:' => 'owner.email', + 'created:' => 'domain.created', + 'paid-till:' => 'domain.expires', +/* + 'nserver:' => 'domain.nserver.', + 'source:' => 'domain.source', + 'type:' => 'owner.type', + 'org:' => 'owner.organization', + 'fax-no:' => 'owner.fax', +*/ + ); + + $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items, 'dmy'); + + $r['regyinfo'] = array( + 'referrer' => 'http://www.ripn.net', + 'registrar' => 'RUCENTER-REG-RIPN' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.tel.php b/classes/whois.tel.php similarity index 96% rename from whois.tel.php rename to classes/whois.tel.php index 3ffe821..812d0bd 100644 --- a/whois.tel.php +++ b/classes/whois.tel.php @@ -1,45 +1,45 @@ - 'http://www.telnic.org', - 'registrar' => 'Telnic' - ); - return $r; - } - } + 'http://www.telnic.org', + 'registrar' => 'Telnic' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.travel.php b/classes/whois.travel.php old mode 100755 new mode 100644 similarity index 96% rename from whois.travel.php rename to classes/whois.travel.php index 9400ab9..8f090d8 --- a/whois.travel.php +++ b/classes/whois.travel.php @@ -1,43 +1,43 @@ - \ No newline at end of file diff --git a/whois.uk.php b/classes/whois.uk.php similarity index 96% rename from whois.uk.php rename to classes/whois.uk.php index d33e4b1..83be53a 100644 --- a/whois.uk.php +++ b/classes/whois.uk.php @@ -1,80 +1,80 @@ - 'Registrant:', - 'owner.address' => "Registrant's address:", - 'owner.type' => 'Registrant type:', - 'domain.created' => 'Registered on:', - 'domain.changed' => 'Last updated:', - 'domain.expires' => 'Renewal date:', - 'domain.nserver' => 'Name servers:', - 'domain.sponsor' => 'Registrar:', - 'domain.status' => 'Registration status:', - 'domain.dnssec' => 'DNSSEC:', - '' => 'WHOIS lookup made at', - 'disclaimer' => '--', - ); - - $r['regrinfo'] = get_blocks($data_str['rawdata'], $items); - - if (isset($r['regrinfo']['owner'])) - { - $r['regrinfo']['owner']['organization'] = $r['regrinfo']['owner']['organization'][0]; - $r['regrinfo']['domain']['sponsor'] = $r['regrinfo']['domain']['sponsor'][0]; - $r['regrinfo']['registered'] = 'yes'; - - $r = format_dates($r, 'dmy'); - } - else - { - if (strpos($data_str['rawdata'][1],'Error for ')) - { - $r['regrinfo']['registered'] = 'yes'; - $r['regrinfo']['domain']['status'] = 'invalid'; - } - else - $r['regrinfo']['registered'] = 'no'; - } - - $r['regyinfo'] = array( - 'referrer' => 'http://www.nominet.org.uk', - 'registrar' => 'Nominet UK' - ); - return $r; - } - } + 'Registrant:', + 'owner.address' => "Registrant's address:", + 'owner.type' => 'Registrant type:', + 'domain.created' => 'Registered on:', + 'domain.changed' => 'Last updated:', + 'domain.expires' => 'Renewal date:', + 'domain.nserver' => 'Name servers:', + 'domain.sponsor' => 'Registrar:', + 'domain.status' => 'Registration status:', + 'domain.dnssec' => 'DNSSEC:', + '' => 'WHOIS lookup made at', + 'disclaimer' => '--', + ); + + $r['regrinfo'] = get_blocks($data_str['rawdata'], $items); + + if (isset($r['regrinfo']['owner'])) + { + $r['regrinfo']['owner']['organization'] = $r['regrinfo']['owner']['organization'][0]; + $r['regrinfo']['domain']['sponsor'] = $r['regrinfo']['domain']['sponsor'][0]; + $r['regrinfo']['registered'] = 'yes'; + + $r = format_dates($r, 'dmy'); + } + else + { + if (strpos($data_str['rawdata'][1],'Error for ')) + { + $r['regrinfo']['registered'] = 'yes'; + $r['regrinfo']['domain']['status'] = 'invalid'; + } + else + $r['regrinfo']['registered'] = 'no'; + } + + $r['regyinfo'] = array( + 'referrer' => 'http://www.nominet.org.uk', + 'registrar' => 'Nominet UK' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.us.php b/classes/whois.us.php similarity index 96% rename from whois.us.php rename to classes/whois.us.php index 393bd53..7cab37e 100644 --- a/whois.us.php +++ b/classes/whois.us.php @@ -1,44 +1,44 @@ -'http://www.neustar.us', - 'registrar' => 'NEUSTAR INC.' - ); - return $r; - } - } +'http://www.neustar.us', + 'registrar' => 'NEUSTAR INC.' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.utils.php b/classes/whois.utils.php old mode 100755 new mode 100644 similarity index 100% rename from whois.utils.php rename to classes/whois.utils.php diff --git a/whois.ve.php b/classes/whois.ve.php similarity index 100% rename from whois.ve.php rename to classes/whois.ve.php diff --git a/whois.wf.php b/classes/whois.wf.php similarity index 96% rename from whois.wf.php rename to classes/whois.wf.php index 5c1fa29..62779b3 100644 --- a/whois.wf.php +++ b/classes/whois.wf.php @@ -1,78 +1,78 @@ - 'fax', - 'e-mail' => 'email', - 'nic-hdl' => 'handle', - 'ns-list' => 'handle', - 'person' => 'name', - 'address' => 'address.', - 'descr' => 'desc', - 'anniversary' => '', - 'domain' => '', - 'last-update' => 'changed', - 'registered' => 'created', - 'country' => 'address.country', - 'registrar' => 'sponsor', - 'role' => 'organization' - ); - - $contacts = array( - 'admin-c' => 'admin', - 'tech-c' => 'tech', - 'zone-c' => 'zone', - 'holder-c' => 'owner', - 'nsl-id' => 'nserver' - ); - - $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain','dmY'); - - if (isset($reg['nserver'])) - { - $reg['domain'] = array_merge($reg['domain'],$reg['nserver']); - unset($reg['nserver']); - } - - $r['regrinfo'] = $reg; - $r['regyinfo'] = array( - 'referrer' => 'http://www.nic.fr', - 'registrar' => 'AFNIC' - ); - return $r; - } - } + 'fax', + 'e-mail' => 'email', + 'nic-hdl' => 'handle', + 'ns-list' => 'handle', + 'person' => 'name', + 'address' => 'address.', + 'descr' => 'desc', + 'anniversary' => '', + 'domain' => '', + 'last-update' => 'changed', + 'registered' => 'created', + 'country' => 'address.country', + 'registrar' => 'sponsor', + 'role' => 'organization' + ); + + $contacts = array( + 'admin-c' => 'admin', + 'tech-c' => 'tech', + 'zone-c' => 'zone', + 'holder-c' => 'owner', + 'nsl-id' => 'nserver' + ); + + $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain','dmY'); + + if (isset($reg['nserver'])) + { + $reg['domain'] = array_merge($reg['domain'],$reg['nserver']); + unset($reg['nserver']); + } + + $r['regrinfo'] = $reg; + $r['regyinfo'] = array( + 'referrer' => 'http://www.nic.fr', + 'registrar' => 'AFNIC' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.ws.php b/classes/whois.ws.php similarity index 96% rename from whois.ws.php rename to classes/whois.ws.php index 5e8e0e1..ffedcaf 100644 --- a/whois.ws.php +++ b/classes/whois.ws.php @@ -1,76 +1,76 @@ - 'domain.name', - 'Registrant Name:' => 'owner.organization', - 'Registrant Email:' => 'owner.email', - 'Domain Created:' => 'domain.created', - 'Domain Last Updated:' => 'domain.changed', - 'Registrar Name:' => 'domain.sponsor', - 'Current Nameservers:' => 'domain.nserver.', - 'Administrative Contact Email:' => 'admin.email', - 'Administrative Contact Telephone:' => 'admin.phone', - 'Registrar Whois:' => 'rwhois' - ); - - $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items, 'ymd'); - - $r['regyinfo']['referrer'] = 'http://www.samoanic.ws'; - $r['regyinfo']['registrar'] = 'Samoa Nic'; - - if (!empty($r['regrinfo']['domain']['name'])) - { - $r['regrinfo']['registered'] = 'yes'; - - if (isset($r['regrinfo']['rwhois'])) - { - if ($this->deep_whois) - { - $r['regyinfo']['whois'] = $r['regrinfo']['rwhois']; - $r = $this->DeepWhois($query,$r); - } - - unset($r['regrinfo']['rwhois']); - } - } - else - $r['regrinfo']['registered'] = 'no'; - - return $r; - } - } + 'domain.name', + 'Registrant Name:' => 'owner.organization', + 'Registrant Email:' => 'owner.email', + 'Domain Created:' => 'domain.created', + 'Domain Last Updated:' => 'domain.changed', + 'Registrar Name:' => 'domain.sponsor', + 'Current Nameservers:' => 'domain.nserver.', + 'Administrative Contact Email:' => 'admin.email', + 'Administrative Contact Telephone:' => 'admin.phone', + 'Registrar Whois:' => 'rwhois' + ); + + $r['regrinfo'] = generic_parser_b($data_str['rawdata'], $items, 'ymd'); + + $r['regyinfo']['referrer'] = 'http://www.samoanic.ws'; + $r['regyinfo']['registrar'] = 'Samoa Nic'; + + if (!empty($r['regrinfo']['domain']['name'])) + { + $r['regrinfo']['registered'] = 'yes'; + + if (isset($r['regrinfo']['rwhois'])) + { + if ($this->deep_whois) + { + $r['regyinfo']['whois'] = $r['regrinfo']['rwhois']; + $r = $this->DeepWhois($query,$r); + } + + unset($r['regrinfo']['rwhois']); + } + } + else + $r['regrinfo']['registered'] = 'no'; + + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.xxx.php b/classes/whois.xxx.php similarity index 100% rename from whois.xxx.php rename to classes/whois.xxx.php diff --git a/whois.yt.php b/classes/whois.yt.php similarity index 96% rename from whois.yt.php rename to classes/whois.yt.php index d9b943e..c1f0e53 100644 --- a/whois.yt.php +++ b/classes/whois.yt.php @@ -1,78 +1,78 @@ - 'fax', - 'e-mail' => 'email', - 'nic-hdl' => 'handle', - 'ns-list' => 'handle', - 'person' => 'name', - 'address' => 'address.', - 'descr' => 'desc', - 'anniversary' => '', - 'domain' => '', - 'last-update' => 'changed', - 'registered' => 'created', - 'country' => 'address.country', - 'registrar' => 'sponsor', - 'role' => 'organization' - ); - - $contacts = array( - 'admin-c' => 'admin', - 'tech-c' => 'tech', - 'zone-c' => 'zone', - 'holder-c' => 'owner', - 'nsl-id' => 'nserver' - ); - - $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain','dmY'); - - if (isset($reg['nserver'])) - { - $reg['domain'] = array_merge($reg['domain'],$reg['nserver']); - unset($reg['nserver']); - } - - $r['regrinfo'] = $reg; - $r['regyinfo'] = array( - 'referrer' => 'http://www.nic.fr', - 'registrar' => 'AFNIC' - ); - return $r; - } - } + 'fax', + 'e-mail' => 'email', + 'nic-hdl' => 'handle', + 'ns-list' => 'handle', + 'person' => 'name', + 'address' => 'address.', + 'descr' => 'desc', + 'anniversary' => '', + 'domain' => '', + 'last-update' => 'changed', + 'registered' => 'created', + 'country' => 'address.country', + 'registrar' => 'sponsor', + 'role' => 'organization' + ); + + $contacts = array( + 'admin-c' => 'admin', + 'tech-c' => 'tech', + 'zone-c' => 'zone', + 'holder-c' => 'owner', + 'nsl-id' => 'nserver' + ); + + $reg = generic_parser_a($data_str['rawdata'], $translate, $contacts, 'domain','dmY'); + + if (isset($reg['nserver'])) + { + $reg['domain'] = array_merge($reg['domain'],$reg['nserver']); + unset($reg['nserver']); + } + + $r['regrinfo'] = $reg; + $r['regyinfo'] = array( + 'referrer' => 'http://www.nic.fr', + 'registrar' => 'AFNIC' + ); + return $r; + } + } ?> \ No newline at end of file diff --git a/whois.zanet.php b/classes/whois.zanet.php old mode 100755 new mode 100644 similarity index 96% rename from whois.zanet.php rename to classes/whois.zanet.php index 58bfe5f..235b780 --- a/whois.zanet.php +++ b/classes/whois.zanet.php @@ -1,90 +1,90 @@ - 'Domain Name : ', - 'domain.created' => 'Record Created :', - 'domain.changed' => 'Record Last Updated :', - 'owner.name' => 'Registered for :', - 'admin' => 'Administrative Contact :', - 'tech' => 'Technical Contact :', - 'domain.nserver' => 'Domain Name Servers listed in order:', - 'registered' => 'No such domain: ', - '' => 'The ZA NiC whois' - ); - - // Arrange contacts ... - - $rawdata = array(); - - while (list($key, $line) = each($data_str['rawdata'])) - { - if (strpos($line, ' Contact ') !== false) - { - $pos = strpos($line, ':'); - - if ($pos !== false) - { - $rawdata[] = substr($line, 0, $pos + 1); - $rawdata[] = trim(substr($line, $pos + 1)); - continue; - } - } - $rawdata[] = $line; - } - - $r['regrinfo'] = get_blocks($rawdata, $items); - - if (isset($r['regrinfo']['registered'])) - { - $r['regrinfo']['registered'] = 'no'; - } - else - { - if (isset($r['regrinfo']['admin'])) - $r['regrinfo']['admin'] = get_contact($r['regrinfo']['admin']); - - if (isset($r['regrinfo']['tech'])) - $r['regrinfo']['tech'] = get_contact($r['regrinfo']['tech']); - } - - $r['regyinfo']['referrer'] = 'http://www.za.net/'; // or http://www.za.org - $r['regyinfo']['registrar'] = 'ZA NiC'; - format_dates($r, 'xmdxxy'); - return $r; - } - } + 'Domain Name : ', + 'domain.created' => 'Record Created :', + 'domain.changed' => 'Record Last Updated :', + 'owner.name' => 'Registered for :', + 'admin' => 'Administrative Contact :', + 'tech' => 'Technical Contact :', + 'domain.nserver' => 'Domain Name Servers listed in order:', + 'registered' => 'No such domain: ', + '' => 'The ZA NiC whois' + ); + + // Arrange contacts ... + + $rawdata = array(); + + while (list($key, $line) = each($data_str['rawdata'])) + { + if (strpos($line, ' Contact ') !== false) + { + $pos = strpos($line, ':'); + + if ($pos !== false) + { + $rawdata[] = substr($line, 0, $pos + 1); + $rawdata[] = trim(substr($line, $pos + 1)); + continue; + } + } + $rawdata[] = $line; + } + + $r['regrinfo'] = get_blocks($rawdata, $items); + + if (isset($r['regrinfo']['registered'])) + { + $r['regrinfo']['registered'] = 'no'; + } + else + { + if (isset($r['regrinfo']['admin'])) + $r['regrinfo']['admin'] = get_contact($r['regrinfo']['admin']); + + if (isset($r['regrinfo']['tech'])) + $r['regrinfo']['tech'] = get_contact($r['regrinfo']['tech']); + } + + $r['regyinfo']['referrer'] = 'http://www.za.net/'; // or http://www.za.org + $r['regyinfo']['registrar'] = 'ZA NiC'; + format_dates($r, 'xmdxxy'); + return $r; + } + } ?> \ No newline at end of file diff --git a/css/app.css b/css/app.css new file mode 100644 index 0000000..78df995 --- /dev/null +++ b/css/app.css @@ -0,0 +1,127 @@ +@import url(https://fonts.googleapis.com/css?family=Source+Code+Pro:500,600,700,400); +body { + font-family: 'Source Code Pro', cursive; + overflow-x: hidden; +} +h1, h2, h3, h4, h5, h6 { + font-family: 'Source Code Pro', cursive; + text-align: center; +} +h1#page-title { + font-weight: 700; + text-align: center; +} +h5 { + text-decoration: underline; +} +p { + font-family: 'Source Code Pro', cursive; + margin-top: 1rem; + text-align: center; +} +p.help-text { + text-align: left; + margin-bottom: 0rem; +} +.button.expand { + display: block; + width: 100%; +} +.no-padding { + padding: 0; +} +body div .no-padding, +body div.no-padding { + padding: 0; +} +.row, +.row .row { + margin: 0 auto; + max-width: 100%; +} +body div div#query-results-sidebar { + padding: 0; +} +.row .columns, +.row .row .columns, +.row .row .row .columns { + padding: 0; +} +.error { + display: none; +} +.fieldset { + padding: 0.75rem; + border: none; + margin: 0; +} +.fieldset b { + text-indent: 1rem; +} +.error { + display: none; +} +/* Browser specific (not valid) styles to make preformatted text wrap */ + +pre { + white-space: pre-wrap; /* css-3 */ + white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + word-wrap: break-word; /* Internet Explorer 5.5+ */ +} +.hide-by-default { + display: none; +} +.dinsly-item { + margin-top: 1rem; +} +@media(min-width:40.063em) { + .dinsly-item { + margin-top: 0.5rem; + } +} + + + +/* +Generic Styling, for Desktops/Laptops +*/ +table { + width: 100%; + border-collapse: collapse; +} +thead { + display: none; +} +/* Zebra striping */ +tr:nth-of-type(odd) { + background: #eee; +} +th { + background: #333; + color: white; + font-weight: bold; +} +td, th { + padding: 6px; + border: 1px solid #ccc; + text-align: left; +} +#map_container{ + position: relative; + padding-top: 24px; +} +@media(max-width: 40em) { + body div div#query-results { + padding: 0 1rem; + } +} +/* +#map{ + height: 0; + overflow: hidden; + padding-bottom: 22.25%; + padding-top: 30px; + position: relative; +}*/ \ No newline at end of file diff --git a/css/foundation.css b/css/foundation.css new file mode 100644 index 0000000..eba42b4 --- /dev/null +++ b/css/foundation.css @@ -0,0 +1,3174 @@ +@charset "UTF-8"; +/** + * Foundation for Sites by ZURB + * Version 6.0.5 + * foundation.zurb.com + * Licensed under MIT Open Source + */ +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS and IE text size adjust after device orientation change, + * without disabling user zoom. + */ +html { + font-family: sans-serif; + /* 1 */ + -ms-text-size-adjust: 100%; + /* 2 */ + -webkit-text-size-adjust: 100%; + /* 2 */ } + +/** + * Remove default margin. + */ +body { + margin: 0; } + +/* HTML5 display definitions + ========================================================================== */ +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. + */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; } + +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + */ +audio, +canvas, +progress, +video { + display: inline-block; + /* 1 */ + vertical-align: baseline; + /* 2 */ } + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ +audio:not([controls]) { + display: none; + height: 0; } + +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22. + */ +[hidden], +template { + display: none; } + +/* Links + ========================================================================== */ +/** + * Remove the gray background color from active links in IE 10. + */ +a { + background-color: transparent; } + +/** + * Improve readability of focused elements when they are also in an + * active/hover state. + */ +a:active, +a:hover { + outline: 0; } + +/* Text-level semantics + ========================================================================== */ +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + */ +abbr[title] { + border-bottom: 1px dotted; } + +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ +b, +strong { + font-weight: bold; } + +/** + * Address styling not present in Safari and Chrome. + */ +dfn { + font-style: italic; } + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. + */ +h1 { + font-size: 2em; + margin: 0.67em 0; } + +/** + * Address styling not present in IE 8/9. + */ +mark { + background: #ff0; + color: #000; } + +/** + * Address inconsistent and variable font size in all browsers. + */ +small { + font-size: 80%; } + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } + +sup { + top: -0.5em; } + +sub { + bottom: -0.25em; } + +/* Embedded content + ========================================================================== */ +/** + * Remove border when inside `a` element in IE 8/9/10. + */ +img { + border: 0; } + +/** + * Correct overflow not hidden in IE 9/10/11. + */ +svg:not(:root) { + overflow: hidden; } + +/* Grouping content + ========================================================================== */ +/** + * Address margin not present in IE 8/9 and Safari. + */ +figure { + margin: 1em 40px; } + +/** + * Address differences between Firefox and other browsers. + */ +hr { + box-sizing: content-box; + height: 0; } + +/** + * Contain overflow in all browsers. + */ +pre { + overflow: auto; } + +/** + * Address odd `em`-unit font size rendering in all browsers. + */ +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; } + +/* Forms + ========================================================================== */ +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ +button, +input, +optgroup, +select, +textarea { + color: inherit; + /* 1 */ + font: inherit; + /* 2 */ + margin: 0; + /* 3 */ } + +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ +button { + overflow: visible; } + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. + */ +button, +select { + text-transform: none; } + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + /* 2 */ + cursor: pointer; + /* 3 */ } + +/** + * Re-set default cursor for disabled elements. + */ +button[disabled], +html input[disabled] { + cursor: default; } + +/** + * Remove inner padding and border in Firefox 4+. + */ +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; } + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ +input { + line-height: normal; } + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; + /* 1 */ + padding: 0; + /* 2 */ } + +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; } + +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome. + */ +input[type="search"] { + -webkit-appearance: textfield; + /* 1 */ + box-sizing: content-box; + /* 2 */ } + +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). + */ +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; } + +/** + * Define consistent border, margin, and padding. + */ +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; } + +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ +legend { + border: 0; + /* 1 */ + padding: 0; + /* 2 */ } + +/** + * Remove default vertical scrollbar in IE 8/9/10/11. + */ +textarea { + overflow: auto; } + +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ +optgroup { + font-weight: bold; } + +/* Tables + ========================================================================== */ +/** + * Remove most spacing between table cells. + */ +table { + border-collapse: collapse; + border-spacing: 0; } + +td, +th { + padding: 0; } + +.foundation-mq { + font-family: "small=0em&medium=40em&large=64em&xlarge=75em&xxlarge=90em"; } + +html, +body { + font-size: 100%; + box-sizing: border-box; } + +*, +*:before, +*:after { + box-sizing: inherit; } + +body { + padding: 0; + margin: 0; + font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; + font-weight: normal; + line-height: 1.5; + color: #0a0a0a; + background: #fefefe; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } + +img { + max-width: 100%; + height: auto; + -ms-interpolation-mode: bicubic; + display: inline-block; + vertical-align: middle; } + +textarea { + height: auto; + min-height: 50px; + border-radius: 0; } + +select { + width: 100%; + border-radius: 0; } + +#map_canvas img, +#map_canvas embed, +#map_canvas object, +.map_canvas img, +.map_canvas embed, +.map_canvas object, +.mqa-display img, +.mqa-display embed, +.mqa-display object { + max-width: none !important; } + +button { + -webkit-appearance: none; + -moz-appearance: none; + background: transparent; + padding: 0; + border: 0; + border-radius: 0; + line-height: 1; } + +.row { + max-width: 75rem; + margin-left: auto; + margin-right: auto; } + .row::before, .row::after { + content: ' '; + display: table; } + .row::after { + clear: both; } + .row.collapse > .column, .row.collapse > .columns { + padding-left: 0; + padding-right: 0; } + .row .row { + margin-left: -0.9375rem; + margin-right: -0.9375rem; } + .row .row.collapse { + margin-left: 0; + margin-right: 0; } + .row.small-collapse > .column, .row.small-collapse > .columns { + padding-left: 0; + padding-right: 0; } + .row.small-uncollapse > .column, .row.small-uncollapse > .columns { + padding-left: 30px; + padding-right: 30px; } + @media screen and (min-width: 40em) { + .row.medium-collapse > .column, .row.medium-collapse > .columns { + padding-left: 0; + padding-right: 0; } + .row.medium-uncollapse > .column, .row.medium-uncollapse > .columns { + padding-left: 30px; + padding-right: 30px; } } + @media screen and (min-width: 64em) { + .row.large-collapse > .column, .row.large-collapse > .columns { + padding-left: 0; + padding-right: 0; } + .row.large-uncollapse > .column, .row.large-uncollapse > .columns { + padding-left: 30px; + padding-right: 30px; } } + .row.expanded { + max-width: none; } + +.column, .columns { + width: 100%; + float: left; + padding-left: 0.9375rem; + padding-right: 0.9375rem; } + .column:last-child:not(:first-child), .columns:last-child:not(:first-child) { + float: right; } + .column.end:last-child:last-child, .end.columns:last-child:last-child { + float: left; } + +.column.row.row, .row.row.columns { + float: none; } + .row .column.row.row, .row .row.row.columns { + padding-left: 0; + padding-right: 0; + margin-left: 0; + margin-right: 0; } + +.small-1 { + width: 8.33333%; } + +.small-push-1 { + position: relative; + left: 8.33333%; } + +.small-pull-1 { + position: relative; + left: -8.33333%; } + +.small-offset-0 { + margin-left: 0%; } + +.small-2 { + width: 16.66667%; } + +.small-push-2 { + position: relative; + left: 16.66667%; } + +.small-pull-2 { + position: relative; + left: -16.66667%; } + +.small-offset-1 { + margin-left: 8.33333%; } + +.small-3 { + width: 25%; } + +.small-push-3 { + position: relative; + left: 25%; } + +.small-pull-3 { + position: relative; + left: -25%; } + +.small-offset-2 { + margin-left: 16.66667%; } + +.small-4 { + width: 33.33333%; } + +.small-push-4 { + position: relative; + left: 33.33333%; } + +.small-pull-4 { + position: relative; + left: -33.33333%; } + +.small-offset-3 { + margin-left: 25%; } + +.small-5 { + width: 41.66667%; } + +.small-push-5 { + position: relative; + left: 41.66667%; } + +.small-pull-5 { + position: relative; + left: -41.66667%; } + +.small-offset-4 { + margin-left: 33.33333%; } + +.small-6 { + width: 50%; } + +.small-push-6 { + position: relative; + left: 50%; } + +.small-pull-6 { + position: relative; + left: -50%; } + +.small-offset-5 { + margin-left: 41.66667%; } + +.small-7 { + width: 58.33333%; } + +.small-push-7 { + position: relative; + left: 58.33333%; } + +.small-pull-7 { + position: relative; + left: -58.33333%; } + +.small-offset-6 { + margin-left: 50%; } + +.small-8 { + width: 66.66667%; } + +.small-push-8 { + position: relative; + left: 66.66667%; } + +.small-pull-8 { + position: relative; + left: -66.66667%; } + +.small-offset-7 { + margin-left: 58.33333%; } + +.small-9 { + width: 75%; } + +.small-push-9 { + position: relative; + left: 75%; } + +.small-pull-9 { + position: relative; + left: -75%; } + +.small-offset-8 { + margin-left: 66.66667%; } + +.small-10 { + width: 83.33333%; } + +.small-push-10 { + position: relative; + left: 83.33333%; } + +.small-pull-10 { + position: relative; + left: -83.33333%; } + +.small-offset-9 { + margin-left: 75%; } + +.small-11 { + width: 91.66667%; } + +.small-push-11 { + position: relative; + left: 91.66667%; } + +.small-pull-11 { + position: relative; + left: -91.66667%; } + +.small-offset-10 { + margin-left: 83.33333%; } + +.small-12 { + width: 100%; } + +.small-offset-11 { + margin-left: 91.66667%; } + +.small-up-1 > .column, .small-up-1 > .columns { + width: 100%; + float: left; } + .small-up-1 > .column:nth-of-type(1n), .small-up-1 > .columns:nth-of-type(1n) { + clear: none; } + .small-up-1 > .column:nth-of-type(1n+1), .small-up-1 > .columns:nth-of-type(1n+1) { + clear: both; } + .small-up-1 > .column:last-child, .small-up-1 > .columns:last-child { + float: left; } + +.small-up-2 > .column, .small-up-2 > .columns { + width: 50%; + float: left; } + .small-up-2 > .column:nth-of-type(1n), .small-up-2 > .columns:nth-of-type(1n) { + clear: none; } + .small-up-2 > .column:nth-of-type(2n+1), .small-up-2 > .columns:nth-of-type(2n+1) { + clear: both; } + .small-up-2 > .column:last-child, .small-up-2 > .columns:last-child { + float: left; } + +.small-up-3 > .column, .small-up-3 > .columns { + width: 33.33333%; + float: left; } + .small-up-3 > .column:nth-of-type(1n), .small-up-3 > .columns:nth-of-type(1n) { + clear: none; } + .small-up-3 > .column:nth-of-type(3n+1), .small-up-3 > .columns:nth-of-type(3n+1) { + clear: both; } + .small-up-3 > .column:last-child, .small-up-3 > .columns:last-child { + float: left; } + +.small-up-4 > .column, .small-up-4 > .columns { + width: 25%; + float: left; } + .small-up-4 > .column:nth-of-type(1n), .small-up-4 > .columns:nth-of-type(1n) { + clear: none; } + .small-up-4 > .column:nth-of-type(4n+1), .small-up-4 > .columns:nth-of-type(4n+1) { + clear: both; } + .small-up-4 > .column:last-child, .small-up-4 > .columns:last-child { + float: left; } + +.small-up-5 > .column, .small-up-5 > .columns { + width: 20%; + float: left; } + .small-up-5 > .column:nth-of-type(1n), .small-up-5 > .columns:nth-of-type(1n) { + clear: none; } + .small-up-5 > .column:nth-of-type(5n+1), .small-up-5 > .columns:nth-of-type(5n+1) { + clear: both; } + .small-up-5 > .column:last-child, .small-up-5 > .columns:last-child { + float: left; } + +.small-up-6 > .column, .small-up-6 > .columns { + width: 16.66667%; + float: left; } + .small-up-6 > .column:nth-of-type(1n), .small-up-6 > .columns:nth-of-type(1n) { + clear: none; } + .small-up-6 > .column:nth-of-type(6n+1), .small-up-6 > .columns:nth-of-type(6n+1) { + clear: both; } + .small-up-6 > .column:last-child, .small-up-6 > .columns:last-child { + float: left; } + +.small-up-7 > .column, .small-up-7 > .columns { + width: 14.28571%; + float: left; } + .small-up-7 > .column:nth-of-type(1n), .small-up-7 > .columns:nth-of-type(1n) { + clear: none; } + .small-up-7 > .column:nth-of-type(7n+1), .small-up-7 > .columns:nth-of-type(7n+1) { + clear: both; } + .small-up-7 > .column:last-child, .small-up-7 > .columns:last-child { + float: left; } + +.small-up-8 > .column, .small-up-8 > .columns { + width: 12.5%; + float: left; } + .small-up-8 > .column:nth-of-type(1n), .small-up-8 > .columns:nth-of-type(1n) { + clear: none; } + .small-up-8 > .column:nth-of-type(8n+1), .small-up-8 > .columns:nth-of-type(8n+1) { + clear: both; } + .small-up-8 > .column:last-child, .small-up-8 > .columns:last-child { + float: left; } + +.column.small-centered, .small-centered.columns { + float: none; + margin-left: auto; + margin-right: auto; } + +.small-uncenter, +.small-push-0, +.small-pull-0 { + position: static; + margin-left: 0; + margin-right: 0; } + +@media screen and (min-width: 40em) { + .medium-1 { + width: 8.33333%; } + .medium-push-1 { + position: relative; + left: 8.33333%; } + .medium-pull-1 { + position: relative; + left: -8.33333%; } + .medium-offset-0 { + margin-left: 0%; } + .medium-2 { + width: 16.66667%; } + .medium-push-2 { + position: relative; + left: 16.66667%; } + .medium-pull-2 { + position: relative; + left: -16.66667%; } + .medium-offset-1 { + margin-left: 8.33333%; } + .medium-3 { + width: 25%; } + .medium-push-3 { + position: relative; + left: 25%; } + .medium-pull-3 { + position: relative; + left: -25%; } + .medium-offset-2 { + margin-left: 16.66667%; } + .medium-4 { + width: 33.33333%; } + .medium-push-4 { + position: relative; + left: 33.33333%; } + .medium-pull-4 { + position: relative; + left: -33.33333%; } + .medium-offset-3 { + margin-left: 25%; } + .medium-5 { + width: 41.66667%; } + .medium-push-5 { + position: relative; + left: 41.66667%; } + .medium-pull-5 { + position: relative; + left: -41.66667%; } + .medium-offset-4 { + margin-left: 33.33333%; } + .medium-6 { + width: 50%; } + .medium-push-6 { + position: relative; + left: 50%; } + .medium-pull-6 { + position: relative; + left: -50%; } + .medium-offset-5 { + margin-left: 41.66667%; } + .medium-7 { + width: 58.33333%; } + .medium-push-7 { + position: relative; + left: 58.33333%; } + .medium-pull-7 { + position: relative; + left: -58.33333%; } + .medium-offset-6 { + margin-left: 50%; } + .medium-8 { + width: 66.66667%; } + .medium-push-8 { + position: relative; + left: 66.66667%; } + .medium-pull-8 { + position: relative; + left: -66.66667%; } + .medium-offset-7 { + margin-left: 58.33333%; } + .medium-9 { + width: 75%; } + .medium-push-9 { + position: relative; + left: 75%; } + .medium-pull-9 { + position: relative; + left: -75%; } + .medium-offset-8 { + margin-left: 66.66667%; } + .medium-10 { + width: 83.33333%; } + .medium-push-10 { + position: relative; + left: 83.33333%; } + .medium-pull-10 { + position: relative; + left: -83.33333%; } + .medium-offset-9 { + margin-left: 75%; } + .medium-11 { + width: 91.66667%; } + .medium-push-11 { + position: relative; + left: 91.66667%; } + .medium-pull-11 { + position: relative; + left: -91.66667%; } + .medium-offset-10 { + margin-left: 83.33333%; } + .medium-12 { + width: 100%; } + .medium-offset-11 { + margin-left: 91.66667%; } + .medium-up-1 > .column, .medium-up-1 > .columns { + width: 100%; + float: left; } + .medium-up-1 > .column:nth-of-type(1n), .medium-up-1 > .columns:nth-of-type(1n) { + clear: none; } + .medium-up-1 > .column:nth-of-type(1n+1), .medium-up-1 > .columns:nth-of-type(1n+1) { + clear: both; } + .medium-up-1 > .column:last-child, .medium-up-1 > .columns:last-child { + float: left; } + .medium-up-2 > .column, .medium-up-2 > .columns { + width: 50%; + float: left; } + .medium-up-2 > .column:nth-of-type(1n), .medium-up-2 > .columns:nth-of-type(1n) { + clear: none; } + .medium-up-2 > .column:nth-of-type(2n+1), .medium-up-2 > .columns:nth-of-type(2n+1) { + clear: both; } + .medium-up-2 > .column:last-child, .medium-up-2 > .columns:last-child { + float: left; } + .medium-up-3 > .column, .medium-up-3 > .columns { + width: 33.33333%; + float: left; } + .medium-up-3 > .column:nth-of-type(1n), .medium-up-3 > .columns:nth-of-type(1n) { + clear: none; } + .medium-up-3 > .column:nth-of-type(3n+1), .medium-up-3 > .columns:nth-of-type(3n+1) { + clear: both; } + .medium-up-3 > .column:last-child, .medium-up-3 > .columns:last-child { + float: left; } + .medium-up-4 > .column, .medium-up-4 > .columns { + width: 25%; + float: left; } + .medium-up-4 > .column:nth-of-type(1n), .medium-up-4 > .columns:nth-of-type(1n) { + clear: none; } + .medium-up-4 > .column:nth-of-type(4n+1), .medium-up-4 > .columns:nth-of-type(4n+1) { + clear: both; } + .medium-up-4 > .column:last-child, .medium-up-4 > .columns:last-child { + float: left; } + .medium-up-5 > .column, .medium-up-5 > .columns { + width: 20%; + float: left; } + .medium-up-5 > .column:nth-of-type(1n), .medium-up-5 > .columns:nth-of-type(1n) { + clear: none; } + .medium-up-5 > .column:nth-of-type(5n+1), .medium-up-5 > .columns:nth-of-type(5n+1) { + clear: both; } + .medium-up-5 > .column:last-child, .medium-up-5 > .columns:last-child { + float: left; } + .medium-up-6 > .column, .medium-up-6 > .columns { + width: 16.66667%; + float: left; } + .medium-up-6 > .column:nth-of-type(1n), .medium-up-6 > .columns:nth-of-type(1n) { + clear: none; } + .medium-up-6 > .column:nth-of-type(6n+1), .medium-up-6 > .columns:nth-of-type(6n+1) { + clear: both; } + .medium-up-6 > .column:last-child, .medium-up-6 > .columns:last-child { + float: left; } + .medium-up-7 > .column, .medium-up-7 > .columns { + width: 14.28571%; + float: left; } + .medium-up-7 > .column:nth-of-type(1n), .medium-up-7 > .columns:nth-of-type(1n) { + clear: none; } + .medium-up-7 > .column:nth-of-type(7n+1), .medium-up-7 > .columns:nth-of-type(7n+1) { + clear: both; } + .medium-up-7 > .column:last-child, .medium-up-7 > .columns:last-child { + float: left; } + .medium-up-8 > .column, .medium-up-8 > .columns { + width: 12.5%; + float: left; } + .medium-up-8 > .column:nth-of-type(1n), .medium-up-8 > .columns:nth-of-type(1n) { + clear: none; } + .medium-up-8 > .column:nth-of-type(8n+1), .medium-up-8 > .columns:nth-of-type(8n+1) { + clear: both; } + .medium-up-8 > .column:last-child, .medium-up-8 > .columns:last-child { + float: left; } + .column.medium-centered, .medium-centered.columns { + float: none; + margin-left: auto; + margin-right: auto; } + .medium-uncenter, + .medium-push-0, + .medium-pull-0 { + position: static; + margin-left: 0; + margin-right: 0; } } + +@media screen and (min-width: 64em) { + .large-1 { + width: 8.33333%; } + .large-push-1 { + position: relative; + left: 8.33333%; } + .large-pull-1 { + position: relative; + left: -8.33333%; } + .large-offset-0 { + margin-left: 0%; } + .large-2 { + width: 16.66667%; } + .large-push-2 { + position: relative; + left: 16.66667%; } + .large-pull-2 { + position: relative; + left: -16.66667%; } + .large-offset-1 { + margin-left: 8.33333%; } + .large-3 { + width: 25%; } + .large-push-3 { + position: relative; + left: 25%; } + .large-pull-3 { + position: relative; + left: -25%; } + .large-offset-2 { + margin-left: 16.66667%; } + .large-4 { + width: 33.33333%; } + .large-push-4 { + position: relative; + left: 33.33333%; } + .large-pull-4 { + position: relative; + left: -33.33333%; } + .large-offset-3 { + margin-left: 25%; } + .large-5 { + width: 41.66667%; } + .large-push-5 { + position: relative; + left: 41.66667%; } + .large-pull-5 { + position: relative; + left: -41.66667%; } + .large-offset-4 { + margin-left: 33.33333%; } + .large-6 { + width: 50%; } + .large-push-6 { + position: relative; + left: 50%; } + .large-pull-6 { + position: relative; + left: -50%; } + .large-offset-5 { + margin-left: 41.66667%; } + .large-7 { + width: 58.33333%; } + .large-push-7 { + position: relative; + left: 58.33333%; } + .large-pull-7 { + position: relative; + left: -58.33333%; } + .large-offset-6 { + margin-left: 50%; } + .large-8 { + width: 66.66667%; } + .large-push-8 { + position: relative; + left: 66.66667%; } + .large-pull-8 { + position: relative; + left: -66.66667%; } + .large-offset-7 { + margin-left: 58.33333%; } + .large-9 { + width: 75%; } + .large-push-9 { + position: relative; + left: 75%; } + .large-pull-9 { + position: relative; + left: -75%; } + .large-offset-8 { + margin-left: 66.66667%; } + .large-10 { + width: 83.33333%; } + .large-push-10 { + position: relative; + left: 83.33333%; } + .large-pull-10 { + position: relative; + left: -83.33333%; } + .large-offset-9 { + margin-left: 75%; } + .large-11 { + width: 91.66667%; } + .large-push-11 { + position: relative; + left: 91.66667%; } + .large-pull-11 { + position: relative; + left: -91.66667%; } + .large-offset-10 { + margin-left: 83.33333%; } + .large-12 { + width: 100%; } + .large-offset-11 { + margin-left: 91.66667%; } + .large-up-1 > .column, .large-up-1 > .columns { + width: 100%; + float: left; } + .large-up-1 > .column:nth-of-type(1n), .large-up-1 > .columns:nth-of-type(1n) { + clear: none; } + .large-up-1 > .column:nth-of-type(1n+1), .large-up-1 > .columns:nth-of-type(1n+1) { + clear: both; } + .large-up-1 > .column:last-child, .large-up-1 > .columns:last-child { + float: left; } + .large-up-2 > .column, .large-up-2 > .columns { + width: 50%; + float: left; } + .large-up-2 > .column:nth-of-type(1n), .large-up-2 > .columns:nth-of-type(1n) { + clear: none; } + .large-up-2 > .column:nth-of-type(2n+1), .large-up-2 > .columns:nth-of-type(2n+1) { + clear: both; } + .large-up-2 > .column:last-child, .large-up-2 > .columns:last-child { + float: left; } + .large-up-3 > .column, .large-up-3 > .columns { + width: 33.33333%; + float: left; } + .large-up-3 > .column:nth-of-type(1n), .large-up-3 > .columns:nth-of-type(1n) { + clear: none; } + .large-up-3 > .column:nth-of-type(3n+1), .large-up-3 > .columns:nth-of-type(3n+1) { + clear: both; } + .large-up-3 > .column:last-child, .large-up-3 > .columns:last-child { + float: left; } + .large-up-4 > .column, .large-up-4 > .columns { + width: 25%; + float: left; } + .large-up-4 > .column:nth-of-type(1n), .large-up-4 > .columns:nth-of-type(1n) { + clear: none; } + .large-up-4 > .column:nth-of-type(4n+1), .large-up-4 > .columns:nth-of-type(4n+1) { + clear: both; } + .large-up-4 > .column:last-child, .large-up-4 > .columns:last-child { + float: left; } + .large-up-5 > .column, .large-up-5 > .columns { + width: 20%; + float: left; } + .large-up-5 > .column:nth-of-type(1n), .large-up-5 > .columns:nth-of-type(1n) { + clear: none; } + .large-up-5 > .column:nth-of-type(5n+1), .large-up-5 > .columns:nth-of-type(5n+1) { + clear: both; } + .large-up-5 > .column:last-child, .large-up-5 > .columns:last-child { + float: left; } + .large-up-6 > .column, .large-up-6 > .columns { + width: 16.66667%; + float: left; } + .large-up-6 > .column:nth-of-type(1n), .large-up-6 > .columns:nth-of-type(1n) { + clear: none; } + .large-up-6 > .column:nth-of-type(6n+1), .large-up-6 > .columns:nth-of-type(6n+1) { + clear: both; } + .large-up-6 > .column:last-child, .large-up-6 > .columns:last-child { + float: left; } + .large-up-7 > .column, .large-up-7 > .columns { + width: 14.28571%; + float: left; } + .large-up-7 > .column:nth-of-type(1n), .large-up-7 > .columns:nth-of-type(1n) { + clear: none; } + .large-up-7 > .column:nth-of-type(7n+1), .large-up-7 > .columns:nth-of-type(7n+1) { + clear: both; } + .large-up-7 > .column:last-child, .large-up-7 > .columns:last-child { + float: left; } + .large-up-8 > .column, .large-up-8 > .columns { + width: 12.5%; + float: left; } + .large-up-8 > .column:nth-of-type(1n), .large-up-8 > .columns:nth-of-type(1n) { + clear: none; } + .large-up-8 > .column:nth-of-type(8n+1), .large-up-8 > .columns:nth-of-type(8n+1) { + clear: both; } + .large-up-8 > .column:last-child, .large-up-8 > .columns:last-child { + float: left; } + .column.large-centered, .large-centered.columns { + float: none; + margin-left: auto; + margin-right: auto; } + .large-uncenter, + .large-push-0, + .large-pull-0 { + position: static; + margin-left: 0; + margin-right: 0; } } + +div, +dl, +dt, +dd, +ul, +ol, +li, +h1, +h2, +h3, +h4, +h5, +h6, +pre, +form, +p, +blockquote, +th, +td { + margin: 0; + padding: 0; } + +p { + font-size: inherit; + line-height: 1.6; + margin-bottom: 1rem; + text-rendering: optimizeLegibility; } + +em, +i { + font-style: italic; + line-height: inherit; } + +strong, +b { + font-weight: bold; + line-height: inherit; } + +small { + font-size: 80%; + line-height: inherit; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; + font-weight: normal; + font-style: normal; + color: inherit; + text-rendering: optimizeLegibility; + margin-top: 0; + margin-bottom: 0.5rem; + line-height: 1.4; } + h1 small, + h2 small, + h3 small, + h4 small, + h5 small, + h6 small { + color: #cacaca; + line-height: 0; } + +h1 { + font-size: 1.5rem; } + +h2 { + font-size: 1.25rem; } + +h3 { + font-size: 1.1875rem; } + +h4 { + font-size: 1.125rem; } + +h5 { + font-size: 1.0625rem; } + +h6 { + font-size: 1rem; } + +@media screen and (min-width: 40em) { + h1 { + font-size: 3rem; } + h2 { + font-size: 2.5rem; } + h3 { + font-size: 1.9375rem; } + h4 { + font-size: 1.5625rem; } + h5 { + font-size: 1.25rem; } + h6 { + font-size: 1rem; } } + +a { + color: #2199e8; + text-decoration: none; + line-height: inherit; + cursor: pointer; } + a:hover, a:focus { + color: #1585cf; } + a img { + border: 0; } + +hr { + max-width: 75rem; + height: 0; + border-right: 0; + border-top: 0; + border-bottom: 1px solid #cacaca; + border-left: 0; + margin: 1.25rem auto; + clear: both; } + +ul, +ol, +dl { + line-height: 1.6; + margin-bottom: 1rem; + list-style-position: outside; } + +li { + font-size: inherit; } + +ul { + list-style-type: disc; + margin-left: 1.25rem; } + +ol { + margin-left: 1.25rem; } + +ul ul, ol ul, ul ol, ol ol { + margin-left: 1.25rem; + margin-bottom: 0; + list-style-type: inherit; } + +dl { + margin-bottom: 1rem; } + dl dt { + margin-bottom: 0.3rem; + font-weight: bold; } + +blockquote { + margin: 0 0 1rem; + padding: 0.5625rem 1.25rem 0 1.1875rem; + border-left: 1px solid #cacaca; } + blockquote, blockquote p { + line-height: 1.6; + color: #8a8a8a; } + +cite { + display: block; + font-size: 0.8125rem; + color: #8a8a8a; } + cite:before { + content: '\2014 \0020'; } + +abbr { + color: #0a0a0a; + cursor: help; + border-bottom: 1px dotted #0a0a0a; } + +code { + font-family: Consolas, "Liberation Mono", Courier, monospace; + font-weight: normal; + color: #0a0a0a; + background-color: #e6e6e6; + border: 1px solid #cacaca; + padding: 0.125rem 0.3125rem 0.0625rem; } + +kbd { + padding: 0.125rem 0.25rem 0; + margin: 0; + background-color: #e6e6e6; + color: #0a0a0a; + font-family: Consolas, "Liberation Mono", Courier, monospace; } + +.subheader { + margin-top: 0.2rem; + margin-bottom: 0.5rem; + font-weight: normal; + line-height: 1.4; + color: #8a8a8a; } + +.lead { + font-size: 125%; + line-height: 1.6; } + +.stat { + font-size: 2.5rem; + line-height: 1; } + p + .stat { + margin-top: -1rem; } + +.no-bullet { + margin-left: 0; + list-style: none; } + +.text-left { + text-align: left; } + +.text-right { + text-align: right; } + +.text-center { + text-align: center; } + +.text-justify { + text-align: justify; } + +@media screen and (min-width: 40em) { + .medium-text-left { + text-align: left; } + .medium-text-right { + text-align: right; } + .medium-text-center { + text-align: center; } + .medium-text-justify { + text-align: justify; } } + +@media screen and (min-width: 64em) { + .large-text-left { + text-align: left; } + .large-text-right { + text-align: right; } + .large-text-center { + text-align: center; } + .large-text-justify { + text-align: justify; } } + +.show-for-print { + display: none !important; } + +@media print { + * { + background: transparent !important; + color: black !important; + box-shadow: none !important; + text-shadow: none !important; } + .show-for-print { + display: block !important; } + .hide-for-print { + display: none !important; } + table.show-for-print { + display: table !important; } + thead.show-for-print { + display: table-header-group !important; } + tbody.show-for-print { + display: table-row-group !important; } + tr.show-for-print { + display: table-row !important; } + td.show-for-print { + display: table-cell !important; } + th.show-for-print { + display: table-cell !important; } + a, + a:visited { + text-decoration: underline; } + a[href]:after { + content: " (" attr(href) ")"; } + .ir a:after, + a[href^='javascript:']:after, + a[href^='#']:after { + content: ''; } + abbr[title]:after { + content: " (" attr(title) ")"; } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; } + thead { + display: table-header-group; } + tr, + img { + page-break-inside: avoid; } + img { + max-width: 100% !important; } + @page { + margin: 0.5cm; } + p, + h2, + h3 { + orphans: 3; + widows: 3; } + h2, + h3 { + page-break-after: avoid; } } + +.button { + display: inline-block; + text-align: center; + line-height: 1; + cursor: pointer; + -webkit-appearance: none; + transition: all 0.25s ease-out; + vertical-align: middle; + border: 1px solid transparent; + border-radius: 0; + padding: 0.85em 1em; + margin: 0 1rem 1rem 0; + font-size: 0.9rem; + background: #2199e8; + color: #fff; } + [data-whatinput='mouse'] .button { + outline: 0; } + .button:hover, .button:focus { + background: #1583cc; + color: #fff; } + .button.tiny { + font-size: 0.6rem; } + .button.small { + font-size: 0.75rem; } + .button.large { + font-size: 1.25rem; } + .button.expanded { + display: block; + width: 100%; + margin-left: 0; + margin-right: 0; } + .button.primary { + background: #2199e8; + color: #fff; } + .button.primary:hover, .button.primary:focus { + background: #147cc0; + color: #fff; } + .button.secondary { + background: #777; + color: #fff; } + .button.secondary:hover, .button.secondary:focus { + background: #5f5f5f; + color: #fff; } + .button.success { + background: #3adb76; + color: #fff; } + .button.success:hover, .button.success:focus { + background: #22bb5b; + color: #fff; } + .button.alert { + background: #ec5840; + color: #fff; } + .button.alert:hover, .button.alert:focus { + background: #da3116; + color: #fff; } + .button.warning { + background: #ffae00; + color: #fff; } + .button.warning:hover, .button.warning:focus { + background: #cc8b00; + color: #fff; } + .button.hollow { + border: 1px solid #2199e8; + color: #2199e8; } + .button.hollow, .button.hollow:hover, .button.hollow:focus { + background: transparent; } + .button.hollow:hover, .button.hollow:focus { + border-color: #0c4d78; + color: #0c4d78; } + .button.hollow.primary { + border: 1px solid #2199e8; + color: #2199e8; } + .button.hollow.primary:hover, .button.hollow.primary:focus { + border-color: #0c4d78; + color: #0c4d78; } + .button.hollow.secondary { + border: 1px solid #777; + color: #777; } + .button.hollow.secondary:hover, .button.hollow.secondary:focus { + border-color: #3c3c3c; + color: #3c3c3c; } + .button.hollow.success { + border: 1px solid #3adb76; + color: #3adb76; } + .button.hollow.success:hover, .button.hollow.success:focus { + border-color: #157539; + color: #157539; } + .button.hollow.alert { + border: 1px solid #ec5840; + color: #ec5840; } + .button.hollow.alert:hover, .button.hollow.alert:focus { + border-color: #881f0e; + color: #881f0e; } + .button.hollow.warning { + border: 1px solid #ffae00; + color: #ffae00; } + .button.hollow.warning:hover, .button.hollow.warning:focus { + border-color: #805700; + color: #805700; } + .button.disabled { + opacity: 0.25; + cursor: not-allowed; + pointer-events: none; } + .button.dropdown::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 0.4em; + border-color: #fefefe transparent transparent; + border-top-style: solid; + position: relative; + top: 0.4em; + float: right; + margin-left: 1em; + display: inline-block; } + .button.arrow-only::after { + margin-left: 0; + float: none; + top: 0.2em; } + +[type='text'], [type='password'], [type='date'], [type='datetime'], [type='datetime-local'], [type='month'], [type='week'], [type='email'], [type='number'], [type='search'], [type='tel'], [type='time'], [type='url'], [type='color'], +textarea { + display: block; + box-sizing: border-box; + width: 100%; + height: 2.4375rem; + padding: 0.5rem; + border: 1px solid #cacaca; + margin: 0 0 1rem; + font-family: inherit; + font-size: 1rem; + color: #0a0a0a; + background-color: #fefefe; + box-shadow: inset 0 1px 2px rgba(10, 10, 10, 0.1); + border-radius: 0; + transition: box-shadow 0.5s, border-color 0.25s ease-in-out; + -webkit-appearance: none; + -moz-appearance: none; } + [type='text']:focus, [type='password']:focus, [type='date']:focus, [type='datetime']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='week']:focus, [type='email']:focus, [type='number']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='url']:focus, [type='color']:focus, + textarea:focus { + border: 1px solid #8a8a8a; + background: #fefefe; + outline: none; + box-shadow: 0 0 5px #cacaca; + transition: box-shadow 0.5s, border-color 0.25s ease-in-out; } + +textarea { + max-width: 100%; } + textarea[rows] { + height: auto; } + +input:disabled, input[readonly], +textarea:disabled, +textarea[readonly] { + background-color: #e6e6e6; + cursor: default; } + +[type='submit'], +[type='button'] { + border-radius: 0; + -webkit-appearance: none; + -moz-appearance: none; } + +input[type='search'] { + box-sizing: border-box; } + +[type='file'], +[type='checkbox'], +[type='radio'] { + margin: 0 0 1rem; } + +[type='checkbox'] + label, +[type='radio'] + label { + display: inline-block; + margin-left: 0.5rem; + margin-right: 1rem; + margin-bottom: 0; + vertical-align: baseline; } + +label > [type='checkbox'], +label > [type='label'] { + margin-right: 0.5rem; } + +[type='file'] { + width: 100%; } + +label { + display: block; + margin: 0; + font-size: 0.875rem; + font-weight: normal; + line-height: 1.8; + color: #0a0a0a; } + label.middle { + margin: 0 0 1rem; + padding: 0.5625rem 0; } + +.help-text { + margin-top: -0.5rem; + font-size: 0.8125rem; + font-style: italic; + color: #333; } + +.input-group { + display: table; + width: 100%; + margin-bottom: 1rem; } + +.input-group-label, .input-group-field, .input-group-button { + display: table-cell; + margin: 0; + vertical-align: middle; } + +.input-group-label { + text-align: center; + width: 1%; + height: 100%; + padding: 0 1rem; + background: #e6e6e6; + color: #0a0a0a; + border: 1px solid #cacaca; } + .input-group-label:first-child { + border-right: 0; } + .input-group-label:last-child { + border-left: 0; } + +.input-group-button { + height: 100%; + padding-top: 0; + padding-bottom: 0; + text-align: center; + width: 1%; } + .input-group-button a, + .input-group-button input, + .input-group-button button { + margin: 0; } + +fieldset { + border: 0; + padding: 0; + margin: 0; } + +legend { + margin-bottom: 0.5rem; } + +.fieldset { + border: 1px solid #cacaca; + padding: 1.25rem; + margin: 1.125rem 0; } + .fieldset legend { + background: #fefefe; + padding: 0 0.1875rem; + margin: 0; + margin-left: -0.1875rem; } + +select { + height: 2.4375rem; + padding: 0.5rem; + border: 1px solid #cacaca; + border-radius: 0; + margin: 0 0 1rem; + font-size: 1rem; + font-family: inherit; + line-height: normal; + color: #0a0a0a; + background-color: #fafafa; + border-radius: 0; + -webkit-appearance: none; + -moz-appearance: none; + background-image: url('data:image/svg+xml;utf8,'); + background-size: 9px 6px; + background-position: right 0.5rem center; + background-repeat: no-repeat; } + @media screen and (min-width: 0\0) { + select { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAYCAYAAACbU/80AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIpJREFUeNrEkckNgDAMBBfRkEt0ObRBBdsGXUDgmQfK4XhH2m8czQAAy27R3tsw4Qfe2x8uOO6oYLb6GlOor3GF+swURAOmUJ+RwtEJs9WvTGEYxBXqI1MQAZhCfUQKRzDMVj+TwrAIV6jvSUEkYAr1LSkcyTBb/V+KYfX7xAeusq3sLDtGH3kEGACPWIflNZfhRQAAAABJRU5ErkJggg=="); } } + select:disabled { + background-color: #e6e6e6; + cursor: default; } + select::-ms-expand { + display: none; } + select[multiple] { + height: auto; } + +.is-invalid-input:not(:focus) { + background-color: rgba(236, 88, 64, 0.1); + border-color: #ec5840; } + +.is-invalid-label { + color: #ec5840; } + +.form-error { + display: none; + margin-top: -0.5rem; + margin-bottom: 1rem; + font-size: 0.75rem; + font-weight: bold; + color: #ec5840; } + .form-error.is-visible { + display: block; } + +.hide { + display: none !important; } + +.invisible { + visibility: hidden; } + +@media screen and (min-width: 0em) and (max-width: 39.9375em) { + .hide-for-small-only { + display: none !important; } } + +@media screen and (max-width: 0em), screen and (min-width: 40em) { + .show-for-small-only { + display: none !important; } } + +@media screen and (min-width: 40em) { + .hide-for-medium { + display: none !important; } } + +@media screen and (max-width: 39.9375em) { + .show-for-medium { + display: none !important; } } + +@media screen and (min-width: 40em) and (max-width: 63.9375em) { + .hide-for-medium-only { + display: none !important; } } + +@media screen and (max-width: 39.9375em), screen and (min-width: 64em) { + .show-for-medium-only { + display: none !important; } } + +@media screen and (min-width: 64em) { + .hide-for-large { + display: none !important; } } + +@media screen and (max-width: 63.9375em) { + .show-for-large { + display: none !important; } } + +@media screen and (min-width: 64em) and (max-width: 74.9375em) { + .hide-for-large-only { + display: none !important; } } + +@media screen and (max-width: 63.9375em), screen and (min-width: 75em) { + .show-for-large-only { + display: none !important; } } + +.show-for-sr, +.show-on-focus { + position: absolute !important; + width: 1px; + height: 1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); } + +.show-on-focus:active, .show-on-focus:focus { + position: static !important; + height: auto; + width: auto; + overflow: visible; + clip: auto; } + +.show-for-landscape, +.hide-for-portrait { + display: block !important; } + @media screen and (orientation: landscape) { + .show-for-landscape, + .hide-for-portrait { + display: block !important; } } + @media screen and (orientation: portrait) { + .show-for-landscape, + .hide-for-portrait { + display: none !important; } } + +.hide-for-landscape, +.show-for-portrait { + display: none !important; } + @media screen and (orientation: landscape) { + .hide-for-landscape, + .show-for-portrait { + display: none !important; } } + @media screen and (orientation: portrait) { + .hide-for-landscape, + .show-for-portrait { + display: block !important; } } + +.float-left { + float: left !important; } + +.float-right { + float: right !important; } + +.float-center { + display: block; + margin-left: auto; + margin-right: auto; } + +.clearfix::before, .clearfix::after { + content: ' '; + display: table; } + +.clearfix::after { + clear: both; } + +.accordion { + list-style-type: none; + background: #fefefe; + border: 1px solid #e6e6e6; + border-radius: 0; + margin-left: 0; } + +.accordion-title { + display: block; + padding: 1.25rem 1rem; + line-height: 1; + font-size: 0.75rem; + color: #2199e8; + position: relative; + border-bottom: 1px solid #e6e6e6; } + .accordion-title:hover, .accordion-title:focus { + background-color: #e6e6e6; } + :last-child > .accordion-title { + border-bottom-width: 0; } + .accordion-title::before { + content: '+'; + position: absolute; + right: 1rem; + top: 50%; + margin-top: -0.5rem; } + .is-active > .accordion-title::before { + content: '–'; } + +.accordion-content { + padding: 1.25rem 1rem; + display: none; + border-bottom: 1px solid #e6e6e6; } + +.is-accordion-submenu-parent > a { + position: relative; } + .is-accordion-submenu-parent > a::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 6px; + border-color: #2199e8 transparent transparent; + border-top-style: solid; + position: absolute; + top: 50%; + margin-top: -4px; + right: 1rem; } + +.is-accordion-submenu-parent[aria-expanded='true'] > a::after { + -webkit-transform-origin: 50% 50%; + -ms-transform-origin: 50% 50%; + transform-origin: 50% 50%; + -webkit-transform: scaleY(-1); + -ms-transform: scaleY(-1); + transform: scaleY(-1); } + +.badge { + display: inline-block; + padding: 0.3em; + min-width: 2.1em; + font-size: 0.6rem; + text-align: center; + border-radius: 50%; + background: #2199e8; + color: #fefefe; } + .badge.secondary { + background: #777; + color: #fefefe; } + .badge.success { + background: #3adb76; + color: #fefefe; } + .badge.alert { + background: #ec5840; + color: #fefefe; } + .badge.warning { + background: #ffae00; + color: #fefefe; } + +.breadcrumbs { + list-style: none; + margin: 0 0 1rem 0; } + .breadcrumbs::before, .breadcrumbs::after { + content: ' '; + display: table; } + .breadcrumbs::after { + clear: both; } + .breadcrumbs li { + float: left; + color: #0a0a0a; + font-size: 0.6875rem; + cursor: default; + text-transform: uppercase; } + .breadcrumbs li:not(:last-child)::after { + color: #cacaca; + content: "/"; + margin: 0 0.75rem; + position: relative; + top: 1px; + opacity: 1; } + .breadcrumbs a { + color: #2199e8; } + .breadcrumbs a:hover { + text-decoration: underline; } + .breadcrumbs .disabled { + color: #cacaca; } + +.button-group { + margin-bottom: 1rem; + font-size: 0.9rem; } + .button-group::before, .button-group::after { + content: ' '; + display: table; } + .button-group::after { + clear: both; } + .button-group .button { + float: left; + margin: 0; + font-size: inherit; } + .button-group .button:not(:last-child) { + border-right: 1px solid #fefefe; } + .button-group.tiny { + font-size: 0.6rem; } + .button-group.small { + font-size: 0.75rem; } + .button-group.large { + font-size: 1.25rem; } + .button-group.expanded .button:nth-last-child(2):first-child, + .button-group.expanded .button:nth-last-child(2):first-child ~ .button { + width: 50%; } + .button-group.expanded .button:nth-last-child(3):first-child, + .button-group.expanded .button:nth-last-child(3):first-child ~ .button { + width: 33.33333%; } + .button-group.expanded .button:nth-last-child(4):first-child, + .button-group.expanded .button:nth-last-child(4):first-child ~ .button { + width: 25%; } + .button-group.expanded .button:nth-last-child(5):first-child, + .button-group.expanded .button:nth-last-child(5):first-child ~ .button { + width: 20%; } + .button-group.expanded .button:nth-last-child(6):first-child, + .button-group.expanded .button:nth-last-child(6):first-child ~ .button { + width: 16.66667%; } + .button-group.primary .button { + background: #2199e8; + color: #fff; } + .button-group.primary .button:hover, .button-group.primary .button:focus { + background: #147cc0; + color: #fff; } + .button-group.secondary .button { + background: #777; + color: #fff; } + .button-group.secondary .button:hover, .button-group.secondary .button:focus { + background: #5f5f5f; + color: #fff; } + .button-group.success .button { + background: #3adb76; + color: #fff; } + .button-group.success .button:hover, .button-group.success .button:focus { + background: #22bb5b; + color: #fff; } + .button-group.alert .button { + background: #ec5840; + color: #fff; } + .button-group.alert .button:hover, .button-group.alert .button:focus { + background: #da3116; + color: #fff; } + .button-group.warning .button { + background: #ffae00; + color: #fff; } + .button-group.warning .button:hover, .button-group.warning .button:focus { + background: #cc8b00; + color: #fff; } + .button-group.stacked .button, .button-group.stacked-for-small .button { + width: 100%; + border-right: 0; } + @media screen and (min-width: 40em) { + .button-group.stacked-for-small .button { + width: auto; } + .button-group.stacked-for-small .button:not(:last-child) { + border-right: 1px solid #fefefe; } } + +.callout { + margin: 0 0 1rem 0; + padding: 1rem; + border: 1px solid rgba(10, 10, 10, 0.25); + border-radius: 0; + position: relative; + background-color: white; } + .callout > :first-child { + margin-top: 0; } + .callout > :last-child { + margin-bottom: 0; } + .callout.primary { + background-color: #def0fc; } + .callout.primary a { + color: #116ca8; } + .callout.primary a:hover { + color: #0a4063; } + .callout.secondary { + background-color: #ebebeb; } + .callout.success { + background-color: #e1faea; } + .callout.success a { + color: #1ea450; } + .callout.success a:hover { + color: #126330; } + .callout.alert { + background-color: #fce6e2; } + .callout.alert a { + color: #bf2b13; } + .callout.alert a:hover { + color: #791b0c; } + .callout.warning { + background-color: #fff3d9; } + .callout.warning a { + color: #b37a00; } + .callout.warning a:hover { + color: #664600; } + .callout.small { + padding-top: 0.5rem; + padding-right: 0.5rem; + padding-bottom: 0.5rem; + padding-left: 0.5rem; } + .callout.large { + padding-top: 3rem; + padding-right: 3rem; + padding-bottom: 3rem; + padding-left: 3rem; } + +.close-button { + position: absolute; + color: #8a8a8a; + right: 1rem; + top: 0.5rem; + font-size: 2em; + line-height: 1; + cursor: pointer; } + [data-whatinput='mouse'] .close-button { + outline: 0; } + .close-button:hover, .close-button:focus { + color: #0a0a0a; } + +.is-drilldown { + position: relative; + overflow: hidden; } + +.is-drilldown-submenu { + position: absolute; + top: 0; + left: 100%; + z-index: -1; + height: 100%; + width: 100%; + background: #fefefe; + transition: -webkit-transform 0.15s linear; + transition: transform 0.15s linear; } + .is-drilldown-submenu.is-active { + z-index: 1; + display: block; + -webkit-transform: translateX(-100%); + -ms-transform: translateX(-100%); + transform: translateX(-100%); } + .is-drilldown-submenu.is-closing { + -webkit-transform: translateX(100%); + -ms-transform: translateX(100%); + transform: translateX(100%); } + +.is-drilldown-submenu-parent > a { + position: relative; } + .is-drilldown-submenu-parent > a::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 6px; + border-color: transparent transparent transparent #2199e8; + border-left-style: solid; + position: absolute; + top: 50%; + margin-top: -6px; + right: 1rem; } + +.js-drilldown-back::before { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 6px; + border-color: transparent #2199e8 transparent transparent; + border-right-style: solid; + float: left; + margin-right: 0.75rem; + margin-left: 0.6rem; + margin-top: 14px; } + +.dropdown-pane { + background-color: #fefefe; + border: 1px solid #cacaca; + display: block; + padding: 1rem; + position: absolute; + visibility: hidden; + width: 300px; + z-index: 10; + border-radius: 0; } + .dropdown-pane.is-open { + visibility: visible; } + +.dropdown-pane.tiny { + width: 100px; } + +.dropdown-pane.small { + width: 200px; } + +.dropdown-pane.large { + width: 400px; } + +[data-whatinput='mouse'] .dropdown.menu a { + outline: 0; } + +.dropdown.menu .is-dropdown-submenu-parent { + position: relative; } + .dropdown.menu .is-dropdown-submenu-parent a::after { + float: right; + margin-top: 3px; + margin-left: 10px; } + .dropdown.menu .is-dropdown-submenu-parent.is-down-arrow a { + padding-right: 1.5rem; + position: relative; } + .dropdown.menu .is-dropdown-submenu-parent.is-down-arrow > a::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 5px; + border-color: #2199e8 transparent transparent; + border-top-style: solid; + position: absolute; + top: 12px; + right: 5px; } + .dropdown.menu .is-dropdown-submenu-parent.is-left-arrow > a::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 5px; + border-color: transparent #2199e8 transparent transparent; + border-right-style: solid; + float: left; + margin-left: 0; + margin-right: 10px; } + .dropdown.menu .is-dropdown-submenu-parent.is-right-arrow > a::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 5px; + border-color: transparent transparent transparent #2199e8; + border-left-style: solid; } + .dropdown.menu .is-dropdown-submenu-parent.is-left-arrow.opens-inner .submenu { + right: 0; + left: auto; } + .dropdown.menu .is-dropdown-submenu-parent.is-right-arrow.opens-inner .submenu { + left: 0; + right: auto; } + .dropdown.menu .is-dropdown-submenu-parent.opens-inner .submenu { + top: 100%; } + +.no-js .dropdown.menu ul { + display: none; } + +.dropdown.menu .submenu { + display: none; + position: absolute; + top: 0; + left: 100%; + min-width: 200px; + z-index: 1; + background: #fefefe; + border: 1px solid #cacaca; } + .dropdown.menu .submenu > li { + width: 100%; } + .dropdown.menu .submenu.first-sub { + top: 100%; + left: 0; + right: auto; } + .dropdown.menu .submenu:not(.js-dropdown-nohover) > .is-dropdown-submenu-parent:hover > .dropdown.menu .submenu, .dropdown.menu .submenu.js-dropdown-active { + display: block; } + +.dropdown.menu .is-dropdown-submenu-parent.opens-left .submenu { + left: auto; + right: 100%; } + +.dropdown.menu.align-right .submenu.first-sub { + top: 100%; + left: auto; + right: 0; } + +.is-dropdown-menu.vertical { + width: 100px; } + .is-dropdown-menu.vertical.align-right { + float: right; } + .is-dropdown-menu.vertical > li .submenu { + top: 0; + left: 100%; } + +.flex-video { + position: relative; + height: 0; + padding-top: 1.5625rem; + padding-bottom: 75%; + margin-bottom: 1rem; + overflow: hidden; } + .flex-video iframe, + .flex-video object, + .flex-video embed, + .flex-video video { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; } + .flex-video.widescreen { + padding-bottom: 56.25%; } + .flex-video.vimeo { + padding-top: 0; } + +.label { + display: inline-block; + padding: 0.33333rem 0.5rem; + font-size: 0.8rem; + line-height: 1; + white-space: nowrap; + cursor: default; + border-radius: 0; + background: #2199e8; + color: #fefefe; } + .label.secondary { + background: #777; + color: #fefefe; } + .label.success { + background: #3adb76; + color: #fefefe; } + .label.alert { + background: #ec5840; + color: #fefefe; } + .label.warning { + background: #ffae00; + color: #fefefe; } + +.media-object { + margin-bottom: 1rem; + display: block; } + .media-object img { + max-width: none; } + @media screen and (min-width: 0em) and (max-width: 39.9375em) { + .media-object.stack-for-small .media-object-section { + display: block; + padding: 0; + padding-bottom: 1rem; } + .media-object.stack-for-small .media-object-section img { + width: 100%; } } + +.media-object-section { + display: table-cell; + vertical-align: top; } + .media-object-section:first-child { + padding-right: 1rem; } + .media-object-section:last-child:not( + .media-object-section:first-child) { + padding-left: 1rem; } + .media-object-section.middle { + vertical-align: middle; } + .media-object-section.bottom { + vertical-align: bottom; } + +.menu { + margin: 0; + list-style-type: none; } + .menu > li { + display: table-cell; + vertical-align: middle; } + [data-whatinput='mouse'] .menu > li { + outline: 0; } + .menu > li:not(.menu-text) > a { + display: block; + padding: 0.7rem 1rem; + line-height: 1; } + .menu input, + .menu a, + .menu button { + margin-bottom: 0; } + .menu > li > a > img, + .menu > li > a > i { + vertical-align: middle; } + .menu > li > a > span { + vertical-align: middle; } + .menu > li > a > img, + .menu > li > a > i { + display: inline-block; + margin-right: 0.25rem; } + .menu > li { + display: table-cell; } + .menu.vertical > li { + display: block; } + @media screen and (min-width: 40em) { + .menu.medium-horizontal > li { + display: table-cell; } + .menu.medium-vertical > li { + display: block; } } + @media screen and (min-width: 64em) { + .menu.large-horizontal > li { + display: table-cell; } + .menu.large-vertical > li { + display: block; } } + .menu.simple a { + padding: 0; + margin-right: 1rem; } + .menu.align-right > li { + float: right; } + .menu.expanded { + display: table; + width: 100%; } + .menu.expanded > li:nth-last-child(2):first-child, + .menu.expanded > li:nth-last-child(2):first-child ~ li { + width: 50%; } + .menu.expanded > li:nth-last-child(3):first-child, + .menu.expanded > li:nth-last-child(3):first-child ~ li { + width: 33.33333%; } + .menu.expanded > li:nth-last-child(4):first-child, + .menu.expanded > li:nth-last-child(4):first-child ~ li { + width: 25%; } + .menu.expanded > li:nth-last-child(5):first-child, + .menu.expanded > li:nth-last-child(5):first-child ~ li { + width: 20%; } + .menu.expanded > li:nth-last-child(6):first-child, + .menu.expanded > li:nth-last-child(6):first-child ~ li { + width: 16.66667%; } + .menu.expanded > li:first-child:last-child { + width: 100%; } + .menu.icon-top > li > a { + text-align: center; } + .menu.icon-top > li > a > img, + .menu.icon-top > li > a > i { + display: block; + margin: 0 auto 0.25rem; } + .menu.nested { + margin-left: 1rem; } + +.menu-text { + font-weight: bold; + color: inherit; + line-height: 1; + padding-top: 0; + padding-bottom: 0; + padding: 0.7rem 1rem; } + +html, +body { + height: 100%; } + +.off-canvas-wrapper { + width: 100%; + overflow-x: hidden; + position: relative; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-overflow-scrolling: auto; } + +.off-canvas-wrapper-inner { + position: relative; + width: 100%; + transition: -webkit-transform 0.5s ease; + transition: transform 0.5s ease; } + .off-canvas-wrapper-inner::before, .off-canvas-wrapper-inner::after { + content: ' '; + display: table; } + .off-canvas-wrapper-inner::after { + clear: both; } + +.off-canvas-content, +.off-canvas-content { + min-height: 100%; + background: #fefefe; + transition: -webkit-transform 0.5s ease; + transition: transform 0.5s ease; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + z-index: 1; + box-shadow: 0 0 10px rgba(10, 10, 10, 0.5); } + +.js-off-canvas-exit { + display: none; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(254, 254, 254, 0.25); + cursor: pointer; + transition: background 0.5s ease; } + .is-off-canvas-open .js-off-canvas-exit { + display: block; } + +.off-canvas { + position: absolute; + background: #e6e6e6; + z-index: -1; + max-height: 100%; + overflow-y: auto; + -webkit-transform: translateX(0px); + -ms-transform: translateX(0px); + transform: translateX(0px); } + [data-whatinput='mouse'] .off-canvas { + outline: 0; } + .off-canvas.position-left { + left: -250px; + top: 0; + width: 250px; } + .is-open-left { + -webkit-transform: translateX(250px); + -ms-transform: translateX(250px); + transform: translateX(250px); } + .off-canvas.position-right { + right: -250px; + top: 0; + width: 250px; } + .is-open-right { + -webkit-transform: translateX(-250px); + -ms-transform: translateX(-250px); + transform: translateX(-250px); } + +@media screen and (min-width: 40em) { + .position-left.reveal-for-medium { + left: 0; + z-index: auto; + position: fixed; } + .position-left.reveal-for-medium ~ .off-canvas-content { + margin-left: 250px; } + .position-right.reveal-for-medium { + right: 0; + z-index: auto; + position: fixed; } + .position-right.reveal-for-medium ~ .off-canvas-content { + margin-right: 250px; } } + +@media screen and (min-width: 64em) { + .position-left.reveal-for-large { + left: 0; + z-index: auto; + position: fixed; } + .position-left.reveal-for-large ~ .off-canvas-content { + margin-left: 250px; } + .position-right.reveal-for-large { + right: 0; + z-index: auto; + position: fixed; } + .position-right.reveal-for-large ~ .off-canvas-content { + margin-right: 250px; } } + +.orbit { + position: relative; } + +.orbit-container { + position: relative; + margin: 0; + overflow: hidden; + list-style: none; } + +.orbit-slide { + width: 100%; + max-height: 100%; } + .orbit-slide.no-motionui.is-active { + top: 0; + left: 0; } + +.orbit-figure { + margin: 0; } + +.orbit-image { + margin: 0; + width: 100%; + max-width: 100%; } + +.orbit-caption { + position: absolute; + bottom: 0; + width: 100%; + padding: 1rem; + margin-bottom: 0; + color: #fefefe; + background-color: rgba(10, 10, 10, 0.5); } + +.orbit-previous, .orbit-next { + position: absolute; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); + z-index: 10; + padding: 1rem; + color: #fefefe; } + [data-whatinput='mouse'] .orbit-previous, [data-whatinput='mouse'] .orbit-next { + outline: 0; } + .orbit-previous:hover, .orbit-next:hover, .orbit-previous:active, .orbit-next:active, .orbit-previous:focus, .orbit-next:focus { + background-color: rgba(10, 10, 10, 0.5); } + +.orbit-previous { + left: 0; } + +.orbit-next { + left: auto; + right: 0; } + +.orbit-bullets { + position: relative; + margin-top: 0.8rem; + margin-bottom: 0.8rem; + text-align: center; } + [data-whatinput='mouse'] .orbit-bullets { + outline: 0; } + .orbit-bullets button { + width: 1.2rem; + height: 1.2rem; + margin: 0.1rem; + background-color: #cacaca; + border-radius: 50%; } + .orbit-bullets button:hover { + background-color: #8a8a8a; } + .orbit-bullets button.is-active { + background-color: #8a8a8a; } + +.pagination { + margin-left: 0; + margin-bottom: 1rem; } + .pagination::before, .pagination::after { + content: ' '; + display: table; } + .pagination::after { + clear: both; } + .pagination li { + font-size: 0.875rem; + margin-right: 0.0625rem; + display: none; + border-radius: 0; } + .pagination li:last-child, .pagination li:first-child { + display: inline-block; } + @media screen and (min-width: 40em) { + .pagination li { + display: inline-block; } } + .pagination a, + .pagination button { + color: #0a0a0a; + display: block; + padding: 0.1875rem 0.625rem; + border-radius: 0; } + .pagination a:hover, + .pagination button:hover { + background: #e6e6e6; } + .pagination .current { + padding: 0.1875rem 0.625rem; + background: #2199e8; + color: #fefefe; + cursor: default; } + .pagination .disabled { + padding: 0.1875rem 0.625rem; + color: #cacaca; + cursor: default; } + .pagination .disabled:hover { + background: transparent; } + .pagination .ellipsis::after { + content: '…'; + padding: 0.1875rem 0.625rem; + color: #0a0a0a; } + +.pagination-previous a::before, +.pagination-previous.disabled::before { + content: '«'; + display: inline-block; + margin-right: 0.5rem; } + +.pagination-next a::after, +.pagination-next.disabled::after { + content: '»'; + display: inline-block; + margin-left: 0.5rem; } + +.progress { + background-color: #cacaca; + height: 1rem; + margin-bottom: 1rem; + border-radius: 0; } + .progress.primary .progress-meter { + background-color: #2199e8; } + .progress.secondary .progress-meter { + background-color: #777; } + .progress.success .progress-meter { + background-color: #3adb76; } + .progress.alert .progress-meter { + background-color: #ec5840; } + .progress.warning .progress-meter { + background-color: #ffae00; } + +.progress-meter { + position: relative; + display: block; + width: 0%; + height: 100%; + background-color: #2199e8; + border-radius: 0; } + .progress-meter .progress-meter-text { + position: absolute; + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + margin: 0; + font-size: 0.75rem; + font-weight: bold; + color: #fefefe; + white-space: nowrap; } + +.slider { + position: relative; + height: 0.5rem; + margin-top: 1.25rem; + margin-bottom: 2.25rem; + background-color: #e6e6e6; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -ms-touch-action: none; + touch-action: none; } + +.slider-fill { + position: absolute; + top: 0; + left: 0; + display: inline-block; + max-width: 100%; + height: 0.5rem; + background-color: #cacaca; + transition: all 0.2s ease-in-out; } + .slider-fill.is-dragging { + transition: all 0s linear; } + +.slider-handle { + position: absolute; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); + position: absolute; + left: 0; + z-index: 1; + display: inline-block; + width: 1.4rem; + height: 1.4rem; + background-color: #2199e8; + transition: all 0.2s ease-in-out; + -ms-touch-action: manipulation; + touch-action: manipulation; + border-radius: 0; } + [data-whatinput='mouse'] .slider-handle { + outline: 0; } + .slider-handle:hover { + background-color: #1583cc; } + .slider-handle.is-dragging { + transition: all 0s linear; } + +.slider.disabled, +.slider[disabled] { + opacity: 0.25; + cursor: not-allowed; } + +.slider.vertical { + display: inline-block; + width: 0.5rem; + height: 12.5rem; + margin: 0 1.25rem; + -webkit-transform: scale(1, -1); + -ms-transform: scale(1, -1); + transform: scale(1, -1); } + .slider.vertical .slider-fill { + top: 0; + width: 0.5rem; + max-height: 100%; } + .slider.vertical .slider-handle { + position: absolute; + top: 0; + left: 50%; + width: 1.4rem; + height: 1.4rem; + -webkit-transform: translateX(-50%); + -ms-transform: translateX(-50%); + transform: translateX(-50%); } + +.sticky-container { + position: relative; } + +.sticky { + position: absolute; + z-index: 0; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); } + +.sticky.is-stuck { + position: fixed; + z-index: 5; } + .sticky.is-stuck.is-at-top { + top: 0; } + .sticky.is-stuck.is-at-bottom { + bottom: 0; } + +.sticky.is-anchored { + position: absolute; + left: auto; + right: auto; } + .sticky.is-anchored.is-at-bottom { + bottom: 0; } + +body.is-reveal-open { + overflow: hidden; } + +.reveal-overlay { + display: none; + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + z-index: 1005; + background-color: rgba(10, 10, 10, 0.45); + overflow-y: scroll; } + +.reveal { + display: none; + z-index: 1006; + padding: 1rem; + border: 1px solid #cacaca; + margin: 100px auto 0 auto; + background-color: #fefefe; + border-radius: 0; + position: absolute; + overflow-y: auto; } + [data-whatinput='mouse'] .reveal { + outline: 0; } + @media screen and (min-width: 40em) { + .reveal { + min-height: 0; } } + .reveal .column, .reveal .columns, + .reveal .columns { + min-width: 0; } + .reveal > :last-child { + margin-bottom: 0; } + @media screen and (min-width: 40em) { + .reveal { + width: 600px; + max-width: 75rem; } } + .reveal.collapse { + padding: 0; } + @media screen and (min-width: 40em) { + .reveal .reveal { + left: auto; + right: auto; + margin: 0 auto; } } + @media screen and (min-width: 40em) { + .reveal.tiny { + width: 30%; + max-width: 75rem; } } + @media screen and (min-width: 40em) { + .reveal.small { + width: 50%; + max-width: 75rem; } } + @media screen and (min-width: 40em) { + .reveal.large { + width: 90%; + max-width: 75rem; } } + .reveal.full { + top: 0; + left: 0; + width: 100%; + height: 100%; + height: 100vh; + min-height: 100vh; + max-width: none; + margin-left: 0; } + +.switch { + margin-bottom: 1rem; + outline: 0; + position: relative; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + color: #fefefe; + font-weight: bold; + font-size: 0.875rem; } + +.switch-input { + opacity: 0; + position: absolute; } + +.switch-paddle { + background: #cacaca; + cursor: pointer; + display: block; + position: relative; + width: 4rem; + height: 2rem; + transition: all 0.25s ease-out; + border-radius: 0; + color: inherit; + font-weight: inherit; } + input + .switch-paddle { + margin: 0; } + .switch-paddle::after { + background: #fefefe; + content: ''; + display: block; + position: absolute; + height: 1.5rem; + left: 0.25rem; + top: 0.25rem; + width: 1.5rem; + transition: all 0.25s ease-out; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + border-radius: 0; } + input:checked ~ .switch-paddle { + background: #2199e8; } + input:checked ~ .switch-paddle::after { + left: 2.25rem; } + [data-whatinput='mouse'] input:focus ~ .switch-paddle { + outline: 0; } + +.switch-active, .switch-inactive { + position: absolute; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); } + +.switch-active { + left: 8%; + display: none; } + input:checked + label > .switch-active { + display: block; } + +.switch-inactive { + right: 15%; } + input:checked + label > .switch-inactive { + display: none; } + +.switch.tiny .switch-paddle { + width: 3rem; + height: 1.5rem; + font-size: 0.625rem; } + +.switch.tiny .switch-paddle::after { + width: 1rem; + height: 1rem; } + +.switch.tiny input:checked ~ .switch-paddle:after { + left: 1.75rem; } + +.switch.small .switch-paddle { + width: 3.5rem; + height: 1.75rem; + font-size: 0.75rem; } + +.switch.small .switch-paddle::after { + width: 1.25rem; + height: 1.25rem; } + +.switch.small input:checked ~ .switch-paddle:after { + left: 2rem; } + +.switch.large .switch-paddle { + width: 5rem; + height: 2.5rem; + font-size: 1rem; } + +.switch.large .switch-paddle::after { + width: 2rem; + height: 2rem; } + +.switch.large input:checked ~ .switch-paddle:after { + left: 2.75rem; } + +table { + margin-bottom: 1rem; + border-radius: 0; } + thead, + tbody, + tfoot { + border: 1px solid #f1f1f1; + background-color: #fefefe; } + caption { + font-weight: bold; + padding: 0.5rem 0.625rem 0.625rem; } + thead, + tfoot { + background: #f8f8f8; + color: #0a0a0a; } + thead tr, + tfoot tr { + background: transparent; } + thead th, + thead td, + tfoot th, + tfoot td { + padding: 0.5rem 0.625rem 0.625rem; + font-weight: bold; + text-align: left; } + tbody tr:nth-child(even) { + background-color: #f1f1f1; } + tbody th, + tbody td { + padding: 0.5rem 0.625rem 0.625rem; } + +@media screen and (max-width: 63.9375em) { + table.stack thead { + display: none; } + table.stack tfoot { + display: none; } + table.stack tr, + table.stack th, + table.stack td { + display: block; } + table.stack td { + border-top: 0; } } + +table.scroll { + display: block; + width: 100%; + overflow-y: scroll; } + +table.hover tr:hover { + background-color: #f9f9f9; } + +table.hover tr:nth-of-type(even):hover { + background-color: #ececec; } + +.tabs { + margin: 0; + list-style-type: none; + background: #fefefe; + border: 1px solid #e6e6e6; } + .tabs::before, .tabs::after { + content: ' '; + display: table; } + .tabs::after { + clear: both; } + .tabs.simple > li > a { + padding: 0; } + .tabs.simple > li > a:hover { + background: transparent; } + .tabs.vertical > li { + width: auto; + float: none; + display: block; } + .tabs.primary { + background: #2199e8; } + .tabs.primary > li > a { + color: #fefefe; } + .tabs.primary > li > a:hover, .tabs.primary > li > a:focus { + background: #1893e4; } + +.tabs-title { + float: left; } + .tabs-title > a { + display: block; + padding: 1.25rem 1.5rem; + line-height: 1; + font-size: 12px; + color: #2199e8; } + .tabs-title > a:hover { + background: #fefefe; } + .tabs-title > a:focus, .tabs-title > a[aria-selected='true'] { + background: #e6e6e6; } + +.tabs-content { + background: #fefefe; + transition: all 0.5s ease; + border: 1px solid #e6e6e6; + border-top: 0; } + .tabs-content.vertical { + border: 1px solid #e6e6e6; + border-left: 0; } + +.tabs-panel { + display: none; + padding: 1rem; } + .tabs-panel.is-active { + display: block; } + +.thumbnail { + border: solid 4px #fefefe; + box-shadow: 0 0 0 1px rgba(10, 10, 10, 0.2); + display: inline-block; + line-height: 0; + max-width: 100%; + transition: box-shadow 200ms ease-out; + border-radius: 0; + margin-bottom: 1rem; } + .thumbnail:hover, .thumbnail:focus { + box-shadow: 0 0 6px 1px rgba(33, 153, 232, 0.5); } + +.title-bar { + background: #0a0a0a; + color: #fefefe; + padding: 0.5rem; } + .title-bar::before, .title-bar::after { + content: ' '; + display: table; } + .title-bar::after { + clear: both; } + .title-bar .menu-icon { + margin-left: 0.25rem; + margin-right: 0.5rem; } + +.title-bar-left { + float: left; } + +.title-bar-right { + float: right; + text-align: right; } + +.title-bar-title { + font-weight: bold; + vertical-align: middle; + display: inline-block; } + +.menu-icon { + position: relative; + display: inline-block; + vertical-align: middle; + cursor: pointer; + width: 20px; + height: 16px; } + .menu-icon::after { + content: ''; + position: absolute; + display: block; + width: 100%; + height: 2px; + background: #fefefe; + top: 0; + left: 0; + box-shadow: 0 7px 0 #fefefe, 0 14px 0 #fefefe; } + .menu-icon:hover::after { + background: #cacaca; + box-shadow: 0 7px 0 #cacaca, 0 14px 0 #cacaca; } + +.has-tip { + border-bottom: dotted 1px #8a8a8a; + font-weight: bold; + position: relative; + display: inline-block; + cursor: help; } + +.tooltip { + background-color: #0a0a0a; + color: #fefefe; + font-size: 80%; + padding: 0.75rem; + position: absolute; + z-index: 10; + top: calc(100% + 0.6495rem); + max-width: 10rem !important; + border-radius: 0; } + .tooltip::before { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 0.75rem; + border-color: transparent transparent #0a0a0a; + border-bottom-style: solid; + bottom: 100%; + position: absolute; + left: 50%; + -webkit-transform: translateX(-50%); + -ms-transform: translateX(-50%); + transform: translateX(-50%); } + .tooltip.top::before { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 0.75rem; + border-color: #0a0a0a transparent transparent; + border-top-style: solid; + top: 100%; + bottom: auto; } + .tooltip.left::before { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 0.75rem; + border-color: transparent transparent transparent #0a0a0a; + border-left-style: solid; + bottom: auto; + left: 100%; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); } + .tooltip.right::before { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 0.75rem; + border-color: transparent #0a0a0a transparent transparent; + border-right-style: solid; + bottom: auto; + left: auto; + right: 100%; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); } + +.top-bar { + padding: 0.5rem; } + .top-bar::before, .top-bar::after { + content: ' '; + display: table; } + .top-bar::after { + clear: both; } + .top-bar, + .top-bar ul { + background-color: #e6e6e6; } + .top-bar a { + color: #2199e8; } + .top-bar input { + width: 200px; + margin-right: 1rem; } + +@media screen and (min-width: 40em) { + .top-bar-left { + float: left; } + .top-bar-right { + float: right; } } diff --git a/css/foundation.min.css b/css/foundation.min.css new file mode 100644 index 0000000..4d8e698 --- /dev/null +++ b/css/foundation.min.css @@ -0,0 +1 @@ +@charset "UTF-8";/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */button,img,legend{border:0}body,button,legend{padding:0}.row.collapse>.column,.row.collapse>.columns,.row.small-collapse>.column,.row.small-collapse>.columns{padding-left:0;padding-right:0}.button.dropdown::after,.small-pull-1,.small-pull-10,.small-pull-11,.small-pull-2,.small-pull-3,.small-pull-4,.small-pull-5,.small-pull-6,.small-pull-7,.small-pull-8,.small-pull-9,.small-push-1,.small-push-10,.small-push-11,.small-push-2,.small-push-3,.small-push-4,.small-push-5,.small-push-7,.small-push-8,.small-push-9,sub,sup{position:relative}h1,h2,h3,h4,h5,h6,p{text-rendering:optimizeLegibility}.dropdown-pane,.invisible{visibility:hidden}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,optgroup,strong{font-weight:700}dfn{font-style:italic}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;vertical-align:baseline}.button,img{vertical-align:middle}sup{top:-.5em}sub{bottom:-.25em}.orbit-caption,.sticky.is-anchored.is-at-bottom,.sticky.is-stuck.is-at-bottom{bottom:0}img{max-width:100%;height:auto;-ms-interpolation-mode:bicubic;display:inline-block}svg:not(:root){overflow:hidden}figure{margin:1em 40px}pre,textarea{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}a,b,em,i,small,strong{line-height:inherit}dl,ol,p,ul{line-height:1.6}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}.foundation-mq{font-family:"small=0em&medium=40em&large=64em&xlarge=75em&xxlarge=90em"}body,h1,h2,h3,h4,h5,h6{font-family:"Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-weight:400}body,html{font-size:100%;box-sizing:border-box}*,:after,:before{box-sizing:inherit}body{margin:0;line-height:1.5;color:#0a0a0a;background:#fefefe;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}select{width:100%}#map_canvas embed,#map_canvas img,#map_canvas object,.map_canvas embed,.map_canvas img,.map_canvas object,.mqa-display embed,.mqa-display img,.mqa-display object{max-width:none!important}button{overflow:visible;-webkit-appearance:none;-moz-appearance:none;background:0 0;border-radius:0;line-height:1}.row{max-width:75rem;margin-left:auto;margin-right:auto}.row::after,.row::before{content:' ';display:table}.row::after{clear:both}.row .row{margin-left:-.9375rem;margin-right:-.9375rem}.row .row.collapse{margin-left:0;margin-right:0}.row.small-uncollapse>.column,.row.small-uncollapse>.columns{padding-left:30px;padding-right:30px}@media screen and (min-width:40em){.row.medium-collapse>.column,.row.medium-collapse>.columns{padding-left:0;padding-right:0}.row.medium-uncollapse>.column,.row.medium-uncollapse>.columns{padding-left:30px;padding-right:30px}}@media screen and (min-width:64em){.row.large-collapse>.column,.row.large-collapse>.columns{padding-left:0;padding-right:0}.row.large-uncollapse>.column,.row.large-uncollapse>.columns{padding-left:30px;padding-right:30px}}.row.expanded{max-width:none}.column,.columns{width:100%;float:left;padding-left:.9375rem;padding-right:.9375rem}.column:last-child:not(:first-child),.columns:last-child:not(:first-child){float:right}.column.end:last-child:last-child,.end.columns:last-child:last-child{float:left}.column.row.row,.row.row.columns{float:none}.row .column.row.row,.row .row.row.columns{padding-left:0;padding-right:0;margin-left:0;margin-right:0}.small-1{width:8.33333%}.small-push-1{left:8.33333%}.small-pull-1{left:-8.33333%}.small-offset-0{margin-left:0}.small-2{width:16.66667%}.small-push-2{left:16.66667%}.small-pull-2{left:-16.66667%}.small-offset-1{margin-left:8.33333%}.small-3{width:25%}.small-push-3{left:25%}.small-pull-3{left:-25%}.small-offset-2{margin-left:16.66667%}.small-4{width:33.33333%}.small-push-4{left:33.33333%}.small-pull-4{left:-33.33333%}.small-offset-3{margin-left:25%}.small-5{width:41.66667%}.small-push-5{left:41.66667%}.small-pull-5{left:-41.66667%}.small-offset-4{margin-left:33.33333%}.small-6{width:50%}.small-push-6{position:relative;left:50%}.small-pull-6{left:-50%}.small-offset-5{margin-left:41.66667%}.small-7{width:58.33333%}.small-push-7{left:58.33333%}.small-pull-7{left:-58.33333%}.small-offset-6{margin-left:50%}.small-8{width:66.66667%}.small-push-8{left:66.66667%}.small-pull-8{left:-66.66667%}.small-offset-7{margin-left:58.33333%}.small-9{width:75%}.small-push-9{left:75%}.small-pull-9{left:-75%}.small-offset-8{margin-left:66.66667%}.small-10{width:83.33333%}.small-push-10{left:83.33333%}.small-pull-10{left:-83.33333%}.small-offset-9{margin-left:75%}.small-11{width:91.66667%}.small-push-11{left:91.66667%}.small-pull-11{left:-91.66667%}.small-offset-10{margin-left:83.33333%}.small-12{width:100%}.small-offset-11{margin-left:91.66667%}.small-up-1>.column,.small-up-1>.columns{width:100%;float:left}.small-up-1>.column:nth-of-type(1n),.small-up-1>.columns:nth-of-type(1n){clear:none}.small-up-1>.column:nth-of-type(1n+1),.small-up-1>.columns:nth-of-type(1n+1){clear:both}.small-up-1>.column:last-child,.small-up-1>.columns:last-child{float:left}.small-up-2>.column,.small-up-2>.columns{width:50%;float:left}.small-up-2>.column:nth-of-type(1n),.small-up-2>.columns:nth-of-type(1n){clear:none}.small-up-2>.column:nth-of-type(2n+1),.small-up-2>.columns:nth-of-type(2n+1){clear:both}.small-up-2>.column:last-child,.small-up-2>.columns:last-child{float:left}.small-up-3>.column,.small-up-3>.columns{width:33.33333%;float:left}.small-up-3>.column:nth-of-type(1n),.small-up-3>.columns:nth-of-type(1n){clear:none}.small-up-3>.column:nth-of-type(3n+1),.small-up-3>.columns:nth-of-type(3n+1){clear:both}.small-up-3>.column:last-child,.small-up-3>.columns:last-child{float:left}.small-up-4>.column,.small-up-4>.columns{width:25%;float:left}.small-up-4>.column:nth-of-type(1n),.small-up-4>.columns:nth-of-type(1n){clear:none}.small-up-4>.column:nth-of-type(4n+1),.small-up-4>.columns:nth-of-type(4n+1){clear:both}.small-up-4>.column:last-child,.small-up-4>.columns:last-child{float:left}.small-up-5>.column,.small-up-5>.columns{width:20%;float:left}.small-up-5>.column:nth-of-type(1n),.small-up-5>.columns:nth-of-type(1n){clear:none}.small-up-5>.column:nth-of-type(5n+1),.small-up-5>.columns:nth-of-type(5n+1){clear:both}.small-up-5>.column:last-child,.small-up-5>.columns:last-child{float:left}.small-up-6>.column,.small-up-6>.columns{width:16.66667%;float:left}.small-up-6>.column:nth-of-type(1n),.small-up-6>.columns:nth-of-type(1n){clear:none}.small-up-6>.column:nth-of-type(6n+1),.small-up-6>.columns:nth-of-type(6n+1){clear:both}.small-up-6>.column:last-child,.small-up-6>.columns:last-child{float:left}.small-up-7>.column,.small-up-7>.columns{width:14.28571%;float:left}.small-up-7>.column:nth-of-type(1n),.small-up-7>.columns:nth-of-type(1n){clear:none}.small-up-7>.column:nth-of-type(7n+1),.small-up-7>.columns:nth-of-type(7n+1){clear:both}.small-up-7>.column:last-child,.small-up-7>.columns:last-child{float:left}.small-up-8>.column,.small-up-8>.columns{width:12.5%;float:left}.small-up-8>.column:nth-of-type(1n),.small-up-8>.columns:nth-of-type(1n){clear:none}.small-up-8>.column:nth-of-type(8n+1),.small-up-8>.columns:nth-of-type(8n+1){clear:both}.small-up-8>.column:last-child,.small-up-8>.columns:last-child{float:left}.column.small-centered,.small-centered.columns{float:none;margin-left:auto;margin-right:auto}.small-pull-0,.small-push-0,.small-uncenter{position:static;margin-left:0;margin-right:0}@media screen and (min-width:40em){.medium-pull-1,.medium-pull-10,.medium-pull-11,.medium-pull-2,.medium-pull-3,.medium-pull-4,.medium-pull-5,.medium-pull-6,.medium-pull-7,.medium-pull-8,.medium-pull-9,.medium-push-1,.medium-push-10,.medium-push-11,.medium-push-2,.medium-push-3,.medium-push-4,.medium-push-5,.medium-push-7,.medium-push-8,.medium-push-9{position:relative}.medium-1{width:8.33333%}.medium-push-1{left:8.33333%}.medium-pull-1{left:-8.33333%}.medium-offset-0{margin-left:0}.medium-2{width:16.66667%}.medium-push-2{left:16.66667%}.medium-pull-2{left:-16.66667%}.medium-offset-1{margin-left:8.33333%}.medium-3{width:25%}.medium-push-3{left:25%}.medium-pull-3{left:-25%}.medium-offset-2{margin-left:16.66667%}.medium-4{width:33.33333%}.medium-push-4{left:33.33333%}.medium-pull-4{left:-33.33333%}.medium-offset-3{margin-left:25%}.medium-5{width:41.66667%}.medium-push-5{left:41.66667%}.medium-pull-5{left:-41.66667%}.medium-offset-4{margin-left:33.33333%}.medium-6{width:50%}.medium-push-6{position:relative;left:50%}.medium-pull-6{left:-50%}.medium-offset-5{margin-left:41.66667%}.medium-7{width:58.33333%}.medium-push-7{left:58.33333%}.medium-pull-7{left:-58.33333%}.medium-offset-6{margin-left:50%}.medium-8{width:66.66667%}.medium-push-8{left:66.66667%}.medium-pull-8{left:-66.66667%}.medium-offset-7{margin-left:58.33333%}.medium-9{width:75%}.medium-push-9{left:75%}.medium-pull-9{left:-75%}.medium-offset-8{margin-left:66.66667%}.medium-10{width:83.33333%}.medium-push-10{left:83.33333%}.medium-pull-10{left:-83.33333%}.medium-offset-9{margin-left:75%}.medium-11{width:91.66667%}.medium-push-11{left:91.66667%}.medium-pull-11{left:-91.66667%}.medium-offset-10{margin-left:83.33333%}.medium-12{width:100%}.medium-offset-11{margin-left:91.66667%}.medium-up-1>.column,.medium-up-1>.columns{width:100%;float:left}.medium-up-1>.column:nth-of-type(1n),.medium-up-1>.columns:nth-of-type(1n){clear:none}.medium-up-1>.column:nth-of-type(1n+1),.medium-up-1>.columns:nth-of-type(1n+1){clear:both}.medium-up-1>.column:last-child,.medium-up-1>.columns:last-child{float:left}.medium-up-2>.column,.medium-up-2>.columns{width:50%;float:left}.medium-up-2>.column:nth-of-type(1n),.medium-up-2>.columns:nth-of-type(1n){clear:none}.medium-up-2>.column:nth-of-type(2n+1),.medium-up-2>.columns:nth-of-type(2n+1){clear:both}.medium-up-2>.column:last-child,.medium-up-2>.columns:last-child{float:left}.medium-up-3>.column,.medium-up-3>.columns{width:33.33333%;float:left}.medium-up-3>.column:nth-of-type(1n),.medium-up-3>.columns:nth-of-type(1n){clear:none}.medium-up-3>.column:nth-of-type(3n+1),.medium-up-3>.columns:nth-of-type(3n+1){clear:both}.medium-up-3>.column:last-child,.medium-up-3>.columns:last-child{float:left}.medium-up-4>.column,.medium-up-4>.columns{width:25%;float:left}.medium-up-4>.column:nth-of-type(1n),.medium-up-4>.columns:nth-of-type(1n){clear:none}.medium-up-4>.column:nth-of-type(4n+1),.medium-up-4>.columns:nth-of-type(4n+1){clear:both}.medium-up-4>.column:last-child,.medium-up-4>.columns:last-child{float:left}.medium-up-5>.column,.medium-up-5>.columns{width:20%;float:left}.medium-up-5>.column:nth-of-type(1n),.medium-up-5>.columns:nth-of-type(1n){clear:none}.medium-up-5>.column:nth-of-type(5n+1),.medium-up-5>.columns:nth-of-type(5n+1){clear:both}.medium-up-5>.column:last-child,.medium-up-5>.columns:last-child{float:left}.medium-up-6>.column,.medium-up-6>.columns{width:16.66667%;float:left}.medium-up-6>.column:nth-of-type(1n),.medium-up-6>.columns:nth-of-type(1n){clear:none}.medium-up-6>.column:nth-of-type(6n+1),.medium-up-6>.columns:nth-of-type(6n+1){clear:both}.medium-up-6>.column:last-child,.medium-up-6>.columns:last-child{float:left}.medium-up-7>.column,.medium-up-7>.columns{width:14.28571%;float:left}.medium-up-7>.column:nth-of-type(1n),.medium-up-7>.columns:nth-of-type(1n){clear:none}.medium-up-7>.column:nth-of-type(7n+1),.medium-up-7>.columns:nth-of-type(7n+1){clear:both}.medium-up-7>.column:last-child,.medium-up-7>.columns:last-child{float:left}.medium-up-8>.column,.medium-up-8>.columns{width:12.5%;float:left}.medium-up-8>.column:nth-of-type(1n),.medium-up-8>.columns:nth-of-type(1n){clear:none}.medium-up-8>.column:nth-of-type(8n+1),.medium-up-8>.columns:nth-of-type(8n+1){clear:both}.medium-up-8>.column:last-child,.medium-up-8>.columns:last-child{float:left}.column.medium-centered,.medium-centered.columns{float:none;margin-left:auto;margin-right:auto}.medium-pull-0,.medium-push-0,.medium-uncenter{position:static;margin-left:0;margin-right:0}}@media screen and (min-width:64em){.large-pull-1,.large-pull-10,.large-pull-11,.large-pull-2,.large-pull-3,.large-pull-4,.large-pull-5,.large-pull-6,.large-pull-7,.large-pull-8,.large-pull-9,.large-push-1,.large-push-10,.large-push-11,.large-push-2,.large-push-3,.large-push-4,.large-push-5,.large-push-7,.large-push-8,.large-push-9{position:relative}.large-1{width:8.33333%}.large-push-1{left:8.33333%}.large-pull-1{left:-8.33333%}.large-offset-0{margin-left:0}.large-2{width:16.66667%}.large-push-2{left:16.66667%}.large-pull-2{left:-16.66667%}.large-offset-1{margin-left:8.33333%}.large-3{width:25%}.large-push-3{left:25%}.large-pull-3{left:-25%}.large-offset-2{margin-left:16.66667%}.large-4{width:33.33333%}.large-push-4{left:33.33333%}.large-pull-4{left:-33.33333%}.large-offset-3{margin-left:25%}.large-5{width:41.66667%}.large-push-5{left:41.66667%}.large-pull-5{left:-41.66667%}.large-offset-4{margin-left:33.33333%}.large-6{width:50%}.large-push-6{position:relative;left:50%}.large-pull-6{left:-50%}.large-offset-5{margin-left:41.66667%}.large-7{width:58.33333%}.large-push-7{left:58.33333%}.large-pull-7{left:-58.33333%}.large-offset-6{margin-left:50%}.large-8{width:66.66667%}.large-push-8{left:66.66667%}.large-pull-8{left:-66.66667%}.large-offset-7{margin-left:58.33333%}.large-9{width:75%}.large-push-9{left:75%}.large-pull-9{left:-75%}.large-offset-8{margin-left:66.66667%}.large-10{width:83.33333%}.large-push-10{left:83.33333%}.large-pull-10{left:-83.33333%}.large-offset-9{margin-left:75%}.large-11{width:91.66667%}.large-push-11{left:91.66667%}.large-pull-11{left:-91.66667%}.large-offset-10{margin-left:83.33333%}.large-12{width:100%}.large-offset-11{margin-left:91.66667%}.large-up-1>.column,.large-up-1>.columns{width:100%;float:left}.large-up-1>.column:nth-of-type(1n),.large-up-1>.columns:nth-of-type(1n){clear:none}.large-up-1>.column:nth-of-type(1n+1),.large-up-1>.columns:nth-of-type(1n+1){clear:both}.large-up-1>.column:last-child,.large-up-1>.columns:last-child{float:left}.large-up-2>.column,.large-up-2>.columns{width:50%;float:left}.large-up-2>.column:nth-of-type(1n),.large-up-2>.columns:nth-of-type(1n){clear:none}.large-up-2>.column:nth-of-type(2n+1),.large-up-2>.columns:nth-of-type(2n+1){clear:both}.large-up-2>.column:last-child,.large-up-2>.columns:last-child{float:left}.large-up-3>.column,.large-up-3>.columns{width:33.33333%;float:left}.large-up-3>.column:nth-of-type(1n),.large-up-3>.columns:nth-of-type(1n){clear:none}.large-up-3>.column:nth-of-type(3n+1),.large-up-3>.columns:nth-of-type(3n+1){clear:both}.large-up-3>.column:last-child,.large-up-3>.columns:last-child{float:left}.large-up-4>.column,.large-up-4>.columns{width:25%;float:left}.large-up-4>.column:nth-of-type(1n),.large-up-4>.columns:nth-of-type(1n){clear:none}.large-up-4>.column:nth-of-type(4n+1),.large-up-4>.columns:nth-of-type(4n+1){clear:both}.large-up-4>.column:last-child,.large-up-4>.columns:last-child{float:left}.large-up-5>.column,.large-up-5>.columns{width:20%;float:left}.large-up-5>.column:nth-of-type(1n),.large-up-5>.columns:nth-of-type(1n){clear:none}.large-up-5>.column:nth-of-type(5n+1),.large-up-5>.columns:nth-of-type(5n+1){clear:both}.large-up-5>.column:last-child,.large-up-5>.columns:last-child{float:left}.large-up-6>.column,.large-up-6>.columns{width:16.66667%;float:left}.large-up-6>.column:nth-of-type(1n),.large-up-6>.columns:nth-of-type(1n){clear:none}.large-up-6>.column:nth-of-type(6n+1),.large-up-6>.columns:nth-of-type(6n+1){clear:both}.large-up-6>.column:last-child,.large-up-6>.columns:last-child{float:left}.large-up-7>.column,.large-up-7>.columns{width:14.28571%;float:left}.large-up-7>.column:nth-of-type(1n),.large-up-7>.columns:nth-of-type(1n){clear:none}.large-up-7>.column:nth-of-type(7n+1),.large-up-7>.columns:nth-of-type(7n+1){clear:both}.large-up-7>.column:last-child,.large-up-7>.columns:last-child{float:left}.large-up-8>.column,.large-up-8>.columns{width:12.5%;float:left}.large-up-8>.column:nth-of-type(1n),.large-up-8>.columns:nth-of-type(1n){clear:none}.large-up-8>.column:nth-of-type(8n+1),.large-up-8>.columns:nth-of-type(8n+1){clear:both}.large-up-8>.column:last-child,.large-up-8>.columns:last-child{float:left}.column.large-centered,.large-centered.columns{float:none;margin-left:auto;margin-right:auto}.large-pull-0,.large-push-0,.large-uncenter{position:static;margin-left:0;margin-right:0}}.breadcrumbs::after,.button-group::after,.clearfix::after,.off-canvas-wrapper-inner::after,.pagination::after,.tabs::after,.title-bar::after,.top-bar::after,hr{clear:both}ol,ul{margin-left:1.25rem}blockquote,dd,div,dl,dt,form,h1,h2,h3,h4,h5,h6,li,ol,p,pre,td,th,ul{margin:0;padding:0}dl,ol,p,ul{margin-bottom:1rem}p{font-size:inherit}em,i{font-style:italic}h1,h2,h3,h4,h5,h6{font-style:normal;color:inherit;margin-top:0;margin-bottom:.5rem;line-height:1.4}code,kbd{background-color:#e6e6e6;color:#0a0a0a;font-family:Consolas,"Liberation Mono",Courier,monospace}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{color:#cacaca;line-height:0}h1{font-size:1.5rem}h2{font-size:1.25rem}h3{font-size:1.1875rem}h4{font-size:1.125rem}h5{font-size:1.0625rem}h6{font-size:1rem}@media screen and (min-width:40em){h1{font-size:3rem}h2{font-size:2.5rem}h3{font-size:1.9375rem}h4{font-size:1.5625rem}h5{font-size:1.25rem}h6{font-size:1rem}}a{background-color:transparent;color:#2199e8;text-decoration:none;cursor:pointer}a:focus,a:hover{color:#1585cf}a img{border:0}hr{box-sizing:content-box;max-width:75rem;height:0;border-right:0;border-top:0;border-bottom:1px solid #cacaca;border-left:0;margin:1.25rem auto}dl,ol,ul{list-style-position:outside}li{font-size:inherit}ul{list-style-type:disc}ol ol,ol ul,ul ol,ul ul{margin-left:1.25rem;margin-bottom:0;list-style-type:inherit}.accordion,.menu,.tabs{list-style-type:none}dl dt{margin-bottom:.3rem;font-weight:700}.subheader,code,label{font-weight:400}blockquote{margin:0 0 1rem;padding:.5625rem 1.25rem 0 1.1875rem;border-left:1px solid #cacaca}blockquote,blockquote p{line-height:1.6;color:#8a8a8a}cite{display:block;font-size:.8125rem;color:#8a8a8a}cite:before{content:'\2014 \0020'}abbr{color:#0a0a0a;cursor:help;border-bottom:1px dotted #0a0a0a}code{border:1px solid #cacaca;padding:.125rem .3125rem .0625rem}kbd{padding:.125rem .25rem 0;margin:0}.subheader{margin-top:.2rem;margin-bottom:.5rem;line-height:1.4;color:#8a8a8a}.lead{font-size:125%;line-height:1.6}.button,.stat{line-height:1}.stat{font-size:2.5rem}p+.stat{margin-top:-1rem}.no-bullet{margin-left:0;list-style:none}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}@media screen and (min-width:40em){.medium-text-left{text-align:left}.medium-text-right{text-align:right}.medium-text-center{text-align:center}.medium-text-justify{text-align:justify}}@media screen and (min-width:64em){.large-text-left{text-align:left}.large-text-right{text-align:right}.large-text-center{text-align:center}.large-text-justify{text-align:justify}}.show-for-print{display:none!important}@media print{blockquote,img,pre,tr{page-break-inside:avoid}*{background:0 0!important;color:#000!important;box-shadow:none!important;text-shadow:none!important}.show-for-print{display:block!important}.hide-for-print{display:none!important}table.show-for-print{display:table!important}thead.show-for-print{display:table-header-group!important}tbody.show-for-print{display:table-row-group!important}tr.show-for-print{display:table-row!important}td.show-for-print,th.show-for-print{display:table-cell!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}.ir a:after,a[href^='javascript:']:after,a[href^='#']:after{content:''}abbr[title]:after{content:" (" attr(title) ")"}blockquote,pre{border:1px solid #999}thead{display:table-header-group}img{max-width:100%!important}@page{margin:.5cm}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.button{display:inline-block;text-align:center;cursor:pointer;-webkit-appearance:none;transition:all .25s ease-out;border:1px solid transparent;border-radius:0;padding:.85em 1em;margin:0 1rem 1rem 0;font-size:.9rem;background:#2199e8;color:#fff}[data-whatinput=mouse] .button{outline:0}.button:focus,.button:hover{background:#1583cc;color:#fff}.button.tiny{font-size:.6rem}.button.small{font-size:.75rem}.button.large{font-size:1.25rem}.button.expanded{display:block;width:100%;margin-left:0;margin-right:0}.button.primary{background:#2199e8;color:#fff}.button.primary:focus,.button.primary:hover{background:#147cc0;color:#fff}.button.secondary{background:#777;color:#fff}.button.secondary:focus,.button.secondary:hover{background:#5f5f5f;color:#fff}.button.success{background:#3adb76;color:#fff}.button.success:focus,.button.success:hover{background:#22bb5b;color:#fff}.button.alert{background:#ec5840;color:#fff}.button.alert:focus,.button.alert:hover{background:#da3116;color:#fff}.button.warning{background:#ffae00;color:#fff}.button.warning:focus,.button.warning:hover{background:#cc8b00;color:#fff}.button.hollow{border:1px solid #2199e8;color:#2199e8}.button.hollow,.button.hollow:focus,.button.hollow:hover{background:0 0}.button.hollow:focus,.button.hollow:hover{border-color:#0c4d78;color:#0c4d78}.button.hollow.primary{border:1px solid #2199e8;color:#2199e8}.button.hollow.primary:focus,.button.hollow.primary:hover{border-color:#0c4d78;color:#0c4d78}.button.hollow.secondary{border:1px solid #777;color:#777}.button.hollow.secondary:focus,.button.hollow.secondary:hover{border-color:#3c3c3c;color:#3c3c3c}.button.hollow.success{border:1px solid #3adb76;color:#3adb76}.button.hollow.success:focus,.button.hollow.success:hover{border-color:#157539;color:#157539}.button.hollow.alert{border:1px solid #ec5840;color:#ec5840}.button.hollow.alert:focus,.button.hollow.alert:hover{border-color:#881f0e;color:#881f0e}.button.hollow.warning{border:1px solid #ffae00;color:#ffae00}.button.hollow.warning:focus,.button.hollow.warning:hover{border-color:#805700;color:#805700}.button.disabled{opacity:.25;cursor:not-allowed;pointer-events:none}.button.dropdown::after{content:'';width:0;height:0;border:.4em inset;border-color:#fefefe transparent transparent;border-top-style:solid;top:.4em;float:right;margin-left:1em;display:inline-block}.button.arrow-only::after{margin-left:0;float:none;top:.2em}[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=month],[type=week],[type=email],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=color],textarea{display:block;box-sizing:border-box;width:100%;height:2.4375rem;padding:.5rem;border:1px solid #cacaca;margin:0 0 1rem;font-family:inherit;font-size:1rem;color:#0a0a0a;background-color:#fefefe;box-shadow:inset 0 1px 2px rgba(10,10,10,.1);border-radius:0;transition:box-shadow .5s,border-color .25s ease-in-out;-webkit-appearance:none;-moz-appearance:none}[type=text]:focus,[type=password]:focus,[type=date]:focus,[type=datetime]:focus,[type=datetime-local]:focus,[type=month]:focus,[type=week]:focus,[type=email]:focus,[type=number]:focus,[type=search]:focus,[type=tel]:focus,[type=time]:focus,[type=url]:focus,[type=color]:focus,textarea:focus{border:1px solid #8a8a8a;background:#fefefe;outline:0;box-shadow:0 0 5px #cacaca;transition:box-shadow .5s,border-color .25s ease-in-out}textarea{min-height:50px;max-width:100%}textarea[rows]{height:auto}input:disabled,input[readonly],textarea:disabled,textarea[readonly]{background-color:#e6e6e6;cursor:default}[type=submit],[type=button]{border-radius:0;-webkit-appearance:none;-moz-appearance:none}input[type=search]{box-sizing:border-box}[type=file],[type=checkbox],[type=radio]{margin:0 0 1rem}[type=checkbox]+label,[type=radio]+label{display:inline-block;margin-left:.5rem;margin-right:1rem;margin-bottom:0;vertical-align:baseline}label>[type=checkbox],label>[type=label]{margin-right:.5rem}[type=file]{width:100%}label{display:block;margin:0;font-size:.875rem;line-height:1.8;color:#0a0a0a}.form-error,.menu-text,.switch{font-weight:700}label.middle{margin:0 0 1rem;padding:.5625rem 0}.help-text{margin-top:-.5rem;font-size:.8125rem;font-style:italic;color:#333}.input-group{display:table;width:100%;margin-bottom:1rem}.input-group-button,.input-group-label{height:100%;width:1%;text-align:center}.input-group-button a,.input-group-button button,.input-group-button input,fieldset{margin:0}.input-group-button,.input-group-field,.input-group-label{display:table-cell;margin:0;vertical-align:middle}.input-group-label{padding:0 1rem;background:#e6e6e6;color:#0a0a0a;border:1px solid #cacaca}.input-group-label:first-child{border-right:0}.input-group-label:last-child{border-left:0}.fieldset,select{border:1px solid #cacaca}.input-group-button{padding-top:0;padding-bottom:0}fieldset{border:0;padding:0}legend{margin-bottom:.5rem}.fieldset{padding:1.25rem;margin:1.125rem 0}.fieldset legend{background:#fefefe;padding:0 .1875rem;margin:0 0 0 -.1875rem}select{height:2.4375rem;padding:.5rem;margin:0 0 1rem;font-size:1rem;font-family:inherit;line-height:normal;color:#0a0a0a;background-color:#fafafa;border-radius:0;-webkit-appearance:none;-moz-appearance:none;background-image:url('data:image/svg+xml;utf8,');background-size:9px 6px;background-position:right .5rem center;background-repeat:no-repeat}.form-error,.is-invalid-label{color:#ec5840}@media screen and (min-width:0\0){select{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAYCAYAAACbU/80AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIpJREFUeNrEkckNgDAMBBfRkEt0ObRBBdsGXUDgmQfK4XhH2m8czQAAy27R3tsw4Qfe2x8uOO6oYLb6GlOor3GF+swURAOmUJ+RwtEJs9WvTGEYxBXqI1MQAZhCfUQKRzDMVj+TwrAIV6jvSUEkYAr1LSkcyTBb/V+KYfX7xAeusq3sLDtGH3kEGACPWIflNZfhRQAAAABJRU5ErkJggg==)}}select:disabled{background-color:#e6e6e6;cursor:default}select::-ms-expand{display:none}select[multiple]{height:auto}.is-invalid-input:not(:focus){background-color:rgba(236,88,64,.1);border-color:#ec5840}.form-error{display:none;margin-top:-.5rem;margin-bottom:1rem;font-size:.75rem}.form-error.is-visible{display:block}.hide{display:none!important}@media screen and (min-width:0em) and (max-width:39.9375em){.hide-for-small-only{display:none!important}}@media screen and (max-width:0em),screen and (min-width:40em){.show-for-small-only{display:none!important}}@media screen and (min-width:40em){.hide-for-medium{display:none!important}}@media screen and (max-width:39.9375em){.show-for-medium{display:none!important}}@media screen and (min-width:40em) and (max-width:63.9375em){.hide-for-medium-only{display:none!important}}@media screen and (max-width:39.9375em),screen and (min-width:64em){.show-for-medium-only{display:none!important}}@media screen and (min-width:64em){.hide-for-large{display:none!important}}@media screen and (max-width:63.9375em){.show-for-large{display:none!important}}@media screen and (min-width:64em) and (max-width:74.9375em){.hide-for-large-only{display:none!important}}@media screen and (max-width:63.9375em),screen and (min-width:75em){.show-for-large-only{display:none!important}}.show-for-sr,.show-on-focus{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)}.show-on-focus:active,.show-on-focus:focus{position:static!important;height:auto;width:auto;overflow:visible;clip:auto}.hide-for-portrait,.show-for-landscape{display:block!important}@media screen and (orientation:landscape){.hide-for-portrait,.show-for-landscape{display:block!important}.hide-for-landscape,.show-for-portrait{display:none!important}}.hide-for-landscape,.show-for-portrait{display:none!important}@media screen and (orientation:portrait){.hide-for-portrait,.show-for-landscape{display:none!important}.hide-for-landscape,.show-for-portrait{display:block!important}}.float-left{float:left!important}.float-right{float:right!important}.float-center{display:block;margin-left:auto;margin-right:auto}.clearfix::after,.clearfix::before{content:' ';display:table}.accordion{background:#fefefe;border:1px solid #e6e6e6;border-radius:0;margin-left:0}.accordion-title{display:block;padding:1.25rem 1rem;line-height:1;font-size:.75rem;color:#2199e8;position:relative;border-bottom:1px solid #e6e6e6}.accordion-title:focus,.accordion-title:hover{background-color:#e6e6e6}:last-child>.accordion-title{border-bottom-width:0}.accordion-title::before{content:'+';position:absolute;right:1rem;top:50%;margin-top:-.5rem}.is-active>.accordion-title::before{content:'–'}.accordion-content{padding:1.25rem 1rem;display:none;border-bottom:1px solid #e6e6e6}.is-accordion-submenu-parent>a{position:relative}.is-accordion-submenu-parent>a::after{content:'';display:block;width:0;height:0;border:6px inset;border-color:#2199e8 transparent transparent;border-top-style:solid;position:absolute;top:50%;margin-top:-4px;right:1rem}.is-accordion-submenu-parent[aria-expanded=true]>a::after{-webkit-transform-origin:50% 50%;-ms-transform-origin:50% 50%;transform-origin:50% 50%;-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}.badge{display:inline-block;padding:.3em;min-width:2.1em;font-size:.6rem;text-align:center;border-radius:50%;background:#2199e8;color:#fefefe}.badge.secondary{background:#777;color:#fefefe}.badge.success{background:#3adb76;color:#fefefe}.badge.alert{background:#ec5840;color:#fefefe}.badge.warning{background:#ffae00;color:#fefefe}.breadcrumbs{list-style:none;margin:0 0 1rem}.breadcrumbs::after,.breadcrumbs::before{content:' ';display:table}.breadcrumbs li{float:left;color:#0a0a0a;font-size:.6875rem;cursor:default;text-transform:uppercase}.breadcrumbs li:not(:last-child)::after{color:#cacaca;content:"/";margin:0 .75rem;position:relative;top:1px;opacity:1}.breadcrumbs a{color:#2199e8}.breadcrumbs a:hover{text-decoration:underline}.breadcrumbs .disabled{color:#cacaca}.button-group{margin-bottom:1rem;font-size:.9rem}.button-group::after,.button-group::before{content:' ';display:table}.button-group .button{float:left;margin:0;font-size:inherit}.button-group .button:not(:last-child){border-right:1px solid #fefefe}.button-group.tiny{font-size:.6rem}.button-group.small{font-size:.75rem}.button-group.large{font-size:1.25rem}.button-group.expanded .button:nth-last-child(2):first-child,.button-group.expanded .button:nth-last-child(2):first-child~.button{width:50%}.button-group.expanded .button:nth-last-child(3):first-child,.button-group.expanded .button:nth-last-child(3):first-child~.button{width:33.33333%}.button-group.expanded .button:nth-last-child(4):first-child,.button-group.expanded .button:nth-last-child(4):first-child~.button{width:25%}.button-group.expanded .button:nth-last-child(5):first-child,.button-group.expanded .button:nth-last-child(5):first-child~.button{width:20%}.button-group.expanded .button:nth-last-child(6):first-child,.button-group.expanded .button:nth-last-child(6):first-child~.button{width:16.66667%}.button-group.primary .button{background:#2199e8;color:#fff}.button-group.primary .button:focus,.button-group.primary .button:hover{background:#147cc0;color:#fff}.button-group.secondary .button{background:#777;color:#fff}.button-group.secondary .button:focus,.button-group.secondary .button:hover{background:#5f5f5f;color:#fff}.button-group.success .button{background:#3adb76;color:#fff}.button-group.success .button:focus,.button-group.success .button:hover{background:#22bb5b;color:#fff}.button-group.alert .button{background:#ec5840;color:#fff}.button-group.alert .button:focus,.button-group.alert .button:hover{background:#da3116;color:#fff}.button-group.warning .button{background:#ffae00;color:#fff}.button-group.warning .button:focus,.button-group.warning .button:hover{background:#cc8b00;color:#fff}.button-group.stacked .button,.button-group.stacked-for-small .button{width:100%;border-right:0}@media screen and (min-width:40em){.button-group.stacked-for-small .button{width:auto}.button-group.stacked-for-small .button:not(:last-child){border-right:1px solid #fefefe}}.callout{margin:0 0 1rem;padding:1rem;border:1px solid rgba(10,10,10,.25);border-radius:0;position:relative;background-color:#fff}.callout>:first-child{margin-top:0}.callout>:last-child{margin-bottom:0}.callout.primary{background-color:#def0fc}.callout.primary a{color:#116ca8}.callout.primary a:hover{color:#0a4063}.callout.secondary{background-color:#ebebeb}.callout.success{background-color:#e1faea}.callout.success a{color:#1ea450}.callout.success a:hover{color:#126330}.callout.alert{background-color:#fce6e2}.callout.alert a{color:#bf2b13}.callout.alert a:hover{color:#791b0c}.callout.warning{background-color:#fff3d9}.callout.warning a{color:#b37a00}.callout.warning a:hover{color:#664600}.callout.small{padding:.5rem}.callout.large{padding:3rem}.close-button{position:absolute;color:#8a8a8a;right:1rem;top:.5rem;font-size:2em;line-height:1;cursor:pointer}[data-whatinput=mouse] .close-button{outline:0}.close-button:focus,.close-button:hover{color:#0a0a0a}.is-drilldown{position:relative;overflow:hidden}.is-drilldown-submenu{position:absolute;top:0;left:100%;z-index:-1;height:100%;width:100%;background:#fefefe;transition:-webkit-transform .15s linear;transition:transform .15s linear}.is-drilldown-submenu-parent>a::after,.js-drilldown-back::before{width:0;content:'';display:block;height:0}.is-drilldown-submenu.is-active{z-index:1;display:block;-webkit-transform:translateX(-100%);-ms-transform:translateX(-100%);transform:translateX(-100%)}.is-drilldown-submenu.is-closing{-webkit-transform:translateX(100%);-ms-transform:translateX(100%);transform:translateX(100%)}.is-drilldown-submenu-parent>a{position:relative}.is-drilldown-submenu-parent>a::after{border:6px inset;border-color:transparent transparent transparent #2199e8;border-left-style:solid;position:absolute;top:50%;margin-top:-6px;right:1rem}.js-drilldown-back::before{border:6px inset;border-color:transparent #2199e8 transparent transparent;border-right-style:solid;float:left;margin-right:.75rem;margin-left:.6rem;margin-top:14px}.dropdown-pane{background-color:#fefefe;border:1px solid #cacaca;display:block;padding:1rem;position:absolute;width:300px;z-index:10;border-radius:0}.dropdown-pane.is-open{visibility:visible}.dropdown-pane.tiny{width:100px}.dropdown-pane.small{width:200px}.dropdown-pane.large{width:400px}[data-whatinput=mouse] .dropdown.menu a{outline:0}.dropdown.menu .is-dropdown-submenu-parent{position:relative}.dropdown.menu .is-dropdown-submenu-parent a::after{float:right;margin-top:3px;margin-left:10px}.dropdown.menu .is-dropdown-submenu-parent.is-down-arrow a{padding-right:1.5rem;position:relative}.dropdown.menu .is-dropdown-submenu-parent.is-down-arrow>a::after{content:'';display:block;width:0;height:0;border:5px inset;border-color:#2199e8 transparent transparent;border-top-style:solid;position:absolute;top:12px;right:5px}.dropdown.menu .is-dropdown-submenu-parent.is-left-arrow>a::after{content:'';display:block;width:0;height:0;border:5px inset;border-color:transparent #2199e8 transparent transparent;border-right-style:solid;float:left;margin-left:0;margin-right:10px}.is-dropdown-menu.vertical.align-right,.menu.align-right>li{float:right}.dropdown.menu .is-dropdown-submenu-parent.is-right-arrow>a::after{content:'';display:block;width:0;height:0;border:5px inset;border-color:transparent transparent transparent #2199e8;border-left-style:solid}.dropdown.menu .is-dropdown-submenu-parent.is-left-arrow.opens-inner .submenu{right:0;left:auto}.dropdown.menu .is-dropdown-submenu-parent.is-right-arrow.opens-inner .submenu{left:0;right:auto}.dropdown.menu .is-dropdown-submenu-parent.opens-inner .submenu{top:100%}.no-js .dropdown.menu ul{display:none}.dropdown.menu .submenu{display:none;position:absolute;top:0;left:100%;min-width:200px;z-index:1;background:#fefefe;border:1px solid #cacaca}.dropdown.menu .submenu>li{width:100%}.dropdown.menu .submenu.first-sub{top:100%;left:0;right:auto}.dropdown.menu .submenu.js-dropdown-active,.dropdown.menu .submenu:not(.js-dropdown-nohover)>.is-dropdown-submenu-parent:hover>.dropdown.menu .submenu{display:block}.dropdown.menu .is-dropdown-submenu-parent.opens-left .submenu{left:auto;right:100%}.dropdown.menu.align-right .submenu.first-sub{top:100%;left:auto;right:0}.is-dropdown-menu.vertical{width:100px}.is-dropdown-menu.vertical>li .submenu{top:0;left:100%}.flex-video{position:relative;height:0;padding-top:1.5625rem;padding-bottom:75%;margin-bottom:1rem;overflow:hidden}.flex-video embed,.flex-video iframe,.flex-video object,.flex-video video{position:absolute;top:0;left:0;width:100%;height:100%}.flex-video.widescreen{padding-bottom:56.25%}.flex-video.vimeo{padding-top:0}.label{display:inline-block;padding:.33333rem .5rem;font-size:.8rem;line-height:1;white-space:nowrap;cursor:default;border-radius:0;background:#2199e8;color:#fefefe}.label.secondary{background:#777;color:#fefefe}.label.success{background:#3adb76;color:#fefefe}.label.alert{background:#ec5840;color:#fefefe}.label.warning{background:#ffae00;color:#fefefe}.media-object{margin-bottom:1rem;display:block}.media-object img{max-width:none}@media screen and (min-width:0em) and (max-width:39.9375em){.media-object.stack-for-small .media-object-section{display:block;padding:0 0 1rem}.media-object.stack-for-small .media-object-section img{width:100%}}.media-object-section{display:table-cell;vertical-align:top}.media-object-section:first-child{padding-right:1rem}.media-object-section:last-child:not(+.media-object-section:first-child){padding-left:1rem}.media-object-section.middle{vertical-align:middle}.media-object-section.bottom{vertical-align:bottom}.menu>li,.menu>li>a>i,.menu>li>a>img,.menu>li>a>span{vertical-align:middle}.menu{margin:0}[data-whatinput=mouse] .menu>li{outline:0}.menu>li:not(.menu-text)>a{display:block;padding:.7rem 1rem;line-height:1}.menu a,.menu button,.menu input{margin-bottom:0}.menu>li>a>i,.menu>li>a>img{display:inline-block;margin-right:.25rem}.menu>li{display:table-cell}.menu.vertical>li{display:block}@media screen and (min-width:40em){.menu.medium-horizontal>li{display:table-cell}.menu.medium-vertical>li{display:block}}@media screen and (min-width:64em){.menu.large-horizontal>li{display:table-cell}.menu.large-vertical>li{display:block}}.menu.simple a{padding:0;margin-right:1rem}.menu.expanded{display:table;width:100%}.menu.expanded>li:nth-last-child(2):first-child,.menu.expanded>li:nth-last-child(2):first-child~li{width:50%}.menu.expanded>li:nth-last-child(3):first-child,.menu.expanded>li:nth-last-child(3):first-child~li{width:33.33333%}.menu.expanded>li:nth-last-child(4):first-child,.menu.expanded>li:nth-last-child(4):first-child~li{width:25%}.menu.expanded>li:nth-last-child(5):first-child,.menu.expanded>li:nth-last-child(5):first-child~li{width:20%}.menu.expanded>li:nth-last-child(6):first-child,.menu.expanded>li:nth-last-child(6):first-child~li{width:16.66667%}.menu.expanded>li:first-child:last-child{width:100%}.menu.icon-top>li>a{text-align:center}.menu.icon-top>li>a>i,.menu.icon-top>li>a>img{display:block;margin:0 auto .25rem}.menu.nested{margin-left:1rem}.menu-text{color:inherit;line-height:1;padding:.7rem 1rem}body,html{height:100%}.off-canvas-wrapper{width:100%;overflow-x:hidden;position:relative;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-overflow-scrolling:auto}.off-canvas-wrapper-inner{position:relative;width:100%;transition:-webkit-transform .5s ease;transition:transform .5s ease}.off-canvas-wrapper-inner::after,.off-canvas-wrapper-inner::before{content:' ';display:table}.off-canvas-content{min-height:100%;background:#fefefe;transition:-webkit-transform .5s ease;transition:transform .5s ease;-webkit-backface-visibility:hidden;backface-visibility:hidden;z-index:1;box-shadow:0 0 10px rgba(10,10,10,.5)}.js-off-canvas-exit{display:none;position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(254,254,254,.25);cursor:pointer;transition:background .5s ease}.is-off-canvas-open .js-off-canvas-exit{display:block}.off-canvas{position:absolute;background:#e6e6e6;z-index:-1;max-height:100%;overflow-y:auto;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}.orbit-caption,.orbit-next:active,.orbit-next:focus,.orbit-next:hover,.orbit-previous:active,.orbit-previous:focus,.orbit-previous:hover{background-color:rgba(10,10,10,.5)}[data-whatinput=mouse] .off-canvas{outline:0}.off-canvas.position-left{left:-250px;top:0;width:250px}.is-open-left{-webkit-transform:translateX(250px);-ms-transform:translateX(250px);transform:translateX(250px)}.off-canvas.position-right{right:-250px;top:0;width:250px}.is-open-right{-webkit-transform:translateX(-250px);-ms-transform:translateX(-250px);transform:translateX(-250px)}@media screen and (min-width:40em){.position-left.reveal-for-medium{left:0;z-index:auto;position:fixed}.position-left.reveal-for-medium~.off-canvas-content{margin-left:250px}.position-right.reveal-for-medium{right:0;z-index:auto;position:fixed}.position-right.reveal-for-medium~.off-canvas-content{margin-right:250px}}@media screen and (min-width:64em){.position-left.reveal-for-large{left:0;z-index:auto;position:fixed}.position-left.reveal-for-large~.off-canvas-content{margin-left:250px}.position-right.reveal-for-large{right:0;z-index:auto;position:fixed}.position-right.reveal-for-large~.off-canvas-content{margin-right:250px}}.orbit,.orbit-container{position:relative}.orbit-container{margin:0;overflow:hidden;list-style:none}.orbit-caption,.orbit-next,.orbit-previous{position:absolute;padding:1rem;color:#fefefe}.orbit-slide{width:100%;max-height:100%}.orbit-slide.no-motionui.is-active{top:0;left:0}.orbit-figure{margin:0}.orbit-image{margin:0;width:100%;max-width:100%}.orbit-caption{width:100%;margin-bottom:0}.orbit-next,.orbit-previous{top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);z-index:10}[data-whatinput=mouse] .orbit-next,[data-whatinput=mouse] .orbit-previous{outline:0}.orbit-previous{left:0}.orbit-next{left:auto;right:0}.orbit-bullets{position:relative;margin-top:.8rem;margin-bottom:.8rem;text-align:center}[data-whatinput=mouse] .orbit-bullets{outline:0}.orbit-bullets button{width:1.2rem;height:1.2rem;margin:.1rem;background-color:#cacaca;border-radius:50%}.orbit-bullets button.is-active,.orbit-bullets button:hover{background-color:#8a8a8a}.pagination{margin-left:0;margin-bottom:1rem}.pagination::after,.pagination::before{content:' ';display:table}.pagination li{font-size:.875rem;margin-right:.0625rem;display:none;border-radius:0}.pagination li:first-child,.pagination li:last-child{display:inline-block}@media screen and (min-width:40em){.pagination li{display:inline-block}.reveal{min-height:0}}.pagination a,.pagination button{color:#0a0a0a;display:block;padding:.1875rem .625rem;border-radius:0}.pagination a:hover,.pagination button:hover{background:#e6e6e6}.pagination .current{padding:.1875rem .625rem;background:#2199e8;color:#fefefe;cursor:default}.pagination .disabled{padding:.1875rem .625rem;color:#cacaca;cursor:default}.pagination .disabled:hover{background:0 0}.pagination .ellipsis::after{content:'…';padding:.1875rem .625rem;color:#0a0a0a}.pagination-previous a::before,.pagination-previous.disabled::before{content:'«';display:inline-block;margin-right:.5rem}.pagination-next a::after,.pagination-next.disabled::after{content:'»';display:inline-block;margin-left:.5rem}.progress{background-color:#cacaca;height:1rem;margin-bottom:1rem;border-radius:0}.progress.primary .progress-meter{background-color:#2199e8}.progress.secondary .progress-meter{background-color:#777}.progress.success .progress-meter{background-color:#3adb76}.progress.alert .progress-meter{background-color:#ec5840}.progress.warning .progress-meter{background-color:#ffae00}.progress-meter{position:relative;display:block;width:0;height:100%;background-color:#2199e8;border-radius:0}.progress-meter .progress-meter-text{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);margin:0;font-size:.75rem;font-weight:700;color:#fefefe;white-space:nowrap}.slider-fill,.slider-handle{left:0;display:inline-block}.slider{position:relative;height:.5rem;margin-top:1.25rem;margin-bottom:2.25rem;background-color:#e6e6e6;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-ms-touch-action:none;touch-action:none}.slider-fill{position:absolute;top:0;max-width:100%;height:.5rem;background-color:#cacaca;transition:all .2s ease-in-out}.slider-fill.is-dragging{transition:all 0s linear}.slider-handle{top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);position:absolute;z-index:1;width:1.4rem;height:1.4rem;background-color:#2199e8;transition:all .2s ease-in-out;-ms-touch-action:manipulation;touch-action:manipulation;border-radius:0}[data-whatinput=mouse] .slider-handle{outline:0}.slider-handle:hover{background-color:#1583cc}.slider-handle.is-dragging{transition:all 0s linear}.slider.disabled,.slider[disabled]{opacity:.25;cursor:not-allowed}.slider.vertical{display:inline-block;width:.5rem;height:12.5rem;margin:0 1.25rem;-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}.slider.vertical .slider-fill{top:0;width:.5rem;max-height:100%}.slider.vertical .slider-handle{position:absolute;top:0;left:50%;width:1.4rem;height:1.4rem;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%)}.sticky-container{position:relative}.sticky{position:absolute;z-index:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.sticky.is-stuck{position:fixed;z-index:5}.sticky.is-stuck.is-at-top{top:0}.sticky.is-anchored{position:absolute;left:auto;right:auto}body.is-reveal-open{overflow:hidden}.reveal-overlay{display:none;position:fixed;top:0;bottom:0;left:0;right:0;z-index:1005;background-color:rgba(10,10,10,.45);overflow-y:scroll}.reveal{display:none;z-index:1006;padding:1rem;border:1px solid #cacaca;margin:100px auto 0;background-color:#fefefe;border-radius:0;position:absolute;overflow-y:auto}.switch-paddle,.switch-paddle::after{display:block;transition:all .25s ease-out}[data-whatinput=mouse] .reveal{outline:0}.reveal .column,.reveal .columns{min-width:0}.reveal>:last-child{margin-bottom:0}.reveal.collapse{padding:0}caption,tbody td,tbody th{padding:.5rem .625rem .625rem}@media screen and (min-width:40em){.reveal{width:600px;max-width:75rem}.reveal .reveal{left:auto;right:auto;margin:0 auto}.reveal.tiny{width:30%;max-width:75rem}.reveal.small{width:50%;max-width:75rem}.reveal.large{width:90%;max-width:75rem}}.reveal.full{top:0;left:0;width:100%;height:100%;height:100vh;min-height:100vh;max-width:none;margin-left:0}.switch{margin-bottom:1rem;outline:0;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:#fefefe;font-size:.875rem}.switch-input{opacity:0;position:absolute}.switch-paddle{background:#cacaca;cursor:pointer;position:relative;width:4rem;height:2rem;border-radius:0;color:inherit;font-weight:inherit}.has-tip,.title-bar-title,caption{font-weight:700}input+.switch-paddle{margin:0}.switch-paddle::after{background:#fefefe;content:'';position:absolute;height:1.5rem;left:.25rem;top:.25rem;width:1.5rem;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);border-radius:0}.switch-active,.switch-inactive,.tooltip.left::before{-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%)}input:checked~.switch-paddle{background:#2199e8}input:checked~.switch-paddle::after{left:2.25rem}[data-whatinput=mouse] input:focus~.switch-paddle{outline:0}.switch-active,.switch-inactive{position:absolute;top:50%;transform:translateY(-50%)}.switch-active{left:8%;display:none}input:checked+label>.switch-active{display:block}.switch-inactive{right:15%}input:checked+label>.switch-inactive{display:none}.switch.tiny .switch-paddle{width:3rem;height:1.5rem;font-size:.625rem}.switch.tiny .switch-paddle::after{width:1rem;height:1rem}.switch.tiny input:checked~.switch-paddle:after{left:1.75rem}.switch.small .switch-paddle{width:3.5rem;height:1.75rem;font-size:.75rem}.switch.small .switch-paddle::after{width:1.25rem;height:1.25rem}.switch.small input:checked~.switch-paddle:after{left:2rem}.switch.large .switch-paddle{width:5rem;height:2.5rem;font-size:1rem}.switch.large .switch-paddle::after{width:2rem;height:2rem}.switch.large input:checked~.switch-paddle:after{left:2.75rem}table{border-collapse:collapse;border-spacing:0;margin-bottom:1rem;border-radius:0}tbody,tfoot,thead{border:1px solid #f1f1f1;background-color:#fefefe}tfoot,thead{background:#f8f8f8;color:#0a0a0a}tfoot tr,thead tr{background:0 0}tfoot td,tfoot th,thead td,thead th{padding:.5rem .625rem .625rem;font-weight:700;text-align:left}tbody tr:nth-child(even){background-color:#f1f1f1}@media screen and (max-width:63.9375em){table.stack tfoot,table.stack thead{display:none}table.stack td,table.stack th,table.stack tr{display:block}table.stack td{border-top:0}}.tabs,.tabs-content{border:1px solid #e6e6e6}table.scroll{display:block;width:100%;overflow-y:scroll}table.hover tr:hover{background-color:#f9f9f9}table.hover tr:nth-of-type(even):hover{background-color:#ececec}.tabs{margin:0;background:#fefefe}.tabs::after,.tabs::before{content:' ';display:table}.tabs.simple>li>a{padding:0}.tabs.simple>li>a:hover{background:0 0}.tabs.vertical>li{width:auto;float:none;display:block}.tabs-title,.title-bar-left{float:left}.tabs.primary{background:#2199e8}.tabs.primary>li>a{color:#fefefe}.tabs.primary>li>a:focus,.tabs.primary>li>a:hover{background:#1893e4}.tabs-title>a{display:block;padding:1.25rem 1.5rem;line-height:1;font-size:12px;color:#2199e8}.tabs-title>a:hover{background:#fefefe}.tabs-title>a:focus,.tabs-title>a[aria-selected=true]{background:#e6e6e6}.tabs-content{background:#fefefe;transition:all .5s ease;border-top:0}.tabs-content.vertical{border:1px solid #e6e6e6;border-left:0}.tabs-panel{display:none;padding:1rem}.tabs-panel.is-active{display:block}.thumbnail{border:4px solid #fefefe;box-shadow:0 0 0 1px rgba(10,10,10,.2);display:inline-block;line-height:0;max-width:100%;transition:box-shadow .2s ease-out;border-radius:0;margin-bottom:1rem}.thumbnail:focus,.thumbnail:hover{box-shadow:0 0 6px 1px rgba(33,153,232,.5)}.title-bar{background:#0a0a0a;color:#fefefe;padding:.5rem}.title-bar::after,.title-bar::before{content:' ';display:table}.menu-icon,.title-bar-title{display:inline-block;vertical-align:middle}.title-bar .menu-icon{margin-left:.25rem;margin-right:.5rem}.title-bar-right{float:right;text-align:right}.menu-icon{position:relative;cursor:pointer;width:20px;height:16px}.menu-icon::after{content:'';position:absolute;display:block;width:100%;height:2px;background:#fefefe;top:0;left:0;box-shadow:0 7px 0 #fefefe,0 14px 0 #fefefe}.menu-icon:hover::after{background:#cacaca;box-shadow:0 7px 0 #cacaca,0 14px 0 #cacaca}.has-tip{border-bottom:dotted 1px #8a8a8a;position:relative;display:inline-block;cursor:help}.tooltip.top::before,.tooltip::before{content:'';display:block;width:0;height:0}.tooltip{background-color:#0a0a0a;color:#fefefe;font-size:80%;padding:.75rem;position:absolute;z-index:10;top:calc(100% + .6495rem);max-width:10rem!important;border-radius:0}.tooltip::before{border:.75rem inset;border-color:transparent transparent #0a0a0a;border-bottom-style:solid;bottom:100%;position:absolute;left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%)}.tooltip.top::before{border:.75rem inset;border-color:#0a0a0a transparent transparent;border-top-style:solid;top:100%;bottom:auto}.tooltip.left::before,.tooltip.right::before{content:'';display:block;width:0;height:0;bottom:auto;top:50%}.tooltip.left::before{border:.75rem inset;border-color:transparent transparent transparent #0a0a0a;border-left-style:solid;left:100%;transform:translateY(-50%)}.tooltip.right::before{border:.75rem inset;border-color:transparent #0a0a0a transparent transparent;border-right-style:solid;left:auto;right:100%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%)}.top-bar{padding:.5rem}.top-bar::after,.top-bar::before{content:' ';display:table}.top-bar,.top-bar ul{background-color:#e6e6e6}.top-bar a{color:#2199e8}.top-bar input{width:200px;margin-right:1rem}@media screen and (min-width:40em){.top-bar-left{float:left}.top-bar-right{float:right}} \ No newline at end of file diff --git a/example.html b/example.html deleted file mode 100755 index b38a0e4..0000000 --- a/example.html +++ /dev/null @@ -1,64 +0,0 @@ - - - -whois.php -base classes to do whois queries with php - - - - -
- -

phpWhois {ver} - base class to do whois queries with php

- -

-© 1999 - 2011 easyDNS -Technologies Inc. & Mark Jeftovic
-Now maintained and hosted by David Saez at OLS 20000
-Placed under the GPL. See the LICENSE file in the distribution. -

- - - -
-
- - - - - - - - - - - - -
-Enter any domain name, ip address or AS handle you would like to query whois for -

-
-
- Show me regular output
- Show me HTMLized output
- Show me the returned PHP object -
- Fast lookup - - -phpWhois web page -
-
-
-
- - -

Results for {query} :

-
-{result} -
- - - - \ No newline at end of file diff --git a/example.php b/example.php deleted file mode 100644 index f878945..0000000 --- a/example.php +++ /dev/null @@ -1,144 +0,0 @@ -deep_whois = empty($_GET['fast']); - - // To use special whois servers (see README) - //$whois->UseServer('uk','whois.nic.uk:1043?{hname} {ip} {query}'); - //$whois->UseServer('au','whois-check.ausregistry.net.au'); - - // Comment the following line to disable support for non ICANN tld's - $whois->non_icann = true; - - $result = $whois->Lookup($query); - $resout = str_replace('{query}', $query, $resout); - $winfo = ''; - - switch ($output) - { - case 'object': - if ($whois->Query['status'] < 0) - { - $winfo = implode($whois->Query['errstr'],"\n

"); - } - else - { - $utils = new utils; - $winfo = $utils->showObject($result); - } - break; - - case 'nice': - if (!empty($result['rawdata'])) - { - $utils = new utils; - $winfo = $utils->showHTML($result); - } - else - { - if (isset($whois->Query['errstr'])) - $winfo = implode($whois->Query['errstr'],"\n

"); - else - $winfo = 'Unexpected error'; - } - break; - - case 'proxy': - if ($allowproxy) - exit(serialize($result)); - - default: - if(!empty($result['rawdata'])) - { - $winfo .= '
'.implode($result['rawdata'],"\n").'
'; - } - else - { - $winfo = implode($whois->Query['errstr'],"\n

"); - } - } - - $resout = str_replace('{result}', $winfo, $resout); - } -else - $resout = ''; - -$out = str_replace('{ver}',$whois->CODE_VERSION,$out); -exit(str_replace('{results}', $resout, $out)); - -//------------------------------------------------------------------------- - -function extract_block (&$plantilla,$mark,$retmark='') -{ -$start = strpos($plantilla,''); -$final = strpos($plantilla,''); - -if ($start === false || $final === false) return; - -$ini = $start+7+strlen($mark); - -$ret=substr($plantilla,$ini,$final-$ini); - -$final+=8+strlen($mark); - -if ($retmark===false) - $plantilla=substr($plantilla,0,$start).substr($plantilla,$final); -else - { - if ($retmark=='') $retmark=$mark; - $plantilla=substr($plantilla,0,$start).'{'.$retmark.'}'.substr($plantilla,$final); - } - -return $ret; -} -?> \ No newline at end of file diff --git a/img/apps/container-box.gif b/img/apps/container-box.gif new file mode 100644 index 0000000..636ebf3 Binary files /dev/null and b/img/apps/container-box.gif differ diff --git a/img/apps/pcp-box.gif b/img/apps/pcp-box.gif new file mode 100644 index 0000000..dcba762 Binary files /dev/null and b/img/apps/pcp-box.gif differ diff --git a/img/apps/pd-box.gif b/img/apps/pd-box.gif new file mode 100644 index 0000000..ed05760 Binary files /dev/null and b/img/apps/pd-box.gif differ diff --git a/img/apps/pdfwl-box.gif b/img/apps/pdfwl-box.gif new file mode 100644 index 0000000..bca49c4 Binary files /dev/null and b/img/apps/pdfwl-box.gif differ diff --git a/img/apps/poa-box.gif b/img/apps/poa-box.gif new file mode 100644 index 0000000..cf57b06 Binary files /dev/null and b/img/apps/poa-box.gif differ diff --git a/img/apps/server-box.gif b/img/apps/server-box.gif new file mode 100644 index 0000000..32ccc67 Binary files /dev/null and b/img/apps/server-box.gif differ diff --git a/img/bullet.gif b/img/bullet.gif new file mode 100644 index 0000000..a63e102 Binary files /dev/null and b/img/bullet.gif differ diff --git a/img/globe.png b/img/globe.png new file mode 100644 index 0000000..0bfa09b Binary files /dev/null and b/img/globe.png differ diff --git a/whois.icon.png b/img/icon.png old mode 100755 new mode 100644 similarity index 100% rename from whois.icon.png rename to img/icon.png diff --git a/img/icons/aspdotnet.png b/img/icons/aspdotnet.png new file mode 100644 index 0000000..eee130b Binary files /dev/null and b/img/icons/aspdotnet.png differ diff --git a/img/icons/fastcgi.png b/img/icons/fastcgi.png new file mode 100644 index 0000000..5efc1f7 Binary files /dev/null and b/img/icons/fastcgi.png differ diff --git a/img/icons/perl.png b/img/icons/perl.png new file mode 100644 index 0000000..b43d82c Binary files /dev/null and b/img/icons/perl.png differ diff --git a/img/icons/php.png b/img/icons/php.png new file mode 100644 index 0000000..fe706d1 Binary files /dev/null and b/img/icons/php.png differ diff --git a/img/icons/python.png b/img/icons/python.png new file mode 100644 index 0000000..62af5e1 Binary files /dev/null and b/img/icons/python.png differ diff --git a/img/icons/ssi.png b/img/icons/ssi.png new file mode 100644 index 0000000..af7a0e9 Binary files /dev/null and b/img/icons/ssi.png differ diff --git a/img/p-box.png b/img/p-box.png new file mode 100644 index 0000000..9b263ef Binary files /dev/null and b/img/p-box.png differ diff --git a/img/panel-logo.png b/img/panel-logo.png new file mode 100644 index 0000000..f6f25e5 Binary files /dev/null and b/img/panel-logo.png differ diff --git a/img/parallels-logo.png b/img/parallels-logo.png new file mode 100644 index 0000000..9842887 Binary files /dev/null and b/img/parallels-logo.png differ diff --git a/img/th.png b/img/th.png new file mode 100644 index 0000000..94cc1be Binary files /dev/null and b/img/th.png differ diff --git a/img/top-bottom.png b/img/top-bottom.png new file mode 100644 index 0000000..dbd10ec Binary files /dev/null and b/img/top-bottom.png differ diff --git a/inc/footer.php b/inc/footer.php new file mode 100644 index 0000000..026c04f --- /dev/null +++ b/inc/footer.php @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/inc/header.php b/inc/header.php new file mode 100644 index 0000000..5fd4ece --- /dev/null +++ b/inc/header.php @@ -0,0 +1,24 @@ + + + + + + + DINSLY Tools + + + + + + + diff --git a/index.php b/index.php new file mode 100644 index 0000000..770c7b3 --- /dev/null +++ b/index.php @@ -0,0 +1,115 @@ + +
+
+
+
+
+
+
+
+ + + + +
+
+

DINSLY Tools

+

A selection of domain tools including Whois, NS Lookup, DIG and IP Locate.

+
+
+
+
IP Locate
+
+
+
NS Lookup
+
+
+
Whois
+
+
+
+
+
+
+
+
+
+ +
+ +
+
+ + Fast lookup +
+
+ +
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + \ No newline at end of file diff --git a/iplocate-map.php b/iplocate-map.php new file mode 100644 index 0000000..5efd9de --- /dev/null +++ b/iplocate-map.php @@ -0,0 +1,42 @@ + + +
+
+
+Query a Success'; + } else { + echo 'Query Failed'; + } +?> + + +
+
+ +
+ \ No newline at end of file diff --git a/iplocate-results.php b/iplocate-results.php new file mode 100644 index 0000000..757cdf2 --- /dev/null +++ b/iplocate-results.php @@ -0,0 +1,98 @@ + + +
+
+Query a Success'; + } else { + echo 'Query Failed'; + } +?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IP Address
Locale
Latitude
Longitude
Postcode/Zip
Region
Country
Timwzone
Service Provider
Reverse
AS
+ +
+
+
+ +
+
+ +
+ \ No newline at end of file diff --git a/js/app.js b/js/app.js new file mode 100644 index 0000000..df14715 --- /dev/null +++ b/js/app.js @@ -0,0 +1,60 @@ +$(document).foundation(); + $('#output-type').change(function() { + var output = $(this).val(); + $('.dinsly-hidden').slideUp( function() { + if(output == 'nslookup') { + $('#dns-type-label').delay(500).slideDown(); + } else if(output == 'whois') { + $('#whois-type-label').delay(500).slideDown(); + } else if(output == 'iplocate') { + $('#iplocate-type-label').delay(500).slideDown(); + } + }); + }); + +$("#submit-button").click(function(e) { + e.preventDefault(); + $('.header-row').slideUp(); + var query = $("input#query-input").val(); + var displayType = $("select#display-type").val(); + var fastLookup = $("input#fast-lookup").is(':checked'); + var outputType = $('select#output-type').val(); + var iplocateType = $('select#iplocate-type').val(); + if (query == "") { + $("label#query-error").slideDown(); + $("input#query-input").focus(); + return false; + } + if(outputType == 'nslookup') { + var displayType = $("select#dns-type").val(); + var processor = 'nslookup-results.php'; + } else if(outputType == 'whois') { + var displayType = $("select#display-type").val(); + var processor = 'whois-results.php'; + } else if(outputType == 'iplocate') { + var displayType = $("select#display-type").val(); + if(iplocateType == 'maponly') { + var processor = 'iplocate-map.php'; + } else if (iplocateType == 'datamap') { + var processor = 'iplocate-results.php'; + } + } + $("label#query-error").slideUp(); + // alert(name + '\r\n' + type + '\r\n' + fast); + var dataString = 'query=' + query + '&displayType=' + displayType + '&fastLookup=' + fastLookup; + $.ajax({ + type: "POST", + url: processor, + async: true, + data: dataString, + success: function(res) { + $('#query-results').html(res) + .hide() + .fadeIn(1500, function() { + }); + } + }); + + return false; + +}); diff --git a/js/foundation.js b/js/foundation.js new file mode 100644 index 0000000..a5a53b7 --- /dev/null +++ b/js/foundation.js @@ -0,0 +1,7470 @@ +!function($) { +"use strict"; + +var FOUNDATION_VERSION = '6.0.5'; + +// Global Foundation object +// This is attached to the window, or used as a module for AMD/Browserify +var Foundation = { + version: FOUNDATION_VERSION, + + /** + * Stores initialized plugins. + */ + _plugins: {}, + + /** + * Stores generated unique ids for plugin instances + */ + _uuids: [], + /** + * Stores currently active plugins. + */ + _activePlugins: {}, + + /** + * Returns a boolean for RTL support + */ + rtl: function(){ + return $('html').attr('dir') === 'rtl'; + }, + /** + * Defines a Foundation plugin, adding it to the `Foundation` namespace and the list of plugins to initialize when reflowing. + * @param {Object} plugin - The constructor of the plugin. + */ + plugin: function(plugin, name) { + // Object key to use when adding to global Foundation object + // Examples: Foundation.Reveal, Foundation.OffCanvas + var className = (name || functionName(plugin)); + // Object key to use when storing the plugin, also used to create the identifying data attribute for the plugin + // Examples: data-reveal, data-off-canvas + var attrName = hyphenate(className); + + // Add to the Foundation object and the plugins list (for reflowing) + this._plugins[attrName] = this[className] = plugin; + }, + /** + * @function + * Creates a pointer to an instance of a Plugin within the Foundation._activePlugins object. + * Sets the `[data-pluginName="uniqueIdHere"]`, allowing easy access to any plugin's internal methods. + * Also fires the initialization event for each plugin, consolidating repeditive code. + * @param {Object} plugin - an instance of a plugin, usually `this` in context. + * @fires Plugin#init + */ + registerPlugin: function(plugin){ + var pluginName = functionName(plugin.constructor).toLowerCase(); + + plugin.uuid = this.GetYoDigits(6, pluginName); + + if(!plugin.$element.attr('data-' + pluginName)){ + plugin.$element.attr('data-' + pluginName, plugin.uuid); + } + /** + * Fires when the plugin has initialized. + * @event Plugin#init + */ + plugin.$element.trigger('init.zf.' + pluginName); + + this._activePlugins[plugin.uuid] = plugin; + + return; + }, + /** + * @function + * Removes the pointer for an instance of a Plugin from the Foundation._activePlugins obj. + * Also fires the destroyed event for the plugin, consolidating repeditive code. + * @param {Object} plugin - an instance of a plugin, usually `this` in context. + * @fires Plugin#destroyed + */ + unregisterPlugin: function(plugin){ + var pluginName = functionName(plugin.constructor).toLowerCase(); + + delete this._activePlugins[plugin.uuid]; + plugin.$element.removeAttr('data-' + pluginName) + /** + * Fires when the plugin has been destroyed. + * @event Plugin#destroyed + */ + .trigger('destroyed.zf.' + pluginName); + + return; + }, + + /** + * @function + * Causes one or more active plugins to re-initialize, resetting event listeners, recalculating positions, etc. + * @param {String} plugins - optional string of an individual plugin key, attained by calling `$(element).data('pluginName')`, or string of a plugin class i.e. `'dropdown'` + * @default If no argument is passed, reflow all currently active plugins. + */ + _reflow: function(plugins){ + var actvPlugins = Object.keys(this._activePlugins); + var _this = this; + + if(!plugins){ + actvPlugins.forEach(function(p){ + _this._activePlugins[p]._init(); + }); + + }else if(typeof plugins === 'string'){ + var namespace = plugins.split('-')[1]; + + if(namespace){ + + this._activePlugins[plugins]._init(); + + }else{ + namespace = new RegExp(plugins, 'i'); + + actvPlugins.filter(function(p){ + return namespace.test(p); + }).forEach(function(p){ + _this._activePlugins[p]._init(); + }); + } + } + + }, + + /** + * returns a random base-36 uid with namespacing + * @function + * @param {Number} length - number of random base-36 digits desired. Increase for more random strings. + * @param {String} namespace - name of plugin to be incorporated in uid, optional. + * @default {String} '' - if no plugin name is provided, nothing is appended to the uid. + * @returns {String} - unique id + */ + GetYoDigits: function(length, namespace){ + length = length || 6; + return Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, length))).toString(36).slice(1) + (namespace ? '-' + namespace : ''); + }, + /** + * Initialize plugins on any elements within `elem` (and `elem` itself) that aren't already initialized. + * @param {Object} elem - jQuery object containing the element to check inside. Also checks the element itself, unless it's the `document` object. + * @param {String|Array} plugins - A list of plugins to initialize. Leave this out to initialize everything. + */ + reflow: function(elem, plugins) { + + // If plugins is undefined, just grab everything + if (typeof plugins === 'undefined') { + plugins = Object.keys(this._plugins); + } + // If plugins is a string, convert it to an array with one item + else if (typeof plugins === 'string') { + plugins = [plugins]; + } + + var _this = this; + + // Iterate through each plugin + $.each(plugins, function(i, name) { + // Get the current plugin + var plugin = _this._plugins[name]; + + // Localize the search to all elements inside elem, as well as elem itself, unless elem === document + var $elem = $(elem).find('[data-'+name+']').addBack('[data-'+name+']'); + + // For each plugin found, initialize it + $elem.each(function() { + var $el = $(this), + opts = {}; + // Don't double-dip on plugins + if ($el.data('zf-plugin')) { + console.warn("Tried to initialize "+name+" on an element that already has a Foundation plugin."); + return; + } + + if($el.attr('data-options')){ + var thing = $el.attr('data-options').split(';').forEach(function(e, i){ + var opt = e.split(':').map(function(el){ return el.trim(); }); + if(opt[0]) opts[opt[0]] = parseValue(opt[1]); + }); + } + try{ + $el.data('zf-plugin', new plugin($(this), opts)); + }catch(er){ + console.error(er); + }finally{ + return; + } + }); + }); + }, + getFnName: functionName, + transitionend: function($elem){ + var transitions = { + 'transition': 'transitionend', + 'WebkitTransition': 'webkitTransitionEnd', + 'MozTransition': 'transitionend', + 'OTransition': 'otransitionend' + }; + var elem = document.createElement('div'), + end; + + for (var t in transitions){ + if (typeof elem.style[t] !== 'undefined'){ + end = transitions[t]; + } + } + if(end){ + return end; + }else{ + end = setTimeout(function(){ + $elem.triggerHandler('transitionend', [$elem]); + }, 1); + return 'transitionend'; + } + } +}; + + +Foundation.util = { + /** + * Function for applying a debounce effect to a function call. + * @function + * @param {Function} func - Function to be called at end of timeout. + * @param {Number} delay - Time in ms to delay the call of `func`. + * @returns function + */ + throttle: function (func, delay) { + var timer = null; + + return function () { + var context = this, args = arguments; + + if (timer === null) { + timer = setTimeout(function () { + func.apply(context, args); + timer = null; + }, delay); + } + }; + } +}; + +// TODO: consider not making this a jQuery function +// TODO: need way to reflow vs. re-initialize +/** + * The Foundation jQuery method. + * @param {String|Array} method - An action to perform on the current jQuery object. + */ +var foundation = function(method) { + var type = typeof method, + $meta = $('meta.foundation-mq'), + $noJS = $('.no-js'); + + if(!$meta.length){ + $('').appendTo(document.head); + } + if($noJS.length){ + $noJS.removeClass('no-js'); + } + + if(type === 'undefined'){//needs to initialize the Foundation object, or an individual plugin. + Foundation.MediaQuery._init(); + Foundation.reflow(this); + }else if(type === 'string'){//an individual method to invoke on a plugin or group of plugins + var args = Array.prototype.slice.call(arguments, 1);//collect all the arguments, if necessary + var plugClass = this.data('zfPlugin');//determine the class of plugin + + if(plugClass !== undefined && plugClass[method] !== undefined){//make sure both the class and method exist + if(this.length === 1){//if there's only one, call it directly. + plugClass[method].apply(plugClass, args); + }else{ + this.each(function(i, el){//otherwise loop through the jQuery collection and invoke the method on each + plugClass[method].apply($(el).data('zfPlugin'), args); + }); + } + }else{//error for no class or no method + throw new ReferenceError("We're sorry, '" + method + "' is not an available method for " + (plugClass ? functionName(plugClass) : 'this element') + '.'); + } + }else{//error for invalid argument type + throw new TypeError("We're sorry, '" + type + "' is not a valid parameter. You must use a string representing the method you wish to invoke."); + } + return this; +}; + +window.Foundation = Foundation; +$.fn.foundation = foundation; + +// Polyfill for requestAnimationFrame +(function() { + if (!Date.now || !window.Date.now) + window.Date.now = Date.now = function() { return new Date().getTime(); }; + + var vendors = ['webkit', 'moz']; + for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) { + var vp = vendors[i]; + window.requestAnimationFrame = window[vp+'RequestAnimationFrame']; + window.cancelAnimationFrame = (window[vp+'CancelAnimationFrame'] + || window[vp+'CancelRequestAnimationFrame']); + } + if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) + || !window.requestAnimationFrame || !window.cancelAnimationFrame) { + var lastTime = 0; + window.requestAnimationFrame = function(callback) { + var now = Date.now(); + var nextTime = Math.max(lastTime + 16, now); + return setTimeout(function() { callback(lastTime = nextTime); }, + nextTime - now); + }; + window.cancelAnimationFrame = clearTimeout; + } + /** + * Polyfill for performance.now, required by rAF + */ + if(!window.performance || !window.performance.now){ + window.performance = { + start: Date.now(), + now: function(){ return Date.now() - this.start; } + }; + } +})(); +if (!Function.prototype.bind) { + Function.prototype.bind = function(oThis) { + if (typeof this !== 'function') { + // closest thing possible to the ECMAScript 5 + // internal IsCallable function + throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); + } + + var aArgs = Array.prototype.slice.call(arguments, 1), + fToBind = this, + fNOP = function() {}, + fBound = function() { + return fToBind.apply(this instanceof fNOP + ? this + : oThis, + aArgs.concat(Array.prototype.slice.call(arguments))); + }; + + if (this.prototype) { + // native functions don't have a prototype + fNOP.prototype = this.prototype; + } + fBound.prototype = new fNOP(); + + return fBound; + }; +} +// Polyfill to get the name of a function in IE9 +function functionName(fn) { + if (Function.prototype.name === undefined) { + var funcNameRegex = /function\s([^(]{1,})\(/; + var results = (funcNameRegex).exec((fn).toString()); + return (results && results.length > 1) ? results[1].trim() : ""; + } + else if (fn.prototype === undefined) { + return fn.constructor.name; + } + else { + return fn.prototype.constructor.name; + } +} +function parseValue(str){ + if(/true/.test(str)) return true; + else if(/false/.test(str)) return false; + else if(!isNaN(str * 1)/* && typeof (str * 1) === "number"*/) return parseFloat(str); + return str; +} +// Convert PascalCase to kebab-case +// Thank you: http://stackoverflow.com/a/8955580 +function hyphenate(str) { + return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); +} + +}(jQuery); + +!function(Foundation, window){ + /** + * Compares the dimensions of an element to a container and determines collision events with container. + * @function + * @param {jQuery} element - jQuery object to test for collisions. + * @param {jQuery} parent - jQuery object to use as bounding container. + * @param {Boolean} lrOnly - set to true to check left and right values only. + * @param {Boolean} tbOnly - set to true to check top and bottom values only. + * @default if no parent object passed, detects collisions with `window`. + * @returns {Boolean} - true if collision free, false if a collision in any direction. + */ + var ImNotTouchingYou = function(element, parent, lrOnly, tbOnly){ + var eleDims = GetDimensions(element), + top, bottom, left, right; + + if(parent){ + var parDims = GetDimensions(parent); + + bottom = (eleDims.offset.top + eleDims.height <= parDims.height + parDims.offset.top); + top = (eleDims.offset.top >= parDims.offset.top); + left = (eleDims.offset.left >= parDims.offset.left); + right = (eleDims.offset.left + eleDims.width <= parDims.width); + }else{ + bottom = (eleDims.offset.top + eleDims.height <= eleDims.windowDims.height + eleDims.windowDims.offset.top); + top = (eleDims.offset.top >= eleDims.windowDims.offset.top); + left = (eleDims.offset.left >= eleDims.windowDims.offset.left); + right = (eleDims.offset.left + eleDims.width <= eleDims.windowDims.width); + } + var allDirs = [bottom, top, left, right]; + + if(lrOnly){ return left === right === true; } + if(tbOnly){ return top === bottom === true; } + + return allDirs.indexOf(false) === -1; + }; + + /** + * Uses native methods to return an object of dimension values. + * @function + * @param {jQuery || HTML} element - jQuery object or DOM element for which to get the dimensions. Can be any element other that document or window. + * @returns {Object} - nested object of integer pixel values + * TODO - if element is window, return only those values. + */ + var GetDimensions = function(elem, test){ + elem = elem.length ? elem[0] : elem; + + if(elem === window || elem === document){ throw new Error("I'm sorry, Dave. I'm afraid I can't do that."); } + + var rect = elem.getBoundingClientRect(), + parRect = elem.parentNode.getBoundingClientRect(), + winRect = document.body.getBoundingClientRect(), + winY = window.pageYOffset, + winX = window.pageXOffset; + + return { + width: rect.width, + height: rect.height, + offset: { + top: rect.top + winY, + left: rect.left + winX + }, + parentDims: { + width: parRect.width, + height: parRect.height, + offset: { + top: parRect.top + winY, + left: parRect.left + winX + } + }, + windowDims: { + width: winRect.width, + height: winRect.height, + offset: { + top: winY, + left: winX + } + } + }; + }; + /** + * Returns an object of top and left integer pixel values for dynamically rendered elements, + * such as: Tooltip, Reveal, and Dropdown + * @function + * @param {jQuery} element - jQuery object for the element being positioned. + * @param {jQuery} anchor - jQuery object for the element's anchor point. + * @param {String} position - a string relating to the desired position of the element, relative to it's anchor + * @param {Number} vOffset - integer pixel value of desired vertical separation between anchor and element. + * @param {Number} hOffset - integer pixel value of desired horizontal separation between anchor and element. + * @param {Boolean} isOverflow - if a collision event is detected, sets to true to default the element to full width - any desired offset. + * TODO alter/rewrite to work with `em` values as well/instead of pixels + */ + var GetOffsets = function(element, anchor, position, vOffset, hOffset, isOverflow){ + var $eleDims = GetDimensions(element), + // var $eleDims = GetDimensions(element), + $anchorDims = anchor ? GetDimensions(anchor) : null; + // $anchorDims = anchor ? GetDimensions(anchor) : null; + switch(position){ + case 'top': + return { + left: $anchorDims.offset.left, + top: $anchorDims.offset.top - ($eleDims.height + vOffset) + }; + break; + case 'left': + return { + left: $anchorDims.offset.left - ($eleDims.width + hOffset), + top: $anchorDims.offset.top + }; + break; + case 'right': + return { + left: $anchorDims.offset.left + $anchorDims.width + hOffset, + top: $anchorDims.offset.top + }; + break; + case 'center top': + return { + left: ($anchorDims.offset.left + ($anchorDims.width / 2)) - ($eleDims.width / 2), + top: $anchorDims.offset.top - ($eleDims.height + vOffset) + }; + break; + case 'center bottom': + return { + left: isOverflow ? hOffset : (($anchorDims.offset.left + ($anchorDims.width / 2)) - ($eleDims.width / 2)), + top: $anchorDims.offset.top + $anchorDims.height + vOffset + }; + break; + case 'center left': + return { + left: $anchorDims.offset.left - ($eleDims.width + hOffset), + top: ($anchorDims.offset.top + ($anchorDims.height / 2)) - ($eleDims.height / 2) + }; + break; + case 'center right': + return { + left: $anchorDims.offset.left + $anchorDims.width + hOffset + 1, + top: ($anchorDims.offset.top + ($anchorDims.height / 2)) - ($eleDims.height / 2) + }; + break; + case 'center': + return { + left: ($eleDims.windowDims.offset.left + ($eleDims.windowDims.width / 2)) - ($eleDims.width / 2), + top: ($eleDims.windowDims.offset.top + ($eleDims.windowDims.height / 2)) - ($eleDims.height / 2) + }; + break; + case 'reveal': + return { + left: ($eleDims.windowDims.width - $eleDims.width) / 2, + top: $eleDims.windowDims.offset.top + vOffset + }; + case 'reveal full': + return { + left: $eleDims.windowDims.offset.left, + top: $eleDims.windowDims.offset.top + }; + break; + default: + return { + left: $anchorDims.offset.left, + top: $anchorDims.offset.top + $anchorDims.height + vOffset + }; + } + }; + Foundation.Box = { + ImNotTouchingYou: ImNotTouchingYou, + GetDimensions: GetDimensions, + GetOffsets: GetOffsets + }; +}(window.Foundation, window); + +/******************************************* + * * + * This util was created by Marius Olbertz * + * Please thank Marius on GitHub /owlbertz * + * or the web http://www.mariusolbertz.de/ * + * * + ******************************************/ +!function($, Foundation){ + 'use strict'; + Foundation.Keyboard = {}; + + var keyCodes = { + 9: 'TAB', + 13: 'ENTER', + 27: 'ESCAPE', + 32: 'SPACE', + 37: 'ARROW_LEFT', + 38: 'ARROW_UP', + 39: 'ARROW_RIGHT', + 40: 'ARROW_DOWN' + }; + + // constants for easier comparing Can be used like Foundation.parseKey(event) === Foundation.keys.SPACE + var keys = (function(kcs) { + var k = {}; + for (var kc in kcs) k[kcs[kc]] = kcs[kc]; + return k; + })(keyCodes); + + Foundation.Keyboard.keys = keys; + + /** + * Parses the (keyboard) event and returns a String that represents its key + * Can be used like Foundation.parseKey(event) === Foundation.keys.SPACE + * @param {Event} event - the event generated by the event handler + * @return String key - String that represents the key pressed + */ + var parseKey = function(event) { + var key = keyCodes[event.which || event.keyCode] || String.fromCharCode(event.which).toUpperCase(); + if (event.shiftKey) key = 'SHIFT_' + key; + if (event.ctrlKey) key = 'CTRL_' + key; + if (event.altKey) key = 'ALT_' + key; + return key; + }; + Foundation.Keyboard.parseKey = parseKey; + + + // plain commands per component go here, ltr and rtl are merged based on orientation + var commands = {}; + + /** + * Handles the given (keyboard) event + * @param {Event} event - the event generated by the event handler + * @param {Object} component - Foundation component, e.g. Slider or Reveal + * @param {Objects} functions - collection of functions that are to be executed + */ + var handleKey = function(event, component, functions) { + var commandList = commands[Foundation.getFnName(component)], + keyCode = parseKey(event), + cmds, + command, + fn; + if (!commandList) return console.warn('Component not defined!'); + + if (typeof commandList.ltr === 'undefined') { // this component does not differentiate between ltr and rtl + cmds = commandList; // use plain list + } else { // merge ltr and rtl: if document is rtl, rtl overwrites ltr and vice versa + if (Foundation.rtl()) cmds = $.extend({}, commandList.ltr, commandList.rtl); + + else cmds = $.extend({}, commandList.rtl, commandList.ltr); + } + command = cmds[keyCode]; + + + fn = functions[command]; + if (fn && typeof fn === 'function') { // execute function with context of the component if exists + fn.apply(component); + if (functions.handled || typeof functions.handled === 'function') { // execute function when event was handled + functions.handled.apply(component); + } + } else { + if (functions.unhandled || typeof functions.unhandled === 'function') { // execute function when event was not handled + functions.unhandled.apply(component); + } + } + }; + Foundation.Keyboard.handleKey = handleKey; + + /** + * Finds all focusable elements within the given `$element` + * @param {jQuery} $element - jQuery object to search within + * @return {jQuery} $focusable - all focusable elements within `$element` + */ + var findFocusable = function($element) { + return $element.find('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]').filter(function() { + if (!$(this).is(':visible') || $(this).attr('tabindex') < 0) { return false; } //only have visible elements and those that have a tabindex greater or equal 0 + return true; + }); + }; + Foundation.Keyboard.findFocusable = findFocusable; + + /** + * Returns the component name name + * @param {Object} component - Foundation component, e.g. Slider or Reveal + * @return String componentName + */ + + var register = function(componentName, cmds) { + commands[componentName] = cmds; + }; + Foundation.Keyboard.register = register; +}(jQuery, window.Foundation); + +!function($, Foundation) { + +// Default set of media queries +var defaultQueries = { + 'default' : 'only screen', + landscape : 'only screen and (orientation: landscape)', + portrait : 'only screen and (orientation: portrait)', + retina : 'only screen and (-webkit-min-device-pixel-ratio: 2),' + + 'only screen and (min--moz-device-pixel-ratio: 2),' + + 'only screen and (-o-min-device-pixel-ratio: 2/1),' + + 'only screen and (min-device-pixel-ratio: 2),' + + 'only screen and (min-resolution: 192dpi),' + + 'only screen and (min-resolution: 2dppx)' +}; + +var MediaQuery = { + queries: [], + current: '', + + /** + * Checks if the screen is at least as wide as a breakpoint. + * @function + * @param {String} size - Name of the breakpoint to check. + * @returns {Boolean} `true` if the breakpoint matches, `false` if it's smaller. + */ + atLeast: function(size) { + var query = this.get(size); + + if (query) { + return window.matchMedia(query).matches; + } + + return false; + }, + + /** + * Gets the media query of a breakpoint. + * @function + * @param {String} size - Name of the breakpoint to get. + * @returns {String|null} - The media query of the breakpoint, or `null` if the breakpoint doesn't exist. + */ + get: function(size) { + for (var i in this.queries) { + var query = this.queries[i]; + if (size === query.name) return query.value; + } + + return null; + }, + + /** + * Initializes the media query helper, by extracting the breakpoint list from the CSS and activating the breakpoint watcher. + * @function + * @private + */ + _init: function() { + var self = this; + var extractedStyles = $('.foundation-mq').css('font-family'); + var namedQueries; + + namedQueries = parseStyleToObject(extractedStyles); + + for (var key in namedQueries) { + self.queries.push({ + name: key, + value: 'only screen and (min-width: ' + namedQueries[key] + ')' + }); + } + + this.current = this._getCurrentSize(); + + this._watcher(); + + // Extend default queries + // namedQueries = $.extend(defaultQueries, namedQueries); + }, + + /** + * Gets the current breakpoint name by testing every breakpoint and returning the last one to match (the biggest one). + * @function + * @private + * @returns {String} Name of the current breakpoint. + */ + _getCurrentSize: function() { + var matched; + + for (var i in this.queries) { + var query = this.queries[i]; + + if (window.matchMedia(query.value).matches) { + matched = query; + } + } + + if(typeof matched === 'object') { + return matched.name; + } else { + return matched; + } + }, + + /** + * Activates the breakpoint watcher, which fires an event on the window whenever the breakpoint changes. + * @function + * @private + */ + _watcher: function() { + var _this = this; + + $(window).on('resize.zf.mediaquery', function() { + var newSize = _this._getCurrentSize(); + + if (newSize !== _this.current) { + // Broadcast the media query change on the window + $(window).trigger('changed.zf.mediaquery', [newSize, _this.current]); + + // Change the current media query + _this.current = newSize; + } + }); + } +}; + +Foundation.MediaQuery = MediaQuery; + +// matchMedia() polyfill - Test a CSS media type/query in JS. +// Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license +window.matchMedia || (window.matchMedia = function() { + 'use strict'; + + // For browsers that support matchMedium api such as IE 9 and webkit + var styleMedia = (window.styleMedia || window.media); + + // For those that don't support matchMedium + if (!styleMedia) { + var style = document.createElement('style'), + script = document.getElementsByTagName('script')[0], + info = null; + + style.type = 'text/css'; + style.id = 'matchmediajs-test'; + + script.parentNode.insertBefore(style, script); + + // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers + info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle; + + styleMedia = { + matchMedium: function(media) { + var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }'; + + // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers + if (style.styleSheet) { + style.styleSheet.cssText = text; + } else { + style.textContent = text; + } + + // Test if media query is true or false + return info.width === '1px'; + } + }; + } + + return function(media) { + return { + matches: styleMedia.matchMedium(media || 'all'), + media: media || 'all' + }; + }; +}()); + +// Thank you: https://github.com/sindresorhus/query-string +function parseStyleToObject(str) { + var styleObject = {}; + + if (typeof str !== 'string') { + return styleObject; + } + + str = str.trim().slice(1, -1); // browsers re-quote string style values + + if (!str) { + return styleObject; + } + + styleObject = str.split('&').reduce(function(ret, param) { + var parts = param.replace(/\+/g, ' ').split('='); + var key = parts[0]; + var val = parts[1]; + key = decodeURIComponent(key); + + // missing `=` should be `null`: + // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters + val = val === undefined ? null : decodeURIComponent(val); + + if (!ret.hasOwnProperty(key)) { + ret[key] = val; + } else if (Array.isArray(ret[key])) { + ret[key].push(val); + } else { + ret[key] = [ret[key], val]; + } + return ret; + }, {}); + + return styleObject; +} + +}(jQuery, Foundation) + +/** + * Motion module. + * @module foundation.motion + */ +!function($, Foundation) { + +var initClasses = ['mui-enter', 'mui-leave']; +var activeClasses = ['mui-enter-active', 'mui-leave-active']; + +function animate(isIn, element, animation, cb) { + element = $(element).eq(0); + + if (!element.length) return; + + var initClass = isIn ? initClasses[0] : initClasses[1]; + var activeClass = isIn ? activeClasses[0] : activeClasses[1]; + + // Set up the animation + reset(); + element.addClass(animation) + .css('transition', 'none'); + // .addClass(initClass); + // if(isIn) element.show(); + requestAnimationFrame(function() { + element.addClass(initClass); + if (isIn) element.show(); + }); + // Start the animation + requestAnimationFrame(function() { + element[0].offsetWidth; + element.css('transition', ''); + element.addClass(activeClass); + }); + // Move(500, element, function(){ + // // element[0].offsetWidth; + // element.css('transition', ''); + // element.addClass(activeClass); + // }); + + // Clean up the animation when it finishes + element.one(Foundation.transitionend(element), finish);//.one('finished.zf.animate', finish); + + // Hides the element (for out animations), resets the element, and runs a callback + function finish() { + if (!isIn) element.hide(); + reset(); + if (cb) cb.apply(element); + } + + // Resets transitions and removes motion-specific classes + function reset() { + element[0].style.transitionDuration = 0; + element.removeClass(initClass + ' ' + activeClass + ' ' + animation); + } +} + +var Motion = { + animateIn: function(element, animation, /*duration,*/ cb) { + animate(true, element, animation, cb); + }, + + animateOut: function(element, animation, /*duration,*/ cb) { + animate(false, element, animation, cb); + } +}; + +var Move = function(duration, elem, fn){ + var anim, prog, start = null; + // console.log('called'); + + function move(ts){ + if(!start) start = window.performance.now(); + // console.log(start, ts); + prog = ts - start; + fn.apply(elem); + + if(prog < duration){ anim = window.requestAnimationFrame(move, elem); } + else{ + window.cancelAnimationFrame(anim); + elem.trigger('finished.zf.animate', [elem]).triggerHandler('finished.zf.animate', [elem]); + } + } + anim = window.requestAnimationFrame(move); +}; + +Foundation.Move = Move; +Foundation.Motion = Motion; + +}(jQuery, Foundation); + +!function($, Foundation){ + 'use strict'; + Foundation.Nest = { + Feather: function(menu, type){ + menu.attr('role', 'menubar'); + type = type || 'zf'; + var items = menu.find('li').attr({'role': 'menuitem'}), + subMenuClass = 'is-' + type + '-submenu', + subItemClass = subMenuClass + '-item', + hasSubClass = 'is-' + type + '-submenu-parent'; + menu.find('a:first').attr('tabindex', 0); + items.each(function(){ + var $item = $(this), + $sub = $item.children('ul'); + if($sub.length){ + $item.addClass('has-submenu ' + hasSubClass) + .attr({ + 'aria-haspopup': true, + 'aria-selected': false, + 'aria-expanded': false, + 'aria-label': $item.children('a:first').text() + }); + $sub.addClass('submenu ' + subMenuClass) + .attr({ + 'data-submenu': '', + 'aria-hidden': true, + 'role': 'menu' + }); + } + if($item.parent('[data-submenu]').length){ + $item.addClass('is-submenu-item ' + subItemClass); + } + }); + return; + }, + Burn: function(menu, type){ + var items = menu.find('li').removeAttr('tabindex'), + subMenuClass = 'is-' + type + '-submenu', + subItemClass = subMenuClass + '-item', + hasSubClass = 'is-' + type + '-submenu-parent'; + + // menu.find('.is-active').removeClass('is-active'); + menu.find('*') + // menu.find('.' + subMenuClass + ', .' + subItemClass + ', .is-active, .has-submenu, .is-submenu-item, .submenu, [data-submenu]') + .removeClass(subMenuClass + ' ' + subItemClass + ' ' + hasSubClass + ' has-submenu is-submenu-item submenu is-active') + .removeAttr('data-submenu').css('display', ''); + + // console.log( menu.find('.' + subMenuClass + ', .' + subItemClass + ', .has-submenu, .is-submenu-item, .submenu, [data-submenu]') + // .removeClass(subMenuClass + ' ' + subItemClass + ' has-submenu is-submenu-item submenu') + // .removeAttr('data-submenu')); + // items.each(function(){ + // var $item = $(this), + // $sub = $item.children('ul'); + // if($item.parent('[data-submenu]').length){ + // $item.removeClass('is-submenu-item ' + subItemClass); + // } + // if($sub.length){ + // $item.removeClass('has-submenu'); + // $sub.removeClass('submenu ' + subMenuClass).removeAttr('data-submenu'); + // } + // }); + } + }; +}(jQuery, window.Foundation); + +!function($, Foundation){ + 'use strict'; + var Timer = function(elem, options, cb){ + var _this = this, + duration = options.duration,//options is an object for easily adding features later. + nameSpace = Object.keys(elem.data())[0] || 'timer', + remain = -1, + start, + timer; + + this.restart = function(){ + remain = -1; + clearTimeout(timer); + this.start(); + }; + + this.start = function(){ + // if(!elem.data('paused')){ return false; }//maybe implement this sanity check if used for other things. + clearTimeout(timer); + remain = remain <= 0 ? duration : remain; + elem.data('paused', false); + start = Date.now(); + timer = setTimeout(function(){ + if(options.infinite){ + _this.restart();//rerun the timer. + } + cb(); + }, remain); + elem.trigger('timerstart.zf.' + nameSpace); + }; + + this.pause = function(){ + //if(elem.data('paused')){ return false; }//maybe implement this sanity check if used for other things. + clearTimeout(timer); + elem.data('paused', true); + var end = Date.now(); + remain = remain - (end - start); + elem.trigger('timerpaused.zf.' + nameSpace); + }; + }; + /** + * Runs a callback function when images are fully loaded. + * @param {Object} images - Image(s) to check if loaded. + * @param {Func} callback - Function to execute when image is fully loaded. + */ + var onImagesLoaded = function(images, callback){ + var self = this, + unloaded = images.length; + + if (unloaded === 0) { + callback(); + } + + var singleImageLoaded = function() { + unloaded--; + if (unloaded === 0) { + callback(); + } + }; + + images.each(function() { + if (this.complete) { + singleImageLoaded(); + } + else if (typeof this.naturalWidth !== 'undefined' && this.naturalWidth > 0) { + singleImageLoaded(); + } + else { + $(this).one('load', function() { + singleImageLoaded(); + }); + } + }); + }; + + Foundation.Timer = Timer; + Foundation.onImagesLoaded = onImagesLoaded; +}(jQuery, window.Foundation); + +//************************************************** +//**Work inspired by multiple jquery swipe plugins** +//**Done by Yohai Ararat *************************** +//************************************************** +(function($) { + + $.spotSwipe = { + version: '1.0.0', + enabled: 'ontouchstart' in document.documentElement, + preventDefault: true, + moveThreshold: 75, + timeThreshold: 200 + }; + + var startPosX, + startPosY, + startTime, + elapsedTime, + isMoving = false; + + function onTouchEnd() { + // alert(this); + this.removeEventListener('touchmove', onTouchMove); + this.removeEventListener('touchend', onTouchEnd); + isMoving = false; + } + + function onTouchMove(e) { + if ($.spotSwipe.preventDefault) { e.preventDefault(); } + if(isMoving) { + var x = e.touches[0].pageX; + var y = e.touches[0].pageY; + var dx = startPosX - x; + var dy = startPosY - y; + var dir; + elapsedTime = new Date().getTime() - startTime; + if(Math.abs(dx) >= $.spotSwipe.moveThreshold && elapsedTime <= $.spotSwipe.timeThreshold) { + dir = dx > 0 ? 'left' : 'right'; + } + else if(Math.abs(dy) >= $.spotSwipe.moveThreshold && elapsedTime <= $.spotSwipe.timeThreshold) { + dir = dy > 0 ? 'down' : 'up'; + } + if(dir) { + onTouchEnd.call(this); + $(this).trigger('swipe', dir).trigger('swipe' + dir); + } + } + } + + function onTouchStart(e) { + if (e.touches.length == 1) { + startPosX = e.touches[0].pageX; + startPosY = e.touches[0].pageY; + isMoving = true; + startTime = new Date().getTime(); + this.addEventListener('touchmove', onTouchMove, false); + this.addEventListener('touchend', onTouchEnd, false); + } + } + + function init() { + this.addEventListener && this.addEventListener('touchstart', onTouchStart, false); + } + + function teardown() { + this.removeEventListener('touchstart', onTouchStart); + } + + $.event.special.swipe = { setup: init }; + + $.each(['left', 'up', 'down', 'right'], function () { + $.event.special['swipe' + this] = { setup: function(){ + $(this).on('swipe', $.noop); + } }; + }); +})(jQuery); +/**************************************************** + * Method for adding psuedo drag events to elements * + ***************************************************/ +!function($){ + $.fn.addTouch = function(){ + this.each(function(i,el){ + $(el).bind('touchstart touchmove touchend touchcancel',function(){ + //we pass the original event object because the jQuery event + //object is normalized to w3c specs and does not provide the TouchList + handleTouch(event); + }); + }); + + var handleTouch = function(event){ + var touches = event.changedTouches, + first = touches[0], + eventTypes = { + touchstart: 'mousedown', + touchmove: 'mousemove', + touchend: 'mouseup' + }, + type = eventTypes[event.type]; + + var simulatedEvent = document.createEvent('MouseEvent'); + simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0/*left*/, null); + first.target.dispatchEvent(simulatedEvent); + }; + }; +}(jQuery); + + +//********************************** +//**From the jQuery Mobile Library** +//**need to recreate functionality** +//**and try to improve if possible** +//********************************** + +/* Removing the jQuery function **** +************************************ + +(function( $, window, undefined ) { + + var $document = $( document ), + // supportTouch = $.mobile.support.touch, + touchStartEvent = 'touchstart'//supportTouch ? "touchstart" : "mousedown", + touchStopEvent = 'touchend'//supportTouch ? "touchend" : "mouseup", + touchMoveEvent = 'touchmove'//supportTouch ? "touchmove" : "mousemove"; + + // setup new event shortcuts + $.each( ( "touchstart touchmove touchend " + + "swipe swipeleft swiperight" ).split( " " ), function( i, name ) { + + $.fn[ name ] = function( fn ) { + return fn ? this.bind( name, fn ) : this.trigger( name ); + }; + + // jQuery < 1.8 + if ( $.attrFn ) { + $.attrFn[ name ] = true; + } + }); + + function triggerCustomEvent( obj, eventType, event, bubble ) { + var originalType = event.type; + event.type = eventType; + if ( bubble ) { + $.event.trigger( event, undefined, obj ); + } else { + $.event.dispatch.call( obj, event ); + } + event.type = originalType; + } + + // also handles taphold + + // Also handles swipeleft, swiperight + $.event.special.swipe = { + + // More than this horizontal displacement, and we will suppress scrolling. + scrollSupressionThreshold: 30, + + // More time than this, and it isn't a swipe. + durationThreshold: 1000, + + // Swipe horizontal displacement must be more than this. + horizontalDistanceThreshold: window.devicePixelRatio >= 2 ? 15 : 30, + + // Swipe vertical displacement must be less than this. + verticalDistanceThreshold: window.devicePixelRatio >= 2 ? 15 : 30, + + getLocation: function ( event ) { + var winPageX = window.pageXOffset, + winPageY = window.pageYOffset, + x = event.clientX, + y = event.clientY; + + if ( event.pageY === 0 && Math.floor( y ) > Math.floor( event.pageY ) || + event.pageX === 0 && Math.floor( x ) > Math.floor( event.pageX ) ) { + + // iOS4 clientX/clientY have the value that should have been + // in pageX/pageY. While pageX/page/ have the value 0 + x = x - winPageX; + y = y - winPageY; + } else if ( y < ( event.pageY - winPageY) || x < ( event.pageX - winPageX ) ) { + + // Some Android browsers have totally bogus values for clientX/Y + // when scrolling/zooming a page. Detectable since clientX/clientY + // should never be smaller than pageX/pageY minus page scroll + x = event.pageX - winPageX; + y = event.pageY - winPageY; + } + + return { + x: x, + y: y + }; + }, + + start: function( event ) { + var data = event.originalEvent.touches ? + event.originalEvent.touches[ 0 ] : event, + location = $.event.special.swipe.getLocation( data ); + return { + time: ( new Date() ).getTime(), + coords: [ location.x, location.y ], + origin: $( event.target ) + }; + }, + + stop: function( event ) { + var data = event.originalEvent.touches ? + event.originalEvent.touches[ 0 ] : event, + location = $.event.special.swipe.getLocation( data ); + return { + time: ( new Date() ).getTime(), + coords: [ location.x, location.y ] + }; + }, + + handleSwipe: function( start, stop, thisObject, origTarget ) { + if ( stop.time - start.time < $.event.special.swipe.durationThreshold && + Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold && + Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) { + var direction = start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight"; + + triggerCustomEvent( thisObject, "swipe", $.Event( "swipe", { target: origTarget, swipestart: start, swipestop: stop }), true ); + triggerCustomEvent( thisObject, direction,$.Event( direction, { target: origTarget, swipestart: start, swipestop: stop } ), true ); + return true; + } + return false; + + }, + + // This serves as a flag to ensure that at most one swipe event event is + // in work at any given time + eventInProgress: false, + + setup: function() { + var events, + thisObject = this, + $this = $( thisObject ), + context = {}; + + // Retrieve the events data for this element and add the swipe context + events = $.data( this, "mobile-events" ); + if ( !events ) { + events = { length: 0 }; + $.data( this, "mobile-events", events ); + } + events.length++; + events.swipe = context; + + context.start = function( event ) { + + // Bail if we're already working on a swipe event + if ( $.event.special.swipe.eventInProgress ) { + return; + } + $.event.special.swipe.eventInProgress = true; + + var stop, + start = $.event.special.swipe.start( event ), + origTarget = event.target, + emitted = false; + + context.move = function( event ) { + if ( !start || event.isDefaultPrevented() ) { + return; + } + + stop = $.event.special.swipe.stop( event ); + if ( !emitted ) { + emitted = $.event.special.swipe.handleSwipe( start, stop, thisObject, origTarget ); + if ( emitted ) { + + // Reset the context to make way for the next swipe event + $.event.special.swipe.eventInProgress = false; + } + } + // prevent scrolling + if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) { + event.preventDefault(); + } + }; + + context.stop = function() { + emitted = true; + + // Reset the context to make way for the next swipe event + $.event.special.swipe.eventInProgress = false; + $document.off( touchMoveEvent, context.move ); + context.move = null; + }; + + $document.on( touchMoveEvent, context.move ) + .one( touchStopEvent, context.stop ); + }; + $this.on( touchStartEvent, context.start ); + }, + + teardown: function() { + var events, context; + + events = $.data( this, "mobile-events" ); + if ( events ) { + context = events.swipe; + delete events.swipe; + events.length--; + if ( events.length === 0 ) { + $.removeData( this, "mobile-events" ); + } + } + + if ( context ) { + if ( context.start ) { + $( this ).off( touchStartEvent, context.start ); + } + if ( context.move ) { + $document.off( touchMoveEvent, context.move ); + } + if ( context.stop ) { + $document.off( touchStopEvent, context.stop ); + } + } + } + }; + $.each({ + swipeleft: "swipe.left", + swiperight: "swipe.right" + }, function( event, sourceEvent ) { + + $.event.special[ event ] = { + setup: function() { + $( this ).bind( sourceEvent, $.noop ); + }, + teardown: function() { + $( this ).unbind( sourceEvent ); + } + }; + }); +})( jQuery, this ); +*/ + +!function(Foundation, $) { + 'use strict'; + // Elements with [data-open] will reveal a plugin that supports it when clicked. + $(document).on('click.zf.trigger', '[data-open]', function() { + var id = $(this).data('open'); + $('#' + id).triggerHandler('open.zf.trigger', [$(this)]); + }); + + // Elements with [data-close] will close a plugin that supports it when clicked. + // If used without a value on [data-close], the event will bubble, allowing it to close a parent component. + $(document).on('click.zf.trigger', '[data-close]', function() { + var id = $(this).data('close'); + if (id) { + $('#' + id).triggerHandler('close.zf.trigger', [$(this)]); + } + else { + $(this).trigger('close.zf.trigger'); + } + }); + + // Elements with [data-toggle] will toggle a plugin that supports it when clicked. + $(document).on('click.zf.trigger', '[data-toggle]', function() { + var id = $(this).data('toggle'); + $('#' + id).triggerHandler('toggle.zf.trigger', [$(this)]); + }); + + // Elements with [data-closable] will respond to close.zf.trigger events. + $(document).on('close.zf.trigger', '[data-closable]', function() { + var animation = $(this).data('closable') || 'fade-out'; + if(Foundation.Motion){ + Foundation.Motion.animateOut($(this), animation, function() { + $(this).trigger('closed.zf'); + }); + }else{ + $(this).fadeOut().trigger('closed.zf'); + } + }); + + var MutationObserver = (function () { + var prefixes = ['WebKit', 'Moz', 'O', 'Ms', '']; + for (var i=0; i < prefixes.length; i++) { + if (prefixes[i] + 'MutationObserver' in window) { + return window[prefixes[i] + 'MutationObserver']; + } + } + return false; + }()); + + + var checkListeners = function(){ + eventsListener(); + resizeListener(); + scrollListener(); + closemeListener(); + }; + /** + * Fires once after all other scripts have loaded + * @function + * @private + */ + $(window).load(function(){ + checkListeners(); + }); + + //******** only fires this function once on load, if there's something to watch ******** + var closemeListener = function(pluginName){ + var yetiBoxes = $('[data-yeti-box]'), + plugNames = ['dropdown', 'tooltip', 'reveal']; + + if(pluginName){ + if(typeof pluginName === 'string'){ + plugNames.push(pluginName); + }else if(typeof pluginName === 'object' && typeof pluginName[0] === 'string'){ + plugNames.concat(pluginName); + }else{ + console.error('Plugin names must be strings'); + } + } + if(yetiBoxes.length){ + var listeners = plugNames.map(function(name){ + return 'closeme.zf.' + name; + }).join(' '); + + $(window).off(listeners).on(listeners, function(e, pluginId){ + var plugin = e.namespace.split('.')[0]; + var plugins = $('[data-' + plugin + ']').not('[data-yeti-box="' + pluginId + '"]'); + + plugins.each(function(){ + var _this = $(this); + + _this.triggerHandler('close.zf.trigger', [_this]); + }); + }); + } + }; + var resizeListener = function(debounce){ + var timer, + $nodes = $('[data-resize]'); + if($nodes.length){ + $(window).off('resize.zf.trigger') + .on('resize.zf.trigger', function(e) { + if (timer) { clearTimeout(timer); } + + timer = setTimeout(function(){ + + if(!MutationObserver){//fallback for IE 9 + $nodes.each(function(){ + $(this).triggerHandler('resizeme.zf.trigger'); + }); + } + //trigger all listening elements and signal a resize event + $nodes.attr('data-events', "resize"); + }, debounce || 10);//default time to emit resize event + }); + } + }; + var scrollListener = function(debounce){ + var timer, + $nodes = $('[data-scroll]'); + if($nodes.length){ + $(window).off('scroll.zf.trigger') + .on('scroll.zf.trigger', function(e){ + if(timer){ clearTimeout(timer); } + + timer = setTimeout(function(){ + + if(!MutationObserver){//fallback for IE 9 + $nodes.each(function(){ + $(this).triggerHandler('scrollme.zf.trigger'); + }); + } + //trigger all listening elements and signal a scroll event + $nodes.attr('data-events', "scroll"); + }, debounce || 10);//default time to emit scroll event + }); + } + }; + // function domMutationObserver(debounce) { + // // !!! This is coming soon and needs more work; not active !!! // + // var timer, + // nodes = document.querySelectorAll('[data-mutate]'); + // // + // if (nodes.length) { + // // var MutationObserver = (function () { + // // var prefixes = ['WebKit', 'Moz', 'O', 'Ms', '']; + // // for (var i=0; i < prefixes.length; i++) { + // // if (prefixes[i] + 'MutationObserver' in window) { + // // return window[prefixes[i] + 'MutationObserver']; + // // } + // // } + // // return false; + // // }()); + // + // + // //for the body, we need to listen for all changes effecting the style and class attributes + // var bodyObserver = new MutationObserver(bodyMutation); + // bodyObserver.observe(document.body, { attributes: true, childList: true, characterData: false, subtree:true, attributeFilter:["style", "class"]}); + // + // + // //body callback + // function bodyMutation(mutate) { + // //trigger all listening elements and signal a mutation event + // if (timer) { clearTimeout(timer); } + // + // timer = setTimeout(function() { + // bodyObserver.disconnect(); + // $('[data-mutate]').attr('data-events',"mutate"); + // }, debounce || 150); + // } + // } + // } + var eventsListener = function() { + if(!MutationObserver){ return false; } + var nodes = document.querySelectorAll('[data-resize], [data-scroll], [data-mutate]'); + + //element callback + var listeningElementsMutation = function(mutationRecordsList) { + var $target = $(mutationRecordsList[0].target); + //trigger the event handler for the element depending on type + switch ($target.attr("data-events")) { + + case "resize" : + $target.triggerHandler('resizeme.zf.trigger', [$target]); + break; + + case "scroll" : + $target.triggerHandler('scrollme.zf.trigger', [$target, window.pageYOffset]); + break; + + // case "mutate" : + // console.log('mutate', $target); + // $target.triggerHandler('mutate.zf.trigger'); + // + // //make sure we don't get stuck in an infinite loop from sloppy codeing + // if ($target.index('[data-mutate]') == $("[data-mutate]").length-1) { + // domMutationObserver(); + // } + // break; + + default : + return false; + //nothing + } + } + + if(nodes.length){ + //for each element that needs to listen for resizing, scrolling, (or coming soon mutation) add a single observer + for (var i = 0; i <= nodes.length-1; i++) { + var elementObserver = new MutationObserver(listeningElementsMutation); + elementObserver.observe(nodes[i], { attributes: true, childList: false, characterData: false, subtree:false, attributeFilter:["data-events"]}); + } + } + }; + // ------------------------------------ + + // [PH] + // Foundation.CheckWatchers = checkWatchers; + Foundation.IHearYou = checkListeners; + // Foundation.ISeeYou = scrollListener; + // Foundation.IFeelYou = closemeListener; + +}(window.Foundation, window.jQuery); + +!function(Foundation, $) { + 'use strict'; + + /** + * Creates a new instance of Abide. + * @class + * @fires Abide#init + * @param {Object} element - jQuery object to add the trigger to. + * @param {Object} options - Overrides to the default plugin settings. + */ + function Abide(element, options) { + this.$element = element; + this.options = $.extend({}, Abide.defaults, this.$element.data(), options); + this.$window = $(window); + this.name = 'Abide'; + this.attr = 'data-abide'; + + this._init(); + this._events(); + + Foundation.registerPlugin(this); + } + + /** + * Default settings for plugin + */ + Abide.defaults = { + validateOn: 'fieldChange', // options: fieldChange, manual, submit + labelErrorClass: 'is-invalid-label', + inputErrorClass: 'is-invalid-input', + formErrorSelector: '.form-error', + formErrorClass: 'is-visible', + patterns: { + alpha : /^[a-zA-Z]+$/, + alpha_numeric : /^[a-zA-Z0-9]+$/, + integer : /^[-+]?\d+$/, + number : /^[-+]?\d*(?:[\.\,]\d+)?$/, + + // amex, visa, diners + card : /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/, + cvv : /^([0-9]){3,4}$/, + + // http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address + email : /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/, + + url : /^(https?|ftp|file|ssh):\/\/(((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/, + // abc.de + domain : /^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,8}$/, + + datetime : /^([0-2][0-9]{3})\-([0-1][0-9])\-([0-3][0-9])T([0-5][0-9])\:([0-5][0-9])\:([0-5][0-9])(Z|([\-\+]([0-1][0-9])\:00))$/, + // YYYY-MM-DD + date : /(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))$/, + // HH:MM:SS + time : /^(0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9]){2}$/, + dateISO : /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/, + // MM/DD/YYYY + month_day_year : /^(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.]\d{4}$/, + // DD/MM/YYYY + day_month_year : /^(0[1-9]|[12][0-9]|3[01])[- \/.](0[1-9]|1[012])[- \/.]\d{4}$/, + + // #FFF or #FFFFFF + color : /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/ + }, + validators: { + equalTo: function (el, required, parent) { + var from = document.getElementById(el.getAttribute(this.add_namespace('data-equalto'))).value, + to = el.value, + valid = (from === to); + + return valid; + } + } + }; + + + /** + * Initializes the Abide plugin and calls functions to get Abide functioning on load. + * @private + */ + Abide.prototype._init = function() { + }; + + /** + * Initializes events for Abide. + * @private + */ + Abide.prototype._events = function() { + var self = this; + this.$element + .off('.abide') + .on('reset.fndtn.abide', function(e) { + self.resetForm($(this)); + }) + .on('submit.fndtn.abide', function(e) { + e.preventDefault(); + self.validateForm(self.$element); + }) + .find('input, textarea, select') + .off('.abide') + .on('blur.fndtn.abide change.fndtn.abide', function (e) { + if (self.options.validateOn === 'fieldChange') { + self.validateInput($(e.target), self.$element); + } + // self.validateForm(self.$element); + }) + .on('keydown.fndtn.abide', function (e) { + // if (settings.live_validate === true && e.which != 9) { + // clearTimeout(self.timer); + // self.timer = setTimeout(function () { + // self.validate([this], e); + // }.bind(this), settings.timeout); + // } + // self.validateForm(self.$element); + }); + + }, + /** + * Calls necessary functions to update Abide upon DOM change + * @private + */ + Abide.prototype._reflow = function() { + var self = this; + }; + /** + * Checks whether or not a form element has the required attribute and if it's checked or not + * @param {Object} element - jQuery object to check for required attribute + * @returns {Boolean} Boolean value depends on whether or not attribute is checked or empty + */ + Abide.prototype.requiredCheck = function($el) { + switch ($el[0].type) { + case 'text': + if ($el.attr('required') && !$el.val()) { + // requirement check does not pass + return false; + } else { + return true; + } + break; + case 'checkbox': + if ($el.attr('required') && !$el.is(':checked')) { + return false; + } else { + return true; + } + break; + case 'radio': + if ($el.attr('required') && !$el.is(':checked')) { + return false; + } else { + return true; + } + break; + default: + if ($el.attr('required') && (!$el.val() || !$el.val().length || $el.is(':empty'))) { + return false; + } else { + return true; + } + } + }; + /** + * Checks whether or not a form element has the required attribute and if it's checked or not + * @param {Object} element - jQuery object to check for required attribute + * @returns {Boolean} Boolean value depends on whether or not attribute is checked or empty + */ + Abide.prototype.findLabel = function($el) { + if ($el.next('label').length) { + return $el.next('label'); + } + else { + return $el.closest('label'); + } + }; + /** + * Adds the CSS error class as specified by the Abide settings to the label, input, and the form + * @param {Object} element - jQuery object to add the class to + */ + Abide.prototype.addErrorClasses = function($el) { + var self = this, + $label = self.findLabel($el), + $formError = $el.next(self.options.formErrorSelector) || $el.find(self.options.formErrorSelector); + + // label + if ($label) { + $label.addClass(self.options.labelErrorClass); + } + // form error + if ($formError) { + $formError.addClass(self.options.formErrorClass); + } + // input + $el.addClass(self.options.inputErrorClass); + }; + /** + * Removes CSS error class as specified by the Abide settings from the label, input, and the form + * @param {Object} element - jQuery object to remove the class from + */ + Abide.prototype.removeErrorClasses = function($el) { + var self = this, + $label = self.findLabel($el), + $formError = $el.next(self.options.formErrorSelector) || $el.find(self.options.formErrorSelector); + // label + if ($label && $label.hasClass(self.options.labelErrorClass)) { + $label.removeClass(self.options.labelErrorClass); + } + // form error + if ($formError && $formError.hasClass(self.options.formErrorClass)) { + $formError.removeClass(self.options.formErrorClass); + } + // input + if ($el.hasClass(self.options.inputErrorClass)) { + $el.removeClass(self.options.inputErrorClass); + } + }; + /** + * Goes through a form to find inputs and proceeds to validate them in ways specific to their type + * @fires Abide#invalid + * @fires Abide#valid + * @param {Object} element - jQuery object to validate, should be an HTML input + * @param {Object} form - jQuery object of the entire form to find the various input elements + */ + Abide.prototype.validateInput = function($el, $form) { + var self = this, + textInput = $form.find('input[type="text"]'), + checkInput = $form.find('input[type="checkbox"]'), + label, + radioGroupName; + + if ($el[0].type === 'text') { + if (!self.requiredCheck($el) || !self.validateText($el)) { + self.addErrorClasses($el); + $el.trigger('invalid.fndtn.abide', $el[0]); + } + else { + self.removeErrorClasses($el); + $el.trigger('valid.fndtn.abide', $el[0]); + } + } + else if ($el[0].type === 'radio') { + radioGroupName = $el.attr('name'); + label = $el.siblings('label'); + + if (self.validateRadio(radioGroupName)) { + $(label).each(function() { + if ($(this).hasClass(self.options.labelErrorClass)) { + $(this).removeClass(self.options.labelErrorClass); + } + }); + $el.trigger('valid.fndtn.abide', $el[0]); + } + else { + $(label).each(function() { + $(this).addClass(self.options.labelErrorClass); + }); + $el.trigger('invalid.fndtn.abide', $el[0]); + }; + } + else if ($el[0].type === 'checkbox') { + if (!self.requiredCheck($el)) { + self.addErrorClasses($el); + $el.trigger('invalid.fndtn.abide', $el[0]); + } + else { + self.removeErrorClasses($el); + $el.trigger('valid.fndtn.abide', $el[0]); + } + } + else { + if (!self.requiredCheck($el) || !self.validateText($el)) { + self.addErrorClasses($el); + $el.trigger('invalid.fndtn.abide', $el[0]); + } + else { + self.removeErrorClasses($el); + $el.trigger('valid.fndtn.abide', $el[0]); + } + } + }; + /** + * Goes through a form and if there are any invalid inputs, it will display the form error element + * @param {Object} element - jQuery object to validate, should be a form HTML element + */ + Abide.prototype.validateForm = function($form) { + var self = this, + inputs = $form.find('input'), + inputCount = $form.find('input').length, + counter = 0; + + while (counter < inputCount) { + self.validateInput($(inputs[counter]), $form); + counter++; + } + + // what are all the things that can go wrong with a form? + if ($form.find('.form-error.is-visible').length || $form.find('.is-invalid-label').length) { + $form.find('[data-abide-error]').css('display', 'block'); + } + else { + $form.find('[data-abide-error]').css('display', 'none'); + } + }; + /** + * Determines whether or a not a text input is valid based on the patterns specified in the attribute + * @param {Object} element - jQuery object to validate, should be a text input HTML element + * @returns {Boolean} Boolean value depends on whether or not the input value matches the pattern specified + */ + Abide.prototype.validateText = function($el) { + var self = this, + valid = false, + patternLib = this.options.patterns, + inputText = $($el).val(), + // maybe have a different way of parsing this bc people might use type + pattern = $($el).attr('pattern'); + + // if there's no value, then return true + // since required check has already been done + if (inputText.length === 0) { + return true; + } + else { + if (inputText.match(patternLib[pattern])) { + return true; + } + else { + return false; + } + } + }; + /** + * Determines whether or a not a radio input is valid based on whether or not it is required and selected + * @param {String} group - A string that specifies the name of a radio button group + * @returns {Boolean} Boolean value depends on whether or not at least one radio input has been selected (if it's required) + */ + Abide.prototype.validateRadio = function(group) { + var self = this, + labels = $(':radio[name="' + group + '"]').siblings('label'), + counter = 0; + // go through each radio button + $(':radio[name="' + group + '"]').each(function() { + // put them through the required checkpoint + if (!self.requiredCheck($(this))) { + // if at least one doesn't pass, add a tally to the counter + counter++; + } + // if at least one is checked + // reset the counter + if ($(this).is(':checked')) { + counter = 0; + } + }); + + if (counter > 0) { + return false; + } + else { + return true; + } + }; + Abide.prototype.matchValidation = function(val, validation) { + + }; + /** + * Resets form inputs and styles + * @param {Object} $form - A jQuery object that should be an HTML form element + */ + Abide.prototype.resetForm = function($form) { + var self = this; + var invalidAttr = 'data-invalid'; + // remove data attributes + $('[' + self.invalidAttr + ']', $form).removeAttr(invalidAttr); + // remove styles + $('.' + self.options.labelErrorClass, $form).not('small').removeClass(self.options.labelErrorClass); + $('.' + self.options.inputErrorClass, $form).not('small').removeClass(self.options.inputErrorClass); + $('.form-error.is-visible').removeClass('is-visible'); + $form.find('[data-abide-error]').css('display', 'none'); + $(':input', $form).not(':button, :submit, :reset, :hidden, [data-abide-ignore]').val('').removeAttr(invalidAttr); + }; + Abide.prototype.destroy = function(){ + //TODO this... + }; + + Foundation.plugin(Abide, 'Abide'); + + // Exports for AMD/Browserify + if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') + module.exports = Abide; + if (typeof define === 'function') + define(['foundation'], function() { + return Abide; + }); + +}(Foundation, jQuery); + +/** + * Accordion module. + * @module foundation.accordion + * @requires foundation.util.keyboard + * @requires foundation.util.motion + */ +!function($, Foundation) { + 'use strict'; + + /** + * Creates a new instance of an accordion. + * @class + * @fires Accordion#init + * @param {jQuery} element - jQuery object to make into an accordion. + */ + function Accordion(element, options){ + this.$element = element; + this.options = $.extend({}, Accordion.defaults, this.$element.data(), options); + + this._init(); + + Foundation.registerPlugin(this); + Foundation.Keyboard.register('Accordion', { + 'ENTER': 'toggle', + 'SPACE': 'toggle', + 'ARROW_DOWN': 'next', + 'ARROW_UP': 'previous' + }); + } + + Accordion.defaults = { + /** + * Amount of time to animate the opening of an accordion pane. + * @option + * @example 250 + */ + slideSpeed: 250, + /** + * Allow the accordion to have multiple open panes. + * @option + * @example false + */ + multiExpand: false, + /** + * Allow the accordion to close all panes. + * @option + * @example false + */ + allowAllClosed: false + }; + + /** + * Initializes the accordion by animating the preset active pane(s). + * @private + */ + Accordion.prototype._init = function() { + this.$element.attr('role', 'tablist'); + this.$tabs = this.$element.children('li'); + this.$tabs.each(function(idx, el){ + + var $el = $(el), + $content = $el.find('[data-tab-content]'), + id = $content[0].id || Foundation.GetYoDigits(6, 'accordion'), + linkId = el.id || id + '-label'; + + $el.find('a:first').attr({ + 'aria-controls': id, + 'role': 'tab', + 'id': linkId, + 'aria-expanded': false, + 'aria-selected': false + }); + $content.attr({'role': 'tabpanel', 'aria-labelledby': linkId, 'aria-hidden': true, 'id': id}); + }); + var $initActive = this.$element.find('.is-active').children('[data-tab-content]'); + if($initActive.length){ + this.down($initActive, true); + } + this._events(); + }; + + /** + * Adds event handlers for items within the accordion. + * @private + */ + Accordion.prototype._events = function() { + var _this = this; + + this.$tabs.each(function(){ + var $elem = $(this); + var $tabContent = $elem.children('[data-tab-content]'); + if ($tabContent.length) { + $elem.children('a').off('click.zf.accordion keydown.zf.accordion') + .on('click.zf.accordion', function(e){ + // $(this).children('a').on('click.zf.accordion', function(e) { + e.preventDefault(); + if ($elem.hasClass('is-active')) { + if(_this.options.allowAllClosed || $elem.siblings().hasClass('is-active')){ + _this.up($tabContent); + } + } + else { + _this.down($tabContent); + } + }).on('keydown.zf.accordion', function(e){ + Foundation.Keyboard.handleKey(e, _this, { + toggle: function() { + _this.toggle($tabContent); + }, + next: function() { + $elem.next().find('a').focus().trigger('click.zf.accordion'); + }, + previous: function() { + $elem.prev().find('a').focus().trigger('click.zf.accordion'); + }, + handled: function() { + e.preventDefault(); + e.stopPropagation(); + } + }); + }); + } + }); + }; + /** + * Toggles the selected content pane's open/close state. + * @param {jQuery} $target - jQuery object of the pane to toggle. + * @function + */ + Accordion.prototype.toggle = function($target){ + if($target.parent().hasClass('is-active')){ + if(this.options.allowAllClosed || $target.parent().siblings().hasClass('is-active')){ + this.up($target); + }else{ return; } + }else{ + this.down($target); + } + }; + /** + * Opens the accordion tab defined by `$target`. + * @param {jQuery} $target - Accordion pane to open. + * @param {Boolean} firstTime - flag to determine if reflow should happen. + * @fires Accordion#down + * @function + */ + Accordion.prototype.down = function($target, firstTime) { + var _this = this; + if(!this.options.multiExpand && !firstTime){ + var $currentActive = this.$element.find('.is-active').children('[data-tab-content]'); + if($currentActive.length){ + this.up($currentActive); + } + } + + $target + .attr('aria-hidden', false) + .parent('[data-tab-content]') + .addBack() + .parent().addClass('is-active'); + + Foundation.Move(_this.options.slideSpeed, $target, function(){ + $target.slideDown(_this.options.slideSpeed); + }); + + if(!firstTime){ + Foundation._reflow(this.$element.attr('data-accordion')); + } + $('#' + $target.attr('aria-labelledby')).attr({ + 'aria-expanded': true, + 'aria-selected': true + }); + /** + * Fires when the tab is done opening. + * @event Accordion#down + */ + this.$element.trigger('down.zf.accordion', [$target]); + }; + + /** + * Closes the tab defined by `$target`. + * @param {jQuery} $target - Accordion tab to close. + * @fires Accordion#up + * @function + */ + Accordion.prototype.up = function($target) { + var $aunts = $target.parent().siblings(), + _this = this; + var canClose = this.options.multiExpand ? $aunts.hasClass('is-active') : $target.parent().hasClass('is-active'); + + if(!this.options.allowAllClosed && !canClose){ + return; + } + + Foundation.Move(this.options.slideSpeed, $target, function(){ + $target.slideUp(_this.options.slideSpeed); + }); + + $target.attr('aria-hidden', true) + .parent().removeClass('is-active'); + + $('#' + $target.attr('aria-labelledby')).attr({ + 'aria-expanded': false, + 'aria-selected': false + }); + + /** + * Fires when the tab is done collapsing up. + * @event Accordion#up + */ + this.$element.trigger('up.zf.accordion', [$target]); + }; + + /** + * Destroys an instance of an accordion. + * @fires Accordion#destroyed + * @function + */ + Accordion.prototype.destroy = function() { + this.$element.find('[data-tab-content]').slideUp(0).css('display', ''); + this.$element.find('a').off('.zf.accordion'); + + Foundation.unregisterPlugin(this); + }; + + Foundation.plugin(Accordion, 'Accordion'); +}(jQuery, window.Foundation); + +/** + * AccordionMenu module. + * @module foundation.accordionMenu + * @requires foundation.util.keyboard + * @requires foundation.util.motion + * @requires foundation.util.nest + */ +!function($) { + 'use strict'; + + /** + * Creates a new instance of an accordion menu. + * @class + * @fires AccordionMenu#init + * @param {jQuery} element - jQuery object to make into an accordion menu. + * @param {Object} options - Overrides to the default plugin settings. + */ + function AccordionMenu(element, options) { + this.$element = element; + this.options = $.extend({}, AccordionMenu.defaults, this.$element.data(), options); + + Foundation.Nest.Feather(this.$element, 'accordion'); + + this._init(); + + Foundation.registerPlugin(this); + Foundation.Keyboard.register('AccordionMenu', { + 'ENTER': 'toggle', + 'SPACE': 'toggle', + 'ARROW_RIGHT': 'open', + 'ARROW_UP': 'up', + 'ARROW_DOWN': 'down', + 'ARROW_LEFT': 'close', + 'ESCAPE': 'closeAll', + 'TAB': 'down', + 'SHIFT_TAB': 'up' + }); + } + + AccordionMenu.defaults = { + /** + * Amount of time to animate the opening of a submenu in ms. + * @option + * @example 250 + */ + slideSpeed: 250, + /** + * Allow the menu to have multiple open panes. + * @option + * @example true + */ + multiOpen: true + }; + + /** + * Initializes the accordion menu by hiding all nested menus. + * @private + */ + AccordionMenu.prototype._init = function() { + this.$element.find('[data-submenu]').not('.is-active').slideUp(0);//.find('a').css('padding-left', '1rem'); + this.$element.attr({ + 'role': 'tablist', + 'aria-multiselectable': this.options.multiOpen + }); + + this.$menuLinks = this.$element.find('.has-submenu'); + this.$menuLinks.each(function(){ + var linkId = this.id || Foundation.GetYoDigits(6, 'acc-menu-link'), + $elem = $(this), + $sub = $elem.children('[data-submenu]'), + subId = $sub[0].id || Foundation.GetYoDigits(6, 'acc-menu'), + isActive = $sub.hasClass('is-active'); + $elem.attr({ + 'aria-controls': subId, + 'aria-expanded': isActive, + 'aria-selected': false, + 'role': 'tab', + 'id': linkId + }); + $sub.attr({ + 'aria-labelledby': linkId, + 'aria-hidden': !isActive, + 'role': 'tabpanel', + 'id': subId + }); + }); + var initPanes = this.$element.find('.is-active'); + if(initPanes.length){ + var _this = this; + initPanes.each(function(){ + _this.down($(this)); + }); + } + this._events(); + }; + + /** + * Adds event handlers for items within the menu. + * @private + */ + AccordionMenu.prototype._events = function() { + var _this = this; + + this.$element.find('li').each(function() { + var $submenu = $(this).children('[data-submenu]'); + + if ($submenu.length) { + $(this).children('a').off('click.zf.accordionmenu').on('click.zf.accordionmenu', function(e) { + e.preventDefault(); + + _this.toggle($submenu); + }); + } + }).on('keydown.zf.accordionmenu', function(e){ + var $element = $(this), + $elements = $element.parent('ul').children('li'), + $prevElement, + $nextElement, + $target = $element.children('[data-submenu]'); + + $elements.each(function(i) { + if ($(this).is($element)) { + $prevElement = $elements.eq(Math.max(0, i-1)); + $nextElement = $elements.eq(Math.min(i+1, $elements.length-1)); + + if ($(this).children('[data-submenu]:visible').length) { // has open sub menu + $nextElement = $element.find('li:first-child'); + } + if ($(this).is(':first-child')) { // is first element of sub menu + $prevElement = $element.parents('li').first(); + } else if ($prevElement.children('[data-submenu]:visible').length) { // if previous element has open sub menu + $prevElement = $prevElement.find('li:last-child'); + } + if ($(this).is(':last-child')) { // is last element of sub menu + $nextElement = $element.parents('li').first().next('li'); + } + + return; + } + }); + Foundation.Keyboard.handleKey(e, _this, { + open: function() { + if ($target.is(':hidden')) { + _this.down($target); + $target.find('li').first().focus(); + } + }, + close: function() { + if ($target.length && !$target.is(':hidden')) { // close active sub of this item + _this.up($target); + } else if ($element.parent('[data-submenu]').length) { // close currently open sub + _this.up($element.parent('[data-submenu]')); + $element.parents('li').first().focus(); + } + }, + up: function() { + $prevElement.focus(); + }, + down: function() { + $nextElement.focus(); + }, + toggle: function() { + if ($element.children('[data-submenu]').length) { + _this.toggle($element.children('[data-submenu]')); + } + }, + closeAll: function() { + _this.hideAll(); + }, + handled: function() { + e.preventDefault(); + e.stopImmediatePropagation(); + } + }); + });//.attr('tabindex', 0); + }; + /** + * Closes all panes of the menu. + * @function + */ + AccordionMenu.prototype.hideAll = function(){ + this.$element.find('[data-submenu]').slideUp(this.options.slideSpeed); + }; + /** + * Toggles the open/close state of a submenu. + * @function + * @param {jQuery} $target - the submenu to toggle + */ + AccordionMenu.prototype.toggle = function($target){ + if(!$target.is(':animated')) { + if (!$target.is(':hidden')) { + this.up($target); + } + else { + this.down($target); + } + } + }; + /** + * Opens the sub-menu defined by `$target`. + * @param {jQuery} $target - Sub-menu to open. + * @fires AccordionMenu#down + */ + AccordionMenu.prototype.down = function($target) { + var _this = this; + + if(!this.options.multiOpen){ + this.up(this.$element.find('.is-active').not($target.parentsUntil(this.$element).add($target))); + } + + $target.addClass('is-active').attr({'aria-hidden': false}) + .parent('.has-submenu').attr({'aria-expanded': true, 'aria-selected': true}); + + Foundation.Move(this.options.slideSpeed, $target, function(){ + $target.slideDown(_this.options.slideSpeed); + }); + /** + * Fires when the menu is done collapsing up. + * @event AccordionMenu#down + */ + this.$element.trigger('down.zf.accordionMenu', [$target]); + }; + + /** + * Closes the sub-menu defined by `$target`. All sub-menus inside the target will be closed as well. + * @param {jQuery} $target - Sub-menu to close. + * @fires AccordionMenu#up + */ + AccordionMenu.prototype.up = function($target) { + var _this = this; + Foundation.Move(this.options.slideSpeed, $target, function(){ + $target.slideUp(_this.options.slideSpeed); + }); + $target.attr('aria-hidden', true) + .find('[data-submenu]').slideUp(0).attr('aria-hidden', true).end() + .parent('.has-submenu') + .attr({'aria-expanded': false, 'aria-selected': false}); + // $target.slideUp(this.options.slideSpeed, function() { + // $target.find('[data-submenu]').slideUp(0).attr('aria-hidden', true); + // }).attr('aria-hidden', true).parent('.has-submenu').attr({'aria-expanded': false, 'aria-selected': false}); + + /** + * Fires when the menu is done collapsing up. + * @event AccordionMenu#up + */ + this.$element.trigger('up.zf.accordionMenu', [$target]); + }; + + /** + * Destroys an instance of accordion menu. + * @fires AccordionMenu#destroyed + */ + AccordionMenu.prototype.destroy = function(){ + this.$element.find('[data-submenu]').slideDown(0).css('display', ''); + this.$element.find('a').off('click.zf.accordionMenu'); + + Foundation.Nest.Burn(this.$element, 'accordion'); + Foundation.unregisterPlugin(this); + }; + + Foundation.plugin(AccordionMenu, 'AccordionMenu'); +}(jQuery, window.Foundation); + +/** + * Drilldown module. + * @module foundation.drilldown + * @requires foundation.util.keyboard + * @requires foundation.util.motion + * @requires foundation.util.nest + */ +!function($, Foundation){ + 'use strict'; + + /** + * Creates a new instance of a drilldown menu. + * @class + * @param {jQuery} element - jQuery object to make into an accordion menu. + * @param {Object} options - Overrides to the default plugin settings. + */ + function Drilldown(element, options){ + this.$element = element; + this.options = $.extend({}, Drilldown.defaults, this.$element.data(), options); + + Foundation.Nest.Feather(this.$element, 'drilldown'); + + this._init(); + + Foundation.registerPlugin(this); + Foundation.Keyboard.register('Drilldown', { + 'ENTER': 'open', + 'SPACE': 'open', + 'ARROW_RIGHT': 'next', + 'ARROW_UP': 'up', + 'ARROW_DOWN': 'down', + 'ARROW_LEFT': 'previous', + 'ESCAPE': 'close', + 'TAB': 'down', + 'SHIFT_TAB': 'up' + }); + } + Drilldown.defaults = { + /** + * Markup used for JS generated back button. Prepended to submenu lists and deleted on `destroy` method, 'js-drilldown-back' class required. Remove the backslash (`\`) if copy and pasting. + * @option + * @example '<\li><\a>Back<\/a><\/li>' + */ + backButton: '
  • Back
  • ', + /** + * Markup used to wrap drilldown menu. Use a class name for independent styling; the JS applied class: `is-drilldown` is required. Remove the backslash (`\`) if copy and pasting. + * @option + * @example '<\div class="is-drilldown"><\/div>' + */ + wrapper: '
    ', + /** + * Allow the menu to return to root list on body click. + * @option + * @example false + */ + closeOnClick: false + // holdOpen: false + }; + /** + * Initializes the drilldown by creating jQuery collections of elements + * @private + */ + Drilldown.prototype._init = function(){ + this.$submenuAnchors = this.$element.find('li.has-submenu'); + this.$submenus = this.$submenuAnchors.children('[data-submenu]'); + this.$menuItems = this.$element.find('li:visible').not('.js-drilldown-back').attr('role', 'menuitem'); + + this._prepareMenu(); + + this._keyboardEvents(); + }; + /** + * prepares drilldown menu by setting attributes to links and elements + * sets a min height to prevent content jumping + * wraps the element if not already wrapped + * @private + * @function + */ + Drilldown.prototype._prepareMenu = function(){ + var _this = this; + // if(!this.options.holdOpen){ + // this._menuLinkEvents(); + // } + this.$submenuAnchors.each(function(){ + var $sub = $(this); + var $link = $sub.find('a:first'); + $link.data('savedHref', $link.attr('href')).removeAttr('href'); + $sub.children('[data-submenu]') + .attr({ + 'aria-hidden': true, + 'tabindex': 0, + 'role': 'menu' + }); + _this._events($sub); + }); + this.$submenus.each(function(){ + var $menu = $(this), + $back = $menu.find('.js-drilldown-back'); + if(!$back.length){ + $menu.prepend(_this.options.backButton); + } + _this._back($menu); + }); + if(!this.$element.parent().hasClass('is-drilldown')){ + this.$wrapper = $(this.options.wrapper).addClass('is-drilldown').css(this._getMaxDims()); + this.$element.wrap(this.$wrapper); + } + + }; + /** + * Adds event handlers to elements in the menu. + * @function + * @private + * @param {jQuery} $elem - the current menu item to add handlers to. + */ + Drilldown.prototype._events = function($elem){ + var _this = this; + + $elem.off('click.zf.drilldown') + .on('click.zf.drilldown', function(e){ + if($(e.target).parentsUntil('ul', 'li').hasClass('is-drilldown-submenu-parent')){ + e.stopImmediatePropagation(); + e.preventDefault(); + } + + // if(e.target !== e.currentTarget.firstElementChild){ + // return false; + // } + _this._show($elem); + + if(_this.options.closeOnClick){ + var $body = $('body').not(_this.$wrapper); + $body.off('.zf.drilldown').on('click.zf.drilldown', function(e){ + e.preventDefault(); + _this._hideAll(); + $body.off('.zf.drilldown'); + }); + } + }); + }; + /** + * Adds keydown event listener to `li`'s in the menu. + * @private + */ + Drilldown.prototype._keyboardEvents = function() { + var _this = this; + this.$menuItems.add(this.$element.find('.js-drilldown-back')).on('keydown.zf.drilldown', function(e){ + var $element = $(this), + $elements = $element.parent('ul').children('li'), + $prevElement, + $nextElement; + + $elements.each(function(i) { + if ($(this).is($element)) { + $prevElement = $elements.eq(Math.max(0, i-1)); + $nextElement = $elements.eq(Math.min(i+1, $elements.length-1)); + return; + } + }); + Foundation.Keyboard.handleKey(e, _this, { + next: function() { + if ($element.is(_this.$submenuAnchors)) { + _this._show($element); + $element.on(Foundation.transitionend($element), function(){ + $element.find('ul li').filter(_this.$menuItems).first().focus(); + }); + } + }, + previous: function() { + _this._hide($element.parent('ul')); + $element.parent('ul').on(Foundation.transitionend($element), function(){ + setTimeout(function() { + $element.parent('ul').parent('li').focus(); + }, 1); + }); + }, + up: function() { + $prevElement.focus(); + }, + down: function() { + $nextElement.focus(); + }, + close: function() { + _this._back(); + //_this.$menuItems.first().focus(); // focus to first element + }, + open: function() { + if (!$element.is(_this.$menuItems)) { // not menu item means back button + _this._hide($element.parent('ul')); + setTimeout(function(){$element.parent('ul').parent('li').focus();}, 1); + } else if ($element.is(_this.$submenuAnchors)) { + _this._show($element); + setTimeout(function(){$element.find('ul li').filter(_this.$menuItems).first().focus();}, 1); + } + }, + handled: function() { + e.preventDefault(); + e.stopImmediatePropagation(); + } + }); + }); // end keyboardAccess + }; + + /** + * Closes all open elements, and returns to root menu. + * @function + * @fires Drilldown#closed + */ + Drilldown.prototype._hideAll = function(){ + var $elem = this.$element.find('.is-drilldown-sub.is-active').addClass('is-closing'); + $elem.one(Foundation.transitionend($elem), function(e){ + $elem.removeClass('is-active is-closing'); + }); + /** + * Fires when the menu is fully closed. + * @event Drilldown#closed + */ + this.$element.trigger('closed.zf.drilldown'); + }; + /** + * Adds event listener for each `back` button, and closes open menus. + * @function + * @fires Drilldown#back + * @param {jQuery} $elem - the current sub-menu to add `back` event. + */ + Drilldown.prototype._back = function($elem){ + var _this = this; + $elem.off('click.zf.drilldown'); + $elem.children('.js-drilldown-back') + .on('click.zf.drilldown', function(e){ + e.stopImmediatePropagation(); + // console.log('mouseup on back'); + _this._hide($elem); + }); + }; + /** + * Adds event listener to menu items w/o submenus to close open menus on click. + * @function + * @private + */ + Drilldown.prototype._menuLinkEvents = function(){ + var _this = this; + this.$menuItems.not('.has-submenu') + .off('click.zf.drilldown') + .on('click.zf.drilldown', function(e){ + // e.stopImmediatePropagation(); + setTimeout(function(){ + _this._hideAll(); + }, 0); + }); + }; + /** + * Opens a submenu. + * @function + * @fires Drilldown#open + * @param {jQuery} $elem - the current element with a submenu to open. + */ + Drilldown.prototype._show = function($elem){ + $elem.children('[data-submenu]').addClass('is-active'); + + this.$element.trigger('open.zf.drilldown', [$elem]); + }; + /** + * Hides a submenu + * @function + * @fires Drilldown#hide + * @param {jQuery} $elem - the current sub-menu to hide. + */ + Drilldown.prototype._hide = function($elem){ + var _this = this; + $elem.addClass('is-closing') + .one(Foundation.transitionend($elem), function(){ + $elem.removeClass('is-active is-closing'); + }); + /** + * Fires when the submenu is has closed. + * @event Drilldown#hide + */ + $elem.trigger('hide.zf.drilldown', [$elem]); + + }; + /** + * Iterates through the nested menus to calculate the min-height, and max-width for the menu. + * Prevents content jumping. + * @function + * @private + */ + Drilldown.prototype._getMaxDims = function(){ + var max = 0, result = {}; + this.$submenus.add(this.$element).each(function(){ + var numOfElems = $(this).children('li').length; + max = numOfElems > max ? numOfElems : max; + }); + + result.height = max * this.$menuItems[0].getBoundingClientRect().height + 'px'; + result.width = this.$element[0].getBoundingClientRect().width + 'px'; + + return result; + }; + /** + * Destroys the Drilldown Menu + * @function + */ + Drilldown.prototype.destroy = function(){ + this._hideAll(); + Foundation.Nest.Burn(this.$element, 'drilldown'); + this.$element.unwrap() + .find('.js-drilldown-back').remove() + .end().find('.is-active, .is-closing, .is-drilldown-sub').removeClass('is-active is-closing is-drilldown-sub') + .end().find('[data-submenu]').removeAttr('aria-hidden tabindex role') + .off('.zf.drilldown').end().off('zf.drilldown'); + this.$element.find('a').each(function(){ + var $link = $(this); + if($link.data('savedHref')){ + $link.attr('href', $link.data('savedHref')).removeData('savedHref'); + }else{ return; } + }); + Foundation.unregisterPlugin(this); + }; + Foundation.plugin(Drilldown, 'Drilldown'); +}(jQuery, window.Foundation); + +/** + * Dropdown module. + * @module foundation.dropdown + * @requires foundation.util.keyboard + * @requires foundation.util.box + */ +!function($, Foundation){ + 'use strict'; + /** + * Creates a new instance of a dropdown. + * @class + * @param {jQuery} element - jQuery object to make into an accordion menu. + * @param {Object} options - Overrides to the default plugin settings. + */ + function Dropdown(element, options){ + this.$element = element; + this.options = $.extend({}, Dropdown.defaults, this.$element.data(), options); + this._init(); + + Foundation.registerPlugin(this); + Foundation.Keyboard.register('Dropdown', { + 'ENTER': 'open', + 'SPACE': 'open', + 'ESCAPE': 'close', + 'TAB': 'tab_forward', + 'SHIFT_TAB': 'tab_backward' + }); + } + + Dropdown.defaults = { + /** + * Amount of time to delay opening a submenu on hover event. + * @option + * @example 250 + */ + hoverDelay: 250, + /** + * Allow submenus to open on hover events + * @option + * @example false + */ + hover: false, + /** + * Don't close dropdown when hovering over dropdown pane + * @option + * @example true + */ + hoverPane: false, + /** + * Number of pixels between the dropdown pane and the triggering element on open. + * @option + * @example 1 + */ + vOffset: 1, + /** + * Number of pixels between the dropdown pane and the triggering element on open. + * @option + * @example 1 + */ + hOffset: 1, + /** + * Class applied to adjust open position. JS will test and fill this in. + * @option + * @example 'top' + */ + positionClass: '', + /** + * Allow the plugin to trap focus to the dropdown pane if opened with keyboard commands. + * @option + * @example false + */ + trapFocus: false, + /** + * Allow the plugin to set focus to the first focusable element within the pane, regardless of method of opening. + * @option + * @example true + */ + autoFocus: false + }; + /** + * Initializes the plugin by setting/checking options and attributes, adding helper variables, and saving the anchor. + * @function + * @private + */ + Dropdown.prototype._init = function(){ + var $id = this.$element.attr('id'); + + this.$anchor = $('[data-toggle="' + $id + '"]') || $('[data-open="' + $id + '"]'); + this.$anchor.attr({ + 'aria-controls': $id, + 'data-is-focus': false, + 'data-yeti-box': $id, + 'aria-haspopup': true, + 'aria-expanded': false + // 'data-resize': $id + }); + + this.options.positionClass = this.getPositionClass(); + this.counter = 4; + this.usedPositions = []; + this.$element.attr({ + 'aria-hidden': 'true', + 'data-yeti-box': $id, + 'data-resize': $id, + 'aria-labelledby': this.$anchor[0].id || Foundation.GetYoDigits(6, 'dd-anchor') + }); + this._events(); + }; + /** + * Helper function to determine current orientation of dropdown pane. + * @function + * @returns {String} position - string value of a position class. + */ + Dropdown.prototype.getPositionClass = function(){ + var position = this.$element[0].className.match(/(top|left|right)/g); + position = position ? position[0] : ''; + return position; + }; + /** + * Adjusts the dropdown panes orientation by adding/removing positioning classes. + * @function + * @private + * @param {String} position - position class to remove. + */ + Dropdown.prototype._reposition = function(position){ + this.usedPositions.push(position ? position : 'bottom'); + //default, try switching to opposite side + if(!position && (this.usedPositions.indexOf('top') < 0)){ + this.$element.addClass('top'); + }else if(position === 'top' && (this.usedPositions.indexOf('bottom') < 0)){ + this.$element.removeClass(position); + }else if(position === 'left' && (this.usedPositions.indexOf('right') < 0)){ + this.$element.removeClass(position) + .addClass('right'); + }else if(position === 'right' && (this.usedPositions.indexOf('left') < 0)){ + this.$element.removeClass(position) + .addClass('left'); + } + + //if default change didn't work, try bottom or left first + else if(!position && (this.usedPositions.indexOf('top') > -1) && (this.usedPositions.indexOf('left') < 0)){ + this.$element.addClass('left'); + }else if(position === 'top' && (this.usedPositions.indexOf('bottom') > -1) && (this.usedPositions.indexOf('left') < 0)){ + this.$element.removeClass(position) + .addClass('left'); + }else if(position === 'left' && (this.usedPositions.indexOf('right') > -1) && (this.usedPositions.indexOf('bottom') < 0)){ + this.$element.removeClass(position); + }else if(position === 'right' && (this.usedPositions.indexOf('left') > -1) && (this.usedPositions.indexOf('bottom') < 0)){ + this.$element.removeClass(position); + } + //if nothing cleared, set to bottom + else{ + this.$element.removeClass(position); + } + this.classChanged = true; + this.counter--; + }; + /** + * Sets the position and orientation of the dropdown pane, checks for collisions. + * Recursively calls itself if a collision is detected, with a new position class. + * @function + * @private + */ + Dropdown.prototype._setPosition = function(){ + if(this.$anchor.attr('aria-expanded') === 'false'){ return false; } + var position = this.getPositionClass(), + $eleDims = Foundation.Box.GetDimensions(this.$element), + $anchorDims = Foundation.Box.GetDimensions(this.$anchor), + _this = this, + direction = (position === 'left' ? 'left' : ((position === 'right') ? 'left' : 'top')), + param = (direction === 'top') ? 'height' : 'width', + offset = (param === 'height') ? this.options.vOffset : this.options.hOffset; + + if(($eleDims.width >= $eleDims.windowDims.width) || (!this.counter && !Foundation.Box.ImNotTouchingYou(this.$element))){ + this.$element.offset(Foundation.Box.GetOffsets(this.$element, this.$anchor, 'center bottom', this.options.vOffset, this.options.hOffset, true)).css({ + 'width': $eleDims.windowDims.width - (this.options.hOffset * 2), + 'height': 'auto' + }); + this.classChanged = true; + return false; + } + + this.$element.offset(Foundation.Box.GetOffsets(this.$element, this.$anchor, position, this.options.vOffset, this.options.hOffset)); + + while(!Foundation.Box.ImNotTouchingYou(this.$element) && this.counter){ + this._reposition(position); + this._setPosition(); + } + }; + /** + * Adds event listeners to the element utilizing the triggers utility library. + * @function + * @private + */ + Dropdown.prototype._events = function(){ + var _this = this; + this.$element.on({ + 'open.zf.trigger': this.open.bind(this), + 'close.zf.trigger': this.close.bind(this), + 'toggle.zf.trigger': this.toggle.bind(this), + 'resizeme.zf.trigger': this._setPosition.bind(this) + }); + + if(this.options.hover){ + this.$anchor.off('mouseenter.zf.dropdown mouseleave.zf.dropdown') + .on('mouseenter.zf.dropdown', function(){ + clearTimeout(_this.timeout); + _this.timeout = setTimeout(function(){ + _this.open(); + _this.$anchor.data('hover', true); + }, _this.options.hoverDelay); + }).on('mouseleave.zf.dropdown', function(){ + clearTimeout(_this.timeout); + _this.timeout = setTimeout(function(){ + _this.close(); + _this.$anchor.data('hover', false); + }, _this.options.hoverDelay); + }); + if(this.options.hoverPane){ + this.$element.off('mouseenter.zf.dropdown mouseleave.zf.dropdown') + .on('mouseenter.zf.dropdown', function(){ + clearTimeout(_this.timeout); + }).on('mouseleave.zf.dropdown', function(){ + clearTimeout(_this.timeout); + _this.timeout = setTimeout(function(){ + _this.close(); + _this.$anchor.data('hover', false); + }, _this.options.hoverDelay); + }); + } + } + this.$anchor.add(this.$element).on('keydown.zf.dropdown', function(e) { + + var $target = $(this), + visibleFocusableElements = Foundation.Keyboard.findFocusable(_this.$element); + + Foundation.Keyboard.handleKey(e, _this, { + tab_forward: function() { + if (this.$element.find(':focus').is(visibleFocusableElements.eq(-1))) { // left modal downwards, setting focus to first element + if (this.options.trapFocus) { // if focus shall be trapped + visibleFocusableElements.eq(0).focus(); + e.preventDefault(); + } else { // if focus is not trapped, close dropdown on focus out + this.close(); + } + } + }, + tab_backward: function() { + if (this.$element.find(':focus').is(visibleFocusableElements.eq(0)) || this.$element.is(':focus')) { // left modal upwards, setting focus to last element + if (this.options.trapFocus) { // if focus shall be trapped + visibleFocusableElements.eq(-1).focus(); + e.preventDefault(); + } else { // if focus is not trapped, close dropdown on focus out + this.close(); + } + } + }, + open: function() { + if ($target.is(_this.$anchor)) { + _this.open(); + _this.$element.attr('tabindex', -1).focus(); + e.preventDefault(); + } + }, + close: function() { + _this.close(); + _this.$anchor.focus(); + } + }); + }); + }; + /** + * Opens the dropdown pane, and fires a bubbling event to close other dropdowns. + * @function + * @fires Dropdown#closeme + * @fires Dropdown#show + */ + Dropdown.prototype.open = function(){ + // var _this = this; + /** + * Fires to close other open dropdowns + * @event Dropdown#closeme + */ + this.$element.trigger('closeme.zf.dropdown', this.$element.attr('id')); + this.$anchor.addClass('hover') + .attr({'aria-expanded': true}); + // this.$element/*.show()*/; + this._setPosition(); + this.$element.addClass('is-open') + .attr({'aria-hidden': false}); + + if(this.options.autoFocus){ + var $focusable = Foundation.Keyboard.findFocusable(this.$element); + if($focusable.length){ + $focusable.eq(0).focus(); + } + } + + + /** + * Fires once the dropdown is visible. + * @event Dropdown#show + */ + this.$element.trigger('show.zf.dropdown', [this.$element]); + //why does this not work correctly for this plugin? + // Foundation.reflow(this.$element, 'dropdown'); + // Foundation._reflow(this.$element.attr('data-dropdown')); + }; + + /** + * Closes the open dropdown pane. + * @function + * @fires Dropdown#hide + */ + Dropdown.prototype.close = function(){ + if(!this.$element.hasClass('is-open')){ + return false; + } + this.$element.removeClass('is-open') + .attr({'aria-hidden': true}); + + this.$anchor.removeClass('hover') + .attr('aria-expanded', false); + + if(this.classChanged){ + var curPositionClass = this.getPositionClass(); + if(curPositionClass){ + this.$element.removeClass(curPositionClass); + } + this.$element.addClass(this.options.positionClass) + /*.hide()*/.css({height: '', width: ''}); + this.classChanged = false; + this.counter = 4; + this.usedPositions.length = 0; + } + this.$element.trigger('hide.zf.dropdown', [this.$element]); + // Foundation.reflow(this.$element, 'dropdown'); + }; + /** + * Toggles the dropdown pane's visibility. + * @function + */ + Dropdown.prototype.toggle = function(){ + if(this.$element.hasClass('is-open')){ + if(this.$anchor.data('hover')) return; + this.close(); + }else{ + this.open(); + } + }; + /** + * Destroys the dropdown. + * @function + */ + Dropdown.prototype.destroy = function(){ + this.$element.off('.zf.trigger').hide(); + this.$anchor.off('.zf.dropdown'); + + Foundation.unregisterPlugin(this); + }; + + Foundation.plugin(Dropdown, 'Dropdown'); +}(jQuery, window.Foundation); + +/** + * DropdownMenu module. + * @module foundation.dropdown-menu + * @requires foundation.util.keyboard + * @requires foundation.util.box + * @requires foundation.util.nest + */ +!function($, Foundation){ + 'use strict'; + + /** + * Creates a new instance of DropdownMenu. + * @class + * @fires DropdownMenu#init + * @param {jQuery} element - jQuery object to make into a dropdown menu. + * @param {Object} options - Overrides to the default plugin settings. + */ + function DropdownMenu(element, options){ + this.$element = element; + this.options = $.extend({}, DropdownMenu.defaults, this.$element.data(), options); + + Foundation.Nest.Feather(this.$element, 'dropdown'); + this._init(); + + Foundation.registerPlugin(this); + Foundation.Keyboard.register('DropdownMenu', { + 'ENTER': 'open', + 'SPACE': 'open', + 'ARROW_RIGHT': 'next', + 'ARROW_UP': 'up', + 'ARROW_DOWN': 'down', + 'ARROW_LEFT': 'previous', + 'ESCAPE': 'close' + }); + } + + /** + * Default settings for plugin + */ + DropdownMenu.defaults = { + /** + * Disallows hover events from opening submenus + * @option + * @example false + */ + disableHover: false, + /** + * Allow a submenu to automatically close on a mouseleave event, if not clicked open. + * @option + * @example true + */ + autoclose: true, + /** + * Amount of time to delay opening a submenu on hover event. + * @option + * @example 50 + */ + hoverDelay: 50, + /** + * Allow a submenu to open/remain open on parent click event. Allows cursor to move away from menu. + * @option + * @example true + */ + clickOpen: false, + /** + * Amount of time to delay closing a submenu on a mouseleave event. + * @option + * @example 500 + */ + + closingTime: 500, + /** + * Position of the menu relative to what direction the submenus should open. Handled by JS. + * @option + * @example 'left' + */ + alignment: 'left', + /** + * Allow clicks on the body to close any open submenus. + * @option + * @example true + */ + closeOnClick: true, + /** + * Class applied to vertical oriented menus, Foundation default is `vertical`. Update this if using your own class. + * @option + * @example 'vertical' + */ + verticalClass: 'vertical', + /** + * Class applied to right-side oriented menus, Foundation default is `align-right`. Update this if using your own class. + * @option + * @example 'align-right' + */ + rightClass: 'align-right', + /** + * Boolean to force overide the clicking of links to perform default action, on second touch event for mobile. + * @option + * @example false + */ + forceFollow: true + }; + /** + * Initializes the plugin, and calls _prepareMenu + * @private + * @function + */ + DropdownMenu.prototype._init = function(){ + var subs = this.$element.find('li.is-dropdown-submenu-parent'); + this.$element.children('.is-dropdown-submenu-parent').children('.is-dropdown-submenu').addClass('first-sub'); + + this.$menuItems = this.$element.find('[role="menuitem"]'); + this.$tabs = this.$element.children('[role="menuitem"]'); + this.isVert = this.$element.hasClass(this.options.verticalClass); + this.$tabs.find('ul.is-dropdown-submenu').addClass(this.options.verticalClass); + + if(this.$element.hasClass(this.options.rightClass) || this.options.alignment === 'right'){ + this.options.alignment = 'right'; + subs.addClass('is-left-arrow opens-left'); + }else{ + subs.addClass('is-right-arrow opens-right'); + } + if(!this.isVert){ + this.$tabs.filter('.is-dropdown-submenu-parent').removeClass('is-right-arrow is-left-arrow opens-right opens-left') + .addClass('is-down-arrow'); + } + this.changed = false; + this._events(); + }; + /** + * Adds event listeners to elements within the menu + * @private + * @function + */ + DropdownMenu.prototype._events = function(){ + var _this = this, + hasTouch = 'ontouchstart' in window || (typeof window.ontouchstart !== 'undefined'), + parClass = 'is-dropdown-submenu-parent', + delay; + + if(this.options.clickOpen || hasTouch){ + this.$menuItems.on('click.zf.dropdownmenu touchstart.zf.dropdownmenu', function(e){ + var $elem = $(e.target).parentsUntil('ul', '.' + parClass), + hasSub = $elem.hasClass(parClass), + hasClicked = $elem.attr('data-is-click') === 'true', + $sub = $elem.children('.is-dropdown-submenu'); + + if(hasSub){ + if(hasClicked){ + if(!_this.options.closeOnClick || (!_this.options.clickOpen && !hasTouch) || (_this.options.forceFollow && hasTouch)){ return; } + else{ + e.stopImmediatePropagation(); + e.preventDefault(); + _this._hide($elem); + } + }else{ + e.preventDefault(); + e.stopImmediatePropagation(); + _this._show($elem.children('.is-dropdown-submenu')); + $elem.add($elem.parentsUntil(_this.$element, '.' + parClass)).attr('data-is-click', true); + } + }else{ return; } + }); + } + + if(!this.options.disableHover){ + this.$menuItems.on('mouseenter.zf.dropdownmenu', function(e){ + e.stopImmediatePropagation(); + var $elem = $(this), + hasSub = $elem.hasClass(parClass); + + if(hasSub){ + clearTimeout(delay); + delay = setTimeout(function(){ + _this._show($elem.children('.is-dropdown-submenu')); + }, _this.options.hoverDelay); + } + }).on('mouseleave.zf.dropdownmenu', function(e){ + var $elem = $(this), + hasSub = $elem.hasClass(parClass); + if(hasSub && _this.options.autoclose){ + if($elem.attr('data-is-click') === 'true' && _this.options.clickOpen){ return false; } + + // clearTimeout(delay); + delay = setTimeout(function(){ + _this._hide($elem); + }, _this.options.closingTime); + } + }); + } + this.$menuItems.on('keydown.zf.dropdownmenu', function(e){ + var $element = $(e.target).parentsUntil('ul', '[role="menuitem"]'), + isTab = _this.$tabs.index($element) > -1, + $elements = isTab ? _this.$tabs : $element.siblings('li').add($element), + $prevElement, + $nextElement; + + $elements.each(function(i) { + if ($(this).is($element)) { + $prevElement = $elements.eq(i-1); + $nextElement = $elements.eq(i+1); + return; + } + }); + + var nextSibling = function() { + if (!$element.is(':last-child')) $nextElement.children('a:first').focus(); + }, prevSibling = function() { + $prevElement.children('a:first').focus(); + }, openSub = function() { + var $sub = $element.children('ul.is-dropdown-submenu'); + if($sub.length){ + _this._show($sub); + $element.find('li > a:first').focus(); + }else{ return; } + }, closeSub = function() { + //if ($element.is(':first-child')) { + var close = $element.parent('ul').parent('li'); + close.children('a:first').focus(); + _this._hide(close); + //} + }; + var functions = { + open: openSub, + close: function() { + _this._hide(_this.$element); + _this.$menuItems.find('a:first').focus(); // focus to first element + }, + handled: function() { + e.preventDefault(); + e.stopImmediatePropagation(); + } + }; + + if (isTab) { + if (_this.vertical) { // vertical menu + if (_this.options.alignment === 'left') { // left aligned + $.extend(functions, { + down: nextSibling, + up: prevSibling, + next: openSub, + previous: closeSub + }); + } else { // right aligned + $.extend(functions, { + down: nextSibling, + up: prevSibling, + next: closeSub, + previous: openSub + }); + } + } else { // horizontal menu + $.extend(functions, { + next: nextSibling, + previous: prevSibling, + down: openSub, + up: closeSub + }); + } + } else { // not tabs -> one sub + if (_this.options.alignment === 'left') { // left aligned + $.extend(functions, { + next: openSub, + previous: closeSub, + down: nextSibling, + up: prevSibling + }); + } else { // right aligned + $.extend(functions, { + next: closeSub, + previous: openSub, + down: nextSibling, + up: prevSibling + }); + } + } + Foundation.Keyboard.handleKey(e, _this, functions); + + }); + }; + /** + * Adds an event handler to the body to close any dropdowns on a click. + * @function + * @private + */ + DropdownMenu.prototype._addBodyHandler = function(){ + var $body = $(document.body), + _this = this; + $body.off('mouseup.zf.dropdownmenu touchend.zf.dropdownmenu') + .on('mouseup.zf.dropdownmenu touchend.zf.dropdownmenu', function(e){ + var $link = _this.$element.find(e.target); + if($link.length){ return; } + + _this._hide(); + $body.off('mouseup.zf.dropdownmenu touchend.zf.dropdownmenu'); + }); + }; + /** + * Opens a dropdown pane, and checks for collisions first. + * @param {jQuery} $sub - ul element that is a submenu to show + * @function + * @private + * @fires DropdownMenu#show + */ + DropdownMenu.prototype._show = function($sub){ + var idx = this.$tabs.index(this.$tabs.filter(function(i, el){ + return $(el).find($sub).length > 0; + })); + var $sibs = $sub.parent('li.is-dropdown-submenu-parent').siblings('li.is-dropdown-submenu-parent'); + this._hide($sibs, idx); + $sub.css('visibility', 'hidden').addClass('js-dropdown-active').attr({'aria-hidden': false}) + .parent('li.is-dropdown-submenu-parent').addClass('is-active') + .attr({'aria-selected': true, 'aria-expanded': true}); + var clear = Foundation.Box.ImNotTouchingYou($sub, null, true); + if(!clear){ + var oldClass = this.options.alignment === 'left' ? '-right' : '-left', + $parentLi = $sub.parent('.is-dropdown-submenu-parent'); + $parentLi.removeClass('opens' + oldClass).addClass('opens-' + this.options.alignment); + clear = Foundation.Box.ImNotTouchingYou($sub, null, true); + if(!clear){ + $parentLi.removeClass('opens-' + this.options.alignment).addClass('opens-inner'); + } + this.changed = true; + } + $sub.css('visibility', ''); + if(this.options.closeOnClick){ this._addBodyHandler(); } + /** + * Fires when the new dropdown pane is visible. + * @event DropdownMenu#show + */ + this.$element.trigger('show.zf.dropdownmenu', [$sub]); + }; + /** + * Hides a single, currently open dropdown pane, if passed a parameter, otherwise, hides everything. + * @function + * @param {jQuery} $elem - element with a submenu to hide + * @param {Number} idx - index of the $tabs collection to hide + * @private + */ + DropdownMenu.prototype._hide = function($elem, idx){ + var $toClose; + if($elem && $elem.length){ + $toClose = $elem; + }else if(idx !== undefined){ + $toClose = this.$tabs.not(function(i, el){ + return i === idx; + }); + } + else{ + $toClose = this.$element; + } + var somethingToClose = $toClose.hasClass('is-active') || $toClose.find('.is-active').length > 0; + + if(somethingToClose){ + $toClose.find('li.is-active').add($toClose).attr({ + 'aria-selected': false, + 'aria-expanded': false, + 'data-is-click': false + }).removeClass('is-active'); + + $toClose.find('ul.js-dropdown-active').attr({ + 'aria-hidden': true + }).removeClass('js-dropdown-active'); + + if(this.changed || $toClose.find('opens-inner').length){ + var oldClass = this.options.alignment === 'left' ? 'right' : 'left'; + $toClose.find('li.is-dropdown-submenu-parent').add($toClose) + .removeClass('opens-inner opens-' + this.options.alignment) + .addClass('opens-' + oldClass); + this.changed = false; + } + /** + * Fires when the open menus are closed. + * @event DropdownMenu#hide + */ + this.$element.trigger('hide.zf.dropdownmenu', [$toClose]); + } + }; + /** + * Destroys the plugin. + * @function + */ + DropdownMenu.prototype.destroy = function(){ + this.$menuItems.off('.zf.dropdownmenu').removeAttr('data-is-click') + .removeClass('is-right-arrow is-left-arrow is-down-arrow opens-right opens-left opens-inner'); + Foundation.Nest.Burn(this.$element, 'dropdown'); + Foundation.unregisterPlugin(this); + }; + + Foundation.plugin(DropdownMenu, 'DropdownMenu'); +}(jQuery, window.Foundation); + +!function(Foundation, $) { + 'use strict'; + + /** + * Creates a new instance of Equalizer. + * @class + * @fires Equalizer#init + * @param {Object} element - jQuery object to add the trigger to. + * @param {Object} options - Overrides to the default plugin settings. + */ + function Equalizer(element, options) { + this.$element = element; + this.options = $.extend({}, Equalizer.defaults, this.$element.data(), options); + this.$window = $(window); + this.name = 'equalizer'; + this.attr = 'data-equalizer'; + + this._init(); + this._events(); + + Foundation.registerPlugin(this); + } + + /** + * Default settings for plugin + */ + Equalizer.defaults = { + /** + * Enable height equalization when stacked on smaller screens. + * @option + * @example true + */ + equalizeOnStack: true, + /** + * Amount of time, in ms, to debounce the size checking/equalization. Lower times mean smoother transitions/less performance on mobile. + * @option + * @example 50 + */ + throttleInterval: 50 + }; + + /** + * Initializes the Equalizer plugin and calls functions to get equalizer functioning on load. + * @private + */ + Equalizer.prototype._init = function() { + this._reflow(); + }; + + /** + * Initializes events for Equalizer. + * @private + */ + Equalizer.prototype._events = function() { + var self = this; + + this.$window + .off('.equalizer') + .on('resize.fndtn.equalizer', Foundation.util.throttle(function () { + self._reflow(); + }, self.options.throttleInterval)); + }; + + /** + * A noop version for the plugin + * @private + */ + Equalizer.prototype._killswitch = function() { + return; + }; + /** + * Calls necessary functions to update Equalizer upon DOM change + * @private + */ + Equalizer.prototype._reflow = function() { + var self = this; + + $('[' + this.attr + ']').each(function() { + var $eqParent = $(this), + adjustedHeights = [], + $images = $eqParent.find('img'); + + if ($images.length) { + Foundation.onImagesLoaded($images, function() { + adjustedHeights = self.getHeights($eqParent); + self.applyHeight($eqParent, adjustedHeights); + }); + } + else { + adjustedHeights = self.getHeights($eqParent); + self.applyHeight($eqParent, adjustedHeights); + } + }); + }; + /** + * Finds the outer heights of children contained within an Equalizer parent and returns them in an array + * @param {Object} $eqParent A jQuery instance of an Equalizer container + * @returns {Array} heights An array of heights of children within Equalizer container + */ + Equalizer.prototype.getHeights = function($eqParent) { + var eqGroupName = $eqParent.data('equalizer'), + eqGroup = eqGroupName ? $eqParent.find('[' + this.attr + '-watch="' + eqGroupName + '"]:visible') : $eqParent.find('[' + this.attr + '-watch]:visible'), + heights; + + eqGroup.height('inherit'); + heights = eqGroup.map(function () { return $(this).outerHeight(false);}).get(); + + return heights; + }; + /** + * Changes the CSS height property of each child in an Equalizer parent to match the tallest + * @param {Object} $eqParent - A jQuery instance of an Equalizer container + * @param {array} heights - An array of heights of children within Equalizer container + * @fires Equalizer#preEqualized + * @fires Equalizer#postEqualized + */ + Equalizer.prototype.applyHeight = function($eqParent, heights) { + var eqGroupName = $eqParent.data('equalizer'), + eqGroup = eqGroupName ? $eqParent.find('['+this.attr+'-watch="'+eqGroupName+'"]:visible') : $eqParent.find('['+this.attr+'-watch]:visible'), + max = Math.max.apply(null, heights); + + /** + * Fires before the heights are applied + * @event Equalizer#preEqualized + */ + $eqParent.trigger('preEqualized.zf.Equalizer'); + + // for now, apply the max height found in the array + for (var i = 0; i < eqGroup.length; i++) { + $(eqGroup[i]).css('height', max); + } + + /** + * Fires when the heights have been applied + * @event Equalizer#postEqualized + */ + $eqParent.trigger('postEqualized.zf.Equalizer'); + }; + /** + * Destroys an instance of Equalizer. + * @function + */ + Equalizer.prototype.destroy = function(){ + //TODO this. + }; + + Foundation.plugin(Equalizer, 'Equalizer'); + + // Exports for AMD/Browserify + if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') + module.exports = Equalizer; + if (typeof define === 'function') + define(['foundation'], function() { + return Equalizer; + }); + +}(Foundation, jQuery); + +/** + * Interchange module. + * @module foundation.interchange + * @requires foundation.util.mediaQuery + * @requires foundation.util.timerAndImageLoader + */ +!function(Foundation, $) { + 'use strict'; + + /** + * Creates a new instance of Interchange. + * @class + * @fires Interchange#init + * @param {Object} element - jQuery object to add the trigger to. + * @param {Object} options - Overrides to the default plugin settings. + */ + function Interchange(element, options) { + this.$element = element; + this.options = $.extend({}, Interchange.defaults, options); + this.rules = []; + this.currentPath = ''; + + this._init(); + this._events(); + + Foundation.registerPlugin(this); + } + + /** + * Default settings for plugin + */ + Interchange.defaults = { + /** + * Rules to be applied to Interchange elements. Set with the `data-interchange` array notation. + * @option + */ + rules: null + }; + + Interchange.SPECIAL_QUERIES = { + 'landscape': 'screen and (orientation: landscape)', + 'portrait': 'screen and (orientation: portrait)', + 'retina': 'only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx)' + }; + + /** + * Initializes the Interchange plugin and calls functions to get interchange functioning on load. + * @function + * @private + */ + Interchange.prototype._init = function() { + this._addBreakpoints(); + this._generateRules(); + this._reflow(); + }; + + /** + * Initializes events for Interchange. + * @function + * @private + */ + Interchange.prototype._events = function() { + $(window).on('resize.fndtn.interchange', Foundation.util.throttle(this._reflow.bind(this), 50)); + }; + + /** + * Calls necessary functions to update Interchange upon DOM change + * @function + * @private + */ + Interchange.prototype._reflow = function() { + var match; + + // Iterate through each rule, but only save the last match + for (var i in this.rules) { + var rule = this.rules[i]; + + if (window.matchMedia(rule.query).matches) { + match = rule; + } + } + + if (match) { + this.replace(match.path); + } + }; + + /** + * Gets the Foundation breakpoints and adds them to the Interchange.SPECIAL_QUERIES object. + * @function + * @private + */ + Interchange.prototype._addBreakpoints = function() { + for (var i in Foundation.MediaQuery.queries) { + var query = Foundation.MediaQuery.queries[i]; + Interchange.SPECIAL_QUERIES[query.name] = query.value; + } + }; + + /** + * Checks the Interchange element for the provided media query + content pairings + * @function + * @private + * @param {Object} element - jQuery object that is an Interchange instance + * @returns {Array} scenarios - Array of objects that have 'mq' and 'path' keys with corresponding keys + */ + Interchange.prototype._generateRules = function() { + var rulesList = []; + var rules; + + if (this.options.rules) { + rules = this.options.rules; + } + else { + rules = this.$element.data('interchange').match(/\[.*?\]/g); + } + + for (var i in rules) { + var rule = rules[i].slice(1, -1).split(', '); + var path = rule.slice(0, -1).join(''); + var query = rule[rule.length - 1]; + + if (Interchange.SPECIAL_QUERIES[query]) { + query = Interchange.SPECIAL_QUERIES[query]; + } + + rulesList.push({ + path: path, + query: query + }); + } + + this.rules = rulesList; + }; + + /** + * Update the `src` property of an image, or change the HTML of a container, to the specified path. + * @function + * @param {String} path - Path to the image or HTML partial. + * @fires Interchange#replaced + */ + Interchange.prototype.replace = function(path) { + if (this.currentPath === path) return; + + var _this = this; + + // Replacing images + if (this.$element[0].nodeName === 'IMG') { + this.$element.attr('src', path).load(function() { + _this.$element.trigger('replaced.zf.interchange'); + _this.currentPath = path; + }); + } + // Replacing background images + else if (path.match(/\.(gif|jpg|jpeg|tiff|png)([?#].*)?/i)) { + this.$element.css({ 'background-image': 'url('+path+')' }); + } + // Replacing HTML + else { + $.get(path, function(response) { + _this.$element.html(response); + _this.$element.trigger('replaced.zf.interchange'); + _this.currentPath = path; + }); + } + }; + /** + * Destroys an instance of interchange. + * @function + */ + Interchange.prototype.destroy = function(){ + //TODO this. + }; + Foundation.plugin(Interchange, 'Interchange'); + + // Exports for AMD/Browserify + if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') + module.exports = Interchange; + if (typeof define === 'function') + define(['foundation'], function() { + return Interchange; + }); + +}(Foundation, jQuery); + +/** + * Magellan module. + * @module foundation.magellan + */ +!function(Foundation, $) { + 'use strict'; + + /** + * Creates a new instance of Magellan. + * @class + * @fires Magellan#init + * @param {Object} element - jQuery object to add the trigger to. + * @param {Object} options - Overrides to the default plugin settings. + */ + function Magellan(element, options) { + this.$element = element; + this.options = $.extend({}, Magellan.defaults, this.$element.data(), options); + + this._init(); + + Foundation.registerPlugin(this); + } + + /** + * Default settings for plugin + */ + Magellan.defaults = { + /** + * Amount of time, in ms, the animated scrolling should take between locations. + * @option + * @example 500 + */ + animationDuration: 500, + /** + * Animation style to use when scrolling between locations. + * @option + * @example 'ease-in-out' + */ + animationEasing: 'linear', + /** + * Number of pixels to use as a marker for location changes. + * @option + * @example 50 + */ + threshold: 50, + /** + * Class applied to the active locations link on the magellan container. + * @option + * @example 'active' + */ + activeClass: 'active', + /** + * Allows the script to manipulate the url of the current page, and if supported, alter the history. + * @option + * @example true + */ + deepLinking: false, + /** + * Number of pixels to offset the scroll of the page on item click if using a sticky nav bar. + * @option + * @example 25 + */ + barOffset: 0 + }; + + /** + * Initializes the Magellan plugin and calls functions to get equalizer functioning on load. + * @private + */ + Magellan.prototype._init = function() { + var id = this.$element[0].id || Foundation.GetYoDigits(6, 'magellan'), + _this = this; + this.$targets = $('[data-magellan-target]'); + this.$links = this.$element.find('a'); + this.$element.attr({ + 'data-resize': id, + 'data-scroll': id, + 'id': id + }); + this.$active = $(); + this.scrollPos = parseInt(window.pageYOffset, 10); + + this._events(); + }; + /** + * Calculates an array of pixel values that are the demarcation lines between locations on the page. + * Can be invoked if new elements are added or the size of a location changes. + * @function + */ + Magellan.prototype.calcPoints = function(){ + var _this = this, + body = document.body, + html = document.documentElement; + + this.points = []; + this.winHeight = Math.round(Math.max(window.innerHeight, html.clientHeight)); + this.docHeight = Math.round(Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight)); + + this.$targets.each(function(){ + var $tar = $(this), + pt = Math.round($tar.offset().top - _this.options.threshold); + $tar.targetPoint = pt; + _this.points.push(pt); + }); + }; + /** + * Initializes events for Magellan. + * @private + */ + Magellan.prototype._events = function() { + var _this = this, + $body = $('html, body'), + opts = { + duration: _this.options.animationDuration, + easing: _this.options.animationEasing + }; + + $(window).one('load', function(){ + _this.calcPoints(); + _this._updateActive(); + }); + + this.$element.on({ + 'resizeme.zf.trigger': this.reflow.bind(this), + 'scrollme.zf.trigger': this._updateActive.bind(this) + }).on('click.zf.magellan', 'a[href^="#"]', function(e) { + e.preventDefault(); + var arrival = this.getAttribute('href'), + scrollPos = $(arrival).offset().top - _this.options.threshold / 2 - _this.options.barOffset; + + // requestAnimationFrame is disabled for this plugin currently + // Foundation.Move(_this.options.animationDuration, $body, function(){ + $body.stop(true).animate({ + scrollTop: scrollPos + }, opts); + }); + // }); + }; + /** + * Calls necessary functions to update Magellan upon DOM change + * @function + */ + Magellan.prototype.reflow = function(){ + this.calcPoints(); + this._updateActive(); + }; + /** + * Updates the visibility of an active location link, and updates the url hash for the page, if deepLinking enabled. + * @private + * @function + * @fires Magellan#update + */ + Magellan.prototype._updateActive = function(/*evt, elem, scrollPos*/){ + var winPos = /*scrollPos ||*/ parseInt(window.pageYOffset, 10), + curIdx; + + if(winPos + this.winHeight === this.docHeight){ curIdx = this.points.length - 1; } + else if(winPos < this.points[0]){ curIdx = 0; } + else{ + var isDown = this.scrollPos < winPos, + _this = this, + curVisible = this.points.filter(function(p, i){ + return isDown ? p <= winPos : p - _this.options.threshold <= winPos;//&& winPos >= _this.points[i -1] - _this.options.threshold; + }); + curIdx = curVisible.length ? curVisible.length - 1 : 0; + } + + this.$active.removeClass(this.options.activeClass); + this.$active = this.$links.eq(curIdx).addClass(this.options.activeClass); + + if(this.options.deepLinking){ + var hash = this.$active[0].getAttribute('href'); + if(window.history.pushState){ + window.history.pushState(null, null, hash); + }else{ + window.location.hash = hash; + } + } + + this.scrollPos = winPos; + /** + * Fires when magellan is finished updating to the new active element. + * @event Magellan#update + */ + this.$element.trigger('update.zf.magellan', [this.$active]); + }; + /** + * Destroys an instance of Magellan and resets the url of the window. + * @function + */ + Magellan.prototype.destroy = function(){ + this.$element.off('.zf.trigger .zf.magellan') + .find('.' + this.options.activeClass).removeClass(this.options.activeClass); + + if(this.options.deepLinking){ + var hash = this.$active[0].getAttribute('href'); + window.location.hash.replace(hash, ''); + } + + Foundation.unregisterPlugin(this); + }; + Foundation.plugin(Magellan, 'Magellan'); + + // Exports for AMD/Browserify + if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') + module.exports = Magellan; + if (typeof define === 'function') + define(['foundation'], function() { + return Magellan; + }); + +}(Foundation, jQuery); + +/** + * OffCanvas module. + * @module foundation.offcanvas + * @requires foundation.util.triggers + * @requires foundation.util.motion + */ +!function($, Foundation) { + +'use strict'; + +/** + * Creates a new instance of an off-canvas wrapper. + * @class + * @fires OffCanvas#init + * @param {Object} element - jQuery object to initialize. + * @param {Object} options - Overrides to the default plugin settings. + */ +function OffCanvas(element, options) { + this.$element = element; + this.options = $.extend({}, OffCanvas.defaults, this.$element.data(), options); + this.$lastTrigger = $(); + + this._init(); + this._events(); + + Foundation.registerPlugin(this); +} + +OffCanvas.defaults = { + /** + * Allow the user to click outside of the menu to close it. + * @option + * @example true + */ + closeOnClick: true, + /** + * Amount of time in ms the open and close transition requires. If none selected, pulls from body style. + * @option + * @example 500 + */ + transitionTime: 0, + /** + * Direction the offcanvas opens from. Determines class applied to body. + * @option + * @example left + */ + position: 'left', + /** + * Force the page to scroll to top on open. + */ + forceTop: true, + /** + * Allow the offcanvas to be sticky while open. Does nothing if Sass option `$maincontent-prevent-scroll === true`. + * Performance in Safari OSX/iOS is not great. + */ + // isSticky: false, + /** + * Allow the offcanvas to remain open for certain breakpoints. Can be used with `isSticky`. + * @option + * @example false + */ + isRevealed: false, + /** + * Breakpoint at which to reveal. JS will use a RegExp to target standard classes, if changing classnames, pass your class @`revealClass`. + * @option + * @example reveal-for-large + */ + revealOn: null, + /** + * Force focus to the offcanvas on open. If true, will focus the opening trigger on close. + * @option + * @example true + */ + autoFocus: true, + /** + * Class used to force an offcanvas to remain open. Foundation defaults for this are `reveal-for-large` & `reveal-for-medium`. + * @option + * TODO improve the regex testing for this. + * @example reveal-for-large + */ + revealClass: 'reveal-for-' +}; + +/** + * Initializes the off-canvas wrapper by adding the exit overlay (if needed). + * @function + * @private + */ +OffCanvas.prototype._init = function() { + var id = this.$element.attr('id'); + + this.$element.attr('aria-hidden', 'true'); + + // Find triggers that affect this element and add aria-expanded to them + $(document) + .find('[data-open="'+id+'"], [data-close="'+id+'"], [data-toggle="'+id+'"]') + .attr('aria-expanded', 'false') + .attr('aria-controls', id); + + // Add a close trigger over the body if necessary + if (this.options.closeOnClick){ + if($('.js-off-canvas-exit').length){ + this.$exiter = $('.js-off-canvas-exit'); + }else{ + var exiter = document.createElement('div'); + exiter.setAttribute('class', 'js-off-canvas-exit'); + $('[data-off-canvas-content]').append(exiter); + + this.$exiter = $(exiter); + } + } + + this.options.isRevealed = this.options.isRevealed || new RegExp(this.options.revealClass, 'g').test(this.$element[0].className); + + if(this.options.isRevealed){ + this.options.revealOn = this.options.revealOn || this.$element[0].className.match(/(reveal-for-medium|reveal-for-large)/g)[0].split('-')[2]; + this._setMQChecker(); + } + if(!this.options.transitionTime){ + this.options.transitionTime = parseFloat(window.getComputedStyle($('[data-off-canvas-wrapper]')[0]).transitionDuration) * 1000; + } +}; + +/** + * Adds event handlers to the off-canvas wrapper and the exit overlay. + * @function + * @private + */ +OffCanvas.prototype._events = function() { + this.$element.on({ + 'open.zf.trigger': this.open.bind(this), + 'close.zf.trigger': this.close.bind(this), + 'toggle.zf.trigger': this.toggle.bind(this), + 'keydown.zf.offcanvas': this._handleKeyboard.bind(this) + }); + + if (this.$exiter.length) { + var _this = this; + this.$exiter.on({'click.zf.offcanvas': this.close.bind(this)}); + } +}; +/** + * Applies event listener for elements that will reveal at certain breakpoints. + * @private + */ +OffCanvas.prototype._setMQChecker = function(){ + var _this = this; + + $(window).on('changed.zf.mediaquery', function(){ + if(Foundation.MediaQuery.atLeast(_this.options.revealOn)){ + _this.reveal(true); + }else{ + _this.reveal(false); + } + }).one('load.zf.offcanvas', function(){ + if(Foundation.MediaQuery.atLeast(_this.options.revealOn)){ + _this.reveal(true); + } + }); +}; +/** + * Handles the revealing/hiding the off-canvas at breakpoints, not the same as open. + * @param {Boolean} isRevealed - true if element should be revealed. + * @function + */ +OffCanvas.prototype.reveal = function(isRevealed){ + var $closer = this.$element.find('[data-close]'); + if(isRevealed){ + // if(!this.options.forceTop){ + // var scrollPos = parseInt(window.pageYOffset); + // this.$element[0].style.transform = 'translate(0,' + scrollPos + 'px)'; + // } + // if(this.options.isSticky){ this._stick(); } + if($closer.length){ $closer.hide(); } + }else{ + // if(this.options.isSticky || !this.options.forceTop){ + // this.$element[0].style.transform = ''; + // $(window).off('scroll.zf.offcanvas'); + // } + if($closer.length){ + $closer.show(); + } + } +}; + +/** + * Opens the off-canvas menu. + * @function + * @param {Object} event - Event object passed from listener. + * @param {jQuery} trigger - element that triggered the off-canvas to open. + * @fires OffCanvas#opened + */ +OffCanvas.prototype.open = function(event, trigger) { + if (this.$element.hasClass('is-open')){ return; } + var _this = this, + $body = $(document.body); + $('body').scrollTop(0); + // window.pageYOffset = 0; + + // if(!this.options.forceTop){ + // var scrollPos = parseInt(window.pageYOffset); + // this.$element[0].style.transform = 'translate(0,' + scrollPos + 'px)'; + // if(this.$exiter.length){ + // this.$exiter[0].style.transform = 'translate(0,' + scrollPos + 'px)'; + // } + // } + /** + * Fires when the off-canvas menu opens. + * @event OffCanvas#opened + */ + Foundation.Move(this.options.transitionTime, this.$element, function(){ + $('[data-off-canvas-wrapper]').addClass('is-off-canvas-open is-open-'+ _this.options.position); + + _this.$element + .addClass('is-open') + .attr('aria-hidden', 'false') + .trigger('opened.zf.offcanvas'); + + // if(_this.options.isSticky){ + // _this._stick(); + // } + }); + if(trigger){ + this.$lastTrigger = trigger.attr('aria-expanded', 'true'); + } + if(this.options.autoFocus){ + this.$element.one('finished.zf.animate', function(){ + _this.$element.find('a, button').eq(0).focus(); + }); + } +}; +/** + * Allows the offcanvas to appear sticky utilizing translate properties. + * @private + */ +// OffCanvas.prototype._stick = function(){ +// var elStyle = this.$element[0].style; +// +// if(this.options.closeOnClick){ +// var exitStyle = this.$exiter[0].style; +// } +// +// $(window).on('scroll.zf.offcanvas', function(e){ +// console.log(e); +// var pageY = window.pageYOffset; +// elStyle.transform = 'translate(0,' + pageY + 'px)'; +// if(exitStyle !== undefined){ exitStyle.transform = 'translate(0,' + pageY + 'px)'; } +// }); +// // this.$element.trigger('stuck.zf.offcanvas'); +// }; +/** + * Closes the off-canvas menu. + * @function + * @fires OffCanvas#closed + */ +OffCanvas.prototype.close = function() { + if(!this.$element.hasClass('is-open')){ return; } + + var _this = this; + + Foundation.Move(this.options.transitionTime, this.$element, function(){ + $('[data-off-canvas-wrapper]').removeClass('is-off-canvas-open is-open-'+_this.options.position); + + _this.$element.removeClass('is-open'); + // Foundation._reflow(); + }); + this.$element.attr('aria-hidden', 'true') + /** + * Fires when the off-canvas menu opens. + * @event OffCanvas#closed + */ + .trigger('closed.zf.offcanvas'); + // if(_this.options.isSticky || !_this.options.forceTop){ + // setTimeout(function(){ + // _this.$element[0].style.transform = ''; + // $(window).off('scroll.zf.offcanvas'); + // }, this.options.transitionTime); + // } + + this.$lastTrigger.attr('aria-expanded', 'false'); +}; + +/** + * Toggles the off-canvas menu open or closed. + * @function + * @param {Object} event - Event object passed from listener. + * @param {jQuery} trigger - element that triggered the off-canvas to open. + */ +OffCanvas.prototype.toggle = function(event, trigger) { + if (this.$element.hasClass('is-open')) { + this.close(event, trigger); + } + else { + this.open(event, trigger); + } +}; + +/** + * Handles keyboard input when detected. When the escape key is pressed, the off-canvas menu closes, and focus is restored to the element that opened the menu. + * @function + * @private + */ +OffCanvas.prototype._handleKeyboard = function(event) { + if (event.which !== 27) return; + + event.stopPropagation(); + event.preventDefault(); + this.close(); + this.$lastTrigger.focus(); +}; +/** + * Destroys the offcanvas plugin. + * @function + */ +OffCanvas.prototype.destroy = function(){ + //TODO make this... +}; + +Foundation.plugin(OffCanvas, 'OffCanvas'); + +}(jQuery, Foundation); + +/** + * Orbit module. + * @module foundation.orbit + * @requires foundation.util.keyboard + * @requires foundation.util.motion + * @requires foundation.util.timerAndImageLoader + * @requires foundation.util.touch + */ +!function($, Foundation){ + 'use strict'; + /** + * Creates a new instance of an orbit carousel. + * @class + * @param {jQuery} element - jQuery object to make into an accordion menu. + * @param {Object} options - Overrides to the default plugin settings. + */ + function Orbit(element, options){ + this.$element = element; + this.options = $.extend({}, Orbit.defaults, this.$element.data(), options); + + this._init(); + + Foundation.registerPlugin(this); + Foundation.Keyboard.register('Orbit', { + 'ltr': { + 'ARROW_RIGHT': 'next', + 'ARROW_LEFT': 'previous' + }, + 'rtl': { + 'ARROW_LEFT': 'next', + 'ARROW_RIGHT': 'previous' + } + }); + } + Orbit.defaults = { + /** + * Tells the JS to loadBullets. + * @option + * @example true + */ + bullets: true, + /** + * Tells the JS to apply event listeners to nav buttons + * @option + * @example true + */ + navButtons: true, + /** + * motion-ui animation class to apply + * @option + * @example 'slide-in-right' + */ + animInFromRight: 'slide-in-right', + /** + * motion-ui animation class to apply + * @option + * @example 'slide-out-right' + */ + animOutToRight: 'slide-out-right', + /** + * motion-ui animation class to apply + * @option + * @example 'slide-in-left' + * + */ + animInFromLeft: 'slide-in-left', + /** + * motion-ui animation class to apply + * @option + * @example 'slide-out-left' + */ + animOutToLeft: 'slide-out-left', + /** + * Allows Orbit to automatically animate on page load. + * @option + * @example true + */ + autoPlay: true, + /** + * Amount of time, in ms, between slide transitions + * @option + * @example 5000 + */ + timerDelay: 5000, + /** + * Allows Orbit to infinitely loop through the slides + * @option + * @example true + */ + infiniteWrap: true, + /** + * Allows the Orbit slides to bind to swipe events for mobile, requires an additional util library + * @option + * @example true + */ + swipe: true, + /** + * Allows the timing function to pause animation on hover. + * @option + * @example true + */ + pauseOnHover: true, + /** + * Allows Orbit to bind keyboard events to the slider, to animate frames with arrow keys + * @option + * @example true + */ + accessible: true, + /** + * Class applied to the container of Orbit + * @option + * @example 'orbit-container' + */ + containerClass: 'orbit-container', + /** + * Class applied to individual slides. + * @option + * @example 'orbit-slide' + */ + slideClass: 'orbit-slide', + /** + * Class applied to the bullet container. You're welcome. + * @option + * @example 'orbit-bullets' + */ + boxOfBullets: 'orbit-bullets', + /** + * Class applied to the `next` navigation button. + * @option + * @example 'orbit-next' + */ + nextClass: 'orbit-next', + /** + * Class applied to the `previous` navigation button. + * @option + * @example 'orbit-previous' + */ + prevClass: 'orbit-previous', + /** + * Boolean to flag the js to use motion ui classes or not. Default to true for backwards compatability. + * @option + * @example true + */ + useMUI: true + }; + /** + * Initializes the plugin by creating jQuery collections, setting attributes, and starting the animation. + * @function + * @private + */ + Orbit.prototype._init = function(){ + this.$wrapper = this.$element.find('.' + this.options.containerClass); + this.$slides = this.$element.find('.' + this.options.slideClass); + var $images = this.$element.find('img'), + initActive = this.$slides.filter('.is-active'); + + if(!initActive.length){ + this.$slides.eq(0).addClass('is-active'); + } + if(!this.options.useMUI){ + this.$slides.addClass('no-motionui'); + } + if($images.length){ + Foundation.onImagesLoaded($images, this._prepareForOrbit.bind(this)); + }else{ + this._prepareForOrbit();//hehe + } + + if(this.options.bullets){ + this._loadBullets(); + } + + this._events(); + + if(this.options.autoPlay){ + this.geoSync(); + } + if(this.options.accessible){ // allow wrapper to be focusable to enable arrow navigation + this.$wrapper.attr('tabindex', 0); + } + }; + /** + * Creates a jQuery collection of bullets, if they are being used. + * @function + * @private + */ + Orbit.prototype._loadBullets = function(){ + this.$bullets = this.$element.find('.' + this.options.boxOfBullets).find('button'); + }; + /** + * Sets a `timer` object on the orbit, and starts the counter for the next slide. + * @function + */ + Orbit.prototype.geoSync = function(){ + var _this = this; + this.timer = new Foundation.Timer( + this.$element, + {duration: this.options.timerDelay, + infinite: false}, + function(){ + _this.changeSlide(true); + }); + this.timer.start(); + }; + /** + * Sets wrapper and slide heights for the orbit. + * @function + * @private + */ + Orbit.prototype._prepareForOrbit = function(){ + var _this = this; + this._setWrapperHeight(function(max){ + _this._setSlideHeight(max); + }); + }; + /** + * Calulates the height of each slide in the collection, and uses the tallest one for the wrapper height. + * @function + * @private + * @param {Function} cb - a callback function to fire when complete. + */ + Orbit.prototype._setWrapperHeight = function(cb){//rewrite this to `for` loop + var max = 0, temp, counter = 0; + + this.$slides.each(function(){ + temp = this.getBoundingClientRect().height; + $(this).attr('data-slide', counter); + + if(counter){//if not the first slide, set css position and display property + $(this).css({'position': 'relative', 'display': 'none'}); + } + max = temp > max ? temp : max; + counter++; + }); + + if(counter === this.$slides.length){ + this.$wrapper.css({'height': max});//only change the wrapper height property once. + cb(max);//fire callback with max height dimension. + } + }; + /** + * Sets the max-height of each slide. + * @function + * @private + */ + Orbit.prototype._setSlideHeight = function(height){ + this.$slides.each(function(){ + $(this).css('max-height', height); + }); + }; + /** + * Adds event listeners to basically everything within the element. + * @function + * @private + */ + Orbit.prototype._events = function(){ + var _this = this; + + //*************************************** + //**Now using custom event - thanks to:** + //** Yohai Ararat of Toronto ** + //*************************************** + if(this.options.swipe){ + this.$slides.off('swipeleft.zf.orbit swiperight.zf.orbit') + .on('swipeleft.zf.orbit', function(e){ + e.preventDefault(); + _this.changeSlide(true); + }).on('swiperight.zf.orbit', function(e){ + e.preventDefault(); + _this.changeSlide(false); + }); + } + //*************************************** + + if(this.options.autoPlay){ + this.$slides.on('click.zf.orbit', function(){ + _this.$element.data('clickedOn', _this.$element.data('clickedOn') ? false : true); + _this.timer[_this.$element.data('clickedOn') ? 'pause' : 'start'](); + }); + if(this.options.pauseOnHover){ + this.$element.on('mouseenter.zf.orbit', function(){ + _this.timer.pause(); + }).on('mouseleave.zf.orbit', function(){ + if(!_this.$element.data('clickedOn')){ + _this.timer.start(); + } + }); + } + } + + if(this.options.navButtons){ + var $controls = this.$element.find('.' + this.options.nextClass + ', .' + this.options.prevClass); + $controls.attr('tabindex', 0) + //also need to handle enter/return and spacebar key presses + .on('click.zf.orbit touchend.zf.orbit', function(){ + _this.changeSlide($(this).hasClass(_this.options.nextClass)); + }); + } + + if(this.options.bullets){ + this.$bullets.on('click.zf.orbit touchend.zf.orbit', function(){ + if(/is-active/g.test(this.className)){ return false; }//if this is active, kick out of function. + var idx = $(this).data('slide'), + ltr = idx > _this.$slides.filter('.is-active').data('slide'), + $slide = _this.$slides.eq(idx); + + _this.changeSlide(ltr, $slide, idx); + }); + } + + this.$wrapper.add(this.$bullets).on('keydown.zf.orbit', function(e){ + // handle keyboard event with keyboard util + Foundation.Keyboard.handleKey(e, _this, { + next: function() { + _this.changeSlide(true); + }, + previous: function() { + _this.changeSlide(false); + }, + handled: function() { // if bullet is focused, make sure focus moves + if ($(e.target).is(_this.$bullets)) { + _this.$bullets.filter('.is-active').focus(); + } + } + }); + }); + }; + /** + * Changes the current slide to a new one. + * @function + * @param {Boolean} isLTR - flag if the slide should move left to right. + * @param {jQuery} chosenSlide - the jQuery element of the slide to show next, if one is selected. + * @param {Number} idx - the index of the new slide in its collection, if one chosen. + * @fires Orbit#slidechange + */ + Orbit.prototype.changeSlide = function(isLTR, chosenSlide, idx){ + var $curSlide = this.$slides.filter('.is-active').eq(0); + + if(/mui/g.test($curSlide[0].className)){ return false; }//if the slide is currently animating, kick out of the function + + var $firstSlide = this.$slides.first(), + $lastSlide = this.$slides.last(), + dirIn = isLTR ? 'Right' : 'Left', + dirOut = isLTR ? 'Left' : 'Right', + _this = this, + $newSlide; + + if(!chosenSlide){//most of the time, this will be auto played or clicked from the navButtons. + $newSlide = isLTR ? //if wrapping enabled, check to see if there is a `next` or `prev` sibling, if not, select the first or last slide to fill in. if wrapping not enabled, attempt to select `next` or `prev`, if there's nothing there, the function will kick out on next step. CRAZY NESTED TERNARIES!!!!! + (this.options.infiniteWrap ? $curSlide.next('.' + this.options.slideClass).length ? $curSlide.next('.' + this.options.slideClass) : $firstSlide : $curSlide.next('.' + this.options.slideClass))//pick next slide if moving left to right + : + (this.options.infiniteWrap ? $curSlide.prev('.' + this.options.slideClass).length ? $curSlide.prev('.' + this.options.slideClass) : $lastSlide : $curSlide.prev('.' + this.options.slideClass));//pick prev slide if moving right to left + }else{ + $newSlide = chosenSlide; + } + if($newSlide.length){ + if(this.options.bullets){ + idx = idx || this.$slides.index($newSlide);//grab index to update bullets + this._updateBullets(idx); + } + if(this.options.useMUI){ + + Foundation.Motion.animateIn( + $newSlide.addClass('is-active').css({'position': 'absolute', 'top': 0}), + this.options['animInFrom' + dirIn], + function(){ + $newSlide.css({'position': 'relative', 'display': 'block'}) + .attr('aria-live', 'polite'); + }); + + Foundation.Motion.animateOut( + $curSlide.removeClass('is-active'), + this.options['animOutTo' + dirOut], + function(){ + $curSlide.removeAttr('aria-live'); + if(_this.options.autoPlay){ + _this.timer.restart(); + } + //do stuff? + }); + }else{ + $curSlide.removeClass('is-active is-in').removeAttr('aria-live').hide(); + $newSlide.addClass('is-active is-in').attr('aria-live', 'polite').show(); + if(this.options.autoPlay){ + this.timer.restart(); + } + } + /** + * Triggers when the slide has finished animating in. + * @event Orbit#slidechange + */ + this.$element.trigger('slidechange.zf.orbit', [$newSlide]); + } + }; + /** + * Updates the active state of the bullets, if displayed. + * @function + * @private + * @param {Number} idx - the index of the current slide. + */ + Orbit.prototype._updateBullets = function(idx){ + var $oldBullet = this.$element.find('.' + this.options.boxOfBullets) + .find('.is-active').removeClass('is-active').blur(), + span = $oldBullet.find('span:last').detach(), + $newBullet = this.$bullets.eq(idx).addClass('is-active').append(span); + }; + /** + * Destroys the carousel and hides the element. + * @function + */ + Orbit.prototype.destroy = function(){ + delete this.timer; + this.$element.off('.zf.orbit').find('*').off('.zf.orbit').end().hide(); + Foundation.unregisterPlugin(this); + }; + + Foundation.plugin(Orbit, 'Orbit'); + +}(jQuery, window.Foundation); + +/** + * ResponsiveMenu module. + * @module foundation.responsiveMenu + * @requires foundation.util.triggers + * @requires foundation.util.mediaQuery + * @requires foundation.util.accordionMenu + * @requires foundation.util.drilldown + * @requires foundation.util.dropdown-menu + */ +!function(Foundation, $) { + 'use strict'; + + // The plugin matches the plugin classes with these plugin instances. + var MenuPlugins = { + dropdown: { + cssClass: 'dropdown', + plugin: Foundation._plugins['dropdown-menu'] || null + }, + drilldown: { + cssClass: 'drilldown', + plugin: Foundation._plugins['drilldown'] || null + }, + accordion: { + cssClass: 'accordion-menu', + plugin: Foundation._plugins['accordion-menu'] || null + } + }; + + // [PH] Media queries + var phMedia = { + small: '(min-width: 0px)', + medium: '(min-width: 640px)' + }; + + /** + * Creates a new instance of a responsive menu. + * @class + * @fires ResponsiveMenu#init + * @param {jQuery} element - jQuery object to make into a dropdown menu. + * @param {Object} options - Overrides to the default plugin settings. + */ + function ResponsiveMenu(element) { + this.$element = $(element); + this.rules = this.$element.data('responsive-menu'); + this.currentMq = null; + this.currentPlugin = null; + + this._init(); + this._events(); + + Foundation.registerPlugin(this); + } + + ResponsiveMenu.defaults = {}; + + /** + * Initializes the Menu by parsing the classes from the 'data-ResponsiveMenu' attribute on the element. + * @function + * @private + */ + ResponsiveMenu.prototype._init = function() { + var rulesTree = {}; + + // Parse rules from "classes" in data attribute + var rules = this.rules.split(' '); + + // Iterate through every rule found + for (var i = 0; i < rules.length; i++) { + var rule = rules[i].split('-'); + var ruleSize = rule.length > 1 ? rule[0] : 'small'; + var rulePlugin = rule.length > 1 ? rule[1] : rule[0]; + + if (MenuPlugins[rulePlugin] !== null) { + rulesTree[ruleSize] = MenuPlugins[rulePlugin]; + } + } + + this.rules = rulesTree; + + if (!$.isEmptyObject(rulesTree)) { + this._checkMediaQueries(); + } + }; + + /** + * Initializes events for the Menu. + * @function + * @private + */ + ResponsiveMenu.prototype._events = function() { + var _this = this; + + $(window).on('changed.zf.mediaquery', function() { + _this._checkMediaQueries(); + }); + // $(window).on('resize.zf.ResponsiveMenu', function() { + // _this._checkMediaQueries(); + // }); + }; + + /** + * Checks the current screen width against available media queries. If the media query has changed, and the plugin needed has changed, the plugins will swap out. + * @function + * @private + */ + ResponsiveMenu.prototype._checkMediaQueries = function() { + var matchedMq, _this = this; + // Iterate through each rule and find the last matching rule + $.each(this.rules, function(key) { + if (Foundation.MediaQuery.atLeast(key)) { + matchedMq = key; + } + }); + + // No match? No dice + if (!matchedMq) return; + + // Plugin already initialized? We good + if (this.currentPlugin instanceof this.rules[matchedMq].plugin) return; + + // Remove existing plugin-specific CSS classes + $.each(MenuPlugins, function(key, value) { + _this.$element.removeClass(value.cssClass); + }); + + // Add the CSS class for the new plugin + this.$element.addClass(this.rules[matchedMq].cssClass); + + // Create an instance of the new plugin + if (this.currentPlugin) this.currentPlugin.destroy(); + this.currentPlugin = new this.rules[matchedMq].plugin(this.$element, {}); + }; + + /** + * Destroys the instance of the current plugin on this element, as well as the window resize handler that switches the plugins out. + * @function + */ + ResponsiveMenu.prototype.destroy = function() { + this.currentPlugin.destroy(); + $(window).off('.zf.ResponsiveMenu'); + Foundation.unregisterPlugin(this); + }; + Foundation.plugin(ResponsiveMenu, 'ResponsiveMenu'); + +}(Foundation, jQuery); + +/** + * ResponsiveToggle module. + * @module foundation.responsiveToggle + * @requires foundation.util.mediaQuery + */ +!function($, Foundation) { + +'use strict'; + +/** + * Creates a new instance of Tab Bar. + * @class + * @fires ResponsiveToggle#init + * @param {jQuery} element - jQuery object to attach tab bar functionality to. + * @param {Object} options - Overrides to the default plugin settings. + */ +function ResponsiveToggle(element, options) { + this.$element = $(element); + this.options = $.extend({}, ResponsiveToggle.defaults, this.$element.data(), options); + + this._init(); + this._events(); + + Foundation.registerPlugin(this); +} + +ResponsiveToggle.defaults = { + /** + * The breakpoint after which the menu is always shown, and the tab bar is hidden. + * @option + * @example 'medium' + */ + hideFor: 'medium' +}; + +/** + * Initializes the tab bar by finding the target element, toggling element, and running update(). + * @function + * @private + */ +ResponsiveToggle.prototype._init = function() { + var targetID = this.$element.data('responsive-toggle'); + if (!targetID) { + console.error('Your tab bar needs an ID of a Menu as the value of data-tab-bar.'); + } + + this.$targetMenu = $('#'+targetID); + this.$toggler = this.$element.find('[data-toggle]'); + + this._update(); +}; + +/** + * Adds necessary event handlers for the tab bar to work. + * @function + * @private + */ +ResponsiveToggle.prototype._events = function() { + var _this = this; + + $(window).on('changed.zf.mediaquery', this._update.bind(this)); + + this.$toggler.on('click.zf.responsiveToggle', this.toggleMenu.bind(this)); +}; + +/** + * Checks the current media query to determine if the tab bar should be visible or hidden. + * @function + * @private + */ +ResponsiveToggle.prototype._update = function() { + // Mobile + if (!Foundation.MediaQuery.atLeast(this.options.hideFor)) { + this.$element.show(); + this.$targetMenu.hide(); + } + + // Desktop + else { + this.$element.hide(); + this.$targetMenu.show(); + } +}; + +/** + * Toggles the element attached to the tab bar. The toggle only happens if the screen is small enough to allow it. + * @function + * @fires ResponsiveToggle#toggled + */ +ResponsiveToggle.prototype.toggleMenu = function() { + if (!Foundation.MediaQuery.atLeast(this.options.hideFor)) { + this.$targetMenu.toggle(0); + + /** + * Fires when the element attached to the tab bar toggles. + * @event ResponsiveToggle#toggled + */ + this.$element.trigger('toggled.zf.responsiveToggle'); + } +}; +ResponsiveToggle.prototype.destroy = function(){ + //TODO this... +}; +Foundation.plugin(ResponsiveToggle, 'ResponsiveToggle'); + +}(jQuery, Foundation); + +/** + * Reveal module. + * @module foundation.reveal + * @requires foundation.util.keyboard + * @requires foundation.util.box + * @requires foundation.util.triggers + * @requires foundation.util.mediaQuery + * @requires foundation.util.motion if using animations + */ +!function(Foundation, $) { + 'use strict'; + + /** + * Creates a new instance of Reveal. + * @class + * @param {jQuery} element - jQuery object to use for the modal. + * @param {Object} options - optional parameters. + */ + + function Reveal(element, options) { + this.$element = element; + this.options = $.extend({}, Reveal.defaults, this.$element.data(), options); + this._init(); + + Foundation.registerPlugin(this); + Foundation.Keyboard.register('Reveal', { + 'ENTER': 'open', + 'SPACE': 'open', + 'ESCAPE': 'close', + 'TAB': 'tab_forward', + 'SHIFT_TAB': 'tab_backward' + }); + } + + Reveal.defaults = { + /** + * Motion-UI class to use for animated elements. If none used, defaults to simple show/hide. + * @option + * @example 'slide-in-left' + */ + animationIn: '', + /** + * Motion-UI class to use for animated elements. If none used, defaults to simple show/hide. + * @option + * @example 'slide-out-right' + */ + animationOut: '', + /** + * Time, in ms, to delay the opening of a modal after a click if no animation used. + * @option + * @example 10 + */ + showDelay: 0, + /** + * Time, in ms, to delay the closing of a modal after a click if no animation used. + * @option + * @example 10 + */ + hideDelay: 0, + /** + * Allows a click on the body/overlay to close the modal. + * @option + * @example true + */ + closeOnClick: true, + /** + * Allows the modal to close if the user presses the `ESCAPE` key. + * @option + * @example true + */ + closeOnEsc: true, + /** + * If true, allows multiple modals to be displayed at once. + * @option + * @example false + */ + multipleOpened: false, + /** + * Distance, in pixels, the modal should push down from the top of the screen. + * @option + * @example 100 + */ + vOffset: 100, + /** + * Distance, in pixels, the modal should push in from the side of the screen. + * @option + * @example 0 + */ + hOffset: 0, + /** + * Allows the modal to be fullscreen, completely blocking out the rest of the view. JS checks for this as well. + * @option + * @example false + */ + fullScreen: false, + /** + * Percentage of screen height the modal should push up from the bottom of the view. + * @option + * @example 10 + */ + btmOffsetPct: 10, + /** + * Allows the modal to generate an overlay div, which will cover the view when modal opens. + * @option + * @example true + */ + overlay: true, + /** + * Allows the modal to remove and reinject markup on close. Should be true if using video elements w/o using provider's api. + * @option + * @example false + */ + resetOnClose: false + }; + + /** + * Initializes the modal by adding the overlay and close buttons, (if selected). + * @private + */ + Reveal.prototype._init = function(){ + this.id = this.$element.attr('id'); + this.isActive = false; + + this.$anchor = $('[data-open="' + this.id + '"]').length ? $('[data-open="' + this.id + '"]') : $('[data-toggle="' + this.id + '"]'); + + if(this.$anchor.length){ + var anchorId = this.$anchor[0].id || Foundation.GetYoDigits(6, 'reveal'); + + this.$anchor.attr({ + 'aria-controls': this.id, + 'id': anchorId, + 'aria-haspopup': true, + 'tabindex': 0 + }); + this.$element.attr({'aria-labelledby': anchorId}); + } + + // this.options.fullScreen = this.$element.hasClass('full'); + if(this.options.fullScreen || this.$element.hasClass('full')){ + this.options.fullScreen = true; + this.options.overlay = false; + } + if(this.options.overlay && !this.$overlay){ + this.$overlay = this._makeOverlay(this.id); + } + + this.$element.attr({ + 'role': 'dialog', + 'aria-hidden': true, + 'data-yeti-box': this.id, + 'data-resize': this.id + }); + + this._events(); + }; + + /** + * Creates an overlay div to display behind the modal. + * @private + */ + Reveal.prototype._makeOverlay = function(id){ + var $overlay = $('
    ') + .addClass('reveal-overlay') + .attr({'tabindex': -1, 'aria-hidden': true}) + .appendTo('body'); + if(this.options.closeOnClick){ + $overlay.attr({ + 'data-close': id + }); + } + return $overlay; + }; + + /** + * Adds event handlers for the modal. + * @private + */ + Reveal.prototype._events = function(){ + var _this = this; + + this.$element.on({ + 'open.zf.trigger': this.open.bind(this), + 'close.zf.trigger': this.close.bind(this), + 'toggle.zf.trigger': this.toggle.bind(this), + 'resizeme.zf.trigger': function(){ + if(_this.$element.is(':visible')){ + _this._setPosition(function(){}); + } + } + }); + + if(this.$anchor.length){ + this.$anchor.on('keydown.zf.reveal', function(e){ + if(e.which === 13 || e.which === 32){ + e.stopPropagation(); + e.preventDefault(); + _this.open(); + } + }); + } + + + if(this.options.closeOnClick && this.options.overlay){ + this.$overlay.off('.zf.reveal').on('click.zf.reveal', this.close.bind(this)); + } + }; + /** + * Sets the position of the modal before opening + * @param {Function} cb - a callback function to execute when positioning is complete. + * @private + */ + Reveal.prototype._setPosition = function(cb){ + var eleDims = Foundation.Box.GetDimensions(this.$element); + var elePos = this.options.fullScreen ? 'reveal full' : (eleDims.height >= (0.5 * eleDims.windowDims.height)) ? 'reveal' : 'center'; + + if(elePos === 'reveal full'){ + //set to full height/width + this.$element + .offset(Foundation.Box.GetOffsets(this.$element, null, elePos, this.options.vOffset)) + .css({ + 'height': eleDims.windowDims.height, + 'width': eleDims.windowDims.width + }); + }else if(!Foundation.MediaQuery.atLeast('medium') || !Foundation.Box.ImNotTouchingYou(this.$element, null, true, false)){ + //if smaller than medium, resize to 100% width minus any custom L/R margin + this.$element + .css({ + 'width': eleDims.windowDims.width - (this.options.hOffset * 2) + }) + .offset(Foundation.Box.GetOffsets(this.$element, null, 'center', this.options.vOffset, this.options.hOffset)); + //flag a boolean so we can reset the size after the element is closed. + this.changedSize = true; + }else{ + this.$element + .css({ + 'max-height': eleDims.windowDims.height - (this.options.vOffset * (this.options.btmOffsetPct / 100 + 1)), + 'width': '' + }) + .offset(Foundation.Box.GetOffsets(this.$element, null, elePos, this.options.vOffset)); + //the max height based on a percentage of vertical offset plus vertical offset + } + + cb(); + }; + + /** + * Opens the modal controlled by `this.$anchor`, and closes all others by default. + * @function + * @fires Reveal#closeAll + * @fires Reveal#open + */ + Reveal.prototype.open = function(){ + var _this = this; + this.isActive = true; + //make element invisible, but remove display: none so we can get size and positioning + this.$element + .css({'visibility': 'hidden'}) + .show() + .scrollTop(0); + + this._setPosition(function(){ + _this.$element.hide() + .css({'visibility': ''}); + if(!_this.options.multipleOpened){ + /** + * Fires immediately before the modal opens. + * Closes any other modals that are currently open + * @event Reveal#closeAll + */ + _this.$element.trigger('closeme.zf.reveal', _this.id); + } + if(_this.options.animationIn){ + if(_this.options.overlay){ + Foundation.Motion.animateIn(_this.$overlay, 'fade-in', function(){ + Foundation.Motion.animateIn(_this.$element, _this.options.animationIn, function(){ + _this.focusableElements = Foundation.Keyboard.findFocusable(_this.$element); + }); + }); + }else{ + Foundation.Motion.animateIn(_this.$element, _this.options.animationIn, function(){ + _this.focusableElements = Foundation.Keyboard.findFocusable(_this.$element); + }); + } + }else{ + if(_this.options.overlay){ + _this.$overlay.show(0, function(){ + _this.$element.show(_this.options.showDelay, function(){ + }); + }); + }else{ + _this.$element.show(_this.options.showDelay, function(){ + }); + } + } + }); + + + // handle accessibility + this.$element.attr({'aria-hidden': false}).attr('tabindex', -1).focus() + /** + * Fires when the modal has successfully opened. + * @event Reveal#open + */ + .trigger('open.zf.reveal'); + + $('body').addClass('is-reveal-open') + .attr({'aria-hidden': (this.options.overlay || this.options.fullScreen) ? true : false}); + setTimeout(function(){ + _this._extraHandlers(); + // Foundation.reflow(); + }, 0); + }; + + /** + * Adds extra event handlers for the body and window if necessary. + * @private + */ + Reveal.prototype._extraHandlers = function(){ + var _this = this; + this.focusableElements = Foundation.Keyboard.findFocusable(this.$element); + + if(!this.options.overlay && this.options.closeOnClick && !this.options.fullScreen){ + $('body').on('click.zf.reveal', function(e){ + // if() + _this.close(); + }); + } + if(this.options.closeOnEsc){ + $(window).on('keydown.zf.reveal', function(e){ + Foundation.Keyboard.handleKey(e, _this, { + close: function() { + if (this.options.closeOnEsc) { + this.close(); + this.$anchor.focus(); + } + } + }); + if (_this.focusableElements.length === 0) { // no focusable elements inside the modal at all, prevent tabbing in general + e.preventDefault(); + } + }); + } + + // lock focus within modal while tabbing + this.$element.on('keydown.zf.reveal', function(e) { + var $target = $(this); + // handle keyboard event with keyboard util + Foundation.Keyboard.handleKey(e, _this, { + tab_forward: function() { + if (this.$element.find(':focus').is(_this.focusableElements.eq(-1))) { // left modal downwards, setting focus to first element + _this.focusableElements.eq(0).focus(); + e.preventDefault(); + } + }, + tab_backward: function() { + if (this.$element.find(':focus').is(_this.focusableElements.eq(0)) || this.$element.is(':focus')) { // left modal upwards, setting focus to last element + _this.focusableElements.eq(-1).focus(); + e.preventDefault(); + } + }, + open: function() { + if (_this.$element.find(':focus').is(_this.$element.find('[data-close]'))) { + setTimeout(function() { // set focus back to anchor if close button has been activated + _this.$anchor.focus(); + }, 1); + } else if ($target.is(_this.focusableElements)) { // dont't trigger if acual element has focus (i.e. inputs, links, ...) + this.open(); + } + }, + close: function() { + if (this.options.closeOnEsc) { + this.close(); + this.$anchor.focus(); + } + } + }); + }); + + }; + + /** + * Closes the modal. + * @function + * @fires Reveal#closed + */ + Reveal.prototype.close = function(){ + if(!this.isActive || !this.$element.is(':visible')){ + return false; + } + var _this = this; + + if(this.options.animationOut){ + Foundation.Motion.animateOut(this.$element, this.options.animationOut, function(){ + if(_this.options.overlay){ + Foundation.Motion.animateOut(_this.$overlay, 'fade-out', function(){ + }); + } + }); + }else{ + this.$element.hide(_this.options.hideDelay, function(){ + if(_this.options.overlay){ + _this.$overlay.hide(0, function(){ + }); + } + }); + } + //conditionals to remove extra event listeners added on open + if(this.options.closeOnEsc){ + $(window).off('keydown.zf.reveal'); + } + if(!this.options.overlay && this.options.closeOnClick){ + $('body').off('click.zf.reveal'); + } + this.$element.off('keydown.zf.reveal'); + + //if the modal changed size, reset it + if(this.changedSize){ + this.$element.css({ + 'height': '', + 'width': '' + }); + } + + $('body').removeClass('is-reveal-open').attr({'aria-hidden': false, 'tabindex': ''}); + + /** + * Resets the modal content + * This prevents a running video to keep going in the background + */ + if(this.options.resetOnClose) { + this.$element.html(this.$element.html()); + } + + this.isActive = false; + this.$element.attr({'aria-hidden': true}) + /** + * Fires when the modal is done closing. + * @event Reveal#closed + */ + .trigger('closed.zf.reveal'); + }; + /** + * Toggles the open/closed state of a modal. + * @function + */ + Reveal.prototype.toggle = function(){ + if(this.isActive){ + this.close(); + }else{ + this.open(); + } + }; + + /** + * Destroys an instance of a modal. + * @function + */ + Reveal.prototype.destroy = function() { + if(this.options.overlay){ + this.$overlay.hide().off().remove(); + } + this.$element.hide(); + this.$anchor.off(); + + Foundation.unregisterPlugin(this); + }; + + Foundation.plugin(Reveal, 'Reveal'); + + // Exports for AMD/Browserify + if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') + module.exports = Reveal; + if (typeof define === 'function') + define(['foundation'], function() { + return Reveal; + }); + +}(Foundation, jQuery); + +/** + * Slider module. + * @module foundation.slider + * @requires foundation.util.motion + * @requires foundation.util.triggers + * @requires foundation.util.keyboard + * @requires foundation.util.touch + */ +!function($, Foundation){ + 'use strict'; + + /** + * Creates a new instance of a drilldown menu. + * @class + * @param {jQuery} element - jQuery object to make into an accordion menu. + * @param {Object} options - Overrides to the default plugin settings. + */ + function Slider(element, options){ + this.$element = element; + this.options = $.extend({}, Slider.defaults, this.$element.data(), options); + + this._init(); + + Foundation.registerPlugin(this); + Foundation.Keyboard.register('Slider', { + 'ltr': { + 'ARROW_RIGHT': 'increase', + 'ARROW_UP': 'increase', + 'ARROW_DOWN': 'decrease', + 'ARROW_LEFT': 'decrease', + 'SHIFT_ARROW_RIGHT': 'increase_fast', + 'SHIFT_ARROW_UP': 'increase_fast', + 'SHIFT_ARROW_DOWN': 'decrease_fast', + 'SHIFT_ARROW_LEFT': 'decrease_fast' + }, + 'rtl': { + 'ARROW_LEFT': 'increase', + 'ARROW_RIGHT': 'decrease', + 'SHIFT_ARROW_LEFT': 'increase_fast', + 'SHIFT_ARROW_RIGHT': 'decrease_fast' + } + }); + } + + Slider.defaults = { + /** + * Minimum value for the slider scale. + * @option + * @example 0 + */ + start: 0, + /** + * Maximum value for the slider scale. + * @option + * @example 100 + */ + end: 100, + /** + * Minimum value change per change event. Not Currently Implemented! + + */ + step: 1, + /** + * Value at which the handle/input *(left handle/first input)* should be set to on initialization. + * @option + * @example 0 + */ + initialStart: 0, + /** + * Value at which the right handle/second input should be set to on initialization. + * @option + * @example 100 + */ + initialEnd: 100, + /** + * Allows the input to be located outside the container and visible. Set to by the JS + * @option + * @example false + */ + binding: false, + /** + * Allows the user to click/tap on the slider bar to select a value. + * @option + * @example true + */ + clickSelect: true, + /** + * Set to true and use the `vertical` class to change alignment to vertical. + * @option + * @example false + */ + vertical: false, + /** + * Allows the user to drag the slider handle(s) to select a value. + * @option + * @example true + */ + draggable: true, + /** + * Disables the slider and prevents event listeners from being applied. Double checked by JS with `disabledClass`. + * @option + * @example false + */ + disabled: false, + /** + * Allows the use of two handles. Double checked by the JS. Changes some logic handling. + * @option + * @example false + */ + doubleSided: false, + /** + * Potential future feature. + */ + // steps: 100, + /** + * Number of decimal places the plugin should go to for floating point precision. + * @option + * @example 2 + */ + decimal: 2, + /** + * Time delay for dragged elements. + */ + // dragDelay: 0, + /** + * Time, in ms, to animate the movement of a slider handle if user clicks/taps on the bar. Needs to be manually set if updating the transition time in the Sass settings. + * @option + * @example 200 + */ + moveTime: 200,//update this if changing the transition time in the sass + /** + * Class applied to disabled sliders. + * @option + * @example 'disabled' + */ + disabledClass: 'disabled' + }; + /** + * Initilizes the plugin by reading/setting attributes, creating collections and setting the initial position of the handle(s). + * @function + * @private + */ + Slider.prototype._init = function(){ + this.inputs = this.$element.find('input'); + this.handles = this.$element.find('[data-slider-handle]'); + + this.$handle = this.handles.eq(0); + this.$input = this.inputs.length ? this.inputs.eq(0) : $('#' + this.$handle.attr('aria-controls')); + this.$fill = this.$element.find('[data-slider-fill]').css(this.options.vertical ? 'height' : 'width', 0); + + var isDbl = false, + _this = this; + if(this.options.disabled || this.$element.hasClass(this.options.disabledClass)){ + this.options.disabled = true; + this.$element.addClass(this.options.disabledClass); + } + if(!this.inputs.length){ + this.inputs = $().add(this.$input); + this.options.binding = true; + } + this._setInitAttr(0); + this._events(this.$handle); + + if(this.handles[1]){ + this.options.doubleSided = true; + this.$handle2 = this.handles.eq(1); + this.$input2 = this.inputs.length ? this.inputs.eq(1) : $('#' + this.$handle2.attr('aria-controls')); + + if(!this.inputs[1]){ + this.inputs = this.inputs.add(this.$input2); + } + isDbl = true; + + this._setHandlePos(this.$handle, this.options.initialStart, true, function(){ + + _this._setHandlePos(_this.$handle2, _this.options.initialEnd); + }); + // this.$handle.triggerHandler('click.zf.slider'); + this._setInitAttr(1); + this._events(this.$handle2); + } + + if(!isDbl){ + this._setHandlePos(this.$handle, this.options.initialStart, true); + } + }; + /** + * Sets the position of the selected handle and fill bar. + * @function + * @private + * @param {jQuery} $hndl - the selected handle to move. + * @param {Number} location - floating point between the start and end values of the slider bar. + * @param {Function} cb - callback function to fire on completion. + * @fires Slider#moved + */ + Slider.prototype._setHandlePos = function($hndl, location, noInvert, cb){ + //might need to alter that slightly for bars that will have odd number selections. + location = parseFloat(location);//on input change events, convert string to number...grumble. + // prevent slider from running out of bounds + if(location < this.options.start){ location = this.options.start; } + else if(location > this.options.end){ location = this.options.end; } + + var isDbl = this.options.doubleSided, + callback = cb || null; + + if(isDbl){ + if(this.handles.index($hndl) === 0){ + var h2Val = parseFloat(this.$handle2.attr('aria-valuenow')); + location = location >= h2Val ? h2Val - this.options.step : location; + }else{ + var h1Val = parseFloat(this.$handle.attr('aria-valuenow')); + location = location <= h1Val ? h1Val + this.options.step : location; + } + } + + if(this.options.vertical && !noInvert){ + location = this.options.end - location; + } + var _this = this, + vert = this.options.vertical, + hOrW = vert ? 'height' : 'width', + lOrT = vert ? 'top' : 'left', + halfOfHandle = $hndl[0].getBoundingClientRect()[hOrW] / 2, + elemDim = this.$element[0].getBoundingClientRect()[hOrW], + pctOfBar = percent(location, this.options.end).toFixed(2), + pxToMove = (elemDim - halfOfHandle) * pctOfBar, + movement = (percent(pxToMove, elemDim) * 100).toFixed(this.options.decimal), + location = location > 0 ? parseFloat(location.toFixed(this.options.decimal)) : 0, + anim, prog, start = null, css = {}; + + this._setValues($hndl, location); + + if(this.options.doubleSided){//update to calculate based on values set to respective inputs?? + var isLeftHndl = this.handles.index($hndl) === 0, + dim, + idx = this.handles.index($hndl); + + if(isLeftHndl){ + css[lOrT] = (pctOfBar > 0 ? pctOfBar * 100 : 0) + '%';// + dim = /*Math.abs*/((percent(this.$handle2.position()[lOrT] + halfOfHandle, elemDim) - parseFloat(pctOfBar)) * 100).toFixed(this.options.decimal) + '%'; + css['min-' + hOrW] = dim; + if(cb && typeof cb === 'function'){ cb(); } + }else{ + location = (location < 100 ? location : 100) - (parseFloat(this.$handle[0].style.left) || this.options.end - location); + css['min-' + hOrW] = location + '%'; + } + } + + this.$element.one('finished.zf.animate', function(){ + _this.animComplete = true; + /** + * Fires when the handle is done moving. + * @event Slider#moved + */ + _this.$element.trigger('moved.zf.slider', [$hndl]); + }); + var moveTime = _this.$element.data('dragging') ? 1000/60 : _this.options.moveTime; + /*var move = new */Foundation.Move(moveTime, $hndl, function(){ + $hndl.css(lOrT, movement + '%'); + if(!_this.options.doubleSided){ + _this.$fill.css(hOrW, pctOfBar * 100 + '%'); + }else{ + _this.$fill.css(css); + } + }); + // move.do(); + }; + /** + * Sets the initial attribute for the slider element. + * @function + * @private + * @param {Number} idx - index of the current handle/input to use. + */ + Slider.prototype._setInitAttr = function(idx){ + var id = this.inputs.eq(idx).attr('id') || Foundation.GetYoDigits(6, 'slider'); + this.inputs.eq(idx).attr({ + 'id': id, + 'max': this.options.end, + 'min': this.options.start + + }); + this.handles.eq(idx).attr({ + 'role': 'slider', + 'aria-controls': id, + 'aria-valuemax': this.options.end, + 'aria-valuemin': this.options.start, + 'aria-valuenow': idx === 0 ? this.options.initialStart : this.options.initialEnd, + 'aria-orientation': this.options.vertical ? 'vertical' : 'horizontal', + 'tabindex': 0 + }); + }; + /** + * Sets the input and `aria-valuenow` values for the slider element. + * @function + * @private + * @param {jQuery} $handle - the currently selected handle. + * @param {Number} val - floating point of the new value. + */ + Slider.prototype._setValues = function($handle, val){ + var idx = this.options.doubleSided ? this.handles.index($handle) : 0; + this.inputs.eq(idx).val(val); + $handle.attr('aria-valuenow', val); + }; + /** + * Handles events on the slider element. + * Calculates the new location of the current handle. + * If there are two handles and the bar was clicked, it determines which handle to move. + * @function + * @private + * @param {Object} e - the `event` object passed from the listener. + * @param {jQuery} $handle - the current handle to calculate for, if selected. + * @param {Number} val - floating point number for the new value of the slider. + */ + Slider.prototype._handleEvent = function(e, $handle, val){ + var value, hasVal; + if(!val){//click or drag events + e.preventDefault(); + var _this = this, + vertical = this.options.vertical, + param = vertical ? 'height' : 'width', + direction = vertical ? 'top' : 'left', + pageXY = vertical ? e.pageY : e.pageX, + halfOfHandle = this.$handle[0].getBoundingClientRect()[param] / 2, + barDim = this.$element[0].getBoundingClientRect()[param], + barOffset = (this.$element.offset()[direction] - pageXY), + barXY = barOffset > 0 ? -halfOfHandle : (barOffset - halfOfHandle) < -barDim ? barDim : Math.abs(barOffset),//if the cursor position is less than or greater than the elements bounding coordinates, set coordinates within those bounds + // eleDim = this.$element[0].getBoundingClientRect()[param], + offsetPct = percent(barXY, barDim); + value = (this.options.end - this.options.start) * offsetPct; + hasVal = false; + + if(!$handle){//figure out which handle it is, pass it to the next function. + var firstHndlPos = absPosition(this.$handle, direction, barXY, param), + secndHndlPos = absPosition(this.$handle2, direction, barXY, param); + $handle = firstHndlPos <= secndHndlPos ? this.$handle : this.$handle2; + } + + }else{//change event on input + value = val; + hasVal = true; + } + + this._setHandlePos($handle, value, hasVal); + }; + /** + * Adds event listeners to the slider elements. + * @function + * @private + * @param {jQuery} $handle - the current handle to apply listeners to. + */ + Slider.prototype._events = function($handle){ + if(this.options.disabled){ return false; } + + var _this = this, + curHandle, + timer; + + this.inputs.off('change.zf.slider').on('change.zf.slider', function(e){ + var idx = _this.inputs.index($(this)); + _this._handleEvent(e, _this.handles.eq(idx), $(this).val()); + }); + + if(this.options.clickSelect){ + this.$element.off('click.zf.slider').on('click.zf.slider', function(e){ + if(_this.$element.data('dragging')){ return false; } + _this.animComplete = false; + if(_this.options.doubleSided){ + _this._handleEvent(e); + }else{ + _this._handleEvent(e, _this.$handle); + } + }); + } + + if(this.options.draggable){ + this.handles.addTouch(); + // var curHandle, + // timer, + var $body = $('body'); + $handle + .off('mousedown.zf.slider') + .on('mousedown.zf.slider', function(e){ + $handle.addClass('is-dragging'); + _this.$fill.addClass('is-dragging');// + _this.$element.data('dragging', true); + _this.animComplete = false; + curHandle = $(e.currentTarget); + + $body.on('mousemove.zf.slider', function(e){ + e.preventDefault(); + + // timer = setTimeout(function(){ + _this._handleEvent(e, curHandle); + // }, _this.options.dragDelay); + }).on('mouseup.zf.slider', function(e){ + // clearTimeout(timer); + _this.animComplete = true; + _this._handleEvent(e, curHandle); + $handle.removeClass('is-dragging'); + _this.$fill.removeClass('is-dragging'); + _this.$element.data('dragging', false); + // Foundation.reflow(_this.$element, 'slider'); + $body.off('mousemove.zf.slider mouseup.zf.slider'); + }); + }); + } + $handle.off('keydown.zf.slider').on('keydown.zf.slider', function(e){ + var idx = _this.options.doubleSided ? _this.handles.index($(this)) : 0, + oldValue = parseFloat(_this.inputs.eq(idx).val()), + newValue; + + var _$handle = $(this); + + // handle keyboard event with keyboard util + Foundation.Keyboard.handleKey(e, _this, { + decrease: function() { + newValue = oldValue - _this.options.step; + }, + increase: function() { + newValue = oldValue + _this.options.step; + }, + decrease_fast: function() { + newValue = oldValue - _this.options.step * 10; + }, + increase_fast: function() { + newValue = oldValue + _this.options.step * 10; + }, + handled: function() { // only set handle pos when event was handled specially + e.preventDefault(); + _this._setHandlePos(_$handle, newValue, true); + } + }); + /*if (newValue) { // if pressed key has special function, update value + e.preventDefault(); + _this._setHandlePos(_$handle, newValue); + }*/ + }); + }; + /** + * Destroys the slider plugin. + */ + Slider.prototype.destroy = function(){ + this.handles.off('.zf.slider'); + this.inputs.off('.zf.slider'); + this.$element.off('.zf.slider'); + + Foundation.unregisterPlugin(this); + }; + + Foundation.plugin(Slider, 'Slider'); + + function percent(frac, num){ + return (frac / num); + } + function absPosition($handle, dir, clickPos, param){ + return Math.abs(($handle.position()[dir] + ($handle[param]() / 2)) - clickPos); + } +}(jQuery, window.Foundation); + +//*********this is in case we go to static, absolute positions instead of dynamic positioning******** +// this.setSteps(function(){ +// _this._events(); +// var initStart = _this.options.positions[_this.options.initialStart - 1] || null; +// var initEnd = _this.options.initialEnd ? _this.options.position[_this.options.initialEnd - 1] : null; +// if(initStart || initEnd){ +// _this._handleEvent(initStart, initEnd); +// } +// }); + +//***********the other part of absolute positions************* +// Slider.prototype.setSteps = function(cb){ +// var posChange = this.$element.outerWidth() / this.options.steps; +// var counter = 0 +// while(counter < this.options.steps){ +// if(counter){ +// this.options.positions.push(this.options.positions[counter - 1] + posChange); +// }else{ +// this.options.positions.push(posChange); +// } +// counter++; +// } +// cb(); +// }; + +/** + * Sticky module. + * @module foundation.sticky + * @requires foundation.util.triggers + * @requires foundation.util.mediaQuery + */ +!function($, Foundation){ + 'use strict'; + + /** + * Creates a new instance of a sticky thing. + * @class + * @param {jQuery} element - jQuery object to make sticky. + * @param {Object} options - options object passed when creating the element programmatically. + */ + function Sticky(element, options){ + this.$element = element; + this.options = $.extend({}, Sticky.defaults, this.$element.data(), options); + + this._init(); + + Foundation.registerPlugin(this); + } + Sticky.defaults = { + /** + * Customizable container template. Add your own classes for styling and sizing. + * @option + * @example '
    ' + */ + container: '
    ', + /** + * Location in the view the element sticks to. + * @option + * @example 'top' + */ + stickTo: 'top', + /** + * If anchored to a single element, the id of that element. + * @option + * @example 'exampleId' + */ + anchor: '', + /** + * If using more than one element as anchor points, the id of the top anchor. + * @option + * @example 'exampleId:top' + */ + topAnchor: '', + /** + * If using more than one element as anchor points, the id of the bottom anchor. + * @option + * @example 'exampleId:bottom' + */ + btmAnchor: '', + /** + * Margin, in `em`'s to apply to the top of the element when it becomes sticky. + * @option + * @example 1 + */ + marginTop: 1, + /** + * Margin, in `em`'s to apply to the bottom of the element when it becomes sticky. + * @option + * @example 1 + */ + marginBottom: 1, + /** + * Breakpoint string that is the minimum screen size an element should become sticky. + * @option + * @example 'medium' + */ + stickyOn: 'medium', + /** + * Class applied to sticky element, and removed on destruction. Foundation defaults to `sticky`. + * @option + * @example 'sticky' + */ + stickyClass: 'sticky', + /** + * Class applied to sticky container. Foundation defaults to `sticky-container`. + * @option + * @example 'sticky-container' + */ + containerClass: 'sticky-container', + /** + * Number of scroll events between the plugin's recalculating sticky points. Setting it to `0` will cause it to recalc every scroll event, setting it to `-1` will prevent recalc on scroll. + * @option + * @example 50 + */ + checkEvery: -1 + }; + + /** + * Initializes the sticky element by adding classes, getting/setting dimensions, breakpoints and attributes + * Also triggered by Foundation._reflow + * @function + * @private + */ + Sticky.prototype._init = function(){ + var $parent = this.$element.parent('[data-sticky-container]'), + id = this.$element[0].id || Foundation.GetYoDigits(6, 'sticky'), + _this = this; + + if(!$parent.length){ + this.wasWrapped = true; + } + this.$container = $parent.length ? $parent : $(this.options.container).wrapInner(this.$element); + this.$container.addClass(this.options.containerClass); + + + this.$element.addClass(this.options.stickyClass) + .attr({'data-resize': id}); + + this.scrollCount = this.options.checkEvery; + this.isStuck = false; + // console.log(this.options.anchor, this.options.topAnchor); + if(this.options.topAnchor !== ''){ + this._parsePoints(); + // console.log(this.points[0]); + }else{ + this.$anchor = this.options.anchor ? $('#' + this.options.anchor) : $(document.body); + } + + + this._setSizes(function(){ + _this._calc(false); + }); + this._events(id.split('-').reverse().join('-')); + }; + /** + * If using multiple elements as anchors, calculates the top and bottom pixel values the sticky thing should stick and unstick on. + * @function + * @private + */ + Sticky.prototype._parsePoints = function(){ + var top = this.options.topAnchor, + btm = this.options.btmAnchor, + pts = [top, btm], + breaks = {}; + for(var i = 0, len = pts.length; i < len && pts[i]; i++){ + var pt; + if(typeof pts[i] === 'number'){ + pt = pts[i]; + }else{ + var place = pts[i].split(':'), + anchor = $('#' + place[0]); + + pt = anchor.offset().top; + if(place[1] && place[1].toLowerCase() === 'bottom'){ + pt += anchor[0].getBoundingClientRect().height; + } + } + breaks[i] = pt; + } + // console.log(breaks); + this.points = breaks; + return; + }; + + /** + * Adds event handlers for the scrolling element. + * @private + * @param {String} id - psuedo-random id for unique scroll event listener. + */ + Sticky.prototype._events = function(id){ + // console.log('called'); + var _this = this, + scrollListener = 'scroll.zf.' + id; + if(this.isOn){ return; } + if(this.canStick){ + this.isOn = true; + // this.$anchor.off('change.zf.sticky') + // .on('change.zf.sticky', function(){ + // _this._setSizes(function(){ + // _this._calc(false); + // }); + // }); + + $(window).off(scrollListener) + .on(scrollListener, function(e){ + if(_this.scrollCount === 0){ + _this.scrollCount = _this.options.checkEvery; + _this._setSizes(function(){ + _this._calc(false, window.pageYOffset); + }); + }else{ + _this.scrollCount--; + _this._calc(false, window.pageYOffset); + } + }); + } + + this.$element.off('resizeme.zf.trigger') + .on('resizeme.zf.trigger', function(e, el){ + _this._setSizes(function(){ + _this._calc(false); + if(_this.canStick){ + if(!_this.isOn){ + _this._events(id); + } + }else if(_this.isOn){ + _this._pauseListeners(scrollListener); + } + }); + }); + }; + + /** + * Removes event handlers for scroll and change events on anchor. + * @fires Sticky#pause + * @param {String} scrollListener - unique, namespaced scroll listener attached to `window` + */ + Sticky.prototype._pauseListeners = function(scrollListener){ + this.isOn = false; + // this.$anchor.off('change.zf.sticky'); + $(window).off(scrollListener); + + /** + * Fires when the plugin is paused due to resize event shrinking the view. + * @event Sticky#pause + * @private + */ + this.$element.trigger('pause.zf.sticky'); + }; + + /** + * Called on every `scroll` event and on `_init` + * fires functions based on booleans and cached values + * @param {Boolean} checkSizes - true if plugin should recalculate sizes and breakpoints. + * @param {Number} scroll - current scroll position passed from scroll event cb function. If not passed, defaults to `window.pageYOffset`. + */ + Sticky.prototype._calc = function(checkSizes, scroll){ + if(checkSizes){ this._setSizes(); } + + if(!this.canStick){ + if(this.isStuck){ + this._removeSticky(true); + } + return false; + } + + if(!scroll){ scroll = window.pageYOffset; } + + if(scroll >= this.topPoint){ + if(scroll <= this.bottomPoint){ + if(!this.isStuck){ + this._setSticky(); + } + }else{ + if(this.isStuck){ + this._removeSticky(false); + } + } + }else{ + if(this.isStuck){ + this._removeSticky(true); + } + } + }; + /** + * Causes the $element to become stuck. + * Adds `position: fixed;`, and helper classes. + * @fires Sticky#stuckto + * @function + * @private + */ + Sticky.prototype._setSticky = function(){ + var stickTo = this.options.stickTo, + mrgn = stickTo === 'top' ? 'marginTop' : 'marginBottom', + notStuckTo = stickTo === 'top' ? 'bottom' : 'top', + css = {}; + + css[mrgn] = this.options[mrgn] + 'em'; + css[stickTo] = 0; + css[notStuckTo] = 'auto'; + css['left'] = this.$container.offset().left + parseInt(window.getComputedStyle(this.$container[0])["padding-left"], 10); + this.isStuck = true; + this.$element.removeClass('is-anchored is-at-' + notStuckTo) + .addClass('is-stuck is-at-' + stickTo) + .css(css) + /** + * Fires when the $element has become `position: fixed;` + * Namespaced to `top` or `bottom`. + * @event Sticky#stuckto + */ + .trigger('sticky.zf.stuckto:' + stickTo); + }; + + /** + * Causes the $element to become unstuck. + * Removes `position: fixed;`, and helper classes. + * Adds other helper classes. + * @param {Boolean} isTop - tells the function if the $element should anchor to the top or bottom of its $anchor element. + * @fires Sticky#unstuckfrom + * @private + */ + Sticky.prototype._removeSticky = function(isTop){ + var stickTo = this.options.stickTo, + stickToTop = stickTo === 'top', + css = {}, + anchorPt = (this.points ? this.points[1] - this.points[0] : this.anchorHeight) - this.elemHeight, + mrgn = stickToTop ? 'marginTop' : 'marginBottom', + notStuckTo = stickToTop ? 'bottom' : 'top', + topOrBottom = isTop ? 'top' : 'bottom'; + + css[mrgn] = 0; + + if((isTop && !stickToTop) || (stickToTop && !isTop)){ + css[stickTo] = anchorPt; + css[notStuckTo] = 0; + }else{ + css[stickTo] = 0; + css[notStuckTo] = anchorPt; + } + + css['left'] = ''; + this.isStuck = false; + this.$element.removeClass('is-stuck is-at-' + stickTo) + .addClass('is-anchored is-at-' + topOrBottom) + .css(css) + /** + * Fires when the $element has become anchored. + * Namespaced to `top` or `bottom`. + * @event Sticky#unstuckfrom + */ + .trigger('sticky.zf.unstuckfrom:' + topOrBottom); + }; + + /** + * Sets the $element and $container sizes for plugin. + * Calls `_setBreakPoints`. + * @param {Function} cb - optional callback function to fire on completion of `_setBreakPoints`. + * @private + */ + Sticky.prototype._setSizes = function(cb){ + this.canStick = Foundation.MediaQuery.atLeast(this.options.stickyOn); + if(!this.canStick){ cb(); } + var _this = this, + newElemWidth = this.$container[0].getBoundingClientRect().width, + comp = window.getComputedStyle(this.$container[0]), + pdng = parseInt(comp['padding-right'], 10); + + // console.log(this.$anchor); + if(this.$anchor && this.$anchor.length){ + this.anchorHeight = this.$anchor[0].getBoundingClientRect().height; + }else{ + this._parsePoints(); + } + + this.$element.css({ + 'max-width': newElemWidth - pdng + 'px' + }); + + var newContainerHeight = this.$element[0].getBoundingClientRect().height || this.containerHeight; + this.containerHeight = newContainerHeight; + this.$container.css({ + height: newContainerHeight + }); + this.elemHeight = newContainerHeight; + + if (this.isStuck) { + this.$element.css({"left":this.$container.offset().left + parseInt(comp['padding-left'], 10)}); + } + + this._setBreakPoints(newContainerHeight, function(){ + if(cb){ cb(); } + }); + + }; + /** + * Sets the upper and lower breakpoints for the element to become sticky/unsticky. + * @param {Number} elemHeight - px value for sticky.$element height, calculated by `_setSizes`. + * @param {Function} cb - optional callback function to be called on completion. + * @private + */ + Sticky.prototype._setBreakPoints = function(elemHeight, cb){ + if(!this.canStick){ + if(cb){ cb(); } + else{ return false; } + } + var mTop = emCalc(this.options.marginTop), + mBtm = emCalc(this.options.marginBottom), + topPoint = this.points ? this.points[0] : this.$anchor.offset().top, + bottomPoint = this.points ? this.points[1] : topPoint + this.anchorHeight, + // topPoint = this.$anchor.offset().top || this.points[0], + // bottomPoint = topPoint + this.anchorHeight || this.points[1], + winHeight = window.innerHeight; + + if(this.options.stickTo === 'top'){ + topPoint -= mTop; + bottomPoint -= (elemHeight + mTop); + }else if(this.options.stickTo === 'bottom'){ + topPoint -= (winHeight - (elemHeight + mBtm)); + bottomPoint -= (winHeight - mBtm); + }else{ + //this would be the stickTo: both option... tricky + } + + this.topPoint = topPoint; + this.bottomPoint = bottomPoint; + + if(cb){ cb(); } + }; + + /** + * Destroys the current sticky element. + * Resets the element to the top position first. + * Removes event listeners, JS-added css properties and classes, and unwraps the $element if the JS added the $container. + * @function + */ + Sticky.prototype.destroy = function(){ + this._removeSticky(true); + + this.$element.removeClass(this.options.stickyClass + ' is-anchored is-at-top') + .css({ + height: '', + top: '', + bottom: '', + 'max-width': '' + }) + .off('resizeme.zf.trigger'); + + this.$anchor.off('change.zf.sticky'); + $(window).off('scroll.zf.sticky'); + + if(this.wasWrapped){ + this.$element.unwrap(); + }else{ + this.$container.removeClass(this.options.containerClass) + .css({ + height: '' + }); + } + Foundation.unregisterPlugin(this); + }; + /** + * Helper function to calculate em values + * @param Number {em} - number of em's to calculate into pixels + */ + function emCalc(em){ + return parseInt(window.getComputedStyle(document.body, null).fontSize, 10) * em; + } + Foundation.plugin(Sticky, 'Sticky'); +}(jQuery, window.Foundation); + +/** + * Tabs module. + * @module foundation.tabs + * @requires foundation.util.keyboard + * @requires foundation.util.timerAndImageLoader if tabs contain images + */ +!function($, Foundation) { + 'use strict'; + + /** + * Creates a new instance of tabs. + * @class + * @fires Tabs#init + * @param {jQuery} element - jQuery object to make into tabs. + * @param {Object} options - Overrides to the default plugin settings. + */ + function Tabs(element, options){ + this.$element = element; + this.options = $.extend({}, Tabs.defaults, this.$element.data(), options); + + this._init(); + Foundation.registerPlugin(this); + Foundation.Keyboard.register('Tabs', { + 'ENTER': 'open', + 'SPACE': 'open', + 'ARROW_RIGHT': 'next', + 'ARROW_UP': 'previous', + 'ARROW_DOWN': 'next', + 'ARROW_LEFT': 'previous' + // 'TAB': 'next', + // 'SHIFT_TAB': 'previous' + }); + } + + Tabs.defaults = { + // /** + // * Allows the JS to alter the url of the window. Not yet implemented. + // */ + // deepLinking: false, + // /** + // * If deepLinking is enabled, allows the window to scroll to content if window is loaded with a hash including a tab-pane id + // */ + // scrollToContent: false, + /** + * Allows the window to scroll to content of active pane on load if set to true. + * @option + * @example false + */ + autoFocus: false, + /** + * Allows keyboard input to 'wrap' around the tab links. + * @option + * @example true + */ + wrapOnKeys: true, + /** + * Allows the tab content panes to match heights if set to true. + * @option + * @example false + */ + matchHeight: false, + /** + * Class applied to `li`'s in tab link list. + * @option + * @example 'tabs-title' + */ + linkClass: 'tabs-title', + // contentClass: 'tabs-content', + /** + * Class applied to the content containers. + * @option + * @example 'tabs-panel' + */ + panelClass: 'tabs-panel' + }; + + /** + * Initializes the tabs by showing and focusing (if autoFocus=true) the preset active tab. + * @private + */ + Tabs.prototype._init = function(){ + var _this = this; + + this.$tabTitles = this.$element.find('.' + this.options.linkClass); + this.$tabContent = $('[data-tabs-content="' + this.$element[0].id + '"]'); + + this.$tabTitles.each(function(){ + var $elem = $(this), + $link = $elem.find('a'), + isActive = $elem.hasClass('is-active'), + hash = $link.attr('href').slice(1), + linkId = hash + '-label', + $tabContent = $(hash); + + $elem.attr({'role': 'presentation'}); + + $link.attr({ + 'role': 'tab', + 'aria-controls': hash, + 'aria-selected': isActive, + 'id': linkId + }); + + $tabContent.attr({ + 'role': 'tabpanel', + 'aria-hidden': !isActive, + 'aria-labelledby': linkId + }); + + if(isActive && _this.options.autoFocus){ + $link.focus(); + } + }); + if(this.options.matchHeight){ + var $images = this.$tabContent.find('img'); + if($images.length){ + Foundation.onImagesLoaded($images, this._setHeight.bind(this)); + }else{ + this._setHeight(); + } + } + this._events(); + }; + /** + * Adds event handlers for items within the tabs. + * @private + */ + Tabs.prototype._events = function(){ + this._addKeyHandler(); + this._addClickHandler(); + if(this.options.matchHeight){ + $(window).on('changed.zf.mediaquery', this._setHeight.bind(this)); + } + }; + + /** + * Adds click handlers for items within the tabs. + * @private + */ + Tabs.prototype._addClickHandler = function(){ + var _this = this; + this.$element.off('click.zf.tabs') + .on('click.zf.tabs', '.' + this.options.linkClass, function(e){ + e.preventDefault(); + e.stopPropagation(); + if($(this).hasClass('is-active')){ + return; + } + _this._handleTabChange($(this)); + }); + }; + + /** + * Adds keyboard event handlers for items within the tabs. + * @private + */ + Tabs.prototype._addKeyHandler = function(){ + var _this = this; + var $firstTab = _this.$element.find('li:first-of-type'); + var $lastTab = _this.$element.find('li:last-of-type'); + + this.$tabTitles.off('keydown.zf.tabs').on('keydown.zf.tabs', function(e){ + if(e.which === 9) return; + e.stopPropagation(); + e.preventDefault(); + + var $element = $(this), + $elements = $element.parent('ul').children('li'), + $prevElement, + $nextElement; + + $elements.each(function(i) { + if ($(this).is($element)) { + if (_this.options.wrapOnKeys) { + $prevElement = i === 0 ? $elements.last() : $elements.eq(i-1); + $nextElement = i === $elements.length -1 ? $elements.first() : $elements.eq(i+1); + } else { + $prevElement = $elements.eq(Math.max(0, i-1)); + $nextElement = $elements.eq(Math.min(i+1, $elements.length-1)); + } + return; + } + }); + + // handle keyboard event with keyboard util + Foundation.Keyboard.handleKey(e, _this, { + open: function() { + $element.find('[role="tab"]').focus(); + _this._handleTabChange($element); + }, + previous: function() { + $prevElement.find('[role="tab"]').focus(); + _this._handleTabChange($prevElement); + }, + next: function() { + $nextElement.find('[role="tab"]').focus(); + _this._handleTabChange($nextElement); + } + }); + }); + }; + + + /** + * Opens the tab `$targetContent` defined by `$target`. + * @param {jQuery} $target - Tab to open. + * @fires Tabs#change + * @function + */ + Tabs.prototype._handleTabChange = function($target){ + var $tabLink = $target.find('[role="tab"]'), + hash = $tabLink.attr('href'), + $targetContent = $(hash), + + $oldTab = this.$element.find('.' + this.options.linkClass + '.is-active') + .removeClass('is-active').find('[role="tab"]') + .attr({'aria-selected': 'false'}).attr('href'); + + $($oldTab).removeClass('is-active').attr({'aria-hidden': 'true'}); + + $target.addClass('is-active'); + + $tabLink.attr({'aria-selected': 'true'}); + + $targetContent + .addClass('is-active') + .attr({'aria-hidden': 'false'}); + + /** + * Fires when the plugin has successfully changed tabs. + * @event Tabs#change + */ + this.$element.trigger('change.zf.tabs', [$target]); + // Foundation.reflow(this.$element, 'tabs'); + }; + + /** + * Public method for selecting a content pane to display. + * @param {jQuery | String} elem - jQuery object or string of the id of the pane to display. + * @function + */ + Tabs.prototype.selectTab = function(elem){ + var idStr; + if(typeof elem === 'object'){ + idStr = elem[0].id; + }else{ + idStr = elem; + } + + if(idStr.indexOf('#') < 0){ + idStr = '#' + idStr; + } + var $target = this.$tabTitles.find('[href="' + idStr + '"]').parent('.' + this.options.linkClass); + + this._handleTabChange($target); + }; + /** + * Sets the height of each panel to the height of the tallest panel. + * If enabled in options, gets called on media query change. + * If loading content via external source, can be called directly or with _reflow. + * @function + * @private + */ + Tabs.prototype._setHeight = function(){ + var max = 0; + this.$tabContent.find('.' + this.options.panelClass) + .css('height', '') + .each(function(){ + var panel = $(this), + isActive = panel.hasClass('is-active'); + + if(!isActive){ + panel.css({'visibility': 'hidden', 'display': 'block'}); + } + var temp = this.getBoundingClientRect().height; + + if(!isActive){ + panel.css({'visibility': '', 'display': ''}); + } + + max = temp > max ? temp : max; + }) + .css('height', max + 'px'); + }; + + /** + * Destroys an instance of an tabs. + * @fires Tabs#destroyed + */ + Tabs.prototype.destroy = function() { + this.$element.find('.' + this.options.linkClass) + .off('.zf.tabs').hide().end() + .find('.' + this.options.panelClass) + .hide(); + if(this.options.matchHeight){ + $(window).off('changed.zf.mediaquery'); + } + Foundation.unregisterPlugin(this); + }; + + Foundation.plugin(Tabs, 'Tabs'); + + function checkClass($elem){ + return $elem.hasClass('is-active'); + } +}(jQuery, window.Foundation); + +/** + * Toggler module. + * @module foundation.toggler + * @requires foundation.util.motion + */ + +!function(Foundation, $) { + 'use strict'; + + /** + * Creates a new instance of Toggler. + * @class + * @fires Toggler#init + * @param {Object} element - jQuery object to add the trigger to. + * @param {Object} options - Overrides to the default plugin settings. + */ + function Toggler(element, options) { + this.$element = element; + this.options = $.extend({}, Toggler.defaults, element.data(), options); + this.className = ''; + + this._init(); + this._events(); + + Foundation.registerPlugin(this); + } + + Toggler.defaults = { + /** + * Tells the plugin if the element should animated when toggled. + * @option + * @example false + */ + animate: false + }; + + /** + * Initializes the Toggler plugin by parsing the toggle class from data-toggler, or animation classes from data-animate. + * @function + * @private + */ + Toggler.prototype._init = function() { + var input; + // Parse animation classes if they were set + if (this.options.animate) { + input = this.options.animate.split(' '); + + this.animationIn = input[0]; + this.animationOut = input[1] || null; + } + // Otherwise, parse toggle class + else { + input = this.$element.data('toggler'); + // Allow for a . at the beginning of the string + this.className = input[0] === '.' ? input.slice(1) : input; + } + + // Add ARIA attributes to triggers + var id = this.$element[0].id; + $('[data-open="'+id+'"], [data-close="'+id+'"], [data-toggle="'+id+'"]') + .attr('aria-controls', id); + // If the target is hidden, add aria-hidden + this.$element.attr('aria-expanded', this.$element.is(':hidden') ? false : true); + }; + + /** + * Initializes events for the toggle trigger. + * @function + * @private + */ + Toggler.prototype._events = function() { + this.$element.off('toggle.zf.trigger').on('toggle.zf.trigger', this.toggle.bind(this)); + }; + + /** + * Toggles the target class on the target element. An event is fired from the original trigger depending on if the resultant state was "on" or "off". + * @function + * @fires Toggler#on + * @fires Toggler#off + */ + Toggler.prototype.toggle = function() { + this[ this.options.animate ? '_toggleAnimate' : '_toggleClass'](); + }; + + Toggler.prototype._toggleClass = function() { + this.$element.toggleClass(this.className); + + var isOn = this.$element.hasClass(this.className); + if (isOn) { + /** + * Fires if the target element has the class after a toggle. + * @event Toggler#on + */ + this.$element.trigger('on.zf.toggler'); + } + else { + /** + * Fires if the target element does not have the class after a toggle. + * @event Toggler#off + */ + this.$element.trigger('off.zf.toggler'); + } + + this._updateARIA(isOn); + }; + + Toggler.prototype._toggleAnimate = function() { + var _this = this; + + if (this.$element.is(':hidden')) { + Foundation.Motion.animateIn(this.$element, this.animationIn, function() { + this.trigger('on.zf.toggler'); + _this._updateARIA(true); + }); + } + else { + Foundation.Motion.animateOut(this.$element, this.animationOut, function() { + this.trigger('off.zf.toggler'); + _this._updateARIA(false); + }); + } + }; + + Toggler.prototype._updateARIA = function(isOn) { + this.$element.attr('aria-expanded', isOn ? true : false); + }; + + /** + * Destroys the instance of Toggler on the element. + * @function + */ + Toggler.prototype.destroy= function() { + this.$element.off('.zf.toggler'); + Foundation.unregisterPlugin(this); + }; + + Foundation.plugin(Toggler, 'Toggler'); + + // Exports for AMD/Browserify + if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') + module.exports = Toggler; + if (typeof define === 'function') + define(['foundation'], function() { + return Toggler; + }); + +}(Foundation, jQuery); + +/** + * Tooltip module. + * @module foundation.tooltip + * @requires foundation.util.box + * @requires foundation.util.triggers + */ +!function($, document, Foundation){ + 'use strict'; + + /** + * Creates a new instance of a Tooltip. + * @class + * @fires Tooltip#init + * @param {jQuery} element - jQuery object to attach a tooltip to. + * @param {Object} options - object to extend the default configuration. + */ + function Tooltip(element, options){ + this.$element = element; + this.options = $.extend({}, Tooltip.defaults, this.$element.data(), options); + + this.isActive = false; + this.isClick = false; + this._init(); + + Foundation.registerPlugin(this); + } + + Tooltip.defaults = { + disableForTouch: false, + /** + * Time, in ms, before a tooltip should open on hover. + * @option + * @example 200 + */ + hoverDelay: 200, + /** + * Time, in ms, a tooltip should take to fade into view. + * @option + * @example 150 + */ + fadeInDuration: 150, + /** + * Time, in ms, a tooltip should take to fade out of view. + * @option + * @example 150 + */ + fadeOutDuration: 150, + /** + * Disables hover events from opening the tooltip if set to true + * @option + * @example false + */ + disableHover: false, + /** + * Optional addtional classes to apply to the tooltip template on init. + * @option + * @example 'my-cool-tip-class' + */ + templateClasses: '', + /** + * Non-optional class added to tooltip templates. Foundation default is 'tooltip'. + * @option + * @example 'tooltip' + */ + tooltipClass: 'tooltip', + /** + * Class applied to the tooltip anchor element. + * @option + * @example 'has-tip' + */ + triggerClass: 'has-tip', + /** + * Minimum breakpoint size at which to open the tooltip. + * @option + * @example 'small' + */ + showOn: 'small', + /** + * Custom template to be used to generate markup for tooltip. + * @option + * @example '
    ' + */ + template: '', + /** + * Text displayed in the tooltip template on open. + * @option + * @example 'Some cool space fact here.' + */ + tipText: '', + touchCloseText: 'Tap to close.', + /** + * Allows the tooltip to remain open if triggered with a click or touch event. + * @option + * @example true + */ + clickOpen: true, + /** + * Additional positioning classes, set by the JS + * @option + * @example 'top' + */ + positionClass: '', + /** + * Distance, in pixels, the template should push away from the anchor on the Y axis. + * @option + * @example 10 + */ + vOffset: 10, + /** + * Distance, in pixels, the template should push away from the anchor on the X axis, if aligned to a side. + * @option + * @example 12 + */ + hOffset: 12 + }; + + /** + * Initializes the tooltip by setting the creating the tip element, adding it's text, setting private variables and setting attributes on the anchor. + * @private + */ + Tooltip.prototype._init = function(){ + var elemId = this.$element.attr('aria-describedby') || Foundation.GetYoDigits(6, 'tooltip'); + + this.options.positionClass = this._getPositionClass(this.$element); + this.options.tipText = this.options.tipText || this.$element.attr('title'); + this.template = this.options.template ? $(this.options.template) : this._buildTemplate(elemId); + + this.template.appendTo(document.body) + .text(this.options.tipText) + .hide(); + + this.$element.attr({ + 'title': '', + 'aria-describedby': elemId, + 'data-yeti-box': elemId, + 'data-toggle': elemId, + 'data-resize': elemId + }).addClass(this.triggerClass); + + //helper variables to track movement on collisions + this.usedPositions = []; + this.counter = 4; + this.classChanged = false; + + this._events(); + }; + + /** + * Grabs the current positioning class, if present, and returns the value or an empty string. + * @private + */ + Tooltip.prototype._getPositionClass = function(element){ + if(!element){ return ''; } + // var position = element.attr('class').match(/top|left|right/g); + var position = element[0].className.match(/(top|left|right)/g); + position = position ? position[0] : ''; + return position; + }; + /** + * builds the tooltip element, adds attributes, and returns the template. + * @private + */ + Tooltip.prototype._buildTemplate = function(id){ + var templateClasses = (this.options.tooltipClass + ' ' + this.options.positionClass).trim(); + var $template = $('
    ').addClass(templateClasses).attr({ + 'role': 'tooltip', + 'aria-hidden': true, + 'data-is-active': false, + 'data-is-focus': false, + 'id': id + }); + return $template; + }; + + /** + * Function that gets called if a collision event is detected. + * @param {String} position - positioning class to try + * @private + */ + Tooltip.prototype._reposition = function(position){ + this.usedPositions.push(position ? position : 'bottom'); + + //default, try switching to opposite side + if(!position && (this.usedPositions.indexOf('top') < 0)){ + this.template.addClass('top'); + }else if(position === 'top' && (this.usedPositions.indexOf('bottom') < 0)){ + this.template.removeClass(position); + }else if(position === 'left' && (this.usedPositions.indexOf('right') < 0)){ + this.template.removeClass(position) + .addClass('right'); + }else if(position === 'right' && (this.usedPositions.indexOf('left') < 0)){ + this.template.removeClass(position) + .addClass('left'); + } + + //if default change didn't work, try bottom or left first + else if(!position && (this.usedPositions.indexOf('top') > -1) && (this.usedPositions.indexOf('left') < 0)){ + this.template.addClass('left'); + }else if(position === 'top' && (this.usedPositions.indexOf('bottom') > -1) && (this.usedPositions.indexOf('left') < 0)){ + this.template.removeClass(position) + .addClass('left'); + }else if(position === 'left' && (this.usedPositions.indexOf('right') > -1) && (this.usedPositions.indexOf('bottom') < 0)){ + this.template.removeClass(position); + }else if(position === 'right' && (this.usedPositions.indexOf('left') > -1) && (this.usedPositions.indexOf('bottom') < 0)){ + this.template.removeClass(position); + } + //if nothing cleared, set to bottom + else{ + this.template.removeClass(position); + } + this.classChanged = true; + this.counter--; + + }; + + /** + * sets the position class of an element and recursively calls itself until there are no more possible positions to attempt, or the tooltip element is no longer colliding. + * if the tooltip is larger than the screen width, default to full width - any user selected margin + * @private + */ + Tooltip.prototype._setPosition = function(){ + var position = this._getPositionClass(this.template), + $tipDims = Foundation.Box.GetDimensions(this.template), + $anchorDims = Foundation.Box.GetDimensions(this.$element), + direction = (position === 'left' ? 'left' : ((position === 'right') ? 'left' : 'top')), + param = (direction === 'top') ? 'height' : 'width', + offset = (param === 'height') ? this.options.vOffset : this.options.hOffset, + _this = this; + + if(($tipDims.width >= $tipDims.windowDims.width) || (!this.counter && !Foundation.Box.ImNotTouchingYou(this.template))){ + this.template.offset(Foundation.Box.GetOffsets(this.template, this.$element, 'center bottom', this.options.vOffset, this.options.hOffset, true)).css({ + // this.$element.offset(Foundation.GetOffsets(this.template, this.$element, 'center bottom', this.options.vOffset, this.options.hOffset, true)).css({ + 'width': $anchorDims.windowDims.width - (this.options.hOffset * 2), + 'height': 'auto' + }); + return false; + } + + this.template.offset(Foundation.Box.GetOffsets(this.template, this.$element,'center ' + (position || 'bottom'), this.options.vOffset, this.options.hOffset)); + + while(!Foundation.Box.ImNotTouchingYou(this.template) && this.counter){ + this._reposition(position); + this._setPosition(); + } + }; + + /** + * reveals the tooltip, and fires an event to close any other open tooltips on the page + * @fires Closeme#tooltip + * @fires Tooltip#show + * @function + */ + Tooltip.prototype.show = function(){ + if(this.options.showOn !== 'all' && !Foundation.MediaQuery.atLeast(this.options.showOn)){ + // console.error('The screen is too small to display this tooltip'); + return false; + } + + var _this = this; + this.template.css('visibility', 'hidden').show(); + this._setPosition(); + + /** + * Fires to close all other open tooltips on the page + * @event Closeme#tooltip + */ + this.$element.trigger('closeme.zf.tooltip', this.template.attr('id')); + + + this.template.attr({ + 'data-is-active': true, + 'aria-hidden': false + }); + _this.isActive = true; + // console.log(this.template); + this.template.stop().hide().css('visibility', '').fadeIn(this.options.fadeInDuration, function(){ + //maybe do stuff? + }); + /** + * Fires when the tooltip is shown + * @event Tooltip#show + */ + this.$element.trigger('show.zf.tooltip'); + }; + + /** + * Hides the current tooltip, and resets the positioning class if it was changed due to collision + * @fires Tooltip#hide + * @function + */ + Tooltip.prototype.hide = function(){ + // console.log('hiding', this.$element.data('yeti-box')); + var _this = this; + this.template.stop().attr({ + 'aria-hidden': true, + 'data-is-active': false + }).fadeOut(this.options.fadeOutDuration, function(){ + _this.isActive = false; + _this.isClick = false; + if(_this.classChanged){ + _this.template + .removeClass(_this._getPositionClass(_this.template)) + .addClass(_this.options.positionClass); + + _this.usedPositions = []; + _this.counter = 4; + _this.classChanged = false; + } + }); + /** + * fires when the tooltip is hidden + * @event Tooltip#hide + */ + this.$element.trigger('hide.zf.tooltip'); + }; + + /** + * adds event listeners for the tooltip and its anchor + * TODO combine some of the listeners like focus and mouseenter, etc. + * @private + */ + Tooltip.prototype._events = function(){ + var _this = this; + var $template = this.template; + var isFocus = false; + + if(!this.options.disableHover){ + + this.$element + .on('mouseenter.zf.tooltip', function(e){ + if(!_this.isActive){ + _this.timeout = setTimeout(function(){ + _this.show(); + }, _this.options.hoverDelay); + } + }) + .on('mouseleave.zf.tooltip', function(e){ + clearTimeout(_this.timeout); + if(!isFocus || (!_this.isClick && _this.options.clickOpen)){ + _this.hide(); + } + }); + } + if(this.options.clickOpen){ + this.$element.on('mousedown.zf.tooltip', function(e){ + e.stopImmediatePropagation(); + if(_this.isClick){ + _this.hide(); + // _this.isClick = false; + }else{ + _this.isClick = true; + if((_this.options.disableHover || !_this.$element.attr('tabindex')) && !_this.isActive){ + _this.show(); + } + } + }); + } + + if(!this.options.disableForTouch){ + this.$element + .on('tap.zf.tooltip touchend.zf.tooltip', function(e){ + _this.isActive ? _this.hide() : _this.show(); + }); + } + + this.$element.on({ + // 'toggle.zf.trigger': this.toggle.bind(this), + // 'close.zf.trigger': this.hide.bind(this) + 'close.zf.trigger': this.hide.bind(this) + }); + + this.$element + .on('focus.zf.tooltip', function(e){ + isFocus = true; + console.log(_this.isClick); + if(_this.isClick){ + return false; + }else{ + // $(window) + _this.show(); + } + }) + + .on('focusout.zf.tooltip', function(e){ + isFocus = false; + _this.isClick = false; + _this.hide(); + }) + + .on('resizeme.zf.trigger', function(){ + if(_this.isActive){ + _this._setPosition(); + } + }); + }; + /** + * adds a toggle method, in addition to the static show() & hide() functions + * @function + */ + Tooltip.prototype.toggle = function(){ + if(this.isActive){ + this.hide(); + }else{ + this.show(); + } + }; + /** + * Destroys an instance of tooltip, removes template element from the view. + * @function + */ + Tooltip.prototype.destroy = function(){ + this.$element.attr('title', this.template.text()) + .off('.zf.trigger .zf.tootip') + // .removeClass('has-tip') + .removeAttr('aria-describedby') + .removeAttr('data-yeti-box') + .removeAttr('data-toggle') + .removeAttr('data-resize'); + + this.template.remove(); + + Foundation.unregisterPlugin(this); + }; + /** + * TODO utilize resize event trigger + */ + + Foundation.plugin(Tooltip, 'Tooltip'); +}(jQuery, window.document, window.Foundation); diff --git a/js/foundation.min.js b/js/foundation.min.js new file mode 100644 index 0000000..f2b7230 --- /dev/null +++ b/js/foundation.min.js @@ -0,0 +1,3 @@ +!function(t){"use strict";function e(t){if(void 0===Function.prototype.name){var e=/function\s([^(]{1,})\(/,i=e.exec(t.toString());return i&&i.length>1?i[1].trim():""}return void 0===t.prototype?t.constructor.name:t.prototype.constructor.name}function i(t){return/true/.test(t)?!0:/false/.test(t)?!1:isNaN(1*t)?t:parseFloat(t)}function n(t){return t.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}var s="6.0.5",o={version:s,_plugins:{},_uuids:[],_activePlugins:{},rtl:function(){return"rtl"===t("html").attr("dir")},plugin:function(t,i){var s=i||e(t),o=n(s);this._plugins[o]=this[s]=t},registerPlugin:function(t){var i=e(t.constructor).toLowerCase();t.uuid=this.GetYoDigits(6,i),t.$element.attr("data-"+i)||t.$element.attr("data-"+i,t.uuid),t.$element.trigger("init.zf."+i),this._activePlugins[t.uuid]=t},unregisterPlugin:function(t){var i=e(t.constructor).toLowerCase();delete this._activePlugins[t.uuid],t.$element.removeAttr("data-"+i).trigger("destroyed.zf."+i)},_reflow:function(t){var e=Object.keys(this._activePlugins),i=this;if(t){if("string"==typeof t){var n=t.split("-")[1];n?this._activePlugins[t]._init():(n=new RegExp(t,"i"),e.filter(function(t){return n.test(t)}).forEach(function(t){i._activePlugins[t]._init()}))}}else e.forEach(function(t){i._activePlugins[t]._init()})},GetYoDigits:function(t,e){return t=t||6,Math.round(Math.pow(36,t+1)-Math.random()*Math.pow(36,t)).toString(36).slice(1)+(e?"-"+e:"")},reflow:function(e,n){"undefined"==typeof n?n=Object.keys(this._plugins):"string"==typeof n&&(n=[n]);var s=this;t.each(n,function(n,o){var a=s._plugins[o],r=t(e).find("[data-"+o+"]").addBack("[data-"+o+"]");r.each(function(){var e=t(this),n={};if(e.data("zf-plugin"))return void console.warn("Tried to initialize "+o+" on an element that already has a Foundation plugin.");if(e.attr("data-options")){e.attr("data-options").split(";").forEach(function(t,e){var s=t.split(":").map(function(t){return t.trim()});s[0]&&(n[s[0]]=i(s[1]))})}try{e.data("zf-plugin",new a(t(this),n))}catch(s){console.error(s)}finally{return}})})},getFnName:e,transitionend:function(t){var e,i={transition:"transitionend",WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"otransitionend"},n=document.createElement("div");for(var s in i)"undefined"!=typeof n.style[s]&&(e=i[s]);return e?e:(e=setTimeout(function(){t.triggerHandler("transitionend",[t])},1),"transitionend")}};o.util={throttle:function(t,e){var i=null;return function(){var n=this,s=arguments;null===i&&(i=setTimeout(function(){t.apply(n,s),i=null},e))}}};var a=function(i){var n=typeof i,s=t("meta.foundation-mq"),a=t(".no-js");if(s.length||t('').appendTo(document.head),a.length&&a.removeClass("no-js"),"undefined"===n)o.MediaQuery._init(),o.reflow(this);else{if("string"!==n)throw new TypeError("We're sorry, '"+n+"' is not a valid parameter. You must use a string representing the method you wish to invoke.");var r=Array.prototype.slice.call(arguments,1),l=this.data("zfPlugin");if(void 0===l||void 0===l[i])throw new ReferenceError("We're sorry, '"+i+"' is not an available method for "+(l?e(l):"this element")+".");1===this.length?l[i].apply(l,r):this.each(function(e,n){l[i].apply(t(n).data("zfPlugin"),r)})}return this};window.Foundation=o,t.fn.foundation=a,function(){Date.now&&window.Date.now||(window.Date.now=Date.now=function(){return(new Date).getTime()});for(var t=["webkit","moz"],e=0;e=h.offset.top,r=d.offset.left>=h.offset.left,l=d.offset.left+d.width<=h.width}else a=d.offset.top+d.height<=d.windowDims.height+d.windowDims.offset.top,o=d.offset.top>=d.windowDims.offset.top,r=d.offset.left>=d.windowDims.offset.left,l=d.offset.left+d.width<=d.windowDims.width;var u=[a,o,r,l];return i?r===l==!0:s?o===a==!0:-1===u.indexOf(!1)},n=function(t,i){if(t=t.length?t[0]:t,t===e||t===document)throw new Error("I'm sorry, Dave. I'm afraid I can't do that.");var n=t.getBoundingClientRect(),s=t.parentNode.getBoundingClientRect(),o=document.body.getBoundingClientRect(),a=e.pageYOffset,r=e.pageXOffset;return{width:n.width,height:n.height,offset:{top:n.top+a,left:n.left+r},parentDims:{width:s.width,height:s.height,offset:{top:s.top+a,left:s.left+r}},windowDims:{width:o.width,height:o.height,offset:{top:a,left:r}}}},s=function(t,e,i,s,o,a){var r=n(t),l=e?n(e):null;switch(i){case"top":return{left:l.offset.left,top:l.offset.top-(r.height+s)};case"left":return{left:l.offset.left-(r.width+o),top:l.offset.top};case"right":return{left:l.offset.left+l.width+o,top:l.offset.top};case"center top":return{left:l.offset.left+l.width/2-r.width/2,top:l.offset.top-(r.height+s)};case"center bottom":return{left:a?o:l.offset.left+l.width/2-r.width/2,top:l.offset.top+l.height+s};case"center left":return{left:l.offset.left-(r.width+o),top:l.offset.top+l.height/2-r.height/2};case"center right":return{left:l.offset.left+l.width+o+1,top:l.offset.top+l.height/2-r.height/2};case"center":return{left:r.windowDims.offset.left+r.windowDims.width/2-r.width/2,top:r.windowDims.offset.top+r.windowDims.height/2-r.height/2};case"reveal":return{left:(r.windowDims.width-r.width)/2,top:r.windowDims.offset.top+s};case"reveal full":return{left:r.windowDims.offset.left,top:r.windowDims.offset.top};default:return{left:l.offset.left,top:l.offset.top+l.height+s}}};t.Box={ImNotTouchingYou:i,GetDimensions:n,GetOffsets:s}}(window.Foundation,window),!function(t,e){"use strict";e.Keyboard={};var i={9:"TAB",13:"ENTER",27:"ESCAPE",32:"SPACE",37:"ARROW_LEFT",38:"ARROW_UP",39:"ARROW_RIGHT",40:"ARROW_DOWN"},n=function(t){var e={};for(var i in t)e[t[i]]=t[i];return e}(i);e.Keyboard.keys=n;var s=function(t){var e=i[t.which||t.keyCode]||String.fromCharCode(t.which).toUpperCase();return t.shiftKey&&(e="SHIFT_"+e),t.ctrlKey&&(e="CTRL_"+e),t.altKey&&(e="ALT_"+e),e};e.Keyboard.parseKey=s;var o={},a=function(i,n,a){var r,l,d,h=o[e.getFnName(n)],u=s(i);return h?(r="undefined"==typeof h.ltr?h:e.rtl()?t.extend({},h.ltr,h.rtl):t.extend({},h.rtl,h.ltr),l=r[u],d=a[l],void(d&&"function"==typeof d?(d.apply(n),(a.handled||"function"==typeof a.handled)&&a.handled.apply(n)):(a.unhandled||"function"==typeof a.unhandled)&&a.unhandled.apply(n))):console.warn("Component not defined!")};e.Keyboard.handleKey=a;var r=function(e){return e.find("a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]").filter(function(){return!t(this).is(":visible")||t(this).attr("tabindex")<0?!1:!0})};e.Keyboard.findFocusable=r;var l=function(t,e){o[t]=e};e.Keyboard.register=l}(jQuery,window.Foundation),!function(t,e){function i(t){var e={};return"string"!=typeof t?e:(t=t.trim().slice(1,-1))?e=t.split("&").reduce(function(t,e){var i=e.replace(/\+/g," ").split("="),n=i[0],s=i[1];return n=decodeURIComponent(n),s=void 0===s?null:decodeURIComponent(s),t.hasOwnProperty(n)?Array.isArray(t[n])?t[n].push(s):t[n]=[t[n],s]:t[n]=s,t},{}):e}var n={queries:[],current:"",atLeast:function(t){var e=this.get(t);return e?window.matchMedia(e).matches:!1},get:function(t){for(var e in this.queries){var i=this.queries[e];if(t===i.name)return i.value}return null},_init:function(){var e,n=this,s=t(".foundation-mq").css("font-family");e=i(s);for(var o in e)n.queries.push({name:o,value:"only screen and (min-width: "+e[o]+")"});this.current=this._getCurrentSize(),this._watcher()},_getCurrentSize:function(){var t;for(var e in this.queries){var i=this.queries[e];window.matchMedia(i.value).matches&&(t=i)}return"object"==typeof t?t.name:t},_watcher:function(){var e=this;t(window).on("resize.zf.mediaquery",function(){var i=e._getCurrentSize();i!==e.current&&(t(window).trigger("changed.zf.mediaquery",[i,e.current]),e.current=i)})}};e.MediaQuery=n,window.matchMedia||(window.matchMedia=function(){"use strict";var t=window.styleMedia||window.media;if(!t){var e=document.createElement("style"),i=document.getElementsByTagName("script")[0],n=null;e.type="text/css",e.id="matchmediajs-test",i.parentNode.insertBefore(e,i),n="getComputedStyle"in window&&window.getComputedStyle(e,null)||e.currentStyle,t={matchMedium:function(t){var i="@media "+t+"{ #matchmediajs-test { width: 1px; } }";return e.styleSheet?e.styleSheet.cssText=i:e.textContent=i,"1px"===n.width}}}return function(e){return{matches:t.matchMedium(e||"all"),media:e||"all"}}}())}(jQuery,Foundation),!function(t,e){function i(i,o,a,r){function l(){i||o.hide(),d(),r&&r.apply(o)}function d(){o[0].style.transitionDuration=0,o.removeClass(h+" "+u+" "+a)}if(o=t(o).eq(0),o.length){var h=i?n[0]:n[1],u=i?s[0]:s[1];d(),o.addClass(a).css("transition","none"),requestAnimationFrame(function(){o.addClass(h),i&&o.show()}),requestAnimationFrame(function(){o[0].offsetWidth,o.css("transition",""),o.addClass(u)}),o.one(e.transitionend(o),l)}}var n=["mui-enter","mui-leave"],s=["mui-enter-active","mui-leave-active"],o={animateIn:function(t,e,n){i(!0,t,e,n)},animateOut:function(t,e,n){i(!1,t,e,n)}},a=function(t,e,i){function n(r){a||(a=window.performance.now()),o=r-a,i.apply(e),t>o?s=window.requestAnimationFrame(n,e):(window.cancelAnimationFrame(s),e.trigger("finished.zf.animate",[e]).triggerHandler("finished.zf.animate",[e]))}var s,o,a=null;s=window.requestAnimationFrame(n)};e.Move=a,e.Motion=o}(jQuery,Foundation),!function(t,e){"use strict";e.Nest={Feather:function(e,i){e.attr("role","menubar"),i=i||"zf";var n=e.find("li").attr({role:"menuitem"}),s="is-"+i+"-submenu",o=s+"-item",a="is-"+i+"-submenu-parent";e.find("a:first").attr("tabindex",0),n.each(function(){var e=t(this),i=e.children("ul");i.length&&(e.addClass("has-submenu "+a).attr({"aria-haspopup":!0,"aria-selected":!1,"aria-expanded":!1,"aria-label":e.children("a:first").text()}),i.addClass("submenu "+s).attr({"data-submenu":"","aria-hidden":!0,role:"menu"})),e.parent("[data-submenu]").length&&e.addClass("is-submenu-item "+o)})},Burn:function(t,e){var i=(t.find("li").removeAttr("tabindex"),"is-"+e+"-submenu"),n=i+"-item",s="is-"+e+"-submenu-parent";t.find("*").removeClass(i+" "+n+" "+s+" has-submenu is-submenu-item submenu is-active").removeAttr("data-submenu").css("display","")}}}(jQuery,window.Foundation),!function(t,e){"use strict";var i=function(t,e,i){var n,s,o=this,a=e.duration,r=Object.keys(t.data())[0]||"timer",l=-1;this.restart=function(){l=-1,clearTimeout(s),this.start()},this.start=function(){clearTimeout(s),l=0>=l?a:l,t.data("paused",!1),n=Date.now(),s=setTimeout(function(){e.infinite&&o.restart(),i()},l),t.trigger("timerstart.zf."+r)},this.pause=function(){clearTimeout(s),t.data("paused",!0);var e=Date.now();l-=e-n,t.trigger("timerpaused.zf."+r)}},n=function(e,i){var n=e.length;0===n&&i();var s=function(){n--,0===n&&i()};e.each(function(){this.complete?s():"undefined"!=typeof this.naturalWidth&&this.naturalWidth>0?s():t(this).one("load",function(){s()})})};e.Timer=i,e.onImagesLoaded=n}(jQuery,window.Foundation),function(t){function e(){this.removeEventListener("touchmove",i),this.removeEventListener("touchend",e),d=!1}function i(i){if(t.spotSwipe.preventDefault&&i.preventDefault(),d){var n,s=i.touches[0].pageX,h=i.touches[0].pageY,u=o-s,c=a-h;l=(new Date).getTime()-r,Math.abs(u)>=t.spotSwipe.moveThreshold&&l<=t.spotSwipe.timeThreshold?n=u>0?"left":"right":Math.abs(c)>=t.spotSwipe.moveThreshold&&l<=t.spotSwipe.timeThreshold&&(n=c>0?"down":"up"),n&&(e.call(this),t(this).trigger("swipe",n).trigger("swipe"+n))}}function n(t){1==t.touches.length&&(o=t.touches[0].pageX,a=t.touches[0].pageY,d=!0,r=(new Date).getTime(),this.addEventListener("touchmove",i,!1),this.addEventListener("touchend",e,!1))}function s(){this.addEventListener&&this.addEventListener("touchstart",n,!1)}t.spotSwipe={version:"1.0.0",enabled:"ontouchstart"in document.documentElement,preventDefault:!0,moveThreshold:75,timeThreshold:200};var o,a,r,l,d=!1;t.event.special.swipe={setup:s},t.each(["left","up","down","right"],function(){t.event.special["swipe"+this]={setup:function(){t(this).on("swipe",t.noop)}}})}(jQuery),!function(t){t.fn.addTouch=function(){this.each(function(i,n){t(n).bind("touchstart touchmove touchend touchcancel",function(){e(event)})});var e=function(t){var e=t.changedTouches,i=e[0],n={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup"},s=n[t.type],o=document.createEvent("MouseEvent");o.initMouseEvent(s,!0,!0,window,1,i.screenX,i.screenY,i.clientX,i.clientY,!1,!1,!1,!1,0,null),i.target.dispatchEvent(o)}}}(jQuery),!function(t,e){"use strict";e(document).on("click.zf.trigger","[data-open]",function(){var t=e(this).data("open");e("#"+t).triggerHandler("open.zf.trigger",[e(this)])}),e(document).on("click.zf.trigger","[data-close]",function(){var t=e(this).data("close");t?e("#"+t).triggerHandler("close.zf.trigger",[e(this)]):e(this).trigger("close.zf.trigger")}),e(document).on("click.zf.trigger","[data-toggle]",function(){var t=e(this).data("toggle");e("#"+t).triggerHandler("toggle.zf.trigger",[e(this)])}),e(document).on("close.zf.trigger","[data-closable]",function(){var i=e(this).data("closable")||"fade-out";t.Motion?t.Motion.animateOut(e(this),i,function(){e(this).trigger("closed.zf")}):e(this).fadeOut().trigger("closed.zf")});var i=function(){for(var t=["WebKit","Moz","O","Ms",""],e=0;eo;)i.validateInput(e(n[o]),t),o++;t.find(".form-error.is-visible").length||t.find(".is-invalid-label").length?t.find("[data-abide-error]").css("display","block"):t.find("[data-abide-error]").css("display","none")},i.prototype.validateText=function(t){var i=this.options.patterns,n=e(t).val(),s=e(t).attr("pattern");return 0===n.length?!0:n.match(i[s])?!0:!1},i.prototype.validateRadio=function(t){var i=this,n=(e(':radio[name="'+t+'"]').siblings("label"),0);return e(':radio[name="'+t+'"]').each(function(){i.requiredCheck(e(this))||n++,e(this).is(":checked")&&(n=0)}),n>0?!1:!0},i.prototype.matchValidation=function(t,e){},i.prototype.resetForm=function(t){var i=this,n="data-invalid";e("["+i.invalidAttr+"]",t).removeAttr(n),e("."+i.options.labelErrorClass,t).not("small").removeClass(i.options.labelErrorClass),e("."+i.options.inputErrorClass,t).not("small").removeClass(i.options.inputErrorClass),e(".form-error.is-visible").removeClass("is-visible"),t.find("[data-abide-error]").css("display","none"),e(":input",t).not(":button, :submit, :reset, :hidden, [data-abide-ignore]").val("").removeAttr(n)},i.prototype.destroy=function(){},t.plugin(i,"Abide"),"undefined"!=typeof module&&"undefined"!=typeof module.exports&&(module.exports=i),"function"==typeof define&&define(["foundation"],function(){return i})}(Foundation,jQuery),!function(t,e){"use strict";function i(n,s){this.$element=n,this.options=t.extend({},i.defaults,this.$element.data(),s),this._init(),e.registerPlugin(this),e.Keyboard.register("Accordion",{ENTER:"toggle",SPACE:"toggle",ARROW_DOWN:"next",ARROW_UP:"previous"})}i.defaults={slideSpeed:250,multiExpand:!1,allowAllClosed:!1},i.prototype._init=function(){this.$element.attr("role","tablist"),this.$tabs=this.$element.children("li"),this.$tabs.each(function(i,n){var s=t(n),o=s.find("[data-tab-content]"),a=o[0].id||e.GetYoDigits(6,"accordion"),r=n.id||a+"-label";s.find("a:first").attr({"aria-controls":a,role:"tab",id:r,"aria-expanded":!1,"aria-selected":!1}),o.attr({role:"tabpanel","aria-labelledby":r,"aria-hidden":!0,id:a})});var i=this.$element.find(".is-active").children("[data-tab-content]");i.length&&this.down(i,!0),this._events()},i.prototype._events=function(){var i=this;this.$tabs.each(function(){var n=t(this),s=n.children("[data-tab-content]");s.length&&n.children("a").off("click.zf.accordion keydown.zf.accordion").on("click.zf.accordion",function(t){t.preventDefault(),n.hasClass("is-active")?(i.options.allowAllClosed||n.siblings().hasClass("is-active"))&&i.up(s):i.down(s)}).on("keydown.zf.accordion",function(t){e.Keyboard.handleKey(t,i,{toggle:function(){i.toggle(s)},next:function(){n.next().find("a").focus().trigger("click.zf.accordion")},previous:function(){n.prev().find("a").focus().trigger("click.zf.accordion")},handled:function(){t.preventDefault(),t.stopPropagation()}})})})},i.prototype.toggle=function(t){if(t.parent().hasClass("is-active")){if(!this.options.allowAllClosed&&!t.parent().siblings().hasClass("is-active"))return;this.up(t)}else this.down(t)},i.prototype.down=function(i,n){var s=this;if(!this.options.multiExpand&&!n){var o=this.$element.find(".is-active").children("[data-tab-content]");o.length&&this.up(o)}i.attr("aria-hidden",!1).parent("[data-tab-content]").addBack().parent().addClass("is-active"),e.Move(s.options.slideSpeed,i,function(){i.slideDown(s.options.slideSpeed)}),n||e._reflow(this.$element.attr("data-accordion")),t("#"+i.attr("aria-labelledby")).attr({"aria-expanded":!0,"aria-selected":!0}),this.$element.trigger("down.zf.accordion",[i])},i.prototype.up=function(i){var n=i.parent().siblings(),s=this,o=this.options.multiExpand?n.hasClass("is-active"):i.parent().hasClass("is-active");(this.options.allowAllClosed||o)&&(e.Move(this.options.slideSpeed,i,function(){i.slideUp(s.options.slideSpeed)}),i.attr("aria-hidden",!0).parent().removeClass("is-active"),t("#"+i.attr("aria-labelledby")).attr({"aria-expanded":!1,"aria-selected":!1}),this.$element.trigger("up.zf.accordion",[i]))},i.prototype.destroy=function(){this.$element.find("[data-tab-content]").slideUp(0).css("display",""),this.$element.find("a").off(".zf.accordion"),e.unregisterPlugin(this)},e.plugin(i,"Accordion")}(jQuery,window.Foundation),!function(t){"use strict";function e(i,n){this.$element=i,this.options=t.extend({},e.defaults,this.$element.data(),n),Foundation.Nest.Feather(this.$element,"accordion"),this._init(),Foundation.registerPlugin(this),Foundation.Keyboard.register("AccordionMenu",{ENTER:"toggle",SPACE:"toggle",ARROW_RIGHT:"open",ARROW_UP:"up",ARROW_DOWN:"down",ARROW_LEFT:"close",ESCAPE:"closeAll",TAB:"down",SHIFT_TAB:"up"})}e.defaults={slideSpeed:250,multiOpen:!0},e.prototype._init=function(){this.$element.find("[data-submenu]").not(".is-active").slideUp(0),this.$element.attr({role:"tablist","aria-multiselectable":this.options.multiOpen}),this.$menuLinks=this.$element.find(".has-submenu"),this.$menuLinks.each(function(){var e=this.id||Foundation.GetYoDigits(6,"acc-menu-link"),i=t(this),n=i.children("[data-submenu]"),s=n[0].id||Foundation.GetYoDigits(6,"acc-menu"),o=n.hasClass("is-active");i.attr({"aria-controls":s,"aria-expanded":o,"aria-selected":!1,role:"tab",id:e}),n.attr({"aria-labelledby":e,"aria-hidden":!o,role:"tabpanel",id:s})});var e=this.$element.find(".is-active");if(e.length){var i=this;e.each(function(){i.down(t(this))})}this._events()},e.prototype._events=function(){var e=this;this.$element.find("li").each(function(){var i=t(this).children("[data-submenu]");i.length&&t(this).children("a").off("click.zf.accordionmenu").on("click.zf.accordionmenu",function(t){t.preventDefault(),e.toggle(i)})}).on("keydown.zf.accordionmenu",function(i){var n,s,o=t(this),a=o.parent("ul").children("li"),r=o.children("[data-submenu]");a.each(function(e){return t(this).is(o)?(n=a.eq(Math.max(0,e-1)),s=a.eq(Math.min(e+1,a.length-1)),t(this).children("[data-submenu]:visible").length&&(s=o.find("li:first-child")),t(this).is(":first-child")?n=o.parents("li").first():n.children("[data-submenu]:visible").length&&(n=n.find("li:last-child")),void(t(this).is(":last-child")&&(s=o.parents("li").first().next("li")))):void 0}),Foundation.Keyboard.handleKey(i,e,{open:function(){r.is(":hidden")&&(e.down(r),r.find("li").first().focus())},close:function(){r.length&&!r.is(":hidden")?e.up(r):o.parent("[data-submenu]").length&&(e.up(o.parent("[data-submenu]")),o.parents("li").first().focus())},up:function(){n.focus()},down:function(){s.focus()},toggle:function(){o.children("[data-submenu]").length&&e.toggle(o.children("[data-submenu]"))},closeAll:function(){e.hideAll()},handled:function(){i.preventDefault(),i.stopImmediatePropagation()}})})},e.prototype.hideAll=function(){this.$element.find("[data-submenu]").slideUp(this.options.slideSpeed)},e.prototype.toggle=function(t){t.is(":animated")||(t.is(":hidden")?this.down(t):this.up(t))},e.prototype.down=function(t){var e=this;this.options.multiOpen||this.up(this.$element.find(".is-active").not(t.parentsUntil(this.$element).add(t))),t.addClass("is-active").attr({"aria-hidden":!1}).parent(".has-submenu").attr({"aria-expanded":!0,"aria-selected":!0}),Foundation.Move(this.options.slideSpeed,t,function(){t.slideDown(e.options.slideSpeed)}),this.$element.trigger("down.zf.accordionMenu",[t])},e.prototype.up=function(t){var e=this;Foundation.Move(this.options.slideSpeed,t,function(){t.slideUp(e.options.slideSpeed)}),t.attr("aria-hidden",!0).find("[data-submenu]").slideUp(0).attr("aria-hidden",!0).end().parent(".has-submenu").attr({"aria-expanded":!1,"aria-selected":!1}),this.$element.trigger("up.zf.accordionMenu",[t])},e.prototype.destroy=function(){this.$element.find("[data-submenu]").slideDown(0).css("display",""),this.$element.find("a").off("click.zf.accordionMenu"),Foundation.Nest.Burn(this.$element,"accordion"),Foundation.unregisterPlugin(this)},Foundation.plugin(e,"AccordionMenu")}(jQuery,window.Foundation),!function(t,e){"use strict";function i(n,s){this.$element=n,this.options=t.extend({},i.defaults,this.$element.data(),s),e.Nest.Feather(this.$element,"drilldown"),this._init(),e.registerPlugin(this),e.Keyboard.register("Drilldown",{ENTER:"open",SPACE:"open",ARROW_RIGHT:"next",ARROW_UP:"up",ARROW_DOWN:"down",ARROW_LEFT:"previous",ESCAPE:"close",TAB:"down",SHIFT_TAB:"up"})}i.defaults={backButton:'
  • Back
  • ',wrapper:"
    ",closeOnClick:!1},i.prototype._init=function(){this.$submenuAnchors=this.$element.find("li.has-submenu"),this.$submenus=this.$submenuAnchors.children("[data-submenu]"),this.$menuItems=this.$element.find("li:visible").not(".js-drilldown-back").attr("role","menuitem"),this._prepareMenu(),this._keyboardEvents()},i.prototype._prepareMenu=function(){var e=this;this.$submenuAnchors.each(function(){var i=t(this),n=i.find("a:first");n.data("savedHref",n.attr("href")).removeAttr("href"),i.children("[data-submenu]").attr({"aria-hidden":!0,tabindex:0,role:"menu"}),e._events(i)}),this.$submenus.each(function(){var i=t(this),n=i.find(".js-drilldown-back");n.length||i.prepend(e.options.backButton),e._back(i)}),this.$element.parent().hasClass("is-drilldown")||(this.$wrapper=t(this.options.wrapper).addClass("is-drilldown").css(this._getMaxDims()),this.$element.wrap(this.$wrapper))},i.prototype._events=function(e){var i=this;e.off("click.zf.drilldown").on("click.zf.drilldown",function(n){if(t(n.target).parentsUntil("ul","li").hasClass("is-drilldown-submenu-parent")&&(n.stopImmediatePropagation(),n.preventDefault()),i._show(e),i.options.closeOnClick){var s=t("body").not(i.$wrapper);s.off(".zf.drilldown").on("click.zf.drilldown",function(t){t.preventDefault(),i._hideAll(),s.off(".zf.drilldown")})}})},i.prototype._keyboardEvents=function(){var i=this;this.$menuItems.add(this.$element.find(".js-drilldown-back")).on("keydown.zf.drilldown",function(n){var s,o,a=t(this),r=a.parent("ul").children("li");r.each(function(e){return t(this).is(a)?(s=r.eq(Math.max(0,e-1)),void(o=r.eq(Math.min(e+1,r.length-1)))):void 0}),e.Keyboard.handleKey(n,i,{next:function(){a.is(i.$submenuAnchors)&&(i._show(a),a.on(e.transitionend(a),function(){a.find("ul li").filter(i.$menuItems).first().focus()}))},previous:function(){i._hide(a.parent("ul")),a.parent("ul").on(e.transitionend(a),function(){setTimeout(function(){a.parent("ul").parent("li").focus()},1)})},up:function(){s.focus()},down:function(){o.focus()},close:function(){i._back()},open:function(){ +a.is(i.$menuItems)?a.is(i.$submenuAnchors)&&(i._show(a),setTimeout(function(){a.find("ul li").filter(i.$menuItems).first().focus()},1)):(i._hide(a.parent("ul")),setTimeout(function(){a.parent("ul").parent("li").focus()},1))},handled:function(){n.preventDefault(),n.stopImmediatePropagation()}})})},i.prototype._hideAll=function(){var t=this.$element.find(".is-drilldown-sub.is-active").addClass("is-closing");t.one(e.transitionend(t),function(e){t.removeClass("is-active is-closing")}),this.$element.trigger("closed.zf.drilldown")},i.prototype._back=function(t){var e=this;t.off("click.zf.drilldown"),t.children(".js-drilldown-back").on("click.zf.drilldown",function(i){i.stopImmediatePropagation(),e._hide(t)})},i.prototype._menuLinkEvents=function(){var t=this;this.$menuItems.not(".has-submenu").off("click.zf.drilldown").on("click.zf.drilldown",function(e){setTimeout(function(){t._hideAll()},0)})},i.prototype._show=function(t){t.children("[data-submenu]").addClass("is-active"),this.$element.trigger("open.zf.drilldown",[t])},i.prototype._hide=function(t){t.addClass("is-closing").one(e.transitionend(t),function(){t.removeClass("is-active is-closing")}),t.trigger("hide.zf.drilldown",[t])},i.prototype._getMaxDims=function(){var e=0,i={};return this.$submenus.add(this.$element).each(function(){var i=t(this).children("li").length;e=i>e?i:e}),i.height=e*this.$menuItems[0].getBoundingClientRect().height+"px",i.width=this.$element[0].getBoundingClientRect().width+"px",i},i.prototype.destroy=function(){this._hideAll(),e.Nest.Burn(this.$element,"drilldown"),this.$element.unwrap().find(".js-drilldown-back").remove().end().find(".is-active, .is-closing, .is-drilldown-sub").removeClass("is-active is-closing is-drilldown-sub").end().find("[data-submenu]").removeAttr("aria-hidden tabindex role").off(".zf.drilldown").end().off("zf.drilldown"),this.$element.find("a").each(function(){var e=t(this);e.data("savedHref")&&e.attr("href",e.data("savedHref")).removeData("savedHref")}),e.unregisterPlugin(this)},e.plugin(i,"Drilldown")}(jQuery,window.Foundation),!function(t,e){"use strict";function i(n,s){this.$element=n,this.options=t.extend({},i.defaults,this.$element.data(),s),this._init(),e.registerPlugin(this),e.Keyboard.register("Dropdown",{ENTER:"open",SPACE:"open",ESCAPE:"close",TAB:"tab_forward",SHIFT_TAB:"tab_backward"})}i.defaults={hoverDelay:250,hover:!1,hoverPane:!1,vOffset:1,hOffset:1,positionClass:"",trapFocus:!1,autoFocus:!1},i.prototype._init=function(){var i=this.$element.attr("id");this.$anchor=t('[data-toggle="'+i+'"]')||t('[data-open="'+i+'"]'),this.$anchor.attr({"aria-controls":i,"data-is-focus":!1,"data-yeti-box":i,"aria-haspopup":!0,"aria-expanded":!1}),this.options.positionClass=this.getPositionClass(),this.counter=4,this.usedPositions=[],this.$element.attr({"aria-hidden":"true","data-yeti-box":i,"data-resize":i,"aria-labelledby":this.$anchor[0].id||e.GetYoDigits(6,"dd-anchor")}),this._events()},i.prototype.getPositionClass=function(){var t=this.$element[0].className.match(/(top|left|right)/g);return t=t?t[0]:""},i.prototype._reposition=function(t){this.usedPositions.push(t?t:"bottom"),!t&&this.usedPositions.indexOf("top")<0?this.$element.addClass("top"):"top"===t&&this.usedPositions.indexOf("bottom")<0?this.$element.removeClass(t):"left"===t&&this.usedPositions.indexOf("right")<0?this.$element.removeClass(t).addClass("right"):"right"===t&&this.usedPositions.indexOf("left")<0?this.$element.removeClass(t).addClass("left"):!t&&this.usedPositions.indexOf("top")>-1&&this.usedPositions.indexOf("left")<0?this.$element.addClass("left"):"top"===t&&this.usedPositions.indexOf("bottom")>-1&&this.usedPositions.indexOf("left")<0?this.$element.removeClass(t).addClass("left"):"left"===t&&this.usedPositions.indexOf("right")>-1&&this.usedPositions.indexOf("bottom")<0?this.$element.removeClass(t):"right"===t&&this.usedPositions.indexOf("left")>-1&&this.usedPositions.indexOf("bottom")<0?this.$element.removeClass(t):this.$element.removeClass(t),this.classChanged=!0,this.counter--},i.prototype._setPosition=function(){if("false"===this.$anchor.attr("aria-expanded"))return!1;var t=this.getPositionClass(),i=e.Box.GetDimensions(this.$element),n=(e.Box.GetDimensions(this.$anchor),"left"===t?"left":"right"===t?"left":"top"),s="top"===n?"height":"width";"height"===s?this.options.vOffset:this.options.hOffset;if(i.width>=i.windowDims.width||!this.counter&&!e.Box.ImNotTouchingYou(this.$element))return this.$element.offset(e.Box.GetOffsets(this.$element,this.$anchor,"center bottom",this.options.vOffset,this.options.hOffset,!0)).css({width:i.windowDims.width-2*this.options.hOffset,height:"auto"}),this.classChanged=!0,!1;for(this.$element.offset(e.Box.GetOffsets(this.$element,this.$anchor,t,this.options.vOffset,this.options.hOffset));!e.Box.ImNotTouchingYou(this.$element)&&this.counter;)this._reposition(t),this._setPosition()},i.prototype._events=function(){var i=this;this.$element.on({"open.zf.trigger":this.open.bind(this),"close.zf.trigger":this.close.bind(this),"toggle.zf.trigger":this.toggle.bind(this),"resizeme.zf.trigger":this._setPosition.bind(this)}),this.options.hover&&(this.$anchor.off("mouseenter.zf.dropdown mouseleave.zf.dropdown").on("mouseenter.zf.dropdown",function(){clearTimeout(i.timeout),i.timeout=setTimeout(function(){i.open(),i.$anchor.data("hover",!0)},i.options.hoverDelay)}).on("mouseleave.zf.dropdown",function(){clearTimeout(i.timeout),i.timeout=setTimeout(function(){i.close(),i.$anchor.data("hover",!1)},i.options.hoverDelay)}),this.options.hoverPane&&this.$element.off("mouseenter.zf.dropdown mouseleave.zf.dropdown").on("mouseenter.zf.dropdown",function(){clearTimeout(i.timeout)}).on("mouseleave.zf.dropdown",function(){clearTimeout(i.timeout),i.timeout=setTimeout(function(){i.close(),i.$anchor.data("hover",!1)},i.options.hoverDelay)})),this.$anchor.add(this.$element).on("keydown.zf.dropdown",function(n){var s=t(this),o=e.Keyboard.findFocusable(i.$element);e.Keyboard.handleKey(n,i,{tab_forward:function(){this.$element.find(":focus").is(o.eq(-1))&&(this.options.trapFocus?(o.eq(0).focus(),n.preventDefault()):this.close())},tab_backward:function(){(this.$element.find(":focus").is(o.eq(0))||this.$element.is(":focus"))&&(this.options.trapFocus?(o.eq(-1).focus(),n.preventDefault()):this.close())},open:function(){s.is(i.$anchor)&&(i.open(),i.$element.attr("tabindex",-1).focus(),n.preventDefault())},close:function(){i.close(),i.$anchor.focus()}})})},i.prototype.open=function(){if(this.$element.trigger("closeme.zf.dropdown",this.$element.attr("id")),this.$anchor.addClass("hover").attr({"aria-expanded":!0}),this._setPosition(),this.$element.addClass("is-open").attr({"aria-hidden":!1}),this.options.autoFocus){var t=e.Keyboard.findFocusable(this.$element);t.length&&t.eq(0).focus()}this.$element.trigger("show.zf.dropdown",[this.$element])},i.prototype.close=function(){if(!this.$element.hasClass("is-open"))return!1;if(this.$element.removeClass("is-open").attr({"aria-hidden":!0}),this.$anchor.removeClass("hover").attr("aria-expanded",!1),this.classChanged){var t=this.getPositionClass();t&&this.$element.removeClass(t),this.$element.addClass(this.options.positionClass).css({height:"",width:""}),this.classChanged=!1,this.counter=4,this.usedPositions.length=0}this.$element.trigger("hide.zf.dropdown",[this.$element])},i.prototype.toggle=function(){if(this.$element.hasClass("is-open")){if(this.$anchor.data("hover"))return;this.close()}else this.open()},i.prototype.destroy=function(){this.$element.off(".zf.trigger").hide(),this.$anchor.off(".zf.dropdown"),e.unregisterPlugin(this)},e.plugin(i,"Dropdown")}(jQuery,window.Foundation),!function(t,e){"use strict";function i(n,s){this.$element=n,this.options=t.extend({},i.defaults,this.$element.data(),s),e.Nest.Feather(this.$element,"dropdown"),this._init(),e.registerPlugin(this),e.Keyboard.register("DropdownMenu",{ENTER:"open",SPACE:"open",ARROW_RIGHT:"next",ARROW_UP:"up",ARROW_DOWN:"down",ARROW_LEFT:"previous",ESCAPE:"close"})}i.defaults={disableHover:!1,autoclose:!0,hoverDelay:50,clickOpen:!1,closingTime:500,alignment:"left",closeOnClick:!0,verticalClass:"vertical",rightClass:"align-right",forceFollow:!0},i.prototype._init=function(){var t=this.$element.find("li.is-dropdown-submenu-parent");this.$element.children(".is-dropdown-submenu-parent").children(".is-dropdown-submenu").addClass("first-sub"),this.$menuItems=this.$element.find('[role="menuitem"]'),this.$tabs=this.$element.children('[role="menuitem"]'),this.isVert=this.$element.hasClass(this.options.verticalClass),this.$tabs.find("ul.is-dropdown-submenu").addClass(this.options.verticalClass),this.$element.hasClass(this.options.rightClass)||"right"===this.options.alignment?(this.options.alignment="right",t.addClass("is-left-arrow opens-left")):t.addClass("is-right-arrow opens-right"),this.isVert||this.$tabs.filter(".is-dropdown-submenu-parent").removeClass("is-right-arrow is-left-arrow opens-right opens-left").addClass("is-down-arrow"),this.changed=!1,this._events()},i.prototype._events=function(){var i,n=this,s="ontouchstart"in window||"undefined"!=typeof window.ontouchstart,o="is-dropdown-submenu-parent";(this.options.clickOpen||s)&&this.$menuItems.on("click.zf.dropdownmenu touchstart.zf.dropdownmenu",function(e){var i=t(e.target).parentsUntil("ul","."+o),a=i.hasClass(o),r="true"===i.attr("data-is-click");i.children(".is-dropdown-submenu");if(a)if(r){if(!n.options.closeOnClick||!n.options.clickOpen&&!s||n.options.forceFollow&&s)return;e.stopImmediatePropagation(),e.preventDefault(),n._hide(i)}else e.preventDefault(),e.stopImmediatePropagation(),n._show(i.children(".is-dropdown-submenu")),i.add(i.parentsUntil(n.$element,"."+o)).attr("data-is-click",!0)}),this.options.disableHover||this.$menuItems.on("mouseenter.zf.dropdownmenu",function(e){e.stopImmediatePropagation();var s=t(this),a=s.hasClass(o);a&&(clearTimeout(i),i=setTimeout(function(){n._show(s.children(".is-dropdown-submenu"))},n.options.hoverDelay))}).on("mouseleave.zf.dropdownmenu",function(e){var s=t(this),a=s.hasClass(o);if(a&&n.options.autoclose){if("true"===s.attr("data-is-click")&&n.options.clickOpen)return!1;i=setTimeout(function(){n._hide(s)},n.options.closingTime)}}),this.$menuItems.on("keydown.zf.dropdownmenu",function(i){var s,o,a=t(i.target).parentsUntil("ul",'[role="menuitem"]'),r=n.$tabs.index(a)>-1,l=r?n.$tabs:a.siblings("li").add(a);l.each(function(e){return t(this).is(a)?(s=l.eq(e-1),void(o=l.eq(e+1))):void 0});var d=function(){a.is(":last-child")||o.children("a:first").focus()},h=function(){s.children("a:first").focus()},u=function(){var t=a.children("ul.is-dropdown-submenu");t.length&&(n._show(t),a.find("li > a:first").focus())},c=function(){var t=a.parent("ul").parent("li");t.children("a:first").focus(),n._hide(t)},f={open:u,close:function(){n._hide(n.$element),n.$menuItems.find("a:first").focus()},handled:function(){i.preventDefault(),i.stopImmediatePropagation()}};r?n.vertical?"left"===n.options.alignment?t.extend(f,{down:d,up:h,next:u,previous:c}):t.extend(f,{down:d,up:h,next:c,previous:u}):t.extend(f,{next:d,previous:h,down:u,up:c}):"left"===n.options.alignment?t.extend(f,{next:u,previous:c,down:d,up:h}):t.extend(f,{next:c,previous:u,down:d,up:h}),e.Keyboard.handleKey(i,n,f)})},i.prototype._addBodyHandler=function(){var e=t(document.body),i=this;e.off("mouseup.zf.dropdownmenu touchend.zf.dropdownmenu").on("mouseup.zf.dropdownmenu touchend.zf.dropdownmenu",function(t){var n=i.$element.find(t.target);n.length||(i._hide(),e.off("mouseup.zf.dropdownmenu touchend.zf.dropdownmenu"))})},i.prototype._show=function(i){var n=this.$tabs.index(this.$tabs.filter(function(e,n){return t(n).find(i).length>0})),s=i.parent("li.is-dropdown-submenu-parent").siblings("li.is-dropdown-submenu-parent");this._hide(s,n),i.css("visibility","hidden").addClass("js-dropdown-active").attr({"aria-hidden":!1}).parent("li.is-dropdown-submenu-parent").addClass("is-active").attr({"aria-selected":!0,"aria-expanded":!0});var o=e.Box.ImNotTouchingYou(i,null,!0);if(!o){var a="left"===this.options.alignment?"-right":"-left",r=i.parent(".is-dropdown-submenu-parent");r.removeClass("opens"+a).addClass("opens-"+this.options.alignment),o=e.Box.ImNotTouchingYou(i,null,!0),o||r.removeClass("opens-"+this.options.alignment).addClass("opens-inner"),this.changed=!0}i.css("visibility",""),this.options.closeOnClick&&this._addBodyHandler(),this.$element.trigger("show.zf.dropdownmenu",[i])},i.prototype._hide=function(t,e){var i;i=t&&t.length?t:void 0!==e?this.$tabs.not(function(t,i){return t===e}):this.$element;var n=i.hasClass("is-active")||i.find(".is-active").length>0;if(n){if(i.find("li.is-active").add(i).attr({"aria-selected":!1,"aria-expanded":!1,"data-is-click":!1}).removeClass("is-active"),i.find("ul.js-dropdown-active").attr({"aria-hidden":!0}).removeClass("js-dropdown-active"),this.changed||i.find("opens-inner").length){var s="left"===this.options.alignment?"right":"left";i.find("li.is-dropdown-submenu-parent").add(i).removeClass("opens-inner opens-"+this.options.alignment).addClass("opens-"+s),this.changed=!1}this.$element.trigger("hide.zf.dropdownmenu",[i])}},i.prototype.destroy=function(){this.$menuItems.off(".zf.dropdownmenu").removeAttr("data-is-click").removeClass("is-right-arrow is-left-arrow is-down-arrow opens-right opens-left opens-inner"),e.Nest.Burn(this.$element,"dropdown"),e.unregisterPlugin(this)},e.plugin(i,"DropdownMenu")}(jQuery,window.Foundation),!function(t,e){"use strict";function i(n,s){this.$element=n,this.options=e.extend({},i.defaults,this.$element.data(),s),this.$window=e(window),this.name="equalizer",this.attr="data-equalizer",this._init(),this._events(),t.registerPlugin(this)}i.defaults={equalizeOnStack:!0,throttleInterval:50},i.prototype._init=function(){this._reflow()},i.prototype._events=function(){var e=this;this.$window.off(".equalizer").on("resize.fndtn.equalizer",t.util.throttle(function(){e._reflow()},e.options.throttleInterval))},i.prototype._killswitch=function(){},i.prototype._reflow=function(){var i=this;e("["+this.attr+"]").each(function(){var n=e(this),s=[],o=n.find("img");o.length?t.onImagesLoaded(o,function(){s=i.getHeights(n),i.applyHeight(n,s)}):(s=i.getHeights(n),i.applyHeight(n,s))})},i.prototype.getHeights=function(t){var i,n=t.data("equalizer"),s=n?t.find("["+this.attr+'-watch="'+n+'"]:visible'):t.find("["+this.attr+"-watch]:visible");return s.height("inherit"),i=s.map(function(){return e(this).outerHeight(!1)}).get()},i.prototype.applyHeight=function(t,i){var n=t.data("equalizer"),s=n?t.find("["+this.attr+'-watch="'+n+'"]:visible'):t.find("["+this.attr+"-watch]:visible"),o=Math.max.apply(null,i);t.trigger("preEqualized.zf.Equalizer");for(var a=0;a=t:t-n.options.threshold<=e});t=s.length?s.length-1:0}if(this.$active.removeClass(this.options.activeClass),this.$active=this.$links.eq(t).addClass(this.options.activeClass),this.options.deepLinking){var o=this.$active[0].getAttribute("href");window.history.pushState?window.history.pushState(null,null,o):window.location.hash=o}this.scrollPos=e,this.$element.trigger("update.zf.magellan",[this.$active])},i.prototype.destroy=function(){if(this.$element.off(".zf.trigger .zf.magellan").find("."+this.options.activeClass).removeClass(this.options.activeClass),this.options.deepLinking){var e=this.$active[0].getAttribute("href");window.location.hash.replace(e,"")}t.unregisterPlugin(this)},t.plugin(i,"Magellan"),"undefined"!=typeof module&&"undefined"!=typeof module.exports&&(module.exports=i),"function"==typeof define&&define(["foundation"],function(){return i})}(Foundation,jQuery),!function(t,e){"use strict";function i(n,s){this.$element=n,this.options=t.extend({},i.defaults,this.$element.data(),s),this.$lastTrigger=t(),this._init(),this._events(),e.registerPlugin(this)}i.defaults={closeOnClick:!0,transitionTime:0,position:"left",forceTop:!0,isRevealed:!1,revealOn:null,autoFocus:!0,revealClass:"reveal-for-"},i.prototype._init=function(){var e=this.$element.attr("id");if(this.$element.attr("aria-hidden","true"),t(document).find('[data-open="'+e+'"], [data-close="'+e+'"], [data-toggle="'+e+'"]').attr("aria-expanded","false").attr("aria-controls",e),this.options.closeOnClick)if(t(".js-off-canvas-exit").length)this.$exiter=t(".js-off-canvas-exit");else{var i=document.createElement("div");i.setAttribute("class","js-off-canvas-exit"),t("[data-off-canvas-content]").append(i),this.$exiter=t(i)}this.options.isRevealed=this.options.isRevealed||new RegExp(this.options.revealClass,"g").test(this.$element[0].className),this.options.isRevealed&&(this.options.revealOn=this.options.revealOn||this.$element[0].className.match(/(reveal-for-medium|reveal-for-large)/g)[0].split("-")[2],this._setMQChecker()),this.options.transitionTime||(this.options.transitionTime=1e3*parseFloat(window.getComputedStyle(t("[data-off-canvas-wrapper]")[0]).transitionDuration))},i.prototype._events=function(){if(this.$element.on({"open.zf.trigger":this.open.bind(this),"close.zf.trigger":this.close.bind(this),"toggle.zf.trigger":this.toggle.bind(this),"keydown.zf.offcanvas":this._handleKeyboard.bind(this)}),this.$exiter.length){this.$exiter.on({"click.zf.offcanvas":this.close.bind(this)})}},i.prototype._setMQChecker=function(){var i=this;t(window).on("changed.zf.mediaquery",function(){e.MediaQuery.atLeast(i.options.revealOn)?i.reveal(!0):i.reveal(!1)}).one("load.zf.offcanvas",function(){e.MediaQuery.atLeast(i.options.revealOn)&&i.reveal(!0)})},i.prototype.reveal=function(t){var e=this.$element.find("[data-close]");t?e.length&&e.hide():e.length&&e.show()},i.prototype.open=function(i,n){if(!this.$element.hasClass("is-open")){var s=this;t(document.body);t("body").scrollTop(0),e.Move(this.options.transitionTime,this.$element,function(){t("[data-off-canvas-wrapper]").addClass("is-off-canvas-open is-open-"+s.options.position),s.$element.addClass("is-open").attr("aria-hidden","false").trigger("opened.zf.offcanvas")}),n&&(this.$lastTrigger=n.attr("aria-expanded","true")),this.options.autoFocus&&this.$element.one("finished.zf.animate",function(){s.$element.find("a, button").eq(0).focus()})}},i.prototype.close=function(){if(this.$element.hasClass("is-open")){var i=this;e.Move(this.options.transitionTime,this.$element,function(){t("[data-off-canvas-wrapper]").removeClass("is-off-canvas-open is-open-"+i.options.position),i.$element.removeClass("is-open")}),this.$element.attr("aria-hidden","true").trigger("closed.zf.offcanvas"),this.$lastTrigger.attr("aria-expanded","false")}},i.prototype.toggle=function(t,e){this.$element.hasClass("is-open")?this.close(t,e):this.open(t,e)},i.prototype._handleKeyboard=function(t){27===t.which&&(t.stopPropagation(),t.preventDefault(),this.close(),this.$lastTrigger.focus())},i.prototype.destroy=function(){},e.plugin(i,"OffCanvas")}(jQuery,Foundation),!function(t,e){"use strict";function i(n,s){this.$element=n,this.options=t.extend({},i.defaults,this.$element.data(),s),this._init(),e.registerPlugin(this),e.Keyboard.register("Orbit",{ltr:{ARROW_RIGHT:"next",ARROW_LEFT:"previous"},rtl:{ARROW_LEFT:"next",ARROW_RIGHT:"previous"}})}i.defaults={bullets:!0,navButtons:!0,animInFromRight:"slide-in-right",animOutToRight:"slide-out-right",animInFromLeft:"slide-in-left",animOutToLeft:"slide-out-left",autoPlay:!0,timerDelay:5e3,infiniteWrap:!0,swipe:!0,pauseOnHover:!0,accessible:!0,containerClass:"orbit-container",slideClass:"orbit-slide",boxOfBullets:"orbit-bullets",nextClass:"orbit-next",prevClass:"orbit-previous",useMUI:!0},i.prototype._init=function(){this.$wrapper=this.$element.find("."+this.options.containerClass),this.$slides=this.$element.find("."+this.options.slideClass);var t=this.$element.find("img"),i=this.$slides.filter(".is-active");i.length||this.$slides.eq(0).addClass("is-active"),this.options.useMUI||this.$slides.addClass("no-motionui"),t.length?e.onImagesLoaded(t,this._prepareForOrbit.bind(this)):this._prepareForOrbit(),this.options.bullets&&this._loadBullets(),this._events(),this.options.autoPlay&&this.geoSync(),this.options.accessible&&this.$wrapper.attr("tabindex",0)},i.prototype._loadBullets=function(){this.$bullets=this.$element.find("."+this.options.boxOfBullets).find("button")},i.prototype.geoSync=function(){var t=this;this.timer=new e.Timer(this.$element,{duration:this.options.timerDelay,infinite:!1},function(){t.changeSlide(!0)}),this.timer.start()},i.prototype._prepareForOrbit=function(){var t=this;this._setWrapperHeight(function(e){t._setSlideHeight(e)})},i.prototype._setWrapperHeight=function(e){var i,n=0,s=0;this.$slides.each(function(){i=this.getBoundingClientRect().height,t(this).attr("data-slide",s),s&&t(this).css({position:"relative",display:"none"}),n=i>n?i:n,s++}),s===this.$slides.length&&(this.$wrapper.css({height:n}),e(n))},i.prototype._setSlideHeight=function(e){this.$slides.each(function(){t(this).css("max-height",e)})},i.prototype._events=function(){var i=this;if(this.options.swipe&&this.$slides.off("swipeleft.zf.orbit swiperight.zf.orbit").on("swipeleft.zf.orbit",function(t){t.preventDefault(),i.changeSlide(!0)}).on("swiperight.zf.orbit",function(t){t.preventDefault(),i.changeSlide(!1)}),this.options.autoPlay&&(this.$slides.on("click.zf.orbit",function(){i.$element.data("clickedOn",i.$element.data("clickedOn")?!1:!0),i.timer[i.$element.data("clickedOn")?"pause":"start"]()}),this.options.pauseOnHover&&this.$element.on("mouseenter.zf.orbit",function(){i.timer.pause()}).on("mouseleave.zf.orbit",function(){i.$element.data("clickedOn")||i.timer.start()})),this.options.navButtons){var n=this.$element.find("."+this.options.nextClass+", ."+this.options.prevClass);n.attr("tabindex",0).on("click.zf.orbit touchend.zf.orbit",function(){i.changeSlide(t(this).hasClass(i.options.nextClass))})}this.options.bullets&&this.$bullets.on("click.zf.orbit touchend.zf.orbit",function(){if(/is-active/g.test(this.className))return!1;var e=t(this).data("slide"),n=e>i.$slides.filter(".is-active").data("slide"),s=i.$slides.eq(e);i.changeSlide(n,s,e)}),this.$wrapper.add(this.$bullets).on("keydown.zf.orbit",function(n){e.Keyboard.handleKey(n,i,{next:function(){i.changeSlide(!0)},previous:function(){i.changeSlide(!1)},handled:function(){t(n.target).is(i.$bullets)&&i.$bullets.filter(".is-active").focus()}})})},i.prototype.changeSlide=function(t,i,n){var s=this.$slides.filter(".is-active").eq(0);if(/mui/g.test(s[0].className))return!1;var o,a=this.$slides.first(),r=this.$slides.last(),l=t?"Right":"Left",d=t?"Left":"Right",h=this;o=i?i:t?this.options.infiniteWrap?s.next("."+this.options.slideClass).length?s.next("."+this.options.slideClass):a:s.next("."+this.options.slideClass):this.options.infiniteWrap?s.prev("."+this.options.slideClass).length?s.prev("."+this.options.slideClass):r:s.prev("."+this.options.slideClass),o.length&&(this.options.bullets&&(n=n||this.$slides.index(o),this._updateBullets(n)),this.options.useMUI?(e.Motion.animateIn(o.addClass("is-active").css({position:"absolute",top:0}),this.options["animInFrom"+l],function(){o.css({position:"relative",display:"block"}).attr("aria-live","polite")}),e.Motion.animateOut(s.removeClass("is-active"),this.options["animOutTo"+d],function(){s.removeAttr("aria-live"),h.options.autoPlay&&h.timer.restart()})):(s.removeClass("is-active is-in").removeAttr("aria-live").hide(),o.addClass("is-active is-in").attr("aria-live","polite").show(),this.options.autoPlay&&this.timer.restart()),this.$element.trigger("slidechange.zf.orbit",[o]))},i.prototype._updateBullets=function(t){var e=this.$element.find("."+this.options.boxOfBullets).find(".is-active").removeClass("is-active").blur(),i=e.find("span:last").detach();this.$bullets.eq(t).addClass("is-active").append(i)},i.prototype.destroy=function(){delete this.timer,this.$element.off(".zf.orbit").find("*").off(".zf.orbit").end().hide(),e.unregisterPlugin(this)},e.plugin(i,"Orbit")}(jQuery,window.Foundation),!function(t,e){"use strict";function i(i){this.$element=e(i),this.rules=this.$element.data("responsive-menu"),this.currentMq=null,this.currentPlugin=null,this._init(),this._events(),t.registerPlugin(this)}var n={dropdown:{cssClass:"dropdown",plugin:t._plugins["dropdown-menu"]||null},drilldown:{cssClass:"drilldown",plugin:t._plugins.drilldown||null},accordion:{cssClass:"accordion-menu",plugin:t._plugins["accordion-menu"]||null}};i.defaults={},i.prototype._init=function(){for(var t={},i=this.rules.split(" "),s=0;s1?o[0]:"small",r=o.length>1?o[1]:o[0];null!==n[r]&&(t[a]=n[r])}this.rules=t,e.isEmptyObject(t)||this._checkMediaQueries()},i.prototype._events=function(){var t=this;e(window).on("changed.zf.mediaquery",function(){t._checkMediaQueries()})},i.prototype._checkMediaQueries=function(){var i,s=this;e.each(this.rules,function(e){t.MediaQuery.atLeast(e)&&(i=e)}),i&&(this.currentPlugin instanceof this.rules[i].plugin||(e.each(n,function(t,e){s.$element.removeClass(e.cssClass)}),this.$element.addClass(this.rules[i].cssClass),this.currentPlugin&&this.currentPlugin.destroy(),this.currentPlugin=new this.rules[i].plugin(this.$element,{})))},i.prototype.destroy=function(){this.currentPlugin.destroy(),e(window).off(".zf.ResponsiveMenu"),t.unregisterPlugin(this)},t.plugin(i,"ResponsiveMenu")}(Foundation,jQuery),!function(t,e){"use strict";function i(n,s){this.$element=t(n),this.options=t.extend({},i.defaults,this.$element.data(),s),this._init(),this._events(),e.registerPlugin(this)}i.defaults={hideFor:"medium"},i.prototype._init=function(){var e=this.$element.data("responsive-toggle");e||console.error("Your tab bar needs an ID of a Menu as the value of data-tab-bar."),this.$targetMenu=t("#"+e),this.$toggler=this.$element.find("[data-toggle]"),this._update()},i.prototype._events=function(){t(window).on("changed.zf.mediaquery",this._update.bind(this)),this.$toggler.on("click.zf.responsiveToggle",this.toggleMenu.bind(this))},i.prototype._update=function(){e.MediaQuery.atLeast(this.options.hideFor)?(this.$element.hide(),this.$targetMenu.show()):(this.$element.show(),this.$targetMenu.hide())},i.prototype.toggleMenu=function(){e.MediaQuery.atLeast(this.options.hideFor)||(this.$targetMenu.toggle(0),this.$element.trigger("toggled.zf.responsiveToggle"))},i.prototype.destroy=function(){},e.plugin(i,"ResponsiveToggle")}(jQuery,Foundation),!function(t,e){"use strict";function i(n,s){this.$element=n,this.options=e.extend({},i.defaults,this.$element.data(),s),this._init(),t.registerPlugin(this),t.Keyboard.register("Reveal",{ENTER:"open",SPACE:"open",ESCAPE:"close",TAB:"tab_forward",SHIFT_TAB:"tab_backward"})}i.defaults={animationIn:"",animationOut:"",showDelay:0,hideDelay:0,closeOnClick:!0,closeOnEsc:!0,multipleOpened:!1,vOffset:100,hOffset:0,fullScreen:!1,btmOffsetPct:10,overlay:!0,resetOnClose:!1},i.prototype._init=function(){if(this.id=this.$element.attr("id"),this.isActive=!1,this.$anchor=e(e('[data-open="'+this.id+'"]').length?'[data-open="'+this.id+'"]':'[data-toggle="'+this.id+'"]'),this.$anchor.length){var i=this.$anchor[0].id||t.GetYoDigits(6,"reveal");this.$anchor.attr({"aria-controls":this.id,id:i,"aria-haspopup":!0,tabindex:0}),this.$element.attr({"aria-labelledby":i})}(this.options.fullScreen||this.$element.hasClass("full"))&&(this.options.fullScreen=!0,this.options.overlay=!1),this.options.overlay&&!this.$overlay&&(this.$overlay=this._makeOverlay(this.id)),this.$element.attr({role:"dialog","aria-hidden":!0,"data-yeti-box":this.id,"data-resize":this.id}),this._events()},i.prototype._makeOverlay=function(t){var i=e("
    ").addClass("reveal-overlay").attr({tabindex:-1,"aria-hidden":!0}).appendTo("body");return this.options.closeOnClick&&i.attr({"data-close":t}),i},i.prototype._events=function(){var t=this;this.$element.on({"open.zf.trigger":this.open.bind(this),"close.zf.trigger":this.close.bind(this),"toggle.zf.trigger":this.toggle.bind(this),"resizeme.zf.trigger":function(){ +t.$element.is(":visible")&&t._setPosition(function(){})}}),this.$anchor.length&&this.$anchor.on("keydown.zf.reveal",function(e){(13===e.which||32===e.which)&&(e.stopPropagation(),e.preventDefault(),t.open())}),this.options.closeOnClick&&this.options.overlay&&this.$overlay.off(".zf.reveal").on("click.zf.reveal",this.close.bind(this))},i.prototype._setPosition=function(e){var i=t.Box.GetDimensions(this.$element),n=this.options.fullScreen?"reveal full":i.height>=.5*i.windowDims.height?"reveal":"center";"reveal full"===n?this.$element.offset(t.Box.GetOffsets(this.$element,null,n,this.options.vOffset)).css({height:i.windowDims.height,width:i.windowDims.width}):t.MediaQuery.atLeast("medium")&&t.Box.ImNotTouchingYou(this.$element,null,!0,!1)?this.$element.css({"max-height":i.windowDims.height-this.options.vOffset*(this.options.btmOffsetPct/100+1),width:""}).offset(t.Box.GetOffsets(this.$element,null,n,this.options.vOffset)):(this.$element.css({width:i.windowDims.width-2*this.options.hOffset}).offset(t.Box.GetOffsets(this.$element,null,"center",this.options.vOffset,this.options.hOffset)),this.changedSize=!0),e()},i.prototype.open=function(){var i=this;this.isActive=!0,this.$element.css({visibility:"hidden"}).show().scrollTop(0),this._setPosition(function(){i.$element.hide().css({visibility:""}),i.options.multipleOpened||i.$element.trigger("closeme.zf.reveal",i.id),i.options.animationIn?i.options.overlay?t.Motion.animateIn(i.$overlay,"fade-in",function(){t.Motion.animateIn(i.$element,i.options.animationIn,function(){i.focusableElements=t.Keyboard.findFocusable(i.$element)})}):t.Motion.animateIn(i.$element,i.options.animationIn,function(){i.focusableElements=t.Keyboard.findFocusable(i.$element)}):i.options.overlay?i.$overlay.show(0,function(){i.$element.show(i.options.showDelay,function(){})}):i.$element.show(i.options.showDelay,function(){})}),this.$element.attr({"aria-hidden":!1}).attr("tabindex",-1).focus().trigger("open.zf.reveal"),e("body").addClass("is-reveal-open").attr({"aria-hidden":this.options.overlay||this.options.fullScreen?!0:!1}),setTimeout(function(){i._extraHandlers()},0)},i.prototype._extraHandlers=function(){var i=this;this.focusableElements=t.Keyboard.findFocusable(this.$element),this.options.overlay||!this.options.closeOnClick||this.options.fullScreen||e("body").on("click.zf.reveal",function(t){i.close()}),this.options.closeOnEsc&&e(window).on("keydown.zf.reveal",function(e){t.Keyboard.handleKey(e,i,{close:function(){this.options.closeOnEsc&&(this.close(),this.$anchor.focus())}}),0===i.focusableElements.length&&e.preventDefault()}),this.$element.on("keydown.zf.reveal",function(n){var s=e(this);t.Keyboard.handleKey(n,i,{tab_forward:function(){this.$element.find(":focus").is(i.focusableElements.eq(-1))&&(i.focusableElements.eq(0).focus(),n.preventDefault())},tab_backward:function(){(this.$element.find(":focus").is(i.focusableElements.eq(0))||this.$element.is(":focus"))&&(i.focusableElements.eq(-1).focus(),n.preventDefault())},open:function(){i.$element.find(":focus").is(i.$element.find("[data-close]"))?setTimeout(function(){i.$anchor.focus()},1):s.is(i.focusableElements)&&this.open()},close:function(){this.options.closeOnEsc&&(this.close(),this.$anchor.focus())}})})},i.prototype.close=function(){if(!this.isActive||!this.$element.is(":visible"))return!1;var i=this;this.options.animationOut?t.Motion.animateOut(this.$element,this.options.animationOut,function(){i.options.overlay&&t.Motion.animateOut(i.$overlay,"fade-out",function(){})}):this.$element.hide(i.options.hideDelay,function(){i.options.overlay&&i.$overlay.hide(0,function(){})}),this.options.closeOnEsc&&e(window).off("keydown.zf.reveal"),!this.options.overlay&&this.options.closeOnClick&&e("body").off("click.zf.reveal"),this.$element.off("keydown.zf.reveal"),this.changedSize&&this.$element.css({height:"",width:""}),e("body").removeClass("is-reveal-open").attr({"aria-hidden":!1,tabindex:""}),this.options.resetOnClose&&this.$element.html(this.$element.html()),this.isActive=!1,this.$element.attr({"aria-hidden":!0}).trigger("closed.zf.reveal")},i.prototype.toggle=function(){this.isActive?this.close():this.open()},i.prototype.destroy=function(){this.options.overlay&&this.$overlay.hide().off().remove(),this.$element.hide(),this.$anchor.off(),t.unregisterPlugin(this)},t.plugin(i,"Reveal"),"undefined"!=typeof module&&"undefined"!=typeof module.exports&&(module.exports=i),"function"==typeof define&&define(["foundation"],function(){return i})}(Foundation,jQuery),!function(t,e){"use strict";function i(n,s){this.$element=n,this.options=t.extend({},i.defaults,this.$element.data(),s),this._init(),e.registerPlugin(this),e.Keyboard.register("Slider",{ltr:{ARROW_RIGHT:"increase",ARROW_UP:"increase",ARROW_DOWN:"decrease",ARROW_LEFT:"decrease",SHIFT_ARROW_RIGHT:"increase_fast",SHIFT_ARROW_UP:"increase_fast",SHIFT_ARROW_DOWN:"decrease_fast",SHIFT_ARROW_LEFT:"decrease_fast"},rtl:{ARROW_LEFT:"increase",ARROW_RIGHT:"decrease",SHIFT_ARROW_LEFT:"increase_fast",SHIFT_ARROW_RIGHT:"decrease_fast"}})}function n(t,e){return t/e}function s(t,e,i,n){return Math.abs(t.position()[e]+t[n]()/2-i)}i.defaults={start:0,end:100,step:1,initialStart:0,initialEnd:100,binding:!1,clickSelect:!0,vertical:!1,draggable:!0,disabled:!1,doubleSided:!1,decimal:2,moveTime:200,disabledClass:"disabled"},i.prototype._init=function(){this.inputs=this.$element.find("input"),this.handles=this.$element.find("[data-slider-handle]"),this.$handle=this.handles.eq(0),this.$input=this.inputs.length?this.inputs.eq(0):t("#"+this.$handle.attr("aria-controls")),this.$fill=this.$element.find("[data-slider-fill]").css(this.options.vertical?"height":"width",0);var e=!1,i=this;(this.options.disabled||this.$element.hasClass(this.options.disabledClass))&&(this.options.disabled=!0,this.$element.addClass(this.options.disabledClass)),this.inputs.length||(this.inputs=t().add(this.$input),this.options.binding=!0),this._setInitAttr(0),this._events(this.$handle),this.handles[1]&&(this.options.doubleSided=!0,this.$handle2=this.handles.eq(1),this.$input2=this.inputs.length?this.inputs.eq(1):t("#"+this.$handle2.attr("aria-controls")),this.inputs[1]||(this.inputs=this.inputs.add(this.$input2)),e=!0,this._setHandlePos(this.$handle,this.options.initialStart,!0,function(){i._setHandlePos(i.$handle2,i.options.initialEnd)}),this._setInitAttr(1),this._events(this.$handle2)),e||this._setHandlePos(this.$handle,this.options.initialStart,!0)},i.prototype._setHandlePos=function(t,i,s,o){i=parseFloat(i),ithis.options.end&&(i=this.options.end);var a=this.options.doubleSided;if(a)if(0===this.handles.index(t)){var r=parseFloat(this.$handle2.attr("aria-valuenow"));i=i>=r?r-this.options.step:i}else{var l=parseFloat(this.$handle.attr("aria-valuenow"));i=l>=i?l+this.options.step:i}this.options.vertical&&!s&&(i=this.options.end-i);var d=this,h=this.options.vertical,u=h?"height":"width",c=h?"top":"left",f=t[0].getBoundingClientRect()[u]/2,p=this.$element[0].getBoundingClientRect()[u],m=n(i,this.options.end).toFixed(2),g=(p-f)*m,v=(100*n(g,p)).toFixed(this.options.decimal),i=i>0?parseFloat(i.toFixed(this.options.decimal)):0,w={};if(this._setValues(t,i),this.options.doubleSided){var y,b=0===this.handles.index(t);this.handles.index(t);b?(w[c]=(m>0?100*m:0)+"%",y=(100*(n(this.$handle2.position()[c]+f,p)-parseFloat(m))).toFixed(this.options.decimal)+"%",w["min-"+u]=y,o&&"function"==typeof o&&o()):(i=(100>i?i:100)-(parseFloat(this.$handle[0].style.left)||this.options.end-i),w["min-"+u]=i+"%")}this.$element.one("finished.zf.animate",function(){d.animComplete=!0,d.$element.trigger("moved.zf.slider",[t])});var $=d.$element.data("dragging")?1e3/60:d.options.moveTime;e.Move($,t,function(){t.css(c,v+"%"),d.options.doubleSided?d.$fill.css(w):d.$fill.css(u,100*m+"%")})},i.prototype._setInitAttr=function(t){var i=this.inputs.eq(t).attr("id")||e.GetYoDigits(6,"slider");this.inputs.eq(t).attr({id:i,max:this.options.end,min:this.options.start}),this.handles.eq(t).attr({role:"slider","aria-controls":i,"aria-valuemax":this.options.end,"aria-valuemin":this.options.start,"aria-valuenow":0===t?this.options.initialStart:this.options.initialEnd,"aria-orientation":this.options.vertical?"vertical":"horizontal",tabindex:0})},i.prototype._setValues=function(t,e){var i=this.options.doubleSided?this.handles.index(t):0;this.inputs.eq(i).val(e),t.attr("aria-valuenow",e)},i.prototype._handleEvent=function(t,e,i){var o,a;if(i)o=i,a=!0;else{t.preventDefault();var r=this.options.vertical,l=r?"height":"width",d=r?"top":"left",h=r?t.pageY:t.pageX,u=this.$handle[0].getBoundingClientRect()[l]/2,c=this.$element[0].getBoundingClientRect()[l],f=this.$element.offset()[d]-h,p=f>0?-u:-c>f-u?c:Math.abs(f),m=n(p,c);if(o=(this.options.end-this.options.start)*m,a=!1,!e){var g=s(this.$handle,d,p,l),v=s(this.$handle2,d,p,l);e=v>=g?this.$handle:this.$handle2}}this._setHandlePos(e,o,a)},i.prototype._events=function(i){if(this.options.disabled)return!1;var n,s=this;if(this.inputs.off("change.zf.slider").on("change.zf.slider",function(e){var i=s.inputs.index(t(this));s._handleEvent(e,s.handles.eq(i),t(this).val())}),this.options.clickSelect&&this.$element.off("click.zf.slider").on("click.zf.slider",function(t){return s.$element.data("dragging")?!1:(s.animComplete=!1,void(s.options.doubleSided?s._handleEvent(t):s._handleEvent(t,s.$handle)))}),this.options.draggable){this.handles.addTouch();var o=t("body");i.off("mousedown.zf.slider").on("mousedown.zf.slider",function(e){i.addClass("is-dragging"),s.$fill.addClass("is-dragging"),s.$element.data("dragging",!0),s.animComplete=!1,n=t(e.currentTarget),o.on("mousemove.zf.slider",function(t){t.preventDefault(),s._handleEvent(t,n)}).on("mouseup.zf.slider",function(t){s.animComplete=!0,s._handleEvent(t,n),i.removeClass("is-dragging"),s.$fill.removeClass("is-dragging"),s.$element.data("dragging",!1),o.off("mousemove.zf.slider mouseup.zf.slider")})})}i.off("keydown.zf.slider").on("keydown.zf.slider",function(i){var n,o=s.options.doubleSided?s.handles.index(t(this)):0,a=parseFloat(s.inputs.eq(o).val()),r=t(this);e.Keyboard.handleKey(i,s,{decrease:function(){n=a-s.options.step},increase:function(){n=a+s.options.step},decrease_fast:function(){n=a-10*s.options.step},increase_fast:function(){n=a+10*s.options.step},handled:function(){i.preventDefault(),s._setHandlePos(r,n,!0)}})})},i.prototype.destroy=function(){this.handles.off(".zf.slider"),this.inputs.off(".zf.slider"),this.$element.off(".zf.slider"),e.unregisterPlugin(this)},e.plugin(i,"Slider")}(jQuery,window.Foundation),!function(t,e){"use strict";function i(n,s){this.$element=n,this.options=t.extend({},i.defaults,this.$element.data(),s),this._init(),e.registerPlugin(this)}function n(t){return parseInt(window.getComputedStyle(document.body,null).fontSize,10)*t}i.defaults={container:"
    ",stickTo:"top",anchor:"",topAnchor:"",btmAnchor:"",marginTop:1,marginBottom:1,stickyOn:"medium",stickyClass:"sticky",containerClass:"sticky-container",checkEvery:-1},i.prototype._init=function(){var i=this.$element.parent("[data-sticky-container]"),n=this.$element[0].id||e.GetYoDigits(6,"sticky"),s=this;i.length||(this.wasWrapped=!0),this.$container=i.length?i:t(this.options.container).wrapInner(this.$element),this.$container.addClass(this.options.containerClass),this.$element.addClass(this.options.stickyClass).attr({"data-resize":n}),this.scrollCount=this.options.checkEvery,this.isStuck=!1,""!==this.options.topAnchor?this._parsePoints():this.$anchor=t(this.options.anchor?"#"+this.options.anchor:document.body),this._setSizes(function(){s._calc(!1)}),this._events(n.split("-").reverse().join("-"))},i.prototype._parsePoints=function(){for(var e=this.options.topAnchor,i=this.options.btmAnchor,n=[e,i],s={},o=0,a=n.length;a>o&&n[o];o++){var r;if("number"==typeof n[o])r=n[o];else{var l=n[o].split(":"),d=t("#"+l[0]);r=d.offset().top,l[1]&&"bottom"===l[1].toLowerCase()&&(r+=d[0].getBoundingClientRect().height)}s[o]=r}this.points=s},i.prototype._events=function(e){var i=this,n="scroll.zf."+e;this.isOn||(this.canStick&&(this.isOn=!0,t(window).off(n).on(n,function(t){0===i.scrollCount?(i.scrollCount=i.options.checkEvery,i._setSizes(function(){i._calc(!1,window.pageYOffset)})):(i.scrollCount--,i._calc(!1,window.pageYOffset))})),this.$element.off("resizeme.zf.trigger").on("resizeme.zf.trigger",function(t,s){i._setSizes(function(){i._calc(!1),i.canStick?i.isOn||i._events(e):i.isOn&&i._pauseListeners(n)})}))},i.prototype._pauseListeners=function(e){this.isOn=!1,t(window).off(e),this.$element.trigger("pause.zf.sticky")},i.prototype._calc=function(t,e){return t&&this._setSizes(),this.canStick?(e||(e=window.pageYOffset),void(e>=this.topPoint?e<=this.bottomPoint?this.isStuck||this._setSticky():this.isStuck&&this._removeSticky(!1):this.isStuck&&this._removeSticky(!0))):(this.isStuck&&this._removeSticky(!0),!1)},i.prototype._setSticky=function(){var t=this.options.stickTo,e="top"===t?"marginTop":"marginBottom",i="top"===t?"bottom":"top",n={};n[e]=this.options[e]+"em",n[t]=0,n[i]="auto",n.left=this.$container.offset().left+parseInt(window.getComputedStyle(this.$container[0])["padding-left"],10),this.isStuck=!0,this.$element.removeClass("is-anchored is-at-"+i).addClass("is-stuck is-at-"+t).css(n).trigger("sticky.zf.stuckto:"+t)},i.prototype._removeSticky=function(t){var e=this.options.stickTo,i="top"===e,n={},s=(this.points?this.points[1]-this.points[0]:this.anchorHeight)-this.elemHeight,o=i?"marginTop":"marginBottom",a=i?"bottom":"top",r=t?"top":"bottom";n[o]=0,t&&!i||i&&!t?(n[e]=s,n[a]=0):(n[e]=0,n[a]=s),n.left="",this.isStuck=!1,this.$element.removeClass("is-stuck is-at-"+e).addClass("is-anchored is-at-"+r).css(n).trigger("sticky.zf.unstuckfrom:"+r)},i.prototype._setSizes=function(t){this.canStick=e.MediaQuery.atLeast(this.options.stickyOn),this.canStick||t();var i=this.$container[0].getBoundingClientRect().width,n=window.getComputedStyle(this.$container[0]),s=parseInt(n["padding-right"],10);this.$anchor&&this.$anchor.length?this.anchorHeight=this.$anchor[0].getBoundingClientRect().height:this._parsePoints(),this.$element.css({"max-width":i-s+"px"});var o=this.$element[0].getBoundingClientRect().height||this.containerHeight;this.containerHeight=o,this.$container.css({height:o}),this.elemHeight=o,this.isStuck&&this.$element.css({left:this.$container.offset().left+parseInt(n["padding-left"],10)}),this._setBreakPoints(o,function(){t&&t()})},i.prototype._setBreakPoints=function(t,e){if(!this.canStick){if(!e)return!1;e()}var i=n(this.options.marginTop),s=n(this.options.marginBottom),o=this.points?this.points[0]:this.$anchor.offset().top,a=this.points?this.points[1]:o+this.anchorHeight,r=window.innerHeight;"top"===this.options.stickTo?(o-=i,a-=t+i):"bottom"===this.options.stickTo&&(o-=r-(t+s),a-=r-s),this.topPoint=o,this.bottomPoint=a,e&&e()},i.prototype.destroy=function(){this._removeSticky(!0),this.$element.removeClass(this.options.stickyClass+" is-anchored is-at-top").css({height:"",top:"",bottom:"","max-width":""}).off("resizeme.zf.trigger"),this.$anchor.off("change.zf.sticky"),t(window).off("scroll.zf.sticky"),this.wasWrapped?this.$element.unwrap():this.$container.removeClass(this.options.containerClass).css({height:""}),e.unregisterPlugin(this)},e.plugin(i,"Sticky")}(jQuery,window.Foundation),!function(t,e){"use strict";function i(n,s){this.$element=n,this.options=t.extend({},i.defaults,this.$element.data(),s),this._init(),e.registerPlugin(this),e.Keyboard.register("Tabs",{ENTER:"open",SPACE:"open",ARROW_RIGHT:"next",ARROW_UP:"previous",ARROW_DOWN:"next",ARROW_LEFT:"previous"})}i.defaults={autoFocus:!1,wrapOnKeys:!0,matchHeight:!1,linkClass:"tabs-title",panelClass:"tabs-panel"},i.prototype._init=function(){var i=this;if(this.$tabTitles=this.$element.find("."+this.options.linkClass),this.$tabContent=t('[data-tabs-content="'+this.$element[0].id+'"]'),this.$tabTitles.each(function(){var e=t(this),n=e.find("a"),s=e.hasClass("is-active"),o=n.attr("href").slice(1),a=o+"-label",r=t(o);e.attr({role:"presentation"}),n.attr({role:"tab","aria-controls":o,"aria-selected":s,id:a}),r.attr({role:"tabpanel","aria-hidden":!s,"aria-labelledby":a}),s&&i.options.autoFocus&&n.focus()}),this.options.matchHeight){var n=this.$tabContent.find("img");n.length?e.onImagesLoaded(n,this._setHeight.bind(this)):this._setHeight()}this._events()},i.prototype._events=function(){this._addKeyHandler(),this._addClickHandler(),this.options.matchHeight&&t(window).on("changed.zf.mediaquery",this._setHeight.bind(this))},i.prototype._addClickHandler=function(){var e=this;this.$element.off("click.zf.tabs").on("click.zf.tabs","."+this.options.linkClass,function(i){i.preventDefault(),i.stopPropagation(),t(this).hasClass("is-active")||e._handleTabChange(t(this))})},i.prototype._addKeyHandler=function(){var i=this;i.$element.find("li:first-of-type"),i.$element.find("li:last-of-type");this.$tabTitles.off("keydown.zf.tabs").on("keydown.zf.tabs",function(n){if(9!==n.which){n.stopPropagation(),n.preventDefault();var s,o,a=t(this),r=a.parent("ul").children("li");r.each(function(e){return t(this).is(a)?void(i.options.wrapOnKeys?(s=0===e?r.last():r.eq(e-1),o=e===r.length-1?r.first():r.eq(e+1)):(s=r.eq(Math.max(0,e-1)),o=r.eq(Math.min(e+1,r.length-1)))):void 0}),e.Keyboard.handleKey(n,i,{open:function(){a.find('[role="tab"]').focus(),i._handleTabChange(a)},previous:function(){s.find('[role="tab"]').focus(),i._handleTabChange(s)},next:function(){o.find('[role="tab"]').focus(),i._handleTabChange(o)}})}})},i.prototype._handleTabChange=function(e){var i=e.find('[role="tab"]'),n=i.attr("href"),s=t(n),o=this.$element.find("."+this.options.linkClass+".is-active").removeClass("is-active").find('[role="tab"]').attr({"aria-selected":"false"}).attr("href");t(o).removeClass("is-active").attr({"aria-hidden":"true"}),e.addClass("is-active"),i.attr({"aria-selected":"true"}),s.addClass("is-active").attr({"aria-hidden":"false"}),this.$element.trigger("change.zf.tabs",[e])},i.prototype.selectTab=function(t){var e;e="object"==typeof t?t[0].id:t,e.indexOf("#")<0&&(e="#"+e);var i=this.$tabTitles.find('[href="'+e+'"]').parent("."+this.options.linkClass);this._handleTabChange(i)},i.prototype._setHeight=function(){var e=0;this.$tabContent.find("."+this.options.panelClass).css("height","").each(function(){var i=t(this),n=i.hasClass("is-active");n||i.css({visibility:"hidden",display:"block"});var s=this.getBoundingClientRect().height;n||i.css({visibility:"",display:""}),e=s>e?s:e}).css("height",e+"px")},i.prototype.destroy=function(){this.$element.find("."+this.options.linkClass).off(".zf.tabs").hide().end().find("."+this.options.panelClass).hide(),this.options.matchHeight&&t(window).off("changed.zf.mediaquery"),e.unregisterPlugin(this)},e.plugin(i,"Tabs")}(jQuery,window.Foundation),!function(t,e){"use strict";function i(n,s){this.$element=n,this.options=e.extend({},i.defaults,n.data(),s),this.className="",this._init(),this._events(),t.registerPlugin(this)}i.defaults={animate:!1},i.prototype._init=function(){var t;this.options.animate?(t=this.options.animate.split(" "),this.animationIn=t[0],this.animationOut=t[1]||null):(t=this.$element.data("toggler"),this.className="."===t[0]?t.slice(1):t);var i=this.$element[0].id;e('[data-open="'+i+'"], [data-close="'+i+'"], [data-toggle="'+i+'"]').attr("aria-controls",i),this.$element.attr("aria-expanded",this.$element.is(":hidden")?!1:!0)},i.prototype._events=function(){this.$element.off("toggle.zf.trigger").on("toggle.zf.trigger",this.toggle.bind(this))},i.prototype.toggle=function(){this[this.options.animate?"_toggleAnimate":"_toggleClass"]()},i.prototype._toggleClass=function(){this.$element.toggleClass(this.className);var t=this.$element.hasClass(this.className);t?this.$element.trigger("on.zf.toggler"):this.$element.trigger("off.zf.toggler"),this._updateARIA(t)},i.prototype._toggleAnimate=function(){var e=this;this.$element.is(":hidden")?t.Motion.animateIn(this.$element,this.animationIn,function(){this.trigger("on.zf.toggler"),e._updateARIA(!0)}):t.Motion.animateOut(this.$element,this.animationOut,function(){this.trigger("off.zf.toggler"),e._updateARIA(!1)})},i.prototype._updateARIA=function(t){this.$element.attr("aria-expanded",t?!0:!1)},i.prototype.destroy=function(){this.$element.off(".zf.toggler"),t.unregisterPlugin(this)},t.plugin(i,"Toggler"),"undefined"!=typeof module&&"undefined"!=typeof module.exports&&(module.exports=i),"function"==typeof define&&define(["foundation"],function(){return i})}(Foundation,jQuery),!function(t,e,i){"use strict";function n(e,s){this.$element=e,this.options=t.extend({},n.defaults,this.$element.data(),s),this.isActive=!1,this.isClick=!1,this._init(),i.registerPlugin(this)}n.defaults={disableForTouch:!1,hoverDelay:200,fadeInDuration:150,fadeOutDuration:150,disableHover:!1,templateClasses:"",tooltipClass:"tooltip",triggerClass:"has-tip",showOn:"small",template:"",tipText:"",touchCloseText:"Tap to close.",clickOpen:!0,positionClass:"",vOffset:10,hOffset:12},n.prototype._init=function(){var n=this.$element.attr("aria-describedby")||i.GetYoDigits(6,"tooltip");this.options.positionClass=this._getPositionClass(this.$element),this.options.tipText=this.options.tipText||this.$element.attr("title"),this.template=this.options.template?t(this.options.template):this._buildTemplate(n),this.template.appendTo(e.body).text(this.options.tipText).hide(),this.$element.attr({title:"","aria-describedby":n,"data-yeti-box":n,"data-toggle":n,"data-resize":n}).addClass(this.triggerClass),this.usedPositions=[],this.counter=4,this.classChanged=!1,this._events()},n.prototype._getPositionClass=function(t){if(!t)return"";var e=t[0].className.match(/(top|left|right)/g);return e=e?e[0]:""},n.prototype._buildTemplate=function(e){var i=(this.options.tooltipClass+" "+this.options.positionClass).trim(),n=t("
    ").addClass(i).attr({role:"tooltip","aria-hidden":!0,"data-is-active":!1,"data-is-focus":!1,id:e});return n},n.prototype._reposition=function(t){this.usedPositions.push(t?t:"bottom"),!t&&this.usedPositions.indexOf("top")<0?this.template.addClass("top"):"top"===t&&this.usedPositions.indexOf("bottom")<0?this.template.removeClass(t):"left"===t&&this.usedPositions.indexOf("right")<0?this.template.removeClass(t).addClass("right"):"right"===t&&this.usedPositions.indexOf("left")<0?this.template.removeClass(t).addClass("left"):!t&&this.usedPositions.indexOf("top")>-1&&this.usedPositions.indexOf("left")<0?this.template.addClass("left"):"top"===t&&this.usedPositions.indexOf("bottom")>-1&&this.usedPositions.indexOf("left")<0?this.template.removeClass(t).addClass("left"):"left"===t&&this.usedPositions.indexOf("right")>-1&&this.usedPositions.indexOf("bottom")<0?this.template.removeClass(t):"right"===t&&this.usedPositions.indexOf("left")>-1&&this.usedPositions.indexOf("bottom")<0?this.template.removeClass(t):this.template.removeClass(t),this.classChanged=!0,this.counter--},n.prototype._setPosition=function(){var t=this._getPositionClass(this.template),e=i.Box.GetDimensions(this.template),n=i.Box.GetDimensions(this.$element),s="left"===t?"left":"right"===t?"left":"top",o="top"===s?"height":"width";"height"===o?this.options.vOffset:this.options.hOffset;if(e.width>=e.windowDims.width||!this.counter&&!i.Box.ImNotTouchingYou(this.template))return this.template.offset(i.Box.GetOffsets(this.template,this.$element,"center bottom",this.options.vOffset,this.options.hOffset,!0)).css({width:n.windowDims.width-2*this.options.hOffset,height:"auto"}),!1;for(this.template.offset(i.Box.GetOffsets(this.template,this.$element,"center "+(t||"bottom"),this.options.vOffset,this.options.hOffset));!i.Box.ImNotTouchingYou(this.template)&&this.counter;)this._reposition(t),this._setPosition()},n.prototype.show=function(){if("all"!==this.options.showOn&&!i.MediaQuery.atLeast(this.options.showOn))return!1;var t=this;this.template.css("visibility","hidden").show(),this._setPosition(),this.$element.trigger("closeme.zf.tooltip",this.template.attr("id")),this.template.attr({"data-is-active":!0,"aria-hidden":!1}),t.isActive=!0,this.template.stop().hide().css("visibility","").fadeIn(this.options.fadeInDuration,function(){}),this.$element.trigger("show.zf.tooltip")},n.prototype.hide=function(){var t=this;this.template.stop().attr({"aria-hidden":!0,"data-is-active":!1}).fadeOut(this.options.fadeOutDuration,function(){t.isActive=!1,t.isClick=!1,t.classChanged&&(t.template.removeClass(t._getPositionClass(t.template)).addClass(t.options.positionClass),t.usedPositions=[],t.counter=4,t.classChanged=!1)}),this.$element.trigger("hide.zf.tooltip")},n.prototype._events=function(){var t=this,e=(this.template,!1);this.options.disableHover||this.$element.on("mouseenter.zf.tooltip",function(e){t.isActive||(t.timeout=setTimeout(function(){t.show()},t.options.hoverDelay))}).on("mouseleave.zf.tooltip",function(i){clearTimeout(t.timeout),(!e||!t.isClick&&t.options.clickOpen)&&t.hide()}),this.options.clickOpen&&this.$element.on("mousedown.zf.tooltip",function(e){e.stopImmediatePropagation(),t.isClick?t.hide():(t.isClick=!0,!t.options.disableHover&&t.$element.attr("tabindex")||t.isActive||t.show())}),this.options.disableForTouch||this.$element.on("tap.zf.tooltip touchend.zf.tooltip",function(e){t.isActive?t.hide():t.show()}),this.$element.on({"close.zf.trigger":this.hide.bind(this)}),this.$element.on("focus.zf.tooltip",function(i){return e=!0,console.log(t.isClick),t.isClick?!1:void t.show()}).on("focusout.zf.tooltip",function(i){e=!1,t.isClick=!1,t.hide()}).on("resizeme.zf.trigger",function(){t.isActive&&t._setPosition()})},n.prototype.toggle=function(){this.isActive?this.hide():this.show()},n.prototype.destroy=function(){this.$element.attr("title",this.template.text()).off(".zf.trigger .zf.tootip").removeAttr("aria-describedby").removeAttr("data-yeti-box").removeAttr("data-toggle").removeAttr("data-resize"),this.template.remove(),i.unregisterPlugin(this)},i.plugin(n,"Tooltip")}(jQuery,window.document,window.Foundation); \ No newline at end of file diff --git a/js/vendor/jquery.min.js b/js/vendor/jquery.min.js new file mode 100644 index 0000000..fad9ab1 --- /dev/null +++ b/js/vendor/jquery.min.js @@ -0,0 +1,5 @@ +/*! jQuery v2.1.4 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b="length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){ +return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,ba=/<([\w:]+)/,ca=/<|&#?\w+;/,da=/<(?:script|style|link)/i,ea=/checked\s*(?:[^=]|=\s*.checked.)/i,fa=/^$|\/(?:java|ecma)script/i,ga=/^true\/(.*)/,ha=/^\s*\s*$/g,ia={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};ia.optgroup=ia.option,ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead,ia.th=ia.td;function ja(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function ka(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function la(a){var b=ga.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function ma(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function na(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function oa(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pa(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=oa(h),f=oa(a),d=0,e=f.length;e>d;d++)pa(f[d],g[d]);if(b)if(c)for(f=f||oa(a),g=g||oa(h),d=0,e=f.length;e>d;d++)na(f[d],g[d]);else na(a,h);return g=oa(h,"script"),g.length>0&&ma(g,!i&&oa(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(ca.test(e)){f=f||k.appendChild(b.createElement("div")),g=(ba.exec(e)||["",""])[1].toLowerCase(),h=ia[g]||ia._default,f.innerHTML=h[1]+e.replace(aa,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=oa(k.appendChild(e),"script"),i&&ma(f),c)){j=0;while(e=f[j++])fa.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(oa(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&ma(oa(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(oa(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!da.test(a)&&!ia[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(aa,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(oa(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(oa(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&ea.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(oa(c,"script"),ka),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,oa(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,la),j=0;g>j;j++)h=f[j],fa.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(ha,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qa,ra={};function sa(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function ta(a){var b=l,c=ra[a];return c||(c=sa(a,b),"none"!==c&&c||(qa=(qa||n("