diff --git a/.gitignore b/.gitignore index 35805828f8c28329583bd73e63e759dcf4bb9bac..f465a798f8c5123fa51dec28a139b4bda0fafc4a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,16 @@ # SR User Related # ###################### -cache/* cache/ +Logs/ +restore/ +backup/ cache.db* config.ini* -Logs/* sickbeard.db* failed.db* autoProcessTV/autoProcessTV.cfg server.crt server.key -restore/ # SR Test Related # ###################### diff --git a/SickBeard.py b/SickBeard.py index 8f0f0de5876c6d778461b126763f6911a87cc430..a5456a42a30ec8709ab35008ff577b49cda04dbd 100755 --- a/SickBeard.py +++ b/SickBeard.py @@ -20,6 +20,9 @@ # Check needed software dependencies to nudge users to fix their setup from __future__ import with_statement +import codecs +codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None) + import time import signal import sys @@ -142,6 +145,10 @@ class SickRage(object): if not hasattr(sys, "setdefaultencoding"): reload(sys) + + if sys.platform == 'win32': + if sys.getwindowsversion()[0] >= 6 and sys.stdout.encoding == 'cp65001': + sickbeard.SYS_ENCODING = 'UTF-8' try: # pylint: disable=E1101 @@ -262,12 +269,15 @@ class SickRage(object): os.chdir(sickbeard.DATA_DIR) # Check if we need to perform a restore first - restoreDir = os.path.join(sickbeard.DATA_DIR, 'restore') - if self.consoleLogging and os.path.exists(restoreDir): - if self.restore(restoreDir, sickbeard.DATA_DIR): - sys.stdout.write("Restore successful...\n") - else: - sys.stdout.write("Restore FAILED!\n") + try: + restoreDir = os.path.join(sickbeard.DATA_DIR, 'restore') + if self.consoleLogging and os.path.exists(restoreDir): + if self.restoreDB(restoreDir, sickbeard.DATA_DIR): + sys.stdout.write("Restore: restoring DB and config.ini successful...\n") + else: + sys.stdout.write("Restore: restoring DB and config.ini FAILED!\n") + except Exception as e: + sys.stdout.write("Restore: restoring DB and config.ini FAILED!\n") # Load the config and publish it to the sickbeard package if self.consoleLogging and not os.path.isfile(sickbeard.CONFIG_FILE): @@ -447,16 +457,17 @@ class SickRage(object): logger.ERROR) logger.log(traceback.format_exc(), logger.DEBUG) - def restore(self, srcDir, dstDir): + def restoreDB(self, srcDir, dstDir): try: - for file in os.listdir(srcDir): - srcFile = os.path.join(srcDir, file) - dstFile = os.path.join(dstDir, file) - bakFile = os.path.join(dstDir, file + '.bak') - shutil.move(dstFile, bakFile) + filesList = ['sickbeard.db', 'config.ini', 'failed.db', 'cache.db'] + + for filename in filesList: + srcFile = os.path.join(srcDir, filename) + dstFile = os.path.join(dstDir, filename) + bakFile = os.path.join(dstDir, '{0}.bak-{1}'.format(filename, datetime.datetime.strftime(datetime.datetime.now(), '%Y%m%d_%H%M%S'))) + if os.path.isfile(dstFile): + shutil.move(dstFile, bakFile) shutil.move(srcFile, dstFile) - - os.rmdir(srcDir) return True except: return False diff --git a/gui/slick/css/lib/bootstrap-formhelpers-2.3.0.css b/gui/slick/css/lib/bootstrap-formhelpers-2.3.0.css new file mode 100644 index 0000000000000000000000000000000000000000..2def9b4873113d65763e66df654cc7b5e1aeb64e --- /dev/null +++ b/gui/slick/css/lib/bootstrap-formhelpers-2.3.0.css @@ -0,0 +1,2140 @@ +/** +* bootstrap-formhelpers.js v2.3.0 by @vincentlamanna +* Copyright 2013 Vincent Lamanna +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +.bfh-flag-AD, +.bfh-flag-AE, +.bfh-flag-AF, +.bfh-flag-AG, +.bfh-flag-AI, +.bfh-flag-AL, +.bfh-flag-AM, +.bfh-flag-AN, +.bfh-flag-AO, +.bfh-flag-AQ, +.bfh-flag-AR, +.bfh-flag-AS, +.bfh-flag-AT, +.bfh-flag-AU, +.bfh-flag-AW, +.bfh-flag-AX, +.bfh-flag-AZ, +.bfh-flag-BA, +.bfh-flag-BB, +.bfh-flag-BD, +.bfh-flag-BE, +.bfh-flag-BG, +.bfh-flag-BH, +.bfh-flag-BI, +.bfh-flag-BJ, +.bfh-flag-BL, +.bfh-flag-BM, +.bfh-flag-BN, +.bfh-flag-BO, +.bfh-flag-BR, +.bfh-flag-BS, +.bfh-flag-BT, +.bfh-flag-BW, +.bfh-flag-BY, +.bfh-flag-BZ, +.bfh-flag-CA, +.bfh-flag-CD, +.bfh-flag-CF, +.bfh-flag-CG, +.bfh-flag-CH, +.bfh-flag-CI, +.bfh-flag-CL, +.bfh-flag-CM, +.bfh-flag-CN, +.bfh-flag-CO, +.bfh-flag-CR, +.bfh-flag-CV, +.bfh-flag-CY, +.bfh-flag-CZ, +.bfh-flag-DJ, +.bfh-flag-DK, +.bfh-flag-DM, +.bfh-flag-DO, +.bfh-flag-DZ, +.bfh-flag-EC, +.bfh-flag-EE, +.bfh-flag-EG, +.bfh-flag-EH, +.bfh-flag-ER, +.bfh-flag-ES, +.bfh-flag-ET, +.bfh-flag-EU, +.bfh-flag-FI, +.bfh-flag-FJ, +.bfh-flag-FK, +.bfh-flag-FM, +.bfh-flag-FO, +.bfh-flag-FR, +.bfh-flag-FX, +.bfh-flag-GF, +.bfh-flag-GP, +.bfh-flag-MQ, +.bfh-flag-NC, +.bfh-flag-PF, +.bfh-flag-PM, +.bfh-flag-RE, +.bfh-flag-TF, +.bfh-flag-WF, +.bfh-flag-GA, +.bfh-flag-GB, +.bfh-flag-GD, +.bfh-flag-GE, +.bfh-flag-GG, +.bfh-flag-GH, +.bfh-flag-GL, +.bfh-flag-GM, +.bfh-flag-GN, +.bfh-flag-GQ, +.bfh-flag-GR, +.bfh-flag-GS, +.bfh-flag-GT, +.bfh-flag-GU, +.bfh-flag-GW, +.bfh-flag-GY, +.bfh-flag-HK, +.bfh-flag-HN, +.bfh-flag-HR, +.bfh-flag-HT, +.bfh-flag-HU, +.bfh-flag-ID, +.bfh-flag-IE, +.bfh-flag-IL, +.bfh-flag-IM, +.bfh-flag-IN, +.bfh-flag-IQ, +.bfh-flag-IS, +.bfh-flag-IT, +.bfh-flag-JE, +.bfh-flag-JM, +.bfh-flag-JO, +.bfh-flag-JP, +.bfh-flag-KE, +.bfh-flag-KG, +.bfh-flag-KH, +.bfh-flag-KI, +.bfh-flag-KM, +.bfh-flag-KN, +.bfh-flag-KP, +.bfh-flag-KR, +.bfh-flag-KV, +.bfh-flag-KW, +.bfh-flag-KY, +.bfh-flag-LA, +.bfh-flag-LC, +.bfh-flag-LK, +.bfh-flag-LR, +.bfh-flag-LS, +.bfh-flag-LT, +.bfh-flag-LU, +.bfh-flag-LV, +.bfh-flag-LY, +.bfh-flag-MA, +.bfh-flag-ME, +.bfh-flag-MG, +.bfh-flag-MH, +.bfh-flag-ML, +.bfh-flag-MM, +.bfh-flag-MP, +.bfh-flag-MR, +.bfh-flag-MS, +.bfh-flag-MT, +.bfh-flag-MU, +.bfh-flag-MV, +.bfh-flag-MW, +.bfh-flag-MZ, +.bfh-flag-NA, +.bfh-flag-NE, +.bfh-flag-NF, +.bfh-flag-NG, +.bfh-flag-NI, +.bfh-flag-NL, +.bfh-flag-NO, +.bfh-flag-NP, +.bfh-flag-NR, +.bfh-flag-NZ, +.bfh-flag-OM, +.bfh-flag-PA, +.bfh-flag-PE, +.bfh-flag-PG, +.bfh-flag-PH, +.bfh-flag-PK, +.bfh-flag-PL, +.bfh-flag-PN, +.bfh-flag-PS, +.bfh-flag-PT, +.bfh-flag-PW, +.bfh-flag-PY, +.bfh-flag-QA, +.bfh-flag-RS, +.bfh-flag-RU, +.bfh-flag-RW, +.bfh-flag-SA, +.bfh-flag-SB, +.bfh-flag-SC, +.bfh-flag-SD, +.bfh-flag-SE, +.bfh-flag-SG, +.bfh-flag-SH, +.bfh-flag-SI, +.bfh-flag-SK, +.bfh-flag-SM, +.bfh-flag-SN, +.bfh-flag-SO, +.bfh-flag-SR, +.bfh-flag-SS, +.bfh-flag-ST, +.bfh-flag-SV, +.bfh-flag-SY, +.bfh-flag-SZ, +.bfh-flag-TC, +.bfh-flag-TD, +.bfh-flag-TG, +.bfh-flag-TH, +.bfh-flag-TJ, +.bfh-flag-TM, +.bfh-flag-TN, +.bfh-flag-TP, +.bfh-flag-TR, +.bfh-flag-TT, +.bfh-flag-TV, +.bfh-flag-TW, +.bfh-flag-TZ, +.bfh-flag-UA, +.bfh-flag-UG, +.bfh-flag-US, +.bfh-flag-UY, +.bfh-flag-UZ, +.bfh-flag-VC, +.bfh-flag-VE, +.bfh-flag-VG, +.bfh-flag-VI, +.bfh-flag-VN, +.bfh-flag-VU, +.bfh-flag-WS, +.bfh-flag-YE, +.bfh-flag-ZA, +.bfh-flag-ZM, +.bfh-flag-BF, +.bfh-flag-CU, +.bfh-flag-DE, +.bfh-flag-IR, +.bfh-flag-KZ, +.bfh-flag-LB, +.bfh-flag-LI, +.bfh-flag-MC, +.bfh-flag-MD, +.bfh-flag-MK, +.bfh-flag-MN, +.bfh-flag-MO, +.bfh-flag-MX, +.bfh-flag-MY, +.bfh-flag-PR, +.bfh-flag-RO, +.bfh-flag-SL, +.bfh-flag-TO, +.bfh-flag-VA, +.bfh-flag-ZW { + width: 16px; + height: 14px; + background: url(../img/bootstrap-formhelpers-countries.flags.png) no-repeat; +} + +.bfh-flag-AD:empty, +.bfh-flag-AE:empty, +.bfh-flag-AF:empty, +.bfh-flag-AG:empty, +.bfh-flag-AI:empty, +.bfh-flag-AL:empty, +.bfh-flag-AM:empty, +.bfh-flag-AN:empty, +.bfh-flag-AO:empty, +.bfh-flag-AQ:empty, +.bfh-flag-AR:empty, +.bfh-flag-AS:empty, +.bfh-flag-AT:empty, +.bfh-flag-AU:empty, +.bfh-flag-AW:empty, +.bfh-flag-AX:empty, +.bfh-flag-AZ:empty, +.bfh-flag-BA:empty, +.bfh-flag-BB:empty, +.bfh-flag-BD:empty, +.bfh-flag-BE:empty, +.bfh-flag-BG:empty, +.bfh-flag-BH:empty, +.bfh-flag-BI:empty, +.bfh-flag-BJ:empty, +.bfh-flag-BL:empty, +.bfh-flag-BM:empty, +.bfh-flag-BN:empty, +.bfh-flag-BO:empty, +.bfh-flag-BR:empty, +.bfh-flag-BS:empty, +.bfh-flag-BT:empty, +.bfh-flag-BW:empty, +.bfh-flag-BY:empty, +.bfh-flag-BZ:empty, +.bfh-flag-CA:empty, +.bfh-flag-CD:empty, +.bfh-flag-CF:empty, +.bfh-flag-CG:empty, +.bfh-flag-CH:empty, +.bfh-flag-CI:empty, +.bfh-flag-CL:empty, +.bfh-flag-CM:empty, +.bfh-flag-CN:empty, +.bfh-flag-CO:empty, +.bfh-flag-CR:empty, +.bfh-flag-CV:empty, +.bfh-flag-CY:empty, +.bfh-flag-CZ:empty, +.bfh-flag-DJ:empty, +.bfh-flag-DK:empty, +.bfh-flag-DM:empty, +.bfh-flag-DO:empty, +.bfh-flag-DZ:empty, +.bfh-flag-EC:empty, +.bfh-flag-EE:empty, +.bfh-flag-EG:empty, +.bfh-flag-EH:empty, +.bfh-flag-ER:empty, +.bfh-flag-ES:empty, +.bfh-flag-ET:empty, +.bfh-flag-EU:empty, +.bfh-flag-FI:empty, +.bfh-flag-FJ:empty, +.bfh-flag-FK:empty, +.bfh-flag-FM:empty, +.bfh-flag-FO:empty, +.bfh-flag-FR:empty, +.bfh-flag-FX:empty, +.bfh-flag-GF:empty, +.bfh-flag-GP:empty, +.bfh-flag-MQ:empty, +.bfh-flag-NC:empty, +.bfh-flag-PF:empty, +.bfh-flag-PM:empty, +.bfh-flag-RE:empty, +.bfh-flag-TF:empty, +.bfh-flag-WF:empty, +.bfh-flag-GA:empty, +.bfh-flag-GB:empty, +.bfh-flag-GD:empty, +.bfh-flag-GE:empty, +.bfh-flag-GG:empty, +.bfh-flag-GH:empty, +.bfh-flag-GL:empty, +.bfh-flag-GM:empty, +.bfh-flag-GN:empty, +.bfh-flag-GQ:empty, +.bfh-flag-GR:empty, +.bfh-flag-GS:empty, +.bfh-flag-GT:empty, +.bfh-flag-GU:empty, +.bfh-flag-GW:empty, +.bfh-flag-GY:empty, +.bfh-flag-HK:empty, +.bfh-flag-HN:empty, +.bfh-flag-HR:empty, +.bfh-flag-HT:empty, +.bfh-flag-HU:empty, +.bfh-flag-ID:empty, +.bfh-flag-IE:empty, +.bfh-flag-IL:empty, +.bfh-flag-IM:empty, +.bfh-flag-IN:empty, +.bfh-flag-IQ:empty, +.bfh-flag-IS:empty, +.bfh-flag-IT:empty, +.bfh-flag-JE:empty, +.bfh-flag-JM:empty, +.bfh-flag-JO:empty, +.bfh-flag-JP:empty, +.bfh-flag-KE:empty, +.bfh-flag-KG:empty, +.bfh-flag-KH:empty, +.bfh-flag-KI:empty, +.bfh-flag-KM:empty, +.bfh-flag-KN:empty, +.bfh-flag-KP:empty, +.bfh-flag-KR:empty, +.bfh-flag-KV:empty, +.bfh-flag-KW:empty, +.bfh-flag-KY:empty, +.bfh-flag-LA:empty, +.bfh-flag-LC:empty, +.bfh-flag-LK:empty, +.bfh-flag-LR:empty, +.bfh-flag-LS:empty, +.bfh-flag-LT:empty, +.bfh-flag-LU:empty, +.bfh-flag-LV:empty, +.bfh-flag-LY:empty, +.bfh-flag-MA:empty, +.bfh-flag-ME:empty, +.bfh-flag-MG:empty, +.bfh-flag-MH:empty, +.bfh-flag-ML:empty, +.bfh-flag-MM:empty, +.bfh-flag-MP:empty, +.bfh-flag-MR:empty, +.bfh-flag-MS:empty, +.bfh-flag-MT:empty, +.bfh-flag-MU:empty, +.bfh-flag-MV:empty, +.bfh-flag-MW:empty, +.bfh-flag-MZ:empty, +.bfh-flag-NA:empty, +.bfh-flag-NE:empty, +.bfh-flag-NF:empty, +.bfh-flag-NG:empty, +.bfh-flag-NI:empty, +.bfh-flag-NL:empty, +.bfh-flag-NO:empty, +.bfh-flag-NP:empty, +.bfh-flag-NR:empty, +.bfh-flag-NZ:empty, +.bfh-flag-OM:empty, +.bfh-flag-PA:empty, +.bfh-flag-PE:empty, +.bfh-flag-PG:empty, +.bfh-flag-PH:empty, +.bfh-flag-PK:empty, +.bfh-flag-PL:empty, +.bfh-flag-PN:empty, +.bfh-flag-PS:empty, +.bfh-flag-PT:empty, +.bfh-flag-PW:empty, +.bfh-flag-PY:empty, +.bfh-flag-QA:empty, +.bfh-flag-RS:empty, +.bfh-flag-RU:empty, +.bfh-flag-RW:empty, +.bfh-flag-SA:empty, +.bfh-flag-SB:empty, +.bfh-flag-SC:empty, +.bfh-flag-SD:empty, +.bfh-flag-SE:empty, +.bfh-flag-SG:empty, +.bfh-flag-SH:empty, +.bfh-flag-SI:empty, +.bfh-flag-SK:empty, +.bfh-flag-SM:empty, +.bfh-flag-SN:empty, +.bfh-flag-SO:empty, +.bfh-flag-SR:empty, +.bfh-flag-SS:empty, +.bfh-flag-ST:empty, +.bfh-flag-SV:empty, +.bfh-flag-SY:empty, +.bfh-flag-SZ:empty, +.bfh-flag-TC:empty, +.bfh-flag-TD:empty, +.bfh-flag-TG:empty, +.bfh-flag-TH:empty, +.bfh-flag-TJ:empty, +.bfh-flag-TM:empty, +.bfh-flag-TN:empty, +.bfh-flag-TP:empty, +.bfh-flag-TR:empty, +.bfh-flag-TT:empty, +.bfh-flag-TV:empty, +.bfh-flag-TW:empty, +.bfh-flag-TZ:empty, +.bfh-flag-UA:empty, +.bfh-flag-UG:empty, +.bfh-flag-US:empty, +.bfh-flag-UY:empty, +.bfh-flag-UZ:empty, +.bfh-flag-VC:empty, +.bfh-flag-VE:empty, +.bfh-flag-VG:empty, +.bfh-flag-VI:empty, +.bfh-flag-VN:empty, +.bfh-flag-VU:empty, +.bfh-flag-WS:empty, +.bfh-flag-YE:empty, +.bfh-flag-ZA:empty, +.bfh-flag-ZM:empty, +.bfh-flag-BF:empty, +.bfh-flag-CU:empty, +.bfh-flag-DE:empty, +.bfh-flag-IR:empty, +.bfh-flag-KZ:empty, +.bfh-flag-LB:empty, +.bfh-flag-LI:empty, +.bfh-flag-MC:empty, +.bfh-flag-MD:empty, +.bfh-flag-MK:empty, +.bfh-flag-MN:empty, +.bfh-flag-MO:empty, +.bfh-flag-MX:empty, +.bfh-flag-MY:empty, +.bfh-flag-PR:empty, +.bfh-flag-RO:empty, +.bfh-flag-SL:empty, +.bfh-flag-TO:empty, +.bfh-flag-VA:empty, +.bfh-flag-ZW:empty { + width: 16px; +} + +.bfh-flag-AD, +.bfh-flag-AE, +.bfh-flag-AF, +.bfh-flag-AG, +.bfh-flag-AI, +.bfh-flag-AL, +.bfh-flag-AM, +.bfh-flag-AN, +.bfh-flag-AO, +.bfh-flag-AQ, +.bfh-flag-AR, +.bfh-flag-AS, +.bfh-flag-AT, +.bfh-flag-AU, +.bfh-flag-AW, +.bfh-flag-AX, +.bfh-flag-AZ, +.bfh-flag-BA, +.bfh-flag-BB, +.bfh-flag-BD, +.bfh-flag-BE, +.bfh-flag-BG, +.bfh-flag-BH, +.bfh-flag-BI, +.bfh-flag-BJ, +.bfh-flag-BL, +.bfh-flag-BM, +.bfh-flag-BN, +.bfh-flag-BO, +.bfh-flag-BR, +.bfh-flag-BS, +.bfh-flag-BT, +.bfh-flag-BW, +.bfh-flag-BY, +.bfh-flag-BZ, +.bfh-flag-CA, +.bfh-flag-CD, +.bfh-flag-CF, +.bfh-flag-CG, +.bfh-flag-CH, +.bfh-flag-CI, +.bfh-flag-CL, +.bfh-flag-CM, +.bfh-flag-CN, +.bfh-flag-CO, +.bfh-flag-CR, +.bfh-flag-CV, +.bfh-flag-CY, +.bfh-flag-CZ, +.bfh-flag-DJ, +.bfh-flag-DK, +.bfh-flag-DM, +.bfh-flag-DO, +.bfh-flag-DZ, +.bfh-flag-EC, +.bfh-flag-EE, +.bfh-flag-EG, +.bfh-flag-EH, +.bfh-flag-ER, +.bfh-flag-ES, +.bfh-flag-ET, +.bfh-flag-EU, +.bfh-flag-FI, +.bfh-flag-FJ, +.bfh-flag-FK, +.bfh-flag-FM, +.bfh-flag-FO, +.bfh-flag-FR, +.bfh-flag-FX, +.bfh-flag-GF, +.bfh-flag-GP, +.bfh-flag-MQ, +.bfh-flag-NC, +.bfh-flag-PF, +.bfh-flag-PM, +.bfh-flag-RE, +.bfh-flag-TF, +.bfh-flag-WF, +.bfh-flag-GA, +.bfh-flag-GB, +.bfh-flag-GD, +.bfh-flag-GE, +.bfh-flag-GG, +.bfh-flag-GH, +.bfh-flag-GL, +.bfh-flag-GM, +.bfh-flag-GN, +.bfh-flag-GQ, +.bfh-flag-GR, +.bfh-flag-GS, +.bfh-flag-GT, +.bfh-flag-GU, +.bfh-flag-GW, +.bfh-flag-GY, +.bfh-flag-HK, +.bfh-flag-HN, +.bfh-flag-HR, +.bfh-flag-HT, +.bfh-flag-HU, +.bfh-flag-ID, +.bfh-flag-IE, +.bfh-flag-IL, +.bfh-flag-IM, +.bfh-flag-IN, +.bfh-flag-IQ, +.bfh-flag-IS, +.bfh-flag-IT, +.bfh-flag-JE, +.bfh-flag-JM, +.bfh-flag-JO, +.bfh-flag-JP, +.bfh-flag-KE, +.bfh-flag-KG, +.bfh-flag-KH, +.bfh-flag-KI, +.bfh-flag-KM, +.bfh-flag-KN, +.bfh-flag-KP, +.bfh-flag-KR, +.bfh-flag-KV, +.bfh-flag-KW, +.bfh-flag-KY, +.bfh-flag-LA, +.bfh-flag-LC, +.bfh-flag-LK, +.bfh-flag-LR, +.bfh-flag-LS, +.bfh-flag-LT, +.bfh-flag-LU, +.bfh-flag-LV, +.bfh-flag-LY, +.bfh-flag-MA, +.bfh-flag-ME, +.bfh-flag-MG, +.bfh-flag-MH, +.bfh-flag-ML, +.bfh-flag-MM, +.bfh-flag-MP, +.bfh-flag-MR, +.bfh-flag-MS, +.bfh-flag-MT, +.bfh-flag-MU, +.bfh-flag-MV, +.bfh-flag-MW, +.bfh-flag-MZ, +.bfh-flag-NA, +.bfh-flag-NE, +.bfh-flag-NF, +.bfh-flag-NG, +.bfh-flag-NI, +.bfh-flag-NL, +.bfh-flag-NO, +.bfh-flag-NP, +.bfh-flag-NR, +.bfh-flag-NZ, +.bfh-flag-OM, +.bfh-flag-PA, +.bfh-flag-PE, +.bfh-flag-PG, +.bfh-flag-PH, +.bfh-flag-PK, +.bfh-flag-PL, +.bfh-flag-PN, +.bfh-flag-PS, +.bfh-flag-PT, +.bfh-flag-PW, +.bfh-flag-PY, +.bfh-flag-QA, +.bfh-flag-RS, +.bfh-flag-RU, +.bfh-flag-RW, +.bfh-flag-SA, +.bfh-flag-SB, +.bfh-flag-SC, +.bfh-flag-SD, +.bfh-flag-SE, +.bfh-flag-SG, +.bfh-flag-SH, +.bfh-flag-SI, +.bfh-flag-SK, +.bfh-flag-SM, +.bfh-flag-SN, +.bfh-flag-SO, +.bfh-flag-SR, +.bfh-flag-SS, +.bfh-flag-ST, +.bfh-flag-SV, +.bfh-flag-SY, +.bfh-flag-SZ, +.bfh-flag-TC, +.bfh-flag-TD, +.bfh-flag-TG, +.bfh-flag-TH, +.bfh-flag-TJ, +.bfh-flag-TM, +.bfh-flag-TN, +.bfh-flag-TP, +.bfh-flag-TR, +.bfh-flag-TT, +.bfh-flag-TV, +.bfh-flag-TW, +.bfh-flag-TZ, +.bfh-flag-UA, +.bfh-flag-UG, +.bfh-flag-US, +.bfh-flag-UY, +.bfh-flag-UZ, +.bfh-flag-VC, +.bfh-flag-VE, +.bfh-flag-VG, +.bfh-flag-VI, +.bfh-flag-VN, +.bfh-flag-VU, +.bfh-flag-WS, +.bfh-flag-YE, +.bfh-flag-ZA, +.bfh-flag-ZM, +.bfh-flag-BF, +.bfh-flag-CU, +.bfh-flag-DE, +.bfh-flag-IR, +.bfh-flag-KZ, +.bfh-flag-LB, +.bfh-flag-LI, +.bfh-flag-MC, +.bfh-flag-MD, +.bfh-flag-MK, +.bfh-flag-MN, +.bfh-flag-MO, +.bfh-flag-MX, +.bfh-flag-MY, +.bfh-flag-PR, +.bfh-flag-RO, +.bfh-flag-SL, +.bfh-flag-TO, +.bfh-flag-VA, +.bfh-flag-ZW, +.bfh-flag-EUR, +.bfh-flag-XCD { + margin-right: 5px; +} + +.bfh-flag-AD { + background-position: -1921px 0; +} + +.bfh-flag-AE { + background-position: -1904px 0; +} + +.bfh-flag-AF { + background-position: -3689px 0; +} + +.bfh-flag-AG { + background-position: -34px 0; +} + +.bfh-flag-AI { + background-position: -51px 0; +} + +.bfh-flag-AL { + background-position: -68px 0; +} + +.bfh-flag-AM { + background-position: -85px 0; +} + +.bfh-flag-AN { + background-position: -102px 0; +} + +.bfh-flag-AO { + background-position: -119px 0; +} + +.bfh-flag-AQ { + background-position: -136px 0; +} + +.bfh-flag-AR { + background-position: -153px 0; +} + +.bfh-flag-AS { + background-position: -170px 0; +} + +.bfh-flag-AT { + background-position: -187px 0; +} + +.bfh-flag-AU { + background-position: -204px 0; +} + +.bfh-flag-AW { + background-position: -221px 0; +} + +.bfh-flag-AX { + background-position: -238px 0; +} + +.bfh-flag-AZ { + background-position: -255px 0; +} + +.bfh-flag-BA { + background-position: -272px 0; +} + +.bfh-flag-BB { + background-position: -289px 0; +} + +.bfh-flag-BD { + background-position: -306px 0; +} + +.bfh-flag-BE { + background-position: -323px 0; +} + +.bfh-flag-BG { + background-position: -340px 0; +} + +.bfh-flag-BH { + background-position: -357px 0; +} + +.bfh-flag-BI { + background-position: -374px 0; +} + +.bfh-flag-BJ { + background-position: -391px 0; +} + +.bfh-flag-BL { + background-position: -408px 0; +} + +.bfh-flag-BM { + background-position: -425px 0; +} + +.bfh-flag-BN { + background-position: -442px 0; +} + +.bfh-flag-BO { + background-position: -459px 0; +} + +.bfh-flag-BR { + background-position: -476px 0; +} + +.bfh-flag-BS { + background-position: -493px 0; +} + +.bfh-flag-BT { + background-position: -510px 0; +} + +.bfh-flag-BW { + background-position: -527px 0; +} + +.bfh-flag-BY { + background-position: -544px 0; +} + +.bfh-flag-BZ { + background-position: -561px 0; +} + +.bfh-flag-CA { + background-position: -578px 0; +} + +.bfh-flag-CD { + background-position: -595px 0; +} + +.bfh-flag-CF { + background-position: -612px 0; +} + +.bfh-flag-CG { + background-position: -629px 0; +} + +.bfh-flag-CH { + background-position: -646px 0; +} + +.bfh-flag-CI { + background-position: -663px 0; +} + +.bfh-flag-CL { + background-position: -680px 0; +} + +.bfh-flag-CM { + background-position: -697px 0; +} + +.bfh-flag-CN { + background-position: -714px 0; +} + +.bfh-flag-CO { + background-position: -731px 0; +} + +.bfh-flag-CR { + background-position: -748px 0; +} + +.bfh-flag-CV { + background-position: -765px 0; +} + +.bfh-flag-CY { + background-position: -782px 0; +} + +.bfh-flag-CZ { + background-position: -799px 0; +} + +.bfh-flag-DJ { + background-position: -816px 0; +} + +.bfh-flag-DK { + background-position: -833px 0; +} + +.bfh-flag-DM { + background-position: -850px 0; +} + +.bfh-flag-DO { + background-position: -867px 0; +} + +.bfh-flag-DZ { + background-position: -884px 0; +} + +.bfh-flag-EC { + background-position: -901px 0; +} + +.bfh-flag-EE { + background-position: -918px 0; +} + +.bfh-flag-EG { + background-position: -935px 0; +} + +.bfh-flag-EH { + background-position: -952px 0; +} + +.bfh-flag-ER { + background-position: -969px 0; +} + +.bfh-flag-ES { + background-position: -986px 0; +} + +.bfh-flag-ET { + background-position: -1003px 0; +} + +.bfh-flag-EU { + background-position: -1020px 0; +} + +.bfh-flag-FI { + background-position: -1037px 0; +} + +.bfh-flag-FJ { + background-position: -1054px 0; +} + +.bfh-flag-FK { + background-position: -1071px 0; +} + +.bfh-flag-FM { + background-position: -1088px 0; +} + +.bfh-flag-FO { + background-position: -1105px 0; +} + +.bfh-flag-FR, +.bfh-flag-FX, +.bfh-flag-GF, +.bfh-flag-GP, +.bfh-flag-MQ, +.bfh-flag-NC, +.bfh-flag-PF, +.bfh-flag-PM, +.bfh-flag-RE, +.bfh-flag-TF, +.bfh-flag-WF { + background-position: -1122px 0; +} + +.bfh-flag-GA { + background-position: -1139px 0; +} + +.bfh-flag-GB { + background-position: -1156px 0; +} + +.bfh-flag-GD { + background-position: -1173px 0; +} + +.bfh-flag-GE { + background-position: -1190px 0; +} + +.bfh-flag-GG { + background-position: -1207px 0; +} + +.bfh-flag-GH { + background-position: -1224px 0; +} + +.bfh-flag-GL { + background-position: -1241px 0; +} + +.bfh-flag-GM { + background-position: -1258px 0; +} + +.bfh-flag-GN { + background-position: -1275px 0; +} + +.bfh-flag-GQ { + background-position: -1292px 0; +} + +.bfh-flag-GR { + background-position: -1309px 0; +} + +.bfh-flag-GS { + background-position: -1326px 0; +} + +.bfh-flag-GT { + background-position: -1343px 0; +} + +.bfh-flag-GU { + background-position: -1360px 0; +} + +.bfh-flag-GW { + background-position: -1377px 0; +} + +.bfh-flag-GY { + background-position: -1394px 0; +} + +.bfh-flag-HK { + background-position: -1411px 0; +} + +.bfh-flag-HN { + background-position: -1428px 0; +} + +.bfh-flag-HR { + background-position: -1445px 0; +} + +.bfh-flag-HT { + background-position: -1462px 0; +} + +.bfh-flag-HU { + background-position: -1479px 0; +} + +.bfh-flag-ID { + background-position: -1496px 0; +} + +.bfh-flag-IE { + background-position: -1513px 0; +} + +.bfh-flag-IL { + background-position: -1530px 0; +} + +.bfh-flag-IM { + background-position: -1547px 0; +} + +.bfh-flag-IN { + background-position: -1564px 0; +} + +.bfh-flag-IQ { + background-position: -1581px 0; +} + +.bfh-flag-IS { + background-position: -1598px 0; +} + +.bfh-flag-IT { + background-position: -1615px 0; +} + +.bfh-flag-JE { + background-position: -1632px 0; +} + +.bfh-flag-JM { + background-position: -1649px 0; +} + +.bfh-flag-JO { + background-position: -1666px 0; +} + +.bfh-flag-JP { + background-position: -1683px 0; +} + +.bfh-flag-KE { + background-position: -1700px 0; +} + +.bfh-flag-KG { + background-position: -1717px 0; +} + +.bfh-flag-KH { + background-position: -1734px 0; +} + +.bfh-flag-KI { + background-position: -1751px 0; +} + +.bfh-flag-KM { + background-position: -1768px 0; +} + +.bfh-flag-KN { + background-position: -1785px 0; +} + +.bfh-flag-KP { + background-position: -1802px 0; +} + +.bfh-flag-KR { + background-position: -1819px 0; +} + +.bfh-flag-KV { + background-position: -1836px 0; +} + +.bfh-flag-KW { + background-position: -1853px 0; +} + +.bfh-flag-KY { + background-position: -1870px 0; +} + +.bfh-flag-LA { + background-position: -1887px 0; +} + +.bfh-flag-LC { + background-position: 0 0; +} + +.bfh-flag-LK { + background-position: -17px 0; +} + +.bfh-flag-LR { + background-position: -1938px 0; +} + +.bfh-flag-LS { + background-position: -1955px 0; +} + +.bfh-flag-LT { + background-position: -1972px 0; +} + +.bfh-flag-LU { + background-position: -1989px 0; +} + +.bfh-flag-LV { + background-position: -2006px 0; +} + +.bfh-flag-LY { + background-position: -2023px 0; +} + +.bfh-flag-MA { + background-position: -2040px 0; +} + +.bfh-flag-ME { + background-position: -2057px 0; +} + +.bfh-flag-MG { + background-position: -2074px 0; +} + +.bfh-flag-MH { + background-position: -2091px 0; +} + +.bfh-flag-ML { + background-position: -2108px 0; +} + +.bfh-flag-MM { + background-position: -2125px 0; +} + +.bfh-flag-MP { + background-position: -2142px 0; +} + +.bfh-flag-MR { + background-position: -2159px 0; +} + +.bfh-flag-MS { + background-position: -2176px 0; +} + +.bfh-flag-MT { + background-position: -2193px 0; +} + +.bfh-flag-MU { + background-position: -2210px 0; +} + +.bfh-flag-MV { + background-position: -2227px 0; +} + +.bfh-flag-MW { + background-position: -2244px 0; +} + +.bfh-flag-MZ { + background-position: -2261px 0; +} + +.bfh-flag-NA { + background-position: -2278px 0; +} + +.bfh-flag-NE { + background-position: -2295px 0; +} + +.bfh-flag-NF { + background-position: -2312px 0; +} + +.bfh-flag-NG { + background-position: -2329px 0; +} + +.bfh-flag-NI { + background-position: -2346px 0; +} + +.bfh-flag-NL { + background-position: -2363px 0; +} + +.bfh-flag-NO { + background-position: -2380px 0; +} + +.bfh-flag-NP { + background-position: -2397px 0; +} + +.bfh-flag-NR { + background-position: -2414px 0; +} + +.bfh-flag-NZ { + background-position: -2431px 0; +} + +.bfh-flag-OM { + background-position: -2448px 0; +} + +.bfh-flag-PA { + background-position: -2465px 0; +} + +.bfh-flag-PE { + background-position: -2482px 0; +} + +.bfh-flag-PG { + background-position: -2499px 0; +} + +.bfh-flag-PH { + background-position: -2516px 0; +} + +.bfh-flag-PK { + background-position: -2533px 0; +} + +.bfh-flag-PL { + background-position: -2550px 0; +} + +.bfh-flag-PN { + background-position: -2567px 0; +} + +.bfh-flag-PS { + background-position: -2584px 0; +} + +.bfh-flag-PT { + background-position: -2601px 0; +} + +.bfh-flag-PW { + background-position: -2618px 0; +} + +.bfh-flag-PY { + background-position: -2635px 0; +} + +.bfh-flag-QA { + background-position: -2652px 0; +} + +.bfh-flag-RS { + background-position: -2669px 0; +} + +.bfh-flag-RU { + background-position: -2686px 0; +} + +.bfh-flag-RW { + background-position: -2703px 0; +} + +.bfh-flag-SA { + background-position: -2720px 0; +} + +.bfh-flag-SB { + background-position: -2737px 0; +} + +.bfh-flag-SC { + background-position: -2754px 0; +} + +.bfh-flag-SD { + background-position: -2771px 0; +} + +.bfh-flag-SE { + background-position: -2788px 0; +} + +.bfh-flag-SG { + background-position: -2805px 0; +} + +.bfh-flag-SH { + background-position: -2822px 0; +} + +.bfh-flag-SI { + background-position: -2839px 0; +} + +.bfh-flag-SK { + background-position: -2856px 0; +} + +.bfh-flag-SM { + background-position: -2873px 0; +} + +.bfh-flag-SN { + background-position: -2890px 0; +} + +.bfh-flag-SO { + background-position: -2907px 0; +} + +.bfh-flag-SR { + background-position: -2924px 0; +} + +.bfh-flag-SS { + background-position: -2941px 0; +} + +.bfh-flag-ST { + background-position: -2958px 0; +} + +.bfh-flag-SV { + background-position: -2975px 0; +} + +.bfh-flag-SY { + background-position: -2992px 0; +} + +.bfh-flag-SZ { + background-position: -3009px 0; +} + +.bfh-flag-TC { + background-position: -3026px 0; +} + +.bfh-flag-TD { + background-position: -3043px 0; +} + +.bfh-flag-TG { + background-position: -3060px 0; +} + +.bfh-flag-TH { + background-position: -3077px 0; +} + +.bfh-flag-TJ { + background-position: -3094px 0; +} + +.bfh-flag-TM { + background-position: -3111px 0; +} + +.bfh-flag-TN { + background-position: -3128px 0; +} + +.bfh-flag-TP { + background-position: -3145px 0; +} + +.bfh-flag-TR { + background-position: -3162px 0; +} + +.bfh-flag-TT { + background-position: -3179px 0; +} + +.bfh-flag-TV { + background-position: -3196px 0; +} + +.bfh-flag-TW { + background-position: -3213px 0; +} + +.bfh-flag-TZ { + background-position: -3230px 0; +} + +.bfh-flag-UA { + background-position: -3247px 0; +} + +.bfh-flag-UG { + background-position: -3264px 0; +} + +.bfh-flag-US { + background-position: -3281px 0; +} + +.bfh-flag-UY { + background-position: -3298px 0; +} + +.bfh-flag-UZ { + background-position: -3315px 0; +} + +.bfh-flag-VC { + background-position: -3332px 0; +} + +.bfh-flag-VE { + background-position: -3349px 0; +} + +.bfh-flag-VG { + background-position: -3366px 0; +} + +.bfh-flag-VI { + background-position: -3383px 0; +} + +.bfh-flag-VN { + background-position: -3400px 0; +} + +.bfh-flag-VU { + background-position: -3417px 0; +} + +.bfh-flag-WS { + background-position: -3434px 0; +} + +.bfh-flag-YE { + background-position: -3451px 0; +} + +.bfh-flag-ZA { + background-position: -3468px 0; +} + +.bfh-flag-ZM { + background-position: -3485px 0; +} + +.bfh-flag-BF { + background-position: -3502px 0; +} + +.bfh-flag-CU { + background-position: -3519px 0; +} + +.bfh-flag-DE { + background-position: -3536px 0; +} + +.bfh-flag-IR { + background-position: -3553px 0; +} + +.bfh-flag-KZ { + background-position: -3570px 0; +} + +.bfh-flag-LB { + background-position: -3587px 0; +} + +.bfh-flag-LI { + background-position: -3604px 0; +} + +.bfh-flag-MC { + background-position: -3621px 0; +} + +.bfh-flag-MD { + background-position: -3638px 0; +} + +.bfh-flag-MK { + background-position: -3655px 0; +} + +.bfh-flag-MN { + background-position: -3672px 0; +} + +.bfh-flag-MO { + background-position: -3706px 0; +} + +.bfh-flag-MX { + background-position: -3723px 0; +} + +.bfh-flag-MY { + background-position: -3740px 0; +} + +.bfh-flag-PR { + background-position: -3757px 0; +} + +.bfh-flag-RO { + background-position: -3774px 0; +} + +.bfh-flag-SL { + background-position: -3791px 0; +} + +.bfh-flag-TO { + background-position: -3808px 0; +} + +.bfh-flag-VA { + background-position: -3825px 0; +} + +.bfh-flag-ZW { + background-position: -3842px 0; +} + +.bfh-flag-EUR { + background: url(../img/eu.png) no-repeat; +} + +.bfh-flag-XCD { + background: url(../img/xcd.png) no-repeat; +} + +.bfh-flag-AUD, +.bfh-flag-CHF, +.bfh-flag-DKK, +.bfh-flag-EUR, +.bfh-flag-XAF, +.bfh-flag-XCD, +.bfh-flag-XOF, +.bfh-flag-XPF, +.bfh-flag-ZAR { + width: 16px; + height: 14px; + background: url(../img/bootstrap-formhelpers-currencies.flags.png) no-repeat; +} + +.bfh-flag-AUD:empty, +.bfh-flag-CHF:empty, +.bfh-flag-DKK:empty, +.bfh-flag-EUR:empty, +.bfh-flag-XAF:empty, +.bfh-flag-XCD:empty, +.bfh-flag-XOF:empty, +.bfh-flag-XPF:empty, +.bfh-flag-ZAR:empty { + width: 16px; +} + +.bfh-flag-AUD, +.bfh-flag-CHF, +.bfh-flag-DKK, +.bfh-flag-EUR, +.bfh-flag-XAF, +.bfh-flag-XCD, +.bfh-flag-XOF, +.bfh-flag-XPF, +.bfh-flag-ZAR { + margin-right: 5px; +} + +.bfh-flag-AUD { + background-position: -32px 0; +} + +.bfh-flag-CHF { + background-position: -224px 0; +} + +.bfh-flag-DKK { + background-position: -64px -16px; +} + +.bfh-flag-EUR { + background-position: -96px -16px; +} + +.bfh-flag-XAF { + background-position: -160px -80px; +} + +.bfh-flag-XCD { + background-position: -176px -80px; +} + +.bfh-flag-XOF { + background-position: -192px -80px; +} + +.bfh-flag-XPF { + background-position: -208px -80px; +} + +.bfh-flag-ZAR { + background-position: -224px -80px; +} + +.bfh-selectbox { + position: relative; +} + +.bfh-selectbox .bfh-selectbox-toggle { + display: inline-block; + padding: 6px 24px 6px 12px; + text-decoration: none; +} + +.bfh-selectbox .bfh-selectbox-toggle:focus { + outline: 0; +} + +.bfh-selectbox .bfh-selectbox-toggle .bfh-selectbox-option { + display: inline-block; + float: left; + width: 100%; + height: 20px; + overflow: hidden; + text-overflow: ellipsis; +} + +.bfh-selectbox .bfh-selectbox-toggle .selectbox-caret { + float: right; + margin-top: 8px; + margin-right: -16px; + margin-left: -10px; +} + +.bfh-selectbox .bfh-selectbox-options { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 90px; + padding: 5px 0; + margin: -1px 0 0; + font-size: 14px; + background-color: #ffffff; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + background-clip: padding-box; +} + +.bfh-selectbox .bfh-selectbox-options.pull-right { + right: 0; + left: auto; +} + +.bfh-selectbox .bfh-selectbox-options .divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} + +.bfh-selectbox .bfh-selectbox-options .bfh-selectbox-filter-container { + width: 100%; + padding: 5px; +} + +.bfh-selectbox .bfh-selectbox-options ul { + max-width: 500px; + max-height: 200px; + padding: 0; + margin: 5px 0 0 0; + overflow-x: hidden; + overflow-y: auto; + list-style: none; +} + +.bfh-selectbox .bfh-selectbox-options ul li > a { + display: block; + width: 100%; + min-height: 26px; + padding: 3px 20px; + overflow-x: hidden; + clear: both; + font-weight: normal; + line-height: 1.428571429; + color: #333333; + text-overflow: ellipsis; + white-space: nowrap; +} + +.bfh-selectbox .bfh-selectbox-options ul li > a:hover, +.bfh-selectbox .bfh-selectbox-options ul li > a:focus { + color: #262626; + text-decoration: none; + background-color: #f5f5f5; +} + +.bfh-selectbox .bfh-selectbox-options ul .bfh-selectbox-options-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.428571429; + color: #999999; +} + +.bfh-selectbox .bfh-selectbox-options ul .disabled > a { + color: #999999; +} + +.bfh-selectbox .bfh-selectbox-options ul .disabled > a:hover, +.bfh-selectbox .bfh-selectbox-options ul .disabled > a:focus { + color: #999999; + text-decoration: none; + cursor: not-allowed; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.bfh-selectbox.open > .bfh-selectbox-options { + display: block; +} + +.bfh-selectbox.open a { + outline: 0; +} + +.pull-right > .bfh-selectbox-options { + right: 0; + left: auto; +} + +.bfh-selectbox-up .caret, +.navbar-fixed-bottom .bfh-selectbox .caret { + border-top: 0 dotted; + border-bottom: 4px solid #000000; + content: ""; +} + +.bfh-selectbox-up .bfh-selectbox-options, +.navbar-fixed-bottom .bfh-selectbox .bfh-selectbox-options { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} + +@media (min-width: 768px) { + .navbar-right .bfh-selectbox-options { + right: 0; + left: auto; + } +} + +.bfh-googlefonts .bfh-selectbox-options a { + width: 230px; + height: 30px; + text-indent: -9999px; + background-image: url(../img/bootstrap-formhelpers-googlefonts.png); +} + +.bfh-googlefonts .bfh-selectbox-options a:focus { + background-color: transparent; + background-repeat: no-repeat; + outline: none; + filter: none; +} + +.bfh-googlefonts .bfh-selectbox-options .active > a, +.bfh-googlefonts .bfh-selectbox-options .active > a:hover { + background-color: transparent; + background-image: url(../img/bootstrap-formhelpers-googlefonts.png); + background-repeat: no-repeat; + outline: none; + filter: none; +} + +.bfh-datepicker-calendar { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 296px; +} + +.bfh-datepicker-calendar > table.calendar { + width: 376px; + background: #ffffff; +} + +.bfh-datepicker-calendar > table.calendar .months-header > th { + font-size: 12px; + text-align: center; +} + +.bfh-datepicker-calendar > table.calendar .months-header > th.month > span { + display: inline-block; + width: 100px; +} + +.bfh-datepicker-calendar > table.calendar .months-header > th.year > span { + display: inline-block; + width: 50px; +} + +.bfh-datepicker-calendar > table.calendar .days-header > th { + width: 30px; + font-size: 11px; + line-height: 12px; + text-align: center; +} + +.bfh-datepicker-calendar > table.calendar > tbody > tr > td { + width: 30px; + font-size: 11px; + line-height: 12px; + text-align: center; +} + +.bfh-datepicker-calendar > table.calendar > tbody > tr > td.today { + color: #ffffff; + background-color: #428bca; +} + +.bfh-datepicker-calendar > table.calendar > tbody > tr > td.off { + color: #999999; +} + +.bfh-datepicker-calendar > table.calendar > tbody > tr > td:not(.off):hover { + color: #262626; + cursor: pointer; + background-color: #f5f5f5; +} + +.bfh-datepicker { + position: relative; +} + +.bfh-datepicker-toggle { + *margin-bottom: -3px; +} + +.bfh-datepicker-toggle > input[readonly] { + cursor: inherit; + background-color: inherit; +} + +.open > .bfh-datepicker-calendar { + display: block; +} + +.bfh-timepicker-popover { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 100px; + background-color: #ffffff; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + background-clip: padding-box; +} + +.bfh-timepicker-popover > table { + width: 180px; + margin: 0; +} + +.bfh-timepicker-popover > table > tbody > tr > td { + text-align: center; + border: 0; +} + +.bfh-timepicker-popover > table > tbody > tr > td.separator { + font-size: 20px; + font-weight: bold; + line-height: 28px; +} + +.bfh-timepicker-popover > table > tbody > tr > td > div > input { + width: 42px !important; + text-align: center; +} + +.bfh-timepicker { + position: relative; +} + +.bfh-timepicker-toggle { + *margin-bottom: -3px; +} + +.bfh-timepicker-toggle > input[readonly] { + cursor: inherit; + background-color: inherit; +} + +.open > .bfh-timepicker-popover { + display: block; +} + +.bfh-slider { + height: 20px; + margin-top: 8px; + margin-bottom: 23px; + background-color: #ffffff; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 4px; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -o-user-select: none; +} + +.bfh-slider > .bfh-slider-handle { + position: absolute; + width: 20px; + height: 34px; + margin-top: -7px; + cursor: col-resize; + background: #efefef; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 4px; +} + +.bfh-slider > .bfh-slider-handle > .bfh-slider-value { + position: absolute; + width: 48px; + height: 20px; + margin-top: 5px; + margin-left: -15px; + line-height: 20px; + text-align: center; + cursor: col-resize; + background-color: #ffffff; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 4px; +} + +.bfh-slider > .bfh-slider-handle > .bfh-slider-value .disabled { + color: #999999; +} + +.bfh-slider.disabled .bfh-slider-value { + color: #999999; +} + +.bfh-colorpicker-popover { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 100px; + padding: 20px; + cursor: default; + background-color: #ffffff; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + background-clip: padding-box; +} + +.bfh-colorpicker-popover > canvas { + width: 384px; + height: 256px; +} + +.bfh-colorpicker { + position: relative; +} + +.bfh-colorpicker-toggle { + *margin-bottom: -3px; +} + +.bfh-colorpicker-toggle > input[readonly] { + cursor: inherit; + background-color: inherit; +} + +.bfh-colorpicker-toggle .bfh-colorpicker-icon { + display: block; + width: 16px; + height: 16px; +} + +.open > .bfh-colorpicker-popover { + display: block; +} + +.input-group > .bfh-number { + border-right: 0; +} + +.input-group > .bfh-number-btn:hover { + background-color: #cccccc; +} \ No newline at end of file diff --git a/gui/slick/css/lib/bootstrap-formhelpers.min-2.3.0.css b/gui/slick/css/lib/bootstrap-formhelpers.min-2.3.0.css new file mode 100644 index 0000000000000000000000000000000000000000..bc8364488655d4f6a494065d97ef9462a9c4b470 --- /dev/null +++ b/gui/slick/css/lib/bootstrap-formhelpers.min-2.3.0.css @@ -0,0 +1,6 @@ +/** +* bootstrap-formhelpers.js v2.3.0 by @vincentlamanna +* Copyright 2013 Vincent Lamanna +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +.bfh-flag-AD,.bfh-flag-AE,.bfh-flag-AF,.bfh-flag-AG,.bfh-flag-AI,.bfh-flag-AL,.bfh-flag-AM,.bfh-flag-AN,.bfh-flag-AO,.bfh-flag-AQ,.bfh-flag-AR,.bfh-flag-AS,.bfh-flag-AT,.bfh-flag-AU,.bfh-flag-AW,.bfh-flag-AX,.bfh-flag-AZ,.bfh-flag-BA,.bfh-flag-BB,.bfh-flag-BD,.bfh-flag-BE,.bfh-flag-BG,.bfh-flag-BH,.bfh-flag-BI,.bfh-flag-BJ,.bfh-flag-BL,.bfh-flag-BM,.bfh-flag-BN,.bfh-flag-BO,.bfh-flag-BR,.bfh-flag-BS,.bfh-flag-BT,.bfh-flag-BW,.bfh-flag-BY,.bfh-flag-BZ,.bfh-flag-CA,.bfh-flag-CD,.bfh-flag-CF,.bfh-flag-CG,.bfh-flag-CH,.bfh-flag-CI,.bfh-flag-CL,.bfh-flag-CM,.bfh-flag-CN,.bfh-flag-CO,.bfh-flag-CR,.bfh-flag-CV,.bfh-flag-CY,.bfh-flag-CZ,.bfh-flag-DJ,.bfh-flag-DK,.bfh-flag-DM,.bfh-flag-DO,.bfh-flag-DZ,.bfh-flag-EC,.bfh-flag-EE,.bfh-flag-EG,.bfh-flag-EH,.bfh-flag-ER,.bfh-flag-ES,.bfh-flag-ET,.bfh-flag-EU,.bfh-flag-FI,.bfh-flag-FJ,.bfh-flag-FK,.bfh-flag-FM,.bfh-flag-FO,.bfh-flag-FR,.bfh-flag-FX,.bfh-flag-GF,.bfh-flag-GP,.bfh-flag-MQ,.bfh-flag-NC,.bfh-flag-PF,.bfh-flag-PM,.bfh-flag-RE,.bfh-flag-TF,.bfh-flag-WF,.bfh-flag-GA,.bfh-flag-GB,.bfh-flag-GD,.bfh-flag-GE,.bfh-flag-GG,.bfh-flag-GH,.bfh-flag-GL,.bfh-flag-GM,.bfh-flag-GN,.bfh-flag-GQ,.bfh-flag-GR,.bfh-flag-GS,.bfh-flag-GT,.bfh-flag-GU,.bfh-flag-GW,.bfh-flag-GY,.bfh-flag-HK,.bfh-flag-HN,.bfh-flag-HR,.bfh-flag-HT,.bfh-flag-HU,.bfh-flag-ID,.bfh-flag-IE,.bfh-flag-IL,.bfh-flag-IM,.bfh-flag-IN,.bfh-flag-IQ,.bfh-flag-IS,.bfh-flag-IT,.bfh-flag-JE,.bfh-flag-JM,.bfh-flag-JO,.bfh-flag-JP,.bfh-flag-KE,.bfh-flag-KG,.bfh-flag-KH,.bfh-flag-KI,.bfh-flag-KM,.bfh-flag-KN,.bfh-flag-KP,.bfh-flag-KR,.bfh-flag-KV,.bfh-flag-KW,.bfh-flag-KY,.bfh-flag-LA,.bfh-flag-LC,.bfh-flag-LK,.bfh-flag-LR,.bfh-flag-LS,.bfh-flag-LT,.bfh-flag-LU,.bfh-flag-LV,.bfh-flag-LY,.bfh-flag-MA,.bfh-flag-ME,.bfh-flag-MG,.bfh-flag-MH,.bfh-flag-ML,.bfh-flag-MM,.bfh-flag-MP,.bfh-flag-MR,.bfh-flag-MS,.bfh-flag-MT,.bfh-flag-MU,.bfh-flag-MV,.bfh-flag-MW,.bfh-flag-MZ,.bfh-flag-NA,.bfh-flag-NE,.bfh-flag-NF,.bfh-flag-NG,.bfh-flag-NI,.bfh-flag-NL,.bfh-flag-NO,.bfh-flag-NP,.bfh-flag-NR,.bfh-flag-NZ,.bfh-flag-OM,.bfh-flag-PA,.bfh-flag-PE,.bfh-flag-PG,.bfh-flag-PH,.bfh-flag-PK,.bfh-flag-PL,.bfh-flag-PN,.bfh-flag-PS,.bfh-flag-PT,.bfh-flag-PW,.bfh-flag-PY,.bfh-flag-QA,.bfh-flag-RS,.bfh-flag-RU,.bfh-flag-RW,.bfh-flag-SA,.bfh-flag-SB,.bfh-flag-SC,.bfh-flag-SD,.bfh-flag-SE,.bfh-flag-SG,.bfh-flag-SH,.bfh-flag-SI,.bfh-flag-SK,.bfh-flag-SM,.bfh-flag-SN,.bfh-flag-SO,.bfh-flag-SR,.bfh-flag-SS,.bfh-flag-ST,.bfh-flag-SV,.bfh-flag-SY,.bfh-flag-SZ,.bfh-flag-TC,.bfh-flag-TD,.bfh-flag-TG,.bfh-flag-TH,.bfh-flag-TJ,.bfh-flag-TM,.bfh-flag-TN,.bfh-flag-TP,.bfh-flag-TR,.bfh-flag-TT,.bfh-flag-TV,.bfh-flag-TW,.bfh-flag-TZ,.bfh-flag-UA,.bfh-flag-UG,.bfh-flag-US,.bfh-flag-UY,.bfh-flag-UZ,.bfh-flag-VC,.bfh-flag-VE,.bfh-flag-VG,.bfh-flag-VI,.bfh-flag-VN,.bfh-flag-VU,.bfh-flag-WS,.bfh-flag-YE,.bfh-flag-ZA,.bfh-flag-ZM,.bfh-flag-BF,.bfh-flag-CU,.bfh-flag-DE,.bfh-flag-IR,.bfh-flag-KZ,.bfh-flag-LB,.bfh-flag-LI,.bfh-flag-MC,.bfh-flag-MD,.bfh-flag-MK,.bfh-flag-MN,.bfh-flag-MO,.bfh-flag-MX,.bfh-flag-MY,.bfh-flag-PR,.bfh-flag-RO,.bfh-flag-SL,.bfh-flag-TO,.bfh-flag-VA,.bfh-flag-ZW{width:16px;height:14px;background:url(../img/bootstrap-formhelpers-countries.flags.png) no-repeat}.bfh-flag-AD:empty,.bfh-flag-AE:empty,.bfh-flag-AF:empty,.bfh-flag-AG:empty,.bfh-flag-AI:empty,.bfh-flag-AL:empty,.bfh-flag-AM:empty,.bfh-flag-AN:empty,.bfh-flag-AO:empty,.bfh-flag-AQ:empty,.bfh-flag-AR:empty,.bfh-flag-AS:empty,.bfh-flag-AT:empty,.bfh-flag-AU:empty,.bfh-flag-AW:empty,.bfh-flag-AX:empty,.bfh-flag-AZ:empty,.bfh-flag-BA:empty,.bfh-flag-BB:empty,.bfh-flag-BD:empty,.bfh-flag-BE:empty,.bfh-flag-BG:empty,.bfh-flag-BH:empty,.bfh-flag-BI:empty,.bfh-flag-BJ:empty,.bfh-flag-BL:empty,.bfh-flag-BM:empty,.bfh-flag-BN:empty,.bfh-flag-BO:empty,.bfh-flag-BR:empty,.bfh-flag-BS:empty,.bfh-flag-BT:empty,.bfh-flag-BW:empty,.bfh-flag-BY:empty,.bfh-flag-BZ:empty,.bfh-flag-CA:empty,.bfh-flag-CD:empty,.bfh-flag-CF:empty,.bfh-flag-CG:empty,.bfh-flag-CH:empty,.bfh-flag-CI:empty,.bfh-flag-CL:empty,.bfh-flag-CM:empty,.bfh-flag-CN:empty,.bfh-flag-CO:empty,.bfh-flag-CR:empty,.bfh-flag-CV:empty,.bfh-flag-CY:empty,.bfh-flag-CZ:empty,.bfh-flag-DJ:empty,.bfh-flag-DK:empty,.bfh-flag-DM:empty,.bfh-flag-DO:empty,.bfh-flag-DZ:empty,.bfh-flag-EC:empty,.bfh-flag-EE:empty,.bfh-flag-EG:empty,.bfh-flag-EH:empty,.bfh-flag-ER:empty,.bfh-flag-ES:empty,.bfh-flag-ET:empty,.bfh-flag-EU:empty,.bfh-flag-FI:empty,.bfh-flag-FJ:empty,.bfh-flag-FK:empty,.bfh-flag-FM:empty,.bfh-flag-FO:empty,.bfh-flag-FR:empty,.bfh-flag-FX:empty,.bfh-flag-GF:empty,.bfh-flag-GP:empty,.bfh-flag-MQ:empty,.bfh-flag-NC:empty,.bfh-flag-PF:empty,.bfh-flag-PM:empty,.bfh-flag-RE:empty,.bfh-flag-TF:empty,.bfh-flag-WF:empty,.bfh-flag-GA:empty,.bfh-flag-GB:empty,.bfh-flag-GD:empty,.bfh-flag-GE:empty,.bfh-flag-GG:empty,.bfh-flag-GH:empty,.bfh-flag-GL:empty,.bfh-flag-GM:empty,.bfh-flag-GN:empty,.bfh-flag-GQ:empty,.bfh-flag-GR:empty,.bfh-flag-GS:empty,.bfh-flag-GT:empty,.bfh-flag-GU:empty,.bfh-flag-GW:empty,.bfh-flag-GY:empty,.bfh-flag-HK:empty,.bfh-flag-HN:empty,.bfh-flag-HR:empty,.bfh-flag-HT:empty,.bfh-flag-HU:empty,.bfh-flag-ID:empty,.bfh-flag-IE:empty,.bfh-flag-IL:empty,.bfh-flag-IM:empty,.bfh-flag-IN:empty,.bfh-flag-IQ:empty,.bfh-flag-IS:empty,.bfh-flag-IT:empty,.bfh-flag-JE:empty,.bfh-flag-JM:empty,.bfh-flag-JO:empty,.bfh-flag-JP:empty,.bfh-flag-KE:empty,.bfh-flag-KG:empty,.bfh-flag-KH:empty,.bfh-flag-KI:empty,.bfh-flag-KM:empty,.bfh-flag-KN:empty,.bfh-flag-KP:empty,.bfh-flag-KR:empty,.bfh-flag-KV:empty,.bfh-flag-KW:empty,.bfh-flag-KY:empty,.bfh-flag-LA:empty,.bfh-flag-LC:empty,.bfh-flag-LK:empty,.bfh-flag-LR:empty,.bfh-flag-LS:empty,.bfh-flag-LT:empty,.bfh-flag-LU:empty,.bfh-flag-LV:empty,.bfh-flag-LY:empty,.bfh-flag-MA:empty,.bfh-flag-ME:empty,.bfh-flag-MG:empty,.bfh-flag-MH:empty,.bfh-flag-ML:empty,.bfh-flag-MM:empty,.bfh-flag-MP:empty,.bfh-flag-MR:empty,.bfh-flag-MS:empty,.bfh-flag-MT:empty,.bfh-flag-MU:empty,.bfh-flag-MV:empty,.bfh-flag-MW:empty,.bfh-flag-MZ:empty,.bfh-flag-NA:empty,.bfh-flag-NE:empty,.bfh-flag-NF:empty,.bfh-flag-NG:empty,.bfh-flag-NI:empty,.bfh-flag-NL:empty,.bfh-flag-NO:empty,.bfh-flag-NP:empty,.bfh-flag-NR:empty,.bfh-flag-NZ:empty,.bfh-flag-OM:empty,.bfh-flag-PA:empty,.bfh-flag-PE:empty,.bfh-flag-PG:empty,.bfh-flag-PH:empty,.bfh-flag-PK:empty,.bfh-flag-PL:empty,.bfh-flag-PN:empty,.bfh-flag-PS:empty,.bfh-flag-PT:empty,.bfh-flag-PW:empty,.bfh-flag-PY:empty,.bfh-flag-QA:empty,.bfh-flag-RS:empty,.bfh-flag-RU:empty,.bfh-flag-RW:empty,.bfh-flag-SA:empty,.bfh-flag-SB:empty,.bfh-flag-SC:empty,.bfh-flag-SD:empty,.bfh-flag-SE:empty,.bfh-flag-SG:empty,.bfh-flag-SH:empty,.bfh-flag-SI:empty,.bfh-flag-SK:empty,.bfh-flag-SM:empty,.bfh-flag-SN:empty,.bfh-flag-SO:empty,.bfh-flag-SR:empty,.bfh-flag-SS:empty,.bfh-flag-ST:empty,.bfh-flag-SV:empty,.bfh-flag-SY:empty,.bfh-flag-SZ:empty,.bfh-flag-TC:empty,.bfh-flag-TD:empty,.bfh-flag-TG:empty,.bfh-flag-TH:empty,.bfh-flag-TJ:empty,.bfh-flag-TM:empty,.bfh-flag-TN:empty,.bfh-flag-TP:empty,.bfh-flag-TR:empty,.bfh-flag-TT:empty,.bfh-flag-TV:empty,.bfh-flag-TW:empty,.bfh-flag-TZ:empty,.bfh-flag-UA:empty,.bfh-flag-UG:empty,.bfh-flag-US:empty,.bfh-flag-UY:empty,.bfh-flag-UZ:empty,.bfh-flag-VC:empty,.bfh-flag-VE:empty,.bfh-flag-VG:empty,.bfh-flag-VI:empty,.bfh-flag-VN:empty,.bfh-flag-VU:empty,.bfh-flag-WS:empty,.bfh-flag-YE:empty,.bfh-flag-ZA:empty,.bfh-flag-ZM:empty,.bfh-flag-BF:empty,.bfh-flag-CU:empty,.bfh-flag-DE:empty,.bfh-flag-IR:empty,.bfh-flag-KZ:empty,.bfh-flag-LB:empty,.bfh-flag-LI:empty,.bfh-flag-MC:empty,.bfh-flag-MD:empty,.bfh-flag-MK:empty,.bfh-flag-MN:empty,.bfh-flag-MO:empty,.bfh-flag-MX:empty,.bfh-flag-MY:empty,.bfh-flag-PR:empty,.bfh-flag-RO:empty,.bfh-flag-SL:empty,.bfh-flag-TO:empty,.bfh-flag-VA:empty,.bfh-flag-ZW:empty{width:16px}.bfh-flag-AD,.bfh-flag-AE,.bfh-flag-AF,.bfh-flag-AG,.bfh-flag-AI,.bfh-flag-AL,.bfh-flag-AM,.bfh-flag-AN,.bfh-flag-AO,.bfh-flag-AQ,.bfh-flag-AR,.bfh-flag-AS,.bfh-flag-AT,.bfh-flag-AU,.bfh-flag-AW,.bfh-flag-AX,.bfh-flag-AZ,.bfh-flag-BA,.bfh-flag-BB,.bfh-flag-BD,.bfh-flag-BE,.bfh-flag-BG,.bfh-flag-BH,.bfh-flag-BI,.bfh-flag-BJ,.bfh-flag-BL,.bfh-flag-BM,.bfh-flag-BN,.bfh-flag-BO,.bfh-flag-BR,.bfh-flag-BS,.bfh-flag-BT,.bfh-flag-BW,.bfh-flag-BY,.bfh-flag-BZ,.bfh-flag-CA,.bfh-flag-CD,.bfh-flag-CF,.bfh-flag-CG,.bfh-flag-CH,.bfh-flag-CI,.bfh-flag-CL,.bfh-flag-CM,.bfh-flag-CN,.bfh-flag-CO,.bfh-flag-CR,.bfh-flag-CV,.bfh-flag-CY,.bfh-flag-CZ,.bfh-flag-DJ,.bfh-flag-DK,.bfh-flag-DM,.bfh-flag-DO,.bfh-flag-DZ,.bfh-flag-EC,.bfh-flag-EE,.bfh-flag-EG,.bfh-flag-EH,.bfh-flag-ER,.bfh-flag-ES,.bfh-flag-ET,.bfh-flag-EU,.bfh-flag-FI,.bfh-flag-FJ,.bfh-flag-FK,.bfh-flag-FM,.bfh-flag-FO,.bfh-flag-FR,.bfh-flag-FX,.bfh-flag-GF,.bfh-flag-GP,.bfh-flag-MQ,.bfh-flag-NC,.bfh-flag-PF,.bfh-flag-PM,.bfh-flag-RE,.bfh-flag-TF,.bfh-flag-WF,.bfh-flag-GA,.bfh-flag-GB,.bfh-flag-GD,.bfh-flag-GE,.bfh-flag-GG,.bfh-flag-GH,.bfh-flag-GL,.bfh-flag-GM,.bfh-flag-GN,.bfh-flag-GQ,.bfh-flag-GR,.bfh-flag-GS,.bfh-flag-GT,.bfh-flag-GU,.bfh-flag-GW,.bfh-flag-GY,.bfh-flag-HK,.bfh-flag-HN,.bfh-flag-HR,.bfh-flag-HT,.bfh-flag-HU,.bfh-flag-ID,.bfh-flag-IE,.bfh-flag-IL,.bfh-flag-IM,.bfh-flag-IN,.bfh-flag-IQ,.bfh-flag-IS,.bfh-flag-IT,.bfh-flag-JE,.bfh-flag-JM,.bfh-flag-JO,.bfh-flag-JP,.bfh-flag-KE,.bfh-flag-KG,.bfh-flag-KH,.bfh-flag-KI,.bfh-flag-KM,.bfh-flag-KN,.bfh-flag-KP,.bfh-flag-KR,.bfh-flag-KV,.bfh-flag-KW,.bfh-flag-KY,.bfh-flag-LA,.bfh-flag-LC,.bfh-flag-LK,.bfh-flag-LR,.bfh-flag-LS,.bfh-flag-LT,.bfh-flag-LU,.bfh-flag-LV,.bfh-flag-LY,.bfh-flag-MA,.bfh-flag-ME,.bfh-flag-MG,.bfh-flag-MH,.bfh-flag-ML,.bfh-flag-MM,.bfh-flag-MP,.bfh-flag-MR,.bfh-flag-MS,.bfh-flag-MT,.bfh-flag-MU,.bfh-flag-MV,.bfh-flag-MW,.bfh-flag-MZ,.bfh-flag-NA,.bfh-flag-NE,.bfh-flag-NF,.bfh-flag-NG,.bfh-flag-NI,.bfh-flag-NL,.bfh-flag-NO,.bfh-flag-NP,.bfh-flag-NR,.bfh-flag-NZ,.bfh-flag-OM,.bfh-flag-PA,.bfh-flag-PE,.bfh-flag-PG,.bfh-flag-PH,.bfh-flag-PK,.bfh-flag-PL,.bfh-flag-PN,.bfh-flag-PS,.bfh-flag-PT,.bfh-flag-PW,.bfh-flag-PY,.bfh-flag-QA,.bfh-flag-RS,.bfh-flag-RU,.bfh-flag-RW,.bfh-flag-SA,.bfh-flag-SB,.bfh-flag-SC,.bfh-flag-SD,.bfh-flag-SE,.bfh-flag-SG,.bfh-flag-SH,.bfh-flag-SI,.bfh-flag-SK,.bfh-flag-SM,.bfh-flag-SN,.bfh-flag-SO,.bfh-flag-SR,.bfh-flag-SS,.bfh-flag-ST,.bfh-flag-SV,.bfh-flag-SY,.bfh-flag-SZ,.bfh-flag-TC,.bfh-flag-TD,.bfh-flag-TG,.bfh-flag-TH,.bfh-flag-TJ,.bfh-flag-TM,.bfh-flag-TN,.bfh-flag-TP,.bfh-flag-TR,.bfh-flag-TT,.bfh-flag-TV,.bfh-flag-TW,.bfh-flag-TZ,.bfh-flag-UA,.bfh-flag-UG,.bfh-flag-US,.bfh-flag-UY,.bfh-flag-UZ,.bfh-flag-VC,.bfh-flag-VE,.bfh-flag-VG,.bfh-flag-VI,.bfh-flag-VN,.bfh-flag-VU,.bfh-flag-WS,.bfh-flag-YE,.bfh-flag-ZA,.bfh-flag-ZM,.bfh-flag-BF,.bfh-flag-CU,.bfh-flag-DE,.bfh-flag-IR,.bfh-flag-KZ,.bfh-flag-LB,.bfh-flag-LI,.bfh-flag-MC,.bfh-flag-MD,.bfh-flag-MK,.bfh-flag-MN,.bfh-flag-MO,.bfh-flag-MX,.bfh-flag-MY,.bfh-flag-PR,.bfh-flag-RO,.bfh-flag-SL,.bfh-flag-TO,.bfh-flag-VA,.bfh-flag-ZW,.bfh-flag-EUR,.bfh-flag-XCD{margin-right:5px}.bfh-flag-AD{background-position:-1921px 0}.bfh-flag-AE{background-position:-1904px 0}.bfh-flag-AF{background-position:-3689px 0}.bfh-flag-AG{background-position:-34px 0}.bfh-flag-AI{background-position:-51px 0}.bfh-flag-AL{background-position:-68px 0}.bfh-flag-AM{background-position:-85px 0}.bfh-flag-AN{background-position:-102px 0}.bfh-flag-AO{background-position:-119px 0}.bfh-flag-AQ{background-position:-136px 0}.bfh-flag-AR{background-position:-153px 0}.bfh-flag-AS{background-position:-170px 0}.bfh-flag-AT{background-position:-187px 0}.bfh-flag-AU{background-position:-204px 0}.bfh-flag-AW{background-position:-221px 0}.bfh-flag-AX{background-position:-238px 0}.bfh-flag-AZ{background-position:-255px 0}.bfh-flag-BA{background-position:-272px 0}.bfh-flag-BB{background-position:-289px 0}.bfh-flag-BD{background-position:-306px 0}.bfh-flag-BE{background-position:-323px 0}.bfh-flag-BG{background-position:-340px 0}.bfh-flag-BH{background-position:-357px 0}.bfh-flag-BI{background-position:-374px 0}.bfh-flag-BJ{background-position:-391px 0}.bfh-flag-BL{background-position:-408px 0}.bfh-flag-BM{background-position:-425px 0}.bfh-flag-BN{background-position:-442px 0}.bfh-flag-BO{background-position:-459px 0}.bfh-flag-BR{background-position:-476px 0}.bfh-flag-BS{background-position:-493px 0}.bfh-flag-BT{background-position:-510px 0}.bfh-flag-BW{background-position:-527px 0}.bfh-flag-BY{background-position:-544px 0}.bfh-flag-BZ{background-position:-561px 0}.bfh-flag-CA{background-position:-578px 0}.bfh-flag-CD{background-position:-595px 0}.bfh-flag-CF{background-position:-612px 0}.bfh-flag-CG{background-position:-629px 0}.bfh-flag-CH{background-position:-646px 0}.bfh-flag-CI{background-position:-663px 0}.bfh-flag-CL{background-position:-680px 0}.bfh-flag-CM{background-position:-697px 0}.bfh-flag-CN{background-position:-714px 0}.bfh-flag-CO{background-position:-731px 0}.bfh-flag-CR{background-position:-748px 0}.bfh-flag-CV{background-position:-765px 0}.bfh-flag-CY{background-position:-782px 0}.bfh-flag-CZ{background-position:-799px 0}.bfh-flag-DJ{background-position:-816px 0}.bfh-flag-DK{background-position:-833px 0}.bfh-flag-DM{background-position:-850px 0}.bfh-flag-DO{background-position:-867px 0}.bfh-flag-DZ{background-position:-884px 0}.bfh-flag-EC{background-position:-901px 0}.bfh-flag-EE{background-position:-918px 0}.bfh-flag-EG{background-position:-935px 0}.bfh-flag-EH{background-position:-952px 0}.bfh-flag-ER{background-position:-969px 0}.bfh-flag-ES{background-position:-986px 0}.bfh-flag-ET{background-position:-1003px 0}.bfh-flag-EU{background-position:-1020px 0}.bfh-flag-FI{background-position:-1037px 0}.bfh-flag-FJ{background-position:-1054px 0}.bfh-flag-FK{background-position:-1071px 0}.bfh-flag-FM{background-position:-1088px 0}.bfh-flag-FO{background-position:-1105px 0}.bfh-flag-FR,.bfh-flag-FX,.bfh-flag-GF,.bfh-flag-GP,.bfh-flag-MQ,.bfh-flag-NC,.bfh-flag-PF,.bfh-flag-PM,.bfh-flag-RE,.bfh-flag-TF,.bfh-flag-WF{background-position:-1122px 0}.bfh-flag-GA{background-position:-1139px 0}.bfh-flag-GB{background-position:-1156px 0}.bfh-flag-GD{background-position:-1173px 0}.bfh-flag-GE{background-position:-1190px 0}.bfh-flag-GG{background-position:-1207px 0}.bfh-flag-GH{background-position:-1224px 0}.bfh-flag-GL{background-position:-1241px 0}.bfh-flag-GM{background-position:-1258px 0}.bfh-flag-GN{background-position:-1275px 0}.bfh-flag-GQ{background-position:-1292px 0}.bfh-flag-GR{background-position:-1309px 0}.bfh-flag-GS{background-position:-1326px 0}.bfh-flag-GT{background-position:-1343px 0}.bfh-flag-GU{background-position:-1360px 0}.bfh-flag-GW{background-position:-1377px 0}.bfh-flag-GY{background-position:-1394px 0}.bfh-flag-HK{background-position:-1411px 0}.bfh-flag-HN{background-position:-1428px 0}.bfh-flag-HR{background-position:-1445px 0}.bfh-flag-HT{background-position:-1462px 0}.bfh-flag-HU{background-position:-1479px 0}.bfh-flag-ID{background-position:-1496px 0}.bfh-flag-IE{background-position:-1513px 0}.bfh-flag-IL{background-position:-1530px 0}.bfh-flag-IM{background-position:-1547px 0}.bfh-flag-IN{background-position:-1564px 0}.bfh-flag-IQ{background-position:-1581px 0}.bfh-flag-IS{background-position:-1598px 0}.bfh-flag-IT{background-position:-1615px 0}.bfh-flag-JE{background-position:-1632px 0}.bfh-flag-JM{background-position:-1649px 0}.bfh-flag-JO{background-position:-1666px 0}.bfh-flag-JP{background-position:-1683px 0}.bfh-flag-KE{background-position:-1700px 0}.bfh-flag-KG{background-position:-1717px 0}.bfh-flag-KH{background-position:-1734px 0}.bfh-flag-KI{background-position:-1751px 0}.bfh-flag-KM{background-position:-1768px 0}.bfh-flag-KN{background-position:-1785px 0}.bfh-flag-KP{background-position:-1802px 0}.bfh-flag-KR{background-position:-1819px 0}.bfh-flag-KV{background-position:-1836px 0}.bfh-flag-KW{background-position:-1853px 0}.bfh-flag-KY{background-position:-1870px 0}.bfh-flag-LA{background-position:-1887px 0}.bfh-flag-LC{background-position:0 0}.bfh-flag-LK{background-position:-17px 0}.bfh-flag-LR{background-position:-1938px 0}.bfh-flag-LS{background-position:-1955px 0}.bfh-flag-LT{background-position:-1972px 0}.bfh-flag-LU{background-position:-1989px 0}.bfh-flag-LV{background-position:-2006px 0}.bfh-flag-LY{background-position:-2023px 0}.bfh-flag-MA{background-position:-2040px 0}.bfh-flag-ME{background-position:-2057px 0}.bfh-flag-MG{background-position:-2074px 0}.bfh-flag-MH{background-position:-2091px 0}.bfh-flag-ML{background-position:-2108px 0}.bfh-flag-MM{background-position:-2125px 0}.bfh-flag-MP{background-position:-2142px 0}.bfh-flag-MR{background-position:-2159px 0}.bfh-flag-MS{background-position:-2176px 0}.bfh-flag-MT{background-position:-2193px 0}.bfh-flag-MU{background-position:-2210px 0}.bfh-flag-MV{background-position:-2227px 0}.bfh-flag-MW{background-position:-2244px 0}.bfh-flag-MZ{background-position:-2261px 0}.bfh-flag-NA{background-position:-2278px 0}.bfh-flag-NE{background-position:-2295px 0}.bfh-flag-NF{background-position:-2312px 0}.bfh-flag-NG{background-position:-2329px 0}.bfh-flag-NI{background-position:-2346px 0}.bfh-flag-NL{background-position:-2363px 0}.bfh-flag-NO{background-position:-2380px 0}.bfh-flag-NP{background-position:-2397px 0}.bfh-flag-NR{background-position:-2414px 0}.bfh-flag-NZ{background-position:-2431px 0}.bfh-flag-OM{background-position:-2448px 0}.bfh-flag-PA{background-position:-2465px 0}.bfh-flag-PE{background-position:-2482px 0}.bfh-flag-PG{background-position:-2499px 0}.bfh-flag-PH{background-position:-2516px 0}.bfh-flag-PK{background-position:-2533px 0}.bfh-flag-PL{background-position:-2550px 0}.bfh-flag-PN{background-position:-2567px 0}.bfh-flag-PS{background-position:-2584px 0}.bfh-flag-PT{background-position:-2601px 0}.bfh-flag-PW{background-position:-2618px 0}.bfh-flag-PY{background-position:-2635px 0}.bfh-flag-QA{background-position:-2652px 0}.bfh-flag-RS{background-position:-2669px 0}.bfh-flag-RU{background-position:-2686px 0}.bfh-flag-RW{background-position:-2703px 0}.bfh-flag-SA{background-position:-2720px 0}.bfh-flag-SB{background-position:-2737px 0}.bfh-flag-SC{background-position:-2754px 0}.bfh-flag-SD{background-position:-2771px 0}.bfh-flag-SE{background-position:-2788px 0}.bfh-flag-SG{background-position:-2805px 0}.bfh-flag-SH{background-position:-2822px 0}.bfh-flag-SI{background-position:-2839px 0}.bfh-flag-SK{background-position:-2856px 0}.bfh-flag-SM{background-position:-2873px 0}.bfh-flag-SN{background-position:-2890px 0}.bfh-flag-SO{background-position:-2907px 0}.bfh-flag-SR{background-position:-2924px 0}.bfh-flag-SS{background-position:-2941px 0}.bfh-flag-ST{background-position:-2958px 0}.bfh-flag-SV{background-position:-2975px 0}.bfh-flag-SY{background-position:-2992px 0}.bfh-flag-SZ{background-position:-3009px 0}.bfh-flag-TC{background-position:-3026px 0}.bfh-flag-TD{background-position:-3043px 0}.bfh-flag-TG{background-position:-3060px 0}.bfh-flag-TH{background-position:-3077px 0}.bfh-flag-TJ{background-position:-3094px 0}.bfh-flag-TM{background-position:-3111px 0}.bfh-flag-TN{background-position:-3128px 0}.bfh-flag-TP{background-position:-3145px 0}.bfh-flag-TR{background-position:-3162px 0}.bfh-flag-TT{background-position:-3179px 0}.bfh-flag-TV{background-position:-3196px 0}.bfh-flag-TW{background-position:-3213px 0}.bfh-flag-TZ{background-position:-3230px 0}.bfh-flag-UA{background-position:-3247px 0}.bfh-flag-UG{background-position:-3264px 0}.bfh-flag-US{background-position:-3281px 0}.bfh-flag-UY{background-position:-3298px 0}.bfh-flag-UZ{background-position:-3315px 0}.bfh-flag-VC{background-position:-3332px 0}.bfh-flag-VE{background-position:-3349px 0}.bfh-flag-VG{background-position:-3366px 0}.bfh-flag-VI{background-position:-3383px 0}.bfh-flag-VN{background-position:-3400px 0}.bfh-flag-VU{background-position:-3417px 0}.bfh-flag-WS{background-position:-3434px 0}.bfh-flag-YE{background-position:-3451px 0}.bfh-flag-ZA{background-position:-3468px 0}.bfh-flag-ZM{background-position:-3485px 0}.bfh-flag-BF{background-position:-3502px 0}.bfh-flag-CU{background-position:-3519px 0}.bfh-flag-DE{background-position:-3536px 0}.bfh-flag-IR{background-position:-3553px 0}.bfh-flag-KZ{background-position:-3570px 0}.bfh-flag-LB{background-position:-3587px 0}.bfh-flag-LI{background-position:-3604px 0}.bfh-flag-MC{background-position:-3621px 0}.bfh-flag-MD{background-position:-3638px 0}.bfh-flag-MK{background-position:-3655px 0}.bfh-flag-MN{background-position:-3672px 0}.bfh-flag-MO{background-position:-3706px 0}.bfh-flag-MX{background-position:-3723px 0}.bfh-flag-MY{background-position:-3740px 0}.bfh-flag-PR{background-position:-3757px 0}.bfh-flag-RO{background-position:-3774px 0}.bfh-flag-SL{background-position:-3791px 0}.bfh-flag-TO{background-position:-3808px 0}.bfh-flag-VA{background-position:-3825px 0}.bfh-flag-ZW{background-position:-3842px 0}.bfh-flag-EUR{background:url(../img/eu.png) no-repeat}.bfh-flag-XCD{background:url(../img/xcd.png) no-repeat}.bfh-flag-AUD,.bfh-flag-CHF,.bfh-flag-DKK,.bfh-flag-EUR,.bfh-flag-XAF,.bfh-flag-XCD,.bfh-flag-XOF,.bfh-flag-XPF,.bfh-flag-ZAR{width:16px;height:14px;background:url(../img/bootstrap-formhelpers-currencies.flags.png) no-repeat}.bfh-flag-AUD:empty,.bfh-flag-CHF:empty,.bfh-flag-DKK:empty,.bfh-flag-EUR:empty,.bfh-flag-XAF:empty,.bfh-flag-XCD:empty,.bfh-flag-XOF:empty,.bfh-flag-XPF:empty,.bfh-flag-ZAR:empty{width:16px}.bfh-flag-AUD,.bfh-flag-CHF,.bfh-flag-DKK,.bfh-flag-EUR,.bfh-flag-XAF,.bfh-flag-XCD,.bfh-flag-XOF,.bfh-flag-XPF,.bfh-flag-ZAR{margin-right:5px}.bfh-flag-AUD{background-position:-32px 0}.bfh-flag-CHF{background-position:-224px 0}.bfh-flag-DKK{background-position:-64px -16px}.bfh-flag-EUR{background-position:-96px -16px}.bfh-flag-XAF{background-position:-160px -80px}.bfh-flag-XCD{background-position:-176px -80px}.bfh-flag-XOF{background-position:-192px -80px}.bfh-flag-XPF{background-position:-208px -80px}.bfh-flag-ZAR{background-position:-224px -80px}.bfh-selectbox{position:relative}.bfh-selectbox .bfh-selectbox-toggle{display:inline-block;padding:6px 24px 6px 12px;text-decoration:none}.bfh-selectbox .bfh-selectbox-toggle:focus{outline:0}.bfh-selectbox .bfh-selectbox-toggle .bfh-selectbox-option{display:inline-block;float:left;width:100%;height:20px;overflow:hidden;text-overflow:ellipsis}.bfh-selectbox .bfh-selectbox-toggle .selectbox-caret{float:right;margin-top:8px;margin-right:-16px;margin-left:-10px}.bfh-selectbox .bfh-selectbox-options{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:90px;padding:5px 0;margin:-1px 0 0;font-size:14px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);background-clip:padding-box}.bfh-selectbox .bfh-selectbox-options.pull-right{right:0;left:auto}.bfh-selectbox .bfh-selectbox-options .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.bfh-selectbox .bfh-selectbox-options .bfh-selectbox-filter-container{width:100%;padding:5px}.bfh-selectbox .bfh-selectbox-options ul{max-width:500px;max-height:200px;padding:0;margin:5px 0 0 0;overflow-x:hidden;overflow-y:auto;list-style:none}.bfh-selectbox .bfh-selectbox-options ul li>a{display:block;width:100%;min-height:26px;padding:3px 20px;overflow-x:hidden;clear:both;font-weight:normal;line-height:1.428571429;color:#333;text-overflow:ellipsis;white-space:nowrap}.bfh-selectbox .bfh-selectbox-options ul li>a:hover,.bfh-selectbox .bfh-selectbox-options ul li>a:focus{color:#262626;text-decoration:none;background-color:#f5f5f5}.bfh-selectbox .bfh-selectbox-options ul .bfh-selectbox-options-header{display:block;padding:3px 20px;font-size:12px;line-height:1.428571429;color:#999}.bfh-selectbox .bfh-selectbox-options ul .disabled>a{color:#999}.bfh-selectbox .bfh-selectbox-options ul .disabled>a:hover,.bfh-selectbox .bfh-selectbox-options ul .disabled>a:focus{color:#999;text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.bfh-selectbox.open>.bfh-selectbox-options{display:block}.bfh-selectbox.open a{outline:0}.pull-right>.bfh-selectbox-options{right:0;left:auto}.bfh-selectbox-up .caret,.navbar-fixed-bottom .bfh-selectbox .caret{border-top:0 dotted;border-bottom:4px solid #000;content:""}.bfh-selectbox-up .bfh-selectbox-options,.navbar-fixed-bottom .bfh-selectbox .bfh-selectbox-options{top:auto;bottom:100%;margin-bottom:1px}@media(min-width:768px){.navbar-right .bfh-selectbox-options{right:0;left:auto}}.bfh-googlefonts .bfh-selectbox-options a{width:230px;height:30px;text-indent:-9999px;background-image:url(../img/bootstrap-formhelpers-googlefonts.png)}.bfh-googlefonts .bfh-selectbox-options a:focus{background-color:transparent;background-repeat:no-repeat;outline:0;filter:none}.bfh-googlefonts .bfh-selectbox-options .active>a,.bfh-googlefonts .bfh-selectbox-options .active>a:hover{background-color:transparent;background-image:url(../img/bootstrap-formhelpers-googlefonts.png);background-repeat:no-repeat;outline:0;filter:none}.bfh-datepicker-calendar{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:296px}.bfh-datepicker-calendar>table.calendar{width:376px;background:#fff}.bfh-datepicker-calendar>table.calendar .months-header>th{font-size:12px;text-align:center}.bfh-datepicker-calendar>table.calendar .months-header>th.month>span{display:inline-block;width:100px}.bfh-datepicker-calendar>table.calendar .months-header>th.year>span{display:inline-block;width:50px}.bfh-datepicker-calendar>table.calendar .days-header>th{width:30px;font-size:11px;line-height:12px;text-align:center}.bfh-datepicker-calendar>table.calendar>tbody>tr>td{width:30px;font-size:11px;line-height:12px;text-align:center}.bfh-datepicker-calendar>table.calendar>tbody>tr>td.today{color:#fff;background-color:#428bca}.bfh-datepicker-calendar>table.calendar>tbody>tr>td.off{color:#999}.bfh-datepicker-calendar>table.calendar>tbody>tr>td:not(.off):hover{color:#262626;cursor:pointer;background-color:#f5f5f5}.bfh-datepicker{position:relative}.bfh-datepicker-toggle{*margin-bottom:-3px}.bfh-datepicker-toggle>input[readonly]{cursor:inherit;background-color:inherit}.open>.bfh-datepicker-calendar{display:block}.bfh-timepicker-popover{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:100px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);background-clip:padding-box}.bfh-timepicker-popover>table{width:180px;margin:0}.bfh-timepicker-popover>table>tbody>tr>td{text-align:center;border:0}.bfh-timepicker-popover>table>tbody>tr>td.separator{font-size:20px;font-weight:bold;line-height:28px}.bfh-timepicker-popover>table>tbody>tr>td>div>input{width:42px!important;text-align:center}.bfh-timepicker{position:relative}.bfh-timepicker-toggle{*margin-bottom:-3px}.bfh-timepicker-toggle>input[readonly]{cursor:inherit;background-color:inherit}.open>.bfh-timepicker-popover{display:block}.bfh-slider{height:20px;margin-top:8px;margin-bottom:23px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-o-user-select:none}.bfh-slider>.bfh-slider-handle{position:absolute;width:20px;height:34px;margin-top:-7px;cursor:col-resize;background:#efefef;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px}.bfh-slider>.bfh-slider-handle>.bfh-slider-value{position:absolute;width:48px;height:20px;margin-top:5px;margin-left:-15px;line-height:20px;text-align:center;cursor:col-resize;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px}.bfh-slider>.bfh-slider-handle>.bfh-slider-value .disabled{color:#999}.bfh-slider.disabled .bfh-slider-value{color:#999}.bfh-colorpicker-popover{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:100px;padding:20px;cursor:default;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);background-clip:padding-box}.bfh-colorpicker-popover>canvas{width:384px;height:256px}.bfh-colorpicker{position:relative}.bfh-colorpicker-toggle{*margin-bottom:-3px}.bfh-colorpicker-toggle>input[readonly]{cursor:inherit;background-color:inherit}.bfh-colorpicker-toggle .bfh-colorpicker-icon{display:block;width:16px;height:16px}.open>.bfh-colorpicker-popover{display:block}.input-group>.bfh-number{border-right:0}.input-group>.bfh-number-btn:hover{background-color:#ccc} \ No newline at end of file diff --git a/gui/slick/css/lib/bootstrap.css b/gui/slick/css/lib/bootstrap.css index 630edc8aac5230076416a561f656e6bb88f38e71..17c9b6eea0a7bdd1ac6b37c9e7ccc6486cb4f147 100644 --- a/gui/slick/css/lib/bootstrap.css +++ b/gui/slick/css/lib/bootstrap.css @@ -1111,7 +1111,7 @@ p { font-weight: 300; line-height: 1.4; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .lead { font-size: 21px; } @@ -1257,7 +1257,7 @@ dt { dd { margin-left: 0; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .dl-horizontal dt { float: left; width: 160px; @@ -1393,12 +1393,12 @@ pre code { margin-right: auto; margin-left: auto; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .container { width: 750px; } } -@media (min-width: 992px) { +@media (min-width: 1011px) { .container { width: 970px; } @@ -1580,7 +1580,7 @@ pre code { .col-xs-offset-0 { margin-left: 0; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { float: left; } @@ -1738,7 +1738,7 @@ pre code { margin-left: 0; } } -@media (min-width: 992px) { +@media (min-width: 1011px) { .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { float: left; } @@ -2662,7 +2662,7 @@ select[multiple].form-group-lg .form-control { margin-bottom: 10px; color: #737373; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .form-inline .form-group { display: inline-block; margin-bottom: 0; @@ -2728,7 +2728,7 @@ select[multiple].form-group-lg .form-control { margin-right: -15px; margin-left: -15px; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .form-horizontal .control-label { padding-top: 7px; margin-bottom: 0; @@ -2738,12 +2738,12 @@ select[multiple].form-group-lg .form-control { .form-horizontal .has-feedback .form-control-feedback { right: 15px; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .form-horizontal .form-group-lg .control-label { padding-top: 14.3px; } } -@media (min-width: 768px) { +@media (min-width: 1010px) { .form-horizontal .form-group-sm .control-label { padding-top: 6px; } @@ -3305,7 +3305,7 @@ tbody.collapse.in { bottom: 100%; margin-bottom: 1px; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .navbar-right .dropdown-menu { right: 0; left: auto; @@ -3721,7 +3721,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn { top: auto; left: auto; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .nav-tabs.nav-justified > li { display: table-cell; width: 1%; @@ -3739,7 +3739,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn { .nav-tabs.nav-justified > .active > a:focus { border: 1px solid #ddd; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .nav-tabs.nav-justified > li > a { border-bottom: 1px solid #ddd; border-radius: 4px 4px 0 0; @@ -3786,7 +3786,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn { top: auto; left: auto; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .nav-justified > li { display: table-cell; width: 1%; @@ -3807,7 +3807,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn { .nav-tabs-justified > .active > a:focus { border: 1px solid #ddd; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .nav-tabs-justified > li > a { border-bottom: 1px solid #ddd; border-radius: 4px 4px 0 0; @@ -3837,12 +3837,12 @@ select[multiple].input-group-sm > .input-group-btn > .btn { margin-bottom: 20px; border: 1px solid transparent; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .navbar { border-radius: 4px; } } -@media (min-width: 768px) { +@media (min-width: 1010px) { .navbar-header { float: left; } @@ -3859,7 +3859,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn { .navbar-collapse.in { overflow-y: auto; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .navbar-collapse { width: auto; border-top: 0; @@ -3900,7 +3900,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn { margin-right: -15px; margin-left: -15px; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .container > .navbar-header, .container-fluid > .navbar-header, .container > .navbar-collapse, @@ -3913,7 +3913,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn { z-index: 1000; border-width: 0 0 1px; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .navbar-static-top { border-radius: 0; } @@ -3925,7 +3925,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn { left: 0; z-index: 1030; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .navbar-fixed-top, .navbar-fixed-bottom { border-radius: 0; @@ -3954,7 +3954,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn { .navbar-brand > img { display: block; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .navbar > .container .navbar-brand, .navbar > .container-fluid .navbar-brand { margin-left: -15px; @@ -3984,7 +3984,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn { .navbar-toggle .icon-bar + .icon-bar { margin-top: 4px; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .navbar-toggle { display: none; } @@ -4020,7 +4020,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn { background-image: none; } } -@media (min-width: 768px) { +@media (min-width: 1010px) { .navbar-nav { float: left; margin: 0; @@ -4044,7 +4044,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn { -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); } -@media (min-width: 768px) { +@media (min-width: 1010px) { .navbar-form .form-group { display: inline-block; margin-bottom: 0; @@ -4102,7 +4102,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn { margin-bottom: 0; } } -@media (min-width: 768px) { +@media (min-width: 1010px) { .navbar-form { width: auto; padding-top: 0; @@ -4141,14 +4141,14 @@ select[multiple].input-group-sm > .input-group-btn > .btn { margin-top: 15px; margin-bottom: 15px; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .navbar-text { float: left; margin-right: 15px; margin-left: 15px; } } -@media (min-width: 768px) { +@media (min-width: 1010px) { .navbar-left { float: left !important; } @@ -5569,7 +5569,7 @@ button.close { height: 50px; overflow: scroll; } -@media (min-width: 768px) { +@media (min-width: 1010px) { .modal-dialog { width: 600px; margin: 30px auto; @@ -5582,7 +5582,7 @@ button.close { width: 300px; } } -@media (min-width: 992px) { +@media (min-width: 1011px) { .modal-lg { width: 900px; } @@ -6008,7 +6008,7 @@ button.close { .carousel-caption .btn { text-shadow: none; } -@media screen and (min-width: 768px) { +@media screen and (min-width: 1010px) { .carousel-control .glyphicon-chevron-left, .carousel-control .glyphicon-chevron-right, .carousel-control .icon-prev, @@ -6172,7 +6172,7 @@ button.close { display: inline-block !important; } } -@media (min-width: 768px) and (max-width: 991px) { +@media (min-width: 1010px) and (max-width: 1012px) { .visible-sm { display: block !important; } @@ -6187,22 +6187,22 @@ button.close { display: table-cell !important; } } -@media (min-width: 768px) and (max-width: 991px) { +@media (min-width: 1010px) and (max-width: 1012px) { .visible-sm-block { display: block !important; } } -@media (min-width: 768px) and (max-width: 991px) { +@media (min-width: 1010px) and (max-width: 1012px) { .visible-sm-inline { display: inline !important; } } -@media (min-width: 768px) and (max-width: 991px) { +@media (min-width: 1010px) and (max-width: 1012px) { .visible-sm-inline-block { display: inline-block !important; } } -@media (min-width: 992px) and (max-width: 1199px) { +@media (min-width: 1011px) and (max-width: 1199px) { .visible-md { display: block !important; } @@ -6217,17 +6217,17 @@ button.close { display: table-cell !important; } } -@media (min-width: 992px) and (max-width: 1199px) { +@media (min-width: 1011px) and (max-width: 1199px) { .visible-md-block { display: block !important; } } -@media (min-width: 992px) and (max-width: 1199px) { +@media (min-width: 1011px) and (max-width: 1199px) { .visible-md-inline { display: inline !important; } } -@media (min-width: 992px) and (max-width: 1199px) { +@media (min-width: 1011px) and (max-width: 1199px) { .visible-md-inline-block { display: inline-block !important; } @@ -6267,12 +6267,12 @@ button.close { display: none !important; } } -@media (min-width: 768px) and (max-width: 991px) { +@media (min-width: 1010px) and (max-width: 1012px) { .hidden-sm { display: none !important; } } -@media (min-width: 992px) and (max-width: 1199px) { +@media (min-width: 1011px) and (max-width: 1199px) { .hidden-md { display: none !important; } diff --git a/gui/slick/css/light.css b/gui/slick/css/light.css index 5579cb53eb0aebb1cb3b02de76a39c2edc79b0b8..b56fb28529990604419134b9a310fced4578c7cf 100644 --- a/gui/slick/css/light.css +++ b/gui/slick/css/light.css @@ -544,20 +544,20 @@ home.tmpl } .progress-100 { - background-image: -moz-linear-gradient(#55aef1, #9cd0f7) !important; - background-image: linear-gradient(#55aef1, #9cd0f7) !important; - background-image: -webkit-linear-gradient(#55aef1, #9cd0f7) !important; - background-image: -o-linear-gradient(#55aef1, #9cd0f7) !important; + background-image: -moz-linear-gradient(#a6cf41, #5b990d) !important; + background-image: linear-gradient(#a6cf41, #5b990d) !important; + background-image: -webkit-linear-gradient(#a6cf41, #5b990d) !important; + background-image: -o-linear-gradient(#a6cf41, #5b990d) !important; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; } .progress-80 { - background-image: -moz-linear-gradient(#a6cf41, #5b990d) !important; - background-image: linear-gradient(#a6cf41, #5b990d) !important; - background-image: -webkit-linear-gradient(#a6cf41, #5b990d) !important; - background-image: -o-linear-gradient(#a6cf41, #5b990d) !important; + background-image: -moz-linear-gradient(#e1ff97, #9db269) !important; + background-image: linear-gradient(#e1ff97, #9db269) !important; + background-image: -webkit-linear-gradient(#e1ff97, #9db269) !important; + background-image: -o-linear-gradient(#e1ff97, #9db269) !important; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; diff --git a/gui/slick/images/bootstrap-formhelpers/bootstrap-formhelpers-countries.flags-LICENSE.txt b/gui/slick/images/bootstrap-formhelpers/bootstrap-formhelpers-countries.flags-LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..41ac7794e6e84d13285d58ba54c59941ad67ad6b --- /dev/null +++ b/gui/slick/images/bootstrap-formhelpers/bootstrap-formhelpers-countries.flags-LICENSE.txt @@ -0,0 +1,7 @@ +Copyright (c) 2012 Go Squared Ltd. http://www.gosquared.com/ + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/gui/slick/images/bootstrap-formhelpers/bootstrap-formhelpers-countries.flags.png b/gui/slick/images/bootstrap-formhelpers/bootstrap-formhelpers-countries.flags.png new file mode 100644 index 0000000000000000000000000000000000000000..726f493c05ee6d1c8260ab7b4c5f155a24d83e85 Binary files /dev/null and b/gui/slick/images/bootstrap-formhelpers/bootstrap-formhelpers-countries.flags.png differ diff --git a/gui/slick/images/bootstrap-formhelpers/bootstrap-formhelpers-currencies.flags.png b/gui/slick/images/bootstrap-formhelpers/bootstrap-formhelpers-currencies.flags.png new file mode 100644 index 0000000000000000000000000000000000000000..ab90de48739a4e79651cd50ae6c95e1dbaa1c0e6 Binary files /dev/null and b/gui/slick/images/bootstrap-formhelpers/bootstrap-formhelpers-currencies.flags.png differ diff --git a/gui/slick/images/bootstrap-formhelpers/bootstrap-formhelpers-googlefonts.png b/gui/slick/images/bootstrap-formhelpers/bootstrap-formhelpers-googlefonts.png new file mode 100644 index 0000000000000000000000000000000000000000..b1ea2ae288c14b85c8396e0a83c2269ac5a2e756 Binary files /dev/null and b/gui/slick/images/bootstrap-formhelpers/bootstrap-formhelpers-googlefonts.png differ diff --git a/gui/slick/images/network/13th street.png b/gui/slick/images/network/13th street.png new file mode 100644 index 0000000000000000000000000000000000000000..300b9cca442369b59f7b7b7f804cd22fed89ec0b Binary files /dev/null and b/gui/slick/images/network/13th street.png differ diff --git a/gui/slick/images/network/33.png b/gui/slick/images/network/33.png index d6d78e9d71cefb2fa0fca88b1a5fbf3e33fa4608..d205e754e0e2b89f0a43dffeda6887690ca5c864 100644 Binary files a/gui/slick/images/network/33.png and b/gui/slick/images/network/33.png differ diff --git a/gui/slick/images/network/3sat hd.png b/gui/slick/images/network/3sat hd.png new file mode 100644 index 0000000000000000000000000000000000000000..026fbf8f0774529ef4d0a2f29f1d5614c050397d Binary files /dev/null and b/gui/slick/images/network/3sat hd.png differ diff --git a/gui/slick/images/network/4kidstv.png b/gui/slick/images/network/4kidstv.png new file mode 100644 index 0000000000000000000000000000000000000000..631c23e050af93b11f52e9145324f6deb705a73e Binary files /dev/null and b/gui/slick/images/network/4kidstv.png differ diff --git a/gui/slick/images/network/aag tv.png b/gui/slick/images/network/aag tv.png new file mode 100644 index 0000000000000000000000000000000000000000..6112ef73781cf31be7d032ea72b1d756ca03e657 Binary files /dev/null and b/gui/slick/images/network/aag tv.png differ diff --git a/gui/slick/images/network/aaj tv.png b/gui/slick/images/network/aaj tv.png new file mode 100644 index 0000000000000000000000000000000000000000..88313c741d9dc3902ef4b8cd35f447d7e08d315b Binary files /dev/null and b/gui/slick/images/network/aaj tv.png differ diff --git a/gui/slick/images/network/abc (australia).png b/gui/slick/images/network/abc (australia).png index ee320b38ae2a7b8414046fc19a48dc08ada904a7..ed50dcaf717c1c2b9b4ed87678d499e9d37edfeb 100644 Binary files a/gui/slick/images/network/abc (australia).png and b/gui/slick/images/network/abc (australia).png differ diff --git a/gui/slick/images/network/abc australia.png b/gui/slick/images/network/abc australia.png index ee320b38ae2a7b8414046fc19a48dc08ada904a7..ed50dcaf717c1c2b9b4ed87678d499e9d37edfeb 100644 Binary files a/gui/slick/images/network/abc australia.png and b/gui/slick/images/network/abc australia.png differ diff --git a/gui/slick/images/network/abc family.png b/gui/slick/images/network/abc family.png index 7a7d92f5516ed6aaeae621e47163c88c64de41e0..addbd3dbb8ac9709871858fe180ebf2d9a7c2e0c 100644 Binary files a/gui/slick/images/network/abc family.png and b/gui/slick/images/network/abc family.png differ diff --git a/gui/slick/images/network/abc tv australia.png b/gui/slick/images/network/abc tv australia.png new file mode 100644 index 0000000000000000000000000000000000000000..ed50dcaf717c1c2b9b4ed87678d499e9d37edfeb Binary files /dev/null and b/gui/slick/images/network/abc tv australia.png differ diff --git a/gui/slick/images/network/abc tv.png b/gui/slick/images/network/abc tv.png new file mode 100644 index 0000000000000000000000000000000000000000..70a1281abb8b0cff9b27410cbccaf0e5dbb6c02a Binary files /dev/null and b/gui/slick/images/network/abc tv.png differ diff --git a/gui/slick/images/network/abc1.png b/gui/slick/images/network/abc1.png index ee320b38ae2a7b8414046fc19a48dc08ada904a7..ed50dcaf717c1c2b9b4ed87678d499e9d37edfeb 100644 Binary files a/gui/slick/images/network/abc1.png and b/gui/slick/images/network/abc1.png differ diff --git a/gui/slick/images/network/abu dhabi tv.png b/gui/slick/images/network/abu dhabi tv.png new file mode 100644 index 0000000000000000000000000000000000000000..ad7989f2d33191a6ddfb0f78d2d8a0e834f00255 Binary files /dev/null and b/gui/slick/images/network/abu dhabi tv.png differ diff --git a/gui/slick/images/network/addiktv.png b/gui/slick/images/network/addiktv.png new file mode 100644 index 0000000000000000000000000000000000000000..48c8cfb709dc748cdd0cec601923d17cf5f4629d Binary files /dev/null and b/gui/slick/images/network/addiktv.png differ diff --git a/gui/slick/images/network/adult swim.png b/gui/slick/images/network/adult swim.png index 7f0af6f28049c4b7550aace30ed6d9723c4fc9f5..1ae908396b74f0d2014a2ff399ec7b754b2be0d3 100644 Binary files a/gui/slick/images/network/adult swim.png and b/gui/slick/images/network/adult swim.png differ diff --git a/gui/slick/images/network/adult-swim.png b/gui/slick/images/network/adult-swim.png index 7f0af6f28049c4b7550aace30ed6d9723c4fc9f5..1ae908396b74f0d2014a2ff399ec7b754b2be0d3 100644 Binary files a/gui/slick/images/network/adult-swim.png and b/gui/slick/images/network/adult-swim.png differ diff --git a/gui/slick/images/network/adultswim.png b/gui/slick/images/network/adultswim.png index 7f0af6f28049c4b7550aace30ed6d9723c4fc9f5..1ae908396b74f0d2014a2ff399ec7b754b2be0d3 100644 Binary files a/gui/slick/images/network/adultswim.png and b/gui/slick/images/network/adultswim.png differ diff --git a/gui/slick/images/network/allocine.png b/gui/slick/images/network/allocine.png new file mode 100644 index 0000000000000000000000000000000000000000..f03bfe134a41405a3c8b050c7ec66ef5621a1d0f Binary files /dev/null and b/gui/slick/images/network/allocine.png differ diff --git a/gui/slick/images/network/alpha tv.png b/gui/slick/images/network/alpha tv.png new file mode 100644 index 0000000000000000000000000000000000000000..3668d253389b790c7aae624d606576a4d043718a Binary files /dev/null and b/gui/slick/images/network/alpha tv.png differ diff --git a/gui/slick/images/network/anime network.png b/gui/slick/images/network/anime network.png index 0ee270998cb526398cb3d5100619d62707d36600..d462d377a762509bc5f37521610cf19617883b50 100644 Binary files a/gui/slick/images/network/anime network.png and b/gui/slick/images/network/anime network.png differ diff --git a/gui/slick/images/network/anixe hd.png b/gui/slick/images/network/anixe hd.png new file mode 100644 index 0000000000000000000000000000000000000000..0eac84eaf14837f4cfa8b48096d66ef6473f820e Binary files /dev/null and b/gui/slick/images/network/anixe hd.png differ diff --git a/gui/slick/images/network/anixe sd.png b/gui/slick/images/network/anixe sd.png new file mode 100644 index 0000000000000000000000000000000000000000..5f3b0e2d39db56e73c263de998c041d21731a0c1 Binary files /dev/null and b/gui/slick/images/network/anixe sd.png differ diff --git a/gui/slick/images/network/ard.png b/gui/slick/images/network/ard.png index 972adfbe1f512d90dd969dd34228a31038561741..6b39a71435a8e6542778ec54ec3d8562e4d3ccb9 100644 Binary files a/gui/slick/images/network/ard.png and b/gui/slick/images/network/ard.png differ diff --git a/gui/slick/images/network/arte hd.png b/gui/slick/images/network/arte hd.png new file mode 100644 index 0000000000000000000000000000000000000000..07115055e9cc42fcf11b39b2c5bd54212c2dd711 Binary files /dev/null and b/gui/slick/images/network/arte hd.png differ diff --git a/gui/slick/images/network/atv.png b/gui/slick/images/network/atv.png new file mode 100644 index 0000000000000000000000000000000000000000..e6919cec02be9a267dd34b9de8c04e2bde3171a7 Binary files /dev/null and b/gui/slick/images/network/atv.png differ diff --git a/gui/slick/images/network/avro.png b/gui/slick/images/network/avro.png index df699932118d16fb5e43fe33a0ad8a7fe691370d..8eb0d7c622077a0f94d135ac7cec60a9454a3ee0 100644 Binary files a/gui/slick/images/network/avro.png and b/gui/slick/images/network/avro.png differ diff --git a/gui/slick/images/network/axn.png b/gui/slick/images/network/axn.png new file mode 100644 index 0000000000000000000000000000000000000000..a00633b1adc409351717cab640d0b48eb49ebc51 Binary files /dev/null and b/gui/slick/images/network/axn.png differ diff --git a/gui/slick/images/network/axs tv.png b/gui/slick/images/network/axs tv.png new file mode 100644 index 0000000000000000000000000000000000000000..38695139717842c114e555af18b456ff4908c242 Binary files /dev/null and b/gui/slick/images/network/axs tv.png differ diff --git a/gui/slick/images/network/azteca.png b/gui/slick/images/network/azteca.png new file mode 100644 index 0000000000000000000000000000000000000000..03f74b2d6fc609eb7ac4478f43fb7d9dc99bd6ca Binary files /dev/null and b/gui/slick/images/network/azteca.png differ diff --git a/gui/slick/images/network/babyfirsttv.png b/gui/slick/images/network/babyfirsttv.png new file mode 100644 index 0000000000000000000000000000000000000000..e6f1e572c81a4e2a809f66a0523830c1d782f3d8 Binary files /dev/null and b/gui/slick/images/network/babyfirsttv.png differ diff --git a/gui/slick/images/network/bbc america.png b/gui/slick/images/network/bbc america.png index 02263846036e3b05c34368d4d193e288d7e5fddd..908289eb188431f691975a31a8b1afbf37b4dfdf 100644 Binary files a/gui/slick/images/network/bbc america.png and b/gui/slick/images/network/bbc america.png differ diff --git a/gui/slick/images/network/bbc canada.png b/gui/slick/images/network/bbc canada.png index 598d0ea6c2d9227eac90e7dacbcbf2d74ceba598..7bf9a7555197b45945e939b80db6cfa87b8102d5 100644 Binary files a/gui/slick/images/network/bbc canada.png and b/gui/slick/images/network/bbc canada.png differ diff --git a/gui/slick/images/network/bbc entertainment.png b/gui/slick/images/network/bbc entertainment.png index c2aad064b82aa17b2ddef414627dc90db63dd240..28b28c584a984f7e9d31da96671f5b979ba91c70 100644 Binary files a/gui/slick/images/network/bbc entertainment.png and b/gui/slick/images/network/bbc entertainment.png differ diff --git a/gui/slick/images/network/bbc four.png b/gui/slick/images/network/bbc four.png index bc3ee07a7e0312e8e5b46c81fe41e339f3d4900b..520920d8a04f25895aabee520b29c9edaaa49607 100644 Binary files a/gui/slick/images/network/bbc four.png and b/gui/slick/images/network/bbc four.png differ diff --git a/gui/slick/images/network/bbc.png b/gui/slick/images/network/bbc.png index c2aad064b82aa17b2ddef414627dc90db63dd240..28b28c584a984f7e9d31da96671f5b979ba91c70 100644 Binary files a/gui/slick/images/network/bbc.png and b/gui/slick/images/network/bbc.png differ diff --git a/gui/slick/images/network/bloomberg.png b/gui/slick/images/network/bloomberg.png index 7d6e1dce163aade85775bf8f4538394de6427d86..b91248a93b402f64b76318d9c7d0481089b975cb 100644 Binary files a/gui/slick/images/network/bloomberg.png and b/gui/slick/images/network/bloomberg.png differ diff --git a/gui/slick/images/network/bounce tv.png b/gui/slick/images/network/bounce tv.png new file mode 100644 index 0000000000000000000000000000000000000000..d1d6f9bf0a9cb730e7226a82ba5f13fc9819123b Binary files /dev/null and b/gui/slick/images/network/bounce tv.png differ diff --git a/gui/slick/images/network/br alpha.png b/gui/slick/images/network/br alpha.png new file mode 100644 index 0000000000000000000000000000000000000000..2f7f78a469ebfd13b3130d894cbc3fb3c0b41b95 Binary files /dev/null and b/gui/slick/images/network/br alpha.png differ diff --git a/gui/slick/images/network/br.png b/gui/slick/images/network/br.png new file mode 100644 index 0000000000000000000000000000000000000000..bebf142bd4bbbfff8cc5325cb350650e1512e769 Binary files /dev/null and b/gui/slick/images/network/br.png differ diff --git a/gui/slick/images/network/bravo.png b/gui/slick/images/network/bravo.png index 248dd5e59015dc5a5e1ec13dc70afc3758ee349f..41329084916114564fcac8d16c82d27c295108e9 100644 Binary files a/gui/slick/images/network/bravo.png and b/gui/slick/images/network/bravo.png differ diff --git a/gui/slick/images/network/btv.png b/gui/slick/images/network/btv.png new file mode 100644 index 0000000000000000000000000000000000000000..170fe84e4f443c9199ff5fe653ab8773d9fbec08 Binary files /dev/null and b/gui/slick/images/network/btv.png differ diff --git a/gui/slick/images/network/canal+.png b/gui/slick/images/network/canal+.png index 499ed8d33406609a8d5ffee486ab27bc9f141488..2fd37bbba2afeca0d31f3c054c5f1759da672afc 100644 Binary files a/gui/slick/images/network/canal+.png and b/gui/slick/images/network/canal+.png differ diff --git a/gui/slick/images/network/canale 5.png b/gui/slick/images/network/canale 5.png new file mode 100644 index 0000000000000000000000000000000000000000..1098a1e4939afa778c4ce694f04d21d012f46b10 Binary files /dev/null and b/gui/slick/images/network/canale 5.png differ diff --git a/gui/slick/images/network/canvas.png b/gui/slick/images/network/canvas.png index 95b579c372e667edf64d38ca165197d787672272..73ae3f8c0c58f2e204631ef023dd59b609d30402 100644 Binary files a/gui/slick/images/network/canvas.png and b/gui/slick/images/network/canvas.png differ diff --git a/gui/slick/images/network/caracol tv.png b/gui/slick/images/network/caracol tv.png new file mode 100644 index 0000000000000000000000000000000000000000..88116726369cf980beaa8aa6e3859cb02a177fe6 Binary files /dev/null and b/gui/slick/images/network/caracol tv.png differ diff --git a/gui/slick/images/network/cctv.png b/gui/slick/images/network/cctv.png new file mode 100644 index 0000000000000000000000000000000000000000..ec25aec17840ea41b443201ef67f5532589be535 Binary files /dev/null and b/gui/slick/images/network/cctv.png differ diff --git a/gui/slick/images/network/city.png b/gui/slick/images/network/city.png index 0cc525d8779be80433d07623ea5e0129326162fd..c8869d1f0670e7fc180fe108791568d7c0d883b5 100644 Binary files a/gui/slick/images/network/city.png and b/gui/slick/images/network/city.png differ diff --git a/gui/slick/images/network/cnbc.png b/gui/slick/images/network/cnbc.png new file mode 100644 index 0000000000000000000000000000000000000000..bd6585c756aacd4c1d13759cba9fee3686fc8b22 Binary files /dev/null and b/gui/slick/images/network/cnbc.png differ diff --git a/gui/slick/images/network/court tv.png b/gui/slick/images/network/court tv.png new file mode 100644 index 0000000000000000000000000000000000000000..8971d68b1eee8467686d6589a5b5f3688c32cc0e Binary files /dev/null and b/gui/slick/images/network/court tv.png differ diff --git a/gui/slick/images/network/crackle.png b/gui/slick/images/network/crackle.png index d46a69572152f949b4e5bebe99865f2fa861127b..5f3ab658ae86356a824fcb9765c71a3417c6385c 100644 Binary files a/gui/slick/images/network/crackle.png and b/gui/slick/images/network/crackle.png differ diff --git a/gui/slick/images/network/cstv.png b/gui/slick/images/network/cstv.png new file mode 100644 index 0000000000000000000000000000000000000000..3a8d80f67c6dfc5eaa08321a10a9b9993e09372d Binary files /dev/null and b/gui/slick/images/network/cstv.png differ diff --git a/gui/slick/images/network/current tv.png b/gui/slick/images/network/current tv.png new file mode 100644 index 0000000000000000000000000000000000000000..97459c79fa7538af12a77926b088bad748e931b0 Binary files /dev/null and b/gui/slick/images/network/current tv.png differ diff --git a/gui/slick/images/network/das erste hd.png b/gui/slick/images/network/das erste hd.png new file mode 100644 index 0000000000000000000000000000000000000000..a55c2e822269b6c1d0bb394902e53e58c4ac2f38 Binary files /dev/null and b/gui/slick/images/network/das erste hd.png differ diff --git a/gui/slick/images/network/das erste.png b/gui/slick/images/network/das erste.png new file mode 100644 index 0000000000000000000000000000000000000000..2836b69f0db863a540da00b81f17ff0d6c48b508 Binary files /dev/null and b/gui/slick/images/network/das erste.png differ diff --git a/gui/slick/images/network/das vierte.png b/gui/slick/images/network/das vierte.png new file mode 100644 index 0000000000000000000000000000000000000000..1c007fef7bcfb1ff3a0f6bc3b1cca3ed8b9b8bb5 Binary files /dev/null and b/gui/slick/images/network/das vierte.png differ diff --git a/gui/slick/images/network/dave.png b/gui/slick/images/network/dave.png index f8289c8aa489ac6b4bef1f09235e5d242b1ba7a4..e70efccc19e9a6189401af6daf72292920d0760c 100644 Binary files a/gui/slick/images/network/dave.png and b/gui/slick/images/network/dave.png differ diff --git a/gui/slick/images/network/deluxe music.png b/gui/slick/images/network/deluxe music.png new file mode 100644 index 0000000000000000000000000000000000000000..def9e4a5aa1de81371ad9f7f39c15da6d3817994 Binary files /dev/null and b/gui/slick/images/network/deluxe music.png differ diff --git a/gui/slick/images/network/dish tv.png b/gui/slick/images/network/dish tv.png new file mode 100644 index 0000000000000000000000000000000000000000..00a5d64c15672bb977f8bbfd41dbba20685758ff Binary files /dev/null and b/gui/slick/images/network/dish tv.png differ diff --git a/gui/slick/images/network/disney cinemagic.png b/gui/slick/images/network/disney cinemagic.png new file mode 100644 index 0000000000000000000000000000000000000000..bb5bb4e3f5c238f7d67701acd791ed0700a837f8 Binary files /dev/null and b/gui/slick/images/network/disney cinemagic.png differ diff --git a/gui/slick/images/network/disney junior.png b/gui/slick/images/network/disney junior.png new file mode 100644 index 0000000000000000000000000000000000000000..4aea6976f4acbf94c235bb0f8edaeb52c7fdcff6 Binary files /dev/null and b/gui/slick/images/network/disney junior.png differ diff --git a/gui/slick/images/network/diy network.png b/gui/slick/images/network/diy network.png index db6dc252709533db9cbe1085227e9ba67453466e..dbb7fcb5d252658190d38d7ade130bc0aafdea2c 100644 Binary files a/gui/slick/images/network/diy network.png and b/gui/slick/images/network/diy network.png differ diff --git a/gui/slick/images/network/dmax hd.png b/gui/slick/images/network/dmax hd.png new file mode 100644 index 0000000000000000000000000000000000000000..69858af7b7661566a7e867588e3df9e5e74f0596 Binary files /dev/null and b/gui/slick/images/network/dmax hd.png differ diff --git a/gui/slick/images/network/einsfestival hd.png b/gui/slick/images/network/einsfestival hd.png new file mode 100644 index 0000000000000000000000000000000000000000..d47a060d41bdbdfee4d477fcdf81bcf5a85ae75a Binary files /dev/null and b/gui/slick/images/network/einsfestival hd.png differ diff --git a/gui/slick/images/network/einsfestival.png b/gui/slick/images/network/einsfestival.png new file mode 100644 index 0000000000000000000000000000000000000000..dec5dfe5c5ebde79b4cb3d3ca908fa6754651b2f Binary files /dev/null and b/gui/slick/images/network/einsfestival.png differ diff --git a/gui/slick/images/network/einsplus.png b/gui/slick/images/network/einsplus.png new file mode 100644 index 0000000000000000000000000000000000000000..553c6824c4b10b1c4ebe7b0346aa78c4b0c418d8 Binary files /dev/null and b/gui/slick/images/network/einsplus.png differ diff --git a/gui/slick/images/network/eo.png b/gui/slick/images/network/eo.png new file mode 100644 index 0000000000000000000000000000000000000000..fc9065f567b3c2dba0488a7ffab43cac91744c7e Binary files /dev/null and b/gui/slick/images/network/eo.png differ diff --git a/gui/slick/images/network/euronews.png b/gui/slick/images/network/euronews.png new file mode 100644 index 0000000000000000000000000000000000000000..2927ec36cae1ada5e94e55170789d687aed3fbd4 Binary files /dev/null and b/gui/slick/images/network/euronews.png differ diff --git a/gui/slick/images/network/fox channel.png b/gui/slick/images/network/fox channel.png new file mode 100644 index 0000000000000000000000000000000000000000..14948afec9e775fc004741d10b6e0280fd050d52 Binary files /dev/null and b/gui/slick/images/network/fox channel.png differ diff --git a/gui/slick/images/network/france 4.png b/gui/slick/images/network/france 4.png new file mode 100644 index 0000000000000000000000000000000000000000..3c445991a159a93a5dbd23ff7ee92645fcaa259c Binary files /dev/null and b/gui/slick/images/network/france 4.png differ diff --git a/gui/slick/images/network/funimation.png b/gui/slick/images/network/funimation.png index dd531ec31f4bc9799cd9d470d1744831456ab571..c2398c91def791e7fb37328551fe34d2fd818dc6 100644 Binary files a/gui/slick/images/network/funimation.png and b/gui/slick/images/network/funimation.png differ diff --git a/gui/slick/images/network/fxx.png b/gui/slick/images/network/fxx.png index 54863a7ef54f4ecceb61bee23b41de5557593f66..6e53e60e850f4894ad856adfcf065ca8814eea40 100644 Binary files a/gui/slick/images/network/fxx.png and b/gui/slick/images/network/fxx.png differ diff --git a/gui/slick/images/network/g4techtv canada.png b/gui/slick/images/network/g4techtv canada.png new file mode 100644 index 0000000000000000000000000000000000000000..7c5739273b12737429493565c851699633bad6d9 Binary files /dev/null and b/gui/slick/images/network/g4techtv canada.png differ diff --git a/gui/slick/images/network/glitz.png b/gui/slick/images/network/glitz.png new file mode 100644 index 0000000000000000000000000000000000000000..d0bd1f98ede6687eaf136b7ca6e13914a63226e4 Binary files /dev/null and b/gui/slick/images/network/glitz.png differ diff --git a/gui/slick/images/network/h2.png b/gui/slick/images/network/h2.png new file mode 100644 index 0000000000000000000000000000000000000000..e574c5a0e1c8b3ddfd4a13fb442c59e874c089cd Binary files /dev/null and b/gui/slick/images/network/h2.png differ diff --git a/gui/slick/images/network/hbo.png b/gui/slick/images/network/hbo.png index b02d40c4b8edd96274393e02e27293230ea35d51..271ee7cbcbacc1f4978135093feb57e0170a6bd3 100644 Binary files a/gui/slick/images/network/hbo.png and b/gui/slick/images/network/hbo.png differ diff --git a/gui/slick/images/network/hdnet.png b/gui/slick/images/network/hdnet.png index 3ad69b8127afd379bac2fdae4662d4ceb10309c4..6a07013ed7811f14ce4ae1775a5e3c1daf770321 100644 Binary files a/gui/slick/images/network/hdnet.png and b/gui/slick/images/network/hdnet.png differ diff --git a/gui/slick/images/network/heimatkanal.png b/gui/slick/images/network/heimatkanal.png new file mode 100644 index 0000000000000000000000000000000000000000..3b42cfe25878956fe528f7f805dfdcf25595907e Binary files /dev/null and b/gui/slick/images/network/heimatkanal.png differ diff --git a/gui/slick/images/network/hgtv canada.png b/gui/slick/images/network/hgtv canada.png index 6e64a5d1c8260c52d5a635cbc2a75d99713a0c31..a291cd466b8ce957a8a735244f468479c0d3e240 100644 Binary files a/gui/slick/images/network/hgtv canada.png and b/gui/slick/images/network/hgtv canada.png differ diff --git a/gui/slick/images/network/hgtv.png b/gui/slick/images/network/hgtv.png index 86ee82b2804b77ef8146b040a6ca1e3098d90c10..0d56590b6f594a4c7b5373f13d740500db0bf175 100644 Binary files a/gui/slick/images/network/hgtv.png and b/gui/slick/images/network/hgtv.png differ diff --git a/gui/slick/images/network/hr.png b/gui/slick/images/network/hr.png new file mode 100644 index 0000000000000000000000000000000000000000..44e2d1d02289cf7a2f4781a9b7321b0e976deb75 Binary files /dev/null and b/gui/slick/images/network/hr.png differ diff --git a/gui/slick/images/network/ifc.png b/gui/slick/images/network/ifc.png index 5026826fd2a5c9cc0fb6ac14a46d9dccbf7b1e0d..8667624eb4de918ddbd4f644983156016513bf5e 100644 Binary files a/gui/slick/images/network/ifc.png and b/gui/slick/images/network/ifc.png differ diff --git a/gui/slick/images/network/im1.png b/gui/slick/images/network/im1.png new file mode 100644 index 0000000000000000000000000000000000000000..c67b9856a159cd9b9d3558b748a4705bdb9a2df3 Binary files /dev/null and b/gui/slick/images/network/im1.png differ diff --git a/gui/slick/images/network/itv granada.png b/gui/slick/images/network/itv granada.png new file mode 100644 index 0000000000000000000000000000000000000000..2acb89f1cfe01a6873d36bd62d7c7cc5b348f661 Binary files /dev/null and b/gui/slick/images/network/itv granada.png differ diff --git a/gui/slick/images/network/joiz.png b/gui/slick/images/network/joiz.png new file mode 100644 index 0000000000000000000000000000000000000000..696d240dfe90f8384e963e08575882531a8b6802 Binary files /dev/null and b/gui/slick/images/network/joiz.png differ diff --git a/gui/slick/images/network/junior.png b/gui/slick/images/network/junior.png new file mode 100644 index 0000000000000000000000000000000000000000..f3e496c38255e0203519a512fdfbd9034bb2c42c Binary files /dev/null and b/gui/slick/images/network/junior.png differ diff --git a/gui/slick/images/network/kabel eins classics.png b/gui/slick/images/network/kabel eins classics.png new file mode 100644 index 0000000000000000000000000000000000000000..6e366a2b7dec793ebe7a5ab39c1f90b9cf92ee60 Binary files /dev/null and b/gui/slick/images/network/kabel eins classics.png differ diff --git a/gui/slick/images/network/kabel eins hd.png b/gui/slick/images/network/kabel eins hd.png new file mode 100644 index 0000000000000000000000000000000000000000..b03818c14879cd998d5cb40a2ca0458c8a72c8fb Binary files /dev/null and b/gui/slick/images/network/kabel eins hd.png differ diff --git a/gui/slick/images/network/kabel eins.png b/gui/slick/images/network/kabel eins.png new file mode 100644 index 0000000000000000000000000000000000000000..f876918baa137983cac03020dcb2f2069b38b703 Binary files /dev/null and b/gui/slick/images/network/kabel eins.png differ diff --git a/gui/slick/images/network/kbs tv2.png b/gui/slick/images/network/kbs tv2.png new file mode 100644 index 0000000000000000000000000000000000000000..b0bbafe1faf2718f656a65c3253cc5fb57a6dd66 Binary files /dev/null and b/gui/slick/images/network/kbs tv2.png differ diff --git a/gui/slick/images/network/kika hd.png b/gui/slick/images/network/kika hd.png new file mode 100644 index 0000000000000000000000000000000000000000..4cfc89f93b21c8530b737e0828de52bb75ab4d5e Binary files /dev/null and b/gui/slick/images/network/kika hd.png differ diff --git a/gui/slick/images/network/kika.png b/gui/slick/images/network/kika.png new file mode 100644 index 0000000000000000000000000000000000000000..98ca830629096dc0dd8c707ede25b20680ab791d Binary files /dev/null and b/gui/slick/images/network/kika.png differ diff --git a/gui/slick/images/network/kro.png b/gui/slick/images/network/kro.png index 3af86472c491f0e9fc5d0865ced21591eb510339..3e080815bb33eca716de42052d7f21458fb6d8fc 100644 Binary files a/gui/slick/images/network/kro.png and b/gui/slick/images/network/kro.png differ diff --git a/gui/slick/images/network/matv.png b/gui/slick/images/network/matv.png new file mode 100644 index 0000000000000000000000000000000000000000..8a8e13d3d05c51ad582ef2469322702f757072bb Binary files /dev/null and b/gui/slick/images/network/matv.png differ diff --git a/gui/slick/images/network/max.png b/gui/slick/images/network/max.png new file mode 100644 index 0000000000000000000000000000000000000000..32dc40916c31c4078752fc5134b298c82610d711 Binary files /dev/null and b/gui/slick/images/network/max.png differ diff --git a/gui/slick/images/network/mgm.png b/gui/slick/images/network/mgm.png new file mode 100644 index 0000000000000000000000000000000000000000..c2e63252edc22b4a1f1ffdba6d32c37ab51fbb79 Binary files /dev/null and b/gui/slick/images/network/mgm.png differ diff --git a/gui/slick/images/network/motorvision tv.png b/gui/slick/images/network/motorvision tv.png index f85768eb173a4958cf560c953d888250cd41fd5c..9d450741e398f0a09cd5c28a23d96f9c03865ce0 100644 Binary files a/gui/slick/images/network/motorvision tv.png and b/gui/slick/images/network/motorvision tv.png differ diff --git a/gui/slick/images/network/motorvision.png b/gui/slick/images/network/motorvision.png index f85768eb173a4958cf560c953d888250cd41fd5c..9d450741e398f0a09cd5c28a23d96f9c03865ce0 100644 Binary files a/gui/slick/images/network/motorvision.png and b/gui/slick/images/network/motorvision.png differ diff --git a/gui/slick/images/network/mtv network.png b/gui/slick/images/network/mtv network.png new file mode 100644 index 0000000000000000000000000000000000000000..30b1a899af1984fdc62673dd34e504a1367993b3 Binary files /dev/null and b/gui/slick/images/network/mtv network.png differ diff --git a/gui/slick/images/network/mtv.png b/gui/slick/images/network/mtv.png index 47305d3d0dce72a4ae0cfd551b844a68bcbd54c9..0c36f2e1ca96d36b49218a319f46b9c0e782d95d 100644 Binary files a/gui/slick/images/network/mtv.png and b/gui/slick/images/network/mtv.png differ diff --git a/gui/slick/images/network/mtv2.png b/gui/slick/images/network/mtv2.png index 00fef6ca3dcb45bbf64bf27bd029a93a0e19532b..8bfb4570f76dc7b09d6276eb6820ec9ecbd56200 100644 Binary files a/gui/slick/images/network/mtv2.png and b/gui/slick/images/network/mtv2.png differ diff --git a/gui/slick/images/network/n tv.png b/gui/slick/images/network/n tv.png new file mode 100644 index 0000000000000000000000000000000000000000..1f4ddf0f668bccab981df8a65adafbfeb4203e15 Binary files /dev/null and b/gui/slick/images/network/n tv.png differ diff --git a/gui/slick/images/network/n24 hd.png b/gui/slick/images/network/n24 hd.png new file mode 100644 index 0000000000000000000000000000000000000000..ed4db9c3dbd3317eddf825a09f877bd06713e007 Binary files /dev/null and b/gui/slick/images/network/n24 hd.png differ diff --git a/gui/slick/images/network/n24.png b/gui/slick/images/network/n24.png new file mode 100644 index 0000000000000000000000000000000000000000..78b793286e0e1cf15859dd2c75a8247451d6e4a4 Binary files /dev/null and b/gui/slick/images/network/n24.png differ diff --git a/gui/slick/images/network/nat geo.png b/gui/slick/images/network/nat geo.png new file mode 100644 index 0000000000000000000000000000000000000000..e687e024deb7721f330d1ea035a3df193b2a5384 Binary files /dev/null and b/gui/slick/images/network/nat geo.png differ diff --git a/gui/slick/images/network/ndr hd.png b/gui/slick/images/network/ndr hd.png new file mode 100644 index 0000000000000000000000000000000000000000..ae33f45d85119257ca573e06483ebc2030b902dc Binary files /dev/null and b/gui/slick/images/network/ndr hd.png differ diff --git a/gui/slick/images/network/neo kika.png b/gui/slick/images/network/neo kika.png new file mode 100644 index 0000000000000000000000000000000000000000..b3e336db2d73c8ba11c610f5b00503863540418f Binary files /dev/null and b/gui/slick/images/network/neo kika.png differ diff --git a/gui/slick/images/network/nick comedy.png b/gui/slick/images/network/nick comedy.png new file mode 100644 index 0000000000000000000000000000000000000000..05d43cd0c6a3643873794c49a2db7e165d515b8b Binary files /dev/null and b/gui/slick/images/network/nick comedy.png differ diff --git a/gui/slick/images/network/nicktoons.png b/gui/slick/images/network/nicktoons.png new file mode 100644 index 0000000000000000000000000000000000000000..77e6b3e7ae14854b7918f82e277d71b9277f5bc3 Binary files /dev/null and b/gui/slick/images/network/nicktoons.png differ diff --git a/gui/slick/images/network/niconico.png b/gui/slick/images/network/niconico.png index 1dfc1ff3208d82bc1a1af70eb9c69e8e30c845b3..545588b04b48e111094d43bdd818691e3f26600e 100644 Binary files a/gui/slick/images/network/niconico.png and b/gui/slick/images/network/niconico.png differ diff --git a/gui/slick/images/network/nolife.png b/gui/slick/images/network/nolife.png new file mode 100644 index 0000000000000000000000000000000000000000..c52f9df4a42ee9c0d687d8cca03bb87bf3fb6f7e Binary files /dev/null and b/gui/slick/images/network/nolife.png differ diff --git a/gui/slick/images/network/nonetwork.png b/gui/slick/images/network/nonetwork.png index a5918a753a6fa916fb75be9492561d3bfa877cf0..246590181c6a60f769ef4273454ea747d67bcf52 100644 Binary files a/gui/slick/images/network/nonetwork.png and b/gui/slick/images/network/nonetwork.png differ diff --git a/gui/slick/images/network/novatv.png b/gui/slick/images/network/novatv.png new file mode 100644 index 0000000000000000000000000000000000000000..3ca3f4be88aaf3a394708b3f456f90ca135e7757 Binary files /dev/null and b/gui/slick/images/network/novatv.png differ diff --git a/gui/slick/images/network/npo 1.png b/gui/slick/images/network/npo 1.png new file mode 100644 index 0000000000000000000000000000000000000000..aa1c1545b2608767c3cb42be19c88d9f3e5424a1 Binary files /dev/null and b/gui/slick/images/network/npo 1.png differ diff --git a/gui/slick/images/network/npo 2.png b/gui/slick/images/network/npo 2.png new file mode 100644 index 0000000000000000000000000000000000000000..7dd8a4f94f93da289351a3eb7810e10ab2d64d1f Binary files /dev/null and b/gui/slick/images/network/npo 2.png differ diff --git a/gui/slick/images/network/npo 3.png b/gui/slick/images/network/npo 3.png new file mode 100644 index 0000000000000000000000000000000000000000..f30019315a747c4cf554b0459c85f6d8b5ce2d79 Binary files /dev/null and b/gui/slick/images/network/npo 3.png differ diff --git a/gui/slick/images/network/nps.png b/gui/slick/images/network/nps.png new file mode 100644 index 0000000000000000000000000000000000000000..433c0b4c6719b20dba14d2afa2d47767eda439fd Binary files /dev/null and b/gui/slick/images/network/nps.png differ diff --git a/gui/slick/images/network/ntr.png b/gui/slick/images/network/ntr.png new file mode 100644 index 0000000000000000000000000000000000000000..ab1dc6cb65bb04d1dc94f6789b5432cdbb3c0467 Binary files /dev/null and b/gui/slick/images/network/ntr.png differ diff --git a/gui/slick/images/network/ntv.png b/gui/slick/images/network/ntv.png index 79a2b5f34284dd7fd82dffc7c978ed24a7751135..d6a461dfe4eaac31f1f307d4f406bd8efa9267a3 100644 Binary files a/gui/slick/images/network/ntv.png and b/gui/slick/images/network/ntv.png differ diff --git a/gui/slick/images/network/oasis hd.png b/gui/slick/images/network/oasis hd.png new file mode 100644 index 0000000000000000000000000000000000000000..dabe4f784cff17ca9a9de87fadfc0020f4994761 Binary files /dev/null and b/gui/slick/images/network/oasis hd.png differ diff --git a/gui/slick/images/network/orf eins.png b/gui/slick/images/network/orf eins.png new file mode 100644 index 0000000000000000000000000000000000000000..57e45bfe7cd4c2bd4bf7c98aaa96e3464c3c3c57 Binary files /dev/null and b/gui/slick/images/network/orf eins.png differ diff --git a/gui/slick/images/network/pbs.png b/gui/slick/images/network/pbs.png index 9cebaef280291df4252c12fbf9c58051cd1c630d..72f1bcf88d413af7be6ebb2a08efd6cc46eab907 100644 Binary files a/gui/slick/images/network/pbs.png and b/gui/slick/images/network/pbs.png differ diff --git a/gui/slick/images/network/phoenix hd.png b/gui/slick/images/network/phoenix hd.png new file mode 100644 index 0000000000000000000000000000000000000000..af4502274b7183dcfc5ca499f5f5c78576226976 Binary files /dev/null and b/gui/slick/images/network/phoenix hd.png differ diff --git a/gui/slick/images/network/phoenix.png b/gui/slick/images/network/phoenix.png new file mode 100644 index 0000000000000000000000000000000000000000..b7fa29feda027051f8bf390f842904e2e06306a0 Binary files /dev/null and b/gui/slick/images/network/phoenix.png differ diff --git a/gui/slick/images/network/playboy tv.png b/gui/slick/images/network/playboy tv.png index 8ac3ddb2b30874d77307d1066e7c9dbca2901b4a..dce01d10ded64da372d419dd81a20231290f1223 100644 Binary files a/gui/slick/images/network/playboy tv.png and b/gui/slick/images/network/playboy tv.png differ diff --git a/gui/slick/images/network/private spice.png b/gui/slick/images/network/private spice.png index 36626583dd2ecc17f73667f33c328a1808fa9913..b87783d0c25cdeffb18c37ed60bacbe8bd25d14b 100644 Binary files a/gui/slick/images/network/private spice.png and b/gui/slick/images/network/private spice.png differ diff --git a/gui/slick/images/network/pro7 hd.png b/gui/slick/images/network/pro7 hd.png new file mode 100644 index 0000000000000000000000000000000000000000..dc91e912cea2f8eff41aa2292307bc0354e8b2d1 Binary files /dev/null and b/gui/slick/images/network/pro7 hd.png differ diff --git a/gui/slick/images/network/production i.g.png b/gui/slick/images/network/production i.g.png index dc2c91366da7c854da357e5e7e09641e8548096f..773fc78c595fc165c38fb669a9e61eb72c7c5e7d 100644 Binary files a/gui/slick/images/network/production i.g.png and b/gui/slick/images/network/production i.g.png differ diff --git a/gui/slick/images/network/prosieben fun.png b/gui/slick/images/network/prosieben fun.png new file mode 100644 index 0000000000000000000000000000000000000000..2a6eea4882d27fa35e245407a12295e9cfbc134c Binary files /dev/null and b/gui/slick/images/network/prosieben fun.png differ diff --git a/gui/slick/images/network/prosieben maxx.png b/gui/slick/images/network/prosieben maxx.png new file mode 100644 index 0000000000000000000000000000000000000000..2238ea9636e5e5dc7177a2556ac89b15b6bd4bcd Binary files /dev/null and b/gui/slick/images/network/prosieben maxx.png differ diff --git a/gui/slick/images/network/prosieben.png b/gui/slick/images/network/prosieben.png new file mode 100644 index 0000000000000000000000000000000000000000..6437e731c38d630f7bfcdd3fcbc9ea1ac738735f Binary files /dev/null and b/gui/slick/images/network/prosieben.png differ diff --git a/gui/slick/images/network/quest.png b/gui/slick/images/network/quest.png new file mode 100644 index 0000000000000000000000000000000000000000..99fbd093f7435cfce84a8b2461907f30a18509b6 Binary files /dev/null and b/gui/slick/images/network/quest.png differ diff --git a/gui/slick/images/network/radio bremen tv.png b/gui/slick/images/network/radio bremen tv.png new file mode 100644 index 0000000000000000000000000000000000000000..3de8a32886fd996d0eef874d4b9edef40f97cd01 Binary files /dev/null and b/gui/slick/images/network/radio bremen tv.png differ diff --git a/gui/slick/images/network/radio west.png b/gui/slick/images/network/radio west.png index cb7370852e813c3514226bb6287139be01d7d204..0d64d9c3c8a29afcbf384b12fba7e84acaaf4d20 100644 Binary files a/gui/slick/images/network/radio west.png and b/gui/slick/images/network/radio west.png differ diff --git a/gui/slick/images/network/radio-canada.png b/gui/slick/images/network/radio-canada.png new file mode 100644 index 0000000000000000000000000000000000000000..43602d994d238ea863229b7d210c5ce1d9267e68 Binary files /dev/null and b/gui/slick/images/network/radio-canada.png differ diff --git a/gui/slick/images/network/rbb.png b/gui/slick/images/network/rbb.png new file mode 100644 index 0000000000000000000000000000000000000000..c736fd896afcf26d55d07fcd867cbc6f44fbdd1a Binary files /dev/null and b/gui/slick/images/network/rbb.png differ diff --git a/gui/slick/images/network/rctv.png b/gui/slick/images/network/rctv.png new file mode 100644 index 0000000000000000000000000000000000000000..6ffd0d7dbed25072b45d69302fd25189aa1e16cf Binary files /dev/null and b/gui/slick/images/network/rctv.png differ diff --git a/gui/slick/images/network/regio tv.png b/gui/slick/images/network/regio tv.png new file mode 100644 index 0000000000000000000000000000000000000000..33c6888faee5d8f8b7ebeed6dd7406c031a62dfa Binary files /dev/null and b/gui/slick/images/network/regio tv.png differ diff --git a/gui/slick/images/network/rtl crime hd.png b/gui/slick/images/network/rtl crime hd.png new file mode 100644 index 0000000000000000000000000000000000000000..e23126aa054ec6f28e3fbc5acd5695fa4f7b3b65 Binary files /dev/null and b/gui/slick/images/network/rtl crime hd.png differ diff --git a/gui/slick/images/network/rtl crime.png b/gui/slick/images/network/rtl crime.png new file mode 100644 index 0000000000000000000000000000000000000000..8e269d6ca58b4d31a27978e23f140b8a033172e8 Binary files /dev/null and b/gui/slick/images/network/rtl crime.png differ diff --git a/gui/slick/images/network/rtl hd.png b/gui/slick/images/network/rtl hd.png new file mode 100644 index 0000000000000000000000000000000000000000..97d5c33caceecb4c21415bce82eb99e04ecda026 Binary files /dev/null and b/gui/slick/images/network/rtl hd.png differ diff --git a/gui/slick/images/network/rtl ii.png b/gui/slick/images/network/rtl ii.png new file mode 100644 index 0000000000000000000000000000000000000000..473739785496b4e1bf238c94792944b0064e2a4a Binary files /dev/null and b/gui/slick/images/network/rtl ii.png differ diff --git a/gui/slick/images/network/rtl living hd.png b/gui/slick/images/network/rtl living hd.png new file mode 100644 index 0000000000000000000000000000000000000000..73a9c91a7f11d65736bd74b564a8b2f6837d83c0 Binary files /dev/null and b/gui/slick/images/network/rtl living hd.png differ diff --git a/gui/slick/images/network/rtl living.png b/gui/slick/images/network/rtl living.png new file mode 100644 index 0000000000000000000000000000000000000000..9e2b8ffd70b42e194507b16e94314100a5f4db8b Binary files /dev/null and b/gui/slick/images/network/rtl living.png differ diff --git a/gui/slick/images/network/rtl nitro.png b/gui/slick/images/network/rtl nitro.png new file mode 100644 index 0000000000000000000000000000000000000000..6f6e9bfa01826d26340ba85925de0b92ebaa7dd4 Binary files /dev/null and b/gui/slick/images/network/rtl nitro.png differ diff --git a/gui/slick/images/network/rtl passion hd.png b/gui/slick/images/network/rtl passion hd.png new file mode 100644 index 0000000000000000000000000000000000000000..7ed59288c264bab2940a0e6d5cea7335233d8e23 Binary files /dev/null and b/gui/slick/images/network/rtl passion hd.png differ diff --git a/gui/slick/images/network/rtl passion.png b/gui/slick/images/network/rtl passion.png new file mode 100644 index 0000000000000000000000000000000000000000..27a936e4f83a35cd8a9b786344ddf968f6df48eb Binary files /dev/null and b/gui/slick/images/network/rtl passion.png differ diff --git a/gui/slick/images/network/rtl.png b/gui/slick/images/network/rtl.png new file mode 100644 index 0000000000000000000000000000000000000000..c80198a7598680a5e77c8738de4ce5fd24f53e5c Binary files /dev/null and b/gui/slick/images/network/rtl.png differ diff --git a/gui/slick/images/network/rtl2 hd.png b/gui/slick/images/network/rtl2 hd.png new file mode 100644 index 0000000000000000000000000000000000000000..a02b0c6b4ec27385e9b595a27e81b2f0260f7df5 Binary files /dev/null and b/gui/slick/images/network/rtl2 hd.png differ diff --git a/gui/slick/images/network/rtl2.png b/gui/slick/images/network/rtl2.png new file mode 100644 index 0000000000000000000000000000000000000000..473739785496b4e1bf238c94792944b0064e2a4a Binary files /dev/null and b/gui/slick/images/network/rtl2.png differ diff --git a/gui/slick/images/network/sat.1 emotions.png b/gui/slick/images/network/sat.1 emotions.png new file mode 100644 index 0000000000000000000000000000000000000000..29cfa92c7b39ff8df0a9348931f19ccdf0256fd5 Binary files /dev/null and b/gui/slick/images/network/sat.1 emotions.png differ diff --git a/gui/slick/images/network/sat.1 gold.png b/gui/slick/images/network/sat.1 gold.png new file mode 100644 index 0000000000000000000000000000000000000000..3cd28cc38f1b9a08cb9f5b8cc6141bac905e0a68 Binary files /dev/null and b/gui/slick/images/network/sat.1 gold.png differ diff --git a/gui/slick/images/network/sat.1 hd.png b/gui/slick/images/network/sat.1 hd.png new file mode 100644 index 0000000000000000000000000000000000000000..a8f55511fc4c60e6b6dcae46e66ab5d079402275 Binary files /dev/null and b/gui/slick/images/network/sat.1 hd.png differ diff --git a/gui/slick/images/network/sat.1.png b/gui/slick/images/network/sat.1.png new file mode 100644 index 0000000000000000000000000000000000000000..6b947cbc8490974cb1b1a6fb629585aedc153dba Binary files /dev/null and b/gui/slick/images/network/sat.1.png differ diff --git a/gui/slick/images/network/sbs 6.png b/gui/slick/images/network/sbs 6.png index b2da1e64647532a25301a9980e7be53dff2b8362..fb5a2454b44d63f30a679ed8c3e66dfeb9e6e585 100644 Binary files a/gui/slick/images/network/sbs 6.png and b/gui/slick/images/network/sbs 6.png differ diff --git a/gui/slick/images/network/sbs 9.png b/gui/slick/images/network/sbs 9.png new file mode 100644 index 0000000000000000000000000000000000000000..42da25c1290703afe1d54d8ab098c60749f4cf57 Binary files /dev/null and b/gui/slick/images/network/sbs 9.png differ diff --git a/gui/slick/images/network/sbs australia.png b/gui/slick/images/network/sbs australia.png index 971b04b243a0031f70033253d1a6d0973f36b7af..2973a9cb37b3e33e102835c9297b1c049d6b61ae 100644 Binary files a/gui/slick/images/network/sbs australia.png and b/gui/slick/images/network/sbs australia.png differ diff --git a/gui/slick/images/network/sbs.png b/gui/slick/images/network/sbs.png index 971b04b243a0031f70033253d1a6d0973f36b7af..2973a9cb37b3e33e102835c9297b1c049d6b61ae 100644 Binary files a/gui/slick/images/network/sbs.png and b/gui/slick/images/network/sbs.png differ diff --git a/gui/slick/images/network/sbs6.png b/gui/slick/images/network/sbs6.png index b2da1e64647532a25301a9980e7be53dff2b8362..fb5a2454b44d63f30a679ed8c3e66dfeb9e6e585 100644 Binary files a/gui/slick/images/network/sbs6.png and b/gui/slick/images/network/sbs6.png differ diff --git a/gui/slick/images/network/series+.png b/gui/slick/images/network/series+.png new file mode 100644 index 0000000000000000000000000000000000000000..5703eb1c183bf1121dd7d6df2e7d7d54001b6468 Binary files /dev/null and b/gui/slick/images/network/series+.png differ diff --git a/gui/slick/images/network/servustv hd.png b/gui/slick/images/network/servustv hd.png new file mode 100644 index 0000000000000000000000000000000000000000..277d8235df8d5cce8a146eb6e7d7c950d201cd82 Binary files /dev/null and b/gui/slick/images/network/servustv hd.png differ diff --git a/gui/slick/images/network/servustv.png b/gui/slick/images/network/servustv.png new file mode 100644 index 0000000000000000000000000000000000000000..2b92ed1d51bc951f49a9356e5d490d9d364d98af Binary files /dev/null and b/gui/slick/images/network/servustv.png differ diff --git a/gui/slick/images/network/set.png b/gui/slick/images/network/set.png new file mode 100644 index 0000000000000000000000000000000000000000..5d58849e8a90d199e15b0bd1781aee5f5c679b4e Binary files /dev/null and b/gui/slick/images/network/set.png differ diff --git a/gui/slick/images/network/sixx hd.png b/gui/slick/images/network/sixx hd.png new file mode 100644 index 0000000000000000000000000000000000000000..1872ae0303ffbe5541926b69ff96bc4927b87318 Binary files /dev/null and b/gui/slick/images/network/sixx hd.png differ diff --git a/gui/slick/images/network/sixx.png b/gui/slick/images/network/sixx.png new file mode 100644 index 0000000000000000000000000000000000000000..b6080328a24dd5e7a449c7c55998fbfc9088beb3 Binary files /dev/null and b/gui/slick/images/network/sixx.png differ diff --git a/gui/slick/images/network/sky action.png b/gui/slick/images/network/sky action.png new file mode 100644 index 0000000000000000000000000000000000000000..3e35c9a616e89ce36fbad4c9dc5cc038059b4784 Binary files /dev/null and b/gui/slick/images/network/sky action.png differ diff --git a/gui/slick/images/network/sky atlantic hd.png b/gui/slick/images/network/sky atlantic hd.png new file mode 100644 index 0000000000000000000000000000000000000000..b6c8f06d3a427f0d41da53e992ccb87094690b0f Binary files /dev/null and b/gui/slick/images/network/sky atlantic hd.png differ diff --git a/gui/slick/images/network/sky bundesliga.png b/gui/slick/images/network/sky bundesliga.png new file mode 100644 index 0000000000000000000000000000000000000000..c0f1ec58eab5f9b8e99beaa42b24dca90022fa5f Binary files /dev/null and b/gui/slick/images/network/sky bundesliga.png differ diff --git a/gui/slick/images/network/sky cinema +1.png b/gui/slick/images/network/sky cinema +1.png new file mode 100644 index 0000000000000000000000000000000000000000..2b93a647cdefc4fc47e36f4e0386c1134e14a4c2 Binary files /dev/null and b/gui/slick/images/network/sky cinema +1.png differ diff --git a/gui/slick/images/network/sky cinema +24.png b/gui/slick/images/network/sky cinema +24.png new file mode 100644 index 0000000000000000000000000000000000000000..6a7dcb965af65b5f0ccf21f4c72e0084ac5c0f04 Binary files /dev/null and b/gui/slick/images/network/sky cinema +24.png differ diff --git a/gui/slick/images/network/sky cinema.png b/gui/slick/images/network/sky cinema.png new file mode 100644 index 0000000000000000000000000000000000000000..f6309c9cc7267baa08a8b451503713a1cd953eb1 Binary files /dev/null and b/gui/slick/images/network/sky cinema.png differ diff --git a/gui/slick/images/network/sky comedy.png b/gui/slick/images/network/sky comedy.png new file mode 100644 index 0000000000000000000000000000000000000000..2648eb0261b91848e35a5da0f121f7b13a6d4daa Binary files /dev/null and b/gui/slick/images/network/sky comedy.png differ diff --git a/gui/slick/images/network/sky emotion.png b/gui/slick/images/network/sky emotion.png new file mode 100644 index 0000000000000000000000000000000000000000..e7500e3c1727554046a9013cfdc0fffbbfbbdd1f Binary files /dev/null and b/gui/slick/images/network/sky emotion.png differ diff --git a/gui/slick/images/network/sky hits.png b/gui/slick/images/network/sky hits.png new file mode 100644 index 0000000000000000000000000000000000000000..cb74f9400641968cf8e545dd31ae17713815e5d6 Binary files /dev/null and b/gui/slick/images/network/sky hits.png differ diff --git a/gui/slick/images/network/sky krimi.png b/gui/slick/images/network/sky krimi.png new file mode 100644 index 0000000000000000000000000000000000000000..9689c47717f2e90f1685ce8325505135499ef816 Binary files /dev/null and b/gui/slick/images/network/sky krimi.png differ diff --git a/gui/slick/images/network/sky nostalgie.png b/gui/slick/images/network/sky nostalgie.png new file mode 100644 index 0000000000000000000000000000000000000000..867e7dda41d5b42ebb64262bd4a192c69123a9fa Binary files /dev/null and b/gui/slick/images/network/sky nostalgie.png differ diff --git a/gui/slick/images/network/sky select.png b/gui/slick/images/network/sky select.png new file mode 100644 index 0000000000000000000000000000000000000000..8666cc8abfaae067458f4878021c002e99bf79c1 Binary files /dev/null and b/gui/slick/images/network/sky select.png differ diff --git a/gui/slick/images/network/sky sport austria.png b/gui/slick/images/network/sky sport austria.png new file mode 100644 index 0000000000000000000000000000000000000000..b05926462454987ec40948ecf8e7ee6f958177e1 Binary files /dev/null and b/gui/slick/images/network/sky sport austria.png differ diff --git a/gui/slick/images/network/sky sport news hd.png b/gui/slick/images/network/sky sport news hd.png new file mode 100644 index 0000000000000000000000000000000000000000..bb3512224b05c8da5953a1d30913f76ce8325e69 Binary files /dev/null and b/gui/slick/images/network/sky sport news hd.png differ diff --git a/gui/slick/images/network/sky sport news.png b/gui/slick/images/network/sky sport news.png new file mode 100644 index 0000000000000000000000000000000000000000..bd0408d0ac7d7598b9f4cb96bba5dcf7b43c0b4b Binary files /dev/null and b/gui/slick/images/network/sky sport news.png differ diff --git a/gui/slick/images/network/sky sport1.png b/gui/slick/images/network/sky sport1.png new file mode 100644 index 0000000000000000000000000000000000000000..1e9a3abfec5822476c4e4a52308c4c40faa6f5ef Binary files /dev/null and b/gui/slick/images/network/sky sport1.png differ diff --git a/gui/slick/images/network/sky sport2.png b/gui/slick/images/network/sky sport2.png new file mode 100644 index 0000000000000000000000000000000000000000..c7060a7ffc90e9ed6898fb5c309c250dba5e3172 Binary files /dev/null and b/gui/slick/images/network/sky sport2.png differ diff --git a/gui/slick/images/network/smithsonian channel.png b/gui/slick/images/network/smithsonian channel.png index 3f811e4202ea9006a95da5c9ed1b2a01f01a83c3..699bc038ba28602d59252891a1f9b207dbf7901f 100644 Binary files a/gui/slick/images/network/smithsonian channel.png and b/gui/slick/images/network/smithsonian channel.png differ diff --git a/gui/slick/images/network/spiegel geschichte.png b/gui/slick/images/network/spiegel geschichte.png new file mode 100644 index 0000000000000000000000000000000000000000..de15abfc3ee99b1dc161f1a06eb748ddfc9f1217 Binary files /dev/null and b/gui/slick/images/network/spiegel geschichte.png differ diff --git a/gui/slick/images/network/sport1 hd.png b/gui/slick/images/network/sport1 hd.png new file mode 100644 index 0000000000000000000000000000000000000000..c82a11f3a159599f1668831f30ca0c835bfd25e7 Binary files /dev/null and b/gui/slick/images/network/sport1 hd.png differ diff --git a/gui/slick/images/network/sport1.png b/gui/slick/images/network/sport1.png new file mode 100644 index 0000000000000000000000000000000000000000..39f8314f315e1d622ef996b2a7273acc293f8190 Binary files /dev/null and b/gui/slick/images/network/sport1.png differ diff --git a/gui/slick/images/network/sr.png b/gui/slick/images/network/sr.png new file mode 100644 index 0000000000000000000000000000000000000000..11cf44b30501c544c88e3f5f05ac90e9a033b9d4 Binary files /dev/null and b/gui/slick/images/network/sr.png differ diff --git a/gui/slick/images/network/srf zwei.png b/gui/slick/images/network/srf zwei.png new file mode 100644 index 0000000000000000000000000000000000000000..f2af07712cd0b05b5f248975d37a093ce38054aa Binary files /dev/null and b/gui/slick/images/network/srf zwei.png differ diff --git a/gui/slick/images/network/star tv.png b/gui/slick/images/network/star tv.png new file mode 100644 index 0000000000000000000000000000000000000000..caee567b92047a50e6799ab14b361c94d4cc7a38 Binary files /dev/null and b/gui/slick/images/network/star tv.png differ diff --git a/gui/slick/images/network/starz!.png b/gui/slick/images/network/starz!.png index 15d2fe874ad536b1dc3728770134d4afa8fec07f..d1e6cd5cdde927f73356077c79e3abe32a9381fe 100644 Binary files a/gui/slick/images/network/starz!.png and b/gui/slick/images/network/starz!.png differ diff --git a/gui/slick/images/network/starz.png b/gui/slick/images/network/starz.png index 15d2fe874ad536b1dc3728770134d4afa8fec07f..d1e6cd5cdde927f73356077c79e3abe32a9381fe 100644 Binary files a/gui/slick/images/network/starz.png and b/gui/slick/images/network/starz.png differ diff --git a/gui/slick/images/network/stv.png b/gui/slick/images/network/stv.png new file mode 100644 index 0000000000000000000000000000000000000000..b472c28b1d4a0b91a41d75a6ac8a61bcaa2469b4 Binary files /dev/null and b/gui/slick/images/network/stv.png differ diff --git a/gui/slick/images/network/subtv.png b/gui/slick/images/network/subtv.png new file mode 100644 index 0000000000000000000000000000000000000000..fa4f71db6c227c7033f2a712eac42f4443b5ec0d Binary files /dev/null and b/gui/slick/images/network/subtv.png differ diff --git a/gui/slick/images/network/sundance.png b/gui/slick/images/network/sundance.png index 25fc2459d35a887abfdc822d29166318cd1b2603..3a510504afd9e3932038483330a491e6e3889217 100644 Binary files a/gui/slick/images/network/sundance.png and b/gui/slick/images/network/sundance.png differ diff --git a/gui/slick/images/network/sundancetv.png b/gui/slick/images/network/sundancetv.png index 25fc2459d35a887abfdc822d29166318cd1b2603..3a510504afd9e3932038483330a491e6e3889217 100644 Binary files a/gui/slick/images/network/sundancetv.png and b/gui/slick/images/network/sundancetv.png differ diff --git a/gui/slick/images/network/super channel.png b/gui/slick/images/network/super channel.png index 33ae0789fd9515f487cc83d71680424aba414310..d36dc8006f276c8a3a5c08bd63ec1b3de1757f02 100644 Binary files a/gui/slick/images/network/super channel.png and b/gui/slick/images/network/super channel.png differ diff --git a/gui/slick/images/network/super rtl hd.png b/gui/slick/images/network/super rtl hd.png new file mode 100644 index 0000000000000000000000000000000000000000..b093530c6ae8ec53daee0362bc153c9236f48f69 Binary files /dev/null and b/gui/slick/images/network/super rtl hd.png differ diff --git a/gui/slick/images/network/super rtl.png b/gui/slick/images/network/super rtl.png new file mode 100644 index 0000000000000000000000000000000000000000..10070c02034acf386c73c400a33d8d3ee4b98621 Binary files /dev/null and b/gui/slick/images/network/super rtl.png differ diff --git a/gui/slick/images/network/svt1.png b/gui/slick/images/network/svt1.png new file mode 100644 index 0000000000000000000000000000000000000000..67da0b5ccc45c1672f839aa6ae540cbf8d6c3c2e Binary files /dev/null and b/gui/slick/images/network/svt1.png differ diff --git a/gui/slick/images/network/swr hd.png b/gui/slick/images/network/swr hd.png new file mode 100644 index 0000000000000000000000000000000000000000..6793852ad3c1faea744b719c25809247072f74ef Binary files /dev/null and b/gui/slick/images/network/swr hd.png differ diff --git a/gui/slick/images/network/swr.png b/gui/slick/images/network/swr.png new file mode 100644 index 0000000000000000000000000000000000000000..c5547d5f212e003534aeadf0deccae068cbb5867 Binary files /dev/null and b/gui/slick/images/network/swr.png differ diff --git a/gui/slick/images/network/syndicated.png b/gui/slick/images/network/syndicated.png index feff12c6f85820bed2fb2657c45bbcb0afe32930..ece0dd551f17741aed21fa74fc9ffa2b945605bd 100644 Binary files a/gui/slick/images/network/syndicated.png and b/gui/slick/images/network/syndicated.png differ diff --git a/gui/slick/images/network/tagesschau24.png b/gui/slick/images/network/tagesschau24.png new file mode 100644 index 0000000000000000000000000000000000000000..9a812a07a2c2e2459dd6d2e726ff46fe5f0ff025 Binary files /dev/null and b/gui/slick/images/network/tagesschau24.png differ diff --git a/gui/slick/images/network/techtv canada.png b/gui/slick/images/network/techtv canada.png new file mode 100644 index 0000000000000000000000000000000000000000..7c5739273b12737429493565c851699633bad6d9 Binary files /dev/null and b/gui/slick/images/network/techtv canada.png differ diff --git a/gui/slick/images/network/tele 5 hd.png b/gui/slick/images/network/tele 5 hd.png new file mode 100644 index 0000000000000000000000000000000000000000..1d268f01d352e83c235c6c1be19b9173926a2fd1 Binary files /dev/null and b/gui/slick/images/network/tele 5 hd.png differ diff --git a/gui/slick/images/network/tele 5.png b/gui/slick/images/network/tele 5.png new file mode 100644 index 0000000000000000000000000000000000000000..74eca32ba84167e3adb5dadbf88f9d6743561c7b Binary files /dev/null and b/gui/slick/images/network/tele 5.png differ diff --git a/gui/slick/images/network/tf1.png b/gui/slick/images/network/tf1.png new file mode 100644 index 0000000000000000000000000000000000000000..2063d350754181fabc220e1929d72d52cf1a612d Binary files /dev/null and b/gui/slick/images/network/tf1.png differ diff --git a/gui/slick/images/network/the wb.png b/gui/slick/images/network/the wb.png index b575a09cbc08c15ea61faf65fa0f644cf4b09eda..a20f74bbb585b27fa25f083bb35d286d3c8a67b5 100644 Binary files a/gui/slick/images/network/the wb.png and b/gui/slick/images/network/the wb.png differ diff --git a/gui/slick/images/network/thewb.png b/gui/slick/images/network/thewb.png index b575a09cbc08c15ea61faf65fa0f644cf4b09eda..a20f74bbb585b27fa25f083bb35d286d3c8a67b5 100644 Binary files a/gui/slick/images/network/thewb.png and b/gui/slick/images/network/thewb.png differ diff --git a/gui/slick/images/network/tmf.png b/gui/slick/images/network/tmf.png deleted file mode 100644 index 8fc18f0290b847a94b0154557b2e4bc1af84cf33..0000000000000000000000000000000000000000 Binary files a/gui/slick/images/network/tmf.png and /dev/null differ diff --git a/gui/slick/images/network/tnt glitz.png b/gui/slick/images/network/tnt glitz.png new file mode 100644 index 0000000000000000000000000000000000000000..637bd7e1fea969fc49d71cc6e55b025f01f9fcad Binary files /dev/null and b/gui/slick/images/network/tnt glitz.png differ diff --git a/gui/slick/images/network/tnt serie.png b/gui/slick/images/network/tnt serie.png new file mode 100644 index 0000000000000000000000000000000000000000..7efcdd2795c12d149fe7e915d85a5af4994cc7ff Binary files /dev/null and b/gui/slick/images/network/tnt serie.png differ diff --git a/gui/slick/images/network/tokyo broadcasting system.png b/gui/slick/images/network/tokyo broadcasting system.png index 1792567faf689a27ff4cb66d5e9056358934c194..a1806d611a1926853e987104b41a0eaba92e30a1 100644 Binary files a/gui/slick/images/network/tokyo broadcasting system.png and b/gui/slick/images/network/tokyo broadcasting system.png differ diff --git a/gui/slick/images/network/tokyo mx.png b/gui/slick/images/network/tokyo mx.png index de1a8740718a3f9a0dbe08a79ff0c1fe41c36584..a4faf3826143bd1e0ce85286c48ae5fdd7ef10eb 100644 Binary files a/gui/slick/images/network/tokyo mx.png and b/gui/slick/images/network/tokyo mx.png differ diff --git a/gui/slick/images/network/tqs.png b/gui/slick/images/network/tqs.png new file mode 100644 index 0000000000000000000000000000000000000000..ec2a6970b13feb2cca31a6db06c38f9b656e7a51 Binary files /dev/null and b/gui/slick/images/network/tqs.png differ diff --git a/gui/slick/images/network/treehouse tv.png b/gui/slick/images/network/treehouse tv.png new file mode 100644 index 0000000000000000000000000000000000000000..4be61faa6d798f6d2286ae8dba0878a87fdf6925 Binary files /dev/null and b/gui/slick/images/network/treehouse tv.png differ diff --git a/gui/slick/images/network/tv 4.png b/gui/slick/images/network/tv 4.png new file mode 100644 index 0000000000000000000000000000000000000000..94195bd236dfb2a3381cb279ded8ef81ca58105f Binary files /dev/null and b/gui/slick/images/network/tv 4.png differ diff --git a/gui/slick/images/network/tv asahi.png b/gui/slick/images/network/tv asahi.png index ef2e2dbecdc1edf032978a6baccab2113f62feeb..ed9df360c1800b6689bed5319423b7cc7a601bd8 100644 Binary files a/gui/slick/images/network/tv asahi.png and b/gui/slick/images/network/tv asahi.png differ diff --git a/gui/slick/images/network/tv azteca.png b/gui/slick/images/network/tv azteca.png new file mode 100644 index 0000000000000000000000000000000000000000..854cc982bc80b5ac470a0b2e35682a0165bc75dc Binary files /dev/null and b/gui/slick/images/network/tv azteca.png differ diff --git a/gui/slick/images/network/tv guide channel.png b/gui/slick/images/network/tv guide channel.png new file mode 100644 index 0000000000000000000000000000000000000000..2ebc1827e72198d96cf8b3ba1304818ce8806c4a Binary files /dev/null and b/gui/slick/images/network/tv guide channel.png differ diff --git a/gui/slick/images/network/tv one nz.png b/gui/slick/images/network/tv one nz.png new file mode 100644 index 0000000000000000000000000000000000000000..f03bb94930019c906175ddc2ec13ea4423d2084f Binary files /dev/null and b/gui/slick/images/network/tv one nz.png differ diff --git a/gui/slick/images/network/tv west.png b/gui/slick/images/network/tv west.png index cb7370852e813c3514226bb6287139be01d7d204..0d64d9c3c8a29afcbf384b12fba7e84acaaf4d20 100644 Binary files a/gui/slick/images/network/tv west.png and b/gui/slick/images/network/tv west.png differ diff --git a/gui/slick/images/network/tv3, norway.png b/gui/slick/images/network/tv3, norway.png new file mode 100644 index 0000000000000000000000000000000000000000..9f0bb33d6877f5f2e0d4390c6847f43accfb5ff7 Binary files /dev/null and b/gui/slick/images/network/tv3, norway.png differ diff --git a/gui/slick/images/network/tv3.png b/gui/slick/images/network/tv3.png index 322818a117c0478413c07e6300938ff9a75807c2..84b134e357a3e2bb6fe94d0d1630e58b65614ad7 100644 Binary files a/gui/slick/images/network/tv3.png and b/gui/slick/images/network/tv3.png differ diff --git a/gui/slick/images/network/tv4.png b/gui/slick/images/network/tv4.png new file mode 100644 index 0000000000000000000000000000000000000000..91690236605bdbe537175d605ee261875c1316a3 Binary files /dev/null and b/gui/slick/images/network/tv4.png differ diff --git a/gui/slick/images/network/tv6.png b/gui/slick/images/network/tv6.png new file mode 100644 index 0000000000000000000000000000000000000000..f36d20b9e9f44b6a98da42c20bfe130617535849 Binary files /dev/null and b/gui/slick/images/network/tv6.png differ diff --git a/gui/slick/images/network/tvb.png b/gui/slick/images/network/tvb.png new file mode 100644 index 0000000000000000000000000000000000000000..0e980bfeb786daa2a5870f2ee2df1800b40c75fd Binary files /dev/null and b/gui/slick/images/network/tvb.png differ diff --git a/gui/slick/images/network/tvg network.png b/gui/slick/images/network/tvg network.png new file mode 100644 index 0000000000000000000000000000000000000000..bcf9316b2173900ecb31d19eb5f21c0ba28cd1c4 Binary files /dev/null and b/gui/slick/images/network/tvg network.png differ diff --git a/gui/slick/images/network/tvi.png b/gui/slick/images/network/tvi.png new file mode 100644 index 0000000000000000000000000000000000000000..fb7a5fc2a342684311525eb72932d40e3fb85583 Binary files /dev/null and b/gui/slick/images/network/tvi.png differ diff --git a/gui/slick/images/network/tvk.png b/gui/slick/images/network/tvk.png new file mode 100644 index 0000000000000000000000000000000000000000..8928c2cee35d1105a6812b370ce0c913190eae93 Binary files /dev/null and b/gui/slick/images/network/tvk.png differ diff --git a/gui/slick/images/network/tvn.png b/gui/slick/images/network/tvn.png new file mode 100644 index 0000000000000000000000000000000000000000..5e2e6c0930df579a66bd9b2be7ed295d0dd95df3 Binary files /dev/null and b/gui/slick/images/network/tvn.png differ diff --git a/gui/slick/images/network/tvnorge.png b/gui/slick/images/network/tvnorge.png new file mode 100644 index 0000000000000000000000000000000000000000..4a17b749b64ca746f81274aba86092c75cbad370 Binary files /dev/null and b/gui/slick/images/network/tvnorge.png differ diff --git a/gui/slick/images/network/tvnz.png b/gui/slick/images/network/tvnz.png new file mode 100644 index 0000000000000000000000000000000000000000..4088c445d84dec12015584b5d5f847b623f5d009 Binary files /dev/null and b/gui/slick/images/network/tvnz.png differ diff --git a/gui/slick/images/network/tvo.png b/gui/slick/images/network/tvo.png new file mode 100644 index 0000000000000000000000000000000000000000..c767542e05edbc2cd3177c4b4c1f25cb7ae26a65 Binary files /dev/null and b/gui/slick/images/network/tvo.png differ diff --git a/gui/slick/images/network/tvp sa.png b/gui/slick/images/network/tvp sa.png new file mode 100644 index 0000000000000000000000000000000000000000..9043c8d615eefa55569b02ef9f9f03e49b127946 Binary files /dev/null and b/gui/slick/images/network/tvp sa.png differ diff --git a/gui/slick/images/network/tvp1.png b/gui/slick/images/network/tvp1.png new file mode 100644 index 0000000000000000000000000000000000000000..78043863b46b2ddd4ae3cdb222c2def6645f0463 Binary files /dev/null and b/gui/slick/images/network/tvp1.png differ diff --git a/gui/slick/images/network/tvp2.png b/gui/slick/images/network/tvp2.png new file mode 100644 index 0000000000000000000000000000000000000000..84dea20fb50e60dd2f7339ab9c803b14354d7aa1 Binary files /dev/null and b/gui/slick/images/network/tvp2.png differ diff --git a/gui/slick/images/network/universal channel.png b/gui/slick/images/network/universal channel.png new file mode 100644 index 0000000000000000000000000000000000000000..c806132243d13c2a17ba486ff1045efd3cf86501 Binary files /dev/null and b/gui/slick/images/network/universal channel.png differ diff --git a/gui/slick/images/network/vara.png b/gui/slick/images/network/vara.png index 3f092ccc09b68f636e6a92732662d0a3919ecfe9..18a32dbacad6552e320d63f65d1ff9737a57bcb7 100644 Binary files a/gui/slick/images/network/vara.png and b/gui/slick/images/network/vara.png differ diff --git a/gui/slick/images/network/viva hd.png b/gui/slick/images/network/viva hd.png new file mode 100644 index 0000000000000000000000000000000000000000..dccd438f202348b777e75cadec91453b6b078e92 Binary files /dev/null and b/gui/slick/images/network/viva hd.png differ diff --git a/gui/slick/images/network/viva.png b/gui/slick/images/network/viva.png new file mode 100644 index 0000000000000000000000000000000000000000..4659368464115984888dad8b0a19962d8c3d4d4c Binary files /dev/null and b/gui/slick/images/network/viva.png differ diff --git a/gui/slick/images/network/vox hd.png b/gui/slick/images/network/vox hd.png new file mode 100644 index 0000000000000000000000000000000000000000..1f5d157fc1761253ea35e6da70cb23dad886de21 Binary files /dev/null and b/gui/slick/images/network/vox hd.png differ diff --git a/gui/slick/images/network/vox.png b/gui/slick/images/network/vox.png index 7dd7bf7ceb5b6c32e66f42aff19c0980abcc8f6d..491694018467290399aeafc80dae42c7583b188b 100644 Binary files a/gui/slick/images/network/vox.png and b/gui/slick/images/network/vox.png differ diff --git a/gui/slick/images/network/vpro.png b/gui/slick/images/network/vpro.png index 3d7bb05ef194421baf489839d6f4e53199b4724e..f37b71f27f7adb54701adf1ba6f6c167c0f12ec8 100644 Binary files a/gui/slick/images/network/vpro.png and b/gui/slick/images/network/vpro.png differ diff --git a/gui/slick/images/network/vrak.tv.png b/gui/slick/images/network/vrak.tv.png new file mode 100644 index 0000000000000000000000000000000000000000..23bdbb2e8c9b8304ebd1da4b5d982e47c7e51b66 Binary files /dev/null and b/gui/slick/images/network/vrak.tv.png differ diff --git a/gui/slick/images/network/wdr hd.png b/gui/slick/images/network/wdr hd.png new file mode 100644 index 0000000000000000000000000000000000000000..d78c900f86ba59652b9d8e138c70eb06dda786ed Binary files /dev/null and b/gui/slick/images/network/wdr hd.png differ diff --git a/gui/slick/images/network/wdr.png b/gui/slick/images/network/wdr.png new file mode 100644 index 0000000000000000000000000000000000000000..0a2dd0e1eab1a1451a7012edbe61c4a611c9c18c Binary files /dev/null and b/gui/slick/images/network/wdr.png differ diff --git a/gui/slick/images/network/wgn america.png b/gui/slick/images/network/wgn america.png index 6ad66eb8a3dc9fc81d0aa7917495bcfec200a40a..e7318704677bd333931ebaaf15ee7fc120eaa0f7 100644 Binary files a/gui/slick/images/network/wgn america.png and b/gui/slick/images/network/wgn america.png differ diff --git a/gui/slick/images/network/xebec.png b/gui/slick/images/network/xebec.png index 3e2a295cb9718b45050f9ca2eed0ba8c43ce92f4..dd9620c969b9f16e5e43e1c7a1909271b75889a0 100644 Binary files a/gui/slick/images/network/xebec.png and b/gui/slick/images/network/xebec.png differ diff --git a/gui/slick/images/network/ytv.png b/gui/slick/images/network/ytv.png new file mode 100644 index 0000000000000000000000000000000000000000..62409ea5c05f81f58103e750f079465b25be0fa7 Binary files /dev/null and b/gui/slick/images/network/ytv.png differ diff --git a/gui/slick/images/network/zdf hd.png b/gui/slick/images/network/zdf hd.png new file mode 100644 index 0000000000000000000000000000000000000000..bafb93fdef414b71186756042d4545dc24b4841e Binary files /dev/null and b/gui/slick/images/network/zdf hd.png differ diff --git a/gui/slick/images/network/zdf.kultur hd.png b/gui/slick/images/network/zdf.kultur hd.png new file mode 100644 index 0000000000000000000000000000000000000000..fc6b2018af8a42f6309089562f5d4aae37a39ea0 Binary files /dev/null and b/gui/slick/images/network/zdf.kultur hd.png differ diff --git a/gui/slick/images/network/zdf.kultur.png b/gui/slick/images/network/zdf.kultur.png new file mode 100644 index 0000000000000000000000000000000000000000..ef252d8d9659a3737d81171665114930403367c4 Binary files /dev/null and b/gui/slick/images/network/zdf.kultur.png differ diff --git a/gui/slick/images/network/zdfinfo hd.png b/gui/slick/images/network/zdfinfo hd.png new file mode 100644 index 0000000000000000000000000000000000000000..9c38daf86cea83c3fa729a93b0da7da8c7b263f5 Binary files /dev/null and b/gui/slick/images/network/zdfinfo hd.png differ diff --git a/gui/slick/images/network/zdfinfo.png b/gui/slick/images/network/zdfinfo.png new file mode 100644 index 0000000000000000000000000000000000000000..95933a288b49b3345b8adede56286c60ebb6ff4a Binary files /dev/null and b/gui/slick/images/network/zdfinfo.png differ diff --git a/gui/slick/images/network/zdfneo hd.png b/gui/slick/images/network/zdfneo hd.png new file mode 100644 index 0000000000000000000000000000000000000000..f99b505dcf414aee15e46ffb534f6658bfbc54c3 Binary files /dev/null and b/gui/slick/images/network/zdfneo hd.png differ diff --git a/gui/slick/images/network/zdfneo.png b/gui/slick/images/network/zdfneo.png new file mode 100644 index 0000000000000000000000000000000000000000..eadc4075431b959738c8a4957be6eb053e4387e4 Binary files /dev/null and b/gui/slick/images/network/zdfneo.png differ diff --git a/gui/slick/images/providers/alpharatio.png b/gui/slick/images/providers/alpharatio.png new file mode 100644 index 0000000000000000000000000000000000000000..cd579d850ef88fa2941478434a312aa0a9d41c74 Binary files /dev/null and b/gui/slick/images/providers/alpharatio.png differ diff --git a/gui/slick/images/providers/rarbg.png b/gui/slick/images/providers/rarbg.png new file mode 100644 index 0000000000000000000000000000000000000000..17fea244ce0e2cc42b69bb65c4e376741f36682e Binary files /dev/null and b/gui/slick/images/providers/rarbg.png differ diff --git a/gui/slick/images/providers/shazbat.png b/gui/slick/images/providers/shazbat.png new file mode 100644 index 0000000000000000000000000000000000000000..8f86095cc25f5867d34897e72bf0313eed33cba4 Binary files /dev/null and b/gui/slick/images/providers/shazbat.png differ diff --git a/gui/slick/images/providers/tntvillage.png b/gui/slick/images/providers/tntvillage.png new file mode 100644 index 0000000000000000000000000000000000000000..4a143fc5e6d4977b165b98f51c9b034d472fb990 Binary files /dev/null and b/gui/slick/images/providers/tntvillage.png differ diff --git a/gui/slick/images/providers/tokyotoshokan.png b/gui/slick/images/providers/tokyotoshokan.png index 66e8c7bf48f4a6f5e56c499f503a4ece9ff53df7..51628a61e12c80e183b40229fc642677a3213cff 100644 Binary files a/gui/slick/images/providers/tokyotoshokan.png and b/gui/slick/images/providers/tokyotoshokan.png differ diff --git a/gui/slick/interfaces/default/config_general.tmpl b/gui/slick/interfaces/default/config_general.tmpl index 2a9b6d574fd6d6929a2ce8ad343e2668fb4b169f..a42dad039b965463c989f1eaa042c9b0efa1dd07 100644 --- a/gui/slick/interfaces/default/config_general.tmpl +++ b/gui/slick/interfaces/default/config_general.tmpl @@ -63,6 +63,16 @@ </label> </div> + <div class="field-pair"> + <label for="showupdate_hour"> + <span class="component-title">When to update shows</span> + <span class="component-desc"> + <input type="text" name="showupdate_hour" id="showupdate_hour" value="$sickbeard.SHOWUPDATE_HOUR" class="form-control input-sm input75" /> + <p>with information such as next air dates, show ended, etc. Use 15 for 3pm, 4 for 4am etc. Anything over 23 or under 0 will be set to 0 (12am)</p> + </span> + </label> + </div> + <div class="field-pair"> <label for="update_shows_on_start"> <span class="component-title">Update shows on startup</span> diff --git a/gui/slick/interfaces/default/config_postProcessing.tmpl b/gui/slick/interfaces/default/config_postProcessing.tmpl index 43c0015adf9ed69c765e5eba72f497528374372a..d6b70956eccb2f0a87a7074bff57fcbd35f0ae08 100644 --- a/gui/slick/interfaces/default/config_postProcessing.tmpl +++ b/gui/slick/interfaces/default/config_postProcessing.tmpl @@ -83,6 +83,13 @@ <span class="component-desc">What method should be used to put file in the TV directory?</span> </label> </div> + <div class="field-pair"> + <input type="checkbox" name="del_rar_contents" id="del_rar_contents" #if $sickbeard.DELRARCONTENTS == True then "checked=\"checked\"" else ""# /> + <label for="del_rar_contents"> + <span class="component-title">Delete RAR contents</span> + <span class="component-desc">Delete content of RAR files, even if Process Method not set to move?</span> + </label> + </div> <div class="field-pair"> <input type="checkbox" name="skip_removed_files" id="skip_removed_files" #if $sickbeard.SKIP_REMOVED_FILES == True then "checked=\"checked\"" else ""# /> <label for="skip_removed_files"> @@ -116,12 +123,21 @@ <span class="component-desc">Move srr/srt/sfv/etc files with the episode when processed?</span> </label> </div> - + <div class="field-pair"> + <label class="nocheck"> + <span class="component-title">Sync File Extensions</span> + <input type="text" name="sync_files" id="sync_files" value="$sickbeard.SYNC_FILES" class="form-control input-sm input350" /> + </label> + <label class="nocheck"> + <span class="component-title"> </span> + <span class="component-desc">comma seperated list of extensions SickRage ignores when Post Processing</span> + </label> + </div> <div class="field-pair"> <input type="checkbox" name="postpone_if_sync_files" id="postpone_if_sync_files" #if $sickbeard.POSTPONE_IF_SYNC_FILES == True then "checked=\"checked\"" else ""# /> <label for="postpone_if_sync_files"> <span class="component-title">Postpone post processing</span> - <span class="component-desc">if !sync files are present in the TV download dir</span> + <span class="component-desc">if sync files are present in the TV download dir</span> </label> </div> diff --git a/gui/slick/interfaces/default/config_providers.tmpl b/gui/slick/interfaces/default/config_providers.tmpl index 35d3894617128d6ea7d56cf6aebd7a1688c59965..ef5bc13c72fb452eb4c187372b50d4adf118bd38 100644 --- a/gui/slick/interfaces/default/config_providers.tmpl +++ b/gui/slick/interfaces/default/config_providers.tmpl @@ -115,7 +115,7 @@ var show_nzb_providers = #if $sickbeard.USE_NZBS then "true" else "false"#; <fieldset class="component-group-list"> <div class="field-pair"> - <label for="editAProvider"> + <label for="editAProvider" id="provider-list"> <span class="component-title">Configure provider:</span> <span class="component-desc"> #set $provider_config_list = [] @@ -530,6 +530,33 @@ var show_nzb_providers = #if $sickbeard.USE_NZBS then "true" else "false"#; </div> #end if + #if $hasattr($curTorrentProvider, 'cat') and $curTorrentProvider.getID() == 'tntvillage': + <div class="field-pair"> + <label for="${curTorrentProvider.getID()}_cat"> + <span class="component-title">Category:</span> + <span class="component-desc"> + <select name="${curTorrentProvider.getID()}_cat" id="${curTorrentProvider.getID()}_cat" class="form-control input-sm"> + #for $i in $curTorrentProvider.category_dict.keys(): + <option value="$curTorrentProvider.category_dict[$i]" #if $curTorrentProvider.category_dict[$i] == $curTorrentProvider.cat then "selected=\"selected\"" else ""#>$i</option> + #end for + </select> + </span> + </label> + </div> + #end if + + #if $hasattr($curTorrentProvider, 'subtitle') and $curTorrentProvider.getID() == 'tntvillage': + <div class="field-pair"> + <label for="${curTorrentProvider.getID()}_subtitle"> + <span class="component-title">Subtitled</span> + <span class="component-desc"> + <input type="checkbox" name="${curTorrentProvider.getID()}_subtitle" id="${curTorrentProvider.getID()}_subtitle" #if $curTorrentProvider.subtitle then "checked=\"checked\"" else ""#/> + <p>select torrent with Italian subtitle</p> + </span> + </label> + </div> + #end if + </div> #end for @@ -586,7 +613,7 @@ var show_nzb_providers = #if $sickbeard.USE_NZBS then "true" else "false"#; </label> </div> - <div class="field-pair"> + <div class="field-pair" id="newznabcapdiv"> <label> <span class="component-title">Newznab search categories:</span> <select id="newznab_cap" multiple="multiple" style="min-width:10em;" ></select> @@ -598,7 +625,9 @@ var show_nzb_providers = #if $sickbeard.USE_NZBS then "true" else "false"#; </label> <label> <span class="component-title"> </span> - <span class="component-desc"><input class="btn" type="button" class="newznab_cat_update" id="newznab_cat_update" value="Update Categories" /></span> + <span class="component-desc"><input class="btn" type="button" class="newznab_cat_update" id="newznab_cat_update" value="Update Categories" /> + <span class="updating_categories"></span> + </span> </label> </div> @@ -671,7 +700,7 @@ var show_nzb_providers = #if $sickbeard.USE_NZBS then "true" else "false"#; </div><!-- /component-group4 //--> #end if - <br/><input type="submit" class="btn config_submitter" value="Save Changes" /><br/> + <br/><input type="submit" class="btn config_submitter_refresh" value="Save Changes" /><br/> </div><!-- /config-components //--> diff --git a/gui/slick/interfaces/default/config_search.tmpl b/gui/slick/interfaces/default/config_search.tmpl index c41bb3310182b0c8bb4065841ea0df8d7cfc6d9e..62dd066b7c38d4ddb2e0aec540debf1668aaeb8e 100755 --- a/gui/slick/interfaces/default/config_search.tmpl +++ b/gui/slick/interfaces/default/config_search.tmpl @@ -166,6 +166,33 @@ </span> </label> </div> + + <div class="field-pair"> + <input id="use_failed_downloads" type="checkbox" class="enabler" name="use_failed_downloads" #if $sickbeard.USE_FAILED_DOWNLOADS == True then "checked=\"checked\"" else ""# /> + <label for="use_failed_downloads"> + <span class="component-title">Use Failed Downloads</span> + <span class="component-desc">Use Failed Download Handling?</span> + </label> + <label class="nocheck" for="use_failed_downloads"> + <span class="component-title"> </span> + <span class="component-desc">Will only work with snatched/downloaded episodes after enabling this</span> + <span class="component-desc"><b>NOTE:</b> See <i>readme-FailedDownloads.md</i> before enabling.</span> + </label> + </div> + + <div id="content_use_failed_downloads"> + <div class="field-pair"> + <input id="delete_failed" type="checkbox" name="delete_failed" #if $sickbeard.DELETE_FAILED == True then "checked=\"checked\"" else ""# /> + <label for="delete_failed"> + <span class="component-title">Delete Failed</span> + <span class="component-desc">Delete files left over from a failed download?</span> + </label> + <label class="nocheck" for="delete_failed"> + <span class="component-title"> </span> + <span class="component-desc"><b>NOTE:</b> This only works if Use Failed Downloads is enabled.</span> + </label> + </div> + </div> <input type="submit" class="btn config_submitter" value="Save Changes" /> @@ -466,12 +493,29 @@ </label> </div> + <div class="field-pair" id="torrent_auth_type"> + <label> + <span class="component-title">Http Authentication</span> + <span class="component-desc"> + <select name="torrent_auth_type" id="torrent_auth_type" class="form-control input-sm"> + #set $http_authtype = {'none': "None", 'basic': "Basic", 'digest': "Digest"} + #for $authvalue,$authname in $http_authtype.items(): + #set $selected = $html_selected if $sickbeard.TORRENT_AUTH_TYPE == $authvalue else '' + <option value="$authvalue"$selected>$authname</option> + #end for + </select> + <p></p> + </span> + </label> + </div> + <div class="field-pair" id="torrent_verify_cert_option"> <label for="torrent_verify_cert"> <span class="component-title">Verify certificate</span> <span class="component-desc"> <input type="checkbox" name="torrent_verify_cert" class="enabler" id="torrent_verify_cert" <%= html_checked if sickbeard.TORRENT_VERIFY_CERT == True else '' %>/> - <p>disable if you get "Deluge: Authentication Error" in your log</p> + <p id="torrent_verify_deluge">disable if you get "Deluge: Authentication Error" in your log</p> + <p id="torrent_verify_rtorrent">Verify SSL certificates for HTTPS requests</p> </span> </label> </div> diff --git a/gui/slick/interfaces/default/displayShow.tmpl b/gui/slick/interfaces/default/displayShow.tmpl index dfc2b23782a80c595102d8daecaae36583827c44..510fffbd6eecf8790f34d0548582f9317509cb7d 100644 --- a/gui/slick/interfaces/default/displayShow.tmpl +++ b/gui/slick/interfaces/default/displayShow.tmpl @@ -381,7 +381,7 @@ #end if >Name</th> #if ($sickbeard.DISPLAY_FILESIZE == True): - <th class="col-ep">Filesize</th> + <th class="col-ep">Size</th> #end if <th class="col-airdate">Airdate</th> #if $sickbeard.DOWNLOAD_URL @@ -481,8 +481,8 @@ #if ($sickbeard.DISPLAY_FILESIZE == True): <td class="col-ep"> #if $epResult["file_size"]: - #set $file_size = $epResult["file_size"] / 1024 / 1024 - $file_size MB + #set $file_size = $sickbeard.helpers.pretty_filesize($epResult["file_size"]) + $file_size #end if </td> #end if diff --git a/gui/slick/interfaces/default/editShow.tmpl b/gui/slick/interfaces/default/editShow.tmpl index 21eda7d3f0c0bf37bdf6bf800dccfbc77956d5a6..a48f482fe71cf9c6af5156f53b727da0583fd6e4 100644 --- a/gui/slick/interfaces/default/editShow.tmpl +++ b/gui/slick/interfaces/default/editShow.tmpl @@ -16,51 +16,16 @@ #if $varExists('header') - <h1 class="header">$header</h1> + <h1 class="header">$header</h1> #else - <h1 class="title">$title</h1> + <h1 class="title">$title</h1> #end if <div id="editShow"> <script type="text/javascript" src="$sbRoot/js/qualityChooser.js?$sbPID"></script> -<script type="text/javascript" charset="utf-8"> -<!-- -\$(document).ready(function(){ - - \$.getJSON('$sbRoot/home/addShows/getIndexerLanguages', {}, function(data) { - var resultStr = ''; - - if (data.results.length == 0) { - flag = ' class="flag" style="background-image:url($sbRoot/images/flags/${show.lang}.png)"'; - resultStr = '<option value="$show.lang" selected="selected" + flag>$show.lang</option>'; - } else { - var current_lang_added = false; - \$.each(data.results, function(index, obj) { - - if (obj == "$show.lang") { - selected = ' selected="selected"'; - current_lang_added = true; - } - else { - selected = ''; - } - - flag = ' class="flag" style="background-image:url($sbRoot/images/flags/' + obj + '.png);"'; - resultStr += '<option value="' + obj + '"' + selected + flag + '>' + obj + '</option>'; - }); - if (!current_lang_added) - resultStr += '<option value="$show.lang" selected="selected">$show.lang</option>'; - - } - \$('#indexerLangSelect').html(resultStr) - - }); - -}); -//--> -</script> +<script type="text/javascript" src="$sbRoot/js/lib/bootstrap-formhelpers.min-2.3.0.js?$sbPID"></script> + -<br> <form action="editShow" method="post"> <input type="hidden" name="show" value="$show.indexerid" /> @@ -73,22 +38,22 @@ <input class="btn btn-inline" type="button" value="Add" id="addSceneName"><br /> <div id="SceneException" > - <div> - <p>This will <b>affect the episode show search</b> on nzb and torrent provider.<br /> - This list overrides the original name, it doesn't append to it.<br /> - </p> - </div> - - <div class="pull-left" style="text-align:center;"> - <h4>Exceptions List</h4> - <select id="exceptions_list" name="exceptions_list" multiple="multiple" style="min-width:10em;" > - #for $cur_exception in $show.exceptions: - <option value="$cur_exception">$cur_exception</option> - #end for - </select> - <div> - <input id="removeSceneName" value="Remove" class="btn float-left" type="button" style="margin-top: 10px;"/> - </div> + <div> + <p>This will <b>affect the episode show search</b> on nzb and torrent provider.<br /> + This list overrides the original name, it doesn't append to it.<br /> + </p> + </div> + + <div class="pull-left" style="text-align:center;"> + <h4>Exceptions List</h4> + <select id="exceptions_list" name="exceptions_list" multiple="multiple" style="min-width:10em;" > + #for $cur_exception in $show.exceptions: + <option value="$cur_exception">$cur_exception</option> + #end for + </select> + <div> + <input id="removeSceneName" value="Remove" class="btn float-left" type="button" style="margin-top: 10px;"/> + </div> <br /> </div> </div> @@ -113,7 +78,7 @@ <b>Info Language:</b><br /> (this will only affect the language of the retrieved metadata file contents and episode filenames)<br /> -<select name="indexerLang" id="indexerLangSelect" class="form-control form-control-inline input-sm"></select><br /> +<select name="indexerLang" id="indexerLangSelect" class="form-control form-control-inline input-sm bfh-languages" data-language="en" data-available="#echo ','.join($sickbeard.indexerApi().config['valid_languages'])#"></select><br /> <br /> <b>Flatten files (no folders):</b> <input type="checkbox" name="flatten_folders" #if $show.flatten_folders == 1 and not $sickbeard.NAMING_FORCE_FOLDERS then "checked=\"checked\"" else ""# #if $sickbeard.NAMING_FORCE_FOLDERS then "disabled=\"disabled\"" else ""#/><br /> @@ -178,49 +143,49 @@ Separate words with a comma, e.g. "word1,word2,word3"<br /> <script type="text/javascript" charset="utf-8"> <!-- - var all_exceptions = new Array; + var all_exceptions = new Array; jQuery('#location').fileBrowser({ title: 'Select Show Location' }); \$('#submit').click(function(){ - all_exceptions = [] + all_exceptions = [] - \$("#exceptions_list option").each ( function() { - all_exceptions.push( \$(this).val() ); - }); - - \$("#exceptions_list").val(all_exceptions); + \$("#exceptions_list option").each ( function() { + all_exceptions.push( \$(this).val() ); + }); + + \$("#exceptions_list").val(all_exceptions); var realvalues = []; - \$('#white option').each(function(i, selected) { - realvalues[i] = \$(selected).val(); - }); - \$("#whitelist").val(realvalues.join(",")); + \$('#white option').each(function(i, selected) { + realvalues[i] = \$(selected).val(); + }); + \$("#whitelist").val(realvalues.join(",")); - realvalues = []; - \$('#black option').each(function(i, selected) { - realvalues[i] = \$(selected).val(); - }); - \$("#blacklist").val(realvalues.join(",")); + realvalues = []; + \$('#black option').each(function(i, selected) { + realvalues[i] = \$(selected).val(); + }); + \$("#blacklist").val(realvalues.join(",")); - }); + }); \$('#addSceneName').click(function() { var scene_ex = \$('#SceneName').val() var option = \$("<option>") - all_exceptions = [] - - \$("#exceptions_list option").each ( function() { - all_exceptions.push( \$(this).val() ) - }); + all_exceptions = [] + + \$("#exceptions_list option").each ( function() { + all_exceptions.push( \$(this).val() ) + }); \$('#SceneName').val('') if (jQuery.inArray(scene_ex, all_exceptions) > -1 || (scene_ex == '')) - return + return - \$("#SceneException").show() + \$("#SceneException").show() option.attr("value",scene_ex) option.html(scene_ex) @@ -228,39 +193,39 @@ Separate words with a comma, e.g. "word1,word2,word3"<br /> }); \$('#removeSceneName').click(function() { - \$('#exceptions_list option:selected').remove(); - - \$(this).toggle_SceneException() + \$('#exceptions_list option:selected').remove(); + + \$(this).toggle_SceneException() }); $.fn.toggle_SceneException = function() { - all_exceptions = [] - - \$("#exceptions_list option").each ( function() { - all_exceptions.push( \$(this).val() ); - }); - - if (all_exceptions == '') - \$("#SceneException").hide(); - else - \$("#SceneException").show(); - } - - \$(this).toggle_SceneException(); + all_exceptions = [] + + \$("#exceptions_list option").each ( function() { + all_exceptions.push( \$(this).val() ); + }); + + if (all_exceptions == '') + \$("#SceneException").hide(); + else + \$("#SceneException").show(); + } + + \$(this).toggle_SceneException(); \$('#removeW').click(function() { - return !\$('#white option:selected').remove().appendTo('#pool'); - }); - \$('#addW').click(function() { - return !\$('#pool option:selected').remove().appendTo('#white'); - }); - \$('#addB').click(function() { - return !\$('#pool option:selected').remove().appendTo('#black'); - }); + return !\$('#white option:selected').remove().appendTo('#pool'); + }); + \$('#addW').click(function() { + return !\$('#pool option:selected').remove().appendTo('#white'); + }); + \$('#addB').click(function() { + return !\$('#pool option:selected').remove().appendTo('#black'); + }); \$('#removeP').click(function() { return !\$('#pool option:selected').remove(); }); - \$('#removeB').click(function() { + \$('#removeB').click(function() { return !\$('#black option:selected').remove().appendTo('#pool'); }); diff --git a/gui/slick/interfaces/default/home_newShow.tmpl b/gui/slick/interfaces/default/home_newShow.tmpl index e41bd8f0cc3dbdfa911f03d94bd211159676b233..651d7a0133fa08feb86b7b0badf4678d5d012f6f 100644 --- a/gui/slick/interfaces/default/home_newShow.tmpl +++ b/gui/slick/interfaces/default/home_newShow.tmpl @@ -17,6 +17,7 @@ <script type="text/javascript" src="$sbRoot/js/qualityChooser.js?$sbPID"></script> <script type="text/javascript" src="$sbRoot/js/newShow.js?$sbPID"></script> <script type="text/javascript" src="$sbRoot/js/addShowOptions.js?$sbPID"></script> +<script type="text/javascript" src="$sbRoot/js/lib/bootstrap-formhelpers.min-2.3.0.js?$sbPID"></script> #if $varExists('header') <h1 class="header">$header</h1> @@ -53,8 +54,7 @@ <input type="text" id="nameToSearch" value="$default_show_name" class="form-control form-control-inline input-sm input350" /> - <select name="indexerLang" id="indexerLangSelect" class="form-control form-control-inline input-sm"> - <option value="en" selected="selected">en</option> + <select name="indexerLang" id="indexerLangSelect" class="form-control form-control-inline input-sm bfh-languages" data-language="en" data-available="#echo ','.join($sickbeard.indexerApi().config['valid_languages'])#"> </select><b>*</b> <select name="providedIndexer" id="providedIndexer" class="form-control form-control-inline input-sm"> diff --git a/gui/slick/interfaces/default/home_trendingShows.tmpl b/gui/slick/interfaces/default/home_trendingShows.tmpl index cd483fa43c5cc57c6f3ad924c25cb3b814397413..d0a1da711588aa40e0ec051913eabae73f54b325 100644 --- a/gui/slick/interfaces/default/home_trendingShows.tmpl +++ b/gui/slick/interfaces/default/home_trendingShows.tmpl @@ -10,7 +10,7 @@ #set global $sbPath='..' -#set global $topmenu='comingEpisodes' +#set global $topmenu='home' #import os.path #include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_top.tmpl') diff --git a/gui/slick/interfaces/default/inc_top.tmpl b/gui/slick/interfaces/default/inc_top.tmpl index e8beb9b1000323b68fe39d38fb88d85cb9b9116d..e67363a9b98535416a3dac990465a42c8afc6731 100644 --- a/gui/slick/interfaces/default/inc_top.tmpl +++ b/gui/slick/interfaces/default/inc_top.tmpl @@ -90,7 +90,9 @@ \$("#SubMenu a:contains('Clear History')").addClass('btn clearhistory').html('<span class="ui-icon ui-icon-trash pull-left"></span> Clear History'); \$("#SubMenu a:contains('Trim History')").addClass('btn trimhistory').html('<span class="ui-icon ui-icon-trash pull-left"></span> Trim History'); \$("#SubMenu a[href$='/errorlogs/clearerrors/']").addClass('btn').html('<span class="ui-icon ui-icon-trash pull-left"></span> Clear Errors'); + #if sickbeard.GIT_USERNAME and sickbeard.GIT_PASSWORD and sickbeard.GIT_AUTOISSUES == 1: \$("#SubMenu a[href$='/errorlogs/submit_errors/']").addClass('btn').html('<span class="ui-icon ui-icon-arrowreturnthick-1-n pull-left"></span> Submit Errors'); + #end if \$("#SubMenu a:contains('Re-scan')").addClass('btn').html('<span class="ui-icon ui-icon-refresh pull-left"></span> Re-scan'); \$("#SubMenu a:contains('Backlog Overview')").addClass('btn').html('<span class="ui-icon ui-icon-refresh pull-left"></span> Backlog Overview'); \$("#SubMenu a[href$='/home/updatePLEX/']").addClass('btn').html('<span class="ui-icon ui-icon-refresh pull-left"></span> Update PLEX'); diff --git a/gui/slick/interfaces/default/viewlogs.tmpl b/gui/slick/interfaces/default/viewlogs.tmpl index 9ef73ebe8caa4168af6366f4c3b0ecf034107bb7..09daab09239ce02d795d41ef8000c59e9a09b08c 100644 --- a/gui/slick/interfaces/default/viewlogs.tmpl +++ b/gui/slick/interfaces/default/viewlogs.tmpl @@ -13,10 +13,51 @@ <script type="text/javascript" charset="utf-8"> <!-- -\$(document).ready(function(){ - \$('#minLevel').change(function(){ - url = '$sbRoot/errorlogs/viewlog/?minLevel='+\$(this).val() +\$(document).ready( + +function(){ + \$('#minLevel,#logFilter,#logSearch').change(function(){ + if ( \$('#logSearch').val().length > 0 ) { + \$('#logSearch').prop('disabled', true); + \$('#logFilter option[value=\\<NONE\\>]').prop('selected', true); + \$('#minLevel option[value=5]').prop('selected', true); + } + \$('#minLevel').prop('disabled', true); + \$('#logFilter').prop('disabled', true); + \$('#logSearch').prop('disabled', true); + document.body.style.cursor='wait' + url = '$sbRoot/errorlogs/viewlog/?minLevel='+\$('select[name=minLevel]').val()+'&logFilter='+\$('select[name=logFilter]').val()+'&logSearch='+\$('#logSearch').val() window.location.href = url + + }); + + \$(window).load(function(){ + + if ( \$('#logSearch').val().length == 0 ) { + \$('#minLevel').prop('disabled', false); + \$('#logFilter').prop('disabled', false); + \$('#logSearch').prop('disabled', false); + } else { + \$('#minLevel').prop('disabled', true); + \$('#logFilter').prop('disabled', true); + \$('#logSearch').prop('disabled', false); + } + + document.body.style.cursor='default'; + }); + + \$('#logSearch').keyup(function() { + if ( \$('#logSearch').val().length == 0 ) { + \$('#logFilter option[value=\\<NONE\\>]').prop('selected', true); + \$('#minLevel option[value=20]').prop('selected', true); + \$('#minLevel').prop('disabled', false); + \$('#logFilter').prop('disabled', false); + url = '$sbRoot/errorlogs/viewlog/?minLevel='+\$('select[name=minLevel]').val()+'&logFilter='+\$('select[name=logFilter]').val()+'&logSearch='+\$('#logSearch').val() + window.location.href = url + } else { + \$('#minLevel').prop('disabled', true); + \$('#logFilter').prop('disabled', true); + } }); }); //--> @@ -35,6 +76,14 @@ $levels.sort(lambda x,y: cmp($reverseNames[$x], $reverseNames[$y])) <option value="$reverseNames[$level]" #if $minLevel == $reverseNames[$level] then "selected=\"selected\"" else ""#>$level.title()</option> #end for </select> + +Filter log by: <select name="logFilter" id="logFilter" class="form-control form-control-inline input-sm"> +#for $logNameFilter in sorted($logNameFilters) +<option value="$logNameFilter" #if $logFilter == $logNameFilter then "selected=\"selected\"" else ""#>$logNameFilters[$logNameFilter]</option> +#end for +</select> +Search log by: +<input type="text" name="logSearch" id="logSearch" value="#if $logSearch then $logSearch else ""#" class="form-control form-control-inline input-sm" /> </div> <br /> <div class="align-left"><pre> @@ -48,10 +97,4 @@ window.setInterval( "location.reload(true)", 600000); // Refresh every 10 minute //--> </script> -<script type="text/javascript" charset="utf-8"> -<!-- -window.setInterval( "location.reload(true)", 600000); // Refresh every 10 minutes -//--> -</script> - #include $os.path.join($sickbeard.PROG_DIR,"gui/slick/interfaces/default/inc_bottom.tmpl") diff --git a/gui/slick/js/ajaxEpSearch.js b/gui/slick/js/ajaxEpSearch.js index 5cb697d6a9bb8a01b0fa8dd579ab697e7d012a94..6aa2db662e092a45cbcc21384360421bfa5e0c00 100644 --- a/gui/slick/js/ajaxEpSearch.js +++ b/gui/slick/js/ajaxEpSearch.js @@ -5,29 +5,32 @@ $.fn.manualSearches = []; function check_manual_searches() { var poll_interval = 5000; - $.ajax({ - url: search_status_url + '?show=' + $('#showID').val(), - success: function (data) { - if (data.episodes) { - poll_interval = 5000; - } - else { - poll_interval = 15000; - } - - updateImages(data); - //cleanupManualSearches(data); - }, - error: function () { - poll_interval = 30000; - }, - type: "GET", - dataType: "json", - complete: function () { - setTimeout(check_manual_searches, poll_interval); - }, - timeout: 15000 // timeout every 15 secs - }); + showId = $('#showID').val() + if ( showId !== undefined) { + $.ajax({ + url: search_status_url + '?show=' + showId, + success: function (data) { + if (data.episodes) { + poll_interval = 5000; + } + else { + poll_interval = 15000; + } + + updateImages(data); + //cleanupManualSearches(data); + }, + error: function () { + poll_interval = 30000; + }, + type: "GET", + dataType: "json", + complete: function () { + setTimeout(check_manual_searches, poll_interval); + }, + timeout: 15000 // timeout every 15 secs + }); + } } @@ -45,9 +48,9 @@ function updateImages(data) { if (el) { if (ep.searchstatus == 'searching') { //el=$('td#' + ep.season + 'x' + ep.episode + '.search img'); - img.attr('title','Searching'); - img.attr('alt','earching'); - img.attr('src',sbRoot+'/images/' + loadingImage); + img.prop('title','Searching'); + img.prop('alt','Searching'); + img.prop('src',sbRoot+'/images/' + loadingImage); disableLink(el); // Update Status and Quality var rSearchTerm = /(\w+)\s\((.+?)\)/; @@ -56,23 +59,24 @@ function updateImages(data) { } else if (ep.searchstatus == 'queued') { //el=$('td#' + ep.season + 'x' + ep.episode + '.search img'); - img.attr('title','Queued'); - img.attr('alt','queued'); - img.attr('src',sbRoot+'/images/' + queuedImage ); + img.prop('title','Queued'); + img.prop('alt','queued'); + img.prop('src',sbRoot+'/images/' + queuedImage ); disableLink(el); HtmlContent = ep.searchstatus; } else if (ep.searchstatus == 'finished') { //el=$('td#' + ep.season + 'x' + ep.episode + '.search img'); - img.attr('title','Searching'); - img.attr('alt','searching'); - img.parent().attr('class','epRetry'); - img.attr('src',sbRoot+'/images/' + searchImage); + img.prop('title','Searching'); + img.prop('alt','searching'); + img.parent().prop('class','epRetry'); + img.prop('src',sbRoot+'/images/' + searchImage); enableLink(el); // Update Status and Quality var rSearchTerm = /(\w+)\s\((.+?)\)/; HtmlContent = ep.status.replace(rSearchTerm,"$1"+' <span class="quality '+ep.quality+'">'+"$2"+'</span>'); + parent.closest('tr').prop("class", ep.overview + " season-" + ep.season + " seasonstyle") } // update the status column if it exists @@ -91,13 +95,13 @@ $(document).ready(function () { function enableLink(el) { el.on('click.disabled', false); - el.attr('enableClick', '1'); + el.prop('enableClick', '1'); el.fadeTo("fast", 1) } function disableLink(el) { el.off('click.disabled'); - el.attr('enableClick', '0'); + el.prop('enableClick', '0'); el.fadeTo("fast", .5) } @@ -121,11 +125,11 @@ function disableLink(el) { event.preventDefault(); // Check if we have disabled the click - if ( $(this).attr('enableClick') == '0' ) { + if ( $(this).prop('enableClick') == '0' ) { return false; } - if ( $(this).attr('class') == "epRetry" ) { + if ( $(this).prop('class') == "epRetry" ) { if ( !confirm("Mark download as bad and retry?") ) return false; }; @@ -137,12 +141,12 @@ function disableLink(el) { // Create var for img under anchor and set options for the loading gif img=$(this).children('img'); - img.attr('title','loading'); - img.attr('alt',''); - img.attr('src',sbRoot+'/images/' + options.loadingImage); + img.prop('title','loading'); + img.prop('alt',''); + img.prop('src',sbRoot+'/images/' + options.loadingImage); - $.getJSON($(this).attr('href'), function(data){ + $.getJSON($(this).prop('href'), function(data){ // if they failed then just put the red X if (data.result == 'failure') { @@ -161,15 +165,15 @@ function disableLink(el) { HtmlContent = data.result.replace(rSearchTerm,"$1"+' <span class="quality '+data.quality+'">'+"$2"+'</span>'); // update the status column if it exists parent.siblings('.col-status').html(HtmlContent) - // Only if the queing was succesfull, disable the onClick event of the loading image + // Only if the queuing was successful, disable the onClick event of the loading image disableLink(link); } // put the corresponding image as the result of queuing of the manual search - img.attr('title',img_result); - img.attr('alt',img_result); - img.attr('height', options.size); - img.attr('src',sbRoot+"/images/"+img_name); + img.prop('title',img_result); + img.prop('alt',img_result); + img.prop('height', options.size); + img.prop('src',sbRoot+"/images/"+img_name); }); // diff --git a/gui/slick/js/config.js b/gui/slick/js/config.js index 5ca1ae1f1752d0c8eae833a1ff14608cbef3713d..6e3f9d018891c38b98554178a7858083ce771c67 100644 --- a/gui/slick/js/config.js +++ b/gui/slick/js/config.js @@ -45,7 +45,7 @@ $(document).ready(function(){ // bind 'myForm' and provide a simple callback function $('#configForm').ajaxForm({ beforeSubmit: function(){ - $('.config_submitter').each(function(){ + $('.config_submitter .config_submitter_refresh').each(function(){ $(this).attr("disabled", "disabled"); $(this).after('<span><img src="' + sbRoot + '/images/loading16' + themeSpinner + '.gif"> Saving...</span>'); $(this).hide(); @@ -68,9 +68,27 @@ $(document).ready(function(){ }); }); - $('#branchCheckout').click(function () { - url = sbRoot+'/home/branchCheckout?branch='+$("#branchVersion").val(); - window.location.href = url; + $('#branchCheckout').click(function() { + var url = sbRoot+'/home/branchCheckout?branch='+$("#branchVersion").val(); + var checkDBversion = sbRoot + "/home/getDBcompare?branchDest=" + var branchDest = $('#branchVersion option:selected').val() + $.getJSON(checkDBversion + branchDest, function(data){ + if (data.status == "success") { + if (data.message == "equal") { + //Checkout Branch + window.location.href = url; + } + if (data.message == "upgrade") { + if ( confirm("Changing branch will upgrade your database.\nYou won't be able to downgrade afterward.\nDo you want to continue?") ) { + //Checkout Branch + window.location.href = url; + } + } + if (data.message == "downgrade") { + alert("Can't switch branch as this will result in a database downgrade.") + } + } + }); }); }); @@ -81,5 +99,12 @@ function config_success(){ $(this).next().remove(); $(this).show(); }); + $('.config_submitter_refresh').each(function(){ + $(this).removeAttr("disabled"); + $(this).next().remove(); + $(this).show(); + url = sbRoot+'/config/providers/'; + window.location.href = url; + }); $('#email_show').trigger('notify'); } diff --git a/gui/slick/js/configProviders.js b/gui/slick/js/configProviders.js index 5010030ef8f56a29de041e62b00cdab57443a047..249e9d774d98fc3a9203ec9fcd1751dc738124e8 100644 --- a/gui/slick/js/configProviders.js +++ b/gui/slick/js/configProviders.js @@ -37,11 +37,15 @@ $(document).ready(function(){ var params = {url: url, name: name, key: key}; var returnData; - $.getJSON(sbRoot + '/config/providers/getNewznabCategories', params, + $(".updating_categories").wrapInner('<span><img src="' + sbRoot + '/images/loading16' + themeSpinner + '.gif"> Updating Categories ...</span>'); + var jqxhr = $.getJSON(sbRoot + '/config/providers/getNewznabCategories', params, function(data){ $(this).updateNewznabCaps( data, selectedProvider ); console.debug(data.tv_categories); }); + jqxhr.always(function() { + $(".updating_categories").empty(); + }); }; $.fn.addProvider = function (id, name, url, key, cat, isDefault, showProvider) { @@ -144,6 +148,8 @@ $(document).ready(function(){ $('#newznab_update_div').hide(); $('#newznab_cat').attr('disabled','disabled'); $('#newznab_cap').attr('disabled','disabled'); + $('#newznab_cat_update').attr('disabled','disabled'); + $('#newznabcapdiv').hide(); $("#newznab_cat option").each(function() { $(this).remove(); @@ -162,6 +168,8 @@ $(document).ready(function(){ $('#newznab_update_div').show(); $('#newznab_cat').removeAttr("disabled"); $('#newznab_cap').removeAttr("disabled"); + $('#newznab_cat_update').removeAttr("disabled"); + $('#newznabcapdiv').show(); } $('#newznab_name').val(data[0]); @@ -180,7 +188,8 @@ $(document).ready(function(){ var newCatOptions = []; if (rrcat) { rrcat.forEach(function (cat) { - newCatOptions.push({text : cat, value : cat}); + if (cat != "") + newCatOptions.push({text : cat, value : cat}); }); $("#newznab_cat").replaceOptions(newCatOptions); }; @@ -203,9 +212,7 @@ $(document).ready(function(){ if (data[0] && data[1] && data[2] && !ifExists($.fn.newznabProvidersCapabilities, data[0])) { $(this).getCategories(isDefault, data); } - else { - $(this).updateNewznabCaps( null, data ); - } + $(this).updateNewznabCaps( null, data ); } } } @@ -317,6 +324,32 @@ $(document).ready(function(){ }); $("#provider_order").val(finalArr.join(' ')); + + $(this).refreshEditAProvider(); + } + + $.fn.refreshEditAProvider = function() { + $('#provider-list').empty(); + + var idArr = $("#provider_order_list").sortable('toArray'); + var finalArr = new Array(); + $.each(idArr, function(key, val) { + if ($('#enable_'+val).prop('checked')) { + finalArr.push(val); + } + }); + + if (finalArr.length > 0) { + $('<select>').prop('id','editAProvider').addClass('form-control input-sm').appendTo('#provider-list'); + for (var i = 0; i < finalArr.length; i++) { + var provider = finalArr[i]; + $('#editAProvider').append($('<option>').prop('value',provider).text($.trim($('#'+provider).text()).replace(/\s\*$/, '').replace(/\s\*\*$/, ''))); + } + } else { + document.getElementsByClassName('component-desc')[0].innerHTML = "No providers available to configure."; + } + + $(this).showHideProviders(); } var newznabProviders = new Array(); @@ -366,8 +399,7 @@ $(document).ready(function(){ $(this).updateTorrentRssProvider(selectedProvider, url, cookies); }); - - $('#editAProvider').change(function(){ + $('body').on('change', '#editAProvider',function(){ $(this).showHideProviders(); }); @@ -483,12 +515,14 @@ $(document).ready(function(){ } $(this).addTorrentRssProvider(data.success, name, url, cookies); + $(this).refreshEditAProvider(); }); }); $('.torrentrss_delete').on('click', function(){ var selectedProvider = $('#editATorrentRssProvider :selected').val(); $(this).deleteTorrentRssProvider(selectedProvider); + $(this).refreshEditAProvider(); }); @@ -579,4 +613,7 @@ $(document).ready(function(){ $("#provider_order_list").disableSelection(); + $(this).populateNewznabSection(); + }); + diff --git a/gui/slick/js/configSearch.js b/gui/slick/js/configSearch.js index f75ea622bfbfbc317796a1761413db41ed09c4fc..4e9aef8489b78c134a9c7c6925386110006fa84b 100644 --- a/gui/slick/js/configSearch.js +++ b/gui/slick/js/configSearch.js @@ -69,6 +69,9 @@ $(document).ready(function(){ $(host_desc_rtorrent).hide(); $(host_desc_torrent).show(); $(torrent_verify_cert_option).hide(); + $(torrent_verify_deluge).hide(); + $(torrent_verify_rtorrent).hide(); + $(torrent_auth_type).hide(); $(torrent_path_option).show(); $(torrent_path_option).find('.fileBrowser').show(); $(torrent_seed_time_option).hide(); @@ -96,6 +99,8 @@ $(document).ready(function(){ } else if ('deluge' == selectedProvider){ client = 'Deluge'; $(torrent_verify_cert_option).show(); + $(torrent_verify_deluge).show(); + $(torrent_verify_rtorrent).hide(); $(label_warning_deluge).show(); $(label_anime_warning_deluge).show(); $('#host_desc_torrent').text('URL to your Deluge client (e.g. http://localhost:8112)'); @@ -113,6 +118,10 @@ $(document).ready(function(){ client = 'rTorrent'; $(torrent_paused_option).hide(); $('#host_desc_torrent').text('URL to your rTorrent client (e.g. scgi://localhost:5000 </br> or https://localhost/rutorrent/plugins/httprpc/action.php)'); + $(torrent_verify_cert_option).show(); + $(torrent_verify_deluge).hide(); + $(torrent_verify_rtorrent).show(); + $(torrent_auth_type).show(); //$('#directory_title').text(client + directory); } $('#host_title').text(client + host); diff --git a/gui/slick/js/fuzzyMoment.js b/gui/slick/js/fuzzyMoment.js index 510ca941e6b5b48315f12990887ca005d65b0b25..ba4c3fc166a0072c2d81d2c6ce798e03a28a4b35 100644 --- a/gui/slick/js/fuzzyMoment.js +++ b/gui/slick/js/fuzzyMoment.js @@ -64,7 +64,8 @@ }); if (trimZero) { - timeToken = timeToken.replace(/hh/ig, 'h'); + timeToken = timeToken.replace(/hh/g, 'h'); + timeToken = timeToken.replace(/HH/g, 'H'); dateToken = dateToken.replace(/\bDD\b/g, 'D'); } diff --git a/gui/slick/js/lib/bootstrap-formhelpers-2.3.0.js b/gui/slick/js/lib/bootstrap-formhelpers-2.3.0.js new file mode 100644 index 0000000000000000000000000000000000000000..9d2da5a66f4b4f5a07e50cfb8889fd116f0d2127 --- /dev/null +++ b/gui/slick/js/lib/bootstrap-formhelpers-2.3.0.js @@ -0,0 +1,17922 @@ +/** +* bootstrap-formhelpers.js v2.3.0 by @vincentlamanna +* Copyright 2013 Vincent Lamanna +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +if (!jQuery) { throw new Error("Bootstrap Form Helpers requires jQuery"); } + +/* ========================================================== + * bootstrap-formhelpers-countries.en_US.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + +var BFHCountriesList = { + 'AF': 'Afghanistan', + 'AL': 'Albania', + 'DZ': 'Algeria', + 'AS': 'American Samoa', + 'AD': 'Andorra', + 'AO': 'Angola', + 'AI': 'Anguilla', + 'AQ': 'Antarctica', + 'AG': 'Antigua and Barbuda', + 'AR': 'Argentina', + 'AM': 'Armenia', + 'AW': 'Aruba', + 'AU': 'Australia', + 'AT': 'Austria', + 'AZ': 'Azerbaijan', + 'BH': 'Bahrain', + 'BD': 'Bangladesh', + 'BB': 'Barbados', + 'BY': 'Belarus', + 'BE': 'Belgium', + 'BZ': 'Belize', + 'BJ': 'Benin', + 'BM': 'Bermuda', + 'BT': 'Bhutan', + 'BO': 'Bolivia', + 'BA': 'Bosnia and Herzegovina', + 'BW': 'Botswana', + 'BV': 'Bouvet Island', + 'BR': 'Brazil', + 'IO': 'British Indian Ocean Territory', + 'VG': 'British Virgin Islands', + 'BN': 'Brunei', + 'BG': 'Bulgaria', + 'BF': 'Burkina Faso', + 'BI': 'Burundi', + 'CI': 'Côte d\'Ivoire', + 'KH': 'Cambodia', + 'CM': 'Cameroon', + 'CA': 'Canada', + 'CV': 'Cape Verde', + 'KY': 'Cayman Islands', + 'CF': 'Central African Republic', + 'TD': 'Chad', + 'CL': 'Chile', + 'CN': 'China', + 'CX': 'Christmas Island', + 'CC': 'Cocos (Keeling) Islands', + 'CO': 'Colombia', + 'KM': 'Comoros', + 'CG': 'Congo', + 'CK': 'Cook Islands', + 'CR': 'Costa Rica', + 'HR': 'Croatia', + 'CU': 'Cuba', + 'CY': 'Cyprus', + 'CZ': 'Czech Republic', + 'CD': 'Democratic Republic of the Congo', + 'DK': 'Denmark', + 'DJ': 'Djibouti', + 'DM': 'Dominica', + 'DO': 'Dominican Republic', + 'TP': 'East Timor', + 'EC': 'Ecuador', + 'EG': 'Egypt', + 'SV': 'El Salvador', + 'GQ': 'Equatorial Guinea', + 'ER': 'Eritrea', + 'EE': 'Estonia', + 'ET': 'Ethiopia', + 'FO': 'Faeroe Islands', + 'FK': 'Falkland Islands', + 'FJ': 'Fiji', + 'FI': 'Finland', + 'MK': 'Former Yugoslav Republic of Macedonia', + 'FR': 'France', + 'FX': 'France, Metropolitan', + 'GF': 'French Guiana', + 'PF': 'French Polynesia', + 'TF': 'French Southern Territories', + 'GA': 'Gabon', + 'GE': 'Georgia', + 'DE': 'Germany', + 'GH': 'Ghana', + 'GI': 'Gibraltar', + 'GR': 'Greece', + 'GL': 'Greenland', + 'GD': 'Grenada', + 'GP': 'Guadeloupe', + 'GU': 'Guam', + 'GT': 'Guatemala', + 'GN': 'Guinea', + 'GW': 'Guinea-Bissau', + 'GY': 'Guyana', + 'HT': 'Haiti', + 'HM': 'Heard and Mc Donald Islands', + 'HN': 'Honduras', + 'HK': 'Hong Kong', + 'HU': 'Hungary', + 'IS': 'Iceland', + 'IN': 'India', + 'ID': 'Indonesia', + 'IR': 'Iran', + 'IQ': 'Iraq', + 'IE': 'Ireland', + 'IL': 'Israel', + 'IT': 'Italy', + 'JM': 'Jamaica', + 'JP': 'Japan', + 'JO': 'Jordan', + 'KZ': 'Kazakhstan', + 'KE': 'Kenya', + 'KI': 'Kiribati', + 'KW': 'Kuwait', + 'KG': 'Kyrgyzstan', + 'LA': 'Laos', + 'LV': 'Latvia', + 'LB': 'Lebanon', + 'LS': 'Lesotho', + 'LR': 'Liberia', + 'LY': 'Libya', + 'LI': 'Liechtenstein', + 'LT': 'Lithuania', + 'LU': 'Luxembourg', + 'MO': 'Macau', + 'MG': 'Madagascar', + 'MW': 'Malawi', + 'MY': 'Malaysia', + 'MV': 'Maldives', + 'ML': 'Mali', + 'MT': 'Malta', + 'MH': 'Marshall Islands', + 'MQ': 'Martinique', + 'MR': 'Mauritania', + 'MU': 'Mauritius', + 'YT': 'Mayotte', + 'MX': 'Mexico', + 'FM': 'Micronesia', + 'MD': 'Moldova', + 'MC': 'Monaco', + 'MN': 'Mongolia', + 'ME': 'Montenegro', + 'MS': 'Montserrat', + 'MA': 'Morocco', + 'MZ': 'Mozambique', + 'MM': 'Myanmar', + 'NA': 'Namibia', + 'NR': 'Nauru', + 'NP': 'Nepal', + 'NL': 'Netherlands', + 'AN': 'Netherlands Antilles', + 'NC': 'New Caledonia', + 'NZ': 'New Zealand', + 'NI': 'Nicaragua', + 'NE': 'Niger', + 'NG': 'Nigeria', + 'NU': 'Niue', + 'NF': 'Norfolk Island', + 'KP': 'North Korea', + 'MP': 'Northern Marianas', + 'NO': 'Norway', + 'OM': 'Oman', + 'PK': 'Pakistan', + 'PW': 'Palau', + 'PS': 'Palestine', + 'PA': 'Panama', + 'PG': 'Papua New Guinea', + 'PY': 'Paraguay', + 'PE': 'Peru', + 'PH': 'Philippines', + 'PN': 'Pitcairn Islands', + 'PL': 'Poland', + 'PT': 'Portugal', + 'PR': 'Puerto Rico', + 'QA': 'Qatar', + 'RE': 'Reunion', + 'RO': 'Romania', + 'RU': 'Russia', + 'RW': 'Rwanda', + 'ST': 'São Tomé and Príncipe', + 'SH': 'Saint Helena', + 'PM': 'St. Pierre and Miquelon', + 'KN': 'Saint Kitts and Nevis', + 'LC': 'Saint Lucia', + 'VC': 'Saint Vincent and the Grenadines', + 'WS': 'Samoa', + 'SM': 'San Marino', + 'SA': 'Saudi Arabia', + 'SN': 'Senegal', + 'RS': 'Serbia', + 'SC': 'Seychelles', + 'SL': 'Sierra Leone', + 'SG': 'Singapore', + 'SK': 'Slovakia', + 'SI': 'Slovenia', + 'SB': 'Solomon Islands', + 'SO': 'Somalia', + 'ZA': 'South Africa', + 'GS': 'South Georgia and the South Sandwich Islands', + 'KR': 'South Korea', + 'ES': 'Spain', + 'LK': 'Sri Lanka', + 'SD': 'Sudan', + 'SR': 'Suriname', + 'SJ': 'Svalbard and Jan Mayen Islands', + 'SZ': 'Swaziland', + 'SE': 'Sweden', + 'CH': 'Switzerland', + 'SY': 'Syria', + 'TW': 'Taiwan', + 'TJ': 'Tajikistan', + 'TZ': 'Tanzania', + 'TH': 'Thailand', + 'BS': 'The Bahamas', + 'GM': 'The Gambia', + 'TG': 'Togo', + 'TK': 'Tokelau', + 'TO': 'Tonga', + 'TT': 'Trinidad and Tobago', + 'TN': 'Tunisia', + 'TR': 'Turkey', + 'TM': 'Turkmenistan', + 'TC': 'Turks and Caicos Islands', + 'TV': 'Tuvalu', + 'VI': 'US Virgin Islands', + 'UG': 'Uganda', + 'UA': 'Ukraine', + 'AE': 'United Arab Emirates', + 'GB': 'United Kingdom', + 'US': 'United States', + 'UM': 'United States Minor Outlying Islands', + 'UY': 'Uruguay', + 'UZ': 'Uzbekistan', + 'VU': 'Vanuatu', + 'VA': 'Vatican City', + 'VE': 'Venezuela', + 'VN': 'Vietnam', + 'WF': 'Wallis and Futuna Islands', + 'EH': 'Western Sahara', + 'YE': 'Yemen', + 'ZM': 'Zambia', + 'ZW': 'Zimbabwe' +}; + + /* ========================================================== + * bootstrap-formhelpers-currencies.en_US.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2013 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + +var BFHCurrenciesList = { + 'AED':{'label':'United Arab Emirates dirham','currencyflag':'','symbol':'د.إ'}, + 'AFN':{'label':'Afghan afghani','currencyflag':'','symbol':'؋'}, + 'ALL':{'label':'Albanian lek','currencyflag':'','symbol':'L'}, + 'AMD':{'label':'Armenian dram','currencyflag':'','symbol':'դր'}, + 'AOA':{'label':'Angolan kwanza','currencyflag':'','symbol':'Kz'}, + 'ARS':{'label':'Argentine peso','currencyflag':'','symbol':'$'}, + 'AUD':{'label':'Australian dollar','currencyflag':'AUD','symbol':'$'}, + 'AWG':{'label':'Aruban florin','currencyflag':'','symbol':'ƒ'}, + 'AZN':{'label':'Azerbaijani manat','currencyflag':'','symbol':''}, + 'BAM':{'label':'Bosnia and Herzegovina convertible mark','currencyflag':'','symbol':'KM'}, + 'BBD':{'label':'Barbadian dollar','currencyflag':'','symbol':'$'}, + 'BDT':{'label':'Bangladeshi taka','currencyflag':'','symbol':'৳'}, + 'BGN':{'label':'Bulgarian lev','currencyflag':'','symbol':'лв'}, + 'BHD':{'label':'Bahraini dinar','currencyflag':'','symbol':'.د.ب'}, + 'BIF':{'label':'Burundian franc','currencyflag':'','symbol':'Fr'}, + 'BMD':{'label':'Bermudian dollar','currencyflag':'','symbol':'$'}, + 'BND':{'label':'Brunei dollar','currencyflag':'','symbol':'$'}, + 'BOB':{'label':'Bolivian boliviano','currencyflag':'','symbol':'Bs'}, + 'BRL':{'label':'Brazilian real','currencyflag':'','symbol':'R$'}, + 'BSD':{'label':'Bahamian dollar','currencyflag':'','symbol':'$'}, + 'BTN':{'label':'Bhutanese ngultrum','currencyflag':'','symbol':'Nu'}, + 'BWP':{'label':'Botswana pula','currencyflag':'','symbol':'P'}, + 'BYR':{'label':'Belarusian ruble','currencyflag':'','symbol':'Br'}, + 'BZD':{'label':'Belize dollar','currencyflag':'','symbol':'$'}, + 'CAD':{'label':'Canadian dollar','currencyflag':'','symbol':'$'}, + 'CDF':{'label':'Congolese franc','currencyflag':'','symbol':'Fr'}, + 'CHF':{'label':'Swiss franc','currencyflag':'CHF','symbol':'Fr'}, + 'CLP':{'label':'Chilean peso','currencyflag':'','symbol':'$'}, + 'CNY':{'label':'Chinese yuan','currencyflag':'','symbol':'¥'}, + 'COP':{'label':'Colombian peso','currencyflag':'','symbol':'$'}, + 'CRC':{'label':'Costa Rican colón','currencyflag':'','symbol':'₡'}, + 'CUP':{'label':'Cuban convertible peso','currencyflag':'','symbol':'$'}, + 'CVE':{'label':'Cape Verdean escudo','currencyflag':'','symbol':'$'}, + 'CZK':{'label':'Czech koruna','currencyflag':'','symbol':'Kč'}, + 'DJF':{'label':'Djiboutian franc','currencyflag':'','symbol':'Fr'}, + 'DKK':{'label':'Danish krone','currencyflag':'DKK','symbol':'kr'}, + 'DOP':{'label':'Dominican peso','currencyflag':'','symbol':'$'}, + 'DZD':{'label':'Algerian dinar','currencyflag':'','symbol':'د.ج'}, + 'EGP':{'label':'Egyptian pound','currencyflag':'','symbol':'ج.م'}, + 'ERN':{'label':'Eritrean nakfa','currencyflag':'','symbol':'Nfk'}, + 'ETB':{'label':'Ethiopian birr','currencyflag':'','symbol':'Br'}, + 'EUR':{'label':'Euro','currencyflag':'EUR','symbol':'€'}, + 'FJD':{'label':'Fijian dollar','currencyflag':'','symbol':'$'}, + 'FKP':{'label':'Falkland Islands pound','currencyflag':'','symbol':'£'}, + 'GBP':{'label':'British pound','currencyflag':'','symbol':'£'}, + 'GEL':{'label':'Georgian lari','currencyflag':'','symbol':'ლ'}, + 'GHS':{'label':'Ghana cedi','currencyflag':'','symbol':'₵'}, + 'GMD':{'label':'Gambian dalasi','currencyflag':'','symbol':'D'}, + 'GNF':{'label':'Guinean franc','currencyflag':'','symbol':'Fr'}, + 'GTQ':{'label':'Guatemalan quetzal','currencyflag':'','symbol':'Q'}, + 'GYD':{'label':'Guyanese dollar','currencyflag':'','symbol':'$'}, + 'HKD':{'label':'Hong Kong dollar','currencyflag':'','symbol':'$'}, + 'HNL':{'label':'Honduran lempira','currencyflag':'','symbol':'L'}, + 'HRK':{'label':'Croatian kuna','currencyflag':'','symbol':'kn'}, + 'HTG':{'label':'Haitian gourde','currencyflag':'','symbol':'G'}, + 'HUF':{'label':'Hungarian forint','currencyflag':'','symbol':'Ft'}, + 'IDR':{'label':'Indonesian rupiah','currencyflag':'','symbol':'Rp'}, + 'ILS':{'label':'Israeli new shekel','currencyflag':'','symbol':'₪'}, + 'IMP':{'label':'Manx pound','currencyflag':'','symbol':'£'}, + 'INR':{'label':'Indian rupee','currencyflag':'','symbol':''}, + 'IQD':{'label':'Iraqi dinar','currencyflag':'','symbol':'ع.د'}, + 'IRR':{'label':'Iranian rial','currencyflag':'','symbol':'﷼'}, + 'ISK':{'label':'Icelandic króna','currencyflag':'','symbol':'kr'}, + 'JEP':{'label':'Jersey pound','currencyflag':'','symbol':'£'}, + 'JMD':{'label':'Jamaican dollar','currencyflag':'','symbol':'$'}, + 'JOD':{'label':'Jordanian dinar','currencyflag':'','symbol':'د.ا'}, + 'JPY':{'label':'Japanese yen','currencyflag':'','symbol':'¥'}, + 'KES':{'label':'Kenyan shilling','currencyflag':'','symbol':'Sh'}, + 'KGS':{'label':'Kyrgyzstani som','currencyflag':'','symbol':'лв'}, + 'KHR':{'label':'Cambodian riel','currencyflag':'','symbol':'៛'}, + 'KMF':{'label':'Comorian franc','currencyflag':'','symbol':'Fr'}, + 'KPW':{'label':'North Korean won','currencyflag':'','symbol':'₩'}, + 'KRW':{'label':'South Korean won','currencyflag':'','symbol':'₩'}, + 'KWD':{'label':'Kuwaiti dinar','currencyflag':'','symbol':'د.ك'}, + 'KYD':{'label':'Cayman Islands dollar','currencyflag':'','symbol':'$'}, + 'KZT':{'label':'Kazakhstani tenge','currencyflag':'','symbol':'₸'}, + 'LAK':{'label':'Lao kip','currencyflag':'','symbol':'₭'}, + 'LBP':{'label':'Lebanese pound','currencyflag':'','symbol':'ل.ل'}, + 'LKR':{'label':'Sri Lankan rupee','currencyflag':'','symbol':'Rs'}, + 'LRD':{'label':'Liberian dollar','currencyflag':'','symbol':'$'}, + 'LSL':{'label':'Lesotho loti','currencyflag':'','symbol':'L'}, + 'LTL':{'label':'Lithuanian litas','currencyflag':'','symbol':'Lt'}, + 'LVL':{'label':'Latvian lats','currencyflag':'','symbol':'Ls'}, + 'LYD':{'label':'Libyan dinar','currencyflag':'','symbol':'ل.د'}, + 'MAD':{'label':'Moroccan dirham','currencyflag':'','symbol':'د.م.'}, + 'MDL':{'label':'Moldovan leu','currencyflag':'','symbol':'L'}, + 'MGA':{'label':'Malagasy ariary','currencyflag':'','symbol':'Ar'}, + 'MKD':{'label':'Macedonian denar','currencyflag':'','symbol':'ден'}, + 'MMK':{'label':'Burmese kyat','currencyflag':'','symbol':'Ks'}, + 'MNT':{'label':'Mongolian tögrög','currencyflag':'','symbol':'₮'}, + 'MOP':{'label':'Macanese pataca','currencyflag':'','symbol':'P'}, + 'MRO':{'label':'Mauritanian ouguiya','currencyflag':'','symbol':'UM'}, + 'MUR':{'label':'Mauritian rupee','currencyflag':'','symbol':'Rs'}, + 'MVR':{'label':'Maldivian rufiyaa','currencyflag':'','symbol':'.ރ'}, + 'MWK':{'label':'Malawian kwacha','currencyflag':'','symbol':'MK'}, + 'MXN':{'label':'Mexican peso','currencyflag':'','symbol':'$'}, + 'MYR':{'label':'Malaysian ringgit','currencyflag':'','symbol':'MR'}, + 'MZN':{'label':'Mozambican metical','currencyflag':'','symbol':'MT'}, + 'NAD':{'label':'Namibian dollar','currencyflag':'','symbol':'$'}, + 'NGN':{'label':'Nigerian naira','currencyflag':'','symbol':'₦'}, + 'NIO':{'label':'Nicaraguan córdoba','currencyflag':'','symbol':'C$'}, + 'NOK':{'label':'Norwegian krone','currencyflag':'','symbol':'kr'}, + 'NPR':{'label':'Nepalese rupee','currencyflag':'','symbol':'Rs'}, + 'NZD':{'label':'New Zealand dollar','currencyflag':'','symbol':'$'}, + 'OMR':{'label':'Omani rial','currencyflag':'','symbol':'ر.ع.'}, + 'PAB':{'label':'Panamanian balboa','currencyflag':'','symbol':'B/.'}, + 'PEN':{'label':'Peruvian nuevo sol','currencyflag':'','symbol':'S/.'}, + 'PGK':{'label':'Papua New Guinean kina','currencyflag':'','symbol':'K'}, + 'PHP':{'label':'Philippine peso','currencyflag':'','symbol':'₱'}, + 'PKR':{'label':'Pakistani rupee','currencyflag':'','symbol':'Rs'}, + 'PLN':{'label':'Polish złoty','currencyflag':'','symbol':'zł'}, + 'PRB':{'label':'Transnistrian ruble','currencyflag':'','symbol':'р.'}, + 'PYG':{'label':'Paraguayan guaraní','currencyflag':'','symbol':'₲'}, + 'QAR':{'label':'Qatari riyal','currencyflag':'','symbol':'ر.ق'}, + 'RON':{'label':'Romanian leu','currencyflag':'','symbol':'L'}, + 'RSD':{'label':'Serbian dinar','currencyflag':'','symbol':'дин'}, + 'RUB':{'label':'Russian ruble','currencyflag':'','symbol':'руб.'}, + 'RWF':{'label':'Rwandan franc','currencyflag':'','symbol':'Fr'}, + 'SAR':{'label':'Saudi riyal','currencyflag':'','symbol':'ر.س'}, + 'SBD':{'label':'Solomon Islands dollar','currencyflag':'','symbol':'$'}, + 'SCR':{'label':'Seychellois rupee','currencyflag':'','symbol':'Rs'}, + 'SDG':{'label':'Singapore dollar','currencyflag':'','symbol':'$'}, + 'SEK':{'label':'Swedish krona','currencyflag':'','symbol':'kr'}, + 'SGD':{'label':'Singapore dollar','currencyflag':'','symbol':'$'}, + 'SHP':{'label':'Saint Helena pound','currencyflag':'','symbol':'£'}, + 'SLL':{'label':'Sierra Leonean leone','currencyflag':'','symbol':'Le'}, + 'SOS':{'label':'Somali shilling','currencyflag':'','symbol':'Sh'}, + 'SRD':{'label':'Surinamese dollar','currencyflag':'','symbol':'$'}, + 'SSP':{'label':'South Sudanese pound','currencyflag':'','symbol':'£'}, + 'STD':{'label':'São Tomé and Príncipe dobra','currencyflag':'','symbol':'Db'}, + 'SVC':{'label':'Salvadoran colón','currencyflag':'','symbol':'₡'}, + 'SYP':{'label':'Syrian pound','currencyflag':'','symbol':'£'}, + 'SZL':{'label':'Swazi lilangeni','currencyflag':'','symbol':'L'}, + 'THB':{'label':'Thai baht','currencyflag':'','symbol':'฿'}, + 'TJS':{'label':'Tajikistani somoni','currencyflag':'','symbol':'SM'}, + 'TMT':{'label':'Turkmenistan manat','currencyflag':'','symbol':'m'}, + 'TND':{'label':'Tunisian dinar','currencyflag':'','symbol':'د.ت'}, + 'TOP':{'label':'Tongan paʻanga','currencyflag':'','symbol':'T$'}, + 'TRY':{'label':'Turkish lira','currencyflag':'','symbol':'₺'}, + 'TTD':{'label':'Trinidad and Tobago dollar','currencyflag':'','symbol':'$'}, + 'TWD':{'label':'New Taiwan dollar','currencyflag':'','symbol':'$'}, + 'TZS':{'label':'Tanzanian shilling','currencyflag':'','symbol':'Sh'}, + 'UAH':{'label':'Ukrainian hryvnia','currencyflag':'','symbol':'₴'}, + 'UGX':{'label':'Ugandan shilling','currencyflag':'','symbol':'Sh'}, + 'USD':{'label':'United States dollar','currencyflag':'','symbol':'$'}, + 'UYU':{'label':'Uruguayan peso','currencyflag':'','symbol':'$'}, + 'UZS':{'label':'Uzbekistani som','currencyflag':'','symbol':'лв'}, + 'VEF':{'label':'Venezuelan bolívar','currencyflag':'','symbol':'Bs F'}, + 'VND':{'label':'Vietnamese đồng','currencyflag':'','symbol':'₫'}, + 'VUV':{'label':'Vanuatu vatu','currencyflag':'','symbol':'Vt'}, + 'WST':{'label':'Samoan tālā','currencyflag':'','symbol':'T'}, + 'XAF':{'label':'Central African CFA franc','currencyflag':'XAF','symbol':'Fr'}, + 'XCD':{'label':'East Caribbean dollar','currencyflag':'XCD','symbol':'$'}, + 'XOF':{'label':'West African CFA franc','currencyflag':'XOF','symbol':'Fr'}, + 'XPF':{'label':'CFP franc','currencyflag':'XPF','symbol':'Fr'}, + 'YER':{'label':'Yemeni rial','currencyflag':'','symbol':'﷼'}, + 'ZAR':{'label':'South African rand','currencyflag':'ZAR','symbol':'R'}, + 'ZMW':{'label':'Zambian kwacha','currencyflag':'','symbol':'ZK'}, + 'ZWL':{'label':'Zimbabwean dollar','currencyflag':'','symbol':'$'} +}; + +/* ========================================================== + * bootstrap-formhelpers-datepicker.en_US.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + +var BFHMonthsList = [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December' +]; + +var BFHDaysList = [ + 'SUN', + 'MON', + 'TUE', + 'WED', + 'THU', + 'FRI', + 'SAT' +]; + +var BFHDayOfWeekStart = 0; + +/* ========================================================== + * bootstrap-formhelpers-fonts.en_US.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + +var BFHFontsList = { + 'Andale Mono': '"Andale Mono", AndaleMono, monospace', + 'Arial': 'Arial, "Helvetica Neue", Helvetica, sans-serif', + 'Arial Black': '"Arial Black", "Arial Bold", Gadget, sans-serif', + 'Arial Narrow': '"Arial Narrow", Arial, sans-serif', + 'Arial Rounded MT Bold': '"Arial Rounded MT Bold", "Helvetica Rounded", Arial, sans-serif', + 'Avant Garde': '"Avant Garde", Avantgarde, "Century Gothic", CenturyGothic, "AppleGothic", sans-serif', + 'Baskerville': 'Baskerville, "Baskerville Old Face", "Hoefler Text", Garamond, "Times New Roman", serif', + 'Big Caslon': '"Big Caslon", "Book Antiqua", "Palatino Linotype", Georgia, serif', + 'Bodoni MT': '"Bodoni MT", Didot, "Didot LT STD", "Hoefler Text", Garamond, "Times New Roman", serif', + 'Book Antiqua': '"Book Antiqua", Palatino, "Palatino Linotype", "Palatino LT STD", Georgia, serif', + 'Brush Script MT': '"Brush Script MT", cursive', + 'Calibri': 'Calibri, Candara, Segoe, "Segoe UI", Optima, Arial, sans-serif', + 'Calisto MT': '"Calisto MT", "Bookman Old Style", Bookman, "Goudy Old Style", Garamond, "Hoefler Text", "Bitstream Charter", Georgia, serif', + 'Cambrio': 'Cambria, Georgia, serif', + 'Candara': 'Candara, Calibri, Segoe, "Segoe UI", Optima, Arial, sans-serif', + 'Century Gothic': '"Century Gothic", CenturyGothic, AppleGothic, sans-serif', + 'Consolas': 'Consolas, monaco, monospace', + 'Copperplate': 'Copperplate, "Copperplate Gothic Light", fantasy', + 'Courier New': '"Courier New", Courier, "Lucida Sans Typewriter", "Lucida Typewriter", monospace', + 'Didot': 'Didot, "Didot LT STD", "Hoefler Text", Garamond, "Times New Roman", serif', + 'Franklin Gothic Medium': '"Franklin Gothic Medium", "Franklin Gothic", "ITC Franklin Gothic", Arial, sans-serif', + 'Futura': 'Futura, "Trebuchet MS", Arial, sans-serif', + 'Garamond': 'Garamond, Baskerville, "Baskerville Old Face", "Hoefler Text", "Times New Roman", serif', + 'Geneva': 'Geneva, Tahoma, Verdana, sans-serif', + 'Georgia': 'Georgia, Times, "Times New Roman", serif', + 'Gill Sans': '"Gill Sans", "Gill Sans MT", Calibri, sans-serif', + 'Goudy Old Style': '"Goudy Old Style", Garamond, "Big Caslon", "Times New Roman", serif', + 'Helvetica': '"Helvetica Neue", Helvetica, Arial, sans-serif', + 'Hoefler Text': '"Hoefler Text", "Baskerville old face", Garamond, "Times New Roman", serif', + 'Impact': 'Impact, Haettenschweiler, "Franklin Gothic Bold", Charcoal, "Helvetica Inserat", "Bitstream Vera Sans Bold", "Arial Black", sans serif', + 'Lucida Bright': '"Lucida Bright", Georgia, serif', + 'Lucida Console': '"Lucida Console", "Lucida Sans Typewriter", Monaco, "Bitstream Vera Sans Mono", monospace', + 'Lucida Sans Typewriter': '"Lucida Sans Typewriter", "Lucida Console", Monaco, "Bitstream Vera Sans Mono", monospace', + 'Lucida Grande': '"Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif', + 'Monaco': 'Monaco, Consolas, "Lucida Console", monospace', + 'Optima': 'Optima, Segoe, "Segoe UI", Candara, Calibri, Arial, sans-serif', + 'Palatino': 'Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif', + 'Papyrus': 'Papyrus, fantasy', + 'Perpetua': 'Perpetua, Baskerville, "Big Caslon", "Palatino Linotype", Palatino, "URW Palladio L", "Nimbus Roman No9 L", serif', + 'Rockwell': 'Rockwell, "Courier Bold", Courier, Georgia, Times, "Times New Roman", serif', + 'Rockwell Extra Bold': '"Rockwell Extra Bold", "Rockwell Bold", monospace', + 'Segoe UI': '"Segoe UI", Frutiger, "Frutiger Linotype', + 'Tahoma': 'Tahoma, Verdana, Segoe, sans-serif', + 'Times New Roman': 'TimesNewRoman, "Times New Roman", Times, Baskerville, Georgia, serif', + 'Trebuchet MS': '"Trebuchet MS", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Tahoma, sans-serif', + 'Verdana': 'Verdana, Geneva, sans-serif' +}; + +/* ========================================================== + * bootstrap-formhelpers-fontsizes.en_US.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + +var BFHFontSizesList = { + '8': '8px', + '9': '9px', + '10': '10px', + '11': '11px', + '12': '12px', + '14': '14px', + '16': '16px', + '18': '18px', + '20': '20px', + '24': '24px', + '28': '28px', + '36': '36px', + '48': '48px' +}; + +/* ========================================================== + * bootstrap-formhelpers-googlefonts.en_US.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * contributed by Aaron Collegeman, Squidoo, 2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + +var BFHGoogleFontsList = { + 'kind': 'webfonts#webfontList', + 'items': [ + { + 'kind': 'webfonts#webfont', + 'family': 'ABeeZee', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Abel', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Abril Fatface', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Aclonica', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Acme', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Actor', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Adamina', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Advent Pro', + 'variants': [ + '100', + '200', + '300', + 'regular', + '500', + '600', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin', + 'greek' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Aguafina Script', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Akronim', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Aladin', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Aldrich', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Alegreya', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic', + '900', + '900italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Alegreya SC', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic', + '900', + '900italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Alex Brush', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Alfa Slab One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Alice', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Alike', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Alike Angular', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Allan', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Allerta', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Allerta Stencil', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Allura', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Almendra', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Almendra Display', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Almendra SC', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Amarante', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Amaranth', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Amatic SC', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Amethysta', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Anaheim', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Andada', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Andika', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin', + 'cyrillic-ext' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Angkor', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Annie Use Your Telescope', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Anonymous Pro', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'cyrillic', + 'greek-ext', + 'latin-ext', + 'latin', + 'greek', + 'cyrillic-ext' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Antic', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Antic Didone', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Antic Slab', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Anton', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Arapey', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Arbutus', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Arbutus Slab', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Architects Daughter', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Archivo Black', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Archivo Narrow', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Arimo', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Arizonia', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Armata', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Artifika', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Arvo', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Asap', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Asset', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Astloch', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Asul', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Atomic Age', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Aubrey', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Audiowide', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Autour One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Average', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Average Sans', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Averia Gruesa Libre', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Averia Libre', + 'variants': [ + '300', + '300italic', + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Averia Sans Libre', + 'variants': [ + '300', + '300italic', + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Averia Serif Libre', + 'variants': [ + '300', + '300italic', + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Bad Script', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Balthazar', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Bangers', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Basic', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Battambang', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Baumans', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Bayon', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Belgrano', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Belleza', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'BenchNine', + 'variants': [ + '300', + 'regular', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Bentham', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Berkshire Swash', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Bevan', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Bigelow Rules', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Bigshot One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Bilbo', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Bilbo Swash Caps', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Bitter', + 'variants': [ + 'regular', + 'italic', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Black Ops One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Bokor', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Bonbon', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Boogaloo', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Bowlby One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Bowlby One SC', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Brawler', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Bree Serif', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Bubblegum Sans', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Bubbler One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Buda', + 'variants': [ + '300' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Buenard', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Butcherman', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Butterfly Kids', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Cabin', + 'variants': [ + 'regular', + 'italic', + '500', + '500italic', + '600', + '600italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Cabin Condensed', + 'variants': [ + 'regular', + '500', + '600', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Cabin Sketch', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Caesar Dressing', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Cagliostro', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Calligraffitti', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Cambo', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Candal', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Cantarell', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Cantata One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Cantora One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Capriola', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Cardo', + 'variants': [ + 'regular', + 'italic', + '700' + ], + 'subsets': [ + 'greek-ext', + 'latin-ext', + 'latin', + 'greek' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Carme', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Carrois Gothic', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Carrois Gothic SC', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Carter One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Caudex', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'greek-ext', + 'latin-ext', + 'latin', + 'greek' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Cedarville Cursive', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Ceviche One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Changa One', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Chango', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Chau Philomene One', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Chela One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Chelsea Market', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Chenla', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Cherry Cream Soda', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Cherry Swash', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Chewy', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Chicle', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Chivo', + 'variants': [ + 'regular', + 'italic', + '900', + '900italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Cinzel', + 'variants': [ + 'regular', + '700', + '900' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Cinzel Decorative', + 'variants': [ + 'regular', + '700', + '900' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Clicker Script', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Coda', + 'variants': [ + 'regular', + '800' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Coda Caption', + 'variants': [ + '800' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Codystar', + 'variants': [ + '300', + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Combo', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Comfortaa', + 'variants': [ + '300', + 'regular', + '700' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin', + 'greek', + 'cyrillic-ext' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Coming Soon', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Concert One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Condiment', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Content', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Contrail One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Convergence', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Cookie', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Copse', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Corben', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Courgette', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Cousine', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Coustard', + 'variants': [ + 'regular', + '900' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Covered By Your Grace', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Crafty Girls', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Creepster', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Crete Round', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Crimson Text', + 'variants': [ + 'regular', + 'italic', + '600', + '600italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Croissant One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Crushed', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Cuprum', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Cutive', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Cutive Mono', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Damion', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Dancing Script', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Dangrek', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Dawning of a New Day', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Days One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Delius', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Delius Swash Caps', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Delius Unicase', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Della Respira', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Devonshire', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Didact Gothic', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'greek-ext', + 'latin-ext', + 'latin', + 'greek', + 'cyrillic-ext' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Diplomata', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Diplomata SC', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Doppio One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Dorsa', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Dosis', + 'variants': [ + '200', + '300', + 'regular', + '500', + '600', + '700', + '800' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Dr Sugiyama', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Droid Sans', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Droid Sans Mono', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Droid Serif', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Duru Sans', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Dynalight', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'EB Garamond', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin', + 'vietnamese', + 'cyrillic-ext' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Eagle Lake', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Eater', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Economica', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Electrolize', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Emblema One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Emilys Candy', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Engagement', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Englebert', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Enriqueta', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Erica One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Esteban', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Euphoria Script', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Ewert', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Exo', + 'variants': [ + '100', + '100italic', + '200', + '200italic', + '300', + '300italic', + 'regular', + 'italic', + '500', + '500italic', + '600', + '600italic', + '700', + '700italic', + '800', + '800italic', + '900', + '900italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Expletus Sans', + 'variants': [ + 'regular', + 'italic', + '500', + '500italic', + '600', + '600italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Fanwood Text', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Fascinate', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Fascinate Inline', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Faster One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Fasthand', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Federant', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Federo', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Felipa', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Fenix', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Finger Paint', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Fjord One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Flamenco', + 'variants': [ + '300', + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Flavors', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Fondamento', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Fontdiner Swanky', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Forum', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin', + 'cyrillic-ext' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Francois One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Freckle Face', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Fredericka the Great', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Fredoka One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Freehand', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Fresca', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Frijole', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Fugaz One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'GFS Didot', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'greek' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'GFS Neohellenic', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'greek' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Gafata', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Galdeano', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Galindo', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Gentium Basic', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Gentium Book Basic', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Geo', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Geostar', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Geostar Fill', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Germania One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Gilda Display', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Give You Glory', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Glass Antiqua', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Glegoo', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Gloria Hallelujah', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Goblin One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Gochi Hand', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Gorditas', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Goudy Bookletter 1911', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Graduate', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Gravitas One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Great Vibes', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Griffy', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Gruppo', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Gudea', + 'variants': [ + 'regular', + 'italic', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Habibi', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Hammersmith One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Hanalei', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Hanalei Fill', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Handlee', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Hanuman', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Happy Monkey', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Headland One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Henny Penny', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Herr Von Muellerhoff', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Holtwood One SC', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Homemade Apple', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Homenaje', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'IM Fell DW Pica', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'IM Fell DW Pica SC', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'IM Fell Double Pica', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'IM Fell Double Pica SC', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'IM Fell English', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'IM Fell English SC', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'IM Fell French Canon', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'IM Fell French Canon SC', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'IM Fell Great Primer', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'IM Fell Great Primer SC', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Iceberg', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Iceland', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Imprima', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Inconsolata', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Inder', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Indie Flower', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Inika', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Irish Grover', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Istok Web', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin', + 'cyrillic-ext' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Italiana', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Italianno', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Jacques Francois', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Jacques Francois Shadow', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Jim Nightshade', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Jockey One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Jolly Lodger', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Josefin Sans', + 'variants': [ + '100', + '100italic', + '300', + '300italic', + 'regular', + 'italic', + '600', + '600italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Josefin Slab', + 'variants': [ + '100', + '100italic', + '300', + '300italic', + 'regular', + 'italic', + '600', + '600italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Joti One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Judson', + 'variants': [ + 'regular', + 'italic', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Julee', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Julius Sans One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Junge', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Jura', + 'variants': [ + '300', + 'regular', + '500', + '600' + ], + 'subsets': [ + 'cyrillic', + 'greek-ext', + 'latin-ext', + 'latin', + 'greek', + 'cyrillic-ext' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Just Another Hand', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Just Me Again Down Here', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Kameron', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Karla', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Kaushan Script', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Keania One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Kelly Slab', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Kenia', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Khmer', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Kite One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Knewave', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Kotta One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Koulen', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Kranky', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Kreon', + 'variants': [ + '300', + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Kristi', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Krona One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'La Belle Aurore', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Lancelot', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Lato', + 'variants': [ + '100', + '100italic', + '300', + '300italic', + 'regular', + 'italic', + '700', + '700italic', + '900', + '900italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'League Script', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Leckerli One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Ledger', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Lekton', + 'variants': [ + 'regular', + 'italic', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Lemon', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Life Savers', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Lilita One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Limelight', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Linden Hill', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Lobster', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin', + 'cyrillic-ext' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Lobster Two', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Londrina Outline', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Londrina Shadow', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Londrina Sketch', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Londrina Solid', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Lora', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Love Ya Like A Sister', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Loved by the King', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Lovers Quarrel', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Luckiest Guy', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Lusitana', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Lustria', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Macondo', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Macondo Swash Caps', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Magra', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Maiden Orange', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Mako', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Marcellus', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Marcellus SC', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Marck Script', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Margarine', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Marko One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Marmelad', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Marvel', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Mate', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Mate SC', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Maven Pro', + 'variants': [ + 'regular', + '500', + '700', + '900' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'McLaren', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Meddon', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'MedievalSharp', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Medula One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Megrim', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Meie Script', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Merienda', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Merienda One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Merriweather', + 'variants': [ + '300', + 'regular', + '700', + '900' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Metal', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Metal Mania', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Metamorphous', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Metrophobic', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Michroma', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Miltonian', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Miltonian Tattoo', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Miniver', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Miss Fajardose', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Modern Antiqua', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Molengo', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Molle', + 'variants': [ + 'italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Monofett', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Monoton', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Monsieur La Doulaise', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Montaga', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Montez', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Montserrat', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Montserrat Alternates', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Montserrat Subrayada', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Moul', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Moulpali', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Mountains of Christmas', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Mouse Memoirs', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Mr Bedfort', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Mr Dafoe', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Mr De Haviland', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Mrs Saint Delafield', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Mrs Sheppards', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Muli', + 'variants': [ + '300', + '300italic', + 'regular', + 'italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Mystery Quest', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Neucha', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Neuton', + 'variants': [ + '200', + '300', + 'regular', + 'italic', + '700', + '800' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'News Cycle', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Niconne', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Nixie One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Nobile', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Nokora', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Norican', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Nosifer', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Nothing You Could Do', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Noticia Text', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin-ext', + 'latin', + 'vietnamese' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Nova Cut', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Nova Flat', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Nova Mono', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin', + 'greek' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Nova Oval', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Nova Round', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Nova Script', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Nova Slim', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Nova Square', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Numans', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Nunito', + 'variants': [ + '300', + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Odor Mean Chey', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Offside', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Old Standard TT', + 'variants': [ + 'regular', + 'italic', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Oldenburg', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Oleo Script', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Oleo Script Swash Caps', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Open Sans', + 'variants': [ + '300', + '300italic', + 'regular', + 'italic', + '600', + '600italic', + '700', + '700italic', + '800', + '800italic' + ], + 'subsets': [ + 'cyrillic', + 'greek-ext', + 'latin-ext', + 'latin', + 'vietnamese', + 'greek', + 'cyrillic-ext' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Open Sans Condensed', + 'variants': [ + '300', + '300italic', + '700' + ], + 'subsets': [ + 'cyrillic', + 'greek-ext', + 'latin-ext', + 'latin', + 'vietnamese', + 'greek', + 'cyrillic-ext' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Oranienbaum', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin', + 'cyrillic-ext' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Orbitron', + 'variants': [ + 'regular', + '500', + '700', + '900' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Oregano', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Orienta', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Original Surfer', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Oswald', + 'variants': [ + '300', + 'regular', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Over the Rainbow', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Overlock', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic', + '900', + '900italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Overlock SC', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Ovo', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Oxygen', + 'variants': [ + '300', + 'regular', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Oxygen Mono', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'PT Mono', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin', + 'cyrillic-ext' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'PT Sans', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'PT Sans Caption', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'PT Sans Narrow', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'PT Serif', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'cyrillic', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'PT Serif Caption', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'cyrillic', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Pacifico', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Paprika', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Parisienne', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Passero One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Passion One', + 'variants': [ + 'regular', + '700', + '900' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Patrick Hand', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Patua One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Paytone One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Peralta', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Permanent Marker', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Petit Formal Script', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Petrona', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Philosopher', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'cyrillic', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Piedra', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Pinyon Script', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Pirata One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Plaster', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Play', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'cyrillic', + 'greek-ext', + 'latin-ext', + 'latin', + 'greek', + 'cyrillic-ext' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Playball', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Playfair Display', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic', + '900', + '900italic' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Playfair Display SC', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic', + '900', + '900italic' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Podkova', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Poiret One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Poller One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Poly', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Pompiere', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Pontano Sans', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Port Lligat Sans', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Port Lligat Slab', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Prata', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Preahvihear', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Press Start 2P', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin', + 'greek' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Princess Sofia', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Prociono', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Prosto One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Puritan', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Purple Purse', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Quando', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Quantico', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Quattrocento', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Quattrocento Sans', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Questrial', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Quicksand', + 'variants': [ + '300', + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Quintessential', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Qwigley', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Racing Sans One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Radley', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Raleway', + 'variants': [ + '100', + '200', + '300', + 'regular', + '500', + '600', + '700', + '800', + '900' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Raleway Dots', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Rambla', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Rammetto One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Ranchers', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Rancho', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Rationale', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Redressed', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Reenie Beanie', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Revalia', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Ribeye', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Ribeye Marrow', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Righteous', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Risque', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Rochester', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Rock Salt', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Rokkitt', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Romanesco', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Ropa Sans', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Rosario', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Rosarivo', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Rouge Script', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Ruda', + 'variants': [ + 'regular', + '700', + '900' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Rufina', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Ruge Boogie', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Ruluko', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Rum Raisin', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Ruslan Display', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin', + 'cyrillic-ext' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Russo One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Ruthie', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Rye', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Sacramento', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Sail', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Salsa', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Sanchez', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Sancreek', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Sansita One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Sarina', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Satisfy', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Scada', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Schoolbell', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Seaweed Script', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Sevillana', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Seymour One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Shadows Into Light', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Shadows Into Light Two', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Shanti', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Share', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Share Tech', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Share Tech Mono', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Shojumaru', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Short Stack', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Siemreap', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Sigmar One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Signika', + 'variants': [ + '300', + 'regular', + '600', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Signika Negative', + 'variants': [ + '300', + 'regular', + '600', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Simonetta', + 'variants': [ + 'regular', + 'italic', + '900', + '900italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Sirin Stencil', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Six Caps', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Skranji', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Slackey', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Smokum', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Smythe', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Sniglet', + 'variants': [ + '800' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Snippet', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Snowburst One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Sofadi One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Sofia', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Sonsie One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Sorts Mill Goudy', + 'variants': [ + 'regular', + 'italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Source Code Pro', + 'variants': [ + '200', + '300', + 'regular', + '600', + '700', + '900' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Source Sans Pro', + 'variants': [ + '200', + '200italic', + '300', + '300italic', + 'regular', + 'italic', + '600', + '600italic', + '700', + '700italic', + '900', + '900italic' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Special Elite', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Spicy Rice', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Spinnaker', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Spirax', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Squada One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Stalemate', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Stalinist One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Stardos Stencil', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Stint Ultra Condensed', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Stint Ultra Expanded', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Stoke', + 'variants': [ + '300', + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Strait', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Sue Ellen Francisco', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Sunshiney', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Supermercado One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Suwannaphum', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Swanky and Moo Moo', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Syncopate', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Tangerine', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Taprom', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'khmer' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Telex', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Tenor Sans', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin', + 'cyrillic-ext' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Text Me One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'The Girl Next Door', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Tienne', + 'variants': [ + 'regular', + '700', + '900' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Tinos', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Titan One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Titillium Web', + 'variants': [ + '200', + '200italic', + '300', + '300italic', + 'regular', + 'italic', + '600', + '600italic', + '700', + '700italic', + '900' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Trade Winds', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Trocchi', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Trochut', + 'variants': [ + 'regular', + 'italic', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Trykker', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Tulpen One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Ubuntu', + 'variants': [ + '300', + '300italic', + 'regular', + 'italic', + '500', + '500italic', + '700', + '700italic' + ], + 'subsets': [ + 'cyrillic', + 'greek-ext', + 'latin-ext', + 'latin', + 'greek', + 'cyrillic-ext' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Ubuntu Condensed', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'greek-ext', + 'latin-ext', + 'latin', + 'greek', + 'cyrillic-ext' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Ubuntu Mono', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'cyrillic', + 'greek-ext', + 'latin-ext', + 'latin', + 'greek', + 'cyrillic-ext' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Ultra', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Uncial Antiqua', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Underdog', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Unica One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'UnifrakturCook', + 'variants': [ + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'UnifrakturMaguntia', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Unkempt', + 'variants': [ + 'regular', + '700' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Unlock', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Unna', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'VT323', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Vampiro One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Varela', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Varela Round', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Vast Shadow', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Vibur', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Vidaloka', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Viga', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Voces', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Volkhov', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Vollkorn', + 'variants': [ + 'regular', + 'italic', + '700', + '700italic' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Voltaire', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Waiting for the Sunrise', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Wallpoet', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Walter Turncoat', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Warnes', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Wellfleet', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Wire One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Yanone Kaffeesatz', + 'variants': [ + '200', + '300', + 'regular', + '700' + ], + 'subsets': [ + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Yellowtail', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Yeseva One', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'cyrillic', + 'latin-ext', + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Yesteryear', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + }, + { + 'kind': 'webfonts#webfont', + 'family': 'Zeyada', + 'variants': [ + 'regular' + ], + 'subsets': [ + 'latin' + ] + } + ] +}; + +/* ========================================================== + * bootstrap-formhelpers-languages.en_US.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + +var BFHLanguagesList = { + 'om': 'Afaan Oromoo', + 'aa': 'Afaraf', + 'af': 'Afrikaans', + 'ak': 'Akan', + 'an': 'aragonés', + 'ig': 'Asụsụ Igbo', + 'gn': 'Avañe\'ẽ', + 'ae': 'avesta', + 'ay': 'aymar aru', + 'az': 'azərbaycan dili', + 'id': 'Bahasa Indonesia', + 'ms': 'bahasa Melayu', + 'bm': 'bamanankan', + 'jv': 'basa Jawa', + 'su': 'Basa Sunda', + 'bi': 'Bislama', + 'bs': 'bosanski jezik', + 'br': 'brezhoneg', + 'ca': 'català', + 'ch': 'Chamoru', + 'ny': 'chiCheŵa', + 'sn': 'chiShona', + 'co': 'corsu', + 'cy': 'Cymraeg', + 'da': 'dansk', + 'se': 'Davvisámegiella', + 'de': 'Deutsch', + 'nv': 'Diné bizaad', + 'et': 'eesti', + 'na': 'Ekakairũ Naoero', + 'en': 'English', + 'es': 'español', + 'eo': 'Esperanto', + 'eu': 'euskara', + 'ee': 'Eʋegbe', + 'to': 'faka Tonga', + 'mg': 'fiteny malagasy', + 'fr': 'français', + 'fy': 'Frysk', + 'ff': 'Fulfulde', + 'fo': 'føroyskt', + 'ga': 'Gaeilge', + 'gv': 'Gaelg', + 'sm': 'gagana fa\'a Samoa', + 'gl': 'galego', + 'sq': 'gjuha shqipe', + 'gd': 'Gàidhlig', + 'ki': 'Gĩkũyũ', + 'ha': 'Hausa', + 'ho': 'Hiri Motu', + 'hr': 'hrvatski jezik', + 'io': 'Ido', + 'rw': 'Ikinyarwanda', + 'rn': 'Ikirundi', + 'ia': 'Interlingua', + 'nd': 'isiNdebele', + 'nr': 'isiNdebele', + 'xh': 'isiXhosa', + 'zu': 'isiZulu', + 'it': 'italiano', + 'ik': 'Iñupiaq', + 'pl': 'polski', + 'mh': 'Kajin M̧ajeļ', + 'kl': 'kalaallisut', + 'kr': 'Kanuri', + 'kw': 'Kernewek', + 'kg': 'KiKongo', + 'sw': 'Kiswahili', + 'ht': 'Kreyòl ayisyen', + 'kj': 'Kuanyama', + 'ku': 'Kurdî', + 'la': 'latine', + 'lv': 'latviešu valoda', + 'lt': 'lietuvių kalba', + 'ro': 'limba română', + 'li': 'Limburgs', + 'ln': 'Lingála', + 'lg': 'Luganda', + 'lb': 'Lëtzebuergesch', + 'hu': 'magyar', + 'mt': 'Malti', + 'nl': 'Nederlands', + 'no': 'Norsk', + 'nb': 'Norsk bokmål', + 'nn': 'Norsk nynorsk', + 'uz': 'O\'zbek', + 'oc': 'occitan', + 'ie': 'Interlingue', + 'hz': 'Otjiherero', + 'ng': 'Owambo', + 'pt': 'português', + 'ty': 'Reo Tahiti', + 'rm': 'rumantsch grischun', + 'qu': 'Runa Simi', + 'sc': 'sardu', + 'za': 'Saɯ cueŋƅ', + 'st': 'Sesotho', + 'tn': 'Setswana', + 'ss': 'SiSwati', + 'sl': 'slovenski jezik', + 'sk': 'slovenčina', + 'so': 'Soomaaliga', + 'fi': 'suomi', + 'sv': 'Svenska', + 'mi': 'te reo Māori', + 'vi': 'Tiếng Việt', + 'lu': 'Tshiluba', + 've': 'Tshivenḓa', + 'tw': 'Twi', + 'tk': 'Türkmen', + 'tr': 'Türkçe', + 'ug': 'Uyƣurqə', + 'vo': 'Volapük', + 'fj': 'vosa Vakaviti', + 'wa': 'walon', + 'tl': 'Wikang Tagalog', + 'wo': 'Wollof', + 'ts': 'Xitsonga', + 'yo': 'Yorùbá', + 'sg': 'yângâ tî sängö', + 'is': 'Íslenska', + 'cs': 'čeština', + 'el': 'ελληνικά', + 'av': 'авар мацӀ', + 'ab': 'аҧсуа бызшәа', + 'ba': 'башҡорт теле', + 'be': 'беларуская мова', + 'bg': 'български език', + 'os': 'ирон æвзаг', + 'kv': 'коми кыв', + 'ky': 'Кыргызча', + 'mk': 'македонски јазик', + 'mn': 'монгол', + 'ce': 'нохчийн мотт', + 'ru': 'русский язык', + 'sr': 'српски језик', + 'tt': 'татар теле', + 'tg': 'тоҷикӣ', + 'uk': 'українська мова', + 'cv': 'чӑваш чӗлхи', + 'cu': 'ѩзыкъ словѣньскъ', + 'kk': 'қазақ тілі', + 'hy': 'Հայերեն', + 'yi': 'ייִדיש', + 'he': 'עברית', + 'ur': 'اردو', + 'ar': 'العربية', + 'fa': 'فارسی', + 'ps': 'پښتو', + 'ks': 'कश्मीरी', + 'ne': 'नेपाली', + 'pi': 'पाऴि', + 'bh': 'भोजपुरी', + 'mr': 'मराठी', + 'sa': 'संस्कृतम्', + 'sd': 'सिन्धी', + 'hi': 'हिन्दी', + 'as': 'অসমীয়া', + 'bn': 'বাংলা', + 'pa': 'ਪੰਜਾਬੀ', + 'gu': 'ગુજરાતી', + 'or': 'ଓଡ଼ିଆ', + 'ta': 'தமிழ்', + 'te': 'తెలుగు', + 'kn': 'ಕನ್ನಡ', + 'ml': 'മലയാളം', + 'si': 'සිංහල', + 'th': 'ไทย', + 'lo': 'ພາສາລາວ', + 'bo': 'བོད་ཡིག', + 'dz': 'རྫོང་ཁ', + 'my': 'ဗမာစာ', + 'ka': 'ქართული', + 'ti': 'ትግርኛ', + 'am': 'አማርኛ', + 'iu': 'ᐃᓄᒃᑎᑐᑦ', + 'oj': 'ᐊᓂᔑᓈᐯᒧᐎᓐ', + 'cr': 'ᓀᐦᐃᔭᐍᐏᐣ', + 'km': 'ខ្មែរ', + 'zh': '中文 (Zhōngwén)', + 'ja': '日本語 (にほんご)', + 'ii': 'ꆈꌠ꒿ Nuosuhxop', + 'ko': '한국어 (韓國語)' +}; + +/* ========================================================== + * bootstrap-formhelpers-phone.en_US.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file edcept in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either edpress or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + +var BFHPhoneFormatList = { + 'AF': '+93 0dd ddd dddd', + 'AL': '+355 0dd ddd ddd', + 'DZ': '+213 0ddd dd dd dd', + 'AS': '+1 (ddd) ddd-dddd', + 'AD': '+376 ddddddddd', + 'AO': '+244 ddd ddd ddd', + 'AI': '+1 (ddd) ddd-dddd', + 'AQ': '+672 ddddddddd', + 'AG': '+1 (ddd) ddd-dddd', + 'AR': '+54 ddddddddd', + 'AM': '+374 0dd dddddd', + 'AW': '+297 ddd dddd', + 'AU': '+61 ddd ddd ddd', + 'AT': '+43 0dddd ddddddddd', + 'AZ': '+994 ddddddddd', + 'BH': '+973 ddddddddd', + 'BD': '+880 ddddddddd', + 'BB': '+1 ddddddddd', + 'BY': '+375 ddddddddd', + 'BE': '+32 ddddddddd', + 'BZ': '+501 ddddddddd', + 'BJ': '+229 ddddddddd', + 'BM': '+1 (ddd) ddd-dddd', + 'BT': '+975 ddddddddd', + 'BO': '+591 ddddddddd', + 'BA': '+387 ddddddddd', + 'BW': '+267 ddddddddd', + 'BV': '+0 ddddddddd', + 'BR': '+55 ddddddddd', + 'IO': '+0 ddddddddd', + 'VG': '+1 (ddd) ddd-dddd', + 'BN': '+673 ddddddddd', + 'BG': '+359 ddddddddd', + 'BF': '+226 ddddddddd', + 'BI': '+257 ddddddddd', + 'CI': '+225 ddddddddd', + 'KH': '+855 ddddddddd', + 'CM': '+237 ddddddddd', + 'CA': '+1 (ddd) ddd-dddd', + 'CV': '+238 ddddddddd', + 'KY': '+1 (ddd) ddd-dddd', + 'CF': '+236 ddddddddd', + 'TD': '+235 ddddddddd', + 'CL': '+56 ddddddddd', + 'CN': '+86 ddddddddd', + 'CX': '+61 ddddddddd', + 'CC': '+61 ddddddddd', + 'CO': '+57 ddddddddd', + 'KM': '+269 ddddddddd', + 'CG': '+242 ddddddddd', + 'CK': '+682 ddddddddd', + 'CR': '+506 ddddddddd', + 'HR': '+385 ddddddddd', + 'CU': '+53 ddddddddd', + 'CY': '+357 ddddddddd', + 'CZ': '+420 ddddddddd', + 'CD': '+243 ddddddddd', + 'DK': '+45 ddddddddd', + 'DJ': '+253 ddddddddd', + 'DM': '+1 (ddd) ddd-dddd', + 'DO': '+1 (ddd) ddd-dddd', + 'TL': '+670 ddddddddd', + 'EC': '+593 ddddddddd', + 'EG': '+20 ddddddddd', + 'SV': '+503 ddddddddd', + 'GQ': '+240 ddddddddd', + 'ER': '+291 ddddddddd', + 'EE': '+372 ddddddddd', + 'ET': '+251 ddddddddd', + 'FO': '+298 ddddddddd', + 'FK': '+500 ddddddddd', + 'FJ': '+679 ddddddddd', + 'FI': '+358 ddddddddd', + 'MK': '+389 ddddddddd', + 'FR': '+33 d dd dd dd dd', + 'GF': '+594 ddddddddd', + 'PF': '+689 ddddddddd', + 'TF': '+262 ddddddddd', + 'GA': '+241 ddddddddd', + 'GE': '+995 ddddddddd', + 'DE': '+49 ddddddddd', + 'GH': '+233 ddddddddd', + 'GI': '+350 ddddddddd', + 'GR': '+30 ddddddddd', + 'GL': '+299 ddddddddd', + 'GD': '+1 (ddd) ddd-dddd', + 'GP': '+590 ddddddddd', + 'GU': '+1 (ddd) ddd-dddd', + 'GT': '+502 ddddddddd', + 'GN': '+224 ddddddddd', + 'GW': '+245 ddddddddd', + 'GY': '+592 ddddddddd', + 'HT': '+509 ddddddddd', + 'HM': '+0 ddddddddd', + 'HN': '+504 ddddddddd', + 'HK': '+852 ddddddddd', + 'HU': '+36 ddddddddd', + 'IS': '+354 ddddddddd', + 'IN': '+91 ddddddddd', + 'ID': '+62 ddddddddd', + 'IR': '+98 ddddddddd', + 'IQ': '+964 ddddddddd', + 'IE': '+353 ddddddddd', + 'IL': '+972 ddddddddd', + 'IT': '+39 ddddddddd', + 'JM': '+1 (ddd) ddd-dddd', + 'JP': '+81 ddddddddd', + 'JO': '+962 ddddddddd', + 'KZ': '+7 ddddddddd', + 'KE': '+254 ddddddddd', + 'KI': '+686 ddddddddd', + 'KW': '+965 ddddddddd', + 'KG': '+996 ddddddddd', + 'LA': '+856 ddddddddd', + 'LV': '+371 ddddddddd', + 'LB': '+961 ddddddddd', + 'LS': '+266 ddddddddd', + 'LR': '+231 ddddddddd', + 'LY': '+218 ddddddddd', + 'LI': '+423 ddddddddd', + 'LT': '+370 ddddddddd', + 'LU': '+352 ddddddddd', + 'MO': '+853 ddddddddd', + 'MG': '+261 ddddddddd', + 'MW': '+265 ddddddddd', + 'MY': '+60 ddddddddd', + 'MV': '+960 ddddddddd', + 'ML': '+223 ddddddddd', + 'MT': '+356 ddddddddd', + 'MH': '+692 ddddddddd', + 'MQ': '+596 ddddddddd', + 'MR': '+222 ddddddddd', + 'MU': '+230 ddddddddd', + 'YT': '+262 ddddddddd', + 'MX': '+52 ddddddddd', + 'FM': '+691 ddddddddd', + 'MD': '+373 ddddddddd', + 'MC': '+377 ddddddddd', + 'MN': '+976 ddddddddd', + 'MS': '+1 (ddd) ddd-dddd', + 'MA': '+212 ddddddddd', + 'MZ': '+258 ddddddddd', + 'MM': '+95 ddddddddd', + 'NA': '+264 ddddddddd', + 'NR': '+674 ddddddddd', + 'NP': '+977 ddddddddd', + 'NL': '+31 ddddddddd', + 'AN': '+599 ddddddddd', + 'NC': '+687 ddddddddd', + 'NZ': '+64 ddddddddd', + 'NI': '+505 ddddddddd', + 'NE': '+227 ddddddddd', + 'NG': '+234 ddddddddd', + 'NU': '+683 ddddddddd', + 'NF': '+672 ddddddddd', + 'KP': '+850 ddddddddd', + 'MP': '+1 (ddd) ddd-dddd', + 'NO': '+47 ddddddddd', + 'OM': '+968 ddddddddd', + 'PK': '+92 ddddddddd', + 'PW': '+680 ddddddddd', + 'PA': '+507 ddddddddd', + 'PG': '+675 ddddddddd', + 'PY': '+595 ddddddddd', + 'PE': '+51 ddddddddd', + 'PH': '+63 ddddddddd', + 'PN': '+870 ddddddddd', + 'PL': '+48 ddddddddd', + 'PT': '+351 ddddddddd', + 'PR': '+1 (ddd) ddd-dddd', + 'QA': '+974 ddddddddd', + 'RE': '+262 ddddddddd', + 'RO': '+40 ddddddddd', + 'RU': '+7 ddddddddd', + 'RW': '+250 ddddddddd', + 'ST': '+239 ddddddddd', + 'SH': '+290 ddddddddd', + 'KN': '+1 (ddd) ddd-dddd', + 'LC': '+1 (ddd) ddd-dddd', + 'PM': '+508 ddddddddd', + 'VC': '+1 (ddd) ddd-dddd', + 'WS': '+685 ddddddddd', + 'SM': '+378 ddddddddd', + 'SA': '+966 ddddddddd', + 'SN': '+221 ddddddddd', + 'SC': '+248 ddddddddd', + 'SL': '+232 ddddddddd', + 'SG': '+65 ddddddddd', + 'SK': '+421 ddddddddd', + 'SI': '+386 ddddddddd', + 'SB': '+677 ddddddddd', + 'SO': '+252 ddddddddd', + 'ZA': '+27 ddddddddd', + 'GS': '+0 ddddddddd', + 'KR': '+82 ddddddddd', + 'ES': '+34 ddddddddd', + 'LK': '+94 ddddddddd', + 'SD': '+249 ddddddddd', + 'SR': '+597 ddddddddd', + 'SJ': '+0 ddddddddd', + 'SZ': '+268 ddddddddd', + 'SE': '+46 ddddddddd', + 'CH': '+41 ddddddddd', + 'SY': '+963 ddddddddd', + 'TW': '+886 ddddddddd', + 'TJ': '+992 ddddddddd', + 'TZ': '+255 ddddddddd', + 'TH': '+66 ddddddddd', + 'BS': '+1 (ddd) ddd-dddd', + 'GM': '+220 ddddddddd', + 'TG': '+228 ddddddddd', + 'TK': '+690 ddddddddd', + 'TO': '+676 ddddddddd', + 'TT': '+1 (ddd) ddd-dddd', + 'TN': '+216 ddddddddd', + 'TR': '+90 ddddddddd', + 'TM': '+993 ddddddddd', + 'TC': '+1 (ddd) ddd-dddd', + 'TV': '+688 ddddddddd', + 'VI': '+1 (ddd) ddd-dddd', + 'UG': '+256 ddddddddd', + 'UA': '+380 ddddddddd', + 'AE': '+971 ddddddddd', + 'GB': '+44 (ddd) dddd dddd', + 'US': '+1 (ddd) ddd-dddd', + 'UM': '+0 ddddddddd', + 'UY': '+598 ddddddddd', + 'UZ': '+998 ddddddddd', + 'VU': '+678 ddddddddd', + 'VA': '+39 ddddddddd', + 'VE': '+58 ddddddddd', + 'VN': '+84 ddddddddd', + 'WF': '+681 ddddddddd', + 'EH': '+0 ddddddddd', + 'YE': '+967 ddddddddd', + 'YU': '+0 ddddddddd', + 'ZM': '+260 ddddddddd', + 'ZW': '+263 ddddddddd' +}; + +/* ========================================================== + * bootstrap-formhelpers-states.en_US.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + +var BFHStatesList = { + 'AF':{ + '1' : {'code':'BAL','name':'Balkh'}, + '2' : {'code':'BAM','name':'Bamian'}, + '3' : {'code':'BDG','name':'Badghis'}, + '4' : {'code':'BDS','name':'Badakhshan'}, + '5' : {'code':'BGL','name':'Baghlan'}, + '6' : {'code':'FRA','name':'Farah'}, + '7' : {'code':'FYB','name':'Faryab'}, + '8' : {'code':'GHA','name':'Ghazni'}, + '9' : {'code':'GHO','name':'Ghowr'}, + '10' : {'code':'HEL','name':'Helmand'}, + '11' : {'code':'HER','name':'Herat'}, + '12' : {'code':'JOW','name':'Jowzjan'}, + '13' : {'code':'KAB','name':'Kabul'}, + '14' : {'code':'KAN','name':'Kandahar'}, + '15' : {'code':'KAP','name':'Kapisa'}, + '16' : {'code':'KDZ','name':'Kondoz'}, + '17' : {'code':'KHO','name':'Khost'}, + '18' : {'code':'KNR','name':'Konar'}, + '19' : {'code':'LAG','name':'Laghman'}, + '20' : {'code':'LOW','name':'Lowgar'}, + '21' : {'code':'NAN','name':'Nangrahar'}, + '22' : {'code':'NIM','name':'Nimruz'}, + '23' : {'code':'NUR','name':'Nurestan'}, + '24' : {'code':'ORU','name':'Oruzgan'}, + '25' : {'code':'PAR','name':'Parwan'}, + '26' : {'code':'PIA','name':'Paktia'}, + '27' : {'code':'PKA','name':'Paktika'}, + '28' : {'code':'SAM','name':'Samangan'}, + '29' : {'code':'SAR','name':'Sar-e Pol'}, + '30' : {'code':'TAK','name':'Takhar'}, + '31' : {'code':'WAR','name':'Wardak'}, + '32' : {'code':'ZAB','name':'Zabol'} + }, + 'AL':{ + '1' : {'code':'BR','name':'Berat'}, + '2' : {'code':'BU','name':'Bulqize'}, + '3' : {'code':'DI','name':'Diber'}, + '4' : {'code':'DL','name':'Delvine'}, + '5' : {'code':'DR','name':'Durres'}, + '6' : {'code':'DV','name':'Devoll'}, + '7' : {'code':'EL','name':'Elbasan'}, + '8' : {'code':'ER','name':'Kolonje'}, + '9' : {'code':'FR','name':'Fier'}, + '10' : {'code':'GJ','name':'Gjirokaster'}, + '11' : {'code':'GR','name':'Gramsh'}, + '12' : {'code':'HA','name':'Has'}, + '13' : {'code':'KA','name':'Kavaje'}, + '14' : {'code':'KB','name':'Kurbin'}, + '15' : {'code':'KC','name':'Kucove'}, + '16' : {'code':'KO','name':'Korce'}, + '17' : {'code':'KR','name':'Kruje'}, + '18' : {'code':'KU','name':'Kukes'}, + '19' : {'code':'LB','name':'Librazhd'}, + '20' : {'code':'LE','name':'Lezhe'}, + '21' : {'code':'LU','name':'Lushnje'}, + '22' : {'code':'MK','name':'Mallakaster'}, + '23' : {'code':'MM','name':'Malesi e Madhe'}, + '24' : {'code':'MR','name':'Mirdite'}, + '25' : {'code':'MT','name':'Mat'}, + '26' : {'code':'PG','name':'Pogradec'}, + '27' : {'code':'PQ','name':'Peqin'}, + '28' : {'code':'PR','name':'Permet'}, + '29' : {'code':'PU','name':'Puke'}, + '30' : {'code':'SH','name':'Shkoder'}, + '31' : {'code':'SK','name':'Skrapar'}, + '32' : {'code':'SR','name':'Sarande'}, + '33' : {'code':'TE','name':'Tepelene'}, + '34' : {'code':'TP','name':'Tropoje'}, + '35' : {'code':'TR','name':'Tirane'}, + '36' : {'code':'VL','name':'Vlore'} + }, + 'DZ':{ + '1' : {'code':'ADE','name':'Ain Defla'}, + '2' : {'code':'ADR','name':'Adrar'}, + '3' : {'code':'ALG','name':'Alger'}, + '4' : {'code':'ANN','name':'Annaba'}, + '5' : {'code':'ATE','name':'Ain Temouchent'}, + '6' : {'code':'BAT','name':'Batna'}, + '7' : {'code':'BBA','name':'Bordj Bou Arreridj'}, + '8' : {'code':'BEC','name':'Bechar'}, + '9' : {'code':'BEJ','name':'Bejaia'}, + '10' : {'code':'BIS','name':'Biskra'}, + '11' : {'code':'BLI','name':'Blida'}, + '12' : {'code':'BMD','name':'Boumerdes'}, + '13' : {'code':'BOA','name':'Bouira'}, + '14' : {'code':'CHL','name':'Chlef'}, + '15' : {'code':'CON','name':'Constantine'}, + '16' : {'code':'DJE','name':'Djelfa'}, + '17' : {'code':'EBA','name':'El Bayadh'}, + '18' : {'code':'EOU','name':'El Oued'}, + '19' : {'code':'ETA','name':'El Tarf'}, + '20' : {'code':'GHA','name':'Ghardaia'}, + '21' : {'code':'GUE','name':'Guelma'}, + '22' : {'code':'ILL','name':'Illizi'}, + '23' : {'code':'JIJ','name':'Jijel'}, + '24' : {'code':'KHE','name':'Khenchela'}, + '25' : {'code':'LAG','name':'Laghouat'}, + '26' : {'code':'MED','name':'Medea'}, + '27' : {'code':'MIL','name':'Mila'}, + '28' : {'code':'MOS','name':'Mostaganem'}, + '29' : {'code':'MSI','name':'M\'Sila'}, + '30' : {'code':'MUA','name':'Muaskar'}, + '31' : {'code':'NAA','name':'Naama'}, + '32' : {'code':'OEB','name':'Oum el-Bouaghi'}, + '33' : {'code':'ORA','name':'Oran'}, + '34' : {'code':'OUA','name':'Ouargla'}, + '35' : {'code':'REL','name':'Relizane'}, + '36' : {'code':'SAH','name':'Souk Ahras'}, + '37' : {'code':'SAI','name':'Saida'}, + '38' : {'code':'SBA','name':'Sidi Bel Abbes'}, + '39' : {'code':'SET','name':'Setif'}, + '40' : {'code':'SKI','name':'Skikda'}, + '41' : {'code':'TAM','name':'Tamanghasset'}, + '42' : {'code':'TEB','name':'Tebessa'}, + '43' : {'code':'TIA','name':'Tiaret'}, + '44' : {'code':'TIN','name':'Tindouf'}, + '45' : {'code':'TIP','name':'Tipaza'}, + '46' : {'code':'TIS','name':'Tissemsilt'}, + '47' : {'code':'TLE','name':'Tlemcen'}, + '48' : {'code':'TOU','name':'Tizi Ouzou'} + }, + 'AS':{ + '1' : {'code':'E','name':'Eastern'}, + '2' : {'code':'M','name':'Manu\'a'}, + '3' : {'code':'R','name':'Rose Island'}, + '4' : {'code':'S','name':'Swains Island'}, + '5' : {'code':'W','name':'Western'} + }, + 'AD':{ + '1' : {'code':'ALV','name':'Andorra la Vella'}, + '2' : {'code':'CAN','name':'Canillo'}, + '3' : {'code':'ENC','name':'Encamp'}, + '4' : {'code':'ESE','name':'Escaldes-Engordany'}, + '5' : {'code':'LMA','name':'La Massana'}, + '6' : {'code':'ORD','name':'Ordino'}, + '7' : {'code':'SJL','name':'Sant Julià de Lòria'} + }, + 'AO':{ + '1' : {'code':'BGO','name':'Bengo'}, + '2' : {'code':'BGU','name':'Benguela'}, + '3' : {'code':'BIE','name':'Bie'}, + '4' : {'code':'CAB','name':'Cabinda'}, + '5' : {'code':'CCU','name':'Cuando-Cubango'}, + '6' : {'code':'CNO','name':'Cuanza Norte'}, + '7' : {'code':'CUS','name':'Cuanza Sul'}, + '8' : {'code':'CNN','name':'Cunene'}, + '9' : {'code':'HUA','name':'Huambo'}, + '10' : {'code':'HUI','name':'Huila'}, + '11' : {'code':'LUA','name':'Luanda'}, + '12' : {'code':'LNO','name':'Lunda Norte'}, + '13' : {'code':'LSU','name':'Lunda Sul'}, + '14' : {'code':'MAL','name':'Malange'}, + '15' : {'code':'MOX','name':'Moxico'}, + '16' : {'code':'NAM','name':'Namibe'}, + '17' : {'code':'UIG','name':'Uige'}, + '18' : {'code':'ZAI','name':'Zaire'} + }, + 'AI':{ + '1' : {'code':'ANG','name':'Anguillita'}, + '2' : {'code':'ANG','name':'Anguila'}, + '3' : {'code':'DOG','name':'Dog'}, + '4' : {'code':'LIT','name':'Little Scrub'}, + '5' : {'code':'PRI','name':'Prickly Pear'}, + '6' : {'code':'SAN','name':'Sandy'}, + '7' : {'code':'SCR','name':'Scrub'}, + '8' : {'code':'SEA','name':'Seal'}, + '9' : {'code':'SOM','name':'Sombrero'} + }, + 'AQ':{ + '1' : {'code':'ASG','name':'Saint George'}, + '2' : {'code':'ASH','name':'Saint Philip'}, + '3' : {'code':'ASJ','name':'Saint John'}, + '4' : {'code':'ASL','name':'Saint Paul'}, + '5' : {'code':'ASM','name':'Saint Mary'}, + '6' : {'code':'ASR','name':'Saint Peter'}, + '7' : {'code':'BAR','name':'Barbuda'}, + '8' : {'code':'RED','name':'Redonda'} + }, + 'AR':{ + '1' : {'code':'AN','name':'Antartida e Islas del Atlantico'}, + '2' : {'code':'BA','name':'Buenos Aires'}, + '3' : {'code':'CA','name':'Catamarca'}, + '4' : {'code':'CH','name':'Chaco'}, + '5' : {'code':'CU','name':'Chubut'}, + '6' : {'code':'CO','name':'Cordoba'}, + '7' : {'code':'CR','name':'Corrientes'}, + '8' : {'code':'CF','name':'Capital Federal'}, + '9' : {'code':'ER','name':'Entre Rios'}, + '10' : {'code':'FO','name':'Formosa'}, + '11' : {'code':'JU','name':'Jujuy'}, + '12' : {'code':'LP','name':'La Pampa'}, + '13' : {'code':'LR','name':'La Rioja'}, + '14' : {'code':'ME','name':'Mendoza'}, + '15' : {'code':'MI','name':'Misiones'}, + '16' : {'code':'NE','name':'Neuquen'}, + '17' : {'code':'RN','name':'Rio Negro'}, + '18' : {'code':'SA','name':'Salta'}, + '19' : {'code':'SJ','name':'San Juan'}, + '20' : {'code':'SL','name':'San Luis'}, + '21' : {'code':'SC','name':'Santa Cruz'}, + '22' : {'code':'SF','name':'Santa Fe'}, + '23' : {'code':'SD','name':'Santiago del Estero'}, + '24' : {'code':'TF','name':'Tierra del Fuego'}, + '25' : {'code':'TU','name':'Tucuman'} + }, + 'AM':{ + '1' : {'code':'AGT','name':'Aragatsotn'}, + '2' : {'code':'ARR','name':'Ararat'}, + '3' : {'code':'ARM','name':'Armavir'}, + '4' : {'code':'GEG','name':'Geghark \'unik\''}, + '5' : {'code':'KOT','name':'Kotayk\''}, + '6' : {'code':'LOR','name':'Lorri'}, + '7' : {'code':'SHI','name':'Shirak'}, + '8' : {'code':'SYU','name':'Syunik\''}, + '9' : {'code':'TAV','name':'Tavush'}, + '10' : {'code':'VAY','name':'Vayots\' Dzor'}, + '11' : {'code':'YER','name':'Yerevan'} + }, + 'AW':{ + '1' : {'code':'ARU','name':'Aruba'}, + '2' : {'code':'DRU','name':'Druif Beach'}, + '3' : {'code':'MAN','name':'Manchebo Beach'}, + '4' : {'code':'NOO','name':'Noord'}, + '5' : {'code':'ORA','name':'Oranjestad'}, + '6' : {'code':'PAL','name':'Palm Beach'}, + '7' : {'code':'ROO','name':'Rooi Thomas'}, + '8' : {'code':'SIN','name':'Sint Nicolaas'}, + '9' : {'code':'SIN','name':'Sint Nicolas'}, + '10' : {'code':'WAY','name':'Wayaca'} + }, + 'AU':{ + '1' : {'code':'ACT','name':'Australian Capital Territory'}, + '2' : {'code':'NSW','name':'New South Wales'}, + '3' : {'code':'NT','name':'Northern Territory'}, + '4' : {'code':'QLD','name':'Queensland'}, + '5' : {'code':'SA','name':'South Australia'}, + '6' : {'code':'TAS','name':'Tasmania'}, + '7' : {'code':'VIC','name':'Victoria'}, + '8' : {'code':'WA','name':'Western Australia'} + }, + 'AT':{ + '1' : {'code':'BUR','name':'Burgenland'}, + '2' : {'code':'KAR','name':'Krnten'}, + '3' : {'code':'NOS','name':'Niederöesterreich'}, + '4' : {'code':'OOS','name':'Oberöesterreich'}, + '5' : {'code':'SAL','name':'Salzburg'}, + '6' : {'code':'STE','name':'Steiermark'}, + '7' : {'code':'TIR','name':'Tirol'}, + '8' : {'code':'VOR','name':'Vorarlberg'}, + '9' : {'code':'WIE','name':'Wien'} + }, + 'AZ':{ + '1' : {'code':'AB','name':'Ali Bayramli'}, + '2' : {'code':'ABS','name':'Abseron'}, + '3' : {'code':'AGC','name':'AgcabAdi'}, + '4' : {'code':'AGM','name':'Agdam'}, + '5' : {'code':'AGS','name':'Agdas'}, + '6' : {'code':'AGA','name':'Agstafa'}, + '7' : {'code':'AGU','name':'Agsu'}, + '8' : {'code':'AST','name':'Astara'}, + '9' : {'code':'BA','name':'Baki'}, + '10' : {'code':'BAB','name':'BabAk'}, + '11' : {'code':'BAL','name':'BalakAn'}, + '12' : {'code':'BAR','name':'BArdA'}, + '13' : {'code':'BEY','name':'Beylaqan'}, + '14' : {'code':'BIL','name':'Bilasuvar'}, + '15' : {'code':'CAB','name':'Cabrayil'}, + '16' : {'code':'CAL','name':'Calilabab'}, + '17' : {'code':'CUL','name':'Culfa'}, + '18' : {'code':'DAS','name':'Daskasan'}, + '19' : {'code':'DAV','name':'Davaci'}, + '20' : {'code':'FUZ','name':'Fuzuli'}, + '21' : {'code':'GA','name':'Ganca'}, + '22' : {'code':'GAD','name':'Gadabay'}, + '23' : {'code':'GOR','name':'Goranboy'}, + '24' : {'code':'GOY','name':'Goycay'}, + '25' : {'code':'HAC','name':'Haciqabul'}, + '26' : {'code':'IMI','name':'Imisli'}, + '27' : {'code':'ISM','name':'Ismayilli'}, + '28' : {'code':'KAL','name':'Kalbacar'}, + '29' : {'code':'KUR','name':'Kurdamir'}, + '30' : {'code':'LA','name':'Lankaran'}, + '31' : {'code':'LAC','name':'Lacin'}, + '32' : {'code':'LAN','name':'Lankaran'}, + '33' : {'code':'LER','name':'Lerik'}, + '34' : {'code':'MAS','name':'Masalli'}, + '35' : {'code':'MI','name':'Mingacevir'}, + '36' : {'code':'NA','name':'Naftalan'}, + '37' : {'code':'NX','name':'Naxcivan'}, + '38' : {'code':'NEF','name':'Neftcala'}, + '39' : {'code':'OGU','name':'Oguz'}, + '40' : {'code':'ORD','name':'Ordubad'}, + '41' : {'code':'QAB','name':'Qabala'}, + '42' : {'code':'QAX','name':'Qax'}, + '43' : {'code':'QAZ','name':'Qazax'}, + '44' : {'code':'QOB','name':'Qobustan'}, + '45' : {'code':'QBA','name':'Quba'}, + '46' : {'code':'QBI','name':'Qubadli'}, + '47' : {'code':'QUS','name':'Qusar'}, + '48' : {'code':'SA','name':'Saki'}, + '49' : {'code':'SAT','name':'Saatli'}, + '50' : {'code':'SAB','name':'Sabirabad'}, + '51' : {'code':'SAD','name':'Sadarak'}, + '52' : {'code':'SAH','name':'Sahbuz'}, + '53' : {'code':'SAK','name':'Saki'}, + '54' : {'code':'SAL','name':'Salyan'}, + '55' : {'code':'SM','name':'Sumqayit'}, + '56' : {'code':'SMI','name':'Samaxi'}, + '57' : {'code':'SKR','name':'Samkir'}, + '58' : {'code':'SMX','name':'Samux'}, + '59' : {'code':'SAR','name':'Sarur'}, + '60' : {'code':'SIY','name':'Siyazan'}, + '61' : {'code':'SS','name':'Susa'}, + '62' : {'code':'SUS','name':'Susa'}, + '63' : {'code':'TAR','name':'Tartar'}, + '64' : {'code':'TOV','name':'Tovuz'}, + '65' : {'code':'UCA','name':'Ucar'}, + '66' : {'code':'XA','name':'Xankandi'}, + '67' : {'code':'XAC','name':'Xacmaz'}, + '68' : {'code':'XAN','name':'Xanlar'}, + '69' : {'code':'XIZ','name':'Xizi'}, + '70' : {'code':'XCI','name':'Xocali'}, + '71' : {'code':'XVD','name':'Xocavand'}, + '72' : {'code':'YAR','name':'Yardimli'}, + '73' : {'code':'YEV','name':'Yevlax'}, + '74' : {'code':'ZAN','name':'Zangilan'}, + '75' : {'code':'ZAQ','name':'Zaqatala'}, + '76' : {'code':'ZAR','name':'Zardab'} + }, + 'BS':{ + '1' : {'code':'ACK','name':'Acklins'}, + '2' : {'code':'BER','name':'Berry Islands'}, + '3' : {'code':'BIM','name':'Bimini'}, + '4' : {'code':'BLK','name':'Black Point'}, + '5' : {'code':'CAT','name':'Cat Island'}, + '6' : {'code':'CAB','name':'Central Abaco'}, + '7' : {'code':'CAN','name':'Central Andros'}, + '8' : {'code':'CEL','name':'Central Eleuthera'}, + '9' : {'code':'FRE','name':'City of Freeport'}, + '10' : {'code':'CRO','name':'Crooked Island'}, + '11' : {'code':'EGB','name':'East Grand Bahama'}, + '12' : {'code':'EXU','name':'Exuma'}, + '13' : {'code':'GRD','name':'Grand Cay'}, + '14' : {'code':'HAR','name':'Harbour Island'}, + '15' : {'code':'HOP','name':'Hope Town'}, + '16' : {'code':'INA','name':'Inagua'}, + '17' : {'code':'LNG','name':'Long Island'}, + '18' : {'code':'MAN','name':'Mangrove Cay'}, + '19' : {'code':'MAY','name':'Mayaguana'}, + '20' : {'code':'MOO','name':'Moore\'s Island'}, + '21' : {'code':'NAB','name':'North Abaco'}, + '22' : {'code':'NAN','name':'North Andros'}, + '23' : {'code':'NEL','name':'North Eleuthera'}, + '24' : {'code':'RAG','name':'Ragged Island'}, + '25' : {'code':'RUM','name':'Rum Cay'}, + '26' : {'code':'SAL','name':'San Salvador'}, + '27' : {'code':'SAB','name':'South Abaco'}, + '28' : {'code':'SAN','name':'South Andros'}, + '29' : {'code':'SEL','name':'South Eleuthera'}, + '30' : {'code':'SWE','name':'Spanish Wells'}, + '31' : {'code':'WGB','name':'West Grand Bahama'} + }, + 'BH':{ + '1' : {'code':'CAP','name':'Capital'}, + '2' : {'code':'CEN','name':'Central'}, + '3' : {'code':'MUH','name':'Muharraq'}, + '4' : {'code':'NOR','name':'Northern'}, + '5' : {'code':'SOU','name':'Southern'} + }, + 'BD':{ + '1' : {'code':'BAR','name':'Barisal'}, + '2' : {'code':'CHI','name':'Chittagong'}, + '3' : {'code':'DHA','name':'Dhaka'}, + '4' : {'code':'KHU','name':'Khulna'}, + '5' : {'code':'RAJ','name':'Rajshahi'}, + '6' : {'code':'SYL','name':'Sylhet'} + }, + 'BB':{ + '1' : {'code':'CC','name':'Christ Church'}, + '2' : {'code':'AND','name':'Saint Andrew'}, + '3' : {'code':'GEO','name':'Saint George'}, + '4' : {'code':'JAM','name':'Saint James'}, + '5' : {'code':'JOH','name':'Saint John'}, + '6' : {'code':'JOS','name':'Saint Joseph'}, + '7' : {'code':'LUC','name':'Saint Lucy'}, + '8' : {'code':'MIC','name':'Saint Michael'}, + '9' : {'code':'PET','name':'Saint Peter'}, + '10' : {'code':'PHI','name':'Saint Philip'}, + '11' : {'code':'THO','name':'Saint Thomas'} + }, + 'BY':{ + '1' : {'code':'BR','name':'Brestskaya (Brest)'}, + '2' : {'code':'HO','name':'Homyel\'skaya (Homyel\')'}, + '3' : {'code':'HM','name':'Horad Minsk'}, + '4' : {'code':'HR','name':'Hrodzyenskaya (Hrodna)'}, + '5' : {'code':'MA','name':'Mahilyowskaya (Mahilyow)'}, + '6' : {'code':'MI','name':'Minskaya'}, + '7' : {'code':'VI','name':'Vitsyebskaya (Vitsyebsk)'} + }, + 'BE':{ + '1' : {'code':'VAN','name':'Antwerpen'}, + '2' : {'code':'WBR','name':'Brabant Wallon'}, + '3' : {'code':'WHT','name':'Hainaut'}, + '4' : {'code':'WLG','name':'Liege'}, + '5' : {'code':'VLI','name':'Limburg'}, + '6' : {'code':'WLX','name':'Luxembourg'}, + '7' : {'code':'WNA','name':'Namur'}, + '8' : {'code':'VOV','name':'Oost-Vlaanderen'}, + '9' : {'code':'VBR','name':'Vlaams Brabant'}, + '10' : {'code':'VWV','name':'West-Vlaanderen'} + }, + 'BZ':{ + '1' : {'code':'BZ','name':'Belize'}, + '2' : {'code':'CY','name':'Cayo'}, + '3' : {'code':'CR','name':'Corozal'}, + '4' : {'code':'OW','name':'Orange Walk'}, + '5' : {'code':'SC','name':'Stann Creek'}, + '6' : {'code':'TO','name':'Toledo'} + }, + 'BJ':{ + '1' : {'code':'AL','name':'Alibori'}, + '2' : {'code':'AK','name':'Atakora'}, + '3' : {'code':'AQ','name':'Atlantique'}, + '4' : {'code':'BO','name':'Borgou'}, + '5' : {'code':'CO','name':'Collines'}, + '6' : {'code':'DO','name':'Donga'}, + '7' : {'code':'KO','name':'Kouffo'}, + '8' : {'code':'LI','name':'Littoral'}, + '9' : {'code':'MO','name':'Mono'}, + '10' : {'code':'OU','name':'Oueme'}, + '11' : {'code':'PL','name':'Plateau'}, + '12' : {'code':'ZO','name':'Zou'} + }, + 'BM':{ + '1' : {'code':'DS','name':'Devonshire'}, + '2' : {'code':'HC','name':'Hamilton City'}, + '3' : {'code':'HA','name':'Hamilton'}, + '4' : {'code':'PG','name':'Paget'}, + '5' : {'code':'PB','name':'Pembroke'}, + '6' : {'code':'GC','name':'Saint George City'}, + '7' : {'code':'SG','name':'Saint George\'s'}, + '8' : {'code':'SA','name':'Sandys'}, + '9' : {'code':'SM','name':'Smith\'s'}, + '10' : {'code':'SH','name':'Southampton'}, + '11' : {'code':'WA','name':'Warwick'} + }, + 'BT':{ + '1' : {'code':'BUM','name':'Bumthang'}, + '2' : {'code':'CHU','name':'Chukha'}, + '3' : {'code':'DAG','name':'Dagana'}, + '4' : {'code':'GAS','name':'Gasa'}, + '5' : {'code':'HAA','name':'Haa'}, + '6' : {'code':'LHU','name':'Lhuntse'}, + '7' : {'code':'MON','name':'Mongar'}, + '8' : {'code':'PAR','name':'Paro'}, + '9' : {'code':'PEM','name':'Pemagatshel'}, + '10' : {'code':'PUN','name':'Punakha'}, + '11' : {'code':'SJO','name':'Samdrup Jongkhar'}, + '12' : {'code':'SAT','name':'Samtse'}, + '13' : {'code':'SAR','name':'Sarpang'}, + '14' : {'code':'THI','name':'Thimphu'}, + '15' : {'code':'TRG','name':'Trashigang'}, + '16' : {'code':'TRY','name':'Trashiyangste'}, + '17' : {'code':'TRO','name':'Trongsa'}, + '18' : {'code':'TSI','name':'Tsirang'}, + '19' : {'code':'WPH','name':'Wangdue Phodrang'}, + '20' : {'code':'ZHE','name':'Zhemgang'} + }, + 'BO':{ + '1' : {'code':'BEN','name':'Beni'}, + '2' : {'code':'CHU','name':'Chuquisaca'}, + '3' : {'code':'COC','name':'Cochabamba'}, + '4' : {'code':'LPZ','name':'La Paz'}, + '5' : {'code':'ORU','name':'Oruro'}, + '6' : {'code':'PAN','name':'Pando'}, + '7' : {'code':'POT','name':'Potosi'}, + '8' : {'code':'SCZ','name':'Santa Cruz'}, + '9' : {'code':'TAR','name':'Tarija'} + }, + 'BA':{ + '1' : {'code':'BRO','name':'Brcko district'}, + '2' : {'code':'FBP','name':'Bosanskopodrinjski Kanton'}, + '3' : {'code':'FHN','name':'Hercegovacko-neretvanski Kanton'}, + '4' : {'code':'FPO','name':'Posavski Kanton'}, + '5' : {'code':'FSA','name':'Kanton Sarajevo'}, + '6' : {'code':'FSB','name':'Srednjebosanski Kanton'}, + '7' : {'code':'FTU','name':'Tuzlanski Kanton'}, + '8' : {'code':'FUS','name':'Unsko-Sanski Kanton'}, + '9' : {'code':'FZA','name':'Zapadnobosanska'}, + '10' : {'code':'FZE','name':'Zenicko-Dobojski Kanton'}, + '11' : {'code':'FZH','name':'Zapadnohercegovacka Zupanija'}, + '12' : {'code':'SBI','name':'Bijeljina'}, + '13' : {'code':'SBL','name':'Banja Luka'}, + '14' : {'code':'SDO','name':'Doboj'}, + '15' : {'code':'SFO','name':'Foca'}, + '16' : {'code':'SSR','name':'Sarajevo-Romanija or Sokolac'}, + '17' : {'code':'STR','name':'Trebinje'}, + '18' : {'code':'SVL','name':'Vlasenica'} + }, + 'BW':{ + '1' : {'code':'CE','name':'Central'}, + '2' : {'code':'GH','name':'Ghanzi'}, + '3' : {'code':'KD','name':'Kgalagadi'}, + '4' : {'code':'KT','name':'Kgatleng'}, + '5' : {'code':'KW','name':'Kweneng'}, + '6' : {'code':'NG','name':'Ngamiland'}, + '7' : {'code':'NE','name':'North East'}, + '8' : {'code':'NW','name':'North West'}, + '9' : {'code':'SE','name':'South East'}, + '10' : {'code':'SO','name':'Southern'} + }, + 'BR':{ + '1' : {'code':'AC','name':'Acre'}, + '2' : {'code':'AL','name':'Alagoas'}, + '3' : {'code':'AP','name':'Amapa'}, + '4' : {'code':'AM','name':'Amazonas'}, + '5' : {'code':'BA','name':'Bahia'}, + '6' : {'code':'CE','name':'Ceara'}, + '7' : {'code':'DF','name':'Distrito Federal'}, + '8' : {'code':'ES','name':'Espirito Santo'}, + '9' : {'code':'GO','name':'Goias'}, + '10' : {'code':'MA','name':'Maranhao'}, + '11' : {'code':'MT','name':'Mato Grosso'}, + '12' : {'code':'MS','name':'Mato Grosso do Sul'}, + '13' : {'code':'MG','name':'Minas Gerais'}, + '14' : {'code':'PA','name':'Para'}, + '15' : {'code':'PB','name':'Paraiba'}, + '16' : {'code':'PR','name':'Parana'}, + '17' : {'code':'PE','name':'Pernambuco'}, + '18' : {'code':'PI','name':'Piaui'}, + '19' : {'code':'RJ','name':'Rio de Janeiro'}, + '20' : {'code':'RN','name':'Rio Grande do Norte'}, + '21' : {'code':'RS','name':'Rio Grande do Sul'}, + '22' : {'code':'RO','name':'Rondonia'}, + '23' : {'code':'RR','name':'Roraima'}, + '24' : {'code':'SC','name':'Santa Catarina'}, + '25' : {'code':'SP','name':'Sao Paulo'}, + '26' : {'code':'SE','name':'Sergipe'}, + '27' : {'code':'TO','name':'Tocantins'} + }, + 'IO':{ + '1' : {'code':'DG','name':'Diego Garcia'}, + '2' : {'code':'DI','name':'Danger Island'}, + '3' : {'code':'EA','name':'Eagle Islands'}, + '4' : {'code':'EG','name':'Egmont Islands'}, + '5' : {'code':'NI','name':'Nelsons Island'}, + '6' : {'code':'PB','name':'Peros Banhos'}, + '7' : {'code':'SI','name':'Salomon Islands'}, + '8' : {'code':'TB','name':'Three Brothers'} + }, + 'BN':{ + '1' : {'code':'BEL','name':'Belait'}, + '2' : {'code':'BRM','name':'Brunei and Muara'}, + '3' : {'code':'TEM','name':'Temburong'}, + '4' : {'code':'TUT','name':'Tutong'} + }, + 'BG':{ + '1' : {'code':'BG-01','name':'Blagoevgrad'}, + '2' : {'code':'BG-02','name':'Burgas'}, + '3' : {'code':'BG-03','name':'Dobrich'}, + '4' : {'code':'BG-04','name':'Gabrovo'}, + '5' : {'code':'BG-05','name':'Haskovo'}, + '6' : {'code':'BG-06','name':'Kardjali'}, + '7' : {'code':'BG-07','name':'Kyustendil'}, + '8' : {'code':'BG-08','name':'Lovech'}, + '9' : {'code':'BG-09','name':'Montana'}, + '10' : {'code':'BG-10','name':'Pazardjik'}, + '11' : {'code':'BG-11','name':'Pernik'}, + '12' : {'code':'BG-12','name':'Pleven'}, + '13' : {'code':'BG-13','name':'Plovdiv'}, + '14' : {'code':'BG-14','name':'Razgrad'}, + '15' : {'code':'BG-15','name':'Shumen'}, + '16' : {'code':'BG-16','name':'Silistra'}, + '17' : {'code':'BG-17','name':'Sliven'}, + '18' : {'code':'BG-18','name':'Smolyan'}, + '19' : {'code':'BG-19','name':'Sofia'}, + '20' : {'code':'BG-20','name':'Sofia - town'}, + '21' : {'code':'BG-21','name':'Stara Zagora'}, + '22' : {'code':'BG-22','name':'Targovishte'}, + '23' : {'code':'BG-23','name':'Varna'}, + '24' : {'code':'BG-24','name':'Veliko Tarnovo'}, + '25' : {'code':'BG-25','name':'Vidin'}, + '26' : {'code':'BG-26','name':'Vratza'}, + '27' : {'code':'BG-27','name':'Yambol'} + }, + 'BF':{ + '1' : {'code':'BAL','name':'Bale'}, + '2' : {'code':'BAM','name':'Bam'}, + '3' : {'code':'BAN','name':'Banwa'}, + '4' : {'code':'BAZ','name':'Bazega'}, + '5' : {'code':'BOR','name':'Bougouriba'}, + '6' : {'code':'BLG','name':'Boulgou'}, + '7' : {'code':'BOK','name':'Boulkiemde'}, + '8' : {'code':'COM','name':'Comoe'}, + '9' : {'code':'GAN','name':'Ganzourgou'}, + '10' : {'code':'GNA','name':'Gnagna'}, + '11' : {'code':'GOU','name':'Gourma'}, + '12' : {'code':'HOU','name':'Houet'}, + '13' : {'code':'IOA','name':'Ioba'}, + '14' : {'code':'KAD','name':'Kadiogo'}, + '15' : {'code':'KEN','name':'Kenedougou'}, + '16' : {'code':'KOD','name':'Komondjari'}, + '17' : {'code':'KOP','name':'Kompienga'}, + '18' : {'code':'KOS','name':'Kossi'}, + '19' : {'code':'KOL','name':'Koulpelogo'}, + '20' : {'code':'KOT','name':'Kouritenga'}, + '21' : {'code':'KOW','name':'Kourweogo'}, + '22' : {'code':'LER','name':'Leraba'}, + '23' : {'code':'LOR','name':'Loroum'}, + '24' : {'code':'MOU','name':'Mouhoun'}, + '25' : {'code':'NAH','name':'Nahouri'}, + '26' : {'code':'NAM','name':'Namentenga'}, + '27' : {'code':'NAY','name':'Nayala'}, + '28' : {'code':'NOU','name':'Noumbiel'}, + '29' : {'code':'OUB','name':'Oubritenga'}, + '30' : {'code':'OUD','name':'Oudalan'}, + '31' : {'code':'PAS','name':'Passore'}, + '32' : {'code':'PON','name':'Poni'}, + '33' : {'code':'SAG','name':'Sanguie'}, + '34' : {'code':'SAM','name':'Sanmatenga'}, + '35' : {'code':'SEN','name':'Seno'}, + '36' : {'code':'SIS','name':'Sissili'}, + '37' : {'code':'SOM','name':'Soum'}, + '38' : {'code':'SOR','name':'Sourou'}, + '39' : {'code':'TAP','name':'Tapoa'}, + '40' : {'code':'TUY','name':'Tuy'}, + '41' : {'code':'YAG','name':'Yagha'}, + '42' : {'code':'YAT','name':'Yatenga'}, + '43' : {'code':'ZIR','name':'Ziro'}, + '44' : {'code':'ZOD','name':'Zondoma'}, + '45' : {'code':'ZOW','name':'Zoundweogo'} + }, + 'BI':{ + '1' : {'code':'BB','name':'Bubanza'}, + '2' : {'code':'BJ','name':'Bujumbura'}, + '3' : {'code':'BR','name':'Bururi'}, + '4' : {'code':'CA','name':'Cankuzo'}, + '5' : {'code':'CI','name':'Cibitoke'}, + '6' : {'code':'GI','name':'Gitega'}, + '7' : {'code':'KR','name':'Karuzi'}, + '8' : {'code':'KY','name':'Kayanza'}, + '9' : {'code':'KI','name':'Kirundo'}, + '10' : {'code':'MA','name':'Makamba'}, + '11' : {'code':'MU','name':'Muramvya'}, + '12' : {'code':'MY','name':'Muyinga'}, + '13' : {'code':'MW','name':'Mwaro'}, + '14' : {'code':'NG','name':'Ngozi'}, + '15' : {'code':'RT','name':'Rutana'}, + '16' : {'code':'RY','name':'Ruyigi'} + }, + 'KH':{ + '1' : {'code':'BA','name':'Battambang'}, + '2' : {'code':'BM','name':'Banteay Meanchey'}, + '3' : {'code':'KB','name':'Keb'}, + '4' : {'code':'KK','name':'Kaoh Kong'}, + '5' : {'code':'KL','name':'Kandal'}, + '6' : {'code':'KM','name':'Kampong Cham'}, + '7' : {'code':'KN','name':'Kampong Chhnang'}, + '8' : {'code':'KO','name':'Kampong Som'}, + '9' : {'code':'KP','name':'Kampot'}, + '10' : {'code':'KR','name':'Kratie'}, + '11' : {'code':'KT','name':'Kampong Thom'}, + '12' : {'code':'KU','name':'Kampong Speu'}, + '13' : {'code':'MK','name':'Mondul Kiri'}, + '14' : {'code':'OM','name':'Oddar Meancheay'}, + '15' : {'code':'PA','name':'Pailin'}, + '16' : {'code':'PG','name':'Prey Veng'}, + '17' : {'code':'PP','name':'Phnom Penh'}, + '18' : {'code':'PR','name':'Preah Vihear'}, + '19' : {'code':'PS','name':'Preah Seihanu (Kompong Som or Si)'}, + '20' : {'code':'PU','name':'Pursat'}, + '21' : {'code':'RK','name':'Ratanak Kiri'}, + '22' : {'code':'SI','name':'Siemreap'}, + '23' : {'code':'SR','name':'Svay Rieng'}, + '24' : {'code':'ST','name':'Stung Treng'}, + '25' : {'code':'TK','name':'Takeo'} + }, + 'CM':{ + '1' : {'code':'ADA','name':'Adamawa (Adamaoua)'}, + '2' : {'code':'CEN','name':'Centre'}, + '3' : {'code':'EST','name':'East (Est)'}, + '4' : {'code':'EXN','name':'Extrême-Nord'}, + '5' : {'code':'LIT','name':'Littoral'}, + '6' : {'code':'NOR','name':'North (Nord)'}, + '7' : {'code':'NOT','name':'Northwest (Nord-Ouest)'}, + '8' : {'code':'OUE','name':'West (Ouest)'}, + '9' : {'code':'SUD','name':'South (Sud)'}, + '10' : {'code':'SOU','name':'Southwest (Sud-Ouest)'} + }, + 'CA':{ + '1' : {'code':'AB','name':'Alberta'}, + '2' : {'code':'BC','name':'British Columbia'}, + '3' : {'code':'MB','name':'Manitoba'}, + '4' : {'code':'NB','name':'New Brunswick'}, + '5' : {'code':'NL','name':'Newfoundland and Labrador'}, + '6' : {'code':'NT','name':'Northwest Territories'}, + '7' : {'code':'NS','name':'Nova Scotia'}, + '8' : {'code':'NU','name':'Nunavut'}, + '9' : {'code':'ON','name':'Ontario'}, + '10' : {'code':'PE','name':'Prince Edward Island'}, + '11' : {'code':'QC','name':'Québec'}, + '12' : {'code':'SK','name':'Saskatchewan'}, + '13' : {'code':'YT','name':'Yukon Territory'} + }, + 'CV':{ + '1' : {'code':'BV','name':'Boa Vista'}, + '2' : {'code':'BR','name':'Brava'}, + '3' : {'code':'CS','name':'Calheta de Sao Miguel'}, + '4' : {'code':'MA','name':'Maio'}, + '5' : {'code':'MO','name':'Mosteiros'}, + '6' : {'code':'PA','name':'Paul'}, + '7' : {'code':'PN','name':'Porto Novo'}, + '8' : {'code':'PR','name':'Praia'}, + '9' : {'code':'RG','name':'Ribeira Grande'}, + '10' : {'code':'SL','name':'Sal'}, + '11' : {'code':'CA','name':'Santa Catarina'}, + '12' : {'code':'CR','name':'Santa Cruz'}, + '13' : {'code':'SD','name':'Sao Domingos'}, + '14' : {'code':'SF','name':'Sao Filipe'}, + '15' : {'code':'SN','name':'Sao Nicolau'}, + '16' : {'code':'SV','name':'Sao Vicente'}, + '17' : {'code':'TA','name':'Tarrafal'} + }, + 'KY':{ + '1' : {'code':'CR','name':'Creek'}, + '2' : {'code':'EA','name':'Eastern'}, + '3' : {'code':'ML','name':'Midland'}, + '4' : {'code':'ST','name':'South Town'}, + '5' : {'code':'SP','name':'Spot Bay'}, + '6' : {'code':'SK','name':'Stake Bay'}, + '7' : {'code':'WD','name':'West End'}, + '8' : {'code':'WN','name':'Western'} + }, + 'CF':{ + '1' : {'code':'BAN','name':'Bangui'}, + '2' : {'code':'BBA','name':'Bamingui-Bangoran'}, + '3' : {'code':'BKO','name':'Basse-Kotto'}, + '4' : {'code':'HKO','name':'Haute-Kotto'}, + '5' : {'code':'HMB','name':'Haut-Mbomou'}, + '6' : {'code':'KEM','name':'Kemo'}, + '7' : {'code':'LOB','name':'Lobaye'}, + '8' : {'code':'MBO','name':'Mbomou'}, + '9' : {'code':'MKD','name':'Mambéré-Kadéï'}, + '10' : {'code':'NGR','name':'Nana-Grebizi'}, + '11' : {'code':'NMM','name':'Nana-Mambere'}, + '12' : {'code':'OMP','name':'Ombella-M\'Poko'}, + '13' : {'code':'OPE','name':'Ouham-Pende'}, + '14' : {'code':'OUH','name':'Ouham'}, + '15' : {'code':'OUK','name':'Ouaka'}, + '16' : {'code':'SMB','name':'Sangha-Mbaere'}, + '17' : {'code':'VAK','name':'Vakaga'} + }, + 'TD':{ + '1' : {'code':'BA','name':'Batha'}, + '2' : {'code':'BI','name':'Biltine'}, + '3' : {'code':'BE','name':'Borkou-Ennedi-Tibesti'}, + '4' : {'code':'CB','name':'Chari-Baguirmi'}, + '5' : {'code':'GU','name':'Guera'}, + '6' : {'code':'KA','name':'Kanem'}, + '7' : {'code':'LA','name':'Lac'}, + '8' : {'code':'LC','name':'Logone Occidental'}, + '9' : {'code':'LR','name':'Logone Oriental'}, + '10' : {'code':'MK','name':'Mayo-Kebbi'}, + '11' : {'code':'MC','name':'Moyen-Chari'}, + '12' : {'code':'OU','name':'Ouaddai'}, + '13' : {'code':'SA','name':'Salamat'}, + '14' : {'code':'TA','name':'Tandjile'} + }, + 'CL':{ + '1' : {'code':'AI','name':'Aisen del General Carlos Ibanez'}, + '2' : {'code':'AN','name':'Antofagasta'}, + '3' : {'code':'AR','name':'Araucania'}, + '4' : {'code':'AT','name':'Atacama'}, + '5' : {'code':'BI','name':'Bio-Bio'}, + '6' : {'code':'CO','name':'Coquimbo'}, + '7' : {'code':'LI','name':'Libertador General Bernardo O\'Hi'}, + '8' : {'code':'LL','name':'Los Lagos'}, + '9' : {'code':'MA','name':'Magallanes y de la Antartica Chi'}, + '10' : {'code':'ML','name':'Maule'}, + '11' : {'code':'RM','name':'Region Metropolitana'}, + '12' : {'code':'TA','name':'Tarapaca'}, + '13' : {'code':'VS','name':'Valparaiso'} + }, + 'CN':{ + '1' : {'code':'AN','name':'Anhui'}, + '2' : {'code':'BE','name':'Beijing'}, + '3' : {'code':'CH','name':'Chongqing'}, + '4' : {'code':'FU','name':'Fujian'}, + '5' : {'code':'GA','name':'Gansu'}, + '6' : {'code':'GU','name':'Guangdong'}, + '7' : {'code':'GX','name':'Guangxi'}, + '8' : {'code':'GZ','name':'Guizhou'}, + '9' : {'code':'HA','name':'Hainan'}, + '10' : {'code':'HB','name':'Hebei'}, + '11' : {'code':'HL','name':'Heilongjiang'}, + '12' : {'code':'HE','name':'Henan'}, + '13' : {'code':'HK','name':'Hong Kong'}, + '14' : {'code':'HU','name':'Hubei'}, + '15' : {'code':'HN','name':'Hunan'}, + '16' : {'code':'IM','name':'Inner Mongolia'}, + '17' : {'code':'JI','name':'Jiangsu'}, + '18' : {'code':'JX','name':'Jiangxi'}, + '19' : {'code':'JL','name':'Jilin'}, + '20' : {'code':'LI','name':'Liaoning'}, + '21' : {'code':'MA','name':'Macau'}, + '22' : {'code':'NI','name':'Ningxia'}, + '23' : {'code':'SH','name':'Shaanxi'}, + '24' : {'code':'SA','name':'Shandong'}, + '25' : {'code':'SG','name':'Shanghai'}, + '26' : {'code':'SX','name':'Shanxi'}, + '27' : {'code':'SI','name':'Sichuan'}, + '28' : {'code':'TI','name':'Tianjin'}, + '29' : {'code':'XI','name':'Xinjiang'}, + '30' : {'code':'YU','name':'Yunnan'}, + '31' : {'code':'ZH','name':'Zhejiang'} + }, + 'CC':{ + '1' : {'code':'D','name':'Direction Island'}, + '2' : {'code':'H','name':'Home Island'}, + '3' : {'code':'O','name':'Horsburgh Island'}, + '4' : {'code':'S','name':'South Island'}, + '5' : {'code':'W','name':'West Island'} + }, + 'CO':{ + '1' : {'code':'AMZ','name':'Amazonas'}, + '2' : {'code':'ANT','name':'Antioquia'}, + '3' : {'code':'ARA','name':'Arauca'}, + '4' : {'code':'ATL','name':'Atlantico'}, + '5' : {'code':'BDC','name':'Bogota D.C.'}, + '6' : {'code':'BOL','name':'Bolivar'}, + '7' : {'code':'BOY','name':'Boyaca'}, + '8' : {'code':'CAL','name':'Caldas'}, + '9' : {'code':'CAQ','name':'Caqueta'}, + '10' : {'code':'CAS','name':'Casanare'}, + '11' : {'code':'CAU','name':'Cauca'}, + '12' : {'code':'CES','name':'Cesar'}, + '13' : {'code':'CHO','name':'Choco'}, + '14' : {'code':'COR','name':'Cordoba'}, + '15' : {'code':'CAM','name':'Cundinamarca'}, + '16' : {'code':'GNA','name':'Guainia'}, + '17' : {'code':'GJR','name':'Guajira'}, + '18' : {'code':'GVR','name':'Guaviare'}, + '19' : {'code':'HUI','name':'Huila'}, + '20' : {'code':'MAG','name':'Magdalena'}, + '21' : {'code':'MET','name':'Meta'}, + '22' : {'code':'NAR','name':'Narino'}, + '23' : {'code':'NDS','name':'Norte de Santander'}, + '24' : {'code':'PUT','name':'Putumayo'}, + '25' : {'code':'QUI','name':'Quindio'}, + '26' : {'code':'RIS','name':'Risaralda'}, + '27' : {'code':'SAP','name':'San Andres y Providencia'}, + '28' : {'code':'SAN','name':'Santander'}, + '29' : {'code':'SUC','name':'Sucre'}, + '30' : {'code':'TOL','name':'Tolima'}, + '31' : {'code':'VDC','name':'Valle del Cauca'}, + '32' : {'code':'VAU','name':'Vaupes'}, + '33' : {'code':'VIC','name':'Vichada'} + }, + 'KM':{ + '1' : {'code':'G','name':'Grande Comore'}, + '2' : {'code':'A','name':'Anjouan'}, + '3' : {'code':'M','name':'Moheli'} + }, + 'CG':{ + '1' : {'code':'BO','name':'Bouenza'}, + '2' : {'code':'BR','name':'Brazzaville'}, + '3' : {'code':'CU','name':'Cuvette'}, + '4' : {'code':'CO','name':'Cuvette-Ouest'}, + '5' : {'code':'KO','name':'Kouilou'}, + '6' : {'code':'LE','name':'Lekoumou'}, + '7' : {'code':'LI','name':'Likouala'}, + '8' : {'code':'NI','name':'Niari'}, + '9' : {'code':'PL','name':'Plateaux'}, + '10' : {'code':'PO','name':'Pool'}, + '11' : {'code':'SA','name':'Sangha'} + }, + 'CK':{ + '1' : {'code':'AI','name':'Aitutaki'}, + '2' : {'code':'AT','name':'Atiu'}, + '3' : {'code':'MA','name':'Manuae'}, + '4' : {'code':'MG','name':'Mangaia'}, + '5' : {'code':'MK','name':'Manihiki'}, + '6' : {'code':'MT','name':'Mitiaro'}, + '7' : {'code':'MU','name':'Mauke'}, + '8' : {'code':'NI','name':'Nassau Island'}, + '9' : {'code':'PA','name':'Palmerston'}, + '10' : {'code':'PE','name':'Penrhyn'}, + '11' : {'code':'PU','name':'Pukapuka'}, + '12' : {'code':'RK','name':'Rakahanga'}, + '13' : {'code':'RR','name':'Rarotonga'}, + '14' : {'code':'SU','name':'Surwarrow'}, + '15' : {'code':'TA','name':'Takutea'} + }, + 'CR':{ + '1' : {'code':'AL','name':'Alajuela'}, + '2' : {'code':'CA','name':'Cartago'}, + '3' : {'code':'GU','name':'Guanacaste'}, + '4' : {'code':'HE','name':'Heredia'}, + '5' : {'code':'LI','name':'Limon'}, + '6' : {'code':'PU','name':'Puntarenas'}, + '7' : {'code':'SJ','name':'San Jose'} + }, + 'CI':{ + '1' : {'code':'ABE','name':'Abengourou'}, + '2' : {'code':'ABI','name':'Abidjan'}, + '3' : {'code':'ABO','name':'Aboisso'}, + '4' : {'code':'ADI','name':'Adiake'}, + '5' : {'code':'ADZ','name':'Adzope'}, + '6' : {'code':'AGB','name':'Agboville'}, + '7' : {'code':'AGN','name':'Agnibilekrou'}, + '8' : {'code':'ALE','name':'Alepe'}, + '9' : {'code':'BOC','name':'Bocanda'}, + '10' : {'code':'BAN','name':'Bangolo'}, + '11' : {'code':'BEO','name':'Beoumi'}, + '12' : {'code':'BIA','name':'Biankouma'}, + '13' : {'code':'BDK','name':'Bondoukou'}, + '14' : {'code':'BGN','name':'Bongouanou'}, + '15' : {'code':'BFL','name':'Bouafle'}, + '16' : {'code':'BKE','name':'Bouake'}, + '17' : {'code':'BNA','name':'Bouna'}, + '18' : {'code':'BDL','name':'Boundiali'}, + '19' : {'code':'DKL','name':'Dabakala'}, + '20' : {'code':'DBU','name':'Dabou'}, + '21' : {'code':'DAL','name':'Daloa'}, + '22' : {'code':'DAN','name':'Danane'}, + '23' : {'code':'DAO','name':'Daoukro'}, + '24' : {'code':'DIM','name':'Dimbokro'}, + '25' : {'code':'DIV','name':'Divo'}, + '26' : {'code':'DUE','name':'Duekoue'}, + '27' : {'code':'FER','name':'Ferkessedougou'}, + '28' : {'code':'GAG','name':'Gagnoa'}, + '29' : {'code':'GBA','name':'Grand-Bassam'}, + '30' : {'code':'GLA','name':'Grand-Lahou'}, + '31' : {'code':'GUI','name':'Guiglo'}, + '32' : {'code':'ISS','name':'Issia'}, + '33' : {'code':'JAC','name':'Jacqueville'}, + '34' : {'code':'KAT','name':'Katiola'}, + '35' : {'code':'KOR','name':'Korhogo'}, + '36' : {'code':'LAK','name':'Lakota'}, + '37' : {'code':'MAN','name':'Man'}, + '38' : {'code':'MKN','name':'Mankono'}, + '39' : {'code':'MBA','name':'Mbahiakro'}, + '40' : {'code':'ODI','name':'Odienne'}, + '41' : {'code':'OUM','name':'Oume'}, + '42' : {'code':'SAK','name':'Sakassou'}, + '43' : {'code':'SPE','name':'San-Pedro'}, + '44' : {'code':'SAS','name':'Sassandra'}, + '45' : {'code':'SEG','name':'Seguela'}, + '46' : {'code':'SIN','name':'Sinfra'}, + '47' : {'code':'SOU','name':'Soubre'}, + '48' : {'code':'TAB','name':'Tabou'}, + '49' : {'code':'TAN','name':'Tanda'}, + '50' : {'code':'TIE','name':'Tiebissou'}, + '51' : {'code':'TIN','name':'Tingrela'}, + '52' : {'code':'TIA','name':'Tiassale'}, + '53' : {'code':'TBA','name':'Touba'}, + '54' : {'code':'TLP','name':'Toulepleu'}, + '55' : {'code':'TMD','name':'Toumodi'}, + '56' : {'code':'VAV','name':'Vavoua'}, + '57' : {'code':'YAM','name':'Yamoussoukro'}, + '58' : {'code':'ZUE','name':'Zuenoula'} + }, + 'HR':{ + '1' : {'code':'BB','name':'Bjelovar-Bilogora'}, + '2' : {'code':'CZ','name':'City of Zagreb'}, + '3' : {'code':'DN','name':'Dubrovnik-Neretva'}, + '4' : {'code':'IS','name':'Istra'}, + '5' : {'code':'KA','name':'Karlovac'}, + '6' : {'code':'KK','name':'Koprivnica-Krizevci'}, + '7' : {'code':'KZ','name':'Krapina-Zagorje'}, + '8' : {'code':'LS','name':'Lika-Senj'}, + '9' : {'code':'ME','name':'Medimurje'}, + '10' : {'code':'OB','name':'Osijek-Baranja'}, + '11' : {'code':'PS','name':'Pozega-Slavonia'}, + '12' : {'code':'PG','name':'Primorje-Gorski Kotar'}, + '13' : {'code':'SI','name':'Sibenik'}, + '14' : {'code':'SM','name':'Sisak-Moslavina'}, + '15' : {'code':'SB','name':'Slavonski Brod-Posavina'}, + '16' : {'code':'SD','name':'Split-Dalmatia'}, + '17' : {'code':'VA','name':'Varazdin'}, + '18' : {'code':'VP','name':'Virovitica-Podravina'}, + '19' : {'code':'VS','name':'Vukovar-Srijem'}, + '20' : {'code':'ZK','name':'Zadar-Knin'}, + '21' : {'code':'ZA','name':'Zagreb'} + }, + 'CU':{ + '1' : {'code':'CA','name':'Camaguey'}, + '2' : {'code':'CD','name':'Ciego de Avila'}, + '3' : {'code':'CI','name':'Cienfuegos'}, + '4' : {'code':'CH','name':'Ciudad de La Habana'}, + '5' : {'code':'GR','name':'Granma'}, + '6' : {'code':'GU','name':'Guantanamo'}, + '7' : {'code':'HO','name':'Holguin'}, + '8' : {'code':'IJ','name':'Isla de la Juventud'}, + '9' : {'code':'LH','name':'La Habana'}, + '10' : {'code':'LT','name':'Las Tunas'}, + '11' : {'code':'MA','name':'Matanzas'}, + '12' : {'code':'PR','name':'Pinar del Rio'}, + '13' : {'code':'SS','name':'Sancti Spiritus'}, + '14' : {'code':'SC','name':'Santiago de Cuba'}, + '15' : {'code':'VC','name':'Villa Clara'} + }, + 'CY':{ + '1' : {'code':'F','name':'Famagusta'}, + '2' : {'code':'K','name':'Kyrenia'}, + '3' : {'code':'A','name':'Larnaca'}, + '4' : {'code':'I','name':'Limassol'}, + '5' : {'code':'N','name':'Nicosia'}, + '6' : {'code':'P','name':'Paphos'} + }, + 'CZ':{ + '1' : {'code':'A','name':'Hlavní město Praha'}, + '2' : {'code':'B','name':'Jihomoravský'}, + '3' : {'code':'C','name':'Jihočeský'}, + '4' : {'code':'E','name':'Pardubický'}, + '5' : {'code':'H','name':'Královéhradecký'}, + '6' : {'code':'J','name':'Vysočina'}, + '7' : {'code':'K','name':'Karlovarský'}, + '8' : {'code':'L','name':'Liberecký'}, + '9' : {'code':'M','name':'Olomoucký'}, + '10' : {'code':'P','name':'Plzeňský'}, + '11' : {'code':'S','name':'Středočeský'}, + '12' : {'code':'T','name':'Moravskoslezský'}, + '13' : {'code':'U','name':'Ústecký'}, + '14' : {'code':'Z','name':'Zlínský'} + }, + 'DK':{ + '1' : {'code':'AR','name':'Arhus'}, + '2' : {'code':'BH','name':'Bornholm'}, + '3' : {'code':'CO','name':'Copenhagen'}, + '4' : {'code':'FO','name':'Faroe Islands'}, + '5' : {'code':'FR','name':'Frederiksborg'}, + '6' : {'code':'FY','name':'Fyn'}, + '7' : {'code':'KO','name':'Kobenhavn'}, + '8' : {'code':'NO','name':'Nordjylland'}, + '9' : {'code':'RI','name':'Ribe'}, + '10' : {'code':'RK','name':'Ringkobing'}, + '11' : {'code':'RO','name':'Roskilde'}, + '12' : {'code':'SO','name':'Sonderjylland'}, + '13' : {'code':'ST','name':'Storstrom'}, + '14' : {'code':'VK','name':'Vejle'}, + '15' : {'code':'VJ','name':'Vestjælland'}, + '16' : {'code':'VB','name':'Viborg'} + }, + 'DJ':{ + '1' : {'code':'S','name':'\'Ali Sabih'}, + '2' : {'code':'K','name':'Dikhil'}, + '3' : {'code':'J','name':'Djibouti'}, + '4' : {'code':'O','name':'Obock'}, + '5' : {'code':'T','name':'Tadjoura'} + }, + 'DM':{ + '1' : {'code':'AND','name':'Saint Andrew Parish'}, + '2' : {'code':'DAV','name':'Saint David Parish'}, + '3' : {'code':'GEO','name':'Saint George Parish'}, + '4' : {'code':'JOH','name':'Saint John Parish'}, + '5' : {'code':'JOS','name':'Saint Joseph Parish'}, + '6' : {'code':'LUK','name':'Saint Luke Parish'}, + '7' : {'code':'MAR','name':'Saint Mark Parish'}, + '8' : {'code':'PAT','name':'Saint Patrick Parish'}, + '9' : {'code':'PAU','name':'Saint Paul Parish'}, + '10' : {'code':'PET','name':'Saint Peter Parish'} + }, + 'DO':{ + '1' : {'code':'DN','name':'Distrito Nacional'}, + '2' : {'code':'AZ','name':'Azua'}, + '3' : {'code':'BC','name':'Baoruco'}, + '4' : {'code':'BH','name':'Barahona'}, + '5' : {'code':'DJ','name':'Dajabon'}, + '6' : {'code':'DU','name':'Duarte'}, + '7' : {'code':'EL','name':'Elias Pina'}, + '8' : {'code':'SY','name':'El Seybo'}, + '9' : {'code':'ET','name':'Espaillat'}, + '10' : {'code':'HM','name':'Hato Mayor'}, + '11' : {'code':'IN','name':'Independencia'}, + '12' : {'code':'AL','name':'La Altagracia'}, + '13' : {'code':'RO','name':'La Romana'}, + '14' : {'code':'VE','name':'La Vega'}, + '15' : {'code':'MT','name':'Maria Trinidad Sanchez'}, + '16' : {'code':'MN','name':'Monsenor Nouel'}, + '17' : {'code':'MC','name':'Monte Cristi'}, + '18' : {'code':'MP','name':'Monte Plata'}, + '19' : {'code':'PD','name':'Pedernales'}, + '20' : {'code':'PR','name':'Peravia (Bani)'}, + '21' : {'code':'PP','name':'Puerto Plata'}, + '22' : {'code':'SL','name':'Salcedo'}, + '23' : {'code':'SM','name':'Samana'}, + '24' : {'code':'SH','name':'Sanchez Ramirez'}, + '25' : {'code':'SC','name':'San Cristobal'}, + '26' : {'code':'JO','name':'San Jose de Ocoa'}, + '27' : {'code':'SJ','name':'San Juan'}, + '28' : {'code':'PM','name':'San Pedro de Macoris'}, + '29' : {'code':'SA','name':'Santiago'}, + '30' : {'code':'ST','name':'Santiago Rodriguez'}, + '31' : {'code':'SD','name':'Santo Domingo'}, + '32' : {'code':'VA','name':'Valverde'} + }, + 'TP':{ + '1' : {'code':'AL','name':'Aileu'}, + '2' : {'code':'AN','name':'Ainaro'}, + '3' : {'code':'BA','name':'Baucau'}, + '4' : {'code':'BO','name':'Bobonaro'}, + '5' : {'code':'CO','name':'Cova Lima'}, + '6' : {'code':'DI','name':'Dili'}, + '7' : {'code':'ER','name':'Ermera'}, + '8' : {'code':'LA','name':'Lautem'}, + '9' : {'code':'LI','name':'Liquica'}, + '10' : {'code':'MT','name':'Manatuto'}, + '11' : {'code':'MF','name':'Manufahi'}, + '12' : {'code':'OE','name':'Oecussi'}, + '13' : {'code':'VI','name':'Viqueque'} + }, + 'EC':{ + '1' : {'code':'AZU','name':'Azuay'}, + '2' : {'code':'BOL','name':'Bolivar'}, + '3' : {'code':'CAN','name':'Cañar'}, + '4' : {'code':'CAR','name':'Carchi'}, + '5' : {'code':'CHI','name':'Chimborazo'}, + '6' : {'code':'COT','name':'Cotopaxi'}, + '7' : {'code':'EOR','name':'El Oro'}, + '8' : {'code':'ESM','name':'Esmeraldas'}, + '9' : {'code':'GPS','name':'Galápagos'}, + '10' : {'code':'GUA','name':'Guayas'}, + '11' : {'code':'IMB','name':'Imbabura'}, + '12' : {'code':'LOJ','name':'Loja'}, + '13' : {'code':'LRO','name':'Los Ríos'}, + '14' : {'code':'MAN','name':'Manabí'}, + '15' : {'code':'MSA','name':'Morona Santiago'}, + '16' : {'code':'NAP','name':'Napo'}, + '17' : {'code':'ORE','name':'Orellana'}, + '18' : {'code':'PAS','name':'Pastaza'}, + '19' : {'code':'PIC','name':'Pichincha'}, + '20' : {'code':'SUC','name':'Sucumbíos'}, + '21' : {'code':'TUN','name':'Tungurahua'}, + '22' : {'code':'ZCH','name':'Zamora Chinchipe'} + }, + 'EG':{ + '1' : {'code':'DHY','name':'Ad Daqahliyah'}, + '2' : {'code':'BAM','name':'Al Bahr al Ahmar'}, + '3' : {'code':'BHY','name':'Al Buhayrah'}, + '4' : {'code':'FYM','name':'Al Fayyum'}, + '5' : {'code':'GBY','name':'Al Gharbiyah'}, + '6' : {'code':'IDR','name':'Al Iskandariyah'}, + '7' : {'code':'IML','name':'Al Isma \'iliyah'}, + '8' : {'code':'JZH','name':'Al Jizah'}, + '9' : {'code':'MFY','name':'Al Minufiyah'}, + '10' : {'code':'MNY','name':'Al Minya'}, + '11' : {'code':'QHR','name':'Al Qahirah'}, + '12' : {'code':'QLY','name':'Al Qalyubiyah'}, + '13' : {'code':'WJD','name':'Al Wadi al Jadid'}, + '14' : {'code':'SHQ','name':'Ash Sharqiyah'}, + '15' : {'code':'SWY','name':'As Suways'}, + '16' : {'code':'ASW','name':'Aswan'}, + '17' : {'code':'ASY','name':'Asyut'}, + '18' : {'code':'BSW','name':'Bani Suwayf'}, + '19' : {'code':'BSD','name':'Bur Sa\'id'}, + '20' : {'code':'DMY','name':'Dumyat'}, + '21' : {'code':'JNS','name':'Janub Sina\''}, + '22' : {'code':'KSH','name':'Kafr ash Shaykh'}, + '23' : {'code':'MAT','name':'Matruh'}, + '24' : {'code':'QIN','name':'Qina'}, + '25' : {'code':'SHS','name':'Shamal Sina\''}, + '26' : {'code':'SUH','name':'Suhaj'} + }, + 'SV':{ + '1' : {'code':'AH','name':'Ahuachapan'}, + '2' : {'code':'CA','name':'Cabanas'}, + '3' : {'code':'CH','name':'Chalatenango'}, + '4' : {'code':'CU','name':'Cuscatlan'}, + '5' : {'code':'LB','name':'La Libertad'}, + '6' : {'code':'PZ','name':'La Paz'}, + '7' : {'code':'UN','name':'La Union'}, + '8' : {'code':'MO','name':'Morazan'}, + '9' : {'code':'SM','name':'San Miguel'}, + '10' : {'code':'SS','name':'San Salvador'}, + '11' : {'code':'SV','name':'San Vicente'}, + '12' : {'code':'SA','name':'Santa Ana'}, + '13' : {'code':'SO','name':'Sonsonate'}, + '14' : {'code':'US','name':'Usulutan'} + }, + 'GQ':{ + '1' : {'code':'AN','name':'Provincia Annobon'}, + '2' : {'code':'BN','name':'Provincia Bioko Norte'}, + '3' : {'code':'BS','name':'Provincia Bioko Sur'}, + '4' : {'code':'CS','name':'Provincia Centro Sur'}, + '5' : {'code':'KN','name':'Provincia Kie-Ntem'}, + '6' : {'code':'LI','name':'Provincia Litoral'}, + '7' : {'code':'WN','name':'Provincia Wele-Nzas'} + }, + 'ER':{ + '1' : {'code':'MA','name':'Central (Maekel)'}, + '2' : {'code':'KE','name':'Anseba (Keren)'}, + '3' : {'code':'DK','name':'Southern Red Sea (Debub-Keih-Bah)'}, + '4' : {'code':'SK','name':'Northern Red Sea (Semien-Keih-Ba)'}, + '5' : {'code':'DE','name':'Southern (Debub)'}, + '6' : {'code':'BR','name':'Gash-Barka (Barentu)'} + }, + 'EE':{ + '1' : {'code':'HA','name':'Harjumaa (Tallinn)'}, + '2' : {'code':'HI','name':'Hiiumaa (Kardla)'}, + '3' : {'code':'IV','name':'Ida-Virumaa (Johvi)'}, + '4' : {'code':'JA','name':'Jarvamaa (Paide)'}, + '5' : {'code':'JO','name':'Jogevamaa (Jogeva)'}, + '6' : {'code':'LV','name':'Laane-Virumaa (Rakvere)'}, + '7' : {'code':'LA','name':'Laanemaa (Haapsalu)'}, + '8' : {'code':'PA','name':'Parnumaa (Parnu)'}, + '9' : {'code':'PO','name':'Polvamaa (Polva)'}, + '10' : {'code':'RA','name':'Raplamaa (Rapla)'}, + '11' : {'code':'SA','name':'Saaremaa (Kuessaare)'}, + '12' : {'code':'TA','name':'Tartumaa (Tartu)'}, + '13' : {'code':'VA','name':'Valgamaa (Valga)'}, + '14' : {'code':'VI','name':'Viljandimaa (Viljandi)'}, + '15' : {'code':'VO','name':'Vorumaa (Voru)'} + }, + 'ET':{ + '1' : {'code':'AF','name':'Afar'}, + '2' : {'code':'AH','name':'Amhara'}, + '3' : {'code':'BG','name':'Benishangul-Gumaz'}, + '4' : {'code':'GB','name':'Gambela'}, + '5' : {'code':'HR','name':'Hariai'}, + '6' : {'code':'OR','name':'Oromia'}, + '7' : {'code':'SM','name':'Somali'}, + '8' : {'code':'SN','name':'Southern Nations - Nationalities'}, + '9' : {'code':'TG','name':'Tigray'}, + '10' : {'code':'AA','name':'Addis Ababa'}, + '11' : {'code':'DD','name':'Dire Dawa'} + }, + 'FO':{ + '1' : {'code':'TÛR','name':'Tûrshavnar Kommuna'}, + '2' : {'code':'KLA','name':'Klaksvík'}, + '3' : {'code':'RUN','name':'Runavík'}, + '4' : {'code':'TVØ','name':'Tvøroyri'}, + '5' : {'code':'FUG','name':'Fuglafjørður'}, + '6' : {'code':'SUN','name':'Sunda Kommuna'}, + '7' : {'code':'VáG','name':'Vágur'}, + '8' : {'code':'NES','name':'Nes'}, + '9' : {'code':'VES','name':'Vestmanna'}, + '10' : {'code':'MIð','name':'Miðvágur'}, + '11' : {'code':'SØR','name':'Sørvágur'}, + '12' : {'code':'GØT','name':'Gøtu Kommuna'}, + '13' : {'code':'SJû','name':'Sjûvar Kommuna'}, + '14' : {'code':'LEI','name':'Leirvík'}, + '15' : {'code':'SAN','name':'Sandavágur'}, + '16' : {'code':'HVA','name':'Hvalba'}, + '17' : {'code':'EIð','name':'Eiði'}, + '18' : {'code':'KVí','name':'Kvívík'}, + '19' : {'code':'SAN','name':'Sandur'}, + '20' : {'code':'SKO','name':'Skopun'}, + '21' : {'code':'HVA','name':'Hvannasund'}, + '22' : {'code':'SUM','name':'Sumba'}, + '23' : {'code':'VIð','name':'Viðareiði'}, + '24' : {'code':'POR','name':'Porkeri'}, + '25' : {'code':'SKá','name':'Skálavík'}, + '26' : {'code':'KUN','name':'Kunoy'}, + '27' : {'code':'HÚS','name':'HÚsavík'}, + '28' : {'code':'HOV','name':'Hov'}, + '29' : {'code':'FáM','name':'Fámjin'}, + '30' : {'code':'FUN','name':'Funningur'}, + '31' : {'code':'HÚS','name':'HÚsar'}, + '32' : {'code':'SKÚ','name':'SkÚvoy'}, + '33' : {'code':'SVí','name':'Svínoy'}, + '34' : {'code':'FUG','name':'Fugloy'} + }, + 'FJ':{ + '1' : {'code':'C','name':'Central Division'}, + '2' : {'code':'E','name':'Eastern Division'}, + '3' : {'code':'N','name':'Northern Division'}, + '4' : {'code':'R','name':'Rotuma'}, + '5' : {'code':'W','name':'Western Division'} + }, + 'FI':{ + '1' : {'code':'AL','name':'Ahvenanmaan Laani'}, + '2' : {'code':'ES','name':'Etela-Suomen Laani'}, + '3' : {'code':'IS','name':'Ita-Suomen Laani'}, + '4' : {'code':'LS','name':'Lansi-Suomen Laani'}, + '5' : {'code':'LA','name':'Lapin Lanani'}, + '6' : {'code':'OU','name':'Oulun Laani'} + }, + 'FR':{ + '1' : {'code':'AL','name':'Alsace'}, + '2' : {'code':'AQ','name':'Aquitaine'}, + '3' : {'code':'AU','name':'Auvergne'}, + '4' : {'code':'BR','name':'Brittany'}, + '5' : {'code':'BU','name':'Burgundy'}, + '6' : {'code':'CE','name':'Center Loire Valley'}, + '7' : {'code':'CH','name':'Champagne'}, + '8' : {'code':'CO','name':'Corse'}, + '9' : {'code':'FR','name':'France Comte'}, + '10' : {'code':'LA','name':'Languedoc Roussillon'}, + '11' : {'code':'LI','name':'Limousin'}, + '12' : {'code':'LO','name':'Lorraine'}, + '13' : {'code':'MI','name':'Midi Pyrenees'}, + '14' : {'code':'NO','name':'Nord Pas de Calais'}, + '15' : {'code':'NR','name':'Normandy'}, + '16' : {'code':'PA','name':'Paris / Ile de France'}, + '17' : {'code':'PI','name':'Picardie'}, + '18' : {'code':'PO','name':'Poitou Charente'}, + '19' : {'code':'PR','name':'Provence'}, + '20' : {'code':'RH','name':'Rhone Alps'}, + '21' : {'code':'RI','name':'Riviera'}, + '22' : {'code':'WE','name':'Western Loire Valley'} + }, + 'FX':{ + '1' : {'code':'Et','name':'Etranger'}, + '2' : {'code':'01','name':'Ain'}, + '3' : {'code':'02','name':'Aisne'}, + '4' : {'code':'03','name':'Allier'}, + '5' : {'code':'04','name':'Alpes de Haute Provence'}, + '6' : {'code':'05','name':'Hautes-Alpes'}, + '7' : {'code':'06','name':'Alpes Maritimes'}, + '8' : {'code':'07','name':'Ardèche'}, + '9' : {'code':'08','name':'Ardennes'}, + '10' : {'code':'09','name':'Ariège'}, + '11' : {'code':'10','name':'Aube'}, + '12' : {'code':'11','name':'Aude'}, + '13' : {'code':'12','name':'Aveyron'}, + '14' : {'code':'13','name':'Bouches du Rhône'}, + '15' : {'code':'14','name':'Calvados'}, + '16' : {'code':'15','name':'Cantal'}, + '17' : {'code':'16','name':'Charente'}, + '18' : {'code':'17','name':'Charente Maritime'}, + '19' : {'code':'18','name':'Cher'}, + '20' : {'code':'19','name':'Corrèze'}, + '21' : {'code':'2A','name':'Corse du Sud'}, + '22' : {'code':'2B','name':'Haute Corse'}, + '23' : {'code':'21','name':'Côte d\'or'}, + '24' : {'code':'22','name':'Côtes d\'Armor'}, + '25' : {'code':'23','name':'Creuse'}, + '26' : {'code':'24','name':'Dordogne'}, + '27' : {'code':'25','name':'Doubs'}, + '28' : {'code':'26','name':'Drôme'}, + '29' : {'code':'27','name':'Eure'}, + '30' : {'code':'28','name':'Eure et Loir'}, + '31' : {'code':'29','name':'Finistère'}, + '32' : {'code':'30','name':'Gard'}, + '33' : {'code':'31','name':'Haute Garonne'}, + '34' : {'code':'32','name':'Gers'}, + '35' : {'code':'33','name':'Gironde'}, + '36' : {'code':'34','name':'Hérault'}, + '37' : {'code':'35','name':'Ille et Vilaine'}, + '38' : {'code':'36','name':'Indre'}, + '39' : {'code':'37','name':'Indre et Loire'}, + '40' : {'code':'38','name':'Isére'}, + '41' : {'code':'39','name':'Jura'}, + '42' : {'code':'40','name':'Landes'}, + '43' : {'code':'41','name':'Loir et Cher'}, + '44' : {'code':'42','name':'Loire'}, + '45' : {'code':'43','name':'Haute Loire'}, + '46' : {'code':'44','name':'Loire Atlantique'}, + '47' : {'code':'45','name':'Loiret'}, + '48' : {'code':'46','name':'Lot'}, + '49' : {'code':'47','name':'Lot et Garonne'}, + '50' : {'code':'48','name':'Lozère'}, + '51' : {'code':'49','name':'Maine et Loire'}, + '52' : {'code':'50','name':'Manche'}, + '53' : {'code':'51','name':'Marne'}, + '54' : {'code':'52','name':'Haute Marne'}, + '55' : {'code':'53','name':'Mayenne'}, + '56' : {'code':'54','name':'Meurthe et Moselle'}, + '57' : {'code':'55','name':'Meuse'}, + '58' : {'code':'56','name':'Morbihan'}, + '59' : {'code':'57','name':'Moselle'}, + '60' : {'code':'58','name':'Nièvre'}, + '61' : {'code':'59','name':'Nord'}, + '62' : {'code':'60','name':'Oise'}, + '63' : {'code':'61','name':'Orne'}, + '64' : {'code':'62','name':'Pas de Calais'}, + '65' : {'code':'63','name':'Puy de Dôme'}, + '66' : {'code':'64','name':'Pyrenees Atlantique'}, + '67' : {'code':'65','name':'Hautes Pyrenees'}, + '68' : {'code':'66','name':'Pyrenees Orientale'}, + '69' : {'code':'67','name':'Bas Rhin'}, + '70' : {'code':'68','name':'Haut Rhin'}, + '71' : {'code':'69','name':'Rhône'}, + '72' : {'code':'70','name':'Haute Saône'}, + '73' : {'code':'71','name':'Saône et Loire'}, + '74' : {'code':'72','name':'Sarthe'}, + '75' : {'code':'73','name':'Savoie'}, + '76' : {'code':'74','name':'Haute Savoie'}, + '77' : {'code':'75','name':'Paris'}, + '78' : {'code':'76','name':'Seine Martitime'}, + '79' : {'code':'77','name':'Seine et Marne'}, + '80' : {'code':'78','name':'Yvelines'}, + '81' : {'code':'79','name':'Deux Sèvres'}, + '82' : {'code':'80','name':'Somme'}, + '83' : {'code':'81','name':'Tarn'}, + '84' : {'code':'82','name':'Tarn et Garonne'}, + '85' : {'code':'83','name':'Var'}, + '86' : {'code':'84','name':'Vaucluse'}, + '87' : {'code':'85','name':'Vendée'}, + '88' : {'code':'86','name':'Vienne'}, + '89' : {'code':'87','name':'Haute Vienne'}, + '90' : {'code':'88','name':'Vosges'}, + '91' : {'code':'89','name':'Yonne'}, + '92' : {'code':'90','name':'Territoire de Belfort'}, + '93' : {'code':'91','name':'Essonne'}, + '94' : {'code':'92','name':'Hauts de Seine'}, + '95' : {'code':'93','name':'Seine St-Denis'}, + '96' : {'code':'94','name':'Val de Marne'}, + '97' : {'code':'95','name':'Val d\'oise'} + }, + 'GF':{ + '1' : {'code':'AWA','name':'Awala-Yalimapo'}, + '2' : {'code':'MAN','name':'Mana'}, + '3' : {'code':'SAI','name':'Saint-Laurent-Du-Maroni'}, + '4' : {'code':'APA','name':'Apatou'}, + '5' : {'code':'GRA','name':'Grand-Santi'}, + '6' : {'code':'PAP','name':'Papaïchton'}, + '7' : {'code':'SAÜ','name':'SaÜl'}, + '8' : {'code':'MAR','name':'Maripasoula'}, + '9' : {'code':'CAM','name':'Camopi'}, + '10' : {'code':'SAI','name':'Saint-Georges'}, + '11' : {'code':'OUA','name':'Ouanary'}, + '12' : {'code':'RéG','name':'Régina'}, + '13' : {'code':'ROU','name':'Roura'}, + '14' : {'code':'SAI','name':'Saint-élie'}, + '15' : {'code':'IRA','name':'Iracoubo'}, + '16' : {'code':'SIN','name':'Sinnamary'}, + '17' : {'code':'KOU','name':'Kourou'}, + '18' : {'code':'MAC','name':'Macouria'}, + '19' : {'code':'MON','name':'Montsinéry-Tonnegrande'}, + '20' : {'code':'MAT','name':'Matoury'}, + '21' : {'code':'CAY','name':'Cayenne'}, + '22' : {'code':'REM','name':'Remire-Montjoly'} + }, + 'PF':{ + '1' : {'code':'M','name':'Archipel des Marquises'}, + '2' : {'code':'T','name':'Archipel des Tuamotu'}, + '3' : {'code':'I','name':'Archipel des Tubuai'}, + '4' : {'code':'V','name':'Iles du Vent'}, + '5' : {'code':'S','name':'Iles Sous-le-Vent'} + }, + 'TF':{ + '1' : {'code':'C','name':'Iles Crozet'}, + '2' : {'code':'K','name':'Iles Kerguelen'}, + '3' : {'code':'A','name':'Ile Amsterdam'}, + '4' : {'code':'P','name':'Ile Saint-Paul'}, + '5' : {'code':'D','name':'Adelie Land'} + }, + 'GA':{ + '1' : {'code':'ES','name':'Estuaire'}, + '2' : {'code':'HO','name':'Haut-Ogooue'}, + '3' : {'code':'MO','name':'Moyen-Ogooue'}, + '4' : {'code':'NG','name':'Ngounie'}, + '5' : {'code':'NY','name':'Nyanga'}, + '6' : {'code':'OI','name':'Ogooue-Ivindo'}, + '7' : {'code':'OL','name':'Ogooue-Lolo'}, + '8' : {'code':'OM','name':'Ogooue-Maritime'}, + '9' : {'code':'WN','name':'Woleu-Ntem'} + }, + 'GM':{ + '1' : {'code':'BJ','name':'Banjul'}, + '2' : {'code':'BS','name':'Basse'}, + '3' : {'code':'BR','name':'Brikama'}, + '4' : {'code':'JA','name':'Janjangbure'}, + '5' : {'code':'KA','name':'Kanifeng'}, + '6' : {'code':'KE','name':'Kerewan'}, + '7' : {'code':'KU','name':'Kuntaur'}, + '8' : {'code':'MA','name':'Mansakonko'}, + '9' : {'code':'LR','name':'Lower River'}, + '10' : {'code':'CR','name':'Central River'}, + '11' : {'code':'NB','name':'North Bank'}, + '12' : {'code':'UR','name':'Upper River'}, + '13' : {'code':'WE','name':'Western'} + }, + 'GE':{ + '1' : {'code':'AB','name':'Abkhazia'}, + '2' : {'code':'AJ','name':'Ajaria'}, + '3' : {'code':'GU','name':'Guria'}, + '4' : {'code':'IM','name':'Imereti'}, + '5' : {'code':'KA','name':'Kakheti'}, + '6' : {'code':'KK','name':'Kvemo Kartli'}, + '7' : {'code':'MM','name':'Mtskheta-Mtianeti'}, + '8' : {'code':'RL','name':'Racha Lechkhumi and Kvemo Svanet'}, + '9' : {'code':'SJ','name':'Samtskhe-Javakheti'}, + '10' : {'code':'SK','name':'Shida Kartli'}, + '11' : {'code':'SZ','name':'Samegrelo-Zemo Svaneti'}, + '12' : {'code':'TB','name':'Tbilisi'} + }, + 'DE':{ + '1' : {'code':'BAW','name':'Baden-Württemberg'}, + '2' : {'code':'BAY','name':'Bayern'}, + '3' : {'code':'BER','name':'Berlin'}, + '4' : {'code':'BRG','name':'Brandenburg'}, + '5' : {'code':'BRE','name':'Bremen'}, + '6' : {'code':'HAM','name':'Hamburg'}, + '7' : {'code':'HES','name':'Hessen'}, + '8' : {'code':'MEC','name':'Mecklenburg-Vorpommern'}, + '9' : {'code':'NDS','name':'Niedersachsen'}, + '10' : {'code':'NRW','name':'Nordrhein-Westfalen'}, + '11' : {'code':'RHE','name':'Rheinland-Pfalz'}, + '12' : {'code':'SAR','name':'Saarland'}, + '13' : {'code':'SAS','name':'Sachsen'}, + '14' : {'code':'SAC','name':'Sachsen-Anhalt'}, + '15' : {'code':'SCN','name':'Schleswig-Holstein'}, + '16' : {'code':'THE','name':'Thüringen'} + }, + 'GH':{ + '1' : {'code':'AS','name':'Ashanti Region'}, + '2' : {'code':'BA','name':'Brong-Ahafo Region'}, + '3' : {'code':'CE','name':'Central Region'}, + '4' : {'code':'EA','name':'Eastern Region'}, + '5' : {'code':'GA','name':'Greater Accra Region'}, + '6' : {'code':'NO','name':'Northern Region'}, + '7' : {'code':'UE','name':'Upper East Region'}, + '8' : {'code':'UW','name':'Upper West Region'}, + '9' : {'code':'VO','name':'Volta Region'}, + '10' : {'code':'WE','name':'Western Region'} + }, + 'GI':{ + '1' : {'code':'EAS','name':'East Side'}, + '2' : {'code':'NOR','name':'North District'}, + '3' : {'code':'REC','name':'Reclamation Areas'}, + '4' : {'code':'SAN','name':'Sandpits Area'}, + '5' : {'code':'SOU','name':'South District'}, + '6' : {'code':'TOW','name':'Town Area'}, + '7' : {'code':'UPP','name':'Upper Town'}, + '8' : {'code':'OTH','name':'Other'} + }, + 'GR':{ + '1' : {'code':'AT','name':'Attica'}, + '2' : {'code':'CN','name':'Central Greece'}, + '3' : {'code':'CM','name':'Central Macedonia'}, + '4' : {'code':'CR','name':'Crete'}, + '5' : {'code':'EM','name':'East Macedonia and Thrace'}, + '6' : {'code':'EP','name':'Epirus'}, + '7' : {'code':'II','name':'Ionian Islands'}, + '8' : {'code':'NA','name':'North Aegean'}, + '9' : {'code':'PP','name':'Peloponnesos'}, + '10' : {'code':'SA','name':'South Aegean'}, + '11' : {'code':'TH','name':'Thessaly'}, + '12' : {'code':'WG','name':'West Greece'}, + '13' : {'code':'WM','name':'West Macedonia'} + }, + 'GL':{ + '1' : {'code':'A','name':'Avannaa'}, + '2' : {'code':'T','name':'Tunu'}, + '3' : {'code':'K','name':'Kitaa'} + }, + '86':{ + '1' : {'code':'A','name':'Saint Andrew'}, + '2' : {'code':'D','name':'Saint David'}, + '3' : {'code':'G','name':'Saint George'}, + '4' : {'code':'J','name':'Saint John'}, + '5' : {'code':'M','name':'Saint Mark'}, + '6' : {'code':'P','name':'Saint Patrick'}, + '7' : {'code':'C','name':'Carriacou'}, + '8' : {'code':'Q','name':'Petit Martinique'} + }, + 'GP':{ + '1' : {'code':'ARR','name':'Arrondissements Of The Guadeloup'}, + '2' : {'code':'CAN','name':'Cantons Of The Guadeloup Depart'}, + '3' : {'code':'COM','name':'Communes Of The Guadeloup Depart'} + }, + 'GU':{ + '1' : {'code':'AGA','name':'Agana Heights'}, + '2' : {'code':'AGA','name':'Agat'}, + '3' : {'code':'ASA','name':'Asan Maina'}, + '4' : {'code':'BAR','name':'Barrigada'}, + '5' : {'code':'CHA','name':'Chalan Pago Ordot'}, + '6' : {'code':'DED','name':'Dededo'}, + '7' : {'code':'HAG','name':'HagÅtña'}, + '8' : {'code':'INA','name':'Inarajan'}, + '9' : {'code':'MAN','name':'Mangilao'}, + '10' : {'code':'MER','name':'Merizo'}, + '11' : {'code':'MON','name':'Mongmong Toto Maite'}, + '12' : {'code':'PIT','name':'Piti'}, + '13' : {'code':'SAN','name':'Santa Rita'}, + '14' : {'code':'SIN','name':'Sinajana'}, + '15' : {'code':'TAL','name':'Talofofo'}, + '16' : {'code':'TAM','name':'Tamuning'}, + '17' : {'code':'UMA','name':'Umatac'}, + '18' : {'code':'YIG','name':'Yigo'}, + '19' : {'code':'YON','name':'Yona'} + }, + 'GT':{ + '1' : {'code':'AV','name':'Alta Verapaz'}, + '2' : {'code':'BV','name':'Baja Verapaz'}, + '3' : {'code':'CM','name':'Chimaltenango'}, + '4' : {'code':'CQ','name':'Chiquimula'}, + '5' : {'code':'PE','name':'El Peten'}, + '6' : {'code':'PR','name':'El Progreso'}, + '7' : {'code':'QC','name':'El Quiche'}, + '8' : {'code':'ES','name':'Escuintla'}, + '9' : {'code':'GU','name':'Guatemala'}, + '10' : {'code':'HU','name':'Huehuetenango'}, + '11' : {'code':'IZ','name':'Izabal'}, + '12' : {'code':'JA','name':'Jalapa'}, + '13' : {'code':'JU','name':'Jutiapa'}, + '14' : {'code':'QZ','name':'Quetzaltenango'}, + '15' : {'code':'RE','name':'Retalhuleu'}, + '16' : {'code':'ST','name':'Sacatepequez'}, + '17' : {'code':'SM','name':'San Marcos'}, + '18' : {'code':'SR','name':'Santa Rosa'}, + '19' : {'code':'SO','name':'Solola'}, + '20' : {'code':'SU','name':'Suchitepequez'}, + '21' : {'code':'TO','name':'Totonicapan'}, + '22' : {'code':'ZA','name':'Zacapa'} + }, + 'GN':{ + '1' : {'code':'CNK','name':'Conakry'}, + '2' : {'code':'BYL','name':'Beyla'}, + '3' : {'code':'BFA','name':'Boffa'}, + '4' : {'code':'BOK','name':'Boke'}, + '5' : {'code':'COY','name':'Coyah'}, + '6' : {'code':'DBL','name':'Dabola'}, + '7' : {'code':'DLB','name':'Dalaba'}, + '8' : {'code':'DGR','name':'Dinguiraye'}, + '9' : {'code':'DBR','name':'Dubreka'}, + '10' : {'code':'FRN','name':'Faranah'}, + '11' : {'code':'FRC','name':'Forecariah'}, + '12' : {'code':'FRI','name':'Fria'}, + '13' : {'code':'GAO','name':'Gaoual'}, + '14' : {'code':'GCD','name':'Gueckedou'}, + '15' : {'code':'KNK','name':'Kankan'}, + '16' : {'code':'KRN','name':'Kerouane'}, + '17' : {'code':'KND','name':'Kindia'}, + '18' : {'code':'KSD','name':'Kissidougou'}, + '19' : {'code':'KBA','name':'Koubia'}, + '20' : {'code':'KDA','name':'Koundara'}, + '21' : {'code':'KRA','name':'Kouroussa'}, + '22' : {'code':'LAB','name':'Labe'}, + '23' : {'code':'LLM','name':'Lelouma'}, + '24' : {'code':'LOL','name':'Lola'}, + '25' : {'code':'MCT','name':'Macenta'}, + '26' : {'code':'MAL','name':'Mali'}, + '27' : {'code':'MAM','name':'Mamou'}, + '28' : {'code':'MAN','name':'Mandiana'}, + '29' : {'code':'NZR','name':'Nzerekore'}, + '30' : {'code':'PIT','name':'Pita'}, + '31' : {'code':'SIG','name':'Siguiri'}, + '32' : {'code':'TLM','name':'Telimele'}, + '33' : {'code':'TOG','name':'Tougue'}, + '34' : {'code':'YOM','name':'Yomou'} + }, + 'GW':{ + '1' : {'code':'BF','name':'Bafata Region'}, + '2' : {'code':'BB','name':'Biombo Region'}, + '3' : {'code':'BS','name':'Bissau Region'}, + '4' : {'code':'BL','name':'Bolama Region'}, + '5' : {'code':'CA','name':'Cacheu Region'}, + '6' : {'code':'GA','name':'Gabu Region'}, + '7' : {'code':'OI','name':'Oio Region'}, + '8' : {'code':'QU','name':'Quinara Region'}, + '9' : {'code':'TO','name':'Tombali Region'} + }, + 'GY':{ + '1' : {'code':'BW','name':'Barima-Waini'}, + '2' : {'code':'CM','name':'Cuyuni-Mazaruni'}, + '3' : {'code':'DM','name':'Demerara-Mahaica'}, + '4' : {'code':'EC','name':'East Berbice-Corentyne'}, + '5' : {'code':'EW','name':'Essequibo Islands-West Demerara'}, + '6' : {'code':'MB','name':'Mahaica-Berbice'}, + '7' : {'code':'PM','name':'Pomeroon-Supenaam'}, + '8' : {'code':'PI','name':'Potaro-Siparuni'}, + '9' : {'code':'UD','name':'Upper Demerara-Berbice'}, + '10' : {'code':'UT','name':'Upper Takutu-Upper Essequibo'} + }, + 'HT':{ + '1' : {'code':'AR','name':'Artibonite'}, + '2' : {'code':'CE','name':'Centre'}, + '3' : {'code':'GA','name':'Grand\'Anse'}, + '4' : {'code':'ND','name':'Nord'}, + '5' : {'code':'NE','name':'Nord-Est'}, + '6' : {'code':'NO','name':'Nord-Ouest'}, + '7' : {'code':'OU','name':'Ouest'}, + '8' : {'code':'SD','name':'Sud'}, + '9' : {'code':'SE','name':'Sud-Est'} + }, + 'HM':{ + '1' : {'code':'F','name':'Flat Island'}, + '2' : {'code':'M','name':'McDonald Island'}, + '3' : {'code':'S','name':'Shag Island'}, + '4' : {'code':'H','name':'Heard Island'} + }, + 'HN':{ + '1' : {'code':'AT','name':'Atlantida'}, + '2' : {'code':'CH','name':'Choluteca'}, + '3' : {'code':'CL','name':'Colon'}, + '4' : {'code':'CM','name':'Comayagua'}, + '5' : {'code':'CP','name':'Copan'}, + '6' : {'code':'CR','name':'Cortes'}, + '7' : {'code':'PA','name':'El Paraiso'}, + '8' : {'code':'FM','name':'Francisco Morazan'}, + '9' : {'code':'GD','name':'Gracias a Dios'}, + '10' : {'code':'IN','name':'Intibuca'}, + '11' : {'code':'IB','name':'Islas de la Bahia (Bay Islands)'}, + '12' : {'code':'PZ','name':'La Paz'}, + '13' : {'code':'LE','name':'Lempira'}, + '14' : {'code':'OC','name':'Ocotepeque'}, + '15' : {'code':'OL','name':'Olancho'}, + '16' : {'code':'SB','name':'Santa Barbara'}, + '17' : {'code':'VA','name':'Valle'}, + '18' : {'code':'YO','name':'Yoro'} + }, + 'HK':{ + '1' : {'code':'HCW','name':'Central and Western Hong Kong Is'}, + '2' : {'code':'HEA','name':'Eastern Hong Kong Island'}, + '3' : {'code':'HSO','name':'Southern Hong Kong Island'}, + '4' : {'code':'HWC','name':'Wan Chai Hong Kong Island'}, + '5' : {'code':'KKC','name':'Kowloon City Kowloon'}, + '6' : {'code':'KKT','name':'Kwun Tong Kowloon'}, + '7' : {'code':'KSS','name':'Sham Shui Po Kowloon'}, + '8' : {'code':'KWT','name':'Wong Tai Sin Kowloon'}, + '9' : {'code':'KYT','name':'Yau Tsim Mong Kowloon'}, + '10' : {'code':'NIS','name':'Islands New Territories'}, + '11' : {'code':'NKT','name':'Kwai Tsing New Territories'}, + '12' : {'code':'NNO','name':'North New Territories'}, + '13' : {'code':'NSK','name':'Sai Kung New Territories'}, + '14' : {'code':'NST','name':'Sha Tin New Territories'}, + '15' : {'code':'NTP','name':'Tai Po New Territories'}, + '16' : {'code':'NTW','name':'Tsuen Wan New Territories'}, + '17' : {'code':'NTM','name':'Tuen Mun New Territories'}, + '18' : {'code':'NYL','name':'Yuen Long New Territories'} + }, + 'HU':{ + '1' : {'code':'BK','name':'Bacs-Kiskun'}, + '2' : {'code':'BA','name':'Baranya'}, + '3' : {'code':'BE','name':'Bekes'}, + '4' : {'code':'BS','name':'Bekescsaba'}, + '5' : {'code':'BZ','name':'Borsod-Abauj-Zemplen'}, + '6' : {'code':'BU','name':'Budapest'}, + '7' : {'code':'CS','name':'Csongrad'}, + '8' : {'code':'DE','name':'Debrecen'}, + '9' : {'code':'DU','name':'Dunaujvaros'}, + '10' : {'code':'EG','name':'Eger'}, + '11' : {'code':'FE','name':'Fejer'}, + '12' : {'code':'GY','name':'Gyor'}, + '13' : {'code':'GM','name':'Gyor-Moson-Sopron'}, + '14' : {'code':'HB','name':'Hajdu-Bihar'}, + '15' : {'code':'HE','name':'Heves'}, + '16' : {'code':'HO','name':'Hodmezovasarhely'}, + '17' : {'code':'JN','name':'Jasz-Nagykun-Szolnok'}, + '18' : {'code':'KA','name':'Kaposvar'}, + '19' : {'code':'KE','name':'Kecskemet'}, + '20' : {'code':'KO','name':'Komarom-Esztergom'}, + '21' : {'code':'MI','name':'Miskolc'}, + '22' : {'code':'NA','name':'Nagykanizsa'}, + '23' : {'code':'NO','name':'Nograd'}, + '24' : {'code':'NY','name':'Nyiregyhaza'}, + '25' : {'code':'PE','name':'Pecs'}, + '26' : {'code':'PS','name':'Pest'}, + '27' : {'code':'SO','name':'Somogy'}, + '28' : {'code':'SP','name':'Sopron'}, + '29' : {'code':'SS','name':'Szabolcs-Szatmar-Bereg'}, + '30' : {'code':'SZ','name':'Szeged'}, + '31' : {'code':'SE','name':'Szekesfehervar'}, + '32' : {'code':'SL','name':'Szolnok'}, + '33' : {'code':'SM','name':'Szombathely'}, + '34' : {'code':'TA','name':'Tatabanya'}, + '35' : {'code':'TO','name':'Tolna'}, + '36' : {'code':'VA','name':'Vas'}, + '37' : {'code':'VE','name':'Veszprem'}, + '38' : {'code':'ZA','name':'Zala'}, + '39' : {'code':'ZZ','name':'Zalaegerszeg'} + }, + 'IS':{ + '1' : {'code':'AL','name':'Austurland'}, + '2' : {'code':'HF','name':'Hofuoborgarsvaeoi'}, + '3' : {'code':'NE','name':'Norourland eystra'}, + '4' : {'code':'NV','name':'Norourland vestra'}, + '5' : {'code':'SL','name':'Suourland'}, + '6' : {'code':'SN','name':'Suournes'}, + '7' : {'code':'VF','name':'Vestfiroir'}, + '8' : {'code':'VL','name':'Vesturland'} + }, + 'IN':{ + '1' : {'code':'AN','name':'Andaman and Nicobar Islands'}, + '2' : {'code':'AP','name':'Andhra Pradesh'}, + '3' : {'code':'AR','name':'Arunachal Pradesh'}, + '4' : {'code':'AS','name':'Assam'}, + '5' : {'code':'BI','name':'Bihar'}, + '6' : {'code':'CH','name':'Chandigarh'}, + '7' : {'code':'DA','name':'Dadra and Nagar Haveli'}, + '8' : {'code':'DM','name':'Daman and Diu'}, + '9' : {'code':'DE','name':'Delhi'}, + '10' : {'code':'GO','name':'Goa'}, + '11' : {'code':'GU','name':'Gujarat'}, + '12' : {'code':'HA','name':'Haryana'}, + '13' : {'code':'HP','name':'Himachal Pradesh'}, + '14' : {'code':'JA','name':'Jammu and Kashmir'}, + '15' : {'code':'KA','name':'Karnataka'}, + '16' : {'code':'KE','name':'Kerala'}, + '17' : {'code':'LI','name':'Lakshadweep Islands'}, + '18' : {'code':'MP','name':'Madhya Pradesh'}, + '19' : {'code':'MA','name':'Maharashtra'}, + '20' : {'code':'MN','name':'Manipur'}, + '21' : {'code':'ME','name':'Meghalaya'}, + '22' : {'code':'MI','name':'Mizoram'}, + '23' : {'code':'NA','name':'Nagaland'}, + '24' : {'code':'OR','name':'Orissa'}, + '25' : {'code':'PO','name':'Pondicherry'}, + '26' : {'code':'PU','name':'Punjab'}, + '27' : {'code':'RA','name':'Rajasthan'}, + '28' : {'code':'SI','name':'Sikkim'}, + '29' : {'code':'TN','name':'Tamil Nadu'}, + '30' : {'code':'TR','name':'Tripura'}, + '31' : {'code':'UP','name':'Uttar Pradesh'}, + '32' : {'code':'WB','name':'West Bengal'} + }, + 'ID':{ + '1' : {'code':'DA','name':'Daista Aceh'}, + '2' : {'code':'SU','name':'Sumatera Utara'}, + '3' : {'code':'SB','name':'Sumatera Barat'}, + '4' : {'code':'SI','name':'Riau'}, + '5' : {'code':'JA','name':'Jambi'}, + '6' : {'code':'SS','name':'Sumatera Selatan'}, + '7' : {'code':'BE','name':'Bengkulu'}, + '8' : {'code':'LA','name':'Lampung'}, + '9' : {'code':'JK','name':'Dki Jakarta'}, + '10' : {'code':'JB','name':'Jawa Barat'}, + '11' : {'code':'JT','name':'Jawa Tengah'}, + '12' : {'code':'DY','name':'Daista Yogyakarta'}, + '13' : {'code':'JT','name':'Jawa Timur'}, + '14' : {'code':'KB','name':'Kalimantan Barat'}, + '15' : {'code':'KT','name':'Kalimantan Tengah'}, + '16' : {'code':'KI','name':'Kalimantan Timur'}, + '17' : {'code':'KS','name':'Kalimantan Selatan'}, + '18' : {'code':'BA','name':'Bali'}, + '19' : {'code':'NB','name':'Nusa Tenggara Barat'}, + '20' : {'code':'NT','name':'Nusa Tenggara Timur'}, + '21' : {'code':'SN','name':'Sulawesi Selatan'}, + '22' : {'code':'ST','name':'Sulawesi Tengah'}, + '23' : {'code':'SA','name':'Sulawesi Utara'}, + '24' : {'code':'SG','name':'Sulawesi Tenggara'}, + '25' : {'code':'MA','name':'Maluku'}, + '26' : {'code':'MU','name':'Maluku Utara'}, + '27' : {'code':'IJ','name':'Irian Jaya Timur'}, + '28' : {'code':'IT','name':'Irian Jaya Tengah'}, + '29' : {'code':'IB','name':'Irian Jawa Barat'}, + '30' : {'code':'BT','name':'Banten'}, + '31' : {'code':'BB','name':'Bangka Belitung'}, + '32' : {'code':'GO','name':'Gorontalo'} + }, + 'IR':{ + '1' : {'code':'ARD','name':'Ardabil'}, + '2' : {'code':'BSH','name':'Bushehr'}, + '3' : {'code':'CMB','name':'Chahar Mahaal and Bakhtiari'}, + '4' : {'code':'EAZ','name':'East Azarbaijan'}, + '5' : {'code':'EFH','name':'Esfahan'}, + '6' : {'code':'FAR','name':'Fars'}, + '7' : {'code':'GIL','name':'Gilan'}, + '8' : {'code':'GLS','name':'Golestan'}, + '9' : {'code':'HMD','name':'Hamadan'}, + '10' : {'code':'HRM','name':'Hormozgan'}, + '11' : {'code':'ILM','name':'Ilam'}, + '12' : {'code':'KBA','name':'Kohkiluyeh and Buyer Ahmad'}, + '13' : {'code':'KRB','name':'Kerman'}, + '14' : {'code':'KRD','name':'Kurdistan'}, + '15' : {'code':'KRM','name':'Kermanshah'}, + '16' : {'code':'KZT','name':'Khuzestan'}, + '17' : {'code':'LRS','name':'Lorestan'}, + '18' : {'code':'MKZ','name':'Markazi'}, + '19' : {'code':'MZD','name':'Mazandaran'}, + '20' : {'code':'NKH','name':'North Khorasan'}, + '21' : {'code':'QAZ','name':'Qazvin'}, + '22' : {'code':'QOM','name':'Qom'}, + '23' : {'code':'RKH','name':'Razavi Khorasan'}, + '24' : {'code':'SBL','name':'Sistan and Baluchistan'}, + '25' : {'code':'SKH','name':'South Khorasan'}, + '26' : {'code':'SMN','name':'Semnan'}, + '27' : {'code':'TEH','name':'Tehran'}, + '28' : {'code':'WEZ','name':'West Azarbaijan'}, + '29' : {'code':'YZD','name':'Yazd'}, + '30' : {'code':'ZAN','name':'Zanjan'} + }, + 'IQ':{ + '1' : {'code':'AB','name':'Al Anbar'}, + '2' : {'code':'AL','name':'Arbil'}, + '3' : {'code':'BA','name':'Al Basrah'}, + '4' : {'code':'BB','name':'Babil'}, + '5' : {'code':'BD','name':'Baghdad'}, + '6' : {'code':'DH','name':'Dahuk'}, + '7' : {'code':'DQ','name':'Dhi Qar'}, + '8' : {'code':'DY','name':'Diyala'}, + '9' : {'code':'KB','name':'Al Karbala'}, + '10' : {'code':'MU','name':'Al Muthanna'}, + '11' : {'code':'MY','name':'Maysan'}, + '12' : {'code':'NJ','name':'An Najaf'}, + '13' : {'code':'NN','name':'Ninawa'}, + '14' : {'code':'QA','name':'Al Qadisyah'}, + '15' : {'code':'SD','name':'Salah ad Din'}, + '16' : {'code':'SL','name':'As Sulaymaniyah'}, + '17' : {'code':'TM','name':'At Ta\'mim'}, + '18' : {'code':'WS','name':'Wasit'} + }, + 'IE':{ + '1' : {'code':'CA','name':'Carlow'}, + '2' : {'code':'CV','name':'Cavan'}, + '3' : {'code':'CL','name':'Clare'}, + '4' : {'code':'CO','name':'Cork'}, + '5' : {'code':'DO','name':'Donegal'}, + '6' : {'code':'DU','name':'Dublin'}, + '7' : {'code':'GA','name':'Galway'}, + '8' : {'code':'KE','name':'Kerry'}, + '9' : {'code':'KI','name':'Kildare'}, + '10' : {'code':'KL','name':'Kilkenny'}, + '11' : {'code':'LA','name':'Laois'}, + '12' : {'code':'LE','name':'Leitrim'}, + '13' : {'code':'LI','name':'Limerick'}, + '14' : {'code':'LO','name':'Longford'}, + '15' : {'code':'LU','name':'Louth'}, + '16' : {'code':'MA','name':'Mayo'}, + '17' : {'code':'ME','name':'Meath'}, + '18' : {'code':'MO','name':'Monaghan'}, + '19' : {'code':'OF','name':'Offaly'}, + '20' : {'code':'RO','name':'Roscommon'}, + '21' : {'code':'SL','name':'Sligo'}, + '22' : {'code':'TI','name':'Tipperary'}, + '23' : {'code':'WA','name':'Waterford'}, + '24' : {'code':'WE','name':'Westmeath'}, + '25' : {'code':'WX','name':'Wexford'}, + '26' : {'code':'WI','name':'Wicklow'} + }, + 'IL':{ + '1' : {'code':'BS','name':'Be\'er Sheva'}, + '2' : {'code':'BH','name':'Bika\'at Hayarden'}, + '3' : {'code':'EA','name':'Eilat and Arava'}, + '4' : {'code':'GA','name':'Galil'}, + '5' : {'code':'HA','name':'Haifa'}, + '6' : {'code':'JM','name':'Jehuda Mountains'}, + '7' : {'code':'JE','name':'Jerusalem'}, + '8' : {'code':'NE','name':'Negev'}, + '10' : {'code':'SE','name':'Semaria'}, + '11' : {'code':'SH','name':'Sharon'}, + '12' : {'code':'TA','name':'Tel Aviv (Gosh Dan)'} + }, + 'IT':{ + '1' : {'code':'AG','name':'Agrigento'}, + '2' : {'code':'AL','name':'Alessandria'}, + '3' : {'code':'AN','name':'Ancona'}, + '4' : {'code':'AO','name':'Aosta'}, + '5' : {'code':'AR','name':'Arezzo'}, + '6' : {'code':'AP','name':'Ascoli Piceno'}, + '7' : {'code':'AT','name':'Asti'}, + '8' : {'code':'AV','name':'Avellino'}, + '9' : {'code':'BA','name':'Bari'}, + '10' : {'code':'BL','name':'Belluno'}, + '11' : {'code':'BN','name':'Benevento'}, + '12' : {'code':'BG','name':'Bergamo'}, + '13' : {'code':'BI','name':'Biella'}, + '14' : {'code':'BO','name':'Bologna'}, + '15' : {'code':'BZ','name':'Bolzano'}, + '16' : {'code':'BS','name':'Brescia'}, + '17' : {'code':'BR','name':'Brindisi'}, + '18' : {'code':'CA','name':'Cagliari'}, + '19' : {'code':'CL','name':'Caltanissetta'}, + '20' : {'code':'CB','name':'Campobasso'}, + '21' : {'code':'CE','name':'Caserta'}, + '22' : {'code':'CT','name':'Catania'}, + '23' : {'code':'CZ','name':'Catanzaro'}, + '24' : {'code':'CH','name':'Chieti'}, + '25' : {'code':'CO','name':'Como'}, + '26' : {'code':'CS','name':'Cosenza'}, + '27' : {'code':'CR','name':'Cremona'}, + '28' : {'code':'KR','name':'Crotone'}, + '29' : {'code':'CN','name':'Cuneo'}, + '30' : {'code':'EN','name':'Enna'}, + '31' : {'code':'FE','name':'Ferrara'}, + '32' : {'code':'FI','name':'Firenze'}, + '33' : {'code':'FG','name':'Foggia'}, + '34' : {'code':'FO','name':'Forlì'}, + '35' : {'code':'FR','name':'Frosinone'}, + '36' : {'code':'GE','name':'Genova'}, + '37' : {'code':'GO','name':'Gorizia'}, + '38' : {'code':'GR','name':'Grosseto'}, + '39' : {'code':'IM','name':'Imperia'}, + '40' : {'code':'IS','name':'Isernia'}, + '41' : {'code':'AQ','name':'Aquila'}, + '42' : {'code':'SP','name':'La Spezia'}, + '43' : {'code':'LT','name':'Latina'}, + '44' : {'code':'LE','name':'Lecce'}, + '45' : {'code':'LC','name':'Lecco'}, + '46' : {'code':'LI','name':'Livorno'}, + '47' : {'code':'LO','name':'Lodi'}, + '48' : {'code':'LU','name':'Lucca'}, + '49' : {'code':'MC','name':'Macerata'}, + '50' : {'code':'MN','name':'Mantova'}, + '51' : {'code':'MS','name':'Massa-Carrara'}, + '52' : {'code':'MT','name':'Matera'}, + '53' : {'code':'ME','name':'Messina'}, + '54' : {'code':'MI','name':'Milano'}, + '55' : {'code':'MO','name':'Modena'}, + '56' : {'code':'NA','name':'Napoli'}, + '57' : {'code':'NO','name':'Novara'}, + '58' : {'code':'NU','name':'Nuoro'}, + '59' : {'code':'OR','name':'Oristano'}, + '60' : {'code':'PD','name':'Padova'}, + '61' : {'code':'PA','name':'Palermo'}, + '62' : {'code':'PR','name':'Parma'}, + '63' : {'code':'PG','name':'Perugia'}, + '64' : {'code':'PV','name':'Pavia'}, + '65' : {'code':'PU','name':'Pesaro Urbino'}, + '66' : {'code':'PE','name':'Pescara'}, + '67' : {'code':'PC','name':'Piacenza'}, + '68' : {'code':'PI','name':'Pisa'}, + '69' : {'code':'PT','name':'Pistoia'}, + '70' : {'code':'PN','name':'Pordenone'}, + '71' : {'code':'PZ','name':'Potenza'}, + '72' : {'code':'PO','name':'Prato'}, + '73' : {'code':'RG','name':'Ragusa'}, + '74' : {'code':'RA','name':'Ravenna'}, + '75' : {'code':'RC','name':'Reggio Calabria'}, + '76' : {'code':'RE','name':'Reggio Emilia'}, + '77' : {'code':'RI','name':'Rieti'}, + '78' : {'code':'RN','name':'Rimini'}, + '79' : {'code':'RM','name':'Roma'}, + '80' : {'code':'RO','name':'Rovigo'}, + '81' : {'code':'SA','name':'Salerno'}, + '82' : {'code':'SS','name':'Sassari'}, + '83' : {'code':'SV','name':'Savona'}, + '84' : {'code':'SI','name':'Siena'}, + '85' : {'code':'SR','name':'Siracusa'}, + '86' : {'code':'SO','name':'Sondrio'}, + '87' : {'code':'TA','name':'Taranto'}, + '88' : {'code':'TE','name':'Teramo'}, + '89' : {'code':'TR','name':'Terni'}, + '90' : {'code':'TO','name':'Torino'}, + '91' : {'code':'TP','name':'Trapani'}, + '92' : {'code':'TN','name':'Trento'}, + '93' : {'code':'TV','name':'Treviso'}, + '94' : {'code':'TS','name':'Trieste'}, + '95' : {'code':'UD','name':'Udine'}, + '96' : {'code':'VA','name':'Varese'}, + '97' : {'code':'VE','name':'Venezia'}, + '98' : {'code':'VB','name':'Verbania'}, + '99' : {'code':'VC','name':'Vercelli'}, + '100' : {'code':'VR','name':'Verona'}, + '101' : {'code':'VV','name':'Vibo Valentia'}, + '102' : {'code':'VI','name':'Vicenza'}, + '103' : {'code':'VT','name':'Viterbo'}, + '104' : {'code':'CI','name':'Carbonia-Iglesias'}, + '105' : {'code':'VS','name':'Medio Campidano'}, + '106' : {'code':'OG','name':'Ogliastra'}, + '107' : {'code':'OT','name':'Olbia-Tempio'}, + '108' : {'code':'MB','name':'Monza e Brianza'}, + '109' : {'code':'FM','name':'Fermo'}, + '110' : {'code':'BT','name':'Barletta-Andria-Trani'} + }, + 'JM':{ + '1' : {'code':'CLA','name':'Clarendon Parish'}, + '2' : {'code':'HAN','name':'Hanover Parish'}, + '3' : {'code':'KIN','name':'Kingston Parish'}, + '4' : {'code':'MAN','name':'Manchester Parish'}, + '5' : {'code':'POR','name':'Portland Parish'}, + '6' : {'code':'AND','name':'Saint Andrew Parish'}, + '7' : {'code':'ANN','name':'Saint Ann Parish'}, + '8' : {'code':'CAT','name':'Saint Catherine Parish'}, + '9' : {'code':'ELI','name':'Saint Elizabeth Parish'}, + '10' : {'code':'JAM','name':'Saint James Parish'}, + '11' : {'code':'MAR','name':'Saint Mary Parish'}, + '12' : {'code':'THO','name':'Saint Thomas Parish'}, + '13' : {'code':'TRL','name':'Trelawny Parish'}, + '14' : {'code':'WML','name':'Westmoreland Parish'} + }, + 'JP':{ + '1' : {'code':'AI','name':'Aichi'}, + '2' : {'code':'AK','name':'Akita'}, + '3' : {'code':'AO','name':'Aomori'}, + '4' : {'code':'CH','name':'Chiba'}, + '5' : {'code':'EH','name':'Ehime'}, + '6' : {'code':'FK','name':'Fukui'}, + '7' : {'code':'FU','name':'Fukuoka'}, + '8' : {'code':'FS','name':'Fukushima'}, + '9' : {'code':'GI','name':'Gifu'}, + '10' : {'code':'GU','name':'Gumma'}, + '11' : {'code':'HI','name':'Hiroshima'}, + '12' : {'code':'HO','name':'Hokkaido'}, + '13' : {'code':'HY','name':'Hyogo'}, + '14' : {'code':'IB','name':'Ibaraki'}, + '15' : {'code':'IS','name':'Ishikawa'}, + '16' : {'code':'IW','name':'Iwate'}, + '17' : {'code':'KA','name':'Kagawa'}, + '18' : {'code':'KG','name':'Kagoshima'}, + '19' : {'code':'KN','name':'Kanagawa'}, + '20' : {'code':'KO','name':'Kochi'}, + '21' : {'code':'KU','name':'Kumamoto'}, + '22' : {'code':'KY','name':'Kyoto'}, + '23' : {'code':'MI','name':'Mie'}, + '24' : {'code':'MY','name':'Miyagi'}, + '25' : {'code':'MZ','name':'Miyazaki'}, + '26' : {'code':'NA','name':'Nagano'}, + '27' : {'code':'NG','name':'Nagasaki'}, + '28' : {'code':'NR','name':'Nara'}, + '29' : {'code':'NI','name':'Niigata'}, + '30' : {'code':'OI','name':'Oita'}, + '31' : {'code':'OK','name':'Okayama'}, + '32' : {'code':'ON','name':'Okinawa'}, + '33' : {'code':'OS','name':'Osaka'}, + '34' : {'code':'SA','name':'Saga'}, + '35' : {'code':'SI','name':'Saitama'}, + '36' : {'code':'SH','name':'Shiga'}, + '37' : {'code':'SM','name':'Shimane'}, + '38' : {'code':'SZ','name':'Shizuoka'}, + '39' : {'code':'TO','name':'Tochigi'}, + '40' : {'code':'TS','name':'Tokushima'}, + '41' : {'code':'TK','name':'Tokyo'}, + '42' : {'code':'TT','name':'Tottori'}, + '43' : {'code':'TY','name':'Toyama'}, + '44' : {'code':'WA','name':'Wakayama'}, + '45' : {'code':'YA','name':'Yamagata'}, + '46' : {'code':'YM','name':'Yamaguchi'}, + '47' : {'code':'YN','name':'Yamanashi'} + }, + 'JO':{ + '1' : {'code':'AM','name':'\'Amman'}, + '2' : {'code':'AJ','name':'Ajlun'}, + '3' : {'code':'AA','name':'Al\'Aqabah'}, + '4' : {'code':'AB','name':'Al Balqa\''}, + '5' : {'code':'AK','name':'Al Karak'}, + '6' : {'code':'AL','name':'Al Mafraq'}, + '7' : {'code':'AT','name':'At Tafilah'}, + '8' : {'code':'AZ','name':'Az Zarqa\''}, + '9' : {'code':'IR','name':'Irbid'}, + '10' : {'code':'JA','name':'Jarash'}, + '11' : {'code':'MA','name':'Ma\'an'}, + '12' : {'code':'MD','name':'Madaba'} + }, + 'KZ':{ + '1' : {'code':'AL','name':'Almaty'}, + '2' : {'code':'AC','name':'Almaty City'}, + '3' : {'code':'AM','name':'Aqmola'}, + '4' : {'code':'AQ','name':'Aqtobe'}, + '5' : {'code':'AS','name':'Astana City'}, + '6' : {'code':'AT','name':'Atyrau'}, + '7' : {'code':'BA','name':'Batys Qazaqstan'}, + '8' : {'code':'BY','name':'Bayqongyr City'}, + '9' : {'code':'MA','name':'Mangghystau'}, + '10' : {'code':'ON','name':'Ongtustik Qazaqstan'}, + '11' : {'code':'PA','name':'Pavlodar'}, + '12' : {'code':'QA','name':'Qaraghandy'}, + '13' : {'code':'QO','name':'Qostanay'}, + '14' : {'code':'QY','name':'Qyzylorda'}, + '15' : {'code':'SH','name':'Shyghys Qazaqstan'}, + '16' : {'code':'SO','name':'Soltustik Qazaqstan'}, + '17' : {'code':'ZH','name':'Zhambyl'} + }, + 'KE':{ + '1' : {'code':'CE','name':'Central'}, + '2' : {'code':'CO','name':'Coast'}, + '3' : {'code':'EA','name':'Eastern'}, + '4' : {'code':'NA','name':'Nairobi Area'}, + '5' : {'code':'NE','name':'North Eastern'}, + '6' : {'code':'NY','name':'Nyanza'}, + '7' : {'code':'RV','name':'Rift Valley'}, + '8' : {'code':'WE','name':'Western'} + }, + 'KI':{ + '1' : {'code':'AG','name':'Abaiang'}, + '2' : {'code':'AM','name':'Abemama'}, + '3' : {'code':'AK','name':'Aranuka'}, + '4' : {'code':'AO','name':'Arorae'}, + '5' : {'code':'BA','name':'Banaba'}, + '6' : {'code':'BE','name':'Beru'}, + '7' : {'code':'bT','name':'Butaritari'}, + '8' : {'code':'KA','name':'Kanton'}, + '9' : {'code':'KR','name':'Kiritimati'}, + '10' : {'code':'KU','name':'Kuria'}, + '11' : {'code':'MI','name':'Maiana'}, + '12' : {'code':'MN','name':'Makin'}, + '13' : {'code':'ME','name':'Marakei'}, + '14' : {'code':'NI','name':'Nikunau'}, + '15' : {'code':'NO','name':'Nonouti'}, + '16' : {'code':'ON','name':'Onotoa'}, + '17' : {'code':'TT','name':'Tabiteuea'}, + '18' : {'code':'TR','name':'Tabuaeran'}, + '19' : {'code':'TM','name':'Tamana'}, + '20' : {'code':'TW','name':'Tarawa'}, + '21' : {'code':'TE','name':'Teraina'} + }, + 'KP':{ + '1' : {'code':'CHA','name':'Chagang-do'}, + '2' : {'code':'HAB','name':'Hamgyong-bukto'}, + '3' : {'code':'HAN','name':'Hamgyong-namdo'}, + '4' : {'code':'HWB','name':'Hwanghae-bukto'}, + '5' : {'code':'HWN','name':'Hwanghae-namdo'}, + '6' : {'code':'KAN','name':'Kangwon-do'}, + '7' : {'code':'PYB','name':'P\'yongan-bukto'}, + '8' : {'code':'PYN','name':'P\'yongan-namdo'}, + '9' : {'code':'YAN','name':'Ryanggang-do (Yanggang-do)'}, + '10' : {'code':'NAJ','name':'Rason Directly Governed City'}, + '11' : {'code':'PYO','name':'P\'yongyang Special City'} + }, + 'KR':{ + '1' : {'code':'CO','name':'Ch\'ungch\'ong-bukto'}, + '2' : {'code':'CH','name':'Ch\'ungch\'ong-namdo'}, + '3' : {'code':'CD','name':'Cheju-do'}, + '4' : {'code':'CB','name':'Cholla-bukto'}, + '5' : {'code':'CN','name':'Cholla-namdo'}, + '6' : {'code':'IG','name':'Inch\'on-gwangyoksi'}, + '7' : {'code':'KA','name':'Kangwon-do'}, + '8' : {'code':'KG','name':'Kwangju-gwangyoksi'}, + '9' : {'code':'KD','name':'Kyonggi-do'}, + '10' : {'code':'KB','name':'Kyongsang-bukto'}, + '11' : {'code':'KN','name':'Kyongsang-namdo'}, + '12' : {'code':'PG','name':'Pusan-gwangyoksi'}, + '13' : {'code':'SO','name':'Soul-t\'ukpyolsi'}, + '14' : {'code':'TA','name':'Taegu-gwangyoksi'}, + '15' : {'code':'TG','name':'Taejon-gwangyoksi'} + }, + 'KW':{ + '1' : {'code':'AL','name':'Al\'Asimah'}, + '2' : {'code':'AA','name':'Al Ahmadi'}, + '3' : {'code':'AF','name':'Al Farwaniyah'}, + '4' : {'code':'AJ','name':'Al Jahra\''}, + '5' : {'code':'HA','name':'Hawalli'} + }, + 'KG':{ + '1' : {'code':'GB','name':'Bishkek'}, + '2' : {'code':'B','name':'Batken'}, + '3' : {'code':'C','name':'Chu'}, + '4' : {'code':'J','name':'Jalal-Abad'}, + '5' : {'code':'N','name':'Naryn'}, + '6' : {'code':'O','name':'Osh'}, + '7' : {'code':'T','name':'Talas'}, + '8' : {'code':'Y','name':'Ysyk-Kol'} + }, + 'LA':{ + '1' : {'code':'VT','name':'Vientiane'}, + '2' : {'code':'AT','name':'Attapu'}, + '3' : {'code':'BK','name':'Bokeo'}, + '4' : {'code':'BL','name':'Bolikhamxai'}, + '5' : {'code':'CH','name':'Champasak'}, + '6' : {'code':'HO','name':'Houaphan'}, + '7' : {'code':'KH','name':'Khammouan'}, + '8' : {'code':'LM','name':'Louang Namtha'}, + '9' : {'code':'LP','name':'Louangphabang'}, + '10' : {'code':'OU','name':'Oudomxai'}, + '11' : {'code':'PH','name':'Phongsali'}, + '12' : {'code':'SL','name':'Salavan'}, + '13' : {'code':'SV','name':'Savannakhet'}, + '14' : {'code':'VI','name':'Vientiane'}, + '15' : {'code':'XA','name':'Xaignabouli'}, + '16' : {'code':'XE','name':'Xekong'}, + '17' : {'code':'XI','name':'Xiangkhoang'}, + '18' : {'code':'XN','name':'Xaisomboun'} + }, + 'LV':{ + '1' : {'code':'AIZ','name':'Aizkraukles Rajons'}, + '2' : {'code':'ALU','name':'Aluksnes Rajons'}, + '3' : {'code':'BAL','name':'Balvu Rajons'}, + '4' : {'code':'BAU','name':'Bauskas Rajons'}, + '5' : {'code':'CES','name':'Cesu Rajons'}, + '6' : {'code':'DGR','name':'Daugavpils Rajons'}, + '7' : {'code':'DOB','name':'Dobeles Rajons'}, + '8' : {'code':'GUL','name':'Gulbenes Rajons'}, + '9' : {'code':'JEK','name':'Jekabpils Rajons'}, + '10' : {'code':'JGR','name':'Jelgavas Rajons'}, + '11' : {'code':'KRA','name':'Kraslavas Rajons'}, + '12' : {'code':'KUL','name':'Kuldigas Rajons'}, + '13' : {'code':'LPR','name':'Liepajas Rajons'}, + '14' : {'code':'LIM','name':'Limbazu Rajons'}, + '15' : {'code':'LUD','name':'Ludzas Rajons'}, + '16' : {'code':'MAD','name':'Madonas Rajons'}, + '17' : {'code':'OGR','name':'Ogres Rajons'}, + '18' : {'code':'PRE','name':'Preilu Rajons'}, + '19' : {'code':'RZR','name':'Rezeknes Rajons'}, + '20' : {'code':'RGR','name':'Rigas Rajons'}, + '21' : {'code':'SAL','name':'Saldus Rajons'}, + '22' : {'code':'TAL','name':'Talsu Rajons'}, + '23' : {'code':'TUK','name':'Tukuma Rajons'}, + '24' : {'code':'VLK','name':'Valkas Rajons'}, + '25' : {'code':'VLM','name':'Valmieras Rajons'}, + '26' : {'code':'VSR','name':'Ventspils Rajons'}, + '27' : {'code':'DGV','name':'Daugavpils'}, + '28' : {'code':'JGV','name':'Jelgava'}, + '29' : {'code':'JUR','name':'Jurmala'}, + '30' : {'code':'LPK','name':'Liepaja'}, + '31' : {'code':'RZK','name':'Rezekne'}, + '32' : {'code':'RGA','name':'Riga'}, + '33' : {'code':'VSL','name':'Ventspils'} + }, + 'LB':{ + '1' : {'code':'BIN','name':'Bint Jbeil'}, + '2' : {'code':'HAS','name':'Hasbaya'}, + '3' : {'code':'MAR','name':'Marjeyoun'}, + '4' : {'code':'NAB','name':'Nabatieh'}, + '5' : {'code':'BAA','name':'Baalbek'}, + '6' : {'code':'HER','name':'Hermel'}, + '7' : {'code':'RAS','name':'Rashaya'}, + '8' : {'code':'WES','name':'Western Beqaa'}, + '9' : {'code':'ZAH','name':'Zahle'}, + '10' : {'code':'AKK','name':'Akkar'}, + '11' : {'code':'BAT','name':'Batroun'}, + '12' : {'code':'BSH','name':'Bsharri'}, + '13' : {'code':'KOU','name':'Koura'}, + '14' : {'code':'MIN','name':'Miniyeh-Danniyeh'}, + '15' : {'code':'TRI','name':'Tripoli'}, + '16' : {'code':'ZGH','name':'Zgharta'}, + '17' : {'code':'ALE','name':'Aley'}, + '18' : {'code':'BAA','name':'Baabda'}, + '19' : {'code':'BYB','name':'Byblos'}, + '20' : {'code':'CHO','name':'Chouf'}, + '21' : {'code':'KES','name':'Kesrwan'}, + '22' : {'code':'MAT','name':'Matn'}, + '23' : {'code':'JEZ','name':'Jezzine'}, + '24' : {'code':'SID','name':'Sidon'}, + '25' : {'code':'TYR','name':'Tyre'} + }, + 'LS':{ + '1' : {'code':'BE','name':'Berea'}, + '2' : {'code':'BB','name':'Butha-Buthe'}, + '3' : {'code':'LE','name':'Leribe'}, + '4' : {'code':'MF','name':'Mafeteng'}, + '5' : {'code':'MS','name':'Maseru'}, + '6' : {'code':'MH','name':'Mohale\'s Hoek'}, + '7' : {'code':'MK','name':'Mokhotlong'}, + '8' : {'code':'QN','name':'Qacha\'s Nek'}, + '9' : {'code':'QT','name':'Quthing'}, + '10' : {'code':'TT','name':'Thaba-Tseka'} + }, + 'LR':{ + '1' : {'code':'BI','name':'Bomi'}, + '2' : {'code':'BG','name':'Bong'}, + '3' : {'code':'GB','name':'Grand Bassa'}, + '4' : {'code':'CM','name':'Grand Cape Mount'}, + '5' : {'code':'GG','name':'Grand Gedeh'}, + '6' : {'code':'GK','name':'Grand Kru'}, + '7' : {'code':'LO','name':'Lofa'}, + '8' : {'code':'MG','name':'Margibi'}, + '9' : {'code':'ML','name':'Maryland'}, + '10' : {'code':'MS','name':'Montserrado'}, + '11' : {'code':'NB','name':'Nimba'}, + '12' : {'code':'RC','name':'River Cess'}, + '13' : {'code':'SN','name':'Sinoe'} + }, + 'LY':{ + '1' : {'code':'AJ','name':'Ajdabiya'}, + '2' : {'code':'AZ','name':'Al \'Aziziyah'}, + '3' : {'code':'FA','name':'Al Fatih'}, + '4' : {'code':'JA','name':'Al Jabal al Akhdar'}, + '5' : {'code':'JU','name':'Al Jufrah'}, + '6' : {'code':'KH','name':'Al Khums'}, + '7' : {'code':'KU','name':'Al Kufrah'}, + '8' : {'code':'NK','name':'An Nuqat al Khams'}, + '9' : {'code':'AS','name':'Ash Shati\''}, + '10' : {'code':'AW','name':'Awbari'}, + '11' : {'code':'ZA','name':'Az Zawiyah'}, + '12' : {'code':'BA','name':'Banghazi'}, + '13' : {'code':'DA','name':'Darnah'}, + '14' : {'code':'GD','name':'Ghadamis'}, + '15' : {'code':'GY','name':'Gharyan'}, + '16' : {'code':'MI','name':'Misratah'}, + '17' : {'code':'MZ','name':'Murzuq'}, + '18' : {'code':'SB','name':'Sabha'}, + '19' : {'code':'SW','name':'Sawfajjin'}, + '20' : {'code':'SU','name':'Surt'}, + '21' : {'code':'TL','name':'Tarabulus (Tripoli)'}, + '22' : {'code':'TH','name':'Tarhunah'}, + '23' : {'code':'TU','name':'Tubruq'}, + '24' : {'code':'YA','name':'Yafran'}, + '25' : {'code':'ZL','name':'Zlitan'} + }, + 'LI':{ + '1' : {'code':'V','name':'Vaduz'}, + '2' : {'code':'A','name':'Schaan'}, + '3' : {'code':'B','name':'Balzers'}, + '4' : {'code':'N','name':'Triesen'}, + '5' : {'code':'E','name':'Eschen'}, + '6' : {'code':'M','name':'Mauren'}, + '7' : {'code':'T','name':'Triesenberg'}, + '8' : {'code':'R','name':'Ruggell'}, + '9' : {'code':'G','name':'Gamprin'}, + '10' : {'code':'L','name':'Schellenberg'}, + '11' : {'code':'P','name':'Planken'} + }, + 'LT':{ + '1' : {'code':'AL','name':'Alytus'}, + '2' : {'code':'KA','name':'Kaunas'}, + '3' : {'code':'KL','name':'Klaipeda'}, + '4' : {'code':'MA','name':'Marijampole'}, + '5' : {'code':'PA','name':'Panevezys'}, + '6' : {'code':'SI','name':'Siauliai'}, + '7' : {'code':'TA','name':'Taurage'}, + '8' : {'code':'TE','name':'Telsiai'}, + '9' : {'code':'UT','name':'Utena'}, + '10' : {'code':'VI','name':'Vilnius'} + }, + 'LU':{ + '1' : {'code':'DD','name':'Diekirch'}, + '2' : {'code':'DC','name':'Clervaux'}, + '3' : {'code':'DR','name':'Redange'}, + '4' : {'code':'DV','name':'Vianden'}, + '5' : {'code':'DW','name':'Wiltz'}, + '6' : {'code':'GG','name':'Grevenmacher'}, + '7' : {'code':'GE','name':'Echternach'}, + '8' : {'code':'GR','name':'Remich'}, + '9' : {'code':'LL','name':'Luxembourg'}, + '10' : {'code':'LC','name':'Capellen'}, + '11' : {'code':'LE','name':'Esch-sur-Alzette'}, + '12' : {'code':'LM','name':'Mersch'} + }, + 'MO':{ + '1' : {'code':'OLF','name':'Our Lady Fatima Parish'}, + '2' : {'code':'ANT','name':'St. Anthony Parish'}, + '3' : {'code':'LAZ','name':'St. Lazarus Parish'}, + '4' : {'code':'CAT','name':'Cathedral Parish'}, + '5' : {'code':'LAW','name':'St. Lawrence Parish'} + }, + 'MK':{ + '1' : {'code':'AER','name':'Aerodrom'}, + '2' : {'code':'ARA','name':'Aračinovo'}, + '3' : {'code':'BER','name':'Berovo'}, + '4' : {'code':'BIT','name':'Bitola'}, + '5' : {'code':'BOG','name':'Bogdanci'}, + '6' : {'code':'BOG','name':'Bogovinje'}, + '7' : {'code':'BOS','name':'Bosilovo'}, + '8' : {'code':'BRV','name':'Brvenica'}, + '9' : {'code':'BUT','name':'Butel'}, + '10' : {'code':'ČAI','name':'Čair'}, + '11' : {'code':'ČAš','name':'Čaška'}, + '12' : {'code':'CEN','name':'Centar'}, + '13' : {'code':'CEN','name':'Centar Župa'}, + '14' : {'code':'Češ','name':'Češinovo-Obleš'}, + '15' : {'code':'ČUČ','name':'Čučer-Sandevo'}, + '16' : {'code':'DEB','name':'Debar'}, + '17' : {'code':'DEB','name':'Debarca'}, + '18' : {'code':'DEL','name':'Delčevo'}, + '19' : {'code':'DEM','name':'Demir Hisar'}, + '20' : {'code':'DEM','name':'Demir Kapija'}, + '21' : {'code':'DOL','name':'Dolneni'}, + '22' : {'code':'DRU','name':'Drugovo'}, + '23' : {'code':'GAZ','name':'Gazi Baba'}, + '24' : {'code':'GEV','name':'Gevgelija'}, + '25' : {'code':'GJO','name':'Gjorče Petrov'}, + '26' : {'code':'GOS','name':'Gostivar'}, + '27' : {'code':'GRA','name':'Gradsko'}, + '28' : {'code':'ILI','name':'Ilinden'}, + '29' : {'code':'JEG','name':'Jegunovce'}, + '30' : {'code':'KAR','name':'Karbinci'}, + '31' : {'code':'KAR','name':'Karpoš'}, + '32' : {'code':'KAV','name':'Kavadarci'}, + '33' : {'code':'KIČ','name':'Kičevo'}, + '34' : {'code':'KIS','name':'Kisela Voda'}, + '35' : {'code':'KOč','name':'Kočani'}, + '36' : {'code':'KON','name':'Konče'}, + '37' : {'code':'KRA','name':'Kratovo'}, + '38' : {'code':'KRI','name':'Kriva Palanka'}, + '39' : {'code':'KRI','name':'Krivogaštani'}, + '40' : {'code':'KRU','name':'Kruševo'}, + '41' : {'code':'KUM','name':'Kumanovo'}, + '42' : {'code':'LIP','name':'Lipkovo'}, + '43' : {'code':'LOZ','name':'Lozovo'}, + '44' : {'code':'MAK','name':'Makedonska Kamenica'}, + '45' : {'code':'MAK','name':'Makedonski Brod'}, + '46' : {'code':'MAV','name':'Mavrovo and Rostuša'}, + '47' : {'code':'MOG','name':'Mogila'}, + '48' : {'code':'NEG','name':'Negotino'}, + '49' : {'code':'NOV','name':'Novaci'}, + '50' : {'code':'NOV','name':'Novo Selo'}, + '51' : {'code':'OHR','name':'Ohrid'}, + '52' : {'code':'OSL','name':'Oslomej'}, + '53' : {'code':'PEH','name':'Pehčevo'}, + '54' : {'code':'PET','name':'Petrovec'}, + '55' : {'code':'PLA','name':'Plasnica'}, + '56' : {'code':'PRI','name':'Prilep'}, + '57' : {'code':'PRO','name':'Probištip'}, + '58' : {'code':'RAD','name':'Radoviš'}, + '59' : {'code':'RAN','name':'Rankovce'}, + '60' : {'code':'RES','name':'Resen'}, + '61' : {'code':'ROS','name':'Rosoman'}, + '62' : {'code':'SAR','name':'Saraj'}, + '63' : {'code':'SOP','name':'Sopište'}, + '64' : {'code':'STA','name':'Star Dojran'}, + '65' : {'code':'STA','name':'Staro Nagoričane'}, + '66' : {'code':'ŠTI','name':'Štip'}, + '67' : {'code':'STR','name':'Struga'}, + '68' : {'code':'STR','name':'Strumica'}, + '69' : {'code':'STU','name':'Studeničani'}, + '70' : {'code':'ŠUT','name':'Šuto Orizari'}, + '71' : {'code':'SVE','name':'Sveti Nikole'}, + '72' : {'code':'TEA','name':'Tearce'}, + '73' : {'code':'TET','name':'Tetovo'}, + '74' : {'code':'VAL','name':'Valandovo'}, + '75' : {'code':'VAS','name':'Vasilevo'}, + '76' : {'code':'VEL','name':'Veles'}, + '77' : {'code':'VEV','name':'Vevčani'}, + '78' : {'code':'VIN','name':'Vinica'}, + '79' : {'code':'VRA','name':'Vraneštica'}, + '80' : {'code':'VRA','name':'Vrapčište'}, + '81' : {'code':'ZAJ','name':'Zajas'}, + '82' : {'code':'ZEL','name':'Zelenikovo'}, + '83' : {'code':'ŽEL','name':'Želino'}, + '84' : {'code':'ZRN','name':'Zrnovci'} + }, + 'MG':{ + '1' : {'code':'AN','name':'Antananarivo'}, + '2' : {'code':'AS','name':'Antsiranana'}, + '3' : {'code':'FN','name':'Fianarantsoa'}, + '4' : {'code':'MJ','name':'Mahajanga'}, + '5' : {'code':'TM','name':'Toamasina'}, + '6' : {'code':'TL','name':'Toliara'} + }, + 'MW':{ + '1' : {'code':'BLK','name':'Balaka'}, + '2' : {'code':'BLT','name':'Blantyre'}, + '3' : {'code':'CKW','name':'Chikwawa'}, + '4' : {'code':'CRD','name':'Chiradzulu'}, + '5' : {'code':'CTP','name':'Chitipa'}, + '6' : {'code':'DDZ','name':'Dedza'}, + '7' : {'code':'DWA','name':'Dowa'}, + '8' : {'code':'KRG','name':'Karonga'}, + '9' : {'code':'KSG','name':'Kasungu'}, + '10' : {'code':'LKM','name':'Likoma'}, + '11' : {'code':'LLG','name':'Lilongwe'}, + '12' : {'code':'MCG','name':'Machinga'}, + '13' : {'code':'MGC','name':'Mangochi'}, + '14' : {'code':'MCH','name':'Mchinji'}, + '15' : {'code':'MLJ','name':'Mulanje'}, + '16' : {'code':'MWZ','name':'Mwanza'}, + '17' : {'code':'MZM','name':'Mzimba'}, + '18' : {'code':'NTU','name':'Ntcheu'}, + '19' : {'code':'NKB','name':'Nkhata Bay'}, + '20' : {'code':'NKH','name':'Nkhotakota'}, + '21' : {'code':'NSJ','name':'Nsanje'}, + '22' : {'code':'NTI','name':'Ntchisi'}, + '23' : {'code':'PHL','name':'Phalombe'}, + '24' : {'code':'RMP','name':'Rumphi'}, + '25' : {'code':'SLM','name':'Salima'}, + '26' : {'code':'THY','name':'Thyolo'}, + '27' : {'code':'ZBA','name':'Zomba'} + }, + 'MY':{ + '1' : {'code':'Johor','name':'Johor'}, + '2' : {'code':'Kedah','name':'Kedah'}, + '3' : {'code':'Kelantan','name':'Kelantan'}, + '4' : {'code':'Labuan','name':'Labuan'}, + '5' : {'code':'Melaka','name':'Melaka'}, + '6' : {'code':'Negeri Sembilan','name':'Negeri Sembilan'}, + '7' : {'code':'Pahang','name':'Pahang'}, + '8' : {'code':'Perak','name':'Perak'}, + '9' : {'code':'Perlis','name':'Perlis'}, + '10' : {'code':'Pulau Pinang','name':'Pulau Pinang'}, + '11' : {'code':'Sabah','name':'Sabah'}, + '12' : {'code':'Sarawak','name':'Sarawak'}, + '13' : {'code':'Selangor','name':'Selangor'}, + '14' : {'code':'Terengganu','name':'Terengganu'}, + '15' : {'code':'Kuala Lumpur','name':'Kuala Lumpur'} + }, + 'MV':{ + '1' : {'code':'AAD','name':'Ari Atoll Dheknu'}, + '2' : {'code':'AAU','name':'Ari Atoll Uthuru'}, + '3' : {'code':'ADD','name':'Addu'}, + '4' : {'code':'FAA','name':'Faadhippolhu'}, + '5' : {'code':'FEA','name':'Felidhe Atoll'}, + '6' : {'code':'FMU','name':'Fua Mulaku'}, + '7' : {'code':'HAD','name':'Huvadhu Atoll Dhekunu'}, + '8' : {'code':'HAU','name':'Huvadhu Atoll Uthuru'}, + '9' : {'code':'HDH','name':'Hadhdhunmathi'}, + '10' : {'code':'KLH','name':'Kolhumadulu'}, + '11' : {'code':'MAA','name':'Male Atoll'}, + '12' : {'code':'MAD','name':'Maalhosmadulu Dhekunu'}, + '13' : {'code':'MAU','name':'Maalhosmadulu Uthuru'}, + '14' : {'code':'MLD','name':'Miladhunmadulu Dhekunu'}, + '15' : {'code':'MLU','name':'Miladhunmadulu Uthuru'}, + '16' : {'code':'MUA','name':'Mulaku Atoll'}, + '17' : {'code':'NAD','name':'Nilandhe Atoll Dhekunu'}, + '18' : {'code':'NAU','name':'Nilandhe Atoll Uthuru'}, + '19' : {'code':'THD','name':'Thiladhunmathi Dhekunu'}, + '20' : {'code':'THU','name':'Thiladhunmathi Uthuru'} + }, + 'ML':{ + '1' : {'code':'GA','name':'Gao'}, + '2' : {'code':'KY','name':'Kayes'}, + '3' : {'code':'KD','name':'Kidal'}, + '4' : {'code':'KL','name':'Koulikoro'}, + '5' : {'code':'MP','name':'Mopti'}, + '6' : {'code':'SG','name':'Segou'}, + '7' : {'code':'SK','name':'Sikasso'}, + '8' : {'code':'TB','name':'Tombouctou'}, + '9' : {'code':'CD','name':'Bamako Capital District'} + }, + 'MT':{ + '1' : {'code':'ATT','name':'Attard'}, + '2' : {'code':'BAL','name':'Balzan'}, + '3' : {'code':'BGU','name':'Birgu'}, + '4' : {'code':'BKK','name':'Birkirkara'}, + '5' : {'code':'BRZ','name':'Birzebbuga'}, + '6' : {'code':'BOR','name':'Bormla'}, + '7' : {'code':'DIN','name':'Dingli'}, + '8' : {'code':'FGU','name':'Fgura'}, + '9' : {'code':'FLO','name':'Floriana'}, + '10' : {'code':'GDJ','name':'Gudja'}, + '11' : {'code':'GZR','name':'Gzira'}, + '12' : {'code':'GRG','name':'Gargur'}, + '13' : {'code':'GXQ','name':'Gaxaq'}, + '14' : {'code':'HMR','name':'Hamrun'}, + '15' : {'code':'IKL','name':'Iklin'}, + '16' : {'code':'ISL','name':'Isla'}, + '17' : {'code':'KLK','name':'Kalkara'}, + '18' : {'code':'KRK','name':'Kirkop'}, + '19' : {'code':'LIJ','name':'Lija'}, + '20' : {'code':'LUQ','name':'Luqa'}, + '21' : {'code':'MRS','name':'Marsa'}, + '22' : {'code':'MKL','name':'Marsaskala'}, + '23' : {'code':'MXL','name':'Marsaxlokk'}, + '24' : {'code':'MDN','name':'Mdina'}, + '25' : {'code':'MEL','name':'Melliea'}, + '26' : {'code':'MGR','name':'Mgarr'}, + '27' : {'code':'MST','name':'Mosta'}, + '28' : {'code':'MQA','name':'Mqabba'}, + '29' : {'code':'MSI','name':'Msida'}, + '30' : {'code':'MTF','name':'Mtarfa'}, + '31' : {'code':'NAX','name':'Naxxar'}, + '32' : {'code':'PAO','name':'Paola'}, + '33' : {'code':'PEM','name':'Pembroke'}, + '34' : {'code':'PIE','name':'Pieta'}, + '35' : {'code':'QOR','name':'Qormi'}, + '36' : {'code':'QRE','name':'Qrendi'}, + '37' : {'code':'RAB','name':'Rabat'}, + '38' : {'code':'SAF','name':'Safi'}, + '39' : {'code':'SGI','name':'San Giljan'}, + '40' : {'code':'SLU','name':'Santa Lucija'}, + '41' : {'code':'SPB','name':'San Pawl il-Bahar'}, + '42' : {'code':'SGW','name':'San Gwann'}, + '43' : {'code':'SVE','name':'Santa Venera'}, + '44' : {'code':'SIG','name':'Siggiewi'}, + '45' : {'code':'SLM','name':'Sliema'}, + '46' : {'code':'SWQ','name':'Swieqi'}, + '47' : {'code':'TXB','name':'Ta Xbiex'}, + '48' : {'code':'TRX','name':'Tarxien'}, + '49' : {'code':'VLT','name':'Valletta'}, + '50' : {'code':'XGJ','name':'Xgajra'}, + '51' : {'code':'ZBR','name':'Zabbar'}, + '52' : {'code':'ZBG','name':'Zebbug'}, + '53' : {'code':'ZJT','name':'Zejtun'}, + '54' : {'code':'ZRQ','name':'Zurrieq'}, + '55' : {'code':'FNT','name':'Fontana'}, + '56' : {'code':'GHJ','name':'Ghajnsielem'}, + '57' : {'code':'GHR','name':'Gharb'}, + '58' : {'code':'GHS','name':'Ghasri'}, + '59' : {'code':'KRC','name':'Kercem'}, + '60' : {'code':'MUN','name':'Munxar'}, + '61' : {'code':'NAD','name':'Nadur'}, + '62' : {'code':'QAL','name':'Qala'}, + '63' : {'code':'VIC','name':'Victoria'}, + '64' : {'code':'SLA','name':'San Lawrenz'}, + '65' : {'code':'SNT','name':'Sannat'}, + '66' : {'code':'ZAG','name':'Xagra'}, + '67' : {'code':'XEW','name':'Xewkija'}, + '68' : {'code':'ZEB','name':'Zebbug'} + }, + 'MH':{ + '1' : {'code':'ALG','name':'Ailinginae'}, + '2' : {'code':'ALL','name':'Ailinglaplap'}, + '3' : {'code':'ALK','name':'Ailuk'}, + '4' : {'code':'ARN','name':'Arno'}, + '5' : {'code':'AUR','name':'Aur'}, + '6' : {'code':'BKR','name':'Bikar'}, + '7' : {'code':'BKN','name':'Bikini'}, + '8' : {'code':'BKK','name':'Bokak'}, + '9' : {'code':'EBN','name':'Ebon'}, + '10' : {'code':'ENT','name':'Enewetak'}, + '11' : {'code':'EKB','name':'Erikub'}, + '12' : {'code':'JBT','name':'Jabat'}, + '13' : {'code':'JLT','name':'Jaluit'}, + '14' : {'code':'JEM','name':'Jemo'}, + '15' : {'code':'KIL','name':'Kili'}, + '16' : {'code':'KWJ','name':'Kwajalein'}, + '17' : {'code':'LAE','name':'Lae'}, + '18' : {'code':'LIB','name':'Lib'}, + '19' : {'code':'LKP','name':'Likiep'}, + '20' : {'code':'MJR','name':'Majuro'}, + '21' : {'code':'MLP','name':'Maloelap'}, + '22' : {'code':'MJT','name':'Mejit'}, + '23' : {'code':'MIL','name':'Mili'}, + '24' : {'code':'NMK','name':'Namorik'}, + '25' : {'code':'NAM','name':'Namu'}, + '26' : {'code':'RGL','name':'Rongelap'}, + '27' : {'code':'RGK','name':'Rongrik'}, + '28' : {'code':'TOK','name':'Toke'}, + '29' : {'code':'UJA','name':'Ujae'}, + '30' : {'code':'UJL','name':'Ujelang'}, + '31' : {'code':'UTK','name':'Utirik'}, + '32' : {'code':'WTH','name':'Wotho'}, + '33' : {'code':'WTJ','name':'Wotje'} + }, + 'MQ':{ + '1' : {'code':'LAJ','name':'L\'Ajoupa-Bouillon'}, + '2' : {'code':'LES','name':'Les Anses-d\'Arlet'}, + '3' : {'code':'BAS','name':'Basse-Pointe'}, + '4' : {'code':'BEL','name':'Bellefontaine'}, + '5' : {'code':'LE','name':'Le Carbet'}, + '6' : {'code':'CAS','name':'Case-Pilote'}, + '7' : {'code':'LE','name':'Le Diamant'}, + '8' : {'code':'DUC','name':'Ducos'}, + '9' : {'code':'FON','name':'Fonds-Saint-Denis'}, + '10' : {'code':'FOR','name':'Fort-De-France'}, + '11' : {'code':'LE','name':'Le François'}, + '12' : {'code':'GRA','name':'Grand\'Rivière'}, + '13' : {'code':'GRO','name':'Gros-Morne'}, + '14' : {'code':'LE','name':'Le Lamentin'}, + '15' : {'code':'LE','name':'Le Lorrain'}, + '16' : {'code':'MAC','name':'Macouba'}, + '17' : {'code':'LE','name':'Le Marigot'}, + '18' : {'code':'LE','name':'Le Marin'}, + '19' : {'code':'LE','name':'Le Morne-Rouge'}, + '20' : {'code':'LE','name':'Le Morne-Vert'}, + '21' : {'code':'LE','name':'Le Prêcheur'}, + '22' : {'code':'RIV','name':'Rivière-Pilote'}, + '23' : {'code':'RIV','name':'Rivière-Salée'}, + '24' : {'code':'LE','name':'Le Robert'}, + '25' : {'code':'SAI','name':'Sainte-Anne'}, + '26' : {'code':'SAI','name':'Sainte-Luce'}, + '27' : {'code':'SAI','name':'Sainte-Marie'}, + '28' : {'code':'SAI','name':'Saint-Esprit'}, + '29' : {'code':'SAI','name':'Saint-Joseph'}, + '30' : {'code':'SAI','name':'Saint-Pierre'}, + '31' : {'code':'SCH','name':'Schœlcher'}, + '32' : {'code':'LA','name':'La Trinité'}, + '33' : {'code':'LES','name':'Les Trois-Îlets'}, + '34' : {'code':'LE','name':'Le Vauclin'} + }, + 'MR':{ + '1' : {'code':'AD','name':'Adrar'}, + '2' : {'code':'AS','name':'Assaba'}, + '3' : {'code':'BR','name':'Brakna'}, + '4' : {'code':'DN','name':'Dakhlet Nouadhibou'}, + '5' : {'code':'GO','name':'Gorgol'}, + '6' : {'code':'GM','name':'Guidimaka'}, + '7' : {'code':'HC','name':'Hodh Ech Chargui'}, + '8' : {'code':'HG','name':'Hodh El Gharbi'}, + '9' : {'code':'IN','name':'Inchiri'}, + '10' : {'code':'TA','name':'Tagant'}, + '11' : {'code':'TZ','name':'Tiris Zemmour'}, + '12' : {'code':'TR','name':'Trarza'}, + '13' : {'code':'NO','name':'Nouakchott'} + }, + 'MU':{ + '1' : {'code':'AG','name':'Agalega Islands'}, + '2' : {'code':'BL','name':'Black River'}, + '3' : {'code':'BR','name':'Beau Bassin-Rose Hill'}, + '4' : {'code':'CC','name':'Cargados Carajos Shoals (Saint B)'}, + '5' : {'code':'CU','name':'Curepipe'}, + '6' : {'code':'FL','name':'Flacq'}, + '7' : {'code':'GP','name':'Grand Port'}, + '8' : {'code':'MO','name':'Moka'}, + '9' : {'code':'PA','name':'Pamplemousses'}, + '10' : {'code':'PL','name':'Port Louis'}, + '11' : {'code':'PU','name':'Port Louis'}, + '12' : {'code':'PW','name':'Plaines Wilhems'}, + '13' : {'code':'QB','name':'Quatre Bornes'}, + '14' : {'code':'RO','name':'Rodrigues'}, + '15' : {'code':'RR','name':'Riviere du Rempart'}, + '16' : {'code':'SA','name':'Savanne'}, + '17' : {'code':'VP','name':'Vacoas-Phoenix'} + }, + 'YT':{ + '1' : {'code':'DZA','name':'Dzaoudzi'}, + '2' : {'code':'PAM','name':'Pamandzi'}, + '3' : {'code':'MAM','name':'Mamoudzou'}, + '4' : {'code':'DEM','name':'Dembeni'}, + '5' : {'code':'BAN','name':'Bandrele'}, + '6' : {'code':'KAN','name':'Kani-Kéli'}, + '7' : {'code':'BOU','name':'Bouéni'}, + '8' : {'code':'CHI','name':'Chirongui'}, + '9' : {'code':'SAD','name':'Sada'}, + '10' : {'code':'OUA','name':'Ouangani'}, + '11' : {'code':'CHI','name':'Chiconi'}, + '12' : {'code':'TSI','name':'Tsingoni'}, + '13' : {'code':'MTS','name':'M\'Tsangamouji'}, + '14' : {'code':'ACO','name':'Acoua'}, + '15' : {'code':'MTS','name':'Mtsamboro'}, + '16' : {'code':'BAN','name':'Bandraboua'}, + '17' : {'code':'KOU','name':'Koungou'} + }, + 'MX':{ + '1' : {'code':'AGU','name':'Aguascalientes'}, + '2' : {'code':'BCN','name':'Baja California Norte'}, + '3' : {'code':'BCS','name':'Baja California Sur'}, + '4' : {'code':'CAM','name':'Campeche'}, + '5' : {'code':'CHP','name':'Chiapas'}, + '6' : {'code':'CHH','name':'Chihuahua'}, + '7' : {'code':'COA','name':'Coahuila de Zaragoza'}, + '8' : {'code':'COL','name':'Colima'}, + '9' : {'code':'DIF','name':'Distrito Federal'}, + '10' : {'code':'DUR','name':'Durango'}, + '11' : {'code':'GUA','name':'Guanajuato'}, + '12' : {'code':'GRO','name':'Guerrero'}, + '13' : {'code':'HID','name':'Hidalgo'}, + '14' : {'code':'JAL','name':'Jalisco'}, + '15' : {'code':'MEX','name':'Mexico'}, + '16' : {'code':'MIC','name':'Michoacan de Ocampo'}, + '17' : {'code':'MOR','name':'Morelos'}, + '18' : {'code':'NAY','name':'Nayarit'}, + '19' : {'code':'NLE','name':'Nuevo Leon'}, + '20' : {'code':'OAX','name':'Oaxaca'}, + '21' : {'code':'PUE','name':'Puebla'}, + '22' : {'code':'QUE','name':'Queretaro de Arteaga'}, + '23' : {'code':'ROO','name':'Quintana Roo'}, + '24' : {'code':'SLP','name':'San Luis Potosi'}, + '25' : {'code':'SIN','name':'Sinaloa'}, + '26' : {'code':'SON','name':'Sonora'}, + '27' : {'code':'TAB','name':'Tabasco'}, + '28' : {'code':'TAM','name':'Tamaulipas'}, + '29' : {'code':'TLA','name':'Tlaxcala'}, + '30' : {'code':'VER','name':'Veracruz-Llave'}, + '31' : {'code':'YUC','name':'Yucatan'}, + '32' : {'code':'ZAC','name':'Zacatecas'} + }, + 'FM':{ + '1' : {'code':'C','name':'Chuuk'}, + '2' : {'code':'K','name':'Kosrae'}, + '3' : {'code':'P','name':'Pohnpei'}, + '4' : {'code':'Y','name':'Yap'} + }, + 'MD':{ + '1' : {'code':'GA','name':'Gagauzia'}, + '2' : {'code':'CU','name':'Chisinau'}, + '3' : {'code':'BA','name':'Balti'}, + '4' : {'code':'CA','name':'Cahul'}, + '5' : {'code':'ED','name':'Edinet'}, + '6' : {'code':'LA','name':'Lapusna'}, + '7' : {'code':'OR','name':'Orhei'}, + '8' : {'code':'SO','name':'Soroca'}, + '9' : {'code':'TI','name':'Tighina'}, + '10' : {'code':'UN','name':'Ungheni'}, + '11' : {'code':'SN','name':'Stânga Nistrului'} + }, + 'MC':{ + '1' : {'code':'FV','name':'Fontvieille'}, + '2' : {'code':'LC','name':'La Condamine'}, + '3' : {'code':'MV','name':'Monaco-Ville'}, + '4' : {'code':'MC','name':'Monte-Carlo'} + }, + 'MN':{ + '1' : {'code':'1','name':'Ulanbaatar'}, + '2' : {'code':'035','name':'Orhon'}, + '3' : {'code':'037','name':'Darhan uul'}, + '4' : {'code':'039','name':'Hentiy'}, + '5' : {'code':'041','name':'Hovsgol'}, + '6' : {'code':'043','name':'Hovd'}, + '7' : {'code':'046','name':'Uvs'}, + '8' : {'code':'047','name':'Tov'}, + '9' : {'code':'049','name':'Selenge'}, + '10' : {'code':'051','name':'Suhbaatar'}, + '11' : {'code':'053','name':'Omnogovi'}, + '12' : {'code':'055','name':'Ovorhangay'}, + '13' : {'code':'057','name':'Dzavhan'}, + '14' : {'code':'059','name':'DundgovL'}, + '15' : {'code':'061','name':'Dornod'}, + '16' : {'code':'063','name':'Dornogov'}, + '17' : {'code':'064','name':'Govi-Sumber'}, + '18' : {'code':'065','name':'Govi-Altay'}, + '19' : {'code':'067','name':'Bulgan'}, + '20' : {'code':'069','name':'Bayanhongor'}, + '21' : {'code':'071','name':'Bayan-Olgiy'}, + '22' : {'code':'073','name':'Arhangay'} + }, + 'MS':{ + '1' : {'code':'A','name':'Saint Anthony'}, + '2' : {'code':'G','name':'Saint Georges'}, + '3' : {'code':'P','name':'Saint Peter'} + }, + 'MA':{ + '1' : {'code':'AGD','name':'Agadir'}, + '2' : {'code':'HOC','name':'Al Hoceima'}, + '3' : {'code':'AZI','name':'Azilal'}, + '4' : {'code':'BME','name':'Beni Mellal'}, + '5' : {'code':'BSL','name':'Ben Slimane'}, + '6' : {'code':'BLM','name':'Boulemane'}, + '7' : {'code':'CBL','name':'Casablanca'}, + '8' : {'code':'CHA','name':'Chaouen'}, + '9' : {'code':'EJA','name':'El Jadida'}, + '10' : {'code':'EKS','name':'El Kelaa des Sraghna'}, + '11' : {'code':'ERA','name':'Er Rachidia'}, + '12' : {'code':'ESS','name':'Essaouira'}, + '13' : {'code':'FES','name':'Fes'}, + '14' : {'code':'FIG','name':'Figuig'}, + '15' : {'code':'GLM','name':'Guelmim'}, + '16' : {'code':'IFR','name':'Ifrane'}, + '17' : {'code':'KEN','name':'Kenitra'}, + '18' : {'code':'KHM','name':'Khemisset'}, + '19' : {'code':'KHN','name':'Khenifra'}, + '20' : {'code':'KHO','name':'Khouribga'}, + '21' : {'code':'LYN','name':'Laayoune'}, + '22' : {'code':'LAR','name':'Larache'}, + '23' : {'code':'MRK','name':'Marrakech'}, + '24' : {'code':'MKN','name':'Meknes'}, + '25' : {'code':'NAD','name':'Nador'}, + '26' : {'code':'ORZ','name':'Ouarzazate'}, + '27' : {'code':'OUJ','name':'Oujda'}, + '28' : {'code':'RSA','name':'Rabat-Sale'}, + '29' : {'code':'SAF','name':'Safi'}, + '30' : {'code':'SET','name':'Settat'}, + '31' : {'code':'SKA','name':'Sidi Kacem'}, + '32' : {'code':'TGR','name':'Tangier'}, + '33' : {'code':'TAN','name':'Tan-Tan'}, + '34' : {'code':'TAO','name':'Taounate'}, + '35' : {'code':'TRD','name':'Taroudannt'}, + '36' : {'code':'TAT','name':'Tata'}, + '37' : {'code':'TAZ','name':'Taza'}, + '38' : {'code':'TET','name':'Tetouan'}, + '39' : {'code':'TIZ','name':'Tiznit'}, + '40' : {'code':'ADK','name':'Ad Dakhla'}, + '41' : {'code':'BJD','name':'Boujdour'}, + '42' : {'code':'ESM','name':'Es Smara'} + }, + 'MZ':{ + '1' : {'code':'CD','name':'Cabo Delgado'}, + '2' : {'code':'GZ','name':'Gaza'}, + '3' : {'code':'IN','name':'Inhambane'}, + '4' : {'code':'MN','name':'Manica'}, + '5' : {'code':'MC','name':'Maputo (city)'}, + '6' : {'code':'MP','name':'Maputo'}, + '7' : {'code':'NA','name':'Nampula'}, + '8' : {'code':'NI','name':'Niassa'}, + '9' : {'code':'SO','name':'Sofala'}, + '10' : {'code':'TE','name':'Tete'}, + '11' : {'code':'ZA','name':'Zambezia'} + }, + 'MM':{ + '1' : {'code':'AY','name':'Ayeyarwady'}, + '2' : {'code':'BG','name':'Bago'}, + '3' : {'code':'MG','name':'Magway'}, + '4' : {'code':'MD','name':'Mandalay'}, + '5' : {'code':'SG','name':'Sagaing'}, + '6' : {'code':'TN','name':'Tanintharyi'}, + '7' : {'code':'YG','name':'Yangon'}, + '8' : {'code':'CH','name':'Chin State'}, + '9' : {'code':'KC','name':'Kachin State'}, + '10' : {'code':'KH','name':'Kayah State'}, + '11' : {'code':'KN','name':'Kayin State'}, + '12' : {'code':'MN','name':'Mon State'}, + '13' : {'code':'RK','name':'Rakhine State'}, + '14' : {'code':'SH','name':'Shan State'} + }, + 'NA':{ + '1' : {'code':'CA','name':'Caprivi'}, + '2' : {'code':'ER','name':'Erongo'}, + '3' : {'code':'HA','name':'Hardap'}, + '4' : {'code':'KR','name':'Karas'}, + '5' : {'code':'KV','name':'Kavango'}, + '6' : {'code':'KH','name':'Khomas'}, + '7' : {'code':'KU','name':'Kunene'}, + '8' : {'code':'OW','name':'Ohangwena'}, + '9' : {'code':'OK','name':'Omaheke'}, + '10' : {'code':'OT','name':'Omusati'}, + '11' : {'code':'ON','name':'Oshana'}, + '12' : {'code':'OO','name':'Oshikoto'}, + '13' : {'code':'OJ','name':'Otjozondjupa'} + }, + 'NR':{ + '1' : {'code':'AO','name':'Aiwo'}, + '2' : {'code':'AA','name':'Anabar'}, + '3' : {'code':'AT','name':'Anetan'}, + '4' : {'code':'AI','name':'Anibare'}, + '5' : {'code':'BA','name':'Baiti'}, + '6' : {'code':'BO','name':'Boe'}, + '7' : {'code':'BU','name':'Buada'}, + '8' : {'code':'DE','name':'Denigomodu'}, + '9' : {'code':'EW','name':'Ewa'}, + '10' : {'code':'IJ','name':'Ijuw'}, + '11' : {'code':'ME','name':'Meneng'}, + '12' : {'code':'NI','name':'Nibok'}, + '13' : {'code':'UA','name':'Uaboe'}, + '14' : {'code':'YA','name':'Yaren'} + }, + 'NP':{ + '1' : {'code':'BA','name':'Bagmati'}, + '2' : {'code':'BH','name':'Bheri'}, + '3' : {'code':'DH','name':'Dhawalagiri'}, + '4' : {'code':'GA','name':'Gandaki'}, + '5' : {'code':'JA','name':'Janakpur'}, + '6' : {'code':'KA','name':'Karnali'}, + '7' : {'code':'KO','name':'Kosi'}, + '8' : {'code':'LU','name':'Lumbini'}, + '9' : {'code':'MA','name':'Mahakali'}, + '10' : {'code':'ME','name':'Mechi'}, + '11' : {'code':'NA','name':'Narayani'}, + '12' : {'code':'RA','name':'Rapti'}, + '13' : {'code':'SA','name':'Sagarmatha'}, + '14' : {'code':'SE','name':'Seti'} + }, + 'NL':{ + '1' : {'code':'DR','name':'Drenthe'}, + '2' : {'code':'FL','name':'Flevoland'}, + '3' : {'code':'FR','name':'Friesland'}, + '4' : {'code':'GE','name':'Gelderland'}, + '5' : {'code':'GR','name':'Groningen'}, + '6' : {'code':'LI','name':'Limburg'}, + '7' : {'code':'NB','name':'Noord Brabant'}, + '8' : {'code':'NH','name':'Noord Holland'}, + '9' : {'code':'OV','name':'Overijssel'}, + '10' : {'code':'UT','name':'Utrecht'}, + '11' : {'code':'ZE','name':'Zeeland'}, + '12' : {'code':'ZH','name':'Zuid Holland'} + }, + 'AN':{ + '1' : {'code':'BON','name':'Bonaire'}, + '2' : {'code':'CUR','name':'Curaçao'}, + '3' : {'code':'SAB','name':'Saba'}, + '4' : {'code':'SEU','name':'Sint Eustatius'}, + '5' : {'code':'SMA','name':'Sint Maarten'} + }, + 'NC':{ + '1' : {'code':'L','name':'Iles Loyaute'}, + '2' : {'code':'N','name':'Nord'}, + '3' : {'code':'S','name':'Sud'} + }, + 'NZ':{ + '1' : {'code':'AUK','name':'Auckland'}, + '2' : {'code':'BOP','name':'Bay of Plenty'}, + '3' : {'code':'CAN','name':'Canterbury'}, + '4' : {'code':'COR','name':'Coromandel'}, + '5' : {'code':'GIS','name':'Gisborne'}, + '6' : {'code':'FIO','name':'Fiordland'}, + '7' : {'code':'HKB','name':'Hawke\'s Bay'}, + '8' : {'code':'MBH','name':'Marlborough'}, + '9' : {'code':'MWT','name':'Manawatu-Wanganui'}, + '10' : {'code':'MCM','name':'Mt Cook-Mackenzie'}, + '11' : {'code':'NSN','name':'Nelson'}, + '12' : {'code':'NTL','name':'Northland'}, + '13' : {'code':'OTA','name':'Otago'}, + '14' : {'code':'STL','name':'Southland'}, + '15' : {'code':'TKI','name':'Taranaki'}, + '16' : {'code':'WGN','name':'Wellington'}, + '17' : {'code':'WKO','name':'Waikato'}, + '18' : {'code':'WAI','name':'Wairprarapa'}, + '19' : {'code':'WTC','name':'West Coast'} + }, + 'NI':{ + '1' : {'code':'AN','name':'Atlantico Norte'}, + '2' : {'code':'AS','name':'Atlantico Sur'}, + '3' : {'code':'BO','name':'Boaco'}, + '4' : {'code':'CA','name':'Carazo'}, + '5' : {'code':'CI','name':'Chinandega'}, + '6' : {'code':'CO','name':'Chontales'}, + '7' : {'code':'ES','name':'Esteli'}, + '8' : {'code':'GR','name':'Granada'}, + '9' : {'code':'JI','name':'Jinotega'}, + '10' : {'code':'LE','name':'Leon'}, + '11' : {'code':'MD','name':'Madriz'}, + '12' : {'code':'MN','name':'Managua'}, + '13' : {'code':'MS','name':'Masaya'}, + '14' : {'code':'MT','name':'Matagalpa'}, + '15' : {'code':'NS','name':'Nuevo Segovia'}, + '16' : {'code':'RS','name':'Rio San Juan'}, + '17' : {'code':'RI','name':'Rivas'} + }, + 'NE':{ + '1' : {'code':'AG','name':'Agadez'}, + '2' : {'code':'DF','name':'Diffa'}, + '3' : {'code':'DS','name':'Dosso'}, + '4' : {'code':'MA','name':'Maradi'}, + '5' : {'code':'NM','name':'Niamey'}, + '6' : {'code':'TH','name':'Tahoua'}, + '7' : {'code':'TL','name':'Tillaberi'}, + '8' : {'code':'ZD','name':'Zinder'} + }, + 'NG':{ + '1' : {'code':'AB','name':'Abia'}, + '2' : {'code':'CT','name':'Abuja Federal Capital Territory'}, + '3' : {'code':'AD','name':'Adamawa'}, + '4' : {'code':'AK','name':'Akwa Ibom'}, + '5' : {'code':'AN','name':'Anambra'}, + '6' : {'code':'BC','name':'Bauchi'}, + '7' : {'code':'BY','name':'Bayelsa'}, + '8' : {'code':'BN','name':'Benue'}, + '9' : {'code':'BO','name':'Borno'}, + '10' : {'code':'CR','name':'Cross River'}, + '11' : {'code':'DE','name':'Delta'}, + '12' : {'code':'EB','name':'Ebonyi'}, + '13' : {'code':'ED','name':'Edo'}, + '14' : {'code':'EK','name':'Ekiti'}, + '15' : {'code':'EN','name':'Enugu'}, + '16' : {'code':'GO','name':'Gombe'}, + '17' : {'code':'IM','name':'Imo'}, + '18' : {'code':'JI','name':'Jigawa'}, + '19' : {'code':'KD','name':'Kaduna'}, + '20' : {'code':'KN','name':'Kano'}, + '21' : {'code':'KT','name':'Katsina'}, + '22' : {'code':'KE','name':'Kebbi'}, + '23' : {'code':'KO','name':'Kogi'}, + '24' : {'code':'KW','name':'Kwara'}, + '25' : {'code':'LA','name':'Lagos'}, + '26' : {'code':'NA','name':'Nassarawa'}, + '27' : {'code':'NI','name':'Niger'}, + '28' : {'code':'OG','name':'Ogun'}, + '29' : {'code':'ONG','name':'Ondo'}, + '30' : {'code':'OS','name':'Osun'}, + '31' : {'code':'OY','name':'Oyo'}, + '32' : {'code':'PL','name':'Plateau'}, + '33' : {'code':'RI','name':'Rivers'}, + '34' : {'code':'SO','name':'Sokoto'}, + '35' : {'code':'TA','name':'Taraba'}, + '36' : {'code':'YO','name':'Yobe'}, + '37' : {'code':'ZA','name':'Zamfara'} + }, + 'NU':{ + '1' : {'code':'MAK','name':'Makefu'}, + '2' : {'code':'TUA','name':'Tuapa'}, + '3' : {'code':'NAM','name':'Namukulu'}, + '4' : {'code':'HIK','name':'Hikutavake'}, + '5' : {'code':'TOI','name':'Toi'}, + '6' : {'code':'MUT','name':'Mutalau'}, + '7' : {'code':'LAK','name':'Lakepa'}, + '8' : {'code':'LIK','name':'Liku'}, + '9' : {'code':'HAK','name':'Hakupu'}, + '10' : {'code':'VAI','name':'Vaiea'}, + '11' : {'code':'AVA','name':'Avatele'}, + '12' : {'code':'TAM','name':'Tamakautoga'}, + '13' : {'code':'ALO','name':'Alofi South'}, + '14' : {'code':'ALO','name':'Alofi North'} + }, + 'NF':{ + '1' : {'code':'NOR','name':'Norfolk Island'} + }, + 'MP':{ + '1' : {'code':'N','name':'Northern Islands'}, + '2' : {'code':'R','name':'Rota'}, + '3' : {'code':'S','name':'Saipan'}, + '4' : {'code':'T','name':'Tinian'} + }, + 'NO':{ + '1' : {'code':'AK','name':'Akershus'}, + '2' : {'code':'AA','name':'Aust-Agder'}, + '3' : {'code':'BU','name':'Buskerud'}, + '4' : {'code':'FM','name':'Finnmark'}, + '5' : {'code':'HM','name':'Hedmark'}, + '6' : {'code':'HL','name':'Hordaland'}, + '7' : {'code':'MR','name':'Møre og Romsdal'}, + '8' : {'code':'NL','name':'Nordland'}, + '9' : {'code':'NT','name':'Nord-Trøndelag'}, + '10' : {'code':'OP','name':'Oppland'}, + '11' : {'code':'OL','name':'Oslo'}, + '12' : {'code':'RL','name':'Rogaland'}, + '13' : {'code':'SJ','name':'Sogn og Fjordane'}, + '14' : {'code':'ST','name':'Sør-Trøndelag'}, + '15' : {'code':'SV','name':'Svalbard'}, + '16' : {'code':'TM','name':'Telemark'}, + '17' : {'code':'TR','name':'Troms'}, + '18' : {'code':'VA','name':'Vest-Agder'}, + '19' : {'code':'VF','name':'Vestfold'}, + '20' : {'code':'OF','name':'Østfold'} + }, + 'OM':{ + '1' : {'code':'DA','name':'Ad Dakhiliyah'}, + '2' : {'code':'BA','name':'Al Batinah'}, + '3' : {'code':'WU','name':'Al Wusta'}, + '4' : {'code':'SH','name':'Ash Sharqiyah'}, + '5' : {'code':'ZA','name':'Az Zahirah'}, + '6' : {'code':'MA','name':'Masqat'}, + '7' : {'code':'MU','name':'Musandam'}, + '8' : {'code':'ZU','name':'Zufar'} + }, + 'PK':{ + '1' : {'code':'B','name':'Balochistan'}, + '2' : {'code':'T','name':'Federally Administered Tribal Ar'}, + '3' : {'code':'I','name':'Islamabad Capital Territory'}, + '4' : {'code':'N','name':'North-West Frontier'}, + '5' : {'code':'P','name':'Punjab'}, + '6' : {'code':'S','name':'Sindh'} + }, + 'PW':{ + '1' : {'code':'AM','name':'Aimeliik'}, + '2' : {'code':'AR','name':'Airai'}, + '3' : {'code':'AN','name':'Angaur'}, + '4' : {'code':'HA','name':'Hatohobei'}, + '5' : {'code':'KA','name':'Kayangel'}, + '6' : {'code':'KO','name':'Koror'}, + '7' : {'code':'ME','name':'Melekeok'}, + '8' : {'code':'NA','name':'Ngaraard'}, + '9' : {'code':'NG','name':'Ngarchelong'}, + '10' : {'code':'ND','name':'Ngardmau'}, + '11' : {'code':'NT','name':'Ngatpang'}, + '12' : {'code':'NC','name':'Ngchesar'}, + '13' : {'code':'NR','name':'Ngeremlengui'}, + '14' : {'code':'NW','name':'Ngiwal'}, + '15' : {'code':'PE','name':'Peleliu'}, + '16' : {'code':'SO','name':'Sonsorol'} + }, + 'PA':{ + '1' : {'code':'BT','name':'Bocas del Toro'}, + '2' : {'code':'CH','name':'Chiriqui'}, + '3' : {'code':'CC','name':'Cocle'}, + '4' : {'code':'CL','name':'Colon'}, + '5' : {'code':'DA','name':'Darien'}, + '6' : {'code':'HE','name':'Herrera'}, + '7' : {'code':'LS','name':'Los Santos'}, + '8' : {'code':'PA','name':'Panama'}, + '9' : {'code':'SB','name':'San Blas'}, + '10' : {'code':'VG','name':'Veraguas'} + }, + 'PG':{ + '1' : {'code':'BV','name':'Bougainville'}, + '2' : {'code':'CE','name':'Central'}, + '3' : {'code':'CH','name':'Chimbu'}, + '4' : {'code':'EH','name':'Eastern Highlands'}, + '5' : {'code':'EB','name':'East New Britain'}, + '6' : {'code':'ES','name':'East Sepik'}, + '7' : {'code':'EN','name':'Enga'}, + '8' : {'code':'GU','name':'Gulf'}, + '9' : {'code':'MD','name':'Madang'}, + '10' : {'code':'MN','name':'Manus'}, + '11' : {'code':'MB','name':'Milne Bay'}, + '12' : {'code':'MR','name':'Morobe'}, + '13' : {'code':'NC','name':'National Capital'}, + '14' : {'code':'NI','name':'New Ireland'}, + '15' : {'code':'NO','name':'Northern'}, + '16' : {'code':'SA','name':'Sandaun'}, + '17' : {'code':'SH','name':'Southern Highlands'}, + '18' : {'code':'WE','name':'Western'}, + '19' : {'code':'WH','name':'Western Highlands'}, + '20' : {'code':'WB','name':'West New Britain'} + }, + 'PY':{ + '1' : {'code':'AG','name':'Alto Paraguay'}, + '2' : {'code':'AN','name':'Alto Parana'}, + '3' : {'code':'AM','name':'Amambay'}, + '4' : {'code':'AS','name':'Asuncion'}, + '5' : {'code':'BO','name':'Boqueron'}, + '6' : {'code':'CG','name':'Caaguazu'}, + '7' : {'code':'CZ','name':'Caazapa'}, + '8' : {'code':'CN','name':'Canindeyu'}, + '9' : {'code':'CE','name':'Central'}, + '10' : {'code':'CC','name':'Concepcion'}, + '11' : {'code':'CD','name':'Cordillera'}, + '12' : {'code':'GU','name':'Guaira'}, + '13' : {'code':'IT','name':'Itapua'}, + '14' : {'code':'MI','name':'Misiones'}, + '15' : {'code':'NE','name':'Neembucu'}, + '16' : {'code':'PA','name':'Paraguari'}, + '17' : {'code':'PH','name':'Presidente Hayes'}, + '18' : {'code':'SP','name':'San Pedro'} + }, + 'PE':{ + '1' : {'code':'AM','name':'Amazonas'}, + '2' : {'code':'AN','name':'Ancash'}, + '3' : {'code':'AP','name':'Apurimac'}, + '4' : {'code':'AR','name':'Arequipa'}, + '5' : {'code':'AY','name':'Ayacucho'}, + '6' : {'code':'CJ','name':'Cajamarca'}, + '7' : {'code':'CL','name':'Callao'}, + '8' : {'code':'CU','name':'Cusco'}, + '9' : {'code':'HV','name':'Huancavelica'}, + '10' : {'code':'HO','name':'Huanuco'}, + '11' : {'code':'IC','name':'Ica'}, + '12' : {'code':'JU','name':'Junin'}, + '13' : {'code':'LD','name':'La Libertad'}, + '14' : {'code':'LY','name':'Lambayeque'}, + '15' : {'code':'LI','name':'Lima'}, + '16' : {'code':'LO','name':'Loreto'}, + '17' : {'code':'MD','name':'Madre de Dios'}, + '18' : {'code':'MO','name':'Moquegua'}, + '19' : {'code':'PA','name':'Pasco'}, + '20' : {'code':'PI','name':'Piura'}, + '21' : {'code':'PU','name':'Puno'}, + '22' : {'code':'SM','name':'San Martin'}, + '23' : {'code':'TA','name':'Tacna'}, + '24' : {'code':'TU','name':'Tumbes'}, + '25' : {'code':'UC','name':'Ucayali'} + }, + 'PH':{ + '1' : {'code':'ABR','name':'Abra'}, + '2' : {'code':'ANO','name':'Agusan del Norte'}, + '3' : {'code':'ASU','name':'Agusan del Sur'}, + '4' : {'code':'AKL','name':'Aklan'}, + '5' : {'code':'ALB','name':'Albay'}, + '6' : {'code':'ANT','name':'Antique'}, + '7' : {'code':'APY','name':'Apayao'}, + '8' : {'code':'AUR','name':'Aurora'}, + '9' : {'code':'BAS','name':'Basilan'}, + '10' : {'code':'BTA','name':'Bataan'}, + '11' : {'code':'BTE','name':'Batanes'}, + '12' : {'code':'BTG','name':'Batangas'}, + '13' : {'code':'BLR','name':'Biliran'}, + '14' : {'code':'BEN','name':'Benguet'}, + '15' : {'code':'BOL','name':'Bohol'}, + '16' : {'code':'BUK','name':'Bukidnon'}, + '17' : {'code':'BUL','name':'Bulacan'}, + '18' : {'code':'CAG','name':'Cagayan'}, + '19' : {'code':'CNO','name':'Camarines Norte'}, + '20' : {'code':'CSU','name':'Camarines Sur'}, + '21' : {'code':'CAM','name':'Camiguin'}, + '22' : {'code':'CAP','name':'Capiz'}, + '23' : {'code':'CAT','name':'Catanduanes'}, + '24' : {'code':'CAV','name':'Cavite'}, + '25' : {'code':'CEB','name':'Cebu'}, + '26' : {'code':'CMP','name':'Compostela'}, + '27' : {'code':'DNO','name':'Davao del Norte'}, + '28' : {'code':'DSU','name':'Davao del Sur'}, + '29' : {'code':'DOR','name':'Davao Oriental'}, + '30' : {'code':'ESA','name':'Eastern Samar'}, + '31' : {'code':'GUI','name':'Guimaras'}, + '32' : {'code':'IFU','name':'Ifugao'}, + '33' : {'code':'INO','name':'Ilocos Norte'}, + '34' : {'code':'ISU','name':'Ilocos Sur'}, + '35' : {'code':'ILO','name':'Iloilo'}, + '36' : {'code':'ISA','name':'Isabela'}, + '37' : {'code':'KAL','name':'Kalinga'}, + '38' : {'code':'LAG','name':'Laguna'}, + '39' : {'code':'LNO','name':'Lanao del Norte'}, + '40' : {'code':'LSU','name':'Lanao del Sur'}, + '41' : {'code':'UNI','name':'La Union'}, + '42' : {'code':'LEY','name':'Leyte'}, + '43' : {'code':'MAG','name':'Maguindanao'}, + '44' : {'code':'MRN','name':'Marinduque'}, + '45' : {'code':'MSB','name':'Masbate'}, + '46' : {'code':'MIC','name':'Mindoro Occidental'}, + '47' : {'code':'MIR','name':'Mindoro Oriental'}, + '48' : {'code':'MSC','name':'Misamis Occidental'}, + '49' : {'code':'MOR','name':'Misamis Oriental'}, + '50' : {'code':'MOP','name':'Mountain'}, + '51' : {'code':'NOC','name':'Negros Occidental'}, + '52' : {'code':'NOR','name':'Negros Oriental'}, + '53' : {'code':'NCT','name':'North Cotabato'}, + '54' : {'code':'NSM','name':'Northern Samar'}, + '55' : {'code':'NEC','name':'Nueva Ecija'}, + '56' : {'code':'NVZ','name':'Nueva Vizcaya'}, + '57' : {'code':'PLW','name':'Palawan'}, + '58' : {'code':'PMP','name':'Pampanga'}, + '59' : {'code':'PNG','name':'Pangasinan'}, + '60' : {'code':'QZN','name':'Quezon'}, + '61' : {'code':'QRN','name':'Quirino'}, + '62' : {'code':'RIZ','name':'Rizal'}, + '63' : {'code':'ROM','name':'Romblon'}, + '64' : {'code':'SMR','name':'Samar'}, + '65' : {'code':'SRG','name':'Sarangani'}, + '66' : {'code':'SQJ','name':'Siquijor'}, + '67' : {'code':'SRS','name':'Sorsogon'}, + '68' : {'code':'SCO','name':'South Cotabato'}, + '69' : {'code':'SLE','name':'Southern Leyte'}, + '70' : {'code':'SKU','name':'Sultan Kudarat'}, + '71' : {'code':'SLU','name':'Sulu'}, + '72' : {'code':'SNO','name':'Surigao del Norte'}, + '73' : {'code':'SSU','name':'Surigao del Sur'}, + '74' : {'code':'TAR','name':'Tarlac'}, + '75' : {'code':'TAW','name':'Tawi-Tawi'}, + '76' : {'code':'ZBL','name':'Zambales'}, + '77' : {'code':'ZNO','name':'Zamboanga del Norte'}, + '78' : {'code':'ZSU','name':'Zamboanga del Sur'}, + '79' : {'code':'ZSI','name':'Zamboanga Sibugay'} + }, + 'PN':{ + '1' : {'code':'PIT','name':'Pitcairn Island'} + }, + 'PL':{ + '1': {'code':'DO','name':'Dolnośląskie'}, + '2' : {'code':'KP','name':'Kujawsko-Pomorskie'}, + '3': {'code':'LL','name':'Lubelskie'}, + '4': {'code':'LU','name':'Lubuskie'}, + '5': {'code':'LO','name':'Łódzkie'}, + '6': {'code':'ML','name':'Małopolskie'}, + '7' : {'code':'MZ','name':'Mazowieckie'}, + '8' : {'code':'OP','name':'Opolskie'}, + '9' : {'code':'PP','name':'Podkarpackie'}, + '10' : {'code':'PL','name':'Podlaskie'}, + '11' : {'code':'PM','name':'Pomorskie'}, + '12': {'code':'SL','name':'Śląskie'}, + '13': {'code':'SW','name':'Świętokrzyskie'}, + '14': {'code':'WM','name':'Warmińsko-Mazurskie'}, + '15' : {'code':'WP','name':'Wielkopolskie'}, + '16' : {'code':'ZA','name':'Zachodniopomorskie'} + }, + 'PT':{ + '1' : {'code':'AC','name':'Açores'}, + '2' : {'code':'AV','name':'Aveiro'}, + '3' : {'code':'BE','name':'Beja'}, + '4' : {'code':'BR','name':'Braga'}, + '5' : {'code':'BA','name':'Bragança'}, + '6' : {'code':'CB','name':'Castelo Branco'}, + '7' : {'code':'CO','name':'Coimbra'}, + '8' : {'code':'EV','name':'évora'}, + '9' : {'code':'FA','name':'Faro'}, + '10' : {'code':'GU','name':'Guarda'}, + '12' : {'code':'LE','name':'Leiria'}, + '13' : {'code':'LI','name':'Lisboa'}, + '14' : {'code':'ME','name':'Madeira'}, + '15' : {'code':'PO','name':'Portalegre'}, + '16' : {'code':'PR','name':'Porto'}, + '17' : {'code':'SA','name':'Santarém'}, + '18' : {'code':'SE','name':'SetÚbal'}, + '19' : {'code':'VC','name':'Viana do Castelo'}, + '20' : {'code':'VR','name':'Vila Real'}, + '21' : {'code':'VI','name':'Viseu'} + }, + 'PR':{ + '1' : {'code':'A-A','name':'Añasco'}, + '2' : {'code':'ADJ','name':'Adjuntas'}, + '3' : {'code':'AGU','name':'Aguada'}, + '4' : {'code':'AGU','name':'Aguadilla'}, + '5' : {'code':'AGU','name':'Aguas Buenas'}, + '6' : {'code':'AIB','name':'Aibonito'}, + '7' : {'code':'ARE','name':'Arecibo'}, + '8' : {'code':'ARR','name':'Arroyo'}, + '9' : {'code':'BAR','name':'Barceloneta'}, + '10' : {'code':'BAR','name':'Barranquitas'}, + '11' : {'code':'BAY','name':'Bayamón'}, + '12' : {'code':'CAB','name':'Cabo Rojo'}, + '13' : {'code':'CAG','name':'Caguas'}, + '14' : {'code':'CAM','name':'Camuy'}, + '15' : {'code':'CAN','name':'Canóvanas'}, + '16' : {'code':'CAR','name':'Carolina'}, + '17' : {'code':'CAT','name':'Cataño'}, + '18' : {'code':'CAY','name':'Cayey'}, + '19' : {'code':'CEI','name':'Ceiba'}, + '20' : {'code':'CIA','name':'Ciales'}, + '21' : {'code':'CID','name':'Cidra'}, + '22' : {'code':'COA','name':'Coamo'}, + '23' : {'code':'COM','name':'Comerío'}, + '24' : {'code':'COR','name':'Corozal'}, + '25' : {'code':'CUL','name':'Culebra'}, + '26' : {'code':'DOR','name':'Dorado'}, + '27' : {'code':'FAJ','name':'Fajardo'}, + '28' : {'code':'FLO','name':'Florida'}, + '29' : {'code':'GUA','name':'Guayama'}, + '30' : {'code':'GUA','name':'Guayanilla'}, + '31' : {'code':'GUA','name':'Guaynabo'}, + '32' : {'code':'GUR','name':'Gurabo'}, + '33' : {'code':'GU¡','name':'Guánica'}, + '34' : {'code':'HAT','name':'Hatillo'}, + '35' : {'code':'HOR','name':'Hormigueros'}, + '36' : {'code':'HUM','name':'Humacao'}, + '37' : {'code':'ISA','name':'Isabela'}, + '38' : {'code':'JAY','name':'Jayuya'}, + '39' : {'code':'JUA','name':'Juana Díaz'}, + '40' : {'code':'JUN','name':'Juncos'}, + '41' : {'code':'LAJ','name':'Lajas'}, + '42' : {'code':'LAR','name':'Lares'}, + '43' : {'code':'LAS','name':'Las Marías'}, + '44' : {'code':'LAS','name':'Las Piedras'}, + '45' : {'code':'LOÕ','name':'Loíza'}, + '46' : {'code':'LUQ','name':'Luquillo'}, + '47' : {'code':'MAN','name':'Manatí'}, + '48' : {'code':'MAR','name':'Maricao'}, + '49' : {'code':'MAU','name':'Maunabo'}, + '50' : {'code':'MAY','name':'Mayagüez'}, + '51' : {'code':'MOC','name':'Moca'}, + '52' : {'code':'MOR','name':'Morovis'}, + '53' : {'code':'NAG','name':'Naguabo'}, + '54' : {'code':'NAR','name':'Naranjito'}, + '55' : {'code':'ORO','name':'Orocovis'}, + '56' : {'code':'PAT','name':'Patillas'}, + '57' : {'code':'PE-','name':'Peñuelas'}, + '58' : {'code':'PON','name':'Ponce'}, + '59' : {'code':'QUE','name':'Quebradillas'}, + '60' : {'code':'RIN','name':'Rincón'}, + '61' : {'code':'RIO','name':'Rio Grande'}, + '62' : {'code':'SAB','name':'Sabana Grande'}, + '63' : {'code':'SAL','name':'Salinas'}, + '64' : {'code':'SAN','name':'San Germàn'}, + '65' : {'code':'SAN','name':'San Juan'}, + '66' : {'code':'SAN','name':'San Lorenzo'}, + '67' : {'code':'SAN','name':'San Sebastiàn'}, + '68' : {'code':'SAN','name':'Santa Isabel'}, + '69' : {'code':'TOA','name':'Toa Alta'}, + '70' : {'code':'TOA','name':'Toa Baja'}, + '71' : {'code':'TRU','name':'Trujillo Alto'}, + '72' : {'code':'UTU','name':'Utuado'}, + '73' : {'code':'VEG','name':'Vega Alta'}, + '74' : {'code':'VEG','name':'Vega Baja'}, + '75' : {'code':'VIE','name':'Vieques'}, + '76' : {'code':'VIL','name':'Villalba'}, + '77' : {'code':'YAB','name':'Yabucoa'}, + '78' : {'code':'YAU','name':'Yauco'} + }, + 'QA':{ + '1' : {'code':'DW','name':'Ad Dawhah'}, + '2' : {'code':'GW','name':'Al Ghuwayriyah'}, + '3' : {'code':'JM','name':'Al Jumayliyah'}, + '4' : {'code':'KR','name':'Al Khawr'}, + '5' : {'code':'WK','name':'Al Wakrah'}, + '6' : {'code':'RN','name':'Ar Rayyan'}, + '7' : {'code':'JB','name':'Jarayan al Batinah'}, + '8' : {'code':'MS','name':'Madinat ash Shamal'}, + '9' : {'code':'UD','name':'Umm Sa\'id'}, + '10' : {'code':'UL','name':'Umm Salal'} + }, + 'RO':{ + '1' : {'code':'AB','name':'Alba'}, + '2' : {'code':'AR','name':'Arad'}, + '3' : {'code':'AG','name':'Arges'}, + '4' : {'code':'BC','name':'Bacau'}, + '5' : {'code':'BH','name':'Bihor'}, + '6' : {'code':'BN','name':'Bistrita-Nasaud'}, + '7' : {'code':'BT','name':'Botosani'}, + '8' : {'code':'BV','name':'Brasov'}, + '9' : {'code':'BR','name':'Braila'}, + '10' : {'code':'B','name':'Bucuresti'}, + '11' : {'code':'BZ','name':'Buzau'}, + '12' : {'code':'CS','name':'Caras-Severin'}, + '13' : {'code':'CL','name':'Calarasi'}, + '14' : {'code':'CJ','name':'Cluj'}, + '15' : {'code':'CT','name':'Constanta'}, + '16' : {'code':'CV','name':'Covasna'}, + '17' : {'code':'DB','name':'Dimbovita'}, + '18' : {'code':'DJ','name':'Dolj'}, + '19' : {'code':'GL','name':'Galati'}, + '20' : {'code':'GR','name':'Giurgiu'}, + '21' : {'code':'GJ','name':'Gorj'}, + '22' : {'code':'HR','name':'Harghita'}, + '23' : {'code':'HD','name':'Hunedoara'}, + '24' : {'code':'IL','name':'Ialomita'}, + '25' : {'code':'IS','name':'Iasi'}, + '26' : {'code':'IF','name':'Ilfov'}, + '27' : {'code':'MM','name':'Maramures'}, + '28' : {'code':'MH','name':'Mehedinti'}, + '29' : {'code':'MS','name':'Mures'}, + '30' : {'code':'NT','name':'Neamt'}, + '31' : {'code':'OT','name':'Olt'}, + '32' : {'code':'PH','name':'Prahova'}, + '33' : {'code':'SM','name':'Satu-Mare'}, + '34' : {'code':'SJ','name':'Salaj'}, + '35' : {'code':'SB','name':'Sibiu'}, + '36' : {'code':'SV','name':'Suceava'}, + '37' : {'code':'TR','name':'Teleorman'}, + '38' : {'code':'TM','name':'Timis'}, + '39' : {'code':'TL','name':'Tulcea'}, + '40' : {'code':'VS','name':'Vaslui'}, + '41' : {'code':'VL','name':'Valcea'}, + '42' : {'code':'VN','name':'Vrancea'} + }, + 'RU':{ + '1' : {'code':'AB','name':'Abakan'}, + '2' : {'code':'AG','name':'Aginskoye'}, + '3' : {'code':'AN','name':'Anadyr'}, + '4' : {'code':'AR','name':'Arkahangelsk'}, + '5' : {'code':'AS','name':'Astrakhan'}, + '6' : {'code':'BA','name':'Barnaul'}, + '7' : {'code':'BE','name':'Belgorod'}, + '8' : {'code':'BI','name':'Birobidzhan'}, + '9' : {'code':'BL','name':'Blagoveshchensk'}, + '10' : {'code':'BR','name':'Bryansk'}, + '11' : {'code':'CH','name':'Cheboksary'}, + '12' : {'code':'CL','name':'Chelyabinsk'}, + '13' : {'code':'CR','name':'Cherkessk'}, + '14' : {'code':'CI','name':'Chita'}, + '15' : {'code':'DU','name':'Dudinka'}, + '16' : {'code':'EL','name':'Elista'}, + '17' : {'code':'GO','name':'Gomo-Altaysk'}, + '18' : {'code':'GA','name':'Gorno-Altaysk'}, + '19' : {'code':'GR','name':'Groznyy'}, + '20' : {'code':'IR','name':'Irkutsk'}, + '21' : {'code':'IV','name':'Ivanovo'}, + '22' : {'code':'IZ','name':'Izhevsk'}, + '23' : {'code':'KA','name':'Kalinigrad'}, + '24' : {'code':'KL','name':'Kaluga'}, + '25' : {'code':'KS','name':'Kasnodar'}, + '26' : {'code':'KZ','name':'Kazan'}, + '27' : {'code':'KE','name':'Kemerovo'}, + '28' : {'code':'KH','name':'Khabarovsk'}, + '29' : {'code':'KM','name':'Khanty-Mansiysk'}, + '30' : {'code':'KO','name':'Kostroma'}, + '31' : {'code':'KR','name':'Krasnodar'}, + '32' : {'code':'KN','name':'Krasnoyarsk'}, + '33' : {'code':'KU','name':'Kudymkar'}, + '34' : {'code':'KG','name':'Kurgan'}, + '35' : {'code':'KK','name':'Kursk'}, + '36' : {'code':'KY','name':'Kyzyl'}, + '37' : {'code':'LI','name':'Lipetsk'}, + '38' : {'code':'MA','name':'Magadan'}, + '39' : {'code':'MK','name':'Makhachkala'}, + '40' : {'code':'MY','name':'Maykop'}, + '41' : {'code':'MO','name':'Moscow'}, + '42' : {'code':'MU','name':'Murmansk'}, + '43' : {'code':'NA','name':'Nalchik'}, + '44' : {'code':'NR','name':'Naryan Mar'}, + '45' : {'code':'NZ','name':'Nazran'}, + '46' : {'code':'NI','name':'Nizhniy Novgorod'}, + '47' : {'code':'NO','name':'Novgorod'}, + '48' : {'code':'NV','name':'Novosibirsk'}, + '49' : {'code':'OM','name':'Omsk'}, + '50' : {'code':'OR','name':'Orel'}, + '51' : {'code':'OE','name':'Orenburg'}, + '52' : {'code':'PA','name':'Palana'}, + '53' : {'code':'PE','name':'Penza'}, + '54' : {'code':'PR','name':'Perm'}, + '55' : {'code':'PK','name':'Petropavlovsk-Kamchatskiy'}, + '56' : {'code':'PT','name':'Petrozavodsk'}, + '57' : {'code':'PS','name':'Pskov'}, + '58' : {'code':'RO','name':'Rostov-na-Donu'}, + '59' : {'code':'RY','name':'Ryazan'}, + '60' : {'code':'SL','name':'Salekhard'}, + '61' : {'code':'SA','name':'Samara'}, + '62' : {'code':'SR','name':'Saransk'}, + '63' : {'code':'SV','name':'Saratov'}, + '64' : {'code':'SM','name':'Smolensk'}, + '65' : {'code':'SP','name':'St. Petersburg'}, + '66' : {'code':'ST','name':'Stavropol'}, + '67' : {'code':'SY','name':'Syktyvkar'}, + '68' : {'code':'TA','name':'Tambov'}, + '69' : {'code':'TO','name':'Tomsk'}, + '70' : {'code':'TU','name':'Tula'}, + '71' : {'code':'TR','name':'Tura'}, + '72' : {'code':'TV','name':'Tver'}, + '73' : {'code':'TY','name':'Tyumen'}, + '74' : {'code':'UF','name':'Ufa'}, + '75' : {'code':'UL','name':'Ul\'yanovsk'}, + '76' : {'code':'UU','name':'Ulan-Ude'}, + '77' : {'code':'US','name':'Ust\'-Ordynskiy'}, + '78' : {'code':'VL','name':'Vladikavkaz'}, + '79' : {'code':'VA','name':'Vladimir'}, + '80' : {'code':'VV','name':'Vladivostok'}, + '81' : {'code':'VG','name':'Volgograd'}, + '82' : {'code':'VD','name':'Vologda'}, + '83' : {'code':'VO','name':'Voronezh'}, + '84' : {'code':'VY','name':'Vyatka'}, + '85' : {'code':'YA','name':'Yakutsk'}, + '86' : {'code':'YR','name':'Yaroslavl'}, + '87' : {'code':'YE','name':'Yekaterinburg'}, + '88' : {'code':'YO','name':'Yoshkar-Ola'} + }, + 'RW':{ + '1' : {'code':'BU','name':'Butare'}, + '2' : {'code':'BY','name':'Byumba'}, + '3' : {'code':'CY','name':'Cyangugu'}, + '4' : {'code':'GK','name':'Gikongoro'}, + '5' : {'code':'GS','name':'Gisenyi'}, + '6' : {'code':'GT','name':'Gitarama'}, + '7' : {'code':'KG','name':'Kibungo'}, + '8' : {'code':'KY','name':'Kibuye'}, + '9' : {'code':'KR','name':'Kigali Rurale'}, + '10' : {'code':'KV','name':'Kigali-ville'}, + '11' : {'code':'RU','name':'Ruhengeri'}, + '12' : {'code':'UM','name':'Umutara'} + }, + 'KN':{ + '1' : {'code':'CCN','name':'Christ Church Nichola Town'}, + '2' : {'code':'SAS','name':'Saint Anne Sandy Point'}, + '3' : {'code':'SGB','name':'Saint George Basseterre'}, + '4' : {'code':'SGG','name':'Saint George Gingerland'}, + '5' : {'code':'SJW','name':'Saint James Windward'}, + '6' : {'code':'SJC','name':'Saint John Capesterre'}, + '7' : {'code':'SJF','name':'Saint John Figtree'}, + '8' : {'code':'SMC','name':'Saint Mary Cayon'}, + '9' : {'code':'CAP','name':'Saint Paul Capesterre'}, + '10' : {'code':'CHA','name':'Saint Paul Charlestown'}, + '11' : {'code':'SPB','name':'Saint Peter Basseterre'}, + '12' : {'code':'STL','name':'Saint Thomas Lowland'}, + '13' : {'code':'STM','name':'Saint Thomas Middle Island'}, + '14' : {'code':'TPP','name':'Trinity Palmetto Point'} + }, + 'LC':{ + '1' : {'code':'AR','name':'Anse-la-Raye'}, + '2' : {'code':'CA','name':'Castries'}, + '3' : {'code':'CH','name':'Choiseul'}, + '4' : {'code':'DA','name':'Dauphin'}, + '5' : {'code':'DE','name':'Dennery'}, + '6' : {'code':'GI','name':'Gros-Islet'}, + '7' : {'code':'LA','name':'Laborie'}, + '8' : {'code':'MI','name':'Micoud'}, + '9' : {'code':'PR','name':'Praslin'}, + '10' : {'code':'SO','name':'Soufriere'}, + '11' : {'code':'VF','name':'Vieux-Fort'} + }, + 'VC':{ + '1' : {'code':'C','name':'Charlotte'}, + '2' : {'code':'R','name':'Grenadines'}, + '3' : {'code':'A','name':'Saint Andrew'}, + '4' : {'code':'D','name':'Saint David'}, + '5' : {'code':'G','name':'Saint George'}, + '6' : {'code':'P','name':'Saint Patrick'} + }, + 'WS':{ + '1' : {'code':'AN','name':'A\'ana'}, + '2' : {'code':'AI','name':'Aiga-i-le-Tai'}, + '3' : {'code':'AT','name':'Atua'}, + '4' : {'code':'FA','name':'Fa\'asaleleaga'}, + '5' : {'code':'GE','name':'Gaga\'emauga'}, + '6' : {'code':'GF','name':'Gagaifomauga'}, + '7' : {'code':'PA','name':'Palauli'}, + '8' : {'code':'SA','name':'Satupa\'itea'}, + '9' : {'code':'TU','name':'Tuamasaga'}, + '10' : {'code':'VF','name':'Va\'a-o-Fonoti'}, + '11' : {'code':'VS','name':'Vaisigano'} + }, + 'SM':{ + '1' : {'code':'AC','name':'Acquaviva'}, + '2' : {'code':'BM','name':'Borgo Maggiore'}, + '3' : {'code':'CH','name':'Chiesanuova'}, + '4' : {'code':'DO','name':'Domagnano'}, + '5' : {'code':'FA','name':'Faetano'}, + '6' : {'code':'FI','name':'Fiorentino'}, + '7' : {'code':'MO','name':'Montegiardino'}, + '8' : {'code':'SM','name':'Citta di San Marino'}, + '9' : {'code':'SE','name':'Serravalle'} + }, + 'ST':{ + '1' : {'code':'S','name':'Sao Tome'}, + '2' : {'code':'P','name':'Principe'} + }, + 'SA':{ + '1' : {'code':'BH','name':'Al Bahah'}, + '2' : {'code':'HS','name':'Al Hudud ash Shamaliyah'}, + '3' : {'code':'JF','name':'Al Jawf'}, + '4' : {'code':'MD','name':'Al Madinah'}, + '5' : {'code':'QS','name':'Al Qasim'}, + '6' : {'code':'RD','name':'Ar Riyad'}, + '7' : {'code':'AQ','name':'Ash Sharqiyah (Eastern)'}, + '8' : {'code':'AS','name':'\'Asir'}, + '9' : {'code':'HL','name':'Ha\'il'}, + '10' : {'code':'JZ','name':'Jizan'}, + '11' : {'code':'ML','name':'Makkah'}, + '12' : {'code':'NR','name':'Najran'}, + '13' : {'code':'TB','name':'Tabuk'} + }, + 'SN':{ + '1' : {'code':'DA','name':'Dakar'}, + '2' : {'code':'DI','name':'Diourbel'}, + '3' : {'code':'FA','name':'Fatick'}, + '4' : {'code':'KA','name':'Kaolack'}, + '5' : {'code':'KO','name':'Kolda'}, + '6' : {'code':'LO','name':'Louga'}, + '7' : {'code':'MA','name':'Matam'}, + '8' : {'code':'SL','name':'Saint-Louis'}, + '9' : {'code':'TA','name':'Tambacounda'}, + '10' : {'code':'TH','name':'Thies'}, + '11' : {'code':'ZI','name':'Ziguinchor'} + }, + 'SC':{ + '1' : {'code':'AP','name':'Anse aux Pins'}, + '2' : {'code':'AB','name':'Anse Boileau'}, + '3' : {'code':'AE','name':'Anse Etoile'}, + '4' : {'code':'AL','name':'Anse Louis'}, + '5' : {'code':'AR','name':'Anse Royale'}, + '6' : {'code':'BL','name':'Baie Lazare'}, + '7' : {'code':'BS','name':'Baie Sainte Anne'}, + '8' : {'code':'BV','name':'Beau Vallon'}, + '9' : {'code':'BA','name':'Bel Air'}, + '10' : {'code':'BO','name':'Bel Ombre'}, + '11' : {'code':'CA','name':'Cascade'}, + '12' : {'code':'GL','name':'Glacis'}, + '13' : {'code':'GM','name':'Grand\' Anse (on Mahe)'}, + '14' : {'code':'GP','name':'Grand\' Anse (on Praslin)'}, + '15' : {'code':'DG','name':'La Digue'}, + '16' : {'code':'RA','name':'La Riviere Anglaise'}, + '17' : {'code':'MB','name':'Mont Buxton'}, + '18' : {'code':'MF','name':'Mont Fleuri'}, + '19' : {'code':'PL','name':'Plaisance'}, + '20' : {'code':'PR','name':'Pointe La Rue'}, + '21' : {'code':'PG','name':'Port Glaud'}, + '22' : {'code':'SL','name':'Saint Louis'}, + '23' : {'code':'TA','name':'Takamaka'} + }, + 'SL':{ + '1' : {'code':'E','name':'Eastern'}, + '2' : {'code':'N','name':'Northern'}, + '3' : {'code':'S','name':'Southern'}, + '4' : {'code':'W','name':'Western'} + }, + 'SK':{ + '1' : {'code':'BA','name':'Banskobystricky'}, + '2' : {'code':'BR','name':'Bratislavsky'}, + '3' : {'code':'KO','name':'Kosicky'}, + '4' : {'code':'NI','name':'Nitriansky'}, + '5' : {'code':'PR','name':'Presovsky'}, + '6' : {'code':'TC','name':'Trenciansky'}, + '7' : {'code':'TV','name':'Trnavsky'}, + '8' : {'code':'ZI','name':'Zilinsky'} + }, + 'SI':{ + '1' : {'code':'4','name':'Štajerska'}, + '2' : {'code':'2A','name':'Gorenjska'}, + '3' : {'code':'5','name':'Prekmurje'}, + '4' : {'code':'3','name':'Koroška'}, + '5' : {'code':'2B','name':'Notranjska'}, + '6' : {'code':'1','name':'Primorska'}, + '7' : {'code':'2C','name':'Dolenjska'}, + '8' : {'code':'2C','name':'Bela Krajina'} + }, + 'SB':{ + '1' : {'code':'CE','name':'Central'}, + '2' : {'code':'CH','name':'Choiseul'}, + '3' : {'code':'GC','name':'Guadalcanal'}, + '4' : {'code':'HO','name':'Honiara'}, + '5' : {'code':'IS','name':'Isabel'}, + '6' : {'code':'MK','name':'Makira'}, + '7' : {'code':'ML','name':'Malaita'}, + '8' : {'code':'RB','name':'Rennell and Bellona'}, + '9' : {'code':'TM','name':'Temotu'}, + '10' : {'code':'WE','name':'Western'} + }, + 'SO':{ + '1' : {'code':'AW','name':'Awdal'}, + '2' : {'code':'BK','name':'Bakool'}, + '3' : {'code':'BN','name':'Banaadir'}, + '4' : {'code':'BR','name':'Bari'}, + '5' : {'code':'BY','name':'Bay'}, + '6' : {'code':'GA','name':'Galguduud'}, + '7' : {'code':'GE','name':'Gedo'}, + '8' : {'code':'HI','name':'Hiiraan'}, + '9' : {'code':'JD','name':'Jubbada Dhexe'}, + '10' : {'code':'JH','name':'Jubbada Hoose'}, + '11' : {'code':'MU','name':'Mudug'}, + '12' : {'code':'NU','name':'Nugaal'}, + '13' : {'code':'SA','name':'Sanaag'}, + '14' : {'code':'SD','name':'Shabeellaha Dhexe'}, + '15' : {'code':'SH','name':'Shabeellaha Hoose'}, + '16' : {'code':'SL','name':'Sool'}, + '17' : {'code':'TO','name':'Togdheer'}, + '18' : {'code':'WG','name':'Woqooyi Galbeed'} + }, + 'ZA':{ + '1' : {'code':'EC','name':'Eastern Cape'}, + '2' : {'code':'FS','name':'Free State'}, + '3' : {'code':'GT','name':'Gauteng'}, + '4' : {'code':'KN','name':'KwaZulu-Natal'}, + '5' : {'code':'LP','name':'Limpopo'}, + '6' : {'code':'MP','name':'Mpumalanga'}, + '7' : {'code':'NW','name':'North West'}, + '8' : {'code':'NC','name':'Northern Cape'}, + '9' : {'code':'WC','name':'Western Cape'} + }, + 'ES':{ + '1' : {'code':'CA','name':'La Coruña'}, + '2' : {'code':'AL','name':'Álava'}, + '3' : {'code':'AB','name':'Albacete'}, + '4' : {'code':'AC','name':'Alicante'}, + '5' : {'code':'AM','name':'Almeria'}, + '6' : {'code':'AS','name':'Asturias'}, + '7' : {'code':'AV','name':'Ávila'}, + '8' : {'code':'BJ','name':'Badajoz'}, + '9' : {'code':'IB','name':'Baleares'}, + '10' : {'code':'BA','name':'Barcelona'}, + '11' : {'code':'BU','name':'Burgos'}, + '12' : {'code':'CC','name':'Cáceres'}, + '13' : {'code':'CZ','name':'Cádiz'}, + '14' : {'code':'CT','name':'Cantabria'}, + '15' : {'code':'CL','name':'Castellón'}, + '16' : {'code':'CE','name':'Ceuta'}, + '17' : {'code':'CR','name':'Ciudad Real'}, + '18' : {'code':'CD','name':'Córdoba'}, + '19' : {'code':'CU','name':'Cuenca'}, + '20' : {'code':'GI','name':'Gerona'}, + '21' : {'code':'GD','name':'Granada'}, + '22' : {'code':'GJ','name':'Guadalajara'}, + '23' : {'code':'GP','name':'Guipúzcoa'}, + '24' : {'code':'HL','name':'Huelva'}, + '25' : {'code':'HS','name':'Huesca'}, + '26' : {'code':'JN','name':'Jaén'}, + '27' : {'code':'RJ','name':'La Rioja'}, + '28' : {'code':'PM','name':'Las Palmas'}, + '29' : {'code':'LE','name':'León'}, + '30' : {'code':'LL','name':'Lérida'}, + '31' : {'code':'LG','name':'Lugo'}, + '32' : {'code':'MD','name':'Madrid'}, + '33' : {'code':'MA','name':'Málaga'}, + '34' : {'code':'ML','name':'Melilla'}, + '35' : {'code':'MU','name':'Murcia'}, + '36' : {'code':'NV','name':'Navarra'}, + '37' : {'code':'OU','name':'Ourense'}, + '38' : {'code':'PL','name':'Palencia'}, + '39' : {'code':'PO','name':'Pontevedra'}, + '40' : {'code':'SL','name':'Salamanca'}, + '41' : {'code':'SC','name':'Santa Cruz de Tenerife'}, + '42' : {'code':'SG','name':'Segovia'}, + '43' : {'code':'SV','name':'Sevilla'}, + '44' : {'code':'SO','name':'Soria'}, + '45' : {'code':'TA','name':'Tarragona'}, + '46' : {'code':'TE','name':'Teruel'}, + '47' : {'code':'TO','name':'Toledo'}, + '48' : {'code':'VC','name':'Valencia'}, + '49' : {'code':'VD','name':'Valladolid'}, + '50' : {'code':'VZ','name':'Vizcaya'}, + '51' : {'code':'ZM','name':'Zamora'}, + '52' : {'code':'ZR','name':'Zaragoza'} + }, + 'LK':{ + '1' : {'code':'CE','name':'Central'}, + '2' : {'code':'EA','name':'Eastern'}, + '3' : {'code':'NC','name':'North Central'}, + '4' : {'code':'NO','name':'Northern'}, + '5' : {'code':'NW','name':'North Western'}, + '6' : {'code':'SA','name':'Sabaragamuwa'}, + '7' : {'code':'SO','name':'Southern'}, + '8' : {'code':'UV','name':'Uva'}, + '9' : {'code':'WE','name':'Western'} + }, + 'SH':{ + '1' : {'code':'A','name':'Ascension'}, + '2' : {'code':'S','name':'Saint Helena'}, + '3' : {'code':'T','name':'Tristan da Cunha'} + }, + 'PM':{ + '1' : {'code':'P','name':'Saint Pierre'}, + '2' : {'code':'M','name':'Miquelon'} + }, + 'SD':{ + '1' : {'code':'ANL','name':'A\'ali an Nil'}, + '2' : {'code':'BAM','name':'Al Bahr al Ahmar'}, + '3' : {'code':'BRT','name':'Al Buhayrat'}, + '4' : {'code':'JZR','name':'Al Jazirah'}, + '5' : {'code':'KRT','name':'Al Khartum'}, + '6' : {'code':'QDR','name':'Al Qadarif'}, + '7' : {'code':'WDH','name':'Al Wahdah'}, + '8' : {'code':'ANB','name':'An Nil al Abyad'}, + '9' : {'code':'ANZ','name':'An Nil al Azraq'}, + '10' : {'code':'ASH','name':'Ash Shamaliyah'}, + '11' : {'code':'BJA','name':'Bahr al Jabal'}, + '12' : {'code':'GIS','name':'Gharb al Istiwa\'iyah'}, + '13' : {'code':'GBG','name':'Gharb Bahr al Ghazal'}, + '14' : {'code':'GDA','name':'Gharb Darfur'}, + '15' : {'code':'GKU','name':'Gharb Kurdufan'}, + '16' : {'code':'JDA','name':'Janub Darfur'}, + '17' : {'code':'JKU','name':'Janub Kurdufan'}, + '18' : {'code':'JQL','name':'Junqali'}, + '19' : {'code':'KSL','name':'Kassala'}, + '20' : {'code':'NNL','name':'Nahr an Nil'}, + '21' : {'code':'SBG','name':'Shamal Bahr al Ghazal'}, + '22' : {'code':'SDA','name':'Shamal Darfur'}, + '23' : {'code':'SKU','name':'Shamal Kurdufan'}, + '24' : {'code':'SIS','name':'Sharq al Istiwa\'iyah'}, + '25' : {'code':'SNR','name':'Sinnar'}, + '26' : {'code':'WRB','name':'Warab'} + }, + 'SR':{ + '1' : {'code':'BR','name':'Brokopondo'}, + '2' : {'code':'CM','name':'Commewijne'}, + '3' : {'code':'CR','name':'Coronie'}, + '4' : {'code':'MA','name':'Marowijne'}, + '5' : {'code':'NI','name':'Nickerie'}, + '6' : {'code':'PA','name':'Para'}, + '7' : {'code':'PM','name':'Paramaribo'}, + '9' : {'code':'SA','name':'Saramacca'}, + '10' : {'code':'SI','name':'Sipaliwini'}, + '11' : {'code':'WA','name':'Wanica'} + }, + 'SZ':{ + '1' : {'code':'H','name':'Hhohho'}, + '2' : {'code':'L','name':'Lubombo'}, + '3' : {'code':'M','name':'Manzini'}, + '4' : {'code':'S','name':'Shishelweni'} + }, + 'SE':{ + '1' : {'code':'K','name':'Blekinge'}, + '2' : {'code':'W','name':'Dalama'}, + '3' : {'code':'I','name':'Gotland'}, + '4' : {'code':'X','name':'Gävleborg'}, + '5' : {'code':'N','name':'Halland'}, + '6' : {'code':'Z','name':'Jämtland'}, + '7' : {'code':'F','name':'Jönköping'}, + '8' : {'code':'H','name':'Kalmar'}, + '9' : {'code':'G','name':'Kronoberg'}, + '10' : {'code':'BD','name':'Norrbotten'}, + '11' : {'code':'M','name':'Skåne'}, + '12' : {'code':'AB','name':'Stockholm'}, + '13' : {'code':'D','name':'Södermanland'}, + '14' : {'code':'C','name':'Uppsala'}, + '15' : {'code':'S','name':'Värmland'}, + '16' : {'code':'AC','name':'Västerbotten'}, + '17' : {'code':'Y','name':'Västernorrland'}, + '18' : {'code':'U','name':'Västmanland'}, + '19' : {'code':'O','name':'Västra Götaland'}, + '20' : {'code':'T','name':'Örebro'}, + '21' : {'code':'E','name':'Östergötland'} + }, + 'CH':{ + '1' : {'code':'AG','name':'Aargau'}, + '2' : {'code':'AR','name':'Appenzell Ausserrhoden'}, + '3' : {'code':'AI','name':'Appenzell Innerrhoden'}, + '4' : {'code':'BS','name':'Basel-Stadt'}, + '5' : {'code':'BL','name':'Basel-Landschaft'}, + '6' : {'code':'BE','name':'Bern'}, + '7' : {'code':'FR','name':'Fribourg'}, + '8' : {'code':'GE','name':'Genève'}, + '9' : {'code':'GL','name':'Glarus'}, + '10' : {'code':'GR','name':'Graubünden'}, + '11' : {'code':'JU','name':'Jura'}, + '12' : {'code':'LU','name':'Lucerne'}, + '13' : {'code':'NE','name':'Neuchâtel'}, + '14' : {'code':'NW','name':'Nidwalden'}, + '15' : {'code':'OW','name':'Obwalden'}, + '16' : {'code':'SG','name':'St. Gallen'}, + '17' : {'code':'SH','name':'Schaffhausen'}, + '18' : {'code':'SZ','name':'Schwyz'}, + '19' : {'code':'SO','name':'Solothurn'}, + '20' : {'code':'TG','name':'Thurgau'}, + '21' : {'code':'TI','name':'Ticino'}, + '22' : {'code':'UR','name':'Uri'}, + '23' : {'code':'VS','name':'Valais'}, + '24' : {'code':'VD','name':'Vaud'}, + '25' : {'code':'ZG','name':'Zug'}, + '26' : {'code':'ZH','name':'Zürich'} + }, + 'SY':{ + '1' : {'code':'HA','name':'Al Hasakah'}, + '2' : {'code':'LA','name':'Al Ladhiqiyah'}, + '3' : {'code':'QU','name':'Al Qunaytirah'}, + '4' : {'code':'RQ','name':'Ar Raqqah'}, + '5' : {'code':'SU','name':'As Suwayda'}, + '6' : {'code':'DA','name':'Dara'}, + '7' : {'code':'DZ','name':'Dayr az Zawr'}, + '8' : {'code':'DI','name':'Dimashq'}, + '9' : {'code':'HL','name':'Halab'}, + '10' : {'code':'HM','name':'Hamah'}, + '11' : {'code':'HI','name':'Hims'}, + '12' : {'code':'ID','name':'Idlib'}, + '13' : {'code':'RD','name':'Rif Dimashq'}, + '14' : {'code':'TA','name':'Tartus'} + }, + 'TW':{ + '1' : {'code':'CH','name':'Chang-hua'}, + '2' : {'code':'CI','name':'Chia-i'}, + '3' : {'code':'HS','name':'Hsin-chu'}, + '4' : {'code':'HL','name':'Hua-lien'}, + '5' : {'code':'IL','name':'I-lan'}, + '6' : {'code':'KH','name':'Kao-hsiung county'}, + '7' : {'code':'KM','name':'Kin-men'}, + '8' : {'code':'LC','name':'Lien-chiang'}, + '9' : {'code':'ML','name':'Miao-li'}, + '10' : {'code':'NT','name':'Nan-t\'ou'}, + '11' : {'code':'PH','name':'P\'eng-hu'}, + '12' : {'code':'PT','name':'P\'ing-tung'}, + '13' : {'code':'TG','name':'T\'ai-chung'}, + '14' : {'code':'TA','name':'T\'ai-nan'}, + '15' : {'code':'TP','name':'T\'ai-pei county'}, + '16' : {'code':'TT','name':'T\'ai-tung'}, + '17' : {'code':'TY','name':'T\'ao-yuan'}, + '18' : {'code':'YL','name':'Yun-lin'}, + '19' : {'code':'CC','name':'Chia-i city'}, + '20' : {'code':'CL','name':'Chi-lung'}, + '21' : {'code':'HC','name':'Hsin-chu'}, + '22' : {'code':'TH','name':'T\'ai-chung'}, + '23' : {'code':'TN','name':'T\'ai-nan'}, + '24' : {'code':'KC','name':'Kao-hsiung city'}, + '25' : {'code':'TC','name':'T\'ai-pei city'} + }, + 'TJ':{ + '1' : {'code':'GB','name':'Gorno-Badakhstan'}, + '2' : {'code':'KT','name':'Khatlon'}, + '3' : {'code':'SU','name':'Sughd'} + }, + 'TZ':{ + '1' : {'code':'AR','name':'Arusha'}, + '2' : {'code':'DS','name':'Dar es Salaam'}, + '3' : {'code':'DO','name':'Dodoma'}, + '4' : {'code':'IR','name':'Iringa'}, + '5' : {'code':'KA','name':'Kagera'}, + '6' : {'code':'KI','name':'Kigoma'}, + '7' : {'code':'KJ','name':'Kilimanjaro'}, + '8' : {'code':'LN','name':'Lindi'}, + '9' : {'code':'MY','name':'Manyara'}, + '10' : {'code':'MR','name':'Mara'}, + '11' : {'code':'MB','name':'Mbeya'}, + '12' : {'code':'MO','name':'Morogoro'}, + '13' : {'code':'MT','name':'Mtwara'}, + '14' : {'code':'MW','name':'Mwanza'}, + '15' : {'code':'PN','name':'Pemba North'}, + '16' : {'code':'PS','name':'Pemba South'}, + '17' : {'code':'PW','name':'Pwani'}, + '18' : {'code':'RK','name':'Rukwa'}, + '19' : {'code':'RV','name':'Ruvuma'}, + '20' : {'code':'SH','name':'Shinyanga'}, + '21' : {'code':'SI','name':'Singida'}, + '22' : {'code':'TB','name':'Tabora'}, + '23' : {'code':'TN','name':'Tanga'}, + '24' : {'code':'ZC','name':'Zanzibar Central/South'}, + '25' : {'code':'ZN','name':'Zanzibar North'}, + '26' : {'code':'ZU','name':'Zanzibar Urban/West'} + }, + 'TH':{ + '1' : {'code':'Amnat Charoen','name':'Amnat Charoen'}, + '2' : {'code':'Ang Thong','name':'Ang Thong'}, + '3' : {'code':'Ayutthaya','name':'Ayutthaya'}, + '4' : {'code':'Bangkok','name':'Bangkok'}, + '5' : {'code':'Buriram','name':'Buriram'}, + '6' : {'code':'Chachoengsao','name':'Chachoengsao'}, + '7' : {'code':'Chai Nat','name':'Chai Nat'}, + '8' : {'code':'Chaiyaphum','name':'Chaiyaphum'}, + '9' : {'code':'Chanthaburi','name':'Chanthaburi'}, + '10' : {'code':'Chiang Mai','name':'Chiang Mai'}, + '11' : {'code':'Chiang Rai','name':'Chiang Rai'}, + '12' : {'code':'Chon Buri','name':'Chon Buri'}, + '13' : {'code':'Chumphon','name':'Chumphon'}, + '14' : {'code':'Kalasin','name':'Kalasin'}, + '15' : {'code':'Kamphaeng Phet','name':'Kamphaeng Phet'}, + '16' : {'code':'Kanchanaburi','name':'Kanchanaburi'}, + '17' : {'code':'Khon Kaen','name':'Khon Kaen'}, + '18' : {'code':'Krabi','name':'Krabi'}, + '19' : {'code':'Lampang','name':'Lampang'}, + '20' : {'code':'Lamphun','name':'Lamphun'}, + '21' : {'code':'Loei','name':'Loei'}, + '22' : {'code':'Lop Buri','name':'Lop Buri'}, + '23' : {'code':'Mae Hong Son','name':'Mae Hong Son'}, + '24' : {'code':'Maha Sarakham','name':'Maha Sarakham'}, + '25' : {'code':'Mukdahan','name':'Mukdahan'}, + '26' : {'code':'Nakhon Nayok','name':'Nakhon Nayok'}, + '27' : {'code':'Nakhon Pathom','name':'Nakhon Pathom'}, + '28' : {'code':'Nakhon Phanom','name':'Nakhon Phanom'}, + '29' : {'code':'Nakhon Ratchasima','name':'Nakhon Ratchasima'}, + '30' : {'code':'Nakhon Sawan','name':'Nakhon Sawan'}, + '31' : {'code':'Nakhon Si Thammarat','name':'Nakhon Si Thammarat'}, + '32' : {'code':'Nan','name':'Nan'}, + '33' : {'code':'Narathiwat','name':'Narathiwat'}, + '34' : {'code':'Nong Bua Lamphu','name':'Nong Bua Lamphu'}, + '35' : {'code':'Nong Khai','name':'Nong Khai'}, + '36' : {'code':'Nonthaburi','name':'Nonthaburi'}, + '37' : {'code':'Pathum Thani','name':'Pathum Thani'}, + '38' : {'code':'Pattani','name':'Pattani'}, + '39' : {'code':'Phangnga','name':'Phangnga'}, + '40' : {'code':'Phatthalung','name':'Phatthalung'}, + '41' : {'code':'Phayao','name':'Phayao'}, + '42' : {'code':'Phetchabun','name':'Phetchabun'}, + '43' : {'code':'Phetchaburi','name':'Phetchaburi'}, + '44' : {'code':'Phichit','name':'Phichit'}, + '45' : {'code':'Phitsanulok','name':'Phitsanulok'}, + '46' : {'code':'Phrae','name':'Phrae'}, + '47' : {'code':'Phuket','name':'Phuket'}, + '48' : {'code':'Prachin Buri','name':'Prachin Buri'}, + '49' : {'code':'Prachuap Khiri Khan','name':'Prachuap Khiri Khan'}, + '50' : {'code':'Ranong','name':'Ranong'}, + '51' : {'code':'Ratchaburi','name':'Ratchaburi'}, + '52' : {'code':'Rayong','name':'Rayong'}, + '53' : {'code':'Roi Et','name':'Roi Et'}, + '54' : {'code':'Sa Kaeo','name':'Sa Kaeo'}, + '55' : {'code':'Sakon Nakhon','name':'Sakon Nakhon'}, + '56' : {'code':'Samut Prakan','name':'Samut Prakan'}, + '57' : {'code':'Samut Sakhon','name':'Samut Sakhon'}, + '58' : {'code':'Samut Songkhram','name':'Samut Songkhram'}, + '59' : {'code':'Sara Buri','name':'Sara Buri'}, + '60' : {'code':'Satun','name':'Satun'}, + '61' : {'code':'Sing Buri','name':'Sing Buri'}, + '62' : {'code':'Sisaket','name':'Sisaket'}, + '63' : {'code':'Songkhla','name':'Songkhla'}, + '64' : {'code':'Sukhothai','name':'Sukhothai'}, + '65' : {'code':'Suphan Buri','name':'Suphan Buri'}, + '66' : {'code':'Surat Thani','name':'Surat Thani'}, + '67' : {'code':'Surin','name':'Surin'}, + '68' : {'code':'Tak','name':'Tak'}, + '69' : {'code':'Trang','name':'Trang'}, + '70' : {'code':'Trat','name':'Trat'}, + '71' : {'code':'Ubon Ratchathani','name':'Ubon Ratchathani'}, + '72' : {'code':'Udon Thani','name':'Udon Thani'}, + '73' : {'code':'Uthai Thani','name':'Uthai Thani'}, + '74' : {'code':'Uttaradit','name':'Uttaradit'}, + '75' : {'code':'Yala','name':'Yala'}, + '76' : {'code':'Yasothon','name':'Yasothon'} + }, + 'TG':{ + '1' : {'code':'K','name':'Kara'}, + '2' : {'code':'P','name':'Plateaux'}, + '3' : {'code':'S','name':'Savanes'}, + '4' : {'code':'C','name':'Centrale'}, + '5' : {'code':'M','name':'Maritime'} + }, + 'TK':{ + '1' : {'code':'A','name':'Atafu'}, + '2' : {'code':'F','name':'Fakaofo'}, + '3' : {'code':'N','name':'Nukunonu'} + }, + 'TO':{ + '1' : {'code':'H','name':'Ha\'apai'}, + '2' : {'code':'T','name':'Tongatapu'}, + '3' : {'code':'V','name':'Vava\'u'} + }, + 'TT':{ + '1' : {'code':'CT','name':'Couva/Tabaquite/Talparo'}, + '2' : {'code':'DM','name':'Diego Martin'}, + '3' : {'code':'MR','name':'Mayaro/Rio Claro'}, + '4' : {'code':'PD','name':'Penal/Debe'}, + '5' : {'code':'PT','name':'Princes Town'}, + '6' : {'code':'SG','name':'Sangre Grande'}, + '7' : {'code':'SL','name':'San Juan/Laventille'}, + '8' : {'code':'SI','name':'Siparia'}, + '9' : {'code':'TP','name':'Tunapuna/Piarco'}, + '10' : {'code':'PS','name':'Port of Spain'}, + '11' : {'code':'SF','name':'San Fernando'}, + '12' : {'code':'AR','name':'Arima'}, + '13' : {'code':'PF','name':'Point Fortin'}, + '14' : {'code':'CH','name':'Chaguanas'}, + '15' : {'code':'TO','name':'Tobago'} + }, + 'TN':{ + '1' : {'code':'AR','name':'Ariana'}, + '2' : {'code':'BJ','name':'Beja'}, + '3' : {'code':'BA','name':'Ben Arous'}, + '4' : {'code':'BI','name':'Bizerte'}, + '5' : {'code':'GB','name':'Gabes'}, + '6' : {'code':'GF','name':'Gafsa'}, + '7' : {'code':'JE','name':'Jendouba'}, + '8' : {'code':'KR','name':'Kairouan'}, + '9' : {'code':'KS','name':'Kasserine'}, + '10' : {'code':'KB','name':'Kebili'}, + '11' : {'code':'KF','name':'Kef'}, + '12' : {'code':'MH','name':'Mahdia'}, + '13' : {'code':'MN','name':'Manouba'}, + '14' : {'code':'ME','name':'Medenine'}, + '15' : {'code':'MO','name':'Monastir'}, + '16' : {'code':'NA','name':'Nabeul'}, + '17' : {'code':'SF','name':'Sfax'}, + '18' : {'code':'SD','name':'Sidi'}, + '19' : {'code':'SL','name':'Siliana'}, + '20' : {'code':'SO','name':'Sousse'}, + '21' : {'code':'TA','name':'Tataouine'}, + '22' : {'code':'TO','name':'Tozeur'}, + '23' : {'code':'TU','name':'Tunis'}, + '24' : {'code':'ZA','name':'Zaghouan'} + }, + 'TR':{ + '1' : {'code':'ADA','name':'Adana'}, + '2' : {'code':'ADI','name':'Adiyaman'}, + '3' : {'code':'AFY','name':'Afyonkarahisar'}, + '4' : {'code':'AGR','name':'Agri'}, + '5' : {'code':'AKS','name':'Aksaray'}, + '6' : {'code':'AMA','name':'Amasya'}, + '7' : {'code':'ANK','name':'Ankara'}, + '8' : {'code':'ANT','name':'Antalya'}, + '9' : {'code':'ARD','name':'Ardahan'}, + '10' : {'code':'ART','name':'Artvin'}, + '11' : {'code':'AYI','name':'Aydin'}, + '12' : {'code':'BAL','name':'Balikesir'}, + '13' : {'code':'BAR','name':'Bartin'}, + '14' : {'code':'BAT','name':'Batman'}, + '15' : {'code':'BAY','name':'Bayburt'}, + '16' : {'code':'BIL','name':'Bilecik'}, + '17' : {'code':'BIN','name':'Bingol'}, + '18' : {'code':'BIT','name':'Bitlis'}, + '19' : {'code':'BOL','name':'Bolu'}, + '20' : {'code':'BRD','name':'Burdur'}, + '21' : {'code':'BRS','name':'Bursa'}, + '22' : {'code':'CKL','name':'Canakkale'}, + '23' : {'code':'CKR','name':'Cankiri'}, + '24' : {'code':'COR','name':'Corum'}, + '25' : {'code':'DEN','name':'Denizli'}, + '26' : {'code':'DIY','name':'Diyarbakir'}, + '27' : {'code':'DUZ','name':'Duzce'}, + '28' : {'code':'EDI','name':'Edirne'}, + '29' : {'code':'ELA','name':'Elazig'}, + '30' : {'code':'EZC','name':'Erzincan'}, + '31' : {'code':'EZR','name':'Erzurum'}, + '32' : {'code':'ESK','name':'Eskisehir'}, + '33' : {'code':'GAZ','name':'Gaziantep'}, + '34' : {'code':'GIR','name':'Giresun'}, + '35' : {'code':'GMS','name':'Gumushane'}, + '36' : {'code':'HKR','name':'Hakkari'}, + '37' : {'code':'HTY','name':'Hatay'}, + '38' : {'code':'IGD','name':'Igdir'}, + '39' : {'code':'ISP','name':'Isparta'}, + '40' : {'code':'IST','name':'Istanbul'}, + '41' : {'code':'IZM','name':'Izmir'}, + '42' : {'code':'KAH','name':'Kahramanmaras'}, + '43' : {'code':'KRB','name':'Karabuk'}, + '44' : {'code':'KRM','name':'Karaman'}, + '45' : {'code':'KRS','name':'Kars'}, + '46' : {'code':'KAS','name':'Kastamonu'}, + '47' : {'code':'KAY','name':'Kayseri'}, + '48' : {'code':'KLS','name':'Kilis'}, + '49' : {'code':'KRK','name':'Kirikkale'}, + '50' : {'code':'KLR','name':'Kirklareli'}, + '51' : {'code':'KRH','name':'Kirsehir'}, + '52' : {'code':'KOC','name':'Kocaeli'}, + '53' : {'code':'KON','name':'Konya'}, + '54' : {'code':'KUT','name':'Kutahya'}, + '55' : {'code':'MAL','name':'Malatya'}, + '56' : {'code':'MAN','name':'Manisa'}, + '57' : {'code':'MAR','name':'Mardin'}, + '58' : {'code':'MER','name':'Mersin'}, + '59' : {'code':'MUG','name':'Mugla'}, + '60' : {'code':'MUS','name':'Mus'}, + '61' : {'code':'NEV','name':'Nevsehir'}, + '62' : {'code':'NIG','name':'Nigde'}, + '63' : {'code':'ORD','name':'Ordu'}, + '64' : {'code':'OSM','name':'Osmaniye'}, + '65' : {'code':'RIZ','name':'Rize'}, + '66' : {'code':'SAK','name':'Sakarya'}, + '67' : {'code':'SAM','name':'Samsun'}, + '68' : {'code':'SAN','name':'Sanliurfa'}, + '69' : {'code':'SII','name':'Siirt'}, + '70' : {'code':'SIN','name':'Sinop'}, + '71' : {'code':'SIR','name':'Sirnak'}, + '72' : {'code':'SIV','name':'Sivas'}, + '73' : {'code':'TEL','name':'Tekirdag'}, + '74' : {'code':'TOK','name':'Tokat'}, + '75' : {'code':'TRA','name':'Trabzon'}, + '76' : {'code':'TUN','name':'Tunceli'}, + '77' : {'code':'USK','name':'Usak'}, + '78' : {'code':'VAN','name':'Van'}, + '79' : {'code':'YAL','name':'Yalova'}, + '80' : {'code':'YOZ','name':'Yozgat'}, + '81' : {'code':'ZON','name':'Zonguldak'} + }, + 'TM':{ + '1' : {'code':'A','name':'Ahal Welayaty'}, + '2' : {'code':'B','name':'Balkan Welayaty'}, + '3' : {'code':'D','name':'Dashhowuz Welayaty'}, + '4' : {'code':'L','name':'Lebap Welayaty'}, + '5' : {'code':'M','name':'Mary Welayaty'} + }, + 'TC':{ + '1' : {'code':'AC','name':'Ambergris Cays'}, + '2' : {'code':'DC','name':'Dellis Cay'}, + '3' : {'code':'FC','name':'French Cay'}, + '4' : {'code':'LW','name':'Little Water Cay'}, + '5' : {'code':'RC','name':'Parrot Cay'}, + '6' : {'code':'PN','name':'Pine Cay'}, + '7' : {'code':'SL','name':'Salt Cay'}, + '8' : {'code':'GT','name':'Grand Turk'}, + '9' : {'code':'SC','name':'South Caicos'}, + '10' : {'code':'EC','name':'East Caicos'}, + '11' : {'code':'MC','name':'Middle Caicos'}, + '12' : {'code':'NC','name':'North Caicos'}, + '13' : {'code':'PR','name':'Providenciales'}, + '14' : {'code':'WC','name':'West Caicos'} + }, + 'TV':{ + '1' : {'code':'NMG','name':'Nanumanga'}, + '2' : {'code':'NLK','name':'Niulakita'}, + '3' : {'code':'NTO','name':'Niutao'}, + '4' : {'code':'FUN','name':'Funafuti'}, + '5' : {'code':'NME','name':'Nanumea'}, + '6' : {'code':'NUI','name':'Nui'}, + '7' : {'code':'NFT','name':'Nukufetau'}, + '8' : {'code':'NLL','name':'Nukulaelae'}, + '9' : {'code':'VAI','name':'Vaitupu'} + }, + 'UG':{ + '1' : {'code':'KAL','name':'Kalangala'}, + '2' : {'code':'KMP','name':'Kampala'}, + '3' : {'code':'KAY','name':'Kayunga'}, + '4' : {'code':'KIB','name':'Kiboga'}, + '5' : {'code':'LUW','name':'Luwero'}, + '6' : {'code':'MAS','name':'Masaka'}, + '7' : {'code':'MPI','name':'Mpigi'}, + '8' : {'code':'MUB','name':'Mubende'}, + '9' : {'code':'MUK','name':'Mukono'}, + '10' : {'code':'NKS','name':'Nakasongola'}, + '11' : {'code':'RAK','name':'Rakai'}, + '12' : {'code':'SEM','name':'Sembabule'}, + '13' : {'code':'WAK','name':'Wakiso'}, + '14' : {'code':'BUG','name':'Bugiri'}, + '15' : {'code':'BUS','name':'Busia'}, + '16' : {'code':'IGA','name':'Iganga'}, + '17' : {'code':'JIN','name':'Jinja'}, + '18' : {'code':'KAB','name':'Kaberamaido'}, + '19' : {'code':'KML','name':'Kamuli'}, + '20' : {'code':'KPC','name':'Kapchorwa'}, + '21' : {'code':'KTK','name':'Katakwi'}, + '22' : {'code':'KUM','name':'Kumi'}, + '23' : {'code':'MAY','name':'Mayuge'}, + '24' : {'code':'MBA','name':'Mbale'}, + '25' : {'code':'PAL','name':'Pallisa'}, + '26' : {'code':'SIR','name':'Sironko'}, + '27' : {'code':'SOR','name':'Soroti'}, + '28' : {'code':'TOR','name':'Tororo'}, + '29' : {'code':'ADJ','name':'Adjumani'}, + '30' : {'code':'APC','name':'Apac'}, + '31' : {'code':'ARU','name':'Arua'}, + '32' : {'code':'GUL','name':'Gulu'}, + '33' : {'code':'KIT','name':'Kitgum'}, + '34' : {'code':'KOT','name':'Kotido'}, + '35' : {'code':'LIR','name':'Lira'}, + '36' : {'code':'MRT','name':'Moroto'}, + '37' : {'code':'MOY','name':'Moyo'}, + '38' : {'code':'NAK','name':'Nakapiripirit'}, + '39' : {'code':'NEB','name':'Nebbi'}, + '40' : {'code':'PAD','name':'Pader'}, + '41' : {'code':'YUM','name':'Yumbe'}, + '42' : {'code':'BUN','name':'Bundibugyo'}, + '43' : {'code':'BSH','name':'Bushenyi'}, + '44' : {'code':'HOI','name':'Hoima'}, + '45' : {'code':'KBL','name':'Kabale'}, + '46' : {'code':'KAR','name':'Kabarole'}, + '47' : {'code':'KAM','name':'Kamwenge'}, + '48' : {'code':'KAN','name':'Kanungu'}, + '49' : {'code':'KAS','name':'Kasese'}, + '50' : {'code':'KBA','name':'Kibaale'}, + '51' : {'code':'KIS','name':'Kisoro'}, + '52' : {'code':'KYE','name':'Kyenjojo'}, + '53' : {'code':'MSN','name':'Masindi'}, + '54' : {'code':'MBR','name':'Mbarara'}, + '55' : {'code':'NTU','name':'Ntungamo'}, + '56' : {'code':'RUK','name':'Rukungiri'} + }, + 'UA':{ + '1' : {'code':'CK','name':'Cherkasy'}, + '2' : {'code':'CH','name':'Chernihiv'}, + '3' : {'code':'CV','name':'Chernivtsi'}, + '4' : {'code':'CR','name':'Crimea'}, + '5' : {'code':'DN','name':'Dnipropetrovs\'k'}, + '6' : {'code':'DO','name':'Donets\'k'}, + '7' : {'code':'IV','name':'Ivano-Frankivs\'k'}, + '8' : {'code':'KL','name':'Kharkiv Kherson'}, + '9' : {'code':'KM','name':'Khmel\'nyts\'kyy'}, + '10' : {'code':'KR','name':'Kirovohrad'}, + '11' : {'code':'KV','name':'Kiev'}, + '12' : {'code':'KY','name':'Kyyiv'}, + '13' : {'code':'LU','name':'Luhans\'k'}, + '14' : {'code':'LV','name':'L\'viv'}, + '15' : {'code':'MY','name':'Mykolayiv'}, + '16' : {'code':'OD','name':'Odesa'}, + '17' : {'code':'PO','name':'Poltava'}, + '18' : {'code':'RI','name':'Rivne'}, + '19' : {'code':'SE','name':'Sevastopol'}, + '20' : {'code':'SU','name':'Sumy'}, + '21' : {'code':'TE','name':'Ternopil\''}, + '22' : {'code':'VI','name':'Vinnytsya'}, + '23' : {'code':'VO','name':'Volyn\''}, + '24' : {'code':'ZK','name':'Zakarpattya'}, + '25' : {'code':'ZA','name':'Zaporizhzhya'}, + '26' : {'code':'ZH','name':'Zhytomyr'} + }, + 'AE':{ + '1' : {'code':'AZ','name':'Abu Zaby'}, + '2' : {'code':'AJ','name':'\'Ajman'}, + '3' : {'code':'FU','name':'Al Fujayrah'}, + '4' : {'code':'SH','name':'Ash Shariqah'}, + '5' : {'code':'DU','name':'Dubayy'}, + '6' : {'code':'RK','name':'R\'as al Khaymah'}, + '7' : {'code':'UQ','name':'Umm al Qaywayn'} + }, + 'GB':{ + '1' : {'code':'ABN','name':'Aberdeen'}, + '2' : {'code':'ABNS','name':'Aberdeenshire'}, + '3' : {'code':'ANG','name':'Anglesey'}, + '4' : {'code':'AGS','name':'Angus'}, + '5' : {'code':'ARY','name':'Argyll and Bute'}, + '6' : {'code':'BEDS','name':'Bedfordshire'}, + '7' : {'code':'BERKS','name':'Berkshire'}, + '8' : {'code':'BLA','name':'Blaenau Gwent'}, + '9' : {'code':'BRI','name':'Bridgend'}, + '10' : {'code':'BSTL','name':'Bristol'}, + '11' : {'code':'BUCKS','name':'Buckinghamshire'}, + '12' : {'code':'CAE','name':'Caerphilly'}, + '13' : {'code':'CAMBS','name':'Cambridgeshire'}, + '14' : {'code':'CDF','name':'Cardiff'}, + '15' : {'code':'CARM','name':'Carmarthenshire'}, + '16' : {'code':'CDGN','name':'Ceredigion'}, + '17' : {'code':'CHES','name':'Cheshire'}, + '18' : {'code':'CLACK','name':'Clackmannanshire'}, + '19' : {'code':'CON','name':'Conwy'}, + '20' : {'code':'CORN','name':'Cornwall'}, + '21' : {'code':'DNBG','name':'Denbighshire'}, + '22' : {'code':'DERBY','name':'Derbyshire'}, + '23' : {'code':'DVN','name':'Devon'}, + '24' : {'code':'DOR','name':'Dorset'}, + '25' : {'code':'DGL','name':'Dumfries and Galloway'}, + '26' : {'code':'DUND','name':'Dundee'}, + '27' : {'code':'DHM','name':'Durham'}, + '28' : {'code':'ARYE','name':'East Ayrshire'}, + '29' : {'code':'DUNBE','name':'East Dunbartonshire'}, + '30' : {'code':'LOTE','name':'East Lothian'}, + '31' : {'code':'RENE','name':'East Renfrewshire'}, + '32' : {'code':'ERYS','name':'East Riding of Yorkshire'}, + '33' : {'code':'SXE','name':'East Sussex'}, + '34' : {'code':'EDIN','name':'Edinburgh'}, + '35' : {'code':'ESX','name':'Essex'}, + '36' : {'code':'FALK','name':'Falkirk'}, + '37' : {'code':'FFE','name':'Fife'}, + '38' : {'code':'FLINT','name':'Flintshire'}, + '39' : {'code':'GLAS','name':'Glasgow'}, + '40' : {'code':'GLOS','name':'Gloucestershire'}, + '41' : {'code':'LDN','name':'Greater London'}, + '42' : {'code':'MCH','name':'Greater Manchester'}, + '43' : {'code':'GDD','name':'Gwynedd'}, + '44' : {'code':'HANTS','name':'Hampshire'}, + '45' : {'code':'HWR','name':'Herefordshire'}, + '46' : {'code':'HERTS','name':'Hertfordshire'}, + '47' : {'code':'HLD','name':'Highlands'}, + '48' : {'code':'IVER','name':'Inverclyde'}, + '49' : {'code':'IOW','name':'Isle of Wight'}, + '50' : {'code':'KNT','name':'Kent'}, + '51' : {'code':'LANCS','name':'Lancashire'}, + '52' : {'code':'LEICS','name':'Leicestershire'}, + '53' : {'code':'LINCS','name':'Lincolnshire'}, + '54' : {'code':'MSY','name':'Merseyside'}, + '55' : {'code':'MERT','name':'Merthyr Tydfil'}, + '56' : {'code':'MLOT','name':'Midlothian'}, + '57' : {'code':'MMOUTH','name':'Monmouthshire'}, + '58' : {'code':'MORAY','name':'Moray'}, + '59' : {'code':'NPRTAL','name':'Neath Port Talbot'}, + '60' : {'code':'NEWPT','name':'Newport'}, + '61' : {'code':'NOR','name':'Norfolk'}, + '62' : {'code':'ARYN','name':'North Ayrshire'}, + '63' : {'code':'LANN','name':'North Lanarkshire'}, + '64' : {'code':'YSN','name':'North Yorkshire'}, + '65' : {'code':'NHM','name':'Northamptonshire'}, + '66' : {'code':'NLD','name':'Northumberland'}, + '67' : {'code':'NOT','name':'Nottinghamshire'}, + '68' : {'code':'ORK','name':'Orkney Islands'}, + '69' : {'code':'OFE','name':'Oxfordshire'}, + '70' : {'code':'PEM','name':'Pembrokeshire'}, + '71' : {'code':'PERTH','name':'Perth and Kinross'}, + '72' : {'code':'PWS','name':'Powys'}, + '73' : {'code':'REN','name':'Renfrewshire'}, + '74' : {'code':'RHON','name':'Rhondda Cynon Taff'}, + '75' : {'code':'RUT','name':'Rutland'}, + '76' : {'code':'BOR','name':'Scottish Borders'}, + '77' : {'code':'SHET','name':'Shetland Islands'}, + '78' : {'code':'SPE','name':'Shropshire'}, + '79' : {'code':'SOM','name':'Somerset'}, + '80' : {'code':'ARYS','name':'South Ayrshire'}, + '81' : {'code':'LANS','name':'South Lanarkshire'}, + '82' : {'code':'YSS','name':'South Yorkshire'}, + '83' : {'code':'SFD','name':'Staffordshire'}, + '84' : {'code':'STIR','name':'Stirling'}, + '85' : {'code':'SFK','name':'Suffolk'}, + '86' : {'code':'SRY','name':'Surrey'}, + '87' : {'code':'SWAN','name':'Swansea'}, + '88' : {'code':'TORF','name':'Torfaen'}, + '89' : {'code':'TWR','name':'Tyne and Wear'}, + '90' : {'code':'VGLAM','name':'Vale of Glamorgan'}, + '91' : {'code':'WARKS','name':'Warwickshire'}, + '92' : {'code':'WDUN','name':'West Dunbartonshire'}, + '93' : {'code':'WLOT','name':'West Lothian'}, + '94' : {'code':'WMD','name':'West Midlands'}, + '95' : {'code':'SXW','name':'West Sussex'}, + '96' : {'code':'YSW','name':'West Yorkshire'}, + '97' : {'code':'WIL','name':'Western Isles'}, + '98' : {'code':'WLT','name':'Wiltshire'}, + '99' : {'code':'WORCS','name':'Worcestershire'}, + '100' : {'code':'WRX','name':'Wrexham'} + }, + 'US':{ + '1' : {'code':'AL','name':'Alabama'}, + '2' : {'code':'AK','name':'Alaska'}, + '3' : {'code':'AS','name':'American Samoa'}, + '4' : {'code':'AZ','name':'Arizona'}, + '5' : {'code':'AR','name':'Arkansas'}, + '6' : {'code':'AF','name':'Armed Forces Africa'}, + '7' : {'code':'AA','name':'Armed Forces Americas'}, + '8' : {'code':'AC','name':'Armed Forces Canada'}, + '9' : {'code':'AE','name':'Armed Forces Europe'}, + '10' : {'code':'AM','name':'Armed Forces Middle East'}, + '11' : {'code':'AP','name':'Armed Forces Pacific'}, + '12' : {'code':'CA','name':'California'}, + '13' : {'code':'CO','name':'Colorado'}, + '14' : {'code':'CT','name':'Connecticut'}, + '15' : {'code':'DE','name':'Delaware'}, + '16' : {'code':'DC','name':'District of Columbia'}, + '17' : {'code':'FM','name':'Federated States Of Micronesia'}, + '18' : {'code':'FL','name':'Florida'}, + '19' : {'code':'GA','name':'Georgia'}, + '20' : {'code':'GU','name':'Guam'}, + '21' : {'code':'HI','name':'Hawaii'}, + '22' : {'code':'ID','name':'Idaho'}, + '23' : {'code':'IL','name':'Illinois'}, + '24' : {'code':'IN','name':'Indiana'}, + '25' : {'code':'IA','name':'Iowa'}, + '26' : {'code':'KS','name':'Kansas'}, + '27' : {'code':'KY','name':'Kentucky'}, + '28' : {'code':'LA','name':'Louisiana'}, + '29' : {'code':'ME','name':'Maine'}, + '30' : {'code':'MH','name':'Marshall Islands'}, + '31' : {'code':'MD','name':'Maryland'}, + '32' : {'code':'MA','name':'Massachusetts'}, + '33' : {'code':'MI','name':'Michigan'}, + '34' : {'code':'MN','name':'Minnesota'}, + '35' : {'code':'MS','name':'Mississippi'}, + '36' : {'code':'MO','name':'Missouri'}, + '37' : {'code':'MT','name':'Montana'}, + '38' : {'code':'NE','name':'Nebraska'}, + '39' : {'code':'NV','name':'Nevada'}, + '40' : {'code':'NH','name':'New Hampshire'}, + '41' : {'code':'NJ','name':'New Jersey'}, + '42' : {'code':'NM','name':'New Mexico'}, + '43' : {'code':'NY','name':'New York'}, + '44' : {'code':'NC','name':'North Carolina'}, + '45' : {'code':'ND','name':'North Dakota'}, + '46' : {'code':'MP','name':'Northern Mariana Islands'}, + '47' : {'code':'OH','name':'Ohio'}, + '48' : {'code':'OK','name':'Oklahoma'}, + '49' : {'code':'OR','name':'Oregon'}, + '50' : {'code':'PW','name':'Palau'}, + '51' : {'code':'PA','name':'Pennsylvania'}, + '52' : {'code':'PR','name':'Puerto Rico'}, + '53' : {'code':'RI','name':'Rhode Island'}, + '54' : {'code':'SC','name':'South Carolina'}, + '55' : {'code':'SD','name':'South Dakota'}, + '56' : {'code':'TN','name':'Tennessee'}, + '57' : {'code':'TX','name':'Texas'}, + '58' : {'code':'UT','name':'Utah'}, + '59' : {'code':'VT','name':'Vermont'}, + '60' : {'code':'VI','name':'Virgin Islands'}, + '61' : {'code':'VA','name':'Virginia'}, + '62' : {'code':'WA','name':'Washington'}, + '63' : {'code':'WV','name':'West Virginia'}, + '64' : {'code':'WI','name':'Wisconsin'}, + '65' : {'code':'WY','name':'Wyoming'} + }, + 'UM':{ + '1' : {'code':'BI','name':'Baker Island'}, + '2' : {'code':'HI','name':'Howland Island'}, + '3' : {'code':'JI','name':'Jarvis Island'}, + '4' : {'code':'JA','name':'Johnston Atoll'}, + '5' : {'code':'KR','name':'Kingman Reef'}, + '6' : {'code':'MA','name':'Midway Atoll'}, + '7' : {'code':'NI','name':'Navassa Island'}, + '8' : {'code':'PA','name':'Palmyra Atoll'}, + '9' : {'code':'WI','name':'Wake Island'} + }, + 'UY':{ + '1' : {'code':'AR','name':'Artigas'}, + '2' : {'code':'CA','name':'Canelones'}, + '3' : {'code':'CL','name':'Cerro Largo'}, + '4' : {'code':'CO','name':'Colonia'}, + '5' : {'code':'DU','name':'Durazno'}, + '6' : {'code':'FS','name':'Flores'}, + '7' : {'code':'FA','name':'Florida'}, + '8' : {'code':'LA','name':'Lavalleja'}, + '9' : {'code':'MA','name':'Maldonado'}, + '10' : {'code':'MO','name':'Montevideo'}, + '11' : {'code':'PA','name':'Paysandu'}, + '12' : {'code':'RN','name':'Rio Negro'}, + '13' : {'code':'RV','name':'Rivera'}, + '14' : {'code':'RO','name':'Rocha'}, + '15' : {'code':'SL','name':'Salto'}, + '16' : {'code':'SJ','name':'San Jose'}, + '17' : {'code':'SO','name':'Soriano'}, + '18' : {'code':'TA','name':'Tacuarembo'}, + '19' : {'code':'TT','name':'Treinta y Tres'} + }, + 'UZ':{ + '1' : {'code':'AN','name':'Andijon'}, + '2' : {'code':'BU','name':'Buxoro'}, + '3' : {'code':'FA','name':'Farg\'ona'}, + '4' : {'code':'JI','name':'Jizzax'}, + '5' : {'code':'NG','name':'Namangan'}, + '6' : {'code':'NW','name':'Navoiy'}, + '7' : {'code':'QA','name':'Qashqadaryo'}, + '8' : {'code':'QR','name':'Qoraqalpog\'iston Republikasi'}, + '9' : {'code':'SA','name':'Samarqand'}, + '10' : {'code':'SI','name':'Sirdaryo'}, + '11' : {'code':'SU','name':'Surxondaryo'}, + '12' : {'code':'TK','name':'Toshkent City'}, + '13' : {'code':'TO','name':'Toshkent Region'}, + '14' : {'code':'XO','name':'Xorazm'} + }, + 'VU':{ + '1' : {'code':'MA','name':'Malampa'}, + '2' : {'code':'PE','name':'Penama'}, + '3' : {'code':'SA','name':'Sanma'}, + '4' : {'code':'SH','name':'Shefa'}, + '5' : {'code':'TA','name':'Tafea'}, + '6' : {'code':'TO','name':'Torba'} + }, + 'VE':{ + '1' : {'code':'AM','name':'Amazonas'}, + '2' : {'code':'AN','name':'Anzoategui'}, + '3' : {'code':'AP','name':'Apure'}, + '4' : {'code':'AR','name':'Aragua'}, + '5' : {'code':'BA','name':'Barinas'}, + '6' : {'code':'BO','name':'Bolivar'}, + '7' : {'code':'CA','name':'Carabobo'}, + '8' : {'code':'CO','name':'Cojedes'}, + '9' : {'code':'DA','name':'Delta Amacuro'}, + '10' : {'code':'DF','name':'Dependencias Federales'}, + '11' : {'code':'DI','name':'Distrito Federal'}, + '12' : {'code':'FA','name':'Falcon'}, + '13' : {'code':'GU','name':'Guarico'}, + '14' : {'code':'LA','name':'Lara'}, + '15' : {'code':'ME','name':'Merida'}, + '16' : {'code':'MI','name':'Miranda'}, + '17' : {'code':'MO','name':'Monagas'}, + '18' : {'code':'NE','name':'Nueva Esparta'}, + '19' : {'code':'PO','name':'Portuguesa'}, + '20' : {'code':'SU','name':'Sucre'}, + '21' : {'code':'TA','name':'Tachira'}, + '22' : {'code':'TR','name':'Trujillo'}, + '23' : {'code':'VA','name':'Vargas'}, + '24' : {'code':'YA','name':'Yaracuy'}, + '25' : {'code':'ZU','name':'Zulia'} + }, + 'VN':{ + '1' : {'code':'AG','name':'An Giang'}, + '2' : {'code':'BG','name':'Bac Giang'}, + '3' : {'code':'BK','name':'Bac Kan'}, + '4' : {'code':'BL','name':'Bac Lieu'}, + '5' : {'code':'BC','name':'Bac Ninh'}, + '6' : {'code':'BR','name':'Ba Ria-Vung Tau'}, + '7' : {'code':'BN','name':'Ben Tre'}, + '8' : {'code':'BH','name':'Binh Dinh'}, + '9' : {'code':'BU','name':'Binh Duong'}, + '10' : {'code':'BP','name':'Binh Phuoc'}, + '11' : {'code':'BT','name':'Binh Thuan'}, + '12' : {'code':'CM','name':'Ca Mau'}, + '13' : {'code':'CT','name':'Can Tho'}, + '14' : {'code':'CB','name':'Cao Bang'}, + '15' : {'code':'DL','name':'Dak Lak'}, + '16' : {'code':'DG','name':'Dak Nong'}, + '17' : {'code':'DN','name':'Da Nang'}, + '18' : {'code':'DB','name':'Dien Bien'}, + '19' : {'code':'DI','name':'Dong Nai'}, + '20' : {'code':'DT','name':'Dong Thap'}, + '21' : {'code':'GL','name':'Gia Lai'}, + '22' : {'code':'HG','name':'Ha Giang'}, + '23' : {'code':'HD','name':'Hai Duong'}, + '24' : {'code':'HP','name':'Hai Phong'}, + '25' : {'code':'HM','name':'Ha Nam'}, + '26' : {'code':'HI','name':'Ha Noi'}, + '27' : {'code':'HT','name':'Ha Tay'}, + '28' : {'code':'HH','name':'Ha Tinh'}, + '29' : {'code':'HB','name':'Hoa Binh'}, + '30' : {'code':'HC','name':'Ho Chin Minh'}, + '31' : {'code':'HU','name':'Hau Giang'}, + '32' : {'code':'HY','name':'Hung Yen'} + }, + 'VI':{ + '1' : {'code':'C','name':'Saint Croix'}, + '2' : {'code':'J','name':'Saint John'}, + '3' : {'code':'T','name':'Saint Thomas'} + }, + 'WF':{ + '1' : {'code':'A','name':'Alo'}, + '2' : {'code':'S','name':'Sigave'}, + '3' : {'code':'W','name':'Wallis'} + }, + 'YE':{ + '1' : {'code':'AB','name':'Abyan'}, + '2' : {'code':'AD','name':'Adan'}, + '3' : {'code':'AM','name':'Amran'}, + '4' : {'code':'BA','name':'Al Bayda'}, + '5' : {'code':'DA','name':'Ad Dali'}, + '6' : {'code':'DH','name':'Dhamar'}, + '7' : {'code':'HD','name':'Hadramawt'}, + '8' : {'code':'HJ','name':'Hajjah'}, + '9' : {'code':'HU','name':'Al Hudaydah'}, + '10' : {'code':'IB','name':'Ibb'}, + '11' : {'code':'JA','name':'Al Jawf'}, + '12' : {'code':'LA','name':'Lahij'}, + '13' : {'code':'MA','name':'Ma\'rib'}, + '14' : {'code':'MR','name':'Al Mahrah'}, + '15' : {'code':'MW','name':'Al Mahwit'}, + '16' : {'code':'SD','name':'Sa\'dah'}, + '17' : {'code':'SN','name':'San\'a'}, + '18' : {'code':'SH','name':'Shabwah'}, + '19' : {'code':'TA','name':'Ta\'izz'} + }, + 'YU':{ + '1' : {'code':'KOS','name':'Kosovo'}, + '2' : {'code':'MON','name':'Montenegro'}, + '3' : {'code':'SER','name':'Serbia'}, + '4' : {'code':'VOJ','name':'Vojvodina'} + }, + 'ZR':{ + '1' : {'code':'BC','name':'Bas-Congo'}, + '2' : {'code':'BN','name':'Bandundu'}, + '3' : {'code':'EQ','name':'Equateur'}, + '4' : {'code':'KA','name':'Katanga'}, + '5' : {'code':'KE','name':'Kasai-Oriental'}, + '6' : {'code':'KN','name':'Kinshasa'}, + '7' : {'code':'KW','name':'Kasai-Occidental'}, + '8' : {'code':'MA','name':'Maniema'}, + '9' : {'code':'NK','name':'Nord-Kivu'}, + '10' : {'code':'OR','name':'Orientale'}, + '11' : {'code':'SK','name':'Sud-Kivu'} + }, + 'ZM':{ + '1' : {'code':'CE','name':'Central'}, + '2' : {'code':'CB','name':'Copperbelt'}, + '3' : {'code':'EA','name':'Eastern'}, + '4' : {'code':'LP','name':'Luapula'}, + '5' : {'code':'LK','name':'Lusaka'}, + '6' : {'code':'NO','name':'Northern'}, + '7' : {'code':'NW','name':'North-Western'}, + '8' : {'code':'SO','name':'Southern'}, + '9' : {'code':'WE','name':'Western'} + }, + 'ZW':{ + '1' : {'code':'BU','name':'Bulawayo'}, + '2' : {'code':'HA','name':'Harare'}, + '3' : {'code':'ML','name':'Manicaland'}, + '4' : {'code':'MC','name':'Mashonaland Central'}, + '5' : {'code':'ME','name':'Mashonaland East'}, + '6' : {'code':'MW','name':'Mashonaland West'}, + '7' : {'code':'MV','name':'Masvingo'}, + '8' : {'code':'MN','name':'Matabeleland North'}, + '9' : {'code':'MS','name':'Matabeleland South'}, + '10' : {'code':'MD','name':'Midlands'} + } +}; + +/* ========================================================== + * bootstrap-formhelpers-timepicker.en_US.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + +var BFHTimePickerDelimiter = ':'; + +var BFHTimePickerModes = { + 'am': 'AM', + 'pm': 'PM' +}; +/* ========================================================== + * bootstrap-formhelpers-timezones.en_US.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + +var BFHTimezonesList = { + 'AF': { + 'Asia/Kabul': 'Kabul' + }, + 'AL': { + 'Europe/Tirane': 'Tirane' + }, + 'DZ': { + 'Africa/Algiers': 'Algiers' + }, + 'AS': { + 'Pacific/Pago_Pago': 'Pago Pago' + }, + 'AD': { + 'Europe/Andorra': 'Andorra' + }, + 'AO': { + 'Africa/Luanda': 'Luanda' + }, + 'AI': { + 'America/Anguilla': 'Anguilla' + }, + 'AQ': { + 'Antarctica/Casey': 'Casey', + 'Antarctica/Davis': 'Davis', + 'Antarctica/DumontDUrville': 'DumontDUrville', + 'Antarctica/Macquarie': 'Macquarie', + 'Antarctica/Mawson': 'Mawson', + 'Antarctica/McMurdo': 'McMurdo', + 'Antarctica/Palmer': 'Palmer', + 'Antarctica/Rothera': 'Rothera', + 'Antarctica/South_Pole': 'South Pole', + 'Antarctica/Syowa': 'Syowa', + 'Antarctica/Vostok': 'Vostok' + }, + 'AG': { + 'America/Antigua': 'Antigua' + }, + 'AR': { + 'America/Argentina/Buenos_Aires': 'Argentina / Buenos Aires', + 'America/Argentina/Catamarca': 'Argentina / Catamarca', + 'America/Argentina/Cordoba': 'Argentina / Cordoba', + 'America/Argentina/Jujuy': 'Argentina / Jujuy', + 'America/Argentina/La_Rioja': 'Argentina / La Rioja', + 'America/Argentina/Mendoza': 'Argentina / Mendoza', + 'America/Argentina/Rio_Gallegos': 'Argentina / Rio Gallegos', + 'America/Argentina/Salta': 'Argentina / Salta', + 'America/Argentina/San_Juan': 'Argentina / San Juan', + 'America/Argentina/San_Luis': 'Argentina / San Luis', + 'America/Argentina/Tucuman': 'Argentina / Tucuman', + 'America/Argentina/Ushuaia': 'Argentina / Ushuaia' + }, + 'AM': { + 'Asia/Yerevan': 'Yerevan' + }, + 'AW': { + 'America/Aruba': 'Aruba' + }, + 'AU': { + 'Australia/Adelaide': 'Adelaide', + 'Australia/Brisbane': 'Brisbane', + 'Australia/Broken_Hill': 'Broken Hill', + 'Australia/Currie': 'Currie', + 'Australia/Darwin': 'Darwin', + 'Australia/Eucla': 'Eucla', + 'Australia/Hobart': 'Hobart', + 'Australia/Lindeman': 'Lindeman', + 'Australia/Lord_Howe': 'Lord Howe', + 'Australia/Melbourne': 'Melbourne', + 'Australia/Perth': 'Perth', + 'Australia/Sydney': 'Sydney' + }, + 'AT': { + 'Europe/Vienna': 'Vienna' + }, + 'AZ': { + 'Asia/Baku': 'Baku' + }, + 'BH': { + 'Asia/Bahrain': 'Bahrain' + }, + 'BD': { + 'Asia/Dhaka': 'Dhaka' + }, + 'BB': { + 'America/Barbados': 'Barbados' + }, + 'BY': { + 'Europe/Minsk': 'Minsk' + }, + 'BE': { + 'Europe/Brussels': 'Brussels' + }, + 'BZ': { + 'America/Belize': 'Belize' + }, + 'BJ': { + 'Africa/Porto-Novo': 'Porto-Novo' + }, + 'BM': { + 'Atlantic/Bermuda': 'Bermuda' + }, + 'BT': { + 'Asia/Thimphu': 'Thimphu' + }, + 'BO': { + 'America/La_Paz': 'La Paz' + }, + 'BA': { + 'Europe/Sarajevo': 'Sarajevo' + }, + 'BW': { + 'Africa/Gaborone': 'Gaborone' + }, + 'BR': { + 'America/Araguaina': 'Araguaina', + 'America/Bahia': 'Bahia', + 'America/Belem': 'Belem', + 'America/Boa_Vista': 'Boa Vista', + 'America/Campo_Grande': 'Campo Grande', + 'America/Cuiaba': 'Cuiaba', + 'America/Eirunepe': 'Eirunepe', + 'America/Fortaleza': 'Fortaleza', + 'America/Maceio': 'Maceio', + 'America/Manaus': 'Manaus', + 'America/Noronha': 'Noronha', + 'America/Porto_Velho': 'Porto Velho', + 'America/Recife': 'Recife', + 'America/Rio_Branco': 'Rio Branco', + 'America/Santarem': 'Santarem', + 'America/Sao_Paulo': 'Sao Paulo' + }, + 'VG': { + 'America/Tortola': 'Tortola' + }, + 'BN': { + 'Asia/Brunei': 'Brunei' + }, + 'BG': { + 'Europe/Sofia': 'Sofia' + }, + 'BF': { + 'Africa/Ouagadougou': 'Ouagadougou' + }, + 'BI': { + 'Africa/Bujumbura': 'Bujumbura' + }, + 'CI': { + 'Africa/Abidjan': 'Abidjan' + }, + 'KH': { + 'Asia/Phnom_Penh': 'Phnom Penh' + }, + 'CM': { + 'Africa/Douala': 'Douala' + }, + 'CA': { + 'America/Atikokan': 'Atikokan', + 'America/Blanc-Sablon': 'Blanc-Sablon', + 'America/Cambridge_Bay': 'Cambridge Bay', + 'America/Creston': 'Creston', + 'America/Dawson': 'Dawson', + 'America/Dawson_Creek': 'Dawson Creek', + 'America/Edmonton': 'Edmonton', + 'America/Glace_Bay': 'Glace Bay', + 'America/Goose_Bay': 'Goose Bay', + 'America/Halifax': 'Halifax', + 'America/Inuvik': 'Inuvik', + 'America/Iqaluit': 'Iqaluit', + 'America/Moncton': 'Moncton', + 'America/Montreal': 'Montreal', + 'America/Nipigon': 'Nipigon', + 'America/Pangnirtung': 'Pangnirtung', + 'America/Rainy_River': 'Rainy River', + 'America/Rankin_Inlet': 'Rankin Inlet', + 'America/Regina': 'Regina', + 'America/Resolute': 'Resolute', + 'America/St_Johns': 'St Johns', + 'America/Swift_Current': 'Swift Current', + 'America/Thunder_Bay': 'Thunder Bay', + 'America/Toronto': 'Toronto', + 'America/Vancouver': 'Vancouver', + 'America/Whitehorse': 'Whitehorse', + 'America/Winnipeg': 'Winnipeg', + 'America/Yellowknife': 'Yellowknife' + }, + 'CV': { + 'Atlantic/Cape_Verde': 'Cape Verde' + }, + 'KY': { + 'America/Cayman': 'Cayman' + }, + 'CF': { + 'Africa/Bangui': 'Bangui' + }, + 'TD': { + 'Africa/Ndjamena': 'Ndjamena' + }, + 'CL': { + 'America/Santiago': 'Santiago', + 'Pacific/Easter': 'Easter' + }, + 'CN': { + 'Asia/Chongqing': 'Chongqing', + 'Asia/Harbin': 'Harbin', + 'Asia/Kashgar': 'Kashgar', + 'Asia/Shanghai': 'Shanghai', + 'Asia/Urumqi': 'Urumqi' + }, + 'CO': { + 'America/Bogota': 'Bogota' + }, + 'KM': { + 'Indian/Comoro': 'Comoro' + }, + 'CG': { + 'Africa/Brazzaville': 'Brazzaville' + }, + 'CR': { + 'America/Costa_Rica': 'Costa Rica' + }, + 'HR': { + 'Europe/Zagreb': 'Zagreb' + }, + 'CU': { + 'America/Havana': 'Havana' + }, + 'CY': { + 'Asia/Nicosia': 'Nicosia' + }, + 'CZ': { + 'Europe/Prague': 'Prague' + }, + 'CD': { + 'Africa/Kinshasa': 'Kinshasa', + 'Africa/Lubumbashi': 'Lubumbashi' + }, + 'DK': { + 'Europe/Copenhagen': 'Copenhagen' + }, + 'DJ': { + 'Africa/Djibouti': 'Djibouti' + }, + 'DM': { + 'America/Dominica': 'Dominica' + }, + 'DO': { + 'America/Santo_Domingo': 'Santo Domingo' + }, + 'TP': { + }, + 'EC': { + 'America/Guayaquil': 'Guayaquil', + 'Pacific/Galapagos': 'Galapagos' + }, + 'EG': { + 'Africa/Cairo': 'Cairo' + }, + 'SV': { + 'America/El_Salvador': 'El Salvador' + }, + 'GQ': { + 'Africa/Malabo': 'Malabo' + }, + 'ER': { + 'Africa/Asmara': 'Asmara' + }, + 'EE': { + 'Europe/Tallinn': 'Tallinn' + }, + 'ET': { + 'Africa/Addis_Ababa': 'Addis Ababa' + }, + 'FO': { + 'Atlantic/Faroe': 'Faroe' + }, + 'FK': { + 'Atlantic/Stanley': 'Stanley' + }, + 'FJ': { + 'Pacific/Fiji': 'Fiji' + }, + 'FI': { + 'Europe/Helsinki': 'Helsinki' + }, + 'MK': { + 'Europe/Skopje': 'Skopje' + }, + 'FR': { + 'Europe/Paris': 'Paris' + }, + 'GA': { + 'Africa/Libreville': 'Libreville' + }, + 'GE': { + 'Asia/Tbilisi': 'Tbilisi' + }, + 'DE': { + 'Europe/Berlin': 'Berlin' + }, + 'GH': { + 'Africa/Accra': 'Accra' + }, + 'GR': { + 'Europe/Athens': 'Athens' + }, + 'GL': { + 'America/Danmarkshavn': 'Danmarkshavn', + 'America/Godthab': 'Godthab', + 'America/Scoresbysund': 'Scoresbysund', + 'America/Thule': 'Thule' + }, + 'GD': { + 'America/Grenada': 'Grenada' + }, + 'GU': { + 'Pacific/Guam': 'Guam' + }, + 'GT': { + 'America/Guatemala': 'Guatemala' + }, + 'GN': { + 'Africa/Conakry': 'Conakry' + }, + 'GW': { + 'Africa/Bissau': 'Bissau' + }, + 'GY': { + 'America/Guyana': 'Guyana' + }, + 'HT': { + 'America/Port-au-Prince': 'Port-au-Prince' + }, + 'HN': { + 'America/Tegucigalpa': 'Tegucigalpa' + }, + 'HK': { + 'Asia/Hong_Kong': 'Hong Kong' + }, + 'HU': { + 'Europe/Budapest': 'Budapest' + }, + 'IS': { + 'Atlantic/Reykjavik': 'Reykjavik' + }, + 'IN': { + 'Asia/Kolkata': 'Kolkata' + }, + 'ID': { + 'Asia/Jakarta': 'Jakarta', + 'Asia/Jayapura': 'Jayapura', + 'Asia/Makassar': 'Makassar', + 'Asia/Pontianak': 'Pontianak' + }, + 'IR': { + 'Asia/Tehran': 'Tehran' + }, + 'IQ': { + 'Asia/Baghdad': 'Baghdad' + }, + 'IE': { + 'Europe/Dublin': 'Dublin' + }, + 'IL': { + 'Asia/Jerusalem': 'Jerusalem' + }, + 'IT': { + 'Europe/Rome': 'Rome' + }, + 'JM': { + 'America/Jamaica': 'Jamaica' + }, + 'JP': { + 'Asia/Tokyo': 'Tokyo' + }, + 'JO': { + 'Asia/Amman': 'Amman' + }, + 'KZ': { + 'Asia/Almaty': 'Almaty', + 'Asia/Aqtau': 'Aqtau', + 'Asia/Aqtobe': 'Aqtobe', + 'Asia/Oral': 'Oral', + 'Asia/Qyzylorda': 'Qyzylorda' + }, + 'KE': { + 'Africa/Nairobi': 'Nairobi' + }, + 'KI': { + 'Pacific/Enderbury': 'Enderbury', + 'Pacific/Kiritimati': 'Kiritimati', + 'Pacific/Tarawa': 'Tarawa' + }, + 'KW': { + 'Asia/Kuwait': 'Kuwait' + }, + 'KG': { + 'Asia/Bishkek': 'Bishkek' + }, + 'LA': { + 'Asia/Vientiane': 'Vientiane' + }, + 'LV': { + 'Europe/Riga': 'Riga' + }, + 'LB': { + 'Asia/Beirut': 'Beirut' + }, + 'LS': { + 'Africa/Maseru': 'Maseru' + }, + 'LR': { + 'Africa/Monrovia': 'Monrovia' + }, + 'LY': { + 'Africa/Tripoli': 'Tripoli' + }, + 'LI': { + 'Europe/Vaduz': 'Vaduz' + }, + 'LT': { + 'Europe/Vilnius': 'Vilnius' + }, + 'LU': { + 'Europe/Luxembourg': 'Luxembourg' + }, + 'MO': { + 'Asia/Macau': 'Macau' + }, + 'MG': { + 'Indian/Antananarivo': 'Antananarivo' + }, + 'MW': { + 'Africa/Blantyre': 'Blantyre' + }, + 'MY': { + 'Asia/Kuala_Lumpur': 'Kuala Lumpur', + 'Asia/Kuching': 'Kuching' + }, + 'MV': { + 'Indian/Maldives': 'Maldives' + }, + 'ML': { + 'Africa/Bamako': 'Bamako' + }, + 'MT': { + 'Europe/Malta': 'Malta' + }, + 'MH': { + 'Pacific/Kwajalein': 'Kwajalein', + 'Pacific/Majuro': 'Majuro' + }, + 'MR': { + 'Africa/Nouakchott': 'Nouakchott' + }, + 'MU': { + 'Indian/Mauritius': 'Mauritius' + }, + 'MX': { + 'America/Bahia_Banderas': 'Bahia Banderas', + 'America/Cancun': 'Cancun', + 'America/Chihuahua': 'Chihuahua', + 'America/Hermosillo': 'Hermosillo', + 'America/Matamoros': 'Matamoros', + 'America/Mazatlan': 'Mazatlan', + 'America/Merida': 'Merida', + 'America/Mexico_City': 'Mexico City', + 'America/Monterrey': 'Monterrey', + 'America/Ojinaga': 'Ojinaga', + 'America/Santa_Isabel': 'Santa Isabel', + 'America/Tijuana': 'Tijuana' + }, + 'FM': { + 'Pacific/Chuuk': 'Chuuk', + 'Pacific/Kosrae': 'Kosrae', + 'Pacific/Pohnpei': 'Pohnpei' + }, + 'MD': { + 'Europe/Chisinau': 'Chisinau' + }, + 'MC': { + 'Europe/Monaco': 'Monaco' + }, + 'MN': { + 'Asia/Choibalsan': 'Choibalsan', + 'Asia/Hovd': 'Hovd', + 'Asia/Ulaanbaatar': 'Ulaanbaatar' + }, + 'ME': { + 'Europe/Podgorica': 'Podgorica' + }, + 'MS': { + 'America/Montserrat': 'Montserrat' + }, + 'MA': { + 'Africa/Casablanca': 'Casablanca' + }, + 'MZ': { + 'Africa/Maputo': 'Maputo' + }, + 'MM': { + 'Asia/Rangoon': 'Rangoon' + }, + 'NA': { + 'Africa/Windhoek': 'Windhoek' + }, + 'NR': { + 'Pacific/Nauru': 'Nauru' + }, + 'NP': { + 'Asia/Kathmandu': 'Kathmandu' + }, + 'NL': { + 'Europe/Amsterdam': 'Amsterdam' + }, + 'AN': { + }, + 'NZ': { + 'Pacific/Auckland': 'Auckland', + 'Pacific/Chatham': 'Chatham' + }, + 'NI': { + 'America/Managua': 'Managua' + }, + 'NE': { + 'Africa/Niamey': 'Niamey' + }, + 'NG': { + 'Africa/Lagos': 'Lagos' + }, + 'NF': { + 'Pacific/Norfolk': 'Norfolk' + }, + 'KP': { + 'Asia/Pyongyang': 'Pyongyang' + }, + 'MP': { + 'Pacific/Saipan': 'Saipan' + }, + 'NO': { + 'Europe/Oslo': 'Oslo' + }, + 'OM': { + 'Asia/Muscat': 'Muscat' + }, + 'PK': { + 'Asia/Karachi': 'Karachi' + }, + 'PW': { + 'Pacific/Palau': 'Palau' + }, + 'PA': { + 'America/Panama': 'Panama' + }, + 'PG': { + 'Pacific/Port_Moresby': 'Port Moresby' + }, + 'PY': { + 'America/Asuncion': 'Asuncion' + }, + 'PE': { + 'America/Lima': 'Lima' + }, + 'PH': { + 'Asia/Manila': 'Manila' + }, + 'PN': { + 'Pacific/Pitcairn': 'Pitcairn' + }, + 'PL': { + 'Europe/Warsaw': 'Warsaw' + }, + 'PT': { + 'Atlantic/Azores': 'Azores', + 'Atlantic/Madeira': 'Madeira', + 'Europe/Lisbon': 'Lisbon' + }, + 'PR': { + 'America/Puerto_Rico': 'Puerto Rico' + }, + 'QA': { + 'Asia/Qatar': 'Qatar' + }, + 'RO': { + 'Europe/Bucharest': 'Bucharest' + }, + 'RU': { + 'Asia/Anadyr': 'Anadyr', + 'Asia/Irkutsk': 'Irkutsk', + 'Asia/Kamchatka': 'Kamchatka', + 'Asia/Krasnoyarsk': 'Krasnoyarsk', + 'Asia/Magadan': 'Magadan', + 'Asia/Novokuznetsk': 'Novokuznetsk', + 'Asia/Novosibirsk': 'Novosibirsk', + 'Asia/Omsk': 'Omsk', + 'Asia/Sakhalin': 'Sakhalin', + 'Asia/Vladivostok': 'Vladivostok', + 'Asia/Yakutsk': 'Yakutsk', + 'Asia/Yekaterinburg': 'Yekaterinburg', + 'Europe/Kaliningrad': 'Kaliningrad', + 'Europe/Moscow': 'Moscow', + 'Europe/Samara': 'Samara', + 'Europe/Volgograd': 'Volgograd' + }, + 'RW': { + 'Africa/Kigali': 'Kigali' + }, + 'ST': { + 'Africa/Sao_Tome': 'Sao Tome' + }, + 'SH': { + 'Atlantic/St_Helena': 'St Helena' + }, + 'KN': { + 'America/St_Kitts': 'St Kitts' + }, + 'LC': { + 'America/St_Lucia': 'St Lucia' + }, + 'VC': { + 'America/St_Vincent': 'St Vincent' + }, + 'WS': { + 'Pacific/Apia': 'Apia' + }, + 'SM': { + 'Europe/San_Marino': 'San Marino' + }, + 'SA': { + 'Asia/Riyadh': 'Riyadh' + }, + 'SN': { + 'Africa/Dakar': 'Dakar' + }, + 'RS': { + 'Europe/Belgrade': 'Belgrade' + }, + 'SC': { + 'Indian/Mahe': 'Mahe' + }, + 'SL': { + 'Africa/Freetown': 'Freetown' + }, + 'SG': { + 'Asia/Singapore': 'Singapore' + }, + 'SK': { + 'Europe/Bratislava': 'Bratislava' + }, + 'SI': { + 'Europe/Ljubljana': 'Ljubljana' + }, + 'SB': { + 'Pacific/Guadalcanal': 'Guadalcanal' + }, + 'SO': { + 'Africa/Mogadishu': 'Mogadishu' + }, + 'ZA': { + 'Africa/Johannesburg': 'Johannesburg' + }, + 'GS': { + 'Atlantic/South_Georgia': 'South Georgia' + }, + 'KR': { + 'Asia/Seoul': 'Seoul' + }, + 'ES': { + 'Africa/Ceuta': 'Ceuta', + 'Atlantic/Canary': 'Canary', + 'Europe/Madrid': 'Madrid' + }, + 'LK': { + 'Asia/Colombo': 'Colombo' + }, + 'SD': { + 'Africa/Khartoum': 'Khartoum' + }, + 'SR': { + 'America/Paramaribo': 'Paramaribo' + }, + 'SZ': { + 'Africa/Mbabane': 'Mbabane' + }, + 'SE': { + 'Europe/Stockholm': 'Stockholm' + }, + 'CH': { + 'Europe/Zurich': 'Zurich' + }, + 'SY': { + 'Asia/Damascus': 'Damascus' + }, + 'TW': { + 'Asia/Taipei': 'Taipei' + }, + 'TJ': { + 'Asia/Dushanbe': 'Dushanbe' + }, + 'TZ': { + 'Africa/Dar_es_Salaam': 'Dar es Salaam' + }, + 'TH': { + 'Asia/Bangkok': 'Bangkok' + }, + 'BS': { + 'America/Nassau': 'Nassau' + }, + 'GM': { + 'Africa/Banjul': 'Banjul' + }, + 'TG': { + 'Africa/Lome': 'Lome' + }, + 'TO': { + 'Pacific/Tongatapu': 'Tongatapu' + }, + 'TT': { + 'America/Port_of_Spain': 'Port of Spain' + }, + 'TN': { + 'Africa/Tunis': 'Tunis' + }, + 'TR': { + 'Europe/Istanbul': 'Istanbul' + }, + 'TM': { + 'Asia/Ashgabat': 'Ashgabat' + }, + 'TC': { + 'America/Grand_Turk': 'Grand Turk' + }, + 'TV': { + 'Pacific/Funafuti': 'Funafuti' + }, + 'VI': { + 'America/St_Thomas': 'St Thomas' + }, + 'UG': { + 'Africa/Kampala': 'Kampala' + }, + 'UA': { + 'Europe/Kiev': 'Kiev', + 'Europe/Simferopol': 'Simferopol', + 'Europe/Uzhgorod': 'Uzhgorod', + 'Europe/Zaporozhye': 'Zaporozhye' + }, + 'AE': { + 'Asia/Dubai': 'Dubai' + }, + 'GB': { + 'Europe/London': 'London' + }, + 'US': { + 'America/Adak': 'Adak', + 'America/Anchorage': 'Anchorage', + 'America/Boise': 'Boise', + 'America/Chicago': 'Chicago', + 'America/Denver': 'Denver', + 'America/Detroit': 'Detroit', + 'America/Indiana/Indianapolis': 'Indiana / Indianapolis', + 'America/Indiana/Knox': 'Indiana / Knox', + 'America/Indiana/Marengo': 'Indiana / Marengo', + 'America/Indiana/Petersburg': 'Indiana / Petersburg', + 'America/Indiana/Tell_City': 'Indiana / Tell City', + 'America/Indiana/Vevay': 'Indiana / Vevay', + 'America/Indiana/Vincennes': 'Indiana / Vincennes', + 'America/Indiana/Winamac': 'Indiana / Winamac', + 'America/Juneau': 'Juneau', + 'America/Kentucky/Louisville': 'Kentucky / Louisville', + 'America/Kentucky/Monticello': 'Kentucky / Monticello', + 'America/Los_Angeles': 'Los Angeles', + 'America/Menominee': 'Menominee', + 'America/Metlakatla': 'Metlakatla', + 'America/New_York': 'New York', + 'America/Nome': 'Nome', + 'America/North_Dakota/Beulah': 'North Dakota / Beulah', + 'America/North_Dakota/Center': 'North Dakota / Center', + 'America/North_Dakota/New_Salem': 'North Dakota / New Salem', + 'America/Phoenix': 'Phoenix', + 'America/Shiprock': 'Shiprock', + 'America/Sitka': 'Sitka', + 'America/Yakutat': 'Yakutat', + 'Pacific/Honolulu': 'Honolulu' + }, + 'UY': { + 'America/Montevideo': 'Montevideo' + }, + 'UZ': { + 'Asia/Samarkand': 'Samarkand', + 'Asia/Tashkent': 'Tashkent' + }, + 'VU': { + 'Pacific/Efate': 'Efate' + }, + 'VA': { + 'Europe/Vatican': 'Vatican' + }, + 'VE': { + 'America/Caracas': 'Caracas' + }, + 'VN': { + 'Asia/Ho_Chi_Minh': 'Ho Chi Minh' + }, + 'EH': { + 'Africa/El_Aaiun': 'El Aaiun' + }, + 'YE': { + 'Asia/Aden': 'Aden' + }, + 'ZM': { + 'Africa/Lusaka': 'Lusaka' + }, + 'ZW': { + 'Africa/Harare': 'Harare' + } +}; + +/* ========================================================== + * bootstrap-formhelpers-colorpicker.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + ++function ($) { + + 'use strict'; + + + /* COLORPICKER CLASS DEFINITION + * ========================= */ + + var toggle = '[data-toggle=bfh-colorpicker]', + BFHColorPicker = function (element, options) { + this.options = $.extend({}, $.fn.bfhcolorpicker.defaults, options); + this.$element = $(element); + + this.initPopover(); + }; + + BFHColorPicker.prototype = { + + constructor: BFHColorPicker, + + initPalette: function() { + var $canvas, + context, + gradient; + + $canvas = this.$element.find('canvas'); + context = $canvas[0].getContext('2d'); + + gradient = context.createLinearGradient(0, 0, $canvas.width(), 0); + + gradient.addColorStop(0, 'rgb(255, 255, 255)'); + gradient.addColorStop(0.1, 'rgb(255, 0, 0)'); + gradient.addColorStop(0.25, 'rgb(255, 0, 255)'); + gradient.addColorStop(0.4, 'rgb(0, 0, 255)'); + gradient.addColorStop(0.55, 'rgb(0, 255, 255)'); + gradient.addColorStop(0.7, 'rgb(0, 255, 0)'); + gradient.addColorStop(0.85, 'rgb(255, 255, 0)'); + gradient.addColorStop(1, 'rgb(255, 0, 0)'); + + context.fillStyle = gradient; + context.fillRect(0, 0, context.canvas.width, context.canvas.height); + + gradient = context.createLinearGradient(0, 0, 0, $canvas.height()); + gradient.addColorStop(0, 'rgba(255, 255, 255, 1)'); + gradient.addColorStop(0.5, 'rgba(255, 255, 255, 0)'); + gradient.addColorStop(0.5, 'rgba(0, 0, 0, 0)'); + gradient.addColorStop(1, 'rgba(0, 0, 0, 1)'); + + context.fillStyle = gradient; + context.fillRect(0, 0, context.canvas.width, context.canvas.height); + }, + + initPopover: function() { + var iconLeft, + iconRight; + + iconLeft = ''; + iconRight = ''; + if (this.options.align === 'right') { + iconRight = '<span class="input-group-addon"><span class="bfh-colorpicker-icon"></span></span>'; + } else { + iconLeft = '<span class="input-group-addon"><span class="bfh-colorpicker-icon"></span></span>'; + } + + this.$element.html( + '<div class="input-group bfh-colorpicker-toggle" data-toggle="bfh-colorpicker">' + + iconLeft + + '<input type="text" name="' + this.options.name + '" class="' + this.options.input + '" placeholder="' + this.options.placeholder + '" readonly>' + + iconRight + + '</div>' + + '<div class="bfh-colorpicker-popover">' + + '<canvas class="bfh-colorpicker-palette" width="384" height="256"></canvas>' + + '</div>' + ); + + this.$element + .on('click.bfhcolorpicker.data-api touchstart.bfhcolorpicker.data-api', toggle, BFHColorPicker.prototype.toggle) + .on('mousedown.bfhcolorpicker.data-api', 'canvas', BFHColorPicker.prototype.mouseDown) + .on('click.bfhcolorpicker.data-api touchstart.bfhcolorpicker.data-api', '.bfh-colorpicker-popover', function() { return false; }); + + this.initPalette(); + + this.$element.val(this.options.color); + }, + + updateVal: function(positionX, positionY) { + var $canvas, + context, + colorX, + colorY, + snappiness, + imageData, + newColor; + + snappiness = 5; + + $canvas = this.$element.find('canvas'); + context = $canvas[0].getContext('2d'); + + colorX = positionX - $canvas.offset().left; + colorY = positionY - $canvas.offset().top; + + colorX = Math.round(colorX / snappiness) * snappiness; + colorY = Math.round(colorY / snappiness) * snappiness; + + if (colorX < 0) { + colorX = 0; + } + if (colorX >= $canvas.width()) { + colorX = $canvas.width() - 1; + } + + if (colorY < 0) { + colorY = 0; + } + if (colorY > $canvas.height()) { + colorY = $canvas.height(); + } + + imageData = context.getImageData(colorX, colorY, 1, 1); + newColor = rgbToHex(imageData.data[0], imageData.data[1], imageData.data[2]); + + if (newColor !== this.$element.val()) { + this.$element.val(newColor); + + this.$element.trigger('change.bfhcolorpicker'); + } + }, + + mouseDown: function(e) { + var $this, + $parent; + + $this = $(this); + $parent = getParent($this); + + $(document) + .on('mousemove.bfhcolorpicker.data-api', {colorpicker: $parent}, BFHColorPicker.prototype.mouseMove) + .one('mouseup.bfhcolorpicker.data-api', {colorpicker: $parent}, BFHColorPicker.prototype.mouseUp); + }, + + mouseMove: function(e) { + var $this; + + $this = e.data.colorpicker; + + $this.data('bfhcolorpicker').updateVal(e.pageX, e.pageY); + }, + + mouseUp: function(e) { + var $this; + + $this = e.data.colorpicker; + + $this.data('bfhcolorpicker').updateVal(e.pageX, e.pageY); + + $(document).off('mousemove.bfhcolorpicker.data-api'); + + if ($this.data('bfhcolorpicker').options.close === true) { + clearMenus(); + } + }, + + toggle: function (e) { + var $this, + $parent, + isActive; + + $this = $(this); + $parent = getParent($this); + + if ($parent.is('.disabled') || $parent.attr('disabled') !== undefined) { + return true; + } + + isActive = $parent.hasClass('open'); + + clearMenus(); + + if (!isActive) { + $parent.trigger(e = $.Event('show.bfhcolorpicker')); + + if (e.isDefaultPrevented()) { + return true; + } + + $parent + .toggleClass('open') + .trigger('shown.bfhcolorpicker'); + + $this.focus(); + } + + return false; + } + }; + + function componentToHex(c) { + var hex = c.toString(16); + return hex.length === 1 ? '0' + hex : hex; + } + + function rgbToHex(r, g, b) { + return '#' + componentToHex(r) + componentToHex(g) + componentToHex(b); + } + + function clearMenus() { + var $parent; + + $(toggle).each(function (e) { + $parent = getParent($(this)); + + if (!$parent.hasClass('open')) { + return true; + } + + $parent.trigger(e = $.Event('hide.bfhcolorpicker')); + + if (e.isDefaultPrevented()) { + return true; + } + + $parent + .removeClass('open') + .trigger('hidden.bfhcolorpicker'); + }); + } + + function getParent($this) { + return $this.closest('.bfh-colorpicker'); + } + + + /* COLORPICKER PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.bfhcolorpicker; + + $.fn.bfhcolorpicker = function (option) { + return this.each(function () { + var $this, + data, + options; + + $this = $(this); + data = $this.data('bfhcolorpicker'); + options = typeof option === 'object' && option; + this.type = 'bfhcolorpicker'; + + if (!data) { + $this.data('bfhcolorpicker', (data = new BFHColorPicker(this, options))); + } + if (typeof option === 'string') { + data[option].call($this); + } + }); + }; + + $.fn.bfhcolorpicker.Constructor = BFHColorPicker; + + $.fn.bfhcolorpicker.defaults = { + align: 'left', + input: 'form-control', + placeholder: '', + name: '', + color: '#000000', + close: true + }; + + + /* COLORPICKER NO CONFLICT + * ========================== */ + + $.fn.bfhcolorpicker.noConflict = function () { + $.fn.bfhcolorpicker = old; + return this; + }; + + + /* COLORPICKER VALHOOKS + * ========================== */ + + var origHook; + if ($.valHooks.div){ + origHook = $.valHooks.div; + } + $.valHooks.div = { + get: function(el) { + if ($(el).hasClass('bfh-colorpicker')) { + return $(el).find('input[type="text"]').val(); + } else if (origHook) { + return origHook.get(el); + } + }, + set: function(el, val) { + if ($(el).hasClass('bfh-colorpicker')) { + $(el).find('.bfh-colorpicker-icon').css('background-color', val); + $(el).find('input[type="text"]').val(val); + } else if (origHook) { + return origHook.set(el,val); + } + } + }; + + + /* COLORPICKER DATA-API + * ============== */ + + $(document).ready( function () { + $('div.bfh-colorpicker').each(function () { + var $colorpicker; + + $colorpicker = $(this); + + $colorpicker.bfhcolorpicker($colorpicker.data()); + }); + }); + + + /* APPLY TO STANDARD COLORPICKER ELEMENTS + * =================================== */ + + $(document) + .on('click.bfhcolorpicker.data-api', clearMenus); + +}(window.jQuery); +/* ========================================================== + * bootstrap-formhelpers-countries.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + ++function ($) { + + 'use strict'; + + + /* COUNTRIES CLASS DEFINITION + * ====================== */ + + var BFHCountries = function (element, options) { + this.options = $.extend({}, $.fn.bfhcountries.defaults, options); + this.$element = $(element); + + if (this.$element.is('select')) { + this.addCountries(); + } + + if (this.$element.hasClass('bfh-selectbox')) { + this.addBootstrapCountries(); + } + + if (this.$element.is('span')) { + this.displayCountry(); + } + }; + + BFHCountries.prototype = { + + constructor: BFHCountries, + + getCountries: function() { + var country, + countries; + + if (this.options.available) { + if (typeof this.options.available === 'string') { + countries = []; + + this.options.available = this.options.available.split(','); + + for (country in BFHCountriesList) { + if (BFHCountriesList.hasOwnProperty(country)) { + if ($.inArray(country, this.options.available) >= 0) { + countries[country] = BFHCountriesList[country]; + } + } + } + } else { + countries = this.options.available; + } + + return countries; + } else { + return BFHCountriesList; + } + }, + + addCountries: function () { + var value, + country, + countries; + + value = this.options.country; + countries = this.getCountries(); + + this.$element.html(''); + + if (this.options.blank === true) { + this.$element.append('<option value=""></option>'); + } + + for (country in countries) { + if (countries.hasOwnProperty(country)) { + this.$element.append('<option value="' + country + '">' + countries[country] + '</option>'); + } + } + + this.$element.val(value); + }, + + addBootstrapCountries: function() { + var $input, + $toggle, + $options, + value, + country, + countries; + + value = this.options.country; + $input = this.$element.find('input[type="hidden"]'); + $toggle = this.$element.find('.bfh-selectbox-option'); + $options = this.$element.find('[role=option]'); + countries = this.getCountries(); + + $options.html(''); + + if (this.options.blank === true) { + $options.append('<li><a tabindex="-1" href="#" data-option=""></a></li>'); + } + + for (country in countries) { + if (countries.hasOwnProperty(country)) { + if (this.options.flags === true) { + $options.append('<li><a tabindex="-1" href="#" data-option="' + country + '"><i class="glyphicon bfh-flag-' + country + '"></i>' + countries[country] + '</a></li>'); + } else { + $options.append('<li><a tabindex="-1" href="#" data-option="' + country + '">' + countries[country] + '</a></li>'); + } + } + } + + this.$element.val(value); + }, + + displayCountry: function () { + var value; + + value = this.options.country; + + if (this.options.flags === true) { + this.$element.html('<i class="glyphicon bfh-flag-' + value + '"></i> ' + BFHCountriesList[value]); + } else { + this.$element.html(BFHCountriesList[value]); + } + } + + }; + + + /* COUNTRY PLUGIN DEFINITION + * ======================= */ + + var old = $.fn.bfhcountries; + + $.fn.bfhcountries = function (option) { + return this.each(function () { + var $this, + data, + options; + + $this = $(this); + data = $this.data('bfhcountries'); + options = typeof option === 'object' && option; + + if (!data) { + $this.data('bfhcountries', (data = new BFHCountries(this, options))); + } + if (typeof option === 'string') { + data[option].call($this); + } + }); + }; + + $.fn.bfhcountries.Constructor = BFHCountries; + + $.fn.bfhcountries.defaults = { + country: '', + available: '', + flags: false, + blank: true + }; + + + /* COUNTRY NO CONFLICT + * ========================== */ + + $.fn.bfhcountries.noConflict = function () { + $.fn.bfhcountries = old; + return this; + }; + + + /* COUNTRY DATA-API + * ============== */ + + $(document).ready( function () { + $('form select.bfh-countries, span.bfh-countries, div.bfh-countries').each(function () { + var $countries; + + $countries = $(this); + + if ($countries.hasClass('bfh-selectbox')) { + $countries.bfhselectbox($countries.data()); + } + $countries.bfhcountries($countries.data()); + }); + }); + +}(window.jQuery); + +/* ========================================================== + * bootstrap-formhelpers-currencies.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2013 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + ++function ($) { + + 'use strict'; + + + /* COUNTRIES CLASS DEFINITION + * ====================== */ + + var BFHCurrencies = function (element, options) { + this.options = $.extend({}, $.fn.bfhcurrencies.defaults, options); + this.$element = $(element); + + if (this.$element.is('select')) { + this.addCurrencies(); + } + + if (this.$element.hasClass('bfh-selectbox')) { + this.addBootstrapCurrencies(); + } + + if (this.$element.is('span')) { + this.displayCurrency(); + } + }; + + BFHCurrencies.prototype = { + + constructor: BFHCurrencies, + + getCurrencies: function () { + var currency, + currencies; + + if (this.options.available) { + currencies = []; + + this.options.available = this.options.available.split(','); + + for (currency in BFHCurrenciesList) { + if (BFHCurrenciesList.hasOwnProperty(currency)) { + if ($.inArray(currency, this.options.available) >= 0) { + currencies[currency] = BFHCurrenciesList[currency]; + } + } + } + + return currencies; + } else { + return BFHCurrenciesList; + } + }, + + addCurrencies: function () { + var value, + currency, + currencies; + + value = this.options.currency; + currencies = this.getCurrencies(); + + this.$element.html(''); + + if (this.options.blank === true) { + this.$element.append('<option value=""></option>'); + } + + for (currency in currencies) { + if (currencies.hasOwnProperty(currency)) { + this.$element.append('<option value="' + currency + '">' + currencies[currency].label + '</option>'); + } + } + + this.$element.val(value); + }, + + + addBootstrapCurrencies: function() { + var $input, + $toggle, + $options, + value, + currency, + currencies, + flag; + + value = this.options.currency; + $input = this.$element.find('input[type="hidden"]'); + $toggle = this.$element.find('.bfh-selectbox-option'); + $options = this.$element.find('[role=option]'); + currencies = this.getCurrencies(); + + $options.html(''); + + if (this.options.blank === true) { + $options.append('<li><a tabindex="-1" href="#" data-option=""></a></li>'); + } + + for (currency in currencies) { + if (currencies.hasOwnProperty(currency)) { + if (this.options.flags === true) { + if (currencies[currency].currencyflag) { + flag = currencies[currency].currencyflag; + } else { + flag = currency.substr(0,2); + } + $options.append('<li><a tabindex="-1" href="#" data-option="' + currency + '"><i class="glyphicon bfh-flag-' + flag + '"></i>' + currencies[currency].label + '</a></li>'); + } else { + $options.append('<li><a tabindex="-1" href="#" data-option="' + currency + '">' + currencies[currency].label + '</a></li>'); + } + } + } + + this.$element.val(value); + }, + + displayCurrency: function () { + var value, + flag; + + value = this.options.currency; + + if (this.options.flags === true) { + if (BFHCurrenciesList[value].currencyflag) { + flag = BFHCurrenciesList[value].currencyflag; + } else { + flag = value.substr(0,2); + } + this.$element.html('<i class="glyphicon bfh-flag-' + flag + '"></i> ' + BFHCurrenciesList[value].label); + } else { + this.$element.html(BFHCurrenciesList[value].label); + } + } + + }; + + + /* CURRENCY PLUGIN DEFINITION + * ======================= */ + + var old = $.fn.bfhcurrencies; + + $.fn.bfhcurrencies = function (option) { + return this.each(function () { + var $this, + data, + options; + + $this = $(this); + data = $this.data('bfhcurrencies'); + options = typeof option === 'object' && option; + + if (!data) { + $this.data('bfhcurrencies', (data = new BFHCurrencies(this, options))); + } + if (typeof option === 'string') { + data[option].call($this); + } + }); + }; + + $.fn.bfhcurrencies.Constructor = BFHCurrencies; + + $.fn.bfhcurrencies.defaults = { + currency: '', + available: '', + flags: false, + blank: true + }; + + + /* CURRENCY NO CONFLICT + * ========================== */ + + $.fn.bfhcurrencies.noConflict = function () { + $.fn.bfhcurrencies = old; + return this; + }; + + + /* CURRENCY DATA-API + * ============== */ + + $(document).ready( function () { + $('form select.bfh-currencies, span.bfh-currencies, div.bfh-currencies').each(function () { + var $currencies; + + $currencies = $(this); + + if ($currencies.hasClass('bfh-selectbox')) { + $currencies.bfhselectbox($currencies.data()); + } + $currencies.bfhcurrencies($currencies.data()); + }); + }); + + +}(window.jQuery); + +/* ========================================================== + * bootstrap-formhelpers-datepicker.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + ++function ($) { + + 'use strict'; + + + /* BFHDATEPICKER CLASS DEFINITION + * ========================= */ + + var toggle = '[data-toggle=bfh-datepicker]', + BFHDatePicker = function (element, options) { + this.options = $.extend({}, $.fn.bfhdatepicker.defaults, options); + this.$element = $(element); + + this.initCalendar(); + }; + + BFHDatePicker.prototype = { + + constructor: BFHDatePicker, + + setDate: function() { + var date, + today, + format; + + date = this.options.date; + format = this.options.format; + + if (date === '' || date === 'today' || date === undefined) { + today = new Date(); + + if (date === 'today') { + this.$element.val(formatDate(format, today.getMonth(), today.getFullYear(), today.getDate())); + } + + this.$element.data('month', today.getMonth()); + this.$element.data('year', today.getFullYear()); + } else { + this.$element.val(date); + this.$element.data('month', Number(getDatePart(format, date, 'm') - 1)); + this.$element.data('year', Number(getDatePart(format, date, 'y'))); + } + }, + + setDateLimit: function(date, limitPrefix) { + var today, + format; + + format = this.options.format; + + if (date !== '') { + this.$element.data(limitPrefix + 'limit', true); + + if (date === 'today') { + today = new Date(); + + this.$element.data(limitPrefix + 'day', today.getDate()); + this.$element.data(limitPrefix + 'month', today.getMonth()); + this.$element.data(limitPrefix + 'year', today.getFullYear()); + } else { + this.$element.data(limitPrefix + 'day', Number(getDatePart(format, date, 'd'))); + this.$element.data(limitPrefix + 'month', Number(getDatePart(format, date, 'm') - 1)); + this.$element.data(limitPrefix + 'year', Number(getDatePart(format, date, 'y'))); + } + } else { + this.$element.data(limitPrefix + 'limit', false); + } + }, + + initCalendar: function() { + var iconLeft, + iconRight, + iconAddon; + + iconLeft = ''; + iconRight = ''; + iconAddon = ''; + if (this.options.icon !== '') { + if (this.options.align === 'right') { + iconRight = '<span class="input-group-addon"><i class="' + this.options.icon + '"></i></span>'; + } else { + iconLeft = '<span class="input-group-addon"><i class="' + this.options.icon + '"></i></span>'; + } + iconAddon = 'input-group'; + } + + this.$element.html( + '<div class="' + iconAddon + ' bfh-datepicker-toggle" data-toggle="bfh-datepicker">' + + iconLeft + + '<input type="text" name="' + this.options.name + '" class="' + this.options.input + '" placeholder="' + this.options.placeholder + '" readonly>' + + iconRight + + '</div>' + + '<div class="bfh-datepicker-calendar">' + + '<table class="calendar table table-bordered">' + + '<thead>' + + '<tr class="months-header">' + + '<th class="month" colspan="4">' + + '<a class="previous" href="#"><i class="glyphicon glyphicon-chevron-left"></i></a>' + + '<span></span>' + + '<a class="next" href="#"><i class="glyphicon glyphicon-chevron-right"></i></a>' + + '</th>' + + '<th class="year" colspan="3">' + + '<a class="previous" href="#"><i class="glyphicon glyphicon-chevron-left"></i></a>' + + '<span></span>' + + '<a class="next" href="#"><i class="glyphicon glyphicon-chevron-right"></i></a>' + + '</th>' + + '</tr>' + + '<tr class="days-header">' + + '</tr>' + + '</thead>' + + '<tbody>' + + '</tbody>' + + '</table>' + + '</div>' + ); + + this.$element + .on('click.bfhdatepicker.data-api touchstart.bfhdatepicker.data-api', toggle, BFHDatePicker.prototype.toggle) + .on('click.bfhdatepicker.data-api touchstart.bfhdatepicker.data-api', '.bfh-datepicker-calendar > table.calendar .month > .previous', BFHDatePicker.prototype.previousMonth) + .on('click.bfhdatepicker.data-api touchstart.bfhdatepicker.data-api', '.bfh-datepicker-calendar > table.calendar .month > .next', BFHDatePicker.prototype.nextMonth) + .on('click.bfhdatepicker.data-api touchstart.bfhdatepicker.data-api', '.bfh-datepicker-calendar > table.calendar .year > .previous', BFHDatePicker.prototype.previousYear) + .on('click.bfhdatepicker.data-api touchstart.bfhdatepicker.data-api', '.bfh-datepicker-calendar > table.calendar .year > .next', BFHDatePicker.prototype.nextYear) + .on('click.bfhdatepicker.data-api touchstart.bfhdatepicker.data-api', '.bfh-datepicker-calendar > table.calendar td:not(.off)', BFHDatePicker.prototype.select) + .on('click.bfhdatepicker.data-api touchstart.bfhdatepicker.data-api', '.bfh-datepicker-calendar > table.calendar', function() { return false; }); + + this.setDate(); + this.setDateLimit(this.options.min, 'lower'); + this.setDateLimit(this.options.max, 'higher'); + + this.updateCalendar(); + }, + + updateCalendarHeader: function($calendar, month, year) { + var $daysHeader, + day; + + $calendar.find('table > thead > tr > th.month > span').text(BFHMonthsList[month]); + $calendar.find('table > thead > tr > th.year > span').text(year); + + $daysHeader = $calendar.find('table > thead > tr.days-header'); + $daysHeader.html(''); + for (day=BFHDayOfWeekStart; day < BFHDaysList.length; day=day+1) { + $daysHeader.append('<th>' + BFHDaysList[day] + '</th>'); + } + for (day=0; day < BFHDayOfWeekStart; day=day+1) { + $daysHeader.append('<th>' + BFHDaysList[day] + '</th>'); + } + }, + + checkMinDate: function(day, month, year) { + var lowerlimit, + lowerday, + lowermonth, + loweryear; + + lowerlimit = this.$element.data('lowerlimit'); + + if (lowerlimit === true) { + lowerday = this.$element.data('lowerday'); + lowermonth = this.$element.data('lowermonth'); + loweryear = this.$element.data('loweryear'); + + if ((day < lowerday && month === lowermonth && year === loweryear) || (month < lowermonth && year === loweryear) || (year < loweryear)) { + return true; + } + } + + return false; + }, + + checkMaxDate: function(day, month, year) { + var higherlimit, + higherday, + highermonth, + higheryear; + + higherlimit = this.$element.data('higherlimit'); + + if (higherlimit === true) { + higherday = this.$element.data('higherday'); + highermonth = this.$element.data('highermonth'); + higheryear = this.$element.data('higheryear'); + + if ((day > higherday && month === highermonth && year === higheryear) || (month > highermonth && year === higheryear) || (year > higheryear)) { + return true; + } + } + + return false; + }, + + checkToday: function(day, month, year) { + var today; + + today = new Date(); + + if (day === today.getDate() && month === today.getMonth() && year === today.getFullYear()) { + return true; + } + + return false; + }, + + updateCalendarDays: function($calendar, month, year) { + var $days, + numDaysPreviousMonth, + numDaysCurrentMonth, + firstDay, + lastDay, + row, + day; + + $days = $calendar.find('table > tbody').html(''); + numDaysPreviousMonth = getNumDaysInMonth(month, year); + numDaysCurrentMonth = getNumDaysInMonth(month + 1, year); + firstDay = getDayOfWeek(month, year, 1); + lastDay = getDayOfWeek(month, year, numDaysCurrentMonth); + + row = ''; + for (day=0; day < (firstDay - BFHDayOfWeekStart + 7) % 7; day=day+1) { + row += '<td class="off">' + (numDaysPreviousMonth - (firstDay - BFHDayOfWeekStart + 7) % 7 + day + 1) + '</td>'; + } + + for (day=1; day <= numDaysCurrentMonth; day=day+1) { + if (this.checkMinDate(day, month, year)) { + row += '<td data-day="' + day + '" class="off">' + day + '</td>'; + } else if (this.checkMaxDate(day, month, year)) { + row += '<td data-day="' + day + '" class="off">' + day + '</td>'; + } else if (this.checkToday(day, month, year)) { + row += '<td data-day="' + day + '" class="today">' + day + '</td>'; + } else { + row += '<td data-day="' + day + '">' + day + '</td>'; + } + if (getDayOfWeek(month, year, day) === (6 + BFHDayOfWeekStart) % 7) { + $days.append('<tr>' + row + '</tr>'); + row = ''; + } + } + + for (day=1; day <= (7 - ((lastDay + 1 - BFHDayOfWeekStart + 7) % 7)) % 7 + 1; day=day+1) { + row += '<td class="off">' + day + '</td>'; + if (day === (7 - ((lastDay + 1 - BFHDayOfWeekStart + 7) % 7)) % 7) { + $days.append('<tr>' + row + '</tr>'); + } + } + }, + + updateCalendar: function () { + var $calendar, + month, + year; + + $calendar = this.$element.find('.bfh-datepicker-calendar'); + month = this.$element.data('month'); + year = this.$element.data('year'); + + this.updateCalendarHeader($calendar, month, year); + this.updateCalendarDays($calendar, month, year); + }, + + previousMonth: function () { + var $this, + $parent, + $datePicker; + + $this = $(this); + $parent = getParent($this); + + if (Number($parent.data('month')) === 0) { + $parent.data('month', 11); + $parent.data('year', Number($parent.data('year')) - 1); + } else { + $parent.data('month', Number($parent.data('month')) - 1); + } + + $datePicker = $parent.data('bfhdatepicker'); + $datePicker.updateCalendar(); + + return false; + }, + + nextMonth: function () { + var $this, + $parent, + $datePicker; + + $this = $(this); + $parent = getParent($this); + + if (Number($parent.data('month')) === 11) { + $parent.data('month', 0); + $parent.data('year', Number($parent.data('year')) + 1); + } else { + $parent.data('month', Number($parent.data('month')) + 1); + } + + $datePicker = $parent.data('bfhdatepicker'); + $datePicker.updateCalendar(); + + return false; + }, + + previousYear: function () { + var $this, + $parent, + $datePicker; + + $this = $(this); + $parent = getParent($this); + + $parent.data('year', Number($parent.data('year')) - 1); + + $datePicker = $parent.data('bfhdatepicker'); + $datePicker.updateCalendar(); + + return false; + }, + + nextYear: function () { + var $this, + $parent, + $datePicker; + + $this = $(this); + $parent = getParent($this); + + $parent.data('year', Number($parent.data('year')) + 1); + + $datePicker = $parent.data('bfhdatepicker'); + $datePicker.updateCalendar(); + + return false; + }, + + select: function (e) { + var $this, + $parent, + $datePicker, + month, + year, + day; + + $this = $(this); + + e.preventDefault(); + e.stopPropagation(); + + $parent = getParent($this); + $datePicker = $parent.data('bfhdatepicker'); + month = $parent.data('month'); + year = $parent.data('year'); + day = $this.data('day'); + + $parent.val(formatDate($datePicker.options.format, month, year, day)); + $parent.trigger('change.bfhdatepicker'); + + if ($datePicker.options.close === true) { + clearMenus(); + } + }, + + toggle: function (e) { + var $this, + $parent, + isActive; + + $this = $(this); + $parent = getParent($this); + + if ($parent.is('.disabled') || $parent.attr('disabled') !== undefined) { + return true; + } + + isActive = $parent.hasClass('open'); + + clearMenus(); + + if (!isActive) { + $parent.trigger(e = $.Event('show.bfhdatepicker')); + + if (e.isDefaultPrevented()) { + return true; + } + + $parent + .toggleClass('open') + .trigger('shown.bfhdatepicker'); + + $this.focus(); + } + + return false; + } + }; + + function getNumDaysInMonth(month, year) { + return new Date(year, month, 0).getDate(); + } + + function getDayOfWeek(month, year, day) { + return new Date(year, month, day).getDay(); + } + + function formatDate(format, month, year, day) { + month += 1; + month = String(month); + day = String(day); + + if (month.length === 1) { + month = '0' + month; + } + if (day.length === 1) { + day = '0' + day; + } + + return format.replace('m', month).replace('y', year).replace('d', day); + } + + function getDatePart(format, date, part) { + var partPositions, + partPosition, + parts; + + partPositions = [ + {'part': 'm', 'position': format.indexOf('m')}, + {'part': 'y', 'position': format.indexOf('y')}, + {'part': 'd', 'position': format.indexOf('d')} + ]; + + partPositions.sort(function(a, b) {return a.position - b.position;}); + + parts = date.match(/(\d+)/g); + + for (partPosition in partPositions) { + if (partPositions.hasOwnProperty(partPosition)) { + if (partPositions[partPosition].part === part) { + return Number(parts[partPosition]).toString(); + } + } + } + } + + function clearMenus() { + var $parent; + + $(toggle).each(function (e) { + $parent = getParent($(this)); + + if (!$parent.hasClass('open')) { + return true; + } + + $parent.trigger(e = $.Event('hide.bfhdatepicker')); + + if (e.isDefaultPrevented()) { + return true; + } + + $parent + .removeClass('open') + .trigger('hidden.bfhdatepicker'); + }); + } + + function getParent($this) { + return $this.closest('.bfh-datepicker'); + } + + + /* DATEPICKER PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.bfhdatepicker; + + $.fn.bfhdatepicker = function (option) { + return this.each(function () { + var $this, + data, + options; + + $this = $(this); + data = $this.data('bfhdatepicker'); + options = typeof option === 'object' && option; + this.type = 'bfhdatepicker'; + + if (!data) { + $this.data('bfhdatepicker', (data = new BFHDatePicker(this, options))); + } + if (typeof option === 'string') { + data[option].call($this); + } + }); + }; + + $.fn.bfhdatepicker.Constructor = BFHDatePicker; + + $.fn.bfhdatepicker.defaults = { + icon: 'glyphicon glyphicon-calendar', + align: 'left', + input: 'form-control', + placeholder: '', + name: '', + date: 'today', + format: 'm/d/y', + min: '', + max: '', + close: true + }; + + + /* DATEPICKER NO CONFLICT + * ========================== */ + + $.fn.bfhdatepicker.noConflict = function () { + $.fn.bfhdatepicker = old; + return this; + }; + + + /* DATEPICKER VALHOOKS + * ========================== */ + + var origHook; + if ($.valHooks.div){ + origHook = $.valHooks.div; + } + $.valHooks.div = { + get: function(el) { + if ($(el).hasClass('bfh-datepicker')) { + return $(el).find('input[type="text"]').val(); + } else if (origHook) { + return origHook.get(el); + } + }, + set: function(el, val) { + if ($(el).hasClass('bfh-datepicker')) { + $(el).find('input[type="text"]').val(val); + } else if (origHook) { + return origHook.set(el,val); + } + } + }; + + + /* DATEPICKER DATA-API + * ============== */ + + $(document).ready( function () { + $('div.bfh-datepicker').each(function () { + var $datepicker; + + $datepicker = $(this); + + $datepicker.bfhdatepicker($datepicker.data()); + }); + }); + + + /* APPLY TO STANDARD DATEPICKER ELEMENTS + * =================================== */ + + $(document) + .on('click.bfhdatepicker.data-api', clearMenus); + +}(window.jQuery); + +/* ========================================================== + * bootstrap-formhelpers-fonts.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * contributed by Aaron Collegeman, Squidoo, 2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + ++function ($) { + + 'use strict'; + + + /* FONTS CLASS DEFINITION + * ====================== */ + + var BFHFonts = function (element, options) { + this.options = $.extend({}, $.fn.bfhfonts.defaults, options); + this.$element = $(element); + + if (this.$element.is('select')) { + this.addFonts(); + } + + if (this.$element.hasClass('bfh-selectbox')) { + this.addBootstrapFonts(); + } + }; + + BFHFonts.prototype = { + + constructor: BFHFonts, + + getFonts: function() { + var font, + fonts; + + if (this.options.available) { + fonts = []; + + this.options.available = this.options.available.split(','); + + for (font in BFHFontsList) { + if (BFHFontsList.hasOwnProperty(font)) { + if ($.inArray(font, this.options.available) >= 0) { + fonts[font] = BFHFontsList[font]; + } + } + } + + return fonts; + } else { + return BFHFontsList; + } + }, + + addFonts: function () { + var value, + font, + fonts; + + value = this.options.font; + fonts = this.getFonts(); + + this.$element.html(''); + + if (this.options.blank === true) { + this.$element.append('<option value=""></option>'); + } + + for (font in fonts) { + if (fonts.hasOwnProperty(font)) { + this.$element.append('<option value="' + font + '">' + font + '</option>'); + } + } + + this.$element.val(value); + }, + + addBootstrapFonts: function() { + var $input, + $toggle, + $options, + value, + font, + fonts; + + value = this.options.font; + $input = this.$element.find('input[type="hidden"]'); + $toggle = this.$element.find('.bfh-selectbox-option'); + $options = this.$element.find('[role=option]'); + fonts = this.getFonts(); + + $options.html(''); + + if (this.options.blank === true) { + $options.append('<li><a tabindex="-1" href="#" data-option=""></a></li>'); + } + + for (font in fonts) { + if (fonts.hasOwnProperty(font)) { + $options.append('<li><a tabindex="-1" href="#" style=\'font-family: ' + fonts[font] + '\' data-option="' + font + '">' + font + '</a></li>'); + } + } + + this.$element.val(value); + } + + }; + + + /* FONTS PLUGIN DEFINITION + * ======================= */ + + var old = $.fn.bfhfonts; + + $.fn.bfhfonts = function (option) { + return this.each(function () { + var $this, + data, + options; + + $this = $(this); + data = $this.data('bfhfonts'); + options = typeof option === 'object' && option; + + if (!data) { + $this.data('bfhfonts', (data = new BFHFonts(this, options))); + } + if (typeof option === 'string') { + data[option].call($this); + } + }); + }; + + $.fn.bfhfonts.Constructor = BFHFonts; + + $.fn.bfhfonts.defaults = { + font: '', + available: '', + blank: true + }; + + + /* FONTS NO CONFLICT + * ========================== */ + + $.fn.bfhfonts.noConflict = function () { + $.fn.bfhfonts = old; + return this; + }; + + + /* FONTS DATA-API + * ============== */ + + $(document).ready( function () { + $('form select.bfh-fonts, span.bfh-fonts, div.bfh-fonts').each(function () { + var $fonts; + + $fonts = $(this); + + if ($fonts.hasClass('bfh-selectbox')) { + $fonts.bfhselectbox($fonts.data()); + } + $fonts.bfhfonts($fonts.data()); + }); + }); + +}(window.jQuery); + +/* ========================================================== + * bootstrap-formhelpers-fontsizes.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * contributed by Aaron Collegeman, Squidoo, 2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + ++function ($) { + + 'use strict'; + + + /* FONTSIZES CLASS DEFINITION + * ====================== */ + + var BFHFontSizes = function (element, options) { + this.options = $.extend({}, $.fn.bfhfontsizes.defaults, options); + this.$element = $(element); + + if (this.$element.is('select')) { + this.addFontSizes(); + } + + if (this.$element.hasClass('bfh-selectbox')) { + this.addBootstrapFontSizes(); + } + }; + + BFHFontSizes.prototype = { + + constructor: BFHFontSizes, + + getFontsizes: function() { + var fontsize, + fontsizes; + + if (this.options.available) { + fontsizes = []; + + this.options.available = this.options.available.split(','); + + for (fontsize in BFHFontSizesList) { + if (BFHFontSizesList.hasOwnProperty(fontsize)) { + if ($.inArray(fontsize, this.options.available) >= 0) { + fontsizes[fontsize] = BFHFontSizesList[fontsize]; + } + } + } + + return fontsizes; + } else { + return BFHFontSizesList; + } + }, + + addFontSizes: function () { + var value, + fontsize, + fontsizes; + + value = this.options.fontsize; + fontsizes = this.getFontsizes(); + + this.$element.html(''); + + if (this.options.blank === true) { + this.$element.append('<option value=""></option>'); + } + + for (fontsize in fontsizes) { + if (fontsizes.hasOwnProperty(fontsize)) { + this.$element.append('<option value="' + fontsize + '">' + fontsizes[fontsize] + '</option>'); + } + } + + this.$element.val(value); + }, + + addBootstrapFontSizes: function() { + var $input, + $toggle, + $options, + value, + fontsize, + fontsizes; + + value = this.options.fontsize; + $input = this.$element.find('input[type="hidden"]'); + $toggle = this.$element.find('.bfh-selectbox-option'); + $options = this.$element.find('[role=option]'); + fontsizes = this.getFontsizes(); + + $options.html(''); + + if (this.options.blank === true) { + $options.append('<li><a tabindex="-1" href="#" data-option=""></a></li>'); + } + + for (fontsize in fontsizes) { + if (fontsizes.hasOwnProperty(fontsize)) { + $options.append('<li><a tabindex="-1" href="#" data-option="' + fontsize + '">' + fontsizes[fontsize] + '</a></li>'); + } + } + + this.$element.val(value); + } + + }; + + + /* FONTSIZES PLUGIN DEFINITION + * ======================= */ + + var old = $.fn.bfhfontsizes; + + $.fn.bfhfontsizes = function (option) { + return this.each(function () { + var $this, + data, + options; + + $this = $(this); + data = $this.data('bfhfontsizes'); + options = typeof option === 'object' && option; + + if (!data) { + $this.data('bfhfontsizes', (data = new BFHFontSizes(this, options))); + } + if (typeof option === 'string') { + data[option].call($this); + } + }); + }; + + $.fn.bfhfontsizes.Constructor = BFHFontSizes; + + $.fn.bfhfontsizes.defaults = { + fontsize: '', + available: '', + blank: true + }; + + + /* FONTSIZES NO CONFLICT + * ========================== */ + + $.fn.bfhfontsizes.noConflict = function () { + $.fn.bfhfontsizes = old; + return this; + }; + + + /* FONTSIZES DATA-API + * ============== */ + + $(document).ready( function () { + $('form select.bfh-fontsizes, span.bfh-fontsizes, div.bfh-fontsizes').each(function () { + var $fontSizes; + + $fontSizes = $(this); + + if ($fontSizes.hasClass('bfh-selectbox')) { + $fontSizes.bfhselectbox($fontSizes.data()); + } + $fontSizes.bfhfontsizes($fontSizes.data()); + }); + }); + +}(window.jQuery); + +/* ========================================================== + * bootstrap-formhelpers-googlefonts.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * contributed by Aaron Collegeman, Squidoo, 2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + ++function ($) { + + 'use strict'; + + + /* GOOGLE FONTS CLASS DEFINITION + * ====================== */ + + var BFHGoogleFonts = function (element, options) { + this.options = $.extend({}, $.fn.bfhgooglefonts.defaults, options); + this.$element = $(element); + + if (this.$element.is('select')) { + this.addFonts(); + } + + if (this.$element.hasClass('bfh-selectbox')) { + this.addBootstrapFonts(); + } + }; + + BFHGoogleFonts.prototype = { + + constructor: BFHGoogleFonts, + + getFonts: function() { + var font, + fonts; + + fonts = []; + + if (this.options.subset) { + for (font in BFHGoogleFontsList.items) { + if (BFHGoogleFontsList.items.hasOwnProperty(font)) { + if ($.inArray(this.options.subset, BFHGoogleFontsList.items[font].subsets) >= 0) { + fonts[BFHGoogleFontsList.items[font].family] = { + 'info': BFHGoogleFontsList.items[font], + 'index': parseInt(font, 10) + }; + } + } + } + } else if (this.options.available) { + this.options.available = this.options.available.split(','); + + for (font in BFHGoogleFontsList.items) { + if (BFHGoogleFontsList.items.hasOwnProperty(font)) { + if ($.inArray(BFHGoogleFontsList.items[font].family, this.options.available) >= 0) { + fonts[BFHGoogleFontsList.items[font].family] = { + 'info': BFHGoogleFontsList.items[font], + 'index': parseInt(font, 10) + }; + } + } + } + } else { + for (font in BFHGoogleFontsList.items) { + if (BFHGoogleFontsList.items.hasOwnProperty(font)) { + fonts[BFHGoogleFontsList.items[font].family] = { + 'info': BFHGoogleFontsList.items[font], + 'index': parseInt(font, 10) + }; + } + } + } + + return fonts; + }, + + addFonts: function () { + var value, + font, + fonts; + + value = this.options.font; + fonts = this.getFonts(); + + this.$element.html(''); + + if (this.options.blank === true) { + this.$element.append('<option value=""></option>'); + } + + for (font in fonts) { + if (fonts.hasOwnProperty(font)) { + this.$element.append('<option value="' + fonts[font].info.family + '">' + fonts[font].info.family + '</option>'); + } + } + + this.$element.val(value); + }, + + addBootstrapFonts: function() { + var $input, + $toggle, + $options, + value, + font, + fonts; + + value = this.options.font; + $input = this.$element.find('input[type="hidden"]'); + $toggle = this.$element.find('.bfh-selectbox-option'); + $options = this.$element.find('[role=option]'); + fonts = this.getFonts(); + + $options.html(''); + + if (this.options.blank === true) { + $options.append('<li><a tabindex="-1" href="#" data-option="" style="background-image: none;"></a></li>'); + } + + for (font in fonts) { + if (fonts.hasOwnProperty(font)) { + $options.append('<li><a tabindex="-1" href="#" style="background-position: 0 -' + ((fonts[font].index * 30) - 2) + 'px;" data-option="' + fonts[font].info.family + '">' + fonts[font].info.family + '</a></li>'); + } + } + + this.$element.val(value); + } + + }; + + + /* GOOGLE FONTS PLUGIN DEFINITION + * ======================= */ + + var old = $.fn.bfhgooglefonts; + + $.fn.bfhgooglefonts = function (option) { + return this.each(function () { + var $this, + data, + options; + + $this = $(this); + data = $this.data('bfhgooglefonts'); + options = typeof option === 'object' && option; + + if (!data) { + $this.data('bfhgooglefonts', (data = new BFHGoogleFonts(this, options))); + } + if (typeof option === 'string') { + data[option].call($this); + } + }); + }; + + $.fn.bfhgooglefonts.Constructor = BFHGoogleFonts; + + $.fn.bfhgooglefonts.defaults = { + font: '', + available: '', + subset: '', + blank: true + }; + + + /* GOOGLE FONTS NO CONFLICT + * ========================== */ + + $.fn.bfhgooglefonts.noConflict = function () { + $.fn.bfhgooglefonts = old; + return this; + }; + + + /* GOOGLE FONTS DATA-API + * ============== */ + + $(document).ready( function () { + $('form select.bfh-googlefonts, span.bfh-googlefonts, div.bfh-googlefonts').each(function () { + var $googleFonts; + + $googleFonts = $(this); + + if ($googleFonts.hasClass('bfh-selectbox')) { + $googleFonts.bfhselectbox($googleFonts.data()); + } + $googleFonts.bfhgooglefonts($googleFonts.data()); + }); + }); + +}(window.jQuery); + +/* ========================================================== + * bootstrap-formhelpers-languages.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * Contribution 2013 Tomasz Kuter + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + ++function ($) { + + 'use strict'; + + + /* LANGUAGES CLASS DEFINITION + * ====================== */ + + var BFHLanguages = function (element, options) { + this.options = $.extend({}, $.fn.bfhlanguages.defaults, options); + this.$element = $(element); + + if (this.$element.is('select')) { + this.addLanguages(); + } + + if (this.$element.is('span')) { + this.displayLanguage(); + } + + if (this.$element.hasClass('bfh-selectbox')) { + this.addBootstrapLanguages(); + } + }; + + BFHLanguages.prototype = { + + constructor: BFHLanguages, + + getLanguages: function () { + var split, + language, + languages; + + if (this.options.available) { + languages = []; + + this.options.available = this.options.available.split(','); + + for (language in this.options.available) { + if (this.options.available.hasOwnProperty(language)) { + if (this.options.available[language].indexOf('_') !== -1) { + split = this.options.available[language].split('_'); + languages[split[0]] = {name: BFHLanguagesList[split[0]], country: split[1]}; + } else { + languages[this.options.available[language]] = BFHLanguagesList[this.options.available[language]]; + } + } + } + + return languages; + } else { + return BFHLanguagesList; + } + }, + + addLanguages: function () { + var split, + value, + languages, + language; + + value = this.options.language; + languages = this.getLanguages(); + + this.$element.html(''); + + if (this.options.blank === true) { + this.$element.append('<option value=""></option>'); + } + + for (language in languages) { + if (languages.hasOwnProperty(language)) { + if (languages[language].hasOwnProperty('name')) { + this.$element.append('<option value="' + language + '_' + languages[language].country + '">' + languages[language].name.toProperCase() + ' (' + BFHCountriesList[languages[language].country] + ')</option>'); + } else { + this.$element.append('<option value="' + language + '">' + languages[language].toProperCase() + '</option>'); + } + } + } + + this.$element.val(value); + }, + + addBootstrapLanguages: function() { + var $input, + $toggle, + $options, + value, + languages, + language, + split; + + value = this.options.language; + $input = this.$element.find('input[type="hidden"]'); + $toggle = this.$element.find('.bfh-selectbox-option'); + $options = this.$element.find('[role=option]'); + languages = this.getLanguages(); + + $options.html(''); + + if (this.options.blank === true) { + $options.append('<li><a tabindex="-1" href="#" data-option=""></a></li>'); + } + + for (language in languages) { + if (languages.hasOwnProperty(language)) { + if (languages[language].hasOwnProperty('name')) { + if (this.options.flags === true) { + $options.append('<li><a tabindex="-1" href="#" data-option="' + language + '_' + languages[language].country + '"><i class="glyphicon bfh-flag-' + languages[language].country + '"></i>' + languages[language].name.toProperCase() + '</a></li>'); + } else { + $options.append('<li><a tabindex="-1" href="#" data-option="' + language + '_' + languages[language].country + '">' + languages[language].name.toProperCase() + ' (' + BFHCountriesList[languages[language].country] + ')</a></li>'); + } + } else { + $options.append('<li><a tabindex="-1" href="#" data-option="' + language + '">' + languages[language] + '</a></li>'); + } + } + } + + this.$element.val(value); + }, + + displayLanguage: function () { + var value; + + value = this.options.language; + + if (value.indexOf('_') !== -1) { + value = value.split('_'); + if (this.options.flags === true) { + this.$element.html('<i class="glyphicon bfh-flag-' + value[1] + '"></i> ' + BFHLanguagesList[value[0]].toProperCase()); + } else { + this.$element.html(BFHLanguagesList[value[0]].toProperCase() + ' (' + BFHCountriesList[value[1]] + ')'); + } + } else { + this.$element.html(BFHLanguagesList[value].toProperCase()); + } + } + + }; + + + /* LANGUAGES PLUGIN DEFINITION + * ======================= */ + + var old = $.fn.bfhlanguages; + + $.fn.bfhlanguages = function (option) { + return this.each(function () { + var $this, + data, + options; + + $this = $(this); + data = $this.data('bfhlanguages'); + options = typeof option === 'object' && option; + + if (!data) { + $this.data('bfhlanguages', (data = new BFHLanguages(this, options))); + } + if (typeof option === 'string') { + data[option].call($this); + } + }); + }; + + $.fn.bfhlanguages.Constructor = BFHLanguages; + + $.fn.bfhlanguages.defaults = { + language: '', + available: '', + flags: false, + blank: true + }; + + + /* LANGUAGES NO CONFLICT + * ========================== */ + + $.fn.bfhlanguages.noConflict = function () { + $.fn.bfhlanguages = old; + return this; + }; + + + /* LANGUAGES DATA-API + * ============== */ + + $(document).ready( function () { + $('form select.bfh-languages, span.bfh-languages, div.bfh-languages').each(function () { + var $languages; + + $languages = $(this); + + if ($languages.hasClass('bfh-selectbox')) { + $languages.bfhselectbox($languages.data()); + } + $languages.bfhlanguages($languages.data()); + }); + }); + + + /* LANGUAGES HELPERS + * ============== */ + + String.prototype.toProperCase = function () { + return this.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}); + }; + +}(window.jQuery); + +/* ========================================================== + * bootstrap-formhelpers-number.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + ++function ($) { + + 'use strict'; + + + /* NUMBER CLASS DEFINITION + * ====================== */ + + var BFHNumber = function (element, options) { + this.options = $.extend({}, $.fn.bfhnumber.defaults, options); + this.$element = $(element); + + this.initInput(); + }; + + BFHNumber.prototype = { + + constructor: BFHNumber, + + initInput: function() { + var value; + + if (this.options.buttons === true) { + this.$element.wrap('<div class="input-group"></div>'); + this.$element.parent().append('<span class="input-group-addon bfh-number-btn inc"><span class="glyphicon glyphicon-chevron-up"></span></span>'); + this.$element.parent().append('<span class="input-group-addon bfh-number-btn dec"><span class="glyphicon glyphicon-chevron-down"></span></span>'); + } + + this.$element.on('change.bfhnumber.data-api', BFHNumber.prototype.change); + + if (this.options.keyboard === true) { + this.$element.on('keydown.bfhnumber.data-api', BFHNumber.prototype.keydown); + } + + if (this.options.buttons === true) { + this.$element.parent() + .on('mousedown.bfhnumber.data-api', '.inc', BFHNumber.prototype.btninc) + .on('mousedown.bfhnumber.data-api', '.dec', BFHNumber.prototype.btndec); + } + + this.formatNumber(); + }, + + keydown: function(e) { + var $this; + + $this = $(this).data('bfhnumber'); + + if ($this.$element.is('.disabled') || $this.$element.attr('disabled') !== undefined) { + return true; + } + + switch (e.which) { + case 38: + $this.increment(); + break; + case 40: + $this.decrement(); + break; + default: + } + + return true; + }, + + mouseup: function(e) { + var $this, + timer, + interval; + + $this = e.data.btn; + timer = $this.$element.data('timer'); + interval = $this.$element.data('interval'); + + clearTimeout(timer); + clearInterval(interval); + }, + + btninc: function() { + var $this, + timer; + + $this = $(this).parent().find('.bfh-number').data('bfhnumber'); + + if ($this.$element.is('.disabled') || $this.$element.attr('disabled') !== undefined) { + return true; + } + + $this.increment(); + + timer = setTimeout(function() { + var interval; + interval = setInterval(function() { + $this.increment(); + }, 80); + $this.$element.data('interval', interval); + }, 750); + $this.$element.data('timer', timer); + + $(document).one('mouseup', {btn: $this}, BFHNumber.prototype.mouseup); + + return true; + }, + + btndec: function() { + var $this, + timer; + + $this = $(this).parent().find('.bfh-number').data('bfhnumber'); + + if ($this.$element.is('.disabled') || $this.$element.attr('disabled') !== undefined) { + return true; + } + + $this.decrement(); + + timer = setTimeout(function() { + var interval; + interval = setInterval(function() { + $this.decrement(); + }, 80); + $this.$element.data('interval', interval); + }, 750); + $this.$element.data('timer', timer); + + $(document).one('mouseup', {btn: $this}, BFHNumber.prototype.mouseup); + + return true; + }, + + change: function() { + var $this; + + $this = $(this).data('bfhnumber'); + + if ($this.$element.is('.disabled') || $this.$element.attr('disabled') !== undefined) { + return true; + } + + $this.formatNumber(); + + return true; + }, + + increment: function() { + var value; + + value = this.getValue(); + + value = value + 1; + + this.$element.val(value).change(); + }, + + decrement: function() { + var value; + + value = this.getValue(); + + value = value - 1; + + this.$element.val(value).change(); + }, + + getValue: function() { + var value; + + value = this.$element.val(); + if (value !== '-1') { + value = String(value).replace(/\D/g, ''); + } + if (String(value).length === 0) { + value = this.options.min; + } + + return parseInt(value); + }, + + formatNumber: function() { + var value, + maxLength, + length, + zero; + + value = this.getValue(); + + if (value > this.options.max) { + if (this.options.wrap === true) { + value = this.options.min; + } else { + value = this.options.max; + } + } + + if (value < this.options.min) { + if (this.options.wrap === true) { + value = this.options.max; + } else { + value = this.options.min; + } + } + + if (this.options.zeros === true) { + maxLength = String(this.options.max).length; + length = String(value).length; + for (zero=length; zero < maxLength; zero = zero + 1) { + value = '0' + value; + } + } + + if (value !== this.$element.val()) { + this.$element.val(value); + } + } + + }; + + /* NUMBER PLUGIN DEFINITION + * ======================= */ + + var old = $.fn.bfhnumber; + + $.fn.bfhnumber = function (option) { + return this.each(function () { + var $this, + data, + options; + + $this = $(this); + data = $this.data('bfhnumber'); + options = typeof option === 'object' && option; + + if (!data) { + $this.data('bfhnumber', (data = new BFHNumber(this, options))); + } + if (typeof option === 'string') { + data[option].call($this); + } + }); + }; + + $.fn.bfhnumber.Constructor = BFHNumber; + + $.fn.bfhnumber.defaults = { + min: 0, + max: 9999, + zeros: false, + keyboard: true, + buttons: true, + wrap: false + }; + + + /* NUMBER NO CONFLICT + * ========================== */ + + $.fn.bfhnumber.noConflict = function () { + $.fn.bfhnumber = old; + return this; + }; + + + /* NUMBER DATA-API + * ============== */ + + $(document).ready( function () { + $('form input[type="text"].bfh-number, form input[type="number"].bfh-number').each(function () { + var $number; + + $number = $(this); + + $number.bfhnumber($number.data()); + }); + }); + + + /* APPLY TO STANDARD NUMBER ELEMENTS + * =================================== */ + + +}(window.jQuery); + +/* ========================================================== + * bootstrap-formhelpers-phone.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + ++function ($) { + + 'use strict'; + + + /* PHONE CLASS DEFINITION + * ====================== */ + + var BFHPhone = function (element, options) { + this.options = $.extend({}, $.fn.bfhphone.defaults, options); + this.$element = $(element); + + if (this.$element.is('input[type="text"]') || this.$element.is('input[type="tel"]')) { + this.addFormatter(); + } + + if (this.$element.is('span')) { + this.displayFormatter(); + } + }; + + BFHPhone.prototype = { + + constructor: BFHPhone, + + addFormatter: function() { + var $country; + + if (this.options.country !== '') { + $country = $(document).find('#' + this.options.country); + + if ($country.length !== 0) { + this.options.format = BFHPhoneFormatList[$country.val()]; + $country.on('change', {phone: this}, this.changeCountry); + } else { + this.options.format = BFHPhoneFormatList[this.options.country]; + } + } + + this.$element.on('keyup.bfhphone.data-api', BFHPhone.prototype.change); + + this.loadFormatter(); + }, + + loadFormatter: function () { + var formattedNumber; + + formattedNumber = formatNumber(this.options.format, this.$element.val()); + + this.$element.val(formattedNumber); + }, + + displayFormatter: function () { + var formattedNumber; + + if (this.options.country !== '') { + this.options.format = BFHPhoneFormatList[this.options.country]; + } + + formattedNumber = formatNumber(this.options.format, this.options.number); + + this.$element.html(formattedNumber); + }, + + changeCountry: function (e) { + var $this, + $phone; + + $this = $(this); + $phone = e.data.phone; + + $phone.$element.val(String($phone.$element.val()).replace(/\+\d*/g, '')); + $phone.options.format = BFHPhoneFormatList[$this.val()]; + + $phone.loadFormatter(); + }, + + change: function(e) { + var $this, + cursorPosition, + cursorEnd, + formattedNumber; + + $this = $(this).data('bfhphone'); + + if ($this.$element.is('.disabled') || $this.$element.attr('disabled') !== undefined) { + return true; + } + + cursorPosition = getCursorPosition($this.$element[0]); + + cursorEnd = false; + if (cursorPosition === $this.$element.val().length) { + cursorEnd = true; + } + + if (e.which === 8 && $this.options.format.charAt($this.$element.val().length) !== 'd') { + $this.$element.val(String($this.$element.val()).substring(0, $this.$element.val().length - 1)); + } + + formattedNumber = formatNumber($this.options.format, $this.$element.val()); + + if (formattedNumber === $this.$element.val()) { + return true; + } + + $this.$element.val(formattedNumber); + + if (cursorEnd) { + cursorPosition = $this.$element.val().length; + } + + setCursorPosition($this.$element[0], cursorPosition); + + return true; + } + + }; + + function formatNumber(format, number) { + var formattedNumber, + indexFormat, + indexNumber, + lastCharacter; + + formattedNumber = ''; + number = String(number).replace(/\D/g, ''); + + for (indexFormat = 0, indexNumber = 0; indexFormat < format.length; indexFormat = indexFormat + 1) { + if (/\d/g.test(format.charAt(indexFormat))) { + if (format.charAt(indexFormat) === number.charAt(indexNumber)) { + formattedNumber += number.charAt(indexNumber); + indexNumber = indexNumber + 1; + } else { + formattedNumber += format.charAt(indexFormat); + } + } else if (format.charAt(indexFormat) !== 'd') { + if (number.charAt(indexNumber) !== '' || format.charAt(indexFormat) === '+') { + formattedNumber += format.charAt(indexFormat); + } + } else { + if (number.charAt(indexNumber) === '') { + formattedNumber += ''; + } else { + formattedNumber += number.charAt(indexNumber); + indexNumber = indexNumber + 1; + } + } + } + + lastCharacter = format.charAt(formattedNumber.length); + if (lastCharacter !== 'd') { + formattedNumber += lastCharacter; + } + + return formattedNumber; + } + + function getCursorPosition($element) { + var position = 0, + selection; + + if (document.selection) { + // IE Support + $element.focus(); + selection = document.selection.createRange(); + selection.moveStart ('character', -$element.value.length); + position = selection.text.length; + } else if ($element.selectionStart || $element.selectionStart === 0) { + position = $element.selectionStart; + } + + return position; + } + + function setCursorPosition($element, position) { + var selection; + + if (document.selection) { + // IE Support + $element.focus (); + selection = document.selection.createRange(); + selection.moveStart ('character', -$element.value.length); + selection.moveStart ('character', position); + selection.moveEnd ('character', 0); + selection.select (); + } else if ($element.selectionStart || $element.selectionStart === 0) { + $element.selectionStart = position; + $element.selectionEnd = position; + $element.focus (); + } + } + + /* PHONE PLUGIN DEFINITION + * ======================= */ + + var old = $.fn.bfhphone; + + $.fn.bfhphone = function (option) { + return this.each(function () { + var $this, + data, + options; + + $this = $(this); + data = $this.data('bfhphone'); + options = typeof option === 'object' && option; + + if (!data) { + $this.data('bfhphone', (data = new BFHPhone(this, options))); + } + if (typeof option === 'string') { + data[option].call($this); + } + }); + }; + + $.fn.bfhphone.Constructor = BFHPhone; + + $.fn.bfhphone.defaults = { + format: '', + number: '', + country: '' + }; + + + /* PHONE NO CONFLICT + * ========================== */ + + $.fn.bfhphone.noConflict = function () { + $.fn.bfhphone = old; + return this; + }; + + + /* PHONE DATA-API + * ============== */ + + $(document).ready( function () { + $('form input[type="text"].bfh-phone, form input[type="tel"].bfh-phone, span.bfh-phone').each(function () { + var $phone; + + $phone = $(this); + + $phone.bfhphone($phone.data()); + }); + }); + +}(window.jQuery); + +/* ========================================================== + * bootstrap-formhelpers-selectbox.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + ++function ($) { + + 'use strict'; + + + /* SELECTBOX CLASS DEFINITION + * ========================= */ + + var toggle = '[data-toggle=bfh-selectbox]', + BFHSelectBox = function (element, options) { + this.options = $.extend({}, $.fn.bfhselectbox.defaults, options); + this.$element = $(element); + + this.initSelectBox(); + }; + + BFHSelectBox.prototype = { + + constructor: BFHSelectBox, + + initSelectBox: function () { + var options; + + options = ''; + this.$element.find('div').each(function() { + options = options + '<li><a tabindex="-1" href="#" data-option="' + $(this).data('value') + '">' + $(this).html() + '</a></li>'; + }); + + this.$element.html( + '<input type="hidden" name="' + this.options.name + '" value="">' + + '<a class="bfh-selectbox-toggle ' + this.options.input + '" role="button" data-toggle="bfh-selectbox" href="#">' + + '<span class="bfh-selectbox-option"></span>' + + '<span class="' + this.options.icon + ' selectbox-caret"></span>' + + '</a>' + + '<div class="bfh-selectbox-options">' + + '<div role="listbox">' + + '<ul role="option">' + + '</ul>' + + '</div>' + + '</div>' + ); + + this.$element.find('[role=option]').html(options); + + if (this.options.filter === true) { + this.$element.find('.bfh-selectbox-options').prepend('<div class="bfh-selectbox-filter-container"><input type="text" class="bfh-selectbox-filter form-control"></div>'); + } + + this.$element.val(this.options.value); + + this.$element + .on('click.bfhselectbox.data-api touchstart.bfhselectbox.data-api', toggle, BFHSelectBox.prototype.toggle) + .on('keydown.bfhselectbox.data-api', toggle + ', [role=option]' , BFHSelectBox.prototype.keydown) + .on('mouseenter.bfhselectbox.data-api', '[role=option] > li > a', BFHSelectBox.prototype.mouseenter) + .on('click.bfhselectbox.data-api', '[role=option] > li > a', BFHSelectBox.prototype.select) + .on('click.bfhselectbox.data-api', '.bfh-selectbox-filter', function () { return false; }) + .on('propertychange.bfhselectbox.data-api change.bfhselectbox.data-api input.bfhselectbox.data-api paste.bfhselectbox.data-api', '.bfh-selectbox-filter', BFHSelectBox.prototype.filter); + }, + + toggle: function (e) { + var $this, + $parent, + isActive; + + $this = $(this); + $parent = getParent($this); + + if ($parent.is('.disabled') || $parent.attr('disabled') !== undefined) { + return true; + } + + isActive = $parent.hasClass('open'); + + clearMenus(); + + if (!isActive) { + $parent.trigger(e = $.Event('show.bfhselectbox')); + + if (e.isDefaultPrevented()) { + return true; + } + + $parent + .toggleClass('open') + .trigger('shown.bfhselectbox') + .find('[role=option] > li > [data-option="' + $parent.val() + '"]').focus(); + } + + return false; + }, + + filter: function() { + var $this, + $parent, + $items; + + $this = $(this); + $parent = getParent($this); + + $items = $('[role=option] li a', $parent); + $items + .hide() + .filter(function() { + return ($(this).text().toUpperCase().indexOf($this.val().toUpperCase()) !== -1); + }) + .show(); + }, + + keydown: function (e) { + var $this, + $items, + $parent, + $subItems, + isActive, + index, + selectedIndex; + + if (!/(38|40|27)/.test(e.keyCode)) { + return true; + } + + $this = $(this); + + e.preventDefault(); + e.stopPropagation(); + + $parent = getParent($this); + isActive = $parent.hasClass('open'); + + if (!isActive || (isActive && e.keyCode === 27)) { + if (e.which === 27) { + $parent.find(toggle).focus(); + } + + return $this.click(); + } + + $items = $('[role=option] li:not(.divider) a:visible', $parent); + + if (!$items.length) { + return true; + } + + $('body').off('mouseenter.bfh-selectbox.data-api', '[role=option] > li > a', BFHSelectBox.prototype.mouseenter); + index = $items.index($items.filter(':focus')); + + if (e.keyCode === 38 && index > 0) { + index = index - 1; + } + + if (e.keyCode === 40 && index < $items.length - 1) { + index = index + 1; + } + + if (!index) { + index = 0; + } + + $items.eq(index).focus(); + $('body').on('mouseenter.bfh-selectbox.data-api', '[role=option] > li > a', BFHSelectBox.prototype.mouseenter); + }, + + mouseenter: function () { + var $this; + + $this = $(this); + + $this.focus(); + }, + + select: function (e) { + var $this, + $parent, + $span, + $input; + + $this = $(this); + + e.preventDefault(); + e.stopPropagation(); + + if ($this.is('.disabled') || $this.attr('disabled') !== undefined) { + return true; + } + + $parent = getParent($this); + + $parent.val($this.data('option')); + $parent.trigger('change.bfhselectbox'); + + clearMenus(); + } + + }; + + function clearMenus() { + var $parent; + + $(toggle).each(function (e) { + $parent = getParent($(this)); + + if (!$parent.hasClass('open')) { + return true; + } + + $parent.trigger(e = $.Event('hide.bfhselectbox')); + + if (e.isDefaultPrevented()) { + return true; + } + + $parent + .removeClass('open') + .trigger('hidden.bfhselectbox'); + }); + } + + function getParent($this) { + return $this.closest('.bfh-selectbox'); + } + + + /* SELECTBOX PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.bfhselectbox; + + $.fn.bfhselectbox = function (option) { + return this.each(function () { + var $this, + data, + options; + + $this = $(this); + data = $this.data('bfhselectbox'); + options = typeof option === 'object' && option; + this.type = 'bfhselectbox'; + + if (!data) { + $this.data('bfhselectbox', (data = new BFHSelectBox(this, options))); + } + if (typeof option === 'string') { + data[option].call($this); + } + }); + }; + + $.fn.bfhselectbox.Constructor = BFHSelectBox; + + $.fn.bfhselectbox.defaults = { + icon: 'caret', + input: 'form-control', + name: '', + value: '', + filter: false + }; + + + /* SELECTBOX NO CONFLICT + * ========================== */ + + $.fn.bfhselectbox.noConflict = function () { + $.fn.bfhselectbox = old; + return this; + }; + + + /* SELECTBOX VALHOOKS + * ========================== */ + + var origHook; + if ($.valHooks.div){ + origHook = $.valHooks.div; + } + $.valHooks.div = { + get: function(el) { + if ($(el).hasClass('bfh-selectbox')) { + return $(el).find('input[type="hidden"]').val(); + } else if (origHook) { + return origHook.get(el); + } + }, + set: function(el, val) { + var $el, + html; + + if ($(el).hasClass('bfh-selectbox')) { + + $el = $(el); + if ($el.find('li a[data-option=\'' + val + '\']').length > 0) { + html = $el.find('li a[data-option=\'' + val + '\']').html(); + } else if ($el.find('li a').length > 0) { + html = $el.find('li a').eq(0).html(); + } else { + val = ''; + html = ''; + } + + $el.find('input[type="hidden"]').val(val); + $el.find('.bfh-selectbox-option').html(html); + } else if (origHook) { + return origHook.set(el,val); + } + } + }; + + + /* SELECTBOX DATA-API + * ============== */ + + $(document).ready( function () { + $('div.bfh-selectbox').each(function () { + var $selectbox; + + $selectbox = $(this); + + $selectbox.bfhselectbox($selectbox.data()); + }); + }); + + + /* APPLY TO STANDARD SELECTBOX ELEMENTS + * =================================== */ + + $(document) + .on('click.bfhselectbox.data-api', clearMenus); + +}(window.jQuery); + +/* ========================================================== + * bootstrap-formhelpers-slider.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + ++function ($) { + + 'use strict'; + + + /* BFHSLIDER CLASS DEFINITION + * ========================= */ + + var BFHSlider = function (element, options) { + this.options = $.extend({}, $.fn.bfhslider.defaults, options); + this.$element = $(element); + + this.initSlider(); + }; + + BFHSlider.prototype = { + + constructor: BFHSlider, + + initSlider: function() { + if (this.options.value === '') { + this.options.value = this.options.min; + } + + this.$element.html( + '<input type="hidden" name="' + this.options.name + '" value="">' + + '<div class="bfh-slider-handle"><div class="bfh-slider-value"></div></div>' + ); + + this.$element.find('input[type="hidden"]').val(this.options.value); + this.updateHandle(this.options.value); + + this.$element.on('mousedown.bfhslider.data-api', BFHSlider.prototype.mouseDown); + }, + + updateHandle: function(val) { + var positionX, + width, + left, + span; + + span = this.options.max - this.options.min; + width = this.$element.width(); + left = this.$element.position().left; + + positionX = Math.round((val - this.options.min) * (width - 20) / span + left); + + this.$element.find('.bfh-slider-handle').css('left', positionX + 'px'); + this.$element.find('.bfh-slider-value').text(val); + }, + + updateVal: function(positionX) { + var width, + left, + right, + val, + span; + + span = this.options.max - this.options.min; + width = this.$element.width(); + left = this.$element.offset().left; + right = left + width; + + if (positionX < left) { + positionX = left; + } + + if (positionX + 20 > right) { + positionX = right; + } + + val = (positionX - left) / width; + val = Math.ceil(val * span + this.options.min); + + if (val === this.$element.val()) { + return true; + } + + this.$element.val(val); + + this.$element.trigger('change.bfhslider'); + }, + + mouseDown: function() { + var $this; + + $this = $(this); + + if ($this.is('.disabled') || $this.attr('disabled') !== undefined) { + return true; + } + + $(document) + .on('mousemove.bfhslider.data-api', {slider: $this}, BFHSlider.prototype.mouseMove) + .one('mouseup.bfhslider.data-api', {slider: $this}, BFHSlider.prototype.mouseUp); + }, + + mouseMove: function(e) { + var $this; + + $this = e.data.slider; + + $this.data('bfhslider').updateVal(e.pageX); + }, + + mouseUp: function(e) { + var $this; + + $this = e.data.slider; + + $this.data('bfhslider').updateVal(e.pageX); + + $(document).off('mousemove.bfhslider.data-api'); + } + }; + + + /* SLIDER PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.bfhslider; + + $.fn.bfhslider = function (option) { + return this.each(function () { + var $this, + data, + options; + + $this = $(this); + data = $this.data('bfhslider'); + options = typeof option === 'object' && option; + this.type = 'bfhslider'; + + if (!data) { + $this.data('bfhslider', (data = new BFHSlider(this, options))); + } + if (typeof option === 'string') { + data[option].call($this); + } + }); + }; + + $.fn.bfhslider.Constructor = BFHSlider; + + $.fn.bfhslider.defaults = { + name: '', + value: '', + min: 0, + max: 100 + }; + + + /* SLIDER NO CONFLICT + * ========================== */ + + $.fn.bfhslider.noConflict = function () { + $.fn.bfhslider = old; + return this; + }; + + + /* SLIDER VALHOOKS + * ========================== */ + + var origHook; + if ($.valHooks.div){ + origHook = $.valHooks.div; + } + $.valHooks.div = { + get: function(el) { + if ($(el).hasClass('bfh-slider')) { + return $(el).find('input[type="hidden"]').val(); + } else if (origHook) { + return origHook.get(el); + } + }, + set: function(el, val) { + if ($(el).hasClass('bfh-slider')) { + $(el).find('input[type="hidden"]').val(val); + $(el).data('bfhslider').updateHandle(val); + } else if (origHook) { + return origHook.set(el,val); + } + } + }; + + + /* SLIDER DATA-API + * ============== */ + + $(document).ready( function () { + $('div.bfh-slider').each(function () { + var $slider; + + $slider = $(this); + + $slider.bfhslider($slider.data()); + }); + }); + +}(window.jQuery); + +/* ========================================================== + * bootstrap-formhelpers-states.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + ++function ($) { + + 'use strict'; + + + /* STATES CLASS DEFINITION + * ====================== */ + + var BFHStates = function (element, options) { + this.options = $.extend({}, $.fn.bfhstates.defaults, options); + this.$element = $(element); + + if (this.$element.is('select')) { + this.addStates(); + } + + if (this.$element.hasClass('bfh-selectbox')) { + this.addBootstrapStates(); + } + + if (this.$element.is('span')) { + this.displayState(); + } + }; + + BFHStates.prototype = { + + constructor: BFHStates, + + addStates: function () { + var country, + $country; + + country = this.options.country; + + if (country !== '') { + $country = $(document).find('#' + country); + + if ($country.length !== 0) { + country = $country.val(); + $country.on('change', {state: this}, this.changeCountry); + } + } + + this.loadStates(country); + }, + + loadStates: function (country) { + var value, + state; + + value = this.options.state; + + this.$element.html(''); + + if (this.options.blank === true) { + this.$element.append('<option value=""></option>'); + } + + for (state in BFHStatesList[country]) { + if (BFHStatesList[country].hasOwnProperty(state)) { + this.$element.append('<option value="' + BFHStatesList[country][state].code + '">' + BFHStatesList[country][state].name + '</option>'); + } + } + + this.$element.val(value); + }, + + changeCountry: function (e) { + var $this, + $state, + country; + + $this = $(this); + $state = e.data.state; + country = $this.val(); + + $state.loadStates(country); + }, + + addBootstrapStates: function() { + var country, + $country; + + country = this.options.country; + + if (country !== '') { + $country = $(document).find('#' + country); + + if ($country.length !== 0) { + country = $country.find('input[type="hidden"]').val(); + $country.on('change.bfhselectbox', {state: this}, this.changeBootstrapCountry); + } + } + + this.loadBootstrapStates(country); + }, + + loadBootstrapStates: function(country) { + var $input, + $toggle, + $options, + stateCode, + stateName, + state; + + stateCode = this.options.state; + stateName = ''; + $input = this.$element.find('input[type="hidden"]'); + $toggle = this.$element.find('.bfh-selectbox-option'); + $options = this.$element.find('[role=option]'); + + $options.html(''); + + if (this.options.blank === true) { + $options.append('<li><a tabindex="-1" href="#" data-option=""></a></li>'); + } + + for (state in BFHStatesList[country]) { + if (BFHStatesList[country].hasOwnProperty(state)) { + $options.append('<li><a tabindex="-1" href="#" data-option="' + BFHStatesList[country][state].code + '">' + BFHStatesList[country][state].name + '</a></li>'); + + if (BFHStatesList[country][state].code === stateCode) { + stateName = BFHStatesList[country][state].name; + } + } + } + + this.$element.val(stateCode); + }, + + changeBootstrapCountry: function (e) { + var $this, + $state, + country; + + $this = $(this); + $state = e.data.state; + country = $this.val(); + + $state.loadBootstrapStates(country); + }, + + displayState: function () { + var country, + stateCode, + stateName, + state; + + country = this.options.country; + stateCode = this.options.state; + stateName = ''; + + for (state in BFHStatesList[country]) { + if (BFHStatesList[country].hasOwnProperty(state)) { + if (BFHStatesList[country][state].code === stateCode) { + stateName = BFHStatesList[country][state].name; + break; + } + } + } + this.$element.html(stateName); + } + + }; + + + /* STATES PLUGIN DEFINITION + * ======================= */ + + var old = $.fn.bfhstates; + + $.fn.bfhstates = function (option) { + return this.each(function () { + var $this, + data, + options; + + $this = $(this); + data = $this.data('bfhstates'); + options = typeof option === 'object' && option; + + if (!data) { + $this.data('bfhstates', (data = new BFHStates(this, options))); + } + if (typeof option === 'string') { + data[option].call($this); + } + }); + }; + + $.fn.bfhstates.Constructor = BFHStates; + + $.fn.bfhstates.defaults = { + country: '', + state: '', + blank: true + }; + + + /* STATES NO CONFLICT + * ========================== */ + + $.fn.bfhstates.noConflict = function () { + $.fn.bfhstates = old; + return this; + }; + + + /* STATES DATA-API + * ============== */ + + $(document).ready( function () { + $('form select.bfh-states, span.bfh-states, div.bfh-states').each(function () { + var $states; + + $states = $(this); + + if ($states.hasClass('bfh-selectbox')) { + $states.bfhselectbox($states.data()); + } + $states.bfhstates($states.data()); + }); + }); + +}(window.jQuery); + +/* ========================================================== + * bootstrap-formhelpers-timepicker.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + ++function ($) { + + 'use strict'; + + + /* TIMEPICKER CLASS DEFINITION + * ========================= */ + + var toggle = '[data-toggle=bfh-timepicker]', + BFHTimePicker = function (element, options) { + this.options = $.extend({}, $.fn.bfhtimepicker.defaults, options); + this.$element = $(element); + + this.initPopover(); + }; + + BFHTimePicker.prototype = { + + constructor: BFHTimePicker, + + setTime: function() { + var time, + today, + timeParts, + hours, + minutes, + mode, + currentMode; + + time = this.options.time; + mode = ''; + currentMode = ''; + + if (time === '' || time === 'now' || time === undefined) { + today = new Date(); + + hours = today.getHours(); + minutes = today.getMinutes(); + + if (this.options.mode === '12h') { + if (hours > 12) { + hours = hours - 12; + mode = ' ' + BFHTimePickerModes.pm; + currentMode = 'pm'; + } else { + mode = ' ' + BFHTimePickerModes.am; + currentMode = 'am'; + } + } + + if (time === 'now') { + this.$element.find('.bfh-timepicker-toggle > input[type="text"]').val(formatTime(hours, minutes) + mode); + } + + this.$element.data('hour', hours); + this.$element.data('minute', minutes); + this.$element.data('mode', currentMode); + } else { + timeParts = String(time).split(BFHTimePickerDelimiter); + hours = timeParts[0]; + minutes = timeParts[1]; + + if (this.options.mode === '12h') { + timeParts = String(minutes).split(' '); + minutes = timeParts[0]; + if (timeParts[1] === BFHTimePickerModes.pm) { + currentMode = 'pm'; + } else { + currentMode = 'am'; + } + } + + this.$element.find('.bfh-timepicker-toggle > input[type="text"]').val(time); + this.$element.data('hour', hours); + this.$element.data('minute', minutes); + this.$element.data('mode', currentMode); + } + }, + + initPopover: function() { + var iconLeft, + iconRight, + iconAddon, + modeAddon, + modeMax; + + iconLeft = ''; + iconRight = ''; + iconAddon = ''; + if (this.options.icon !== '') { + if (this.options.align === 'right') { + iconRight = '<span class="input-group-addon"><i class="' + this.options.icon + '"></i></span>'; + } else { + iconLeft = '<span class="input-group-addon"><i class="' + this.options.icon + '"></i></span>'; + } + iconAddon = 'input-group'; + } + + modeAddon = ''; + modeMax = '23'; + if (this.options.mode === '12h') { + modeAddon = '<td>' + + '<div class="bfh-selectbox" data-input="' + this.options.input + '" data-value="am">' + + '<div data-value="am">' + BFHTimePickerModes.am + '</div>' + + '<div data-value="pm">' + BFHTimePickerModes.pm + '</div>' + + '</div>'; + modeMax = '11'; + } + + this.$element.html( + '<div class="' + iconAddon + ' bfh-timepicker-toggle" data-toggle="bfh-timepicker">' + + iconLeft + + '<input type="text" name="' + this.options.name + '" class="' + this.options.input + '" placeholder="' + this.options.placeholder + '" readonly>' + + iconRight + + '</div>' + + '<div class="bfh-timepicker-popover">' + + '<table class="table">' + + '<tbody>' + + '<tr>' + + '<td class="hour">' + + '<input type="text" class="' + this.options.input + ' bfh-number" data-min="0" data-max="' + modeMax + '" data-zeros="true" data-wrap="true">' + + '</td>' + + '<td class="separator">' + BFHTimePickerDelimiter + '</td>' + + '<td class="minute">' + + '<input type="text" class="' + this.options.input + ' bfh-number" data-min="0" data-max="59" data-zeros="true" data-wrap="true">' + + '</td>' + + modeAddon + + '</tr>' + + '</tbody>' + + '</table>' + + '</div>' + ); + + this.$element + .on('click.bfhtimepicker.data-api touchstart.bfhtimepicker.data-api', toggle, BFHTimePicker.prototype.toggle) + .on('click.bfhtimepicker.data-api touchstart.bfhtimepicker.data-api', '.bfh-timepicker-popover > table', function() { return false; }); + + this.$element.find('.bfh-number').each(function () { + var $number; + + $number = $(this); + + $number.bfhnumber($number.data()); + + $number.on('change', BFHTimePicker.prototype.change); + }); + + this.$element.find('.bfh-selectbox').each(function() { + var $selectbox; + + $selectbox = $(this); + + $selectbox.bfhselectbox($selectbox.data()); + + $selectbox.on('change.bfhselectbox', BFHTimePicker.prototype.change); + }); + + this.setTime(); + + this.updatePopover(); + }, + + updatePopover: function() { + var hour, + minute, + mode; + + hour = this.$element.data('hour'); + minute = this.$element.data('minute'); + mode = this.$element.data('mode'); + + this.$element.find('.hour input[type=text]').val(hour).change(); + this.$element.find('.minute input[type=text]').val(minute).change(); + this.$element.find('.bfh-selectbox').val(mode); + }, + + change: function() { + var $this, + $parent, + $timePicker, + mode; + + $this = $(this); + $parent = getParent($this); + + $timePicker = $parent.data('bfhtimepicker'); + + if ($timePicker && $timePicker !== 'undefined') { + mode = ''; + if ($timePicker.options.mode === '12h') { + mode = ' ' + BFHTimePickerModes[$parent.find('.bfh-selectbox').val()]; + } + + $parent.find('.bfh-timepicker-toggle > input[type="text"]').val($parent.find('.hour input[type=text]').val() + BFHTimePickerDelimiter + $parent.find('.minute input[type=text]').val() + mode); + + $parent.trigger('change.bfhtimepicker'); + } + + return false; + }, + + toggle: function(e) { + var $this, + $parent, + isActive; + + $this = $(this); + $parent = getParent($this); + + if ($parent.is('.disabled') || $parent.attr('disabled') !== undefined) { + return true; + } + + isActive = $parent.hasClass('open'); + + clearMenus(); + + if (!isActive) { + $parent.trigger(e = $.Event('show.bfhtimepicker')); + + if (e.isDefaultPrevented()) { + return true; + } + + $parent + .toggleClass('open') + .trigger('shown.bfhtimepicker'); + + $this.focus(); + } + + return false; + } + }; + + function formatTime(hour, minute) { + hour = String(hour); + if (hour.length === 1) { + hour = '0' + hour; + } + + minute = String(minute); + if (minute.length === 1) { + minute = '0' + minute; + } + + return hour + BFHTimePickerDelimiter + minute; + } + + function clearMenus() { + var $parent; + + $(toggle).each(function (e) { + $parent = getParent($(this)); + + if (!$parent.hasClass('open')) { + return true; + } + + $parent.trigger(e = $.Event('hide.bfhtimepicker')); + + if (e.isDefaultPrevented()) { + return true; + } + + $parent + .removeClass('open') + .trigger('hidden.bfhtimepicker'); + }); + } + + function getParent($this) { + return $this.closest('.bfh-timepicker'); + } + + + /* TIMEPICKER PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.bfhtimepicker; + + $.fn.bfhtimepicker = function (option) { + return this.each(function () { + var $this, + data, + options; + + $this = $(this); + data = $this.data('bfhtimepicker'); + options = typeof option === 'object' && option; + this.type = 'bfhtimepicker'; + + if (!data) { + $this.data('bfhtimepicker', (data = new BFHTimePicker(this, options))); + } + if (typeof option === 'string') { + data[option].call($this); + } + }); + }; + + $.fn.bfhtimepicker.Constructor = BFHTimePicker; + + $.fn.bfhtimepicker.defaults = { + icon: 'glyphicon glyphicon-time', + align: 'left', + input: 'form-control', + placeholder: '', + name: '', + time: 'now', + mode: '24h' + }; + + + /* TIMEPICKER NO CONFLICT + * ========================== */ + + $.fn.bfhtimepicker.noConflict = function () { + $.fn.bfhtimepicker = old; + return this; + }; + + + /* TIMEPICKER VALHOOKS + * ========================== */ + + var origHook; + if ($.valHooks.div){ + origHook = $.valHooks.div; + } + $.valHooks.div = { + get: function(el) { + if ($(el).hasClass('bfh-timepicker')) { + return $(el).find('.bfh-timepicker-toggle > input[type="text"]').val(); + } else if (origHook) { + return origHook.get(el); + } + }, + set: function(el, val) { + var $timepicker; + if ($(el).hasClass('bfh-timepicker')) { + $timepicker = $(el).data('bfhtimepicker'); + $timepicker.options.time = val; + $timepicker.setTime(); + $timepicker.updatePopover(); + } else if (origHook) { + return origHook.set(el,val); + } + } + }; + + + /* TIMEPICKER DATA-API + * ============== */ + + $(document).ready( function () { + $('div.bfh-timepicker').each(function () { + var $timepicker; + + $timepicker = $(this); + + $timepicker.bfhtimepicker($timepicker.data()); + }); + }); + + + /* APPLY TO STANDARD TIMEPICKER ELEMENTS + * =================================== */ + + $(document) + .on('click.bfhtimepicker.data-api', clearMenus); + +}(window.jQuery); + +/* ========================================================== + * bootstrap-formhelpers-timezones.js + * https://github.com/vlamanna/BootstrapFormHelpers + * ========================================================== + * Copyright 2012 Vincent Lamanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + ++function ($) { + + 'use strict'; + + + /* TIMEZONES CLASS DEFINITION + * ====================== */ + + var BFHTimezones = function (element, options) { + this.options = $.extend({}, $.fn.bfhtimezones.defaults, options); + this.$element = $(element); + + if (this.$element.is('select')) { + this.addTimezones(); + } + + if (this.$element.hasClass('bfh-selectbox')) { + this.addBootstrapTimezones(); + } + }; + + BFHTimezones.prototype = { + + constructor: BFHTimezones, + + addTimezones: function () { + var country, + $country; + + country = this.options.country; + + if (country !== '') { + $country = $(document).find('#' + country); + + if ($country.length !== 0) { + country = $country.val(); + $country.on('change', {timezone: this}, this.changeCountry); + } + } + + this.loadTimezones(country); + }, + + loadTimezones: function (country) { + var value, + timezone; + + value = this.options.timezone; + + this.$element.html(''); + + if (this.options.blank === true) { + this.$element.append('<option value=""></option>'); + } + + for (timezone in BFHTimezonesList[country]) { + if (BFHTimezonesList[country].hasOwnProperty(timezone)) { + this.$element.append('<option value="' + timezone + '">' + BFHTimezonesList[country][timezone] + '</option>'); + } + } + + this.$element.val(value); + }, + + changeCountry: function (e) { + var $this, + $timezone, + country; + + $this = $(this); + $timezone = e.data.timezone; + country = $this.val(); + + $timezone.loadTimezones(country); + }, + + addBootstrapTimezones: function() { + var country, + $country; + + country = this.options.country; + + if (country !== '') { + $country = $(document).find('#' + country); + + if ($country.length !== 0) { + country = $country.find('input[type="hidden"]').val(); + $country.on('change.bfhselectbox', {timezone: this}, this.changeBootstrapCountry); + } + } + + this.loadBootstrapTimezones(country); + }, + + loadBootstrapTimezones: function(country) { + var $input, + $toggle, + $options, + value, + timezone; + + value = this.options.timezone; + $input = this.$element.find('input[type="hidden"]'); + $toggle = this.$element.find('.bfh-selectbox-option'); + $options = this.$element.find('[role=option]'); + + $options.html(''); + + if (this.options.blank === true) { + $options.append('<li><a tabindex="-1" href="#" data-option=""></a></li>'); + } + + for (timezone in BFHTimezonesList[country]) { + if (BFHTimezonesList[country].hasOwnProperty(timezone)) { + $options.append('<li><a tabindex="-1" href="#" data-option="' + timezone + '">' + BFHTimezonesList[country][timezone] + '</a></li>'); + } + } + + this.$element.val(value); + }, + + changeBootstrapCountry: function (e) { + var $this, + $timezone, + country; + + $this = $(this); + $timezone = e.data.timezone; + country = $this.val(); + + $timezone.loadBootstrapTimezones(country); + } + + }; + + + /* TIMEZONES PLUGIN DEFINITION + * ======================= */ + + var old = $.fn.bfhtimezones; + + $.fn.bfhtimezones = function (option) { + return this.each(function () { + var $this, + data, + options; + + $this = $(this); + data = $this.data('bfhtimezones'); + options = typeof option === 'object' && option; + + if (!data) { + $this.data('bfhtimezones', (data = new BFHTimezones(this, options))); + } + if (typeof option === 'string') { + data[option].call($this); + } + }); + }; + + $.fn.bfhtimezones.Constructor = BFHTimezones; + + $.fn.bfhtimezones.defaults = { + country: '', + timezone: '', + blank: true + }; + + + /* TIMEZONES NO CONFLICT + * ========================== */ + + $.fn.bfhtimezones.noConflict = function () { + $.fn.bfhtimezones = old; + return this; + }; + + + /* TIMEZONES DATA-API + * ============== */ + + $(document).ready( function () { + $('form select.bfh-timezones, div.bfh-timezones').each(function () { + var $timezones; + + $timezones = $(this); + + if ($timezones.hasClass('bfh-selectbox')) { + $timezones.bfhselectbox($timezones.data()); + } + $timezones.bfhtimezones($timezones.data()); + }); + }); + +}(window.jQuery); diff --git a/gui/slick/js/lib/bootstrap-formhelpers.min-2.3.0.js b/gui/slick/js/lib/bootstrap-formhelpers.min-2.3.0.js new file mode 100644 index 0000000000000000000000000000000000000000..4cffbbccde68a12245af48232e3da4692c36f983 --- /dev/null +++ b/gui/slick/js/lib/bootstrap-formhelpers.min-2.3.0.js @@ -0,0 +1,8 @@ +/** +* bootstrap-formhelpers.js v2.3.0 by @vincentlamanna +* Copyright 2013 Vincent Lamanna +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +if(!jQuery)throw new Error("Bootstrap Form Helpers requires jQuery");var BFHCountriesList={AF:"Afghanistan",AL:"Albania",DZ:"Algeria",AS:"American Samoa",AD:"Andorra",AO:"Angola",AI:"Anguilla",AQ:"Antarctica",AG:"Antigua and Barbuda",AR:"Argentina",AM:"Armenia",AW:"Aruba",AU:"Australia",AT:"Austria",AZ:"Azerbaijan",BH:"Bahrain",BD:"Bangladesh",BB:"Barbados",BY:"Belarus",BE:"Belgium",BZ:"Belize",BJ:"Benin",BM:"Bermuda",BT:"Bhutan",BO:"Bolivia",BA:"Bosnia and Herzegovina",BW:"Botswana",BV:"Bouvet Island",BR:"Brazil",IO:"British Indian Ocean Territory",VG:"British Virgin Islands",BN:"Brunei",BG:"Bulgaria",BF:"Burkina Faso",BI:"Burundi",CI:"Côte d'Ivoire",KH:"Cambodia",CM:"Cameroon",CA:"Canada",CV:"Cape Verde",KY:"Cayman Islands",CF:"Central African Republic",TD:"Chad",CL:"Chile",CN:"China",CX:"Christmas Island",CC:"Cocos (Keeling) Islands",CO:"Colombia",KM:"Comoros",CG:"Congo",CK:"Cook Islands",CR:"Costa Rica",HR:"Croatia",CU:"Cuba",CY:"Cyprus",CZ:"Czech Republic",CD:"Democratic Republic of the Congo",DK:"Denmark",DJ:"Djibouti",DM:"Dominica",DO:"Dominican Republic",TP:"East Timor",EC:"Ecuador",EG:"Egypt",SV:"El Salvador",GQ:"Equatorial Guinea",ER:"Eritrea",EE:"Estonia",ET:"Ethiopia",FO:"Faeroe Islands",FK:"Falkland Islands",FJ:"Fiji",FI:"Finland",MK:"Former Yugoslav Republic of Macedonia",FR:"France",FX:"France, Metropolitan",GF:"French Guiana",PF:"French Polynesia",TF:"French Southern Territories",GA:"Gabon",GE:"Georgia",DE:"Germany",GH:"Ghana",GI:"Gibraltar",GR:"Greece",GL:"Greenland",GD:"Grenada",GP:"Guadeloupe",GU:"Guam",GT:"Guatemala",GN:"Guinea",GW:"Guinea-Bissau",GY:"Guyana",HT:"Haiti",HM:"Heard and Mc Donald Islands",HN:"Honduras",HK:"Hong Kong",HU:"Hungary",IS:"Iceland",IN:"India",ID:"Indonesia",IR:"Iran",IQ:"Iraq",IE:"Ireland",IL:"Israel",IT:"Italy",JM:"Jamaica",JP:"Japan",JO:"Jordan",KZ:"Kazakhstan",KE:"Kenya",KI:"Kiribati",KW:"Kuwait",KG:"Kyrgyzstan",LA:"Laos",LV:"Latvia",LB:"Lebanon",LS:"Lesotho",LR:"Liberia",LY:"Libya",LI:"Liechtenstein",LT:"Lithuania",LU:"Luxembourg",MO:"Macau",MG:"Madagascar",MW:"Malawi",MY:"Malaysia",MV:"Maldives",ML:"Mali",MT:"Malta",MH:"Marshall Islands",MQ:"Martinique",MR:"Mauritania",MU:"Mauritius",YT:"Mayotte",MX:"Mexico",FM:"Micronesia",MD:"Moldova",MC:"Monaco",MN:"Mongolia",ME:"Montenegro",MS:"Montserrat",MA:"Morocco",MZ:"Mozambique",MM:"Myanmar",NA:"Namibia",NR:"Nauru",NP:"Nepal",NL:"Netherlands",AN:"Netherlands Antilles",NC:"New Caledonia",NZ:"New Zealand",NI:"Nicaragua",NE:"Niger",NG:"Nigeria",NU:"Niue",NF:"Norfolk Island",KP:"North Korea",MP:"Northern Marianas",NO:"Norway",OM:"Oman",PK:"Pakistan",PW:"Palau",PS:"Palestine",PA:"Panama",PG:"Papua New Guinea",PY:"Paraguay",PE:"Peru",PH:"Philippines",PN:"Pitcairn Islands",PL:"Poland",PT:"Portugal",PR:"Puerto Rico",QA:"Qatar",RE:"Reunion",RO:"Romania",RU:"Russia",RW:"Rwanda",ST:"São Tomé and Príncipe",SH:"Saint Helena",PM:"St. Pierre and Miquelon",KN:"Saint Kitts and Nevis",LC:"Saint Lucia",VC:"Saint Vincent and the Grenadines",WS:"Samoa",SM:"San Marino",SA:"Saudi Arabia",SN:"Senegal",RS:"Serbia",SC:"Seychelles",SL:"Sierra Leone",SG:"Singapore",SK:"Slovakia",SI:"Slovenia",SB:"Solomon Islands",SO:"Somalia",ZA:"South Africa",GS:"South Georgia and the South Sandwich Islands",KR:"South Korea",ES:"Spain",LK:"Sri Lanka",SD:"Sudan",SR:"Suriname",SJ:"Svalbard and Jan Mayen Islands",SZ:"Swaziland",SE:"Sweden",CH:"Switzerland",SY:"Syria",TW:"Taiwan",TJ:"Tajikistan",TZ:"Tanzania",TH:"Thailand",BS:"The Bahamas",GM:"The Gambia",TG:"Togo",TK:"Tokelau",TO:"Tonga",TT:"Trinidad and Tobago",TN:"Tunisia",TR:"Turkey",TM:"Turkmenistan",TC:"Turks and Caicos Islands",TV:"Tuvalu",VI:"US Virgin Islands",UG:"Uganda",UA:"Ukraine",AE:"United Arab Emirates",GB:"United Kingdom",US:"United States",UM:"United States Minor Outlying Islands",UY:"Uruguay",UZ:"Uzbekistan",VU:"Vanuatu",VA:"Vatican City",VE:"Venezuela",VN:"Vietnam",WF:"Wallis and Futuna Islands",EH:"Western Sahara",YE:"Yemen",ZM:"Zambia",ZW:"Zimbabwe"},BFHCurrenciesList={AED:{label:"United Arab Emirates dirham",currencyflag:"",symbol:"د.إ"},AFN:{label:"Afghan afghani",currencyflag:"",symbol:"؋"},ALL:{label:"Albanian lek",currencyflag:"",symbol:"L"},AMD:{label:"Armenian dram",currencyflag:"",symbol:"դր"},AOA:{label:"Angolan kwanza",currencyflag:"",symbol:"Kz"},ARS:{label:"Argentine peso",currencyflag:"",symbol:"$"},AUD:{label:"Australian dollar",currencyflag:"AUD",symbol:"$"},AWG:{label:"Aruban florin",currencyflag:"",symbol:"ƒ"},AZN:{label:"Azerbaijani manat",currencyflag:"",symbol:""},BAM:{label:"Bosnia and Herzegovina convertible mark",currencyflag:"",symbol:"KM"},BBD:{label:"Barbadian dollar",currencyflag:"",symbol:"$"},BDT:{label:"Bangladeshi taka",currencyflag:"",symbol:"৳"},BGN:{label:"Bulgarian lev",currencyflag:"",symbol:"лв"},BHD:{label:"Bahraini dinar",currencyflag:"",symbol:".د.ب"},BIF:{label:"Burundian franc",currencyflag:"",symbol:"Fr"},BMD:{label:"Bermudian dollar",currencyflag:"",symbol:"$"},BND:{label:"Brunei dollar",currencyflag:"",symbol:"$"},BOB:{label:"Bolivian boliviano",currencyflag:"",symbol:"Bs"},BRL:{label:"Brazilian real",currencyflag:"",symbol:"R$"},BSD:{label:"Bahamian dollar",currencyflag:"",symbol:"$"},BTN:{label:"Bhutanese ngultrum",currencyflag:"",symbol:"Nu"},BWP:{label:"Botswana pula",currencyflag:"",symbol:"P"},BYR:{label:"Belarusian ruble",currencyflag:"",symbol:"Br"},BZD:{label:"Belize dollar",currencyflag:"",symbol:"$"},CAD:{label:"Canadian dollar",currencyflag:"",symbol:"$"},CDF:{label:"Congolese franc",currencyflag:"",symbol:"Fr"},CHF:{label:"Swiss franc",currencyflag:"CHF",symbol:"Fr"},CLP:{label:"Chilean peso",currencyflag:"",symbol:"$"},CNY:{label:"Chinese yuan",currencyflag:"",symbol:"¥"},COP:{label:"Colombian peso",currencyflag:"",symbol:"$"},CRC:{label:"Costa Rican colón",currencyflag:"",symbol:"₡"},CUP:{label:"Cuban convertible peso",currencyflag:"",symbol:"$"},CVE:{label:"Cape Verdean escudo",currencyflag:"",symbol:"$"},CZK:{label:"Czech koruna",currencyflag:"",symbol:"Kč"},DJF:{label:"Djiboutian franc",currencyflag:"",symbol:"Fr"},DKK:{label:"Danish krone",currencyflag:"DKK",symbol:"kr"},DOP:{label:"Dominican peso",currencyflag:"",symbol:"$"},DZD:{label:"Algerian dinar",currencyflag:"",symbol:"د.ج"},EGP:{label:"Egyptian pound",currencyflag:"",symbol:"ج.م"},ERN:{label:"Eritrean nakfa",currencyflag:"",symbol:"Nfk"},ETB:{label:"Ethiopian birr",currencyflag:"",symbol:"Br"},EUR:{label:"Euro",currencyflag:"EUR",symbol:"€"},FJD:{label:"Fijian dollar",currencyflag:"",symbol:"$"},FKP:{label:"Falkland Islands pound",currencyflag:"",symbol:"£"},GBP:{label:"British pound",currencyflag:"",symbol:"£"},GEL:{label:"Georgian lari",currencyflag:"",symbol:"ლ"},GHS:{label:"Ghana cedi",currencyflag:"",symbol:"₵"},GMD:{label:"Gambian dalasi",currencyflag:"",symbol:"D"},GNF:{label:"Guinean franc",currencyflag:"",symbol:"Fr"},GTQ:{label:"Guatemalan quetzal",currencyflag:"",symbol:"Q"},GYD:{label:"Guyanese dollar",currencyflag:"",symbol:"$"},HKD:{label:"Hong Kong dollar",currencyflag:"",symbol:"$"},HNL:{label:"Honduran lempira",currencyflag:"",symbol:"L"},HRK:{label:"Croatian kuna",currencyflag:"",symbol:"kn"},HTG:{label:"Haitian gourde",currencyflag:"",symbol:"G"},HUF:{label:"Hungarian forint",currencyflag:"",symbol:"Ft"},IDR:{label:"Indonesian rupiah",currencyflag:"",symbol:"Rp"},ILS:{label:"Israeli new shekel",currencyflag:"",symbol:"₪"},IMP:{label:"Manx pound",currencyflag:"",symbol:"£"},INR:{label:"Indian rupee",currencyflag:"",symbol:""},IQD:{label:"Iraqi dinar",currencyflag:"",symbol:"ع.د"},IRR:{label:"Iranian rial",currencyflag:"",symbol:"﷼"},ISK:{label:"Icelandic króna",currencyflag:"",symbol:"kr"},JEP:{label:"Jersey pound",currencyflag:"",symbol:"£"},JMD:{label:"Jamaican dollar",currencyflag:"",symbol:"$"},JOD:{label:"Jordanian dinar",currencyflag:"",symbol:"د.ا"},JPY:{label:"Japanese yen",currencyflag:"",symbol:"¥"},KES:{label:"Kenyan shilling",currencyflag:"",symbol:"Sh"},KGS:{label:"Kyrgyzstani som",currencyflag:"",symbol:"лв"},KHR:{label:"Cambodian riel",currencyflag:"",symbol:"៛"},KMF:{label:"Comorian franc",currencyflag:"",symbol:"Fr"},KPW:{label:"North Korean won",currencyflag:"",symbol:"₩"},KRW:{label:"South Korean won",currencyflag:"",symbol:"₩"},KWD:{label:"Kuwaiti dinar",currencyflag:"",symbol:"د.ك"},KYD:{label:"Cayman Islands dollar",currencyflag:"",symbol:"$"},KZT:{label:"Kazakhstani tenge",currencyflag:"",symbol:"₸"},LAK:{label:"Lao kip",currencyflag:"",symbol:"₭"},LBP:{label:"Lebanese pound",currencyflag:"",symbol:"ل.ل"},LKR:{label:"Sri Lankan rupee",currencyflag:"",symbol:"Rs"},LRD:{label:"Liberian dollar",currencyflag:"",symbol:"$"},LSL:{label:"Lesotho loti",currencyflag:"",symbol:"L"},LTL:{label:"Lithuanian litas",currencyflag:"",symbol:"Lt"},LVL:{label:"Latvian lats",currencyflag:"",symbol:"Ls"},LYD:{label:"Libyan dinar",currencyflag:"",symbol:"ل.د"},MAD:{label:"Moroccan dirham",currencyflag:"",symbol:"د.م."},MDL:{label:"Moldovan leu",currencyflag:"",symbol:"L"},MGA:{label:"Malagasy ariary",currencyflag:"",symbol:"Ar"},MKD:{label:"Macedonian denar",currencyflag:"",symbol:"ден"},MMK:{label:"Burmese kyat",currencyflag:"",symbol:"Ks"},MNT:{label:"Mongolian tögrög",currencyflag:"",symbol:"₮"},MOP:{label:"Macanese pataca",currencyflag:"",symbol:"P"},MRO:{label:"Mauritanian ouguiya",currencyflag:"",symbol:"UM"},MUR:{label:"Mauritian rupee",currencyflag:"",symbol:"Rs"},MVR:{label:"Maldivian rufiyaa",currencyflag:"",symbol:".ރ"},MWK:{label:"Malawian kwacha",currencyflag:"",symbol:"MK"},MXN:{label:"Mexican peso",currencyflag:"",symbol:"$"},MYR:{label:"Malaysian ringgit",currencyflag:"",symbol:"MR"},MZN:{label:"Mozambican metical",currencyflag:"",symbol:"MT"},NAD:{label:"Namibian dollar",currencyflag:"",symbol:"$"},NGN:{label:"Nigerian naira",currencyflag:"",symbol:"₦"},NIO:{label:"Nicaraguan córdoba",currencyflag:"",symbol:"C$"},NOK:{label:"Norwegian krone",currencyflag:"",symbol:"kr"},NPR:{label:"Nepalese rupee",currencyflag:"",symbol:"Rs"},NZD:{label:"New Zealand dollar",currencyflag:"",symbol:"$"},OMR:{label:"Omani rial",currencyflag:"",symbol:"ر.ع."},PAB:{label:"Panamanian balboa",currencyflag:"",symbol:"B/."},PEN:{label:"Peruvian nuevo sol",currencyflag:"",symbol:"S/."},PGK:{label:"Papua New Guinean kina",currencyflag:"",symbol:"K"},PHP:{label:"Philippine peso",currencyflag:"",symbol:"₱"},PKR:{label:"Pakistani rupee",currencyflag:"",symbol:"Rs"},PLN:{label:"Polish złoty",currencyflag:"",symbol:"zł"},PRB:{label:"Transnistrian ruble",currencyflag:"",symbol:"р."},PYG:{label:"Paraguayan guaraní",currencyflag:"",symbol:"₲"},QAR:{label:"Qatari riyal",currencyflag:"",symbol:"ر.ق"},RON:{label:"Romanian leu",currencyflag:"",symbol:"L"},RSD:{label:"Serbian dinar",currencyflag:"",symbol:"дин"},RUB:{label:"Russian ruble",currencyflag:"",symbol:"руб."},RWF:{label:"Rwandan franc",currencyflag:"",symbol:"Fr"},SAR:{label:"Saudi riyal",currencyflag:"",symbol:"ر.س"},SBD:{label:"Solomon Islands dollar",currencyflag:"",symbol:"$"},SCR:{label:"Seychellois rupee",currencyflag:"",symbol:"Rs"},SDG:{label:"Singapore dollar",currencyflag:"",symbol:"$"},SEK:{label:"Swedish krona",currencyflag:"",symbol:"kr"},SGD:{label:"Singapore dollar",currencyflag:"",symbol:"$"},SHP:{label:"Saint Helena pound",currencyflag:"",symbol:"£"},SLL:{label:"Sierra Leonean leone",currencyflag:"",symbol:"Le"},SOS:{label:"Somali shilling",currencyflag:"",symbol:"Sh"},SRD:{label:"Surinamese dollar",currencyflag:"",symbol:"$"},SSP:{label:"South Sudanese pound",currencyflag:"",symbol:"£"},STD:{label:"São Tomé and Príncipe dobra",currencyflag:"",symbol:"Db"},SVC:{label:"Salvadoran colón",currencyflag:"",symbol:"₡"},SYP:{label:"Syrian pound",currencyflag:"",symbol:"£"},SZL:{label:"Swazi lilangeni",currencyflag:"",symbol:"L"},THB:{label:"Thai baht",currencyflag:"",symbol:"฿"},TJS:{label:"Tajikistani somoni",currencyflag:"",symbol:"SM"},TMT:{label:"Turkmenistan manat",currencyflag:"",symbol:"m"},TND:{label:"Tunisian dinar",currencyflag:"",symbol:"د.ت"},TOP:{label:"Tongan paʻanga",currencyflag:"",symbol:"T$"},TRY:{label:"Turkish lira",currencyflag:"",symbol:"₺"},TTD:{label:"Trinidad and Tobago dollar",currencyflag:"",symbol:"$"},TWD:{label:"New Taiwan dollar",currencyflag:"",symbol:"$"},TZS:{label:"Tanzanian shilling",currencyflag:"",symbol:"Sh"},UAH:{label:"Ukrainian hryvnia",currencyflag:"",symbol:"₴"},UGX:{label:"Ugandan shilling",currencyflag:"",symbol:"Sh"},USD:{label:"United States dollar",currencyflag:"",symbol:"$"},UYU:{label:"Uruguayan peso",currencyflag:"",symbol:"$"},UZS:{label:"Uzbekistani som",currencyflag:"",symbol:"лв"},VEF:{label:"Venezuelan bolívar",currencyflag:"",symbol:"Bs F"},VND:{label:"Vietnamese đồng",currencyflag:"",symbol:"₫"},VUV:{label:"Vanuatu vatu",currencyflag:"",symbol:"Vt"},WST:{label:"Samoan tālā",currencyflag:"",symbol:"T"},XAF:{label:"Central African CFA franc",currencyflag:"XAF",symbol:"Fr"},XCD:{label:"East Caribbean dollar",currencyflag:"XCD",symbol:"$"},XOF:{label:"West African CFA franc",currencyflag:"XOF",symbol:"Fr"},XPF:{label:"CFP franc",currencyflag:"XPF",symbol:"Fr"},YER:{label:"Yemeni rial",currencyflag:"",symbol:"﷼"},ZAR:{label:"South African rand",currencyflag:"ZAR",symbol:"R"},ZMW:{label:"Zambian kwacha",currencyflag:"",symbol:"ZK"},ZWL:{label:"Zimbabwean dollar",currencyflag:"",symbol:"$"}},BFHMonthsList=["January","February","March","April","May","June","July","August","September","October","November","December"],BFHDaysList=["SUN","MON","TUE","WED","THU","FRI","SAT"],BFHDayOfWeekStart=0,BFHFontsList={"Andale Mono":'"Andale Mono", AndaleMono, monospace',Arial:'Arial, "Helvetica Neue", Helvetica, sans-serif',"Arial Black":'"Arial Black", "Arial Bold", Gadget, sans-serif',"Arial Narrow":'"Arial Narrow", Arial, sans-serif',"Arial Rounded MT Bold":'"Arial Rounded MT Bold", "Helvetica Rounded", Arial, sans-serif',"Avant Garde":'"Avant Garde", Avantgarde, "Century Gothic", CenturyGothic, "AppleGothic", sans-serif',Baskerville:'Baskerville, "Baskerville Old Face", "Hoefler Text", Garamond, "Times New Roman", serif',"Big Caslon":'"Big Caslon", "Book Antiqua", "Palatino Linotype", Georgia, serif',"Bodoni MT":'"Bodoni MT", Didot, "Didot LT STD", "Hoefler Text", Garamond, "Times New Roman", serif',"Book Antiqua":'"Book Antiqua", Palatino, "Palatino Linotype", "Palatino LT STD", Georgia, serif',"Brush Script MT":'"Brush Script MT", cursive',Calibri:'Calibri, Candara, Segoe, "Segoe UI", Optima, Arial, sans-serif',"Calisto MT":'"Calisto MT", "Bookman Old Style", Bookman, "Goudy Old Style", Garamond, "Hoefler Text", "Bitstream Charter", Georgia, serif',Cambrio:"Cambria, Georgia, serif",Candara:'Candara, Calibri, Segoe, "Segoe UI", Optima, Arial, sans-serif',"Century Gothic":'"Century Gothic", CenturyGothic, AppleGothic, sans-serif',Consolas:"Consolas, monaco, monospace",Copperplate:'Copperplate, "Copperplate Gothic Light", fantasy',"Courier New":'"Courier New", Courier, "Lucida Sans Typewriter", "Lucida Typewriter", monospace',Didot:'Didot, "Didot LT STD", "Hoefler Text", Garamond, "Times New Roman", serif',"Franklin Gothic Medium":'"Franklin Gothic Medium", "Franklin Gothic", "ITC Franklin Gothic", Arial, sans-serif',Futura:'Futura, "Trebuchet MS", Arial, sans-serif',Garamond:'Garamond, Baskerville, "Baskerville Old Face", "Hoefler Text", "Times New Roman", serif',Geneva:"Geneva, Tahoma, Verdana, sans-serif",Georgia:'Georgia, Times, "Times New Roman", serif',"Gill Sans":'"Gill Sans", "Gill Sans MT", Calibri, sans-serif',"Goudy Old Style":'"Goudy Old Style", Garamond, "Big Caslon", "Times New Roman", serif',Helvetica:'"Helvetica Neue", Helvetica, Arial, sans-serif',"Hoefler Text":'"Hoefler Text", "Baskerville old face", Garamond, "Times New Roman", serif',Impact:'Impact, Haettenschweiler, "Franklin Gothic Bold", Charcoal, "Helvetica Inserat", "Bitstream Vera Sans Bold", "Arial Black", sans serif',"Lucida Bright":'"Lucida Bright", Georgia, serif',"Lucida Console":'"Lucida Console", "Lucida Sans Typewriter", Monaco, "Bitstream Vera Sans Mono", monospace',"Lucida Sans Typewriter":'"Lucida Sans Typewriter", "Lucida Console", Monaco, "Bitstream Vera Sans Mono", monospace',"Lucida Grande":'"Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif',Monaco:'Monaco, Consolas, "Lucida Console", monospace',Optima:'Optima, Segoe, "Segoe UI", Candara, Calibri, Arial, sans-serif',Palatino:'Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif',Papyrus:"Papyrus, fantasy",Perpetua:'Perpetua, Baskerville, "Big Caslon", "Palatino Linotype", Palatino, "URW Palladio L", "Nimbus Roman No9 L", serif',Rockwell:'Rockwell, "Courier Bold", Courier, Georgia, Times, "Times New Roman", serif',"Rockwell Extra Bold":'"Rockwell Extra Bold", "Rockwell Bold", monospace',"Segoe UI":'"Segoe UI", Frutiger, "Frutiger Linotype',Tahoma:"Tahoma, Verdana, Segoe, sans-serif","Times New Roman":'TimesNewRoman, "Times New Roman", Times, Baskerville, Georgia, serif',"Trebuchet MS":'"Trebuchet MS", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Tahoma, sans-serif',Verdana:"Verdana, Geneva, sans-serif"},BFHFontSizesList={8:"8px",9:"9px",10:"10px",11:"11px",12:"12px",14:"14px",16:"16px",18:"18px",20:"20px",24:"24px",28:"28px",36:"36px",48:"48px"},BFHGoogleFontsList={kind:"webfonts#webfontList",items:[{kind:"webfonts#webfont",family:"ABeeZee",variants:["regular","italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Abel",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Abril Fatface",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Aclonica",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Acme",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Actor",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Adamina",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Advent Pro",variants:["100","200","300","regular","500","600","700"],subsets:["latin-ext","latin","greek"]},{kind:"webfonts#webfont",family:"Aguafina Script",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Akronim",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Aladin",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Aldrich",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Alegreya",variants:["regular","italic","700","700italic","900","900italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Alegreya SC",variants:["regular","italic","700","700italic","900","900italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Alex Brush",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Alfa Slab One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Alice",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Alike",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Alike Angular",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Allan",variants:["regular","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Allerta",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Allerta Stencil",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Allura",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Almendra",variants:["regular","italic","700","700italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Almendra Display",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Almendra SC",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Amarante",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Amaranth",variants:["regular","italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Amatic SC",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Amethysta",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Anaheim",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Andada",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Andika",variants:["regular"],subsets:["cyrillic","latin-ext","latin","cyrillic-ext"]},{kind:"webfonts#webfont",family:"Angkor",variants:["regular"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Annie Use Your Telescope",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Anonymous Pro",variants:["regular","italic","700","700italic"],subsets:["cyrillic","greek-ext","latin-ext","latin","greek","cyrillic-ext"]},{kind:"webfonts#webfont",family:"Antic",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Antic Didone",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Antic Slab",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Anton",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Arapey",variants:["regular","italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Arbutus",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Arbutus Slab",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Architects Daughter",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Archivo Black",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Archivo Narrow",variants:["regular","italic","700","700italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Arimo",variants:["regular","italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Arizonia",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Armata",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Artifika",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Arvo",variants:["regular","italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Asap",variants:["regular","italic","700","700italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Asset",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Astloch",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Asul",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Atomic Age",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Aubrey",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Audiowide",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Autour One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Average",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Average Sans",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Averia Gruesa Libre",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Averia Libre",variants:["300","300italic","regular","italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Averia Sans Libre",variants:["300","300italic","regular","italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Averia Serif Libre",variants:["300","300italic","regular","italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Bad Script",variants:["regular"],subsets:["cyrillic","latin"]},{kind:"webfonts#webfont",family:"Balthazar",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Bangers",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Basic",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Battambang",variants:["regular","700"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Baumans",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Bayon",variants:["regular"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Belgrano",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Belleza",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"BenchNine",variants:["300","regular","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Bentham",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Berkshire Swash",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Bevan",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Bigelow Rules",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Bigshot One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Bilbo",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Bilbo Swash Caps",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Bitter",variants:["regular","italic","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Black Ops One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Bokor",variants:["regular"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Bonbon",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Boogaloo",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Bowlby One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Bowlby One SC",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Brawler",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Bree Serif",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Bubblegum Sans",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Bubbler One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Buda",variants:["300"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Buenard",variants:["regular","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Butcherman",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Butterfly Kids",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Cabin",variants:["regular","italic","500","500italic","600","600italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Cabin Condensed",variants:["regular","500","600","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Cabin Sketch",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Caesar Dressing",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Cagliostro",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Calligraffitti",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Cambo",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Candal",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Cantarell",variants:["regular","italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Cantata One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Cantora One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Capriola",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Cardo",variants:["regular","italic","700"],subsets:["greek-ext","latin-ext","latin","greek"]},{kind:"webfonts#webfont",family:"Carme",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Carrois Gothic",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Carrois Gothic SC",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Carter One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Caudex",variants:["regular","italic","700","700italic"],subsets:["greek-ext","latin-ext","latin","greek"]},{kind:"webfonts#webfont",family:"Cedarville Cursive",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Ceviche One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Changa One",variants:["regular","italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Chango",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Chau Philomene One",variants:["regular","italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Chela One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Chelsea Market",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Chenla",variants:["regular"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Cherry Cream Soda",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Cherry Swash",variants:["regular","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Chewy",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Chicle",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Chivo",variants:["regular","italic","900","900italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Cinzel",variants:["regular","700","900"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Cinzel Decorative",variants:["regular","700","900"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Clicker Script",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Coda",variants:["regular","800"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Coda Caption",variants:["800"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Codystar",variants:["300","regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Combo",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Comfortaa",variants:["300","regular","700"],subsets:["cyrillic","latin-ext","latin","greek","cyrillic-ext"]},{kind:"webfonts#webfont",family:"Coming Soon",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Concert One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Condiment",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Content",variants:["regular","700"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Contrail One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Convergence",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Cookie",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Copse",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Corben",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Courgette",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Cousine",variants:["regular","italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Coustard",variants:["regular","900"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Covered By Your Grace",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Crafty Girls",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Creepster",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Crete Round",variants:["regular","italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Crimson Text",variants:["regular","italic","600","600italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Croissant One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Crushed",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Cuprum",variants:["regular","italic","700","700italic"],subsets:["cyrillic","latin-ext","latin"]},{kind:"webfonts#webfont",family:"Cutive",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Cutive Mono",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Damion",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Dancing Script",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Dangrek",variants:["regular"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Dawning of a New Day",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Days One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Delius",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Delius Swash Caps",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Delius Unicase",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Della Respira",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Devonshire",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Didact Gothic",variants:["regular"],subsets:["cyrillic","greek-ext","latin-ext","latin","greek","cyrillic-ext"]},{kind:"webfonts#webfont",family:"Diplomata",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Diplomata SC",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Doppio One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Dorsa",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Dosis",variants:["200","300","regular","500","600","700","800"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Dr Sugiyama",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Droid Sans",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Droid Sans Mono",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Droid Serif",variants:["regular","italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Duru Sans",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Dynalight",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"EB Garamond",variants:["regular"],subsets:["cyrillic","latin-ext","latin","vietnamese","cyrillic-ext"]},{kind:"webfonts#webfont",family:"Eagle Lake",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Eater",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Economica",variants:["regular","italic","700","700italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Electrolize",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Emblema One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Emilys Candy",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Engagement",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Englebert",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Enriqueta",variants:["regular","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Erica One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Esteban",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Euphoria Script",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Ewert",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Exo",variants:["100","100italic","200","200italic","300","300italic","regular","italic","500","500italic","600","600italic","700","700italic","800","800italic","900","900italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Expletus Sans",variants:["regular","italic","500","500italic","600","600italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Fanwood Text",variants:["regular","italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Fascinate",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Fascinate Inline",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Faster One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Fasthand",variants:["regular"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Federant",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Federo",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Felipa",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Fenix",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Finger Paint",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Fjord One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Flamenco",variants:["300","regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Flavors",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Fondamento",variants:["regular","italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Fontdiner Swanky",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Forum",variants:["regular"],subsets:["cyrillic","latin-ext","latin","cyrillic-ext"]},{kind:"webfonts#webfont",family:"Francois One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Freckle Face",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Fredericka the Great",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Fredoka One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Freehand",variants:["regular"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Fresca",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Frijole",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Fugaz One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"GFS Didot",variants:["regular"],subsets:["greek"]},{kind:"webfonts#webfont",family:"GFS Neohellenic",variants:["regular","italic","700","700italic"],subsets:["greek"]},{kind:"webfonts#webfont",family:"Gafata",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Galdeano",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Galindo",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Gentium Basic",variants:["regular","italic","700","700italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Gentium Book Basic",variants:["regular","italic","700","700italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Geo",variants:["regular","italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Geostar",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Geostar Fill",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Germania One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Gilda Display",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Give You Glory",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Glass Antiqua",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Glegoo",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Gloria Hallelujah",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Goblin One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Gochi Hand",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Gorditas",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Goudy Bookletter 1911",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Graduate",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Gravitas One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Great Vibes",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Griffy",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Gruppo",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Gudea",variants:["regular","italic","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Habibi",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Hammersmith One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Hanalei",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Hanalei Fill",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Handlee",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Hanuman",variants:["regular","700"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Happy Monkey",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Headland One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Henny Penny",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Herr Von Muellerhoff",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Holtwood One SC",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Homemade Apple",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Homenaje",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"IM Fell DW Pica",variants:["regular","italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"IM Fell DW Pica SC",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"IM Fell Double Pica",variants:["regular","italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"IM Fell Double Pica SC",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"IM Fell English",variants:["regular","italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"IM Fell English SC",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"IM Fell French Canon",variants:["regular","italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"IM Fell French Canon SC",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"IM Fell Great Primer",variants:["regular","italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"IM Fell Great Primer SC",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Iceberg",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Iceland",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Imprima",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Inconsolata",variants:["regular","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Inder",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Indie Flower",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Inika",variants:["regular","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Irish Grover",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Istok Web",variants:["regular","italic","700","700italic"],subsets:["cyrillic","latin-ext","latin","cyrillic-ext"]},{kind:"webfonts#webfont",family:"Italiana",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Italianno",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Jacques Francois",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Jacques Francois Shadow",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Jim Nightshade",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Jockey One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Jolly Lodger",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Josefin Sans",variants:["100","100italic","300","300italic","regular","italic","600","600italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Josefin Slab",variants:["100","100italic","300","300italic","regular","italic","600","600italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Joti One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Judson",variants:["regular","italic","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Julee",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Julius Sans One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Junge",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Jura",variants:["300","regular","500","600"],subsets:["cyrillic","greek-ext","latin-ext","latin","greek","cyrillic-ext"]},{kind:"webfonts#webfont",family:"Just Another Hand",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Just Me Again Down Here",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Kameron",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Karla",variants:["regular","italic","700","700italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Kaushan Script",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Keania One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Kelly Slab",variants:["regular"],subsets:["cyrillic","latin-ext","latin"]},{kind:"webfonts#webfont",family:"Kenia",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Khmer",variants:["regular"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Kite One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Knewave",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Kotta One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Koulen",variants:["regular"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Kranky",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Kreon",variants:["300","regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Kristi",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Krona One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"La Belle Aurore",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Lancelot",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Lato",variants:["100","100italic","300","300italic","regular","italic","700","700italic","900","900italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"League Script",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Leckerli One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Ledger",variants:["regular"],subsets:["cyrillic","latin-ext","latin"]},{kind:"webfonts#webfont",family:"Lekton",variants:["regular","italic","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Lemon",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Life Savers",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Lilita One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Limelight",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Linden Hill",variants:["regular","italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Lobster",variants:["regular"],subsets:["cyrillic","latin-ext","latin","cyrillic-ext"]},{kind:"webfonts#webfont",family:"Lobster Two",variants:["regular","italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Londrina Outline",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Londrina Shadow",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Londrina Sketch",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Londrina Solid",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Lora",variants:["regular","italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Love Ya Like A Sister",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Loved by the King",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Lovers Quarrel",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Luckiest Guy",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Lusitana",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Lustria",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Macondo",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Macondo Swash Caps",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Magra",variants:["regular","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Maiden Orange",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Mako",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Marcellus",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Marcellus SC",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Marck Script",variants:["regular"],subsets:["cyrillic","latin-ext","latin"]},{kind:"webfonts#webfont",family:"Margarine",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Marko One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Marmelad",variants:["regular"],subsets:["cyrillic","latin-ext","latin"]},{kind:"webfonts#webfont",family:"Marvel",variants:["regular","italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Mate",variants:["regular","italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Mate SC",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Maven Pro",variants:["regular","500","700","900"],subsets:["latin"]},{kind:"webfonts#webfont",family:"McLaren",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Meddon",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"MedievalSharp",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Medula One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Megrim",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Meie Script",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Merienda",variants:["regular","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Merienda One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Merriweather",variants:["300","regular","700","900"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Metal",variants:["regular"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Metal Mania",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Metamorphous",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Metrophobic",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Michroma",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Miltonian",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Miltonian Tattoo",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Miniver",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Miss Fajardose",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Modern Antiqua",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Molengo",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Molle",variants:["italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Monofett",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Monoton",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Monsieur La Doulaise",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Montaga",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Montez",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Montserrat",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Montserrat Alternates",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Montserrat Subrayada",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Moul",variants:["regular"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Moulpali",variants:["regular"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Mountains of Christmas",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Mouse Memoirs",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Mr Bedfort",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Mr Dafoe",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Mr De Haviland",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Mrs Saint Delafield",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Mrs Sheppards",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Muli",variants:["300","300italic","regular","italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Mystery Quest",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Neucha",variants:["regular"],subsets:["cyrillic","latin"]},{kind:"webfonts#webfont",family:"Neuton",variants:["200","300","regular","italic","700","800"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"News Cycle",variants:["regular","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Niconne",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Nixie One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Nobile",variants:["regular","italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Nokora",variants:["regular","700"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Norican",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Nosifer",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Nothing You Could Do",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Noticia Text",variants:["regular","italic","700","700italic"],subsets:["latin-ext","latin","vietnamese"]},{kind:"webfonts#webfont",family:"Nova Cut",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Nova Flat",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Nova Mono",variants:["regular"],subsets:["latin","greek"]},{kind:"webfonts#webfont",family:"Nova Oval",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Nova Round",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Nova Script",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Nova Slim",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Nova Square",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Numans",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Nunito",variants:["300","regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Odor Mean Chey",variants:["regular"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Offside",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Old Standard TT",variants:["regular","italic","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Oldenburg",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Oleo Script",variants:["regular","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Oleo Script Swash Caps",variants:["regular","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Open Sans",variants:["300","300italic","regular","italic","600","600italic","700","700italic","800","800italic"],subsets:["cyrillic","greek-ext","latin-ext","latin","vietnamese","greek","cyrillic-ext"]},{kind:"webfonts#webfont",family:"Open Sans Condensed",variants:["300","300italic","700"],subsets:["cyrillic","greek-ext","latin-ext","latin","vietnamese","greek","cyrillic-ext"]},{kind:"webfonts#webfont",family:"Oranienbaum",variants:["regular"],subsets:["cyrillic","latin-ext","latin","cyrillic-ext"]},{kind:"webfonts#webfont",family:"Orbitron",variants:["regular","500","700","900"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Oregano",variants:["regular","italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Orienta",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Original Surfer",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Oswald",variants:["300","regular","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Over the Rainbow",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Overlock",variants:["regular","italic","700","700italic","900","900italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Overlock SC",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Ovo",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Oxygen",variants:["300","regular","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Oxygen Mono",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"PT Mono",variants:["regular"],subsets:["cyrillic","latin-ext","latin","cyrillic-ext"]},{kind:"webfonts#webfont",family:"PT Sans",variants:["regular","italic","700","700italic"],subsets:["cyrillic","latin-ext","latin"]},{kind:"webfonts#webfont",family:"PT Sans Caption",variants:["regular","700"],subsets:["cyrillic","latin-ext","latin"]},{kind:"webfonts#webfont",family:"PT Sans Narrow",variants:["regular","700"],subsets:["cyrillic","latin-ext","latin"]},{kind:"webfonts#webfont",family:"PT Serif",variants:["regular","italic","700","700italic"],subsets:["cyrillic","latin"]},{kind:"webfonts#webfont",family:"PT Serif Caption",variants:["regular","italic"],subsets:["cyrillic","latin"]},{kind:"webfonts#webfont",family:"Pacifico",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Paprika",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Parisienne",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Passero One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Passion One",variants:["regular","700","900"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Patrick Hand",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Patua One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Paytone One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Peralta",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Permanent Marker",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Petit Formal Script",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Petrona",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Philosopher",variants:["regular","italic","700","700italic"],subsets:["cyrillic","latin"]},{kind:"webfonts#webfont",family:"Piedra",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Pinyon Script",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Pirata One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Plaster",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Play",variants:["regular","700"],subsets:["cyrillic","greek-ext","latin-ext","latin","greek","cyrillic-ext"]},{kind:"webfonts#webfont",family:"Playball",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Playfair Display",variants:["regular","italic","700","700italic","900","900italic"],subsets:["cyrillic","latin-ext","latin"]},{kind:"webfonts#webfont",family:"Playfair Display SC",variants:["regular","italic","700","700italic","900","900italic"],subsets:["cyrillic","latin-ext","latin"]},{kind:"webfonts#webfont",family:"Podkova",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Poiret One",variants:["regular"],subsets:["cyrillic","latin-ext","latin"]},{kind:"webfonts#webfont",family:"Poller One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Poly",variants:["regular","italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Pompiere",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Pontano Sans",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Port Lligat Sans",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Port Lligat Slab",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Prata",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Preahvihear",variants:["regular"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Press Start 2P",variants:["regular"],subsets:["cyrillic","latin-ext","latin","greek"]},{kind:"webfonts#webfont",family:"Princess Sofia",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Prociono",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Prosto One",variants:["regular"],subsets:["cyrillic","latin-ext","latin"]},{kind:"webfonts#webfont",family:"Puritan",variants:["regular","italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Purple Purse",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Quando",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Quantico",variants:["regular","italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Quattrocento",variants:["regular","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Quattrocento Sans",variants:["regular","italic","700","700italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Questrial",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Quicksand",variants:["300","regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Quintessential",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Qwigley",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Racing Sans One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Radley",variants:["regular","italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Raleway",variants:["100","200","300","regular","500","600","700","800","900"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Raleway Dots",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Rambla",variants:["regular","italic","700","700italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Rammetto One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Ranchers",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Rancho",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Rationale",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Redressed",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Reenie Beanie",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Revalia",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Ribeye",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Ribeye Marrow",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Righteous",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Risque",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Rochester",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Rock Salt",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Rokkitt",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Romanesco",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Ropa Sans",variants:["regular","italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Rosario",variants:["regular","italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Rosarivo",variants:["regular","italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Rouge Script",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Ruda",variants:["regular","700","900"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Rufina",variants:["regular","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Ruge Boogie",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Ruluko",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Rum Raisin",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Ruslan Display",variants:["regular"],subsets:["cyrillic","latin-ext","latin","cyrillic-ext"]},{kind:"webfonts#webfont",family:"Russo One",variants:["regular"],subsets:["cyrillic","latin-ext","latin"]},{kind:"webfonts#webfont",family:"Ruthie",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Rye",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Sacramento",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Sail",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Salsa",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Sanchez",variants:["regular","italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Sancreek",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Sansita One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Sarina",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Satisfy",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Scada",variants:["regular","italic","700","700italic"],subsets:["cyrillic","latin-ext","latin"]},{kind:"webfonts#webfont",family:"Schoolbell",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Seaweed Script",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Sevillana",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Seymour One",variants:["regular"],subsets:["cyrillic","latin-ext","latin"]},{kind:"webfonts#webfont",family:"Shadows Into Light",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Shadows Into Light Two",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Shanti",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Share",variants:["regular","italic","700","700italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Share Tech",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Share Tech Mono",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Shojumaru",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Short Stack",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Siemreap",variants:["regular"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Sigmar One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Signika",variants:["300","regular","600","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Signika Negative",variants:["300","regular","600","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Simonetta",variants:["regular","italic","900","900italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Sirin Stencil",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Six Caps",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Skranji",variants:["regular","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Slackey",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Smokum",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Smythe",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Sniglet",variants:["800"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Snippet",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Snowburst One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Sofadi One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Sofia",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Sonsie One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Sorts Mill Goudy",variants:["regular","italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Source Code Pro",variants:["200","300","regular","600","700","900"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Source Sans Pro",variants:["200","200italic","300","300italic","regular","italic","600","600italic","700","700italic","900","900italic"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Special Elite",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Spicy Rice",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Spinnaker",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Spirax",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Squada One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Stalemate",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Stalinist One",variants:["regular"],subsets:["cyrillic","latin-ext","latin"]},{kind:"webfonts#webfont",family:"Stardos Stencil",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Stint Ultra Condensed",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Stint Ultra Expanded",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Stoke",variants:["300","regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Strait",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Sue Ellen Francisco",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Sunshiney",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Supermercado One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Suwannaphum",variants:["regular"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Swanky and Moo Moo",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Syncopate",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Tangerine",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Taprom",variants:["regular"],subsets:["khmer"]},{kind:"webfonts#webfont",family:"Telex",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Tenor Sans",variants:["regular"],subsets:["cyrillic","latin-ext","latin","cyrillic-ext"]},{kind:"webfonts#webfont",family:"Text Me One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"The Girl Next Door",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Tienne",variants:["regular","700","900"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Tinos",variants:["regular","italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Titan One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Titillium Web",variants:["200","200italic","300","300italic","regular","italic","600","600italic","700","700italic","900"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Trade Winds",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Trocchi",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Trochut",variants:["regular","italic","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Trykker",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Tulpen One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Ubuntu",variants:["300","300italic","regular","italic","500","500italic","700","700italic"],subsets:["cyrillic","greek-ext","latin-ext","latin","greek","cyrillic-ext"]},{kind:"webfonts#webfont",family:"Ubuntu Condensed",variants:["regular"],subsets:["cyrillic","greek-ext","latin-ext","latin","greek","cyrillic-ext"]},{kind:"webfonts#webfont",family:"Ubuntu Mono",variants:["regular","italic","700","700italic"],subsets:["cyrillic","greek-ext","latin-ext","latin","greek","cyrillic-ext"]},{kind:"webfonts#webfont",family:"Ultra",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Uncial Antiqua",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Underdog",variants:["regular"],subsets:["cyrillic","latin-ext","latin"]},{kind:"webfonts#webfont",family:"Unica One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"UnifrakturCook",variants:["700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"UnifrakturMaguntia",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Unkempt",variants:["regular","700"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Unlock",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Unna",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"VT323",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Vampiro One",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Varela",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Varela Round",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Vast Shadow",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Vibur",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Vidaloka",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Viga",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Voces",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Volkhov",variants:["regular","italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Vollkorn",variants:["regular","italic","700","700italic"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Voltaire",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Waiting for the Sunrise",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Wallpoet",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Walter Turncoat",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Warnes",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Wellfleet",variants:["regular"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Wire One",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Yanone Kaffeesatz",variants:["200","300","regular","700"],subsets:["latin-ext","latin"]},{kind:"webfonts#webfont",family:"Yellowtail",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Yeseva One",variants:["regular"],subsets:["cyrillic","latin-ext","latin"]},{kind:"webfonts#webfont",family:"Yesteryear",variants:["regular"],subsets:["latin"]},{kind:"webfonts#webfont",family:"Zeyada",variants:["regular"],subsets:["latin"]}]},BFHLanguagesList={om:"Afaan Oromoo",aa:"Afaraf",af:"Afrikaans",ak:"Akan",an:"aragonés",ig:"Asụsụ Igbo",gn:"Avañe'ẽ",ae:"avesta",ay:"aymar aru",az:"azərbaycan dili",id:"Bahasa Indonesia",ms:"bahasa Melayu",bm:"bamanankan",jv:"basa Jawa",su:"Basa Sunda",bi:"Bislama",bs:"bosanski jezik",br:"brezhoneg",ca:"català",ch:"Chamoru",ny:"chiCheŵa",sn:"chiShona",co:"corsu",cy:"Cymraeg",da:"dansk",se:"Davvisámegiella",de:"Deutsch",nv:"Diné bizaad",et:"eesti",na:"Ekakairũ Naoero",en:"English",es:"español",eo:"Esperanto",eu:"euskara",ee:"Eʋegbe",to:"faka Tonga",mg:"fiteny malagasy",fr:"français",fy:"Frysk",ff:"Fulfulde",fo:"føroyskt",ga:"Gaeilge",gv:"Gaelg",sm:"gagana fa'a Samoa",gl:"galego",sq:"gjuha shqipe",gd:"Gàidhlig",ki:"Gĩkũyũ",ha:"Hausa",ho:"Hiri Motu",hr:"hrvatski jezik",io:"Ido",rw:"Ikinyarwanda",rn:"Ikirundi",ia:"Interlingua",nd:"isiNdebele",nr:"isiNdebele",xh:"isiXhosa",zu:"isiZulu",it:"italiano",ik:"Iñupiaq",pl:"polski",mh:"Kajin M̧ajeļ",kl:"kalaallisut",kr:"Kanuri",kw:"Kernewek",kg:"KiKongo",sw:"Kiswahili",ht:"Kreyòl ayisyen",kj:"Kuanyama",ku:"Kurdî",la:"latine",lv:"latviešu valoda",lt:"lietuvių kalba",ro:"limba română",li:"Limburgs",ln:"Lingála",lg:"Luganda",lb:"Lëtzebuergesch",hu:"magyar",mt:"Malti",nl:"Nederlands",no:"Norsk",nb:"Norsk bokmål",nn:"Norsk nynorsk",uz:"O'zbek",oc:"occitan",ie:"Interlingue",hz:"Otjiherero",ng:"Owambo",pt:"português",ty:"Reo Tahiti",rm:"rumantsch grischun",qu:"Runa Simi",sc:"sardu",za:"Saɯ cueŋƅ",st:"Sesotho",tn:"Setswana",ss:"SiSwati",sl:"slovenski jezik",sk:"slovenčina",so:"Soomaaliga",fi:"suomi",sv:"Svenska",mi:"te reo Māori",vi:"Tiếng Việt",lu:"Tshiluba",ve:"Tshivenḓa",tw:"Twi",tk:"Türkmen",tr:"Türkçe",ug:"Uyƣurqə",vo:"Volapük",fj:"vosa Vakaviti",wa:"walon",tl:"Wikang Tagalog",wo:"Wollof",ts:"Xitsonga",yo:"Yorùbá",sg:"yângâ tî sängö",is:"Íslenska",cs:"čeština",el:"ελληνικά",av:"авар мацӀ",ab:"аҧсуа бызшәа",ba:"башҡорт теле",be:"беларуская мова",bg:"български език",os:"ирон æвзаг",kv:"коми кыв",ky:"Кыргызча",mk:"македонски јазик",mn:"монгол",ce:"нохчийн мотт",ru:"русский язык",sr:"српски језик",tt:"татар теле",tg:"тоҷикӣ",uk:"українська мова",cv:"чӑваш чӗлхи",cu:"ѩзыкъ словѣньскъ",kk:"қазақ тілі",hy:"Հայերեն",yi:"ייִדיש",he:"עברית",ur:"اردو",ar:"العربية",fa:"فارسی",ps:"پښتو",ks:"कश्मीरी",ne:"नेपाली",pi:"पाऴि",bh:"भोजपुरी",mr:"मराठी",sa:"संस्कृतम्",sd:"सिन्धी",hi:"हिन्दी",as:"অসমীয়া",bn:"বাংলা",pa:"ਪੰਜਾਬੀ",gu:"ગુજરાતી",or:"ଓଡ଼ିଆ",ta:"தமிழ்",te:"తెలుగు",kn:"ಕನ್ನಡ",ml:"മലയാളം",si:"සිංහල",th:"ไทย",lo:"ພາສາລາວ",bo:"བོད་ཡིག",dz:"རྫོང་ཁ",my:"ဗမာစာ",ka:"ქართული",ti:"ትግርኛ",am:"አማርኛ",iu:"ᐃᓄᒃᑎᑐᑦ",oj:"ᐊᓂᔑᓈᐯᒧᐎᓐ",cr:"ᓀᐦᐃᔭᐍᐏᐣ",km:"ខ្មែរ",zh:"中文 (Zhōngwén)",ja:"日本語 (にほんご)",ii:"ꆈꌠ꒿ Nuosuhxop",ko:"한국어 (韓國語)"},BFHPhoneFormatList={AF:"+93 0dd ddd dddd",AL:"+355 0dd ddd ddd",DZ:"+213 0ddd dd dd dd",AS:"+1 (ddd) ddd-dddd",AD:"+376 ddddddddd",AO:"+244 ddd ddd ddd",AI:"+1 (ddd) ddd-dddd",AQ:"+672 ddddddddd",AG:"+1 (ddd) ddd-dddd",AR:"+54 ddddddddd",AM:"+374 0dd dddddd",AW:"+297 ddd dddd",AU:"+61 ddd ddd ddd",AT:"+43 0dddd ddddddddd",AZ:"+994 ddddddddd",BH:"+973 ddddddddd",BD:"+880 ddddddddd",BB:"+1 ddddddddd",BY:"+375 ddddddddd",BE:"+32 ddddddddd",BZ:"+501 ddddddddd",BJ:"+229 ddddddddd",BM:"+1 (ddd) ddd-dddd",BT:"+975 ddddddddd",BO:"+591 ddddddddd",BA:"+387 ddddddddd",BW:"+267 ddddddddd",BV:"+0 ddddddddd",BR:"+55 ddddddddd",IO:"+0 ddddddddd",VG:"+1 (ddd) ddd-dddd",BN:"+673 ddddddddd",BG:"+359 ddddddddd",BF:"+226 ddddddddd",BI:"+257 ddddddddd",CI:"+225 ddddddddd",KH:"+855 ddddddddd",CM:"+237 ddddddddd",CA:"+1 (ddd) ddd-dddd",CV:"+238 ddddddddd",KY:"+1 (ddd) ddd-dddd",CF:"+236 ddddddddd",TD:"+235 ddddddddd",CL:"+56 ddddddddd",CN:"+86 ddddddddd",CX:"+61 ddddddddd",CC:"+61 ddddddddd",CO:"+57 ddddddddd",KM:"+269 ddddddddd",CG:"+242 ddddddddd",CK:"+682 ddddddddd",CR:"+506 ddddddddd",HR:"+385 ddddddddd",CU:"+53 ddddddddd",CY:"+357 ddddddddd",CZ:"+420 ddddddddd",CD:"+243 ddddddddd",DK:"+45 ddddddddd",DJ:"+253 ddddddddd",DM:"+1 (ddd) ddd-dddd",DO:"+1 (ddd) ddd-dddd",TL:"+670 ddddddddd",EC:"+593 ddddddddd",EG:"+20 ddddddddd",SV:"+503 ddddddddd",GQ:"+240 ddddddddd",ER:"+291 ddddddddd",EE:"+372 ddddddddd",ET:"+251 ddddddddd",FO:"+298 ddddddddd",FK:"+500 ddddddddd",FJ:"+679 ddddddddd",FI:"+358 ddddddddd",MK:"+389 ddddddddd",FR:"+33 d dd dd dd dd",GF:"+594 ddddddddd",PF:"+689 ddddddddd",TF:"+262 ddddddddd",GA:"+241 ddddddddd",GE:"+995 ddddddddd",DE:"+49 ddddddddd",GH:"+233 ddddddddd",GI:"+350 ddddddddd",GR:"+30 ddddddddd",GL:"+299 ddddddddd",GD:"+1 (ddd) ddd-dddd",GP:"+590 ddddddddd",GU:"+1 (ddd) ddd-dddd",GT:"+502 ddddddddd",GN:"+224 ddddddddd",GW:"+245 ddddddddd",GY:"+592 ddddddddd",HT:"+509 ddddddddd",HM:"+0 ddddddddd",HN:"+504 ddddddddd",HK:"+852 ddddddddd",HU:"+36 ddddddddd",IS:"+354 ddddddddd",IN:"+91 ddddddddd",ID:"+62 ddddddddd",IR:"+98 ddddddddd",IQ:"+964 ddddddddd",IE:"+353 ddddddddd",IL:"+972 ddddddddd",IT:"+39 ddddddddd",JM:"+1 (ddd) ddd-dddd",JP:"+81 ddddddddd",JO:"+962 ddddddddd",KZ:"+7 ddddddddd",KE:"+254 ddddddddd",KI:"+686 ddddddddd",KW:"+965 ddddddddd",KG:"+996 ddddddddd",LA:"+856 ddddddddd",LV:"+371 ddddddddd",LB:"+961 ddddddddd",LS:"+266 ddddddddd",LR:"+231 ddddddddd",LY:"+218 ddddddddd",LI:"+423 ddddddddd",LT:"+370 ddddddddd",LU:"+352 ddddddddd",MO:"+853 ddddddddd",MG:"+261 ddddddddd",MW:"+265 ddddddddd",MY:"+60 ddddddddd",MV:"+960 ddddddddd",ML:"+223 ddddddddd",MT:"+356 ddddddddd",MH:"+692 ddddddddd",MQ:"+596 ddddddddd",MR:"+222 ddddddddd",MU:"+230 ddddddddd",YT:"+262 ddddddddd",MX:"+52 ddddddddd",FM:"+691 ddddddddd",MD:"+373 ddddddddd",MC:"+377 ddddddddd",MN:"+976 ddddddddd",MS:"+1 (ddd) ddd-dddd",MA:"+212 ddddddddd",MZ:"+258 ddddddddd",MM:"+95 ddddddddd",NA:"+264 ddddddddd",NR:"+674 ddddddddd",NP:"+977 ddddddddd",NL:"+31 ddddddddd",AN:"+599 ddddddddd",NC:"+687 ddddddddd",NZ:"+64 ddddddddd",NI:"+505 ddddddddd",NE:"+227 ddddddddd",NG:"+234 ddddddddd",NU:"+683 ddddddddd",NF:"+672 ddddddddd",KP:"+850 ddddddddd",MP:"+1 (ddd) ddd-dddd",NO:"+47 ddddddddd",OM:"+968 ddddddddd",PK:"+92 ddddddddd",PW:"+680 ddddddddd",PA:"+507 ddddddddd",PG:"+675 ddddddddd",PY:"+595 ddddddddd",PE:"+51 ddddddddd",PH:"+63 ddddddddd",PN:"+870 ddddddddd",PL:"+48 ddddddddd",PT:"+351 ddddddddd",PR:"+1 (ddd) ddd-dddd",QA:"+974 ddddddddd",RE:"+262 ddddddddd",RO:"+40 ddddddddd",RU:"+7 ddddddddd",RW:"+250 ddddddddd",ST:"+239 ddddddddd",SH:"+290 ddddddddd",KN:"+1 (ddd) ddd-dddd",LC:"+1 (ddd) ddd-dddd",PM:"+508 ddddddddd",VC:"+1 (ddd) ddd-dddd",WS:"+685 ddddddddd",SM:"+378 ddddddddd",SA:"+966 ddddddddd",SN:"+221 ddddddddd",SC:"+248 ddddddddd",SL:"+232 ddddddddd",SG:"+65 ddddddddd",SK:"+421 ddddddddd",SI:"+386 ddddddddd",SB:"+677 ddddddddd",SO:"+252 ddddddddd",ZA:"+27 ddddddddd",GS:"+0 ddddddddd",KR:"+82 ddddddddd",ES:"+34 ddddddddd",LK:"+94 ddddddddd",SD:"+249 ddddddddd",SR:"+597 ddddddddd",SJ:"+0 ddddddddd",SZ:"+268 ddddddddd",SE:"+46 ddddddddd",CH:"+41 ddddddddd",SY:"+963 ddddddddd",TW:"+886 ddddddddd",TJ:"+992 ddddddddd",TZ:"+255 ddddddddd",TH:"+66 ddddddddd",BS:"+1 (ddd) ddd-dddd",GM:"+220 ddddddddd",TG:"+228 ddddddddd",TK:"+690 ddddddddd",TO:"+676 ddddddddd",TT:"+1 (ddd) ddd-dddd",TN:"+216 ddddddddd",TR:"+90 ddddddddd",TM:"+993 ddddddddd",TC:"+1 (ddd) ddd-dddd",TV:"+688 ddddddddd",VI:"+1 (ddd) ddd-dddd",UG:"+256 ddddddddd",UA:"+380 ddddddddd",AE:"+971 ddddddddd",GB:"+44 (ddd) dddd dddd",US:"+1 (ddd) ddd-dddd",UM:"+0 ddddddddd",UY:"+598 ddddddddd",UZ:"+998 ddddddddd",VU:"+678 ddddddddd",VA:"+39 ddddddddd",VE:"+58 ddddddddd",VN:"+84 ddddddddd",WF:"+681 ddddddddd",EH:"+0 ddddddddd",YE:"+967 ddddddddd",YU:"+0 ddddddddd",ZM:"+260 ddddddddd",ZW:"+263 ddddddddd"},BFHStatesList={AF:{1:{code:"BAL",name:"Balkh"},2:{code:"BAM",name:"Bamian"},3:{code:"BDG",name:"Badghis"},4:{code:"BDS",name:"Badakhshan"},5:{code:"BGL",name:"Baghlan"},6:{code:"FRA",name:"Farah"},7:{code:"FYB",name:"Faryab"},8:{code:"GHA",name:"Ghazni"},9:{code:"GHO",name:"Ghowr"},10:{code:"HEL",name:"Helmand"},11:{code:"HER",name:"Herat"},12:{code:"JOW",name:"Jowzjan"},13:{code:"KAB",name:"Kabul"},14:{code:"KAN",name:"Kandahar"},15:{code:"KAP",name:"Kapisa"},16:{code:"KDZ",name:"Kondoz"},17:{code:"KHO",name:"Khost"},18:{code:"KNR",name:"Konar"},19:{code:"LAG",name:"Laghman"},20:{code:"LOW",name:"Lowgar"},21:{code:"NAN",name:"Nangrahar"},22:{code:"NIM",name:"Nimruz"},23:{code:"NUR",name:"Nurestan"},24:{code:"ORU",name:"Oruzgan"},25:{code:"PAR",name:"Parwan"},26:{code:"PIA",name:"Paktia"},27:{code:"PKA",name:"Paktika"},28:{code:"SAM",name:"Samangan"},29:{code:"SAR",name:"Sar-e Pol"},30:{code:"TAK",name:"Takhar"},31:{code:"WAR",name:"Wardak"},32:{code:"ZAB",name:"Zabol"}},AL:{1:{code:"BR",name:"Berat"},2:{code:"BU",name:"Bulqize"},3:{code:"DI",name:"Diber"},4:{code:"DL",name:"Delvine"},5:{code:"DR",name:"Durres"},6:{code:"DV",name:"Devoll"},7:{code:"EL",name:"Elbasan"},8:{code:"ER",name:"Kolonje"},9:{code:"FR",name:"Fier"},10:{code:"GJ",name:"Gjirokaster"},11:{code:"GR",name:"Gramsh"},12:{code:"HA",name:"Has"},13:{code:"KA",name:"Kavaje"},14:{code:"KB",name:"Kurbin"},15:{code:"KC",name:"Kucove"},16:{code:"KO",name:"Korce"},17:{code:"KR",name:"Kruje"},18:{code:"KU",name:"Kukes"},19:{code:"LB",name:"Librazhd"},20:{code:"LE",name:"Lezhe"},21:{code:"LU",name:"Lushnje"},22:{code:"MK",name:"Mallakaster"},23:{code:"MM",name:"Malesi e Madhe"},24:{code:"MR",name:"Mirdite"},25:{code:"MT",name:"Mat"},26:{code:"PG",name:"Pogradec"},27:{code:"PQ",name:"Peqin"},28:{code:"PR",name:"Permet"},29:{code:"PU",name:"Puke"},30:{code:"SH",name:"Shkoder"},31:{code:"SK",name:"Skrapar"},32:{code:"SR",name:"Sarande"},33:{code:"TE",name:"Tepelene"},34:{code:"TP",name:"Tropoje"},35:{code:"TR",name:"Tirane"},36:{code:"VL",name:"Vlore"}},DZ:{1:{code:"ADE",name:"Ain Defla"},2:{code:"ADR",name:"Adrar"},3:{code:"ALG",name:"Alger"},4:{code:"ANN",name:"Annaba"},5:{code:"ATE",name:"Ain Temouchent"},6:{code:"BAT",name:"Batna"},7:{code:"BBA",name:"Bordj Bou Arreridj"},8:{code:"BEC",name:"Bechar"},9:{code:"BEJ",name:"Bejaia"},10:{code:"BIS",name:"Biskra"},11:{code:"BLI",name:"Blida"},12:{code:"BMD",name:"Boumerdes"},13:{code:"BOA",name:"Bouira"},14:{code:"CHL",name:"Chlef"},15:{code:"CON",name:"Constantine"},16:{code:"DJE",name:"Djelfa"},17:{code:"EBA",name:"El Bayadh"},18:{code:"EOU",name:"El Oued"},19:{code:"ETA",name:"El Tarf"},20:{code:"GHA",name:"Ghardaia"},21:{code:"GUE",name:"Guelma"},22:{code:"ILL",name:"Illizi"},23:{code:"JIJ",name:"Jijel"},24:{code:"KHE",name:"Khenchela"},25:{code:"LAG",name:"Laghouat"},26:{code:"MED",name:"Medea"},27:{code:"MIL",name:"Mila"},28:{code:"MOS",name:"Mostaganem"},29:{code:"MSI",name:"M'Sila"},30:{code:"MUA",name:"Muaskar"},31:{code:"NAA",name:"Naama"},32:{code:"OEB",name:"Oum el-Bouaghi"},33:{code:"ORA",name:"Oran"},34:{code:"OUA",name:"Ouargla"},35:{code:"REL",name:"Relizane"},36:{code:"SAH",name:"Souk Ahras"},37:{code:"SAI",name:"Saida"},38:{code:"SBA",name:"Sidi Bel Abbes"},39:{code:"SET",name:"Setif"},40:{code:"SKI",name:"Skikda"},41:{code:"TAM",name:"Tamanghasset"},42:{code:"TEB",name:"Tebessa"},43:{code:"TIA",name:"Tiaret"},44:{code:"TIN",name:"Tindouf"},45:{code:"TIP",name:"Tipaza"},46:{code:"TIS",name:"Tissemsilt"},47:{code:"TLE",name:"Tlemcen"},48:{code:"TOU",name:"Tizi Ouzou"}},AS:{1:{code:"E",name:"Eastern"},2:{code:"M",name:"Manu'a"},3:{code:"R",name:"Rose Island"},4:{code:"S",name:"Swains Island"},5:{code:"W",name:"Western"}},AD:{1:{code:"ALV",name:"Andorra la Vella"},2:{code:"CAN",name:"Canillo"},3:{code:"ENC",name:"Encamp"},4:{code:"ESE",name:"Escaldes-Engordany"},5:{code:"LMA",name:"La Massana"},6:{code:"ORD",name:"Ordino"},7:{code:"SJL",name:"Sant Julià de Lòria"}},AO:{1:{code:"BGO",name:"Bengo"},2:{code:"BGU",name:"Benguela"},3:{code:"BIE",name:"Bie"},4:{code:"CAB",name:"Cabinda"},5:{code:"CCU",name:"Cuando-Cubango"},6:{code:"CNO",name:"Cuanza Norte"},7:{code:"CUS",name:"Cuanza Sul"},8:{code:"CNN",name:"Cunene"},9:{code:"HUA",name:"Huambo"},10:{code:"HUI",name:"Huila"},11:{code:"LUA",name:"Luanda"},12:{code:"LNO",name:"Lunda Norte"},13:{code:"LSU",name:"Lunda Sul"},14:{code:"MAL",name:"Malange"},15:{code:"MOX",name:"Moxico"},16:{code:"NAM",name:"Namibe"},17:{code:"UIG",name:"Uige"},18:{code:"ZAI",name:"Zaire"}},AI:{1:{code:"ANG",name:"Anguillita"},2:{code:"ANG",name:"Anguila"},3:{code:"DOG",name:"Dog"},4:{code:"LIT",name:"Little Scrub"},5:{code:"PRI",name:"Prickly Pear"},6:{code:"SAN",name:"Sandy"},7:{code:"SCR",name:"Scrub"},8:{code:"SEA",name:"Seal"},9:{code:"SOM",name:"Sombrero"}},AQ:{1:{code:"ASG",name:"Saint George"},2:{code:"ASH",name:"Saint Philip"},3:{code:"ASJ",name:"Saint John"},4:{code:"ASL",name:"Saint Paul"},5:{code:"ASM",name:"Saint Mary"},6:{code:"ASR",name:"Saint Peter"},7:{code:"BAR",name:"Barbuda"},8:{code:"RED",name:"Redonda"}},AR:{1:{code:"AN",name:"Antartida e Islas del Atlantico"},2:{code:"BA",name:"Buenos Aires"},3:{code:"CA",name:"Catamarca"},4:{code:"CH",name:"Chaco"},5:{code:"CU",name:"Chubut"},6:{code:"CO",name:"Cordoba"},7:{code:"CR",name:"Corrientes"},8:{code:"CF",name:"Capital Federal"},9:{code:"ER",name:"Entre Rios"},10:{code:"FO",name:"Formosa"},11:{code:"JU",name:"Jujuy"},12:{code:"LP",name:"La Pampa"},13:{code:"LR",name:"La Rioja"},14:{code:"ME",name:"Mendoza"},15:{code:"MI",name:"Misiones"},16:{code:"NE",name:"Neuquen"},17:{code:"RN",name:"Rio Negro"},18:{code:"SA",name:"Salta"},19:{code:"SJ",name:"San Juan"},20:{code:"SL",name:"San Luis"},21:{code:"SC",name:"Santa Cruz"},22:{code:"SF",name:"Santa Fe"},23:{code:"SD",name:"Santiago del Estero"},24:{code:"TF",name:"Tierra del Fuego"},25:{code:"TU",name:"Tucuman"}},AM:{1:{code:"AGT",name:"Aragatsotn"},2:{code:"ARR",name:"Ararat"},3:{code:"ARM",name:"Armavir"},4:{code:"GEG",name:"Geghark 'unik'"},5:{code:"KOT",name:"Kotayk'"},6:{code:"LOR",name:"Lorri"},7:{code:"SHI",name:"Shirak"},8:{code:"SYU",name:"Syunik'"},9:{code:"TAV",name:"Tavush"},10:{code:"VAY",name:"Vayots' Dzor"},11:{code:"YER",name:"Yerevan"}},AW:{1:{code:"ARU",name:"Aruba"},2:{code:"DRU",name:"Druif Beach"},3:{code:"MAN",name:"Manchebo Beach"},4:{code:"NOO",name:"Noord"},5:{code:"ORA",name:"Oranjestad"},6:{code:"PAL",name:"Palm Beach"},7:{code:"ROO",name:"Rooi Thomas"},8:{code:"SIN",name:"Sint Nicolaas"},9:{code:"SIN",name:"Sint Nicolas"},10:{code:"WAY",name:"Wayaca"}},AU:{1:{code:"ACT",name:"Australian Capital Territory"},2:{code:"NSW",name:"New South Wales"},3:{code:"NT",name:"Northern Territory"},4:{code:"QLD",name:"Queensland"},5:{code:"SA",name:"South Australia"},6:{code:"TAS",name:"Tasmania"},7:{code:"VIC",name:"Victoria"},8:{code:"WA",name:"Western Australia"}},AT:{1:{code:"BUR",name:"Burgenland"},2:{code:"KAR",name:"Krnten"},3:{code:"NOS",name:"Niederöesterreich"},4:{code:"OOS",name:"Oberöesterreich"},5:{code:"SAL",name:"Salzburg"},6:{code:"STE",name:"Steiermark"},7:{code:"TIR",name:"Tirol"},8:{code:"VOR",name:"Vorarlberg"},9:{code:"WIE",name:"Wien"}},AZ:{1:{code:"AB",name:"Ali Bayramli"},2:{code:"ABS",name:"Abseron"},3:{code:"AGC",name:"AgcabAdi"},4:{code:"AGM",name:"Agdam"},5:{code:"AGS",name:"Agdas"},6:{code:"AGA",name:"Agstafa"},7:{code:"AGU",name:"Agsu"},8:{code:"AST",name:"Astara"},9:{code:"BA",name:"Baki"},10:{code:"BAB",name:"BabAk"},11:{code:"BAL",name:"BalakAn"},12:{code:"BAR",name:"BArdA"},13:{code:"BEY",name:"Beylaqan"},14:{code:"BIL",name:"Bilasuvar"},15:{code:"CAB",name:"Cabrayil"},16:{code:"CAL",name:"Calilabab"},17:{code:"CUL",name:"Culfa"},18:{code:"DAS",name:"Daskasan"},19:{code:"DAV",name:"Davaci"},20:{code:"FUZ",name:"Fuzuli"},21:{code:"GA",name:"Ganca"},22:{code:"GAD",name:"Gadabay"},23:{code:"GOR",name:"Goranboy"},24:{code:"GOY",name:"Goycay"},25:{code:"HAC",name:"Haciqabul"},26:{code:"IMI",name:"Imisli"},27:{code:"ISM",name:"Ismayilli"},28:{code:"KAL",name:"Kalbacar"},29:{code:"KUR",name:"Kurdamir"},30:{code:"LA",name:"Lankaran"},31:{code:"LAC",name:"Lacin"},32:{code:"LAN",name:"Lankaran"},33:{code:"LER",name:"Lerik"},34:{code:"MAS",name:"Masalli"},35:{code:"MI",name:"Mingacevir"},36:{code:"NA",name:"Naftalan"},37:{code:"NX",name:"Naxcivan"},38:{code:"NEF",name:"Neftcala"},39:{code:"OGU",name:"Oguz"},40:{code:"ORD",name:"Ordubad"},41:{code:"QAB",name:"Qabala"},42:{code:"QAX",name:"Qax"},43:{code:"QAZ",name:"Qazax"},44:{code:"QOB",name:"Qobustan"},45:{code:"QBA",name:"Quba"},46:{code:"QBI",name:"Qubadli"},47:{code:"QUS",name:"Qusar"},48:{code:"SA",name:"Saki"},49:{code:"SAT",name:"Saatli"},50:{code:"SAB",name:"Sabirabad"},51:{code:"SAD",name:"Sadarak"},52:{code:"SAH",name:"Sahbuz"},53:{code:"SAK",name:"Saki"},54:{code:"SAL",name:"Salyan"},55:{code:"SM",name:"Sumqayit"},56:{code:"SMI",name:"Samaxi"},57:{code:"SKR",name:"Samkir"},58:{code:"SMX",name:"Samux"},59:{code:"SAR",name:"Sarur"},60:{code:"SIY",name:"Siyazan"},61:{code:"SS",name:"Susa"},62:{code:"SUS",name:"Susa"},63:{code:"TAR",name:"Tartar"},64:{code:"TOV",name:"Tovuz"},65:{code:"UCA",name:"Ucar"},66:{code:"XA",name:"Xankandi"},67:{code:"XAC",name:"Xacmaz"},68:{code:"XAN",name:"Xanlar"},69:{code:"XIZ",name:"Xizi"},70:{code:"XCI",name:"Xocali"},71:{code:"XVD",name:"Xocavand"},72:{code:"YAR",name:"Yardimli"},73:{code:"YEV",name:"Yevlax"},74:{code:"ZAN",name:"Zangilan"},75:{code:"ZAQ",name:"Zaqatala"},76:{code:"ZAR",name:"Zardab"}},BS:{1:{code:"ACK",name:"Acklins"},2:{code:"BER",name:"Berry Islands"},3:{code:"BIM",name:"Bimini"},4:{code:"BLK",name:"Black Point"},5:{code:"CAT",name:"Cat Island"},6:{code:"CAB",name:"Central Abaco"},7:{code:"CAN",name:"Central Andros"},8:{code:"CEL",name:"Central Eleuthera"},9:{code:"FRE",name:"City of Freeport"},10:{code:"CRO",name:"Crooked Island"},11:{code:"EGB",name:"East Grand Bahama"},12:{code:"EXU",name:"Exuma"},13:{code:"GRD",name:"Grand Cay"},14:{code:"HAR",name:"Harbour Island"},15:{code:"HOP",name:"Hope Town"},16:{code:"INA",name:"Inagua"},17:{code:"LNG",name:"Long Island"},18:{code:"MAN",name:"Mangrove Cay"},19:{code:"MAY",name:"Mayaguana"},20:{code:"MOO",name:"Moore's Island"},21:{code:"NAB",name:"North Abaco"},22:{code:"NAN",name:"North Andros"},23:{code:"NEL",name:"North Eleuthera"},24:{code:"RAG",name:"Ragged Island"},25:{code:"RUM",name:"Rum Cay"},26:{code:"SAL",name:"San Salvador"},27:{code:"SAB",name:"South Abaco"},28:{code:"SAN",name:"South Andros"},29:{code:"SEL",name:"South Eleuthera"},30:{code:"SWE",name:"Spanish Wells"},31:{code:"WGB",name:"West Grand Bahama"}},BH:{1:{code:"CAP",name:"Capital"},2:{code:"CEN",name:"Central"},3:{code:"MUH",name:"Muharraq"},4:{code:"NOR",name:"Northern"},5:{code:"SOU",name:"Southern"}},BD:{1:{code:"BAR",name:"Barisal"},2:{code:"CHI",name:"Chittagong"},3:{code:"DHA",name:"Dhaka"},4:{code:"KHU",name:"Khulna"},5:{code:"RAJ",name:"Rajshahi"},6:{code:"SYL",name:"Sylhet"}},BB:{1:{code:"CC",name:"Christ Church"},2:{code:"AND",name:"Saint Andrew"},3:{code:"GEO",name:"Saint George"},4:{code:"JAM",name:"Saint James"},5:{code:"JOH",name:"Saint John"},6:{code:"JOS",name:"Saint Joseph"},7:{code:"LUC",name:"Saint Lucy"},8:{code:"MIC",name:"Saint Michael"},9:{code:"PET",name:"Saint Peter"},10:{code:"PHI",name:"Saint Philip"},11:{code:"THO",name:"Saint Thomas"}},BY:{1:{code:"BR",name:"Brestskaya (Brest)"},2:{code:"HO",name:"Homyel'skaya (Homyel')"},3:{code:"HM",name:"Horad Minsk"},4:{code:"HR",name:"Hrodzyenskaya (Hrodna)"},5:{code:"MA",name:"Mahilyowskaya (Mahilyow)"},6:{code:"MI",name:"Minskaya"},7:{code:"VI",name:"Vitsyebskaya (Vitsyebsk)"}},BE:{1:{code:"VAN",name:"Antwerpen"},2:{code:"WBR",name:"Brabant Wallon"},3:{code:"WHT",name:"Hainaut"},4:{code:"WLG",name:"Liege"},5:{code:"VLI",name:"Limburg"},6:{code:"WLX",name:"Luxembourg"},7:{code:"WNA",name:"Namur"},8:{code:"VOV",name:"Oost-Vlaanderen"},9:{code:"VBR",name:"Vlaams Brabant"},10:{code:"VWV",name:"West-Vlaanderen"}},BZ:{1:{code:"BZ",name:"Belize"},2:{code:"CY",name:"Cayo"},3:{code:"CR",name:"Corozal"},4:{code:"OW",name:"Orange Walk"},5:{code:"SC",name:"Stann Creek"},6:{code:"TO",name:"Toledo"}},BJ:{1:{code:"AL",name:"Alibori"},2:{code:"AK",name:"Atakora"},3:{code:"AQ",name:"Atlantique"},4:{code:"BO",name:"Borgou"},5:{code:"CO",name:"Collines"},6:{code:"DO",name:"Donga"},7:{code:"KO",name:"Kouffo"},8:{code:"LI",name:"Littoral"},9:{code:"MO",name:"Mono"},10:{code:"OU",name:"Oueme"},11:{code:"PL",name:"Plateau"},12:{code:"ZO",name:"Zou"}},BM:{1:{code:"DS",name:"Devonshire"},2:{code:"HC",name:"Hamilton City"},3:{code:"HA",name:"Hamilton"},4:{code:"PG",name:"Paget"},5:{code:"PB",name:"Pembroke"},6:{code:"GC",name:"Saint George City"},7:{code:"SG",name:"Saint George's"},8:{code:"SA",name:"Sandys"},9:{code:"SM",name:"Smith's"},10:{code:"SH",name:"Southampton"},11:{code:"WA",name:"Warwick"}},BT:{1:{code:"BUM",name:"Bumthang"},2:{code:"CHU",name:"Chukha"},3:{code:"DAG",name:"Dagana"},4:{code:"GAS",name:"Gasa"},5:{code:"HAA",name:"Haa"},6:{code:"LHU",name:"Lhuntse"},7:{code:"MON",name:"Mongar"},8:{code:"PAR",name:"Paro"},9:{code:"PEM",name:"Pemagatshel"},10:{code:"PUN",name:"Punakha"},11:{code:"SJO",name:"Samdrup Jongkhar"},12:{code:"SAT",name:"Samtse"},13:{code:"SAR",name:"Sarpang"},14:{code:"THI",name:"Thimphu"},15:{code:"TRG",name:"Trashigang"},16:{code:"TRY",name:"Trashiyangste"},17:{code:"TRO",name:"Trongsa"},18:{code:"TSI",name:"Tsirang"},19:{code:"WPH",name:"Wangdue Phodrang"},20:{code:"ZHE",name:"Zhemgang"}},BO:{1:{code:"BEN",name:"Beni"},2:{code:"CHU",name:"Chuquisaca"},3:{code:"COC",name:"Cochabamba"},4:{code:"LPZ",name:"La Paz"},5:{code:"ORU",name:"Oruro"},6:{code:"PAN",name:"Pando"},7:{code:"POT",name:"Potosi"},8:{code:"SCZ",name:"Santa Cruz"},9:{code:"TAR",name:"Tarija"}},BA:{1:{code:"BRO",name:"Brcko district"},2:{code:"FBP",name:"Bosanskopodrinjski Kanton"},3:{code:"FHN",name:"Hercegovacko-neretvanski Kanton"},4:{code:"FPO",name:"Posavski Kanton"},5:{code:"FSA",name:"Kanton Sarajevo"},6:{code:"FSB",name:"Srednjebosanski Kanton"},7:{code:"FTU",name:"Tuzlanski Kanton"},8:{code:"FUS",name:"Unsko-Sanski Kanton"},9:{code:"FZA",name:"Zapadnobosanska"},10:{code:"FZE",name:"Zenicko-Dobojski Kanton"},11:{code:"FZH",name:"Zapadnohercegovacka Zupanija"},12:{code:"SBI",name:"Bijeljina"},13:{code:"SBL",name:"Banja Luka"},14:{code:"SDO",name:"Doboj"},15:{code:"SFO",name:"Foca"},16:{code:"SSR",name:"Sarajevo-Romanija or Sokolac"},17:{code:"STR",name:"Trebinje"},18:{code:"SVL",name:"Vlasenica"}},BW:{1:{code:"CE",name:"Central"},2:{code:"GH",name:"Ghanzi"},3:{code:"KD",name:"Kgalagadi"},4:{code:"KT",name:"Kgatleng"},5:{code:"KW",name:"Kweneng"},6:{code:"NG",name:"Ngamiland"},7:{code:"NE",name:"North East"},8:{code:"NW",name:"North West"},9:{code:"SE",name:"South East"},10:{code:"SO",name:"Southern"}},BR:{1:{code:"AC",name:"Acre"},2:{code:"AL",name:"Alagoas"},3:{code:"AP",name:"Amapa"},4:{code:"AM",name:"Amazonas"},5:{code:"BA",name:"Bahia"},6:{code:"CE",name:"Ceara"},7:{code:"DF",name:"Distrito Federal"},8:{code:"ES",name:"Espirito Santo"},9:{code:"GO",name:"Goias"},10:{code:"MA",name:"Maranhao"},11:{code:"MT",name:"Mato Grosso"},12:{code:"MS",name:"Mato Grosso do Sul"},13:{code:"MG",name:"Minas Gerais"},14:{code:"PA",name:"Para"},15:{code:"PB",name:"Paraiba"},16:{code:"PR",name:"Parana"},17:{code:"PE",name:"Pernambuco"},18:{code:"PI",name:"Piaui"},19:{code:"RJ",name:"Rio de Janeiro"},20:{code:"RN",name:"Rio Grande do Norte"},21:{code:"RS",name:"Rio Grande do Sul"},22:{code:"RO",name:"Rondonia"},23:{code:"RR",name:"Roraima"},24:{code:"SC",name:"Santa Catarina"},25:{code:"SP",name:"Sao Paulo"},26:{code:"SE",name:"Sergipe"},27:{code:"TO",name:"Tocantins"}},IO:{1:{code:"DG",name:"Diego Garcia"},2:{code:"DI",name:"Danger Island"},3:{code:"EA",name:"Eagle Islands"},4:{code:"EG",name:"Egmont Islands"},5:{code:"NI",name:"Nelsons Island"},6:{code:"PB",name:"Peros Banhos"},7:{code:"SI",name:"Salomon Islands"},8:{code:"TB",name:"Three Brothers"}},BN:{1:{code:"BEL",name:"Belait"},2:{code:"BRM",name:"Brunei and Muara"},3:{code:"TEM",name:"Temburong"},4:{code:"TUT",name:"Tutong"}},BG:{1:{code:"BG-01",name:"Blagoevgrad"},2:{code:"BG-02",name:"Burgas"},3:{code:"BG-03",name:"Dobrich"},4:{code:"BG-04",name:"Gabrovo"},5:{code:"BG-05",name:"Haskovo"},6:{code:"BG-06",name:"Kardjali"},7:{code:"BG-07",name:"Kyustendil"},8:{code:"BG-08",name:"Lovech"},9:{code:"BG-09",name:"Montana"},10:{code:"BG-10",name:"Pazardjik"},11:{code:"BG-11",name:"Pernik"},12:{code:"BG-12",name:"Pleven"},13:{code:"BG-13",name:"Plovdiv"},14:{code:"BG-14",name:"Razgrad"},15:{code:"BG-15",name:"Shumen"},16:{code:"BG-16",name:"Silistra"},17:{code:"BG-17",name:"Sliven"},18:{code:"BG-18",name:"Smolyan"},19:{code:"BG-19",name:"Sofia"},20:{code:"BG-20",name:"Sofia - town"},21:{code:"BG-21",name:"Stara Zagora"},22:{code:"BG-22",name:"Targovishte"},23:{code:"BG-23",name:"Varna"},24:{code:"BG-24",name:"Veliko Tarnovo"},25:{code:"BG-25",name:"Vidin"},26:{code:"BG-26",name:"Vratza"},27:{code:"BG-27",name:"Yambol"}},BF:{1:{code:"BAL",name:"Bale"},2:{code:"BAM",name:"Bam"},3:{code:"BAN",name:"Banwa"},4:{code:"BAZ",name:"Bazega"},5:{code:"BOR",name:"Bougouriba"},6:{code:"BLG",name:"Boulgou"},7:{code:"BOK",name:"Boulkiemde"},8:{code:"COM",name:"Comoe"},9:{code:"GAN",name:"Ganzourgou"},10:{code:"GNA",name:"Gnagna"},11:{code:"GOU",name:"Gourma"},12:{code:"HOU",name:"Houet"},13:{code:"IOA",name:"Ioba"},14:{code:"KAD",name:"Kadiogo"},15:{code:"KEN",name:"Kenedougou"},16:{code:"KOD",name:"Komondjari"},17:{code:"KOP",name:"Kompienga"},18:{code:"KOS",name:"Kossi"},19:{code:"KOL",name:"Koulpelogo"},20:{code:"KOT",name:"Kouritenga"},21:{code:"KOW",name:"Kourweogo"},22:{code:"LER",name:"Leraba"},23:{code:"LOR",name:"Loroum"},24:{code:"MOU",name:"Mouhoun"},25:{code:"NAH",name:"Nahouri"},26:{code:"NAM",name:"Namentenga"},27:{code:"NAY",name:"Nayala"},28:{code:"NOU",name:"Noumbiel"},29:{code:"OUB",name:"Oubritenga"},30:{code:"OUD",name:"Oudalan"},31:{code:"PAS",name:"Passore"},32:{code:"PON",name:"Poni"},33:{code:"SAG",name:"Sanguie"},34:{code:"SAM",name:"Sanmatenga"},35:{code:"SEN",name:"Seno"},36:{code:"SIS",name:"Sissili"},37:{code:"SOM",name:"Soum"},38:{code:"SOR",name:"Sourou"},39:{code:"TAP",name:"Tapoa"},40:{code:"TUY",name:"Tuy"},41:{code:"YAG",name:"Yagha"},42:{code:"YAT",name:"Yatenga"},43:{code:"ZIR",name:"Ziro"},44:{code:"ZOD",name:"Zondoma"},45:{code:"ZOW",name:"Zoundweogo"}},BI:{1:{code:"BB",name:"Bubanza"},2:{code:"BJ",name:"Bujumbura"},3:{code:"BR",name:"Bururi"},4:{code:"CA",name:"Cankuzo"},5:{code:"CI",name:"Cibitoke"},6:{code:"GI",name:"Gitega"},7:{code:"KR",name:"Karuzi"},8:{code:"KY",name:"Kayanza"},9:{code:"KI",name:"Kirundo"},10:{code:"MA",name:"Makamba"},11:{code:"MU",name:"Muramvya"},12:{code:"MY",name:"Muyinga"},13:{code:"MW",name:"Mwaro"},14:{code:"NG",name:"Ngozi"},15:{code:"RT",name:"Rutana"},16:{code:"RY",name:"Ruyigi"}},KH:{1:{code:"BA",name:"Battambang"},2:{code:"BM",name:"Banteay Meanchey"},3:{code:"KB",name:"Keb"},4:{code:"KK",name:"Kaoh Kong"},5:{code:"KL",name:"Kandal"},6:{code:"KM",name:"Kampong Cham"},7:{code:"KN",name:"Kampong Chhnang"},8:{code:"KO",name:"Kampong Som"},9:{code:"KP",name:"Kampot"},10:{code:"KR",name:"Kratie"},11:{code:"KT",name:"Kampong Thom"},12:{code:"KU",name:"Kampong Speu"},13:{code:"MK",name:"Mondul Kiri"},14:{code:"OM",name:"Oddar Meancheay"},15:{code:"PA",name:"Pailin"},16:{code:"PG",name:"Prey Veng"},17:{code:"PP",name:"Phnom Penh"},18:{code:"PR",name:"Preah Vihear"},19:{code:"PS",name:"Preah Seihanu (Kompong Som or Si)"},20:{code:"PU",name:"Pursat"},21:{code:"RK",name:"Ratanak Kiri"},22:{code:"SI",name:"Siemreap"},23:{code:"SR",name:"Svay Rieng"},24:{code:"ST",name:"Stung Treng"},25:{code:"TK",name:"Takeo"}},CM:{1:{code:"ADA",name:"Adamawa (Adamaoua)"},2:{code:"CEN",name:"Centre"},3:{code:"EST",name:"East (Est)"},4:{code:"EXN",name:"Extrême-Nord"},5:{code:"LIT",name:"Littoral"},6:{code:"NOR",name:"North (Nord)"},7:{code:"NOT",name:"Northwest (Nord-Ouest)"},8:{code:"OUE",name:"West (Ouest)"},9:{code:"SUD",name:"South (Sud)"},10:{code:"SOU",name:"Southwest (Sud-Ouest)"}},CA:{1:{code:"AB",name:"Alberta"},2:{code:"BC",name:"British Columbia"},3:{code:"MB",name:"Manitoba"},4:{code:"NB",name:"New Brunswick"},5:{code:"NL",name:"Newfoundland and Labrador"},6:{code:"NT",name:"Northwest Territories"},7:{code:"NS",name:"Nova Scotia"},8:{code:"NU",name:"Nunavut"},9:{code:"ON",name:"Ontario"},10:{code:"PE",name:"Prince Edward Island"},11:{code:"QC",name:"Québec"},12:{code:"SK",name:"Saskatchewan"},13:{code:"YT",name:"Yukon Territory"}},CV:{1:{code:"BV",name:"Boa Vista"},2:{code:"BR",name:"Brava"},3:{code:"CS",name:"Calheta de Sao Miguel"},4:{code:"MA",name:"Maio"},5:{code:"MO",name:"Mosteiros"},6:{code:"PA",name:"Paul"},7:{code:"PN",name:"Porto Novo"},8:{code:"PR",name:"Praia"},9:{code:"RG",name:"Ribeira Grande"},10:{code:"SL",name:"Sal"},11:{code:"CA",name:"Santa Catarina"},12:{code:"CR",name:"Santa Cruz"},13:{code:"SD",name:"Sao Domingos"},14:{code:"SF",name:"Sao Filipe"},15:{code:"SN",name:"Sao Nicolau"},16:{code:"SV",name:"Sao Vicente"},17:{code:"TA",name:"Tarrafal"}},KY:{1:{code:"CR",name:"Creek"},2:{code:"EA",name:"Eastern"},3:{code:"ML",name:"Midland"},4:{code:"ST",name:"South Town"},5:{code:"SP",name:"Spot Bay"},6:{code:"SK",name:"Stake Bay"},7:{code:"WD",name:"West End"},8:{code:"WN",name:"Western"}},CF:{1:{code:"BAN",name:"Bangui"},2:{code:"BBA",name:"Bamingui-Bangoran"},3:{code:"BKO",name:"Basse-Kotto"},4:{code:"HKO",name:"Haute-Kotto"},5:{code:"HMB",name:"Haut-Mbomou"},6:{code:"KEM",name:"Kemo"},7:{code:"LOB",name:"Lobaye"},8:{code:"MBO",name:"Mbomou"},9:{code:"MKD",name:"Mambéré-Kadéï"},10:{code:"NGR",name:"Nana-Grebizi"},11:{code:"NMM",name:"Nana-Mambere"},12:{code:"OMP",name:"Ombella-M'Poko"},13:{code:"OPE",name:"Ouham-Pende"},14:{code:"OUH",name:"Ouham"},15:{code:"OUK",name:"Ouaka"},16:{code:"SMB",name:"Sangha-Mbaere"},17:{code:"VAK",name:"Vakaga"}},TD:{1:{code:"BA",name:"Batha"},2:{code:"BI",name:"Biltine"},3:{code:"BE",name:"Borkou-Ennedi-Tibesti"},4:{code:"CB",name:"Chari-Baguirmi"},5:{code:"GU",name:"Guera"},6:{code:"KA",name:"Kanem"},7:{code:"LA",name:"Lac"},8:{code:"LC",name:"Logone Occidental"},9:{code:"LR",name:"Logone Oriental"},10:{code:"MK",name:"Mayo-Kebbi"},11:{code:"MC",name:"Moyen-Chari"},12:{code:"OU",name:"Ouaddai"},13:{code:"SA",name:"Salamat"},14:{code:"TA",name:"Tandjile"}},CL:{1:{code:"AI",name:"Aisen del General Carlos Ibanez"},2:{code:"AN",name:"Antofagasta"},3:{code:"AR",name:"Araucania"},4:{code:"AT",name:"Atacama"},5:{code:"BI",name:"Bio-Bio"},6:{code:"CO",name:"Coquimbo"},7:{code:"LI",name:"Libertador General Bernardo O'Hi"},8:{code:"LL",name:"Los Lagos"},9:{code:"MA",name:"Magallanes y de la Antartica Chi"},10:{code:"ML",name:"Maule"},11:{code:"RM",name:"Region Metropolitana"},12:{code:"TA",name:"Tarapaca"},13:{code:"VS",name:"Valparaiso"}},CN:{1:{code:"AN",name:"Anhui"},2:{code:"BE",name:"Beijing"},3:{code:"CH",name:"Chongqing"},4:{code:"FU",name:"Fujian"},5:{code:"GA",name:"Gansu"},6:{code:"GU",name:"Guangdong"},7:{code:"GX",name:"Guangxi"},8:{code:"GZ",name:"Guizhou"},9:{code:"HA",name:"Hainan"},10:{code:"HB",name:"Hebei"},11:{code:"HL",name:"Heilongjiang"},12:{code:"HE",name:"Henan"},13:{code:"HK",name:"Hong Kong"},14:{code:"HU",name:"Hubei"},15:{code:"HN",name:"Hunan"},16:{code:"IM",name:"Inner Mongolia"},17:{code:"JI",name:"Jiangsu"},18:{code:"JX",name:"Jiangxi"},19:{code:"JL",name:"Jilin"},20:{code:"LI",name:"Liaoning"},21:{code:"MA",name:"Macau"},22:{code:"NI",name:"Ningxia"},23:{code:"SH",name:"Shaanxi"},24:{code:"SA",name:"Shandong"},25:{code:"SG",name:"Shanghai"},26:{code:"SX",name:"Shanxi"},27:{code:"SI",name:"Sichuan"},28:{code:"TI",name:"Tianjin"},29:{code:"XI",name:"Xinjiang"},30:{code:"YU",name:"Yunnan"},31:{code:"ZH",name:"Zhejiang"}},CC:{1:{code:"D",name:"Direction Island"},2:{code:"H",name:"Home Island"},3:{code:"O",name:"Horsburgh Island"},4:{code:"S",name:"South Island"},5:{code:"W",name:"West Island"}},CO:{1:{code:"AMZ",name:"Amazonas"},2:{code:"ANT",name:"Antioquia"},3:{code:"ARA",name:"Arauca"},4:{code:"ATL",name:"Atlantico"},5:{code:"BDC",name:"Bogota D.C."},6:{code:"BOL",name:"Bolivar"},7:{code:"BOY",name:"Boyaca"},8:{code:"CAL",name:"Caldas"},9:{code:"CAQ",name:"Caqueta"},10:{code:"CAS",name:"Casanare"},11:{code:"CAU",name:"Cauca"},12:{code:"CES",name:"Cesar"},13:{code:"CHO",name:"Choco"},14:{code:"COR",name:"Cordoba"},15:{code:"CAM",name:"Cundinamarca"},16:{code:"GNA",name:"Guainia"},17:{code:"GJR",name:"Guajira"},18:{code:"GVR",name:"Guaviare"},19:{code:"HUI",name:"Huila"},20:{code:"MAG",name:"Magdalena"},21:{code:"MET",name:"Meta"},22:{code:"NAR",name:"Narino"},23:{code:"NDS",name:"Norte de Santander"},24:{code:"PUT",name:"Putumayo"},25:{code:"QUI",name:"Quindio"},26:{code:"RIS",name:"Risaralda"},27:{code:"SAP",name:"San Andres y Providencia"},28:{code:"SAN",name:"Santander"},29:{code:"SUC",name:"Sucre"},30:{code:"TOL",name:"Tolima"},31:{code:"VDC",name:"Valle del Cauca"},32:{code:"VAU",name:"Vaupes"},33:{code:"VIC",name:"Vichada"}},KM:{1:{code:"G",name:"Grande Comore"},2:{code:"A",name:"Anjouan"},3:{code:"M",name:"Moheli"}},CG:{1:{code:"BO",name:"Bouenza"},2:{code:"BR",name:"Brazzaville"},3:{code:"CU",name:"Cuvette"},4:{code:"CO",name:"Cuvette-Ouest"},5:{code:"KO",name:"Kouilou"},6:{code:"LE",name:"Lekoumou"},7:{code:"LI",name:"Likouala"},8:{code:"NI",name:"Niari"},9:{code:"PL",name:"Plateaux"},10:{code:"PO",name:"Pool"},11:{code:"SA",name:"Sangha"}},CK:{1:{code:"AI",name:"Aitutaki"},2:{code:"AT",name:"Atiu"},3:{code:"MA",name:"Manuae"},4:{code:"MG",name:"Mangaia"},5:{code:"MK",name:"Manihiki"},6:{code:"MT",name:"Mitiaro"},7:{code:"MU",name:"Mauke"},8:{code:"NI",name:"Nassau Island"},9:{code:"PA",name:"Palmerston"},10:{code:"PE",name:"Penrhyn"},11:{code:"PU",name:"Pukapuka"},12:{code:"RK",name:"Rakahanga"},13:{code:"RR",name:"Rarotonga"},14:{code:"SU",name:"Surwarrow"},15:{code:"TA",name:"Takutea"}},CR:{1:{code:"AL",name:"Alajuela"},2:{code:"CA",name:"Cartago"},3:{code:"GU",name:"Guanacaste"},4:{code:"HE",name:"Heredia"},5:{code:"LI",name:"Limon"},6:{code:"PU",name:"Puntarenas"},7:{code:"SJ",name:"San Jose"}},CI:{1:{code:"ABE",name:"Abengourou"},2:{code:"ABI",name:"Abidjan"},3:{code:"ABO",name:"Aboisso"},4:{code:"ADI",name:"Adiake"},5:{code:"ADZ",name:"Adzope"},6:{code:"AGB",name:"Agboville"},7:{code:"AGN",name:"Agnibilekrou"},8:{code:"ALE",name:"Alepe"},9:{code:"BOC",name:"Bocanda"},10:{code:"BAN",name:"Bangolo"},11:{code:"BEO",name:"Beoumi"},12:{code:"BIA",name:"Biankouma"},13:{code:"BDK",name:"Bondoukou"},14:{code:"BGN",name:"Bongouanou"},15:{code:"BFL",name:"Bouafle"},16:{code:"BKE",name:"Bouake"},17:{code:"BNA",name:"Bouna"},18:{code:"BDL",name:"Boundiali"},19:{code:"DKL",name:"Dabakala"},20:{code:"DBU",name:"Dabou"},21:{code:"DAL",name:"Daloa"},22:{code:"DAN",name:"Danane"},23:{code:"DAO",name:"Daoukro"},24:{code:"DIM",name:"Dimbokro"},25:{code:"DIV",name:"Divo"},26:{code:"DUE",name:"Duekoue"},27:{code:"FER",name:"Ferkessedougou"},28:{code:"GAG",name:"Gagnoa"},29:{code:"GBA",name:"Grand-Bassam"},30:{code:"GLA",name:"Grand-Lahou"},31:{code:"GUI",name:"Guiglo"},32:{code:"ISS",name:"Issia"},33:{code:"JAC",name:"Jacqueville"},34:{code:"KAT",name:"Katiola"},35:{code:"KOR",name:"Korhogo"},36:{code:"LAK",name:"Lakota"},37:{code:"MAN",name:"Man"},38:{code:"MKN",name:"Mankono"},39:{code:"MBA",name:"Mbahiakro"},40:{code:"ODI",name:"Odienne"},41:{code:"OUM",name:"Oume"},42:{code:"SAK",name:"Sakassou"},43:{code:"SPE",name:"San-Pedro"},44:{code:"SAS",name:"Sassandra"},45:{code:"SEG",name:"Seguela"},46:{code:"SIN",name:"Sinfra"},47:{code:"SOU",name:"Soubre"},48:{code:"TAB",name:"Tabou"},49:{code:"TAN",name:"Tanda"},50:{code:"TIE",name:"Tiebissou"},51:{code:"TIN",name:"Tingrela"},52:{code:"TIA",name:"Tiassale"},53:{code:"TBA",name:"Touba"},54:{code:"TLP",name:"Toulepleu"},55:{code:"TMD",name:"Toumodi"},56:{code:"VAV",name:"Vavoua"},57:{code:"YAM",name:"Yamoussoukro"},58:{code:"ZUE",name:"Zuenoula"}},HR:{1:{code:"BB",name:"Bjelovar-Bilogora"},2:{code:"CZ",name:"City of Zagreb"},3:{code:"DN",name:"Dubrovnik-Neretva"},4:{code:"IS",name:"Istra"},5:{code:"KA",name:"Karlovac"},6:{code:"KK",name:"Koprivnica-Krizevci"},7:{code:"KZ",name:"Krapina-Zagorje"},8:{code:"LS",name:"Lika-Senj"},9:{code:"ME",name:"Medimurje"},10:{code:"OB",name:"Osijek-Baranja"},11:{code:"PS",name:"Pozega-Slavonia"},12:{code:"PG",name:"Primorje-Gorski Kotar"},13:{code:"SI",name:"Sibenik"},14:{code:"SM",name:"Sisak-Moslavina"},15:{code:"SB",name:"Slavonski Brod-Posavina"},16:{code:"SD",name:"Split-Dalmatia"},17:{code:"VA",name:"Varazdin"},18:{code:"VP",name:"Virovitica-Podravina"},19:{code:"VS",name:"Vukovar-Srijem"},20:{code:"ZK",name:"Zadar-Knin"},21:{code:"ZA",name:"Zagreb"}},CU:{1:{code:"CA",name:"Camaguey"},2:{code:"CD",name:"Ciego de Avila"},3:{code:"CI",name:"Cienfuegos"},4:{code:"CH",name:"Ciudad de La Habana"},5:{code:"GR",name:"Granma"},6:{code:"GU",name:"Guantanamo"},7:{code:"HO",name:"Holguin"},8:{code:"IJ",name:"Isla de la Juventud"},9:{code:"LH",name:"La Habana"},10:{code:"LT",name:"Las Tunas"},11:{code:"MA",name:"Matanzas"},12:{code:"PR",name:"Pinar del Rio"},13:{code:"SS",name:"Sancti Spiritus"},14:{code:"SC",name:"Santiago de Cuba"},15:{code:"VC",name:"Villa Clara"}},CY:{1:{code:"F",name:"Famagusta"},2:{code:"K",name:"Kyrenia"},3:{code:"A",name:"Larnaca"},4:{code:"I",name:"Limassol"},5:{code:"N",name:"Nicosia"},6:{code:"P",name:"Paphos"}},CZ:{1:{code:"A",name:"Hlavní město Praha"},2:{code:"B",name:"Jihomoravský"},3:{code:"C",name:"Jihočeský"},4:{code:"E",name:"Pardubický"},5:{code:"H",name:"Královéhradecký"},6:{code:"J",name:"Vysočina"},7:{code:"K",name:"Karlovarský"},8:{code:"L",name:"Liberecký"},9:{code:"M",name:"Olomoucký"},10:{code:"P",name:"Plzeňský"},11:{code:"S",name:"Středočeský"},12:{code:"T",name:"Moravskoslezský"},13:{code:"U",name:"Ústecký"},14:{code:"Z",name:"Zlínský"}},DK:{1:{code:"AR",name:"Arhus"},2:{code:"BH",name:"Bornholm"},3:{code:"CO",name:"Copenhagen"},4:{code:"FO",name:"Faroe Islands"},5:{code:"FR",name:"Frederiksborg"},6:{code:"FY",name:"Fyn"},7:{code:"KO",name:"Kobenhavn"},8:{code:"NO",name:"Nordjylland"},9:{code:"RI",name:"Ribe"},10:{code:"RK",name:"Ringkobing"},11:{code:"RO",name:"Roskilde"},12:{code:"SO",name:"Sonderjylland"},13:{code:"ST",name:"Storstrom"},14:{code:"VK",name:"Vejle"},15:{code:"VJ",name:"Vestjælland"},16:{code:"VB",name:"Viborg"}},DJ:{1:{code:"S",name:"'Ali Sabih"},2:{code:"K",name:"Dikhil"},3:{code:"J",name:"Djibouti"},4:{code:"O",name:"Obock"},5:{code:"T",name:"Tadjoura"}},DM:{1:{code:"AND",name:"Saint Andrew Parish"},2:{code:"DAV",name:"Saint David Parish"},3:{code:"GEO",name:"Saint George Parish"},4:{code:"JOH",name:"Saint John Parish"},5:{code:"JOS",name:"Saint Joseph Parish"},6:{code:"LUK",name:"Saint Luke Parish"},7:{code:"MAR",name:"Saint Mark Parish"},8:{code:"PAT",name:"Saint Patrick Parish"},9:{code:"PAU",name:"Saint Paul Parish"},10:{code:"PET",name:"Saint Peter Parish"}},DO:{1:{code:"DN",name:"Distrito Nacional"},2:{code:"AZ",name:"Azua"},3:{code:"BC",name:"Baoruco"},4:{code:"BH",name:"Barahona"},5:{code:"DJ",name:"Dajabon"},6:{code:"DU",name:"Duarte"},7:{code:"EL",name:"Elias Pina"},8:{code:"SY",name:"El Seybo"},9:{code:"ET",name:"Espaillat"},10:{code:"HM",name:"Hato Mayor"},11:{code:"IN",name:"Independencia"},12:{code:"AL",name:"La Altagracia"},13:{code:"RO",name:"La Romana"},14:{code:"VE",name:"La Vega"},15:{code:"MT",name:"Maria Trinidad Sanchez"},16:{code:"MN",name:"Monsenor Nouel"},17:{code:"MC",name:"Monte Cristi"},18:{code:"MP",name:"Monte Plata"},19:{code:"PD",name:"Pedernales"},20:{code:"PR",name:"Peravia (Bani)"},21:{code:"PP",name:"Puerto Plata"},22:{code:"SL",name:"Salcedo"},23:{code:"SM",name:"Samana"},24:{code:"SH",name:"Sanchez Ramirez"},25:{code:"SC",name:"San Cristobal"},26:{code:"JO",name:"San Jose de Ocoa"},27:{code:"SJ",name:"San Juan"},28:{code:"PM",name:"San Pedro de Macoris"},29:{code:"SA",name:"Santiago"},30:{code:"ST",name:"Santiago Rodriguez"},31:{code:"SD",name:"Santo Domingo"},32:{code:"VA",name:"Valverde"}},TP:{1:{code:"AL",name:"Aileu"},2:{code:"AN",name:"Ainaro"},3:{code:"BA",name:"Baucau"},4:{code:"BO",name:"Bobonaro"},5:{code:"CO",name:"Cova Lima"},6:{code:"DI",name:"Dili"},7:{code:"ER",name:"Ermera"},8:{code:"LA",name:"Lautem"},9:{code:"LI",name:"Liquica"},10:{code:"MT",name:"Manatuto"},11:{code:"MF",name:"Manufahi"},12:{code:"OE",name:"Oecussi"},13:{code:"VI",name:"Viqueque"}},EC:{1:{code:"AZU",name:"Azuay"},2:{code:"BOL",name:"Bolivar"},3:{code:"CAN",name:"Cañar"},4:{code:"CAR",name:"Carchi"},5:{code:"CHI",name:"Chimborazo"},6:{code:"COT",name:"Cotopaxi"},7:{code:"EOR",name:"El Oro"},8:{code:"ESM",name:"Esmeraldas"},9:{code:"GPS",name:"Galápagos"},10:{code:"GUA",name:"Guayas"},11:{code:"IMB",name:"Imbabura"},12:{code:"LOJ",name:"Loja"},13:{code:"LRO",name:"Los Ríos"},14:{code:"MAN",name:"Manabí"},15:{code:"MSA",name:"Morona Santiago"},16:{code:"NAP",name:"Napo"},17:{code:"ORE",name:"Orellana"},18:{code:"PAS",name:"Pastaza"},19:{code:"PIC",name:"Pichincha"},20:{code:"SUC",name:"Sucumbíos"},21:{code:"TUN",name:"Tungurahua"},22:{code:"ZCH",name:"Zamora Chinchipe"}},EG:{1:{code:"DHY",name:"Ad Daqahliyah"},2:{code:"BAM",name:"Al Bahr al Ahmar"},3:{code:"BHY",name:"Al Buhayrah"},4:{code:"FYM",name:"Al Fayyum"},5:{code:"GBY",name:"Al Gharbiyah"},6:{code:"IDR",name:"Al Iskandariyah"},7:{code:"IML",name:"Al Isma 'iliyah"},8:{code:"JZH",name:"Al Jizah"},9:{code:"MFY",name:"Al Minufiyah"},10:{code:"MNY",name:"Al Minya"},11:{code:"QHR",name:"Al Qahirah"},12:{code:"QLY",name:"Al Qalyubiyah"},13:{code:"WJD",name:"Al Wadi al Jadid"},14:{code:"SHQ",name:"Ash Sharqiyah"},15:{code:"SWY",name:"As Suways"},16:{code:"ASW",name:"Aswan"},17:{code:"ASY",name:"Asyut"},18:{code:"BSW",name:"Bani Suwayf"},19:{code:"BSD",name:"Bur Sa'id"},20:{code:"DMY",name:"Dumyat"},21:{code:"JNS",name:"Janub Sina'"},22:{code:"KSH",name:"Kafr ash Shaykh"},23:{code:"MAT",name:"Matruh"},24:{code:"QIN",name:"Qina"},25:{code:"SHS",name:"Shamal Sina'"},26:{code:"SUH",name:"Suhaj"}},SV:{1:{code:"AH",name:"Ahuachapan"},2:{code:"CA",name:"Cabanas"},3:{code:"CH",name:"Chalatenango"},4:{code:"CU",name:"Cuscatlan"},5:{code:"LB",name:"La Libertad"},6:{code:"PZ",name:"La Paz"},7:{code:"UN",name:"La Union"},8:{code:"MO",name:"Morazan"},9:{code:"SM",name:"San Miguel"},10:{code:"SS",name:"San Salvador"},11:{code:"SV",name:"San Vicente"},12:{code:"SA",name:"Santa Ana"},13:{code:"SO",name:"Sonsonate"},14:{code:"US",name:"Usulutan"}},GQ:{1:{code:"AN",name:"Provincia Annobon"},2:{code:"BN",name:"Provincia Bioko Norte"},3:{code:"BS",name:"Provincia Bioko Sur"},4:{code:"CS",name:"Provincia Centro Sur"},5:{code:"KN",name:"Provincia Kie-Ntem"},6:{code:"LI",name:"Provincia Litoral"},7:{code:"WN",name:"Provincia Wele-Nzas"}},ER:{1:{code:"MA",name:"Central (Maekel)"},2:{code:"KE",name:"Anseba (Keren)"},3:{code:"DK",name:"Southern Red Sea (Debub-Keih-Bah)"},4:{code:"SK",name:"Northern Red Sea (Semien-Keih-Ba)"},5:{code:"DE",name:"Southern (Debub)"},6:{code:"BR",name:"Gash-Barka (Barentu)"}},EE:{1:{code:"HA",name:"Harjumaa (Tallinn)"},2:{code:"HI",name:"Hiiumaa (Kardla)"},3:{code:"IV",name:"Ida-Virumaa (Johvi)"},4:{code:"JA",name:"Jarvamaa (Paide)"},5:{code:"JO",name:"Jogevamaa (Jogeva)"},6:{code:"LV",name:"Laane-Virumaa (Rakvere)"},7:{code:"LA",name:"Laanemaa (Haapsalu)"},8:{code:"PA",name:"Parnumaa (Parnu)"},9:{code:"PO",name:"Polvamaa (Polva)"},10:{code:"RA",name:"Raplamaa (Rapla)"},11:{code:"SA",name:"Saaremaa (Kuessaare)"},12:{code:"TA",name:"Tartumaa (Tartu)"},13:{code:"VA",name:"Valgamaa (Valga)"},14:{code:"VI",name:"Viljandimaa (Viljandi)"},15:{code:"VO",name:"Vorumaa (Voru)"}},ET:{1:{code:"AF",name:"Afar"},2:{code:"AH",name:"Amhara"},3:{code:"BG",name:"Benishangul-Gumaz"},4:{code:"GB",name:"Gambela"},5:{code:"HR",name:"Hariai"},6:{code:"OR",name:"Oromia"},7:{code:"SM",name:"Somali"},8:{code:"SN",name:"Southern Nations - Nationalities"},9:{code:"TG",name:"Tigray"},10:{code:"AA",name:"Addis Ababa"},11:{code:"DD",name:"Dire Dawa"}},FO:{1:{code:"TÛR",name:"Tûrshavnar Kommuna"},2:{code:"KLA",name:"Klaksvík"},3:{code:"RUN",name:"Runavík"},4:{code:"TVØ",name:"Tvøroyri"},5:{code:"FUG",name:"Fuglafjørður"},6:{code:"SUN",name:"Sunda Kommuna"},7:{code:"VáG",name:"Vágur"},8:{code:"NES",name:"Nes"},9:{code:"VES",name:"Vestmanna"},10:{code:"MIð",name:"Miðvágur"},11:{code:"SØR",name:"Sørvágur"},12:{code:"GØT",name:"Gøtu Kommuna"},13:{code:"SJû",name:"Sjûvar Kommuna"},14:{code:"LEI",name:"Leirvík"},15:{code:"SAN",name:"Sandavágur"},16:{code:"HVA",name:"Hvalba"},17:{code:"EIð",name:"Eiði"},18:{code:"KVí",name:"Kvívík"},19:{code:"SAN",name:"Sandur"},20:{code:"SKO",name:"Skopun"},21:{code:"HVA",name:"Hvannasund"},22:{code:"SUM",name:"Sumba"},23:{code:"VIð",name:"Viðareiði"},24:{code:"POR",name:"Porkeri"},25:{code:"SKá",name:"Skálavík"},26:{code:"KUN",name:"Kunoy"},27:{code:"HÚS",name:"HÚsavík"},28:{code:"HOV",name:"Hov"},29:{code:"FáM",name:"Fámjin"},30:{code:"FUN",name:"Funningur"},31:{code:"HÚS",name:"HÚsar"},32:{code:"SKÚ",name:"SkÚvoy"},33:{code:"SVí",name:"Svínoy"},34:{code:"FUG",name:"Fugloy"}},FJ:{1:{code:"C",name:"Central Division"},2:{code:"E",name:"Eastern Division"},3:{code:"N",name:"Northern Division"},4:{code:"R",name:"Rotuma"},5:{code:"W",name:"Western Division"}},FI:{1:{code:"AL",name:"Ahvenanmaan Laani"},2:{code:"ES",name:"Etela-Suomen Laani"},3:{code:"IS",name:"Ita-Suomen Laani"},4:{code:"LS",name:"Lansi-Suomen Laani"},5:{code:"LA",name:"Lapin Lanani"},6:{code:"OU",name:"Oulun Laani"}},FR:{1:{code:"AL",name:"Alsace"},2:{code:"AQ",name:"Aquitaine"},3:{code:"AU",name:"Auvergne"},4:{code:"BR",name:"Brittany"},5:{code:"BU",name:"Burgundy"},6:{code:"CE",name:"Center Loire Valley"},7:{code:"CH",name:"Champagne"},8:{code:"CO",name:"Corse"},9:{code:"FR",name:"France Comte"},10:{code:"LA",name:"Languedoc Roussillon"},11:{code:"LI",name:"Limousin"},12:{code:"LO",name:"Lorraine"},13:{code:"MI",name:"Midi Pyrenees"},14:{code:"NO",name:"Nord Pas de Calais"},15:{code:"NR",name:"Normandy"},16:{code:"PA",name:"Paris / Ile de France"},17:{code:"PI",name:"Picardie"},18:{code:"PO",name:"Poitou Charente"},19:{code:"PR",name:"Provence"},20:{code:"RH",name:"Rhone Alps"},21:{code:"RI",name:"Riviera"},22:{code:"WE",name:"Western Loire Valley"}},FX:{1:{code:"Et",name:"Etranger"},2:{code:"01",name:"Ain"},3:{code:"02",name:"Aisne"},4:{code:"03",name:"Allier"},5:{code:"04",name:"Alpes de Haute Provence"},6:{code:"05",name:"Hautes-Alpes"},7:{code:"06",name:"Alpes Maritimes"},8:{code:"07",name:"Ardèche"},9:{code:"08",name:"Ardennes"},10:{code:"09",name:"Ariège"},11:{code:"10",name:"Aube"},12:{code:"11",name:"Aude"},13:{code:"12",name:"Aveyron"},14:{code:"13",name:"Bouches du Rhône"},15:{code:"14",name:"Calvados"},16:{code:"15",name:"Cantal"},17:{code:"16",name:"Charente"},18:{code:"17",name:"Charente Maritime"},19:{code:"18",name:"Cher"},20:{code:"19",name:"Corrèze"},21:{code:"2A",name:"Corse du Sud"},22:{code:"2B",name:"Haute Corse"},23:{code:"21",name:"Côte d'or"},24:{code:"22",name:"Côtes d'Armor"},25:{code:"23",name:"Creuse"},26:{code:"24",name:"Dordogne"},27:{code:"25",name:"Doubs"},28:{code:"26",name:"Drôme"},29:{code:"27",name:"Eure"},30:{code:"28",name:"Eure et Loir"},31:{code:"29",name:"Finistère"},32:{code:"30",name:"Gard"},33:{code:"31",name:"Haute Garonne"},34:{code:"32",name:"Gers"},35:{code:"33",name:"Gironde"},36:{code:"34",name:"Hérault"},37:{code:"35",name:"Ille et Vilaine"},38:{code:"36",name:"Indre"},39:{code:"37",name:"Indre et Loire"},40:{code:"38",name:"Isére"},41:{code:"39",name:"Jura"},42:{code:"40",name:"Landes"},43:{code:"41",name:"Loir et Cher"},44:{code:"42",name:"Loire"},45:{code:"43",name:"Haute Loire"},46:{code:"44",name:"Loire Atlantique"},47:{code:"45",name:"Loiret"},48:{code:"46",name:"Lot"},49:{code:"47",name:"Lot et Garonne"},50:{code:"48",name:"Lozère"},51:{code:"49",name:"Maine et Loire"},52:{code:"50",name:"Manche"},53:{code:"51",name:"Marne"},54:{code:"52",name:"Haute Marne"},55:{code:"53",name:"Mayenne"},56:{code:"54",name:"Meurthe et Moselle"},57:{code:"55",name:"Meuse"},58:{code:"56",name:"Morbihan"},59:{code:"57",name:"Moselle"},60:{code:"58",name:"Nièvre"},61:{code:"59",name:"Nord"},62:{code:"60",name:"Oise"},63:{code:"61",name:"Orne"},64:{code:"62",name:"Pas de Calais"},65:{code:"63",name:"Puy de Dôme"},66:{code:"64",name:"Pyrenees Atlantique"},67:{code:"65",name:"Hautes Pyrenees"},68:{code:"66",name:"Pyrenees Orientale"},69:{code:"67",name:"Bas Rhin"},70:{code:"68",name:"Haut Rhin"},71:{code:"69",name:"Rhône"},72:{code:"70",name:"Haute Saône"},73:{code:"71",name:"Saône et Loire"},74:{code:"72",name:"Sarthe"},75:{code:"73",name:"Savoie"},76:{code:"74",name:"Haute Savoie"},77:{code:"75",name:"Paris"},78:{code:"76",name:"Seine Martitime"},79:{code:"77",name:"Seine et Marne"},80:{code:"78",name:"Yvelines"},81:{code:"79",name:"Deux Sèvres"},82:{code:"80",name:"Somme"},83:{code:"81",name:"Tarn"},84:{code:"82",name:"Tarn et Garonne"},85:{code:"83",name:"Var"},86:{code:"84",name:"Vaucluse"},87:{code:"85",name:"Vendée"},88:{code:"86",name:"Vienne"},89:{code:"87",name:"Haute Vienne"},90:{code:"88",name:"Vosges"},91:{code:"89",name:"Yonne"},92:{code:"90",name:"Territoire de Belfort"},93:{code:"91",name:"Essonne"},94:{code:"92",name:"Hauts de Seine"},95:{code:"93",name:"Seine St-Denis"},96:{code:"94",name:"Val de Marne"},97:{code:"95",name:"Val d'oise"}},GF:{1:{code:"AWA",name:"Awala-Yalimapo"},2:{code:"MAN",name:"Mana"},3:{code:"SAI",name:"Saint-Laurent-Du-Maroni"},4:{code:"APA",name:"Apatou"},5:{code:"GRA",name:"Grand-Santi"},6:{code:"PAP",name:"Papaïchton"},7:{code:"SAÜ",name:"SaÜl"},8:{code:"MAR",name:"Maripasoula"},9:{code:"CAM",name:"Camopi"},10:{code:"SAI",name:"Saint-Georges"},11:{code:"OUA",name:"Ouanary"},12:{code:"RéG",name:"Régina"},13:{code:"ROU",name:"Roura"},14:{code:"SAI",name:"Saint-élie"},15:{code:"IRA",name:"Iracoubo"},16:{code:"SIN",name:"Sinnamary"},17:{code:"KOU",name:"Kourou"},18:{code:"MAC",name:"Macouria"},19:{code:"MON",name:"Montsinéry-Tonnegrande"},20:{code:"MAT",name:"Matoury"},21:{code:"CAY",name:"Cayenne"},22:{code:"REM",name:"Remire-Montjoly"}},PF:{1:{code:"M",name:"Archipel des Marquises"},2:{code:"T",name:"Archipel des Tuamotu"},3:{code:"I",name:"Archipel des Tubuai"},4:{code:"V",name:"Iles du Vent"},5:{code:"S",name:"Iles Sous-le-Vent"}},TF:{1:{code:"C",name:"Iles Crozet"},2:{code:"K",name:"Iles Kerguelen"},3:{code:"A",name:"Ile Amsterdam"},4:{code:"P",name:"Ile Saint-Paul"},5:{code:"D",name:"Adelie Land"}},GA:{1:{code:"ES",name:"Estuaire"},2:{code:"HO",name:"Haut-Ogooue"},3:{code:"MO",name:"Moyen-Ogooue"},4:{code:"NG",name:"Ngounie"},5:{code:"NY",name:"Nyanga"},6:{code:"OI",name:"Ogooue-Ivindo"},7:{code:"OL",name:"Ogooue-Lolo"},8:{code:"OM",name:"Ogooue-Maritime"},9:{code:"WN",name:"Woleu-Ntem"}},GM:{1:{code:"BJ",name:"Banjul"},2:{code:"BS",name:"Basse"},3:{code:"BR",name:"Brikama"},4:{code:"JA",name:"Janjangbure"},5:{code:"KA",name:"Kanifeng"},6:{code:"KE",name:"Kerewan"},7:{code:"KU",name:"Kuntaur"},8:{code:"MA",name:"Mansakonko"},9:{code:"LR",name:"Lower River"},10:{code:"CR",name:"Central River"},11:{code:"NB",name:"North Bank"},12:{code:"UR",name:"Upper River"},13:{code:"WE",name:"Western"}},GE:{1:{code:"AB",name:"Abkhazia"},2:{code:"AJ",name:"Ajaria"},3:{code:"GU",name:"Guria"},4:{code:"IM",name:"Imereti"},5:{code:"KA",name:"Kakheti"},6:{code:"KK",name:"Kvemo Kartli"},7:{code:"MM",name:"Mtskheta-Mtianeti"},8:{code:"RL",name:"Racha Lechkhumi and Kvemo Svanet"},9:{code:"SJ",name:"Samtskhe-Javakheti"},10:{code:"SK",name:"Shida Kartli"},11:{code:"SZ",name:"Samegrelo-Zemo Svaneti"},12:{code:"TB",name:"Tbilisi"}},DE:{1:{code:"BAW",name:"Baden-Württemberg"},2:{code:"BAY",name:"Bayern"},3:{code:"BER",name:"Berlin"},4:{code:"BRG",name:"Brandenburg"},5:{code:"BRE",name:"Bremen"},6:{code:"HAM",name:"Hamburg"},7:{code:"HES",name:"Hessen"},8:{code:"MEC",name:"Mecklenburg-Vorpommern"},9:{code:"NDS",name:"Niedersachsen"},10:{code:"NRW",name:"Nordrhein-Westfalen"},11:{code:"RHE",name:"Rheinland-Pfalz"},12:{code:"SAR",name:"Saarland"},13:{code:"SAS",name:"Sachsen"},14:{code:"SAC",name:"Sachsen-Anhalt"},15:{code:"SCN",name:"Schleswig-Holstein"},16:{code:"THE",name:"Thüringen"}},GH:{1:{code:"AS",name:"Ashanti Region"},2:{code:"BA",name:"Brong-Ahafo Region"},3:{code:"CE",name:"Central Region"},4:{code:"EA",name:"Eastern Region"},5:{code:"GA",name:"Greater Accra Region"},6:{code:"NO",name:"Northern Region"},7:{code:"UE",name:"Upper East Region"},8:{code:"UW",name:"Upper West Region"},9:{code:"VO",name:"Volta Region"},10:{code:"WE",name:"Western Region"}},GI:{1:{code:"EAS",name:"East Side"},2:{code:"NOR",name:"North District"},3:{code:"REC",name:"Reclamation Areas"},4:{code:"SAN",name:"Sandpits Area"},5:{code:"SOU",name:"South District"},6:{code:"TOW",name:"Town Area"},7:{code:"UPP",name:"Upper Town"},8:{code:"OTH",name:"Other"}},GR:{1:{code:"AT",name:"Attica"},2:{code:"CN",name:"Central Greece"},3:{code:"CM",name:"Central Macedonia"},4:{code:"CR",name:"Crete"},5:{code:"EM",name:"East Macedonia and Thrace"},6:{code:"EP",name:"Epirus"},7:{code:"II",name:"Ionian Islands"},8:{code:"NA",name:"North Aegean"},9:{code:"PP",name:"Peloponnesos"},10:{code:"SA",name:"South Aegean"},11:{code:"TH",name:"Thessaly"},12:{code:"WG",name:"West Greece"},13:{code:"WM",name:"West Macedonia"}},GL:{1:{code:"A",name:"Avannaa"},2:{code:"T",name:"Tunu"},3:{code:"K",name:"Kitaa"}},86:{1:{code:"A",name:"Saint Andrew"},2:{code:"D",name:"Saint David"},3:{code:"G",name:"Saint George"},4:{code:"J",name:"Saint John"},5:{code:"M",name:"Saint Mark"},6:{code:"P",name:"Saint Patrick"},7:{code:"C",name:"Carriacou"},8:{code:"Q",name:"Petit Martinique"}},GP:{1:{code:"ARR",name:"Arrondissements Of The Guadeloup"},2:{code:"CAN",name:"Cantons Of The Guadeloup Depart"},3:{code:"COM",name:"Communes Of The Guadeloup Depart"}},GU:{1:{code:"AGA",name:"Agana Heights"},2:{code:"AGA",name:"Agat"},3:{code:"ASA",name:"Asan Maina"},4:{code:"BAR",name:"Barrigada"},5:{code:"CHA",name:"Chalan Pago Ordot"},6:{code:"DED",name:"Dededo"},7:{code:"HAG",name:"HagÅtña"},8:{code:"INA",name:"Inarajan"},9:{code:"MAN",name:"Mangilao"},10:{code:"MER",name:"Merizo"},11:{code:"MON",name:"Mongmong Toto Maite"},12:{code:"PIT",name:"Piti"},13:{code:"SAN",name:"Santa Rita"},14:{code:"SIN",name:"Sinajana"},15:{code:"TAL",name:"Talofofo"},16:{code:"TAM",name:"Tamuning"},17:{code:"UMA",name:"Umatac"},18:{code:"YIG",name:"Yigo"},19:{code:"YON",name:"Yona"}},GT:{1:{code:"AV",name:"Alta Verapaz"},2:{code:"BV",name:"Baja Verapaz"},3:{code:"CM",name:"Chimaltenango"},4:{code:"CQ",name:"Chiquimula"},5:{code:"PE",name:"El Peten"},6:{code:"PR",name:"El Progreso"},7:{code:"QC",name:"El Quiche"},8:{code:"ES",name:"Escuintla"},9:{code:"GU",name:"Guatemala"},10:{code:"HU",name:"Huehuetenango"},11:{code:"IZ",name:"Izabal"},12:{code:"JA",name:"Jalapa"},13:{code:"JU",name:"Jutiapa"},14:{code:"QZ",name:"Quetzaltenango"},15:{code:"RE",name:"Retalhuleu"},16:{code:"ST",name:"Sacatepequez"},17:{code:"SM",name:"San Marcos"},18:{code:"SR",name:"Santa Rosa"},19:{code:"SO",name:"Solola"},20:{code:"SU",name:"Suchitepequez"},21:{code:"TO",name:"Totonicapan"},22:{code:"ZA",name:"Zacapa"}},GN:{1:{code:"CNK",name:"Conakry"},2:{code:"BYL",name:"Beyla"},3:{code:"BFA",name:"Boffa"},4:{code:"BOK",name:"Boke"},5:{code:"COY",name:"Coyah"},6:{code:"DBL",name:"Dabola"},7:{code:"DLB",name:"Dalaba"},8:{code:"DGR",name:"Dinguiraye"},9:{code:"DBR",name:"Dubreka"},10:{code:"FRN",name:"Faranah"},11:{code:"FRC",name:"Forecariah"},12:{code:"FRI",name:"Fria"},13:{code:"GAO",name:"Gaoual"},14:{code:"GCD",name:"Gueckedou"},15:{code:"KNK",name:"Kankan"},16:{code:"KRN",name:"Kerouane"},17:{code:"KND",name:"Kindia"},18:{code:"KSD",name:"Kissidougou"},19:{code:"KBA",name:"Koubia"},20:{code:"KDA",name:"Koundara"},21:{code:"KRA",name:"Kouroussa"},22:{code:"LAB",name:"Labe"},23:{code:"LLM",name:"Lelouma"},24:{code:"LOL",name:"Lola"},25:{code:"MCT",name:"Macenta"},26:{code:"MAL",name:"Mali"},27:{code:"MAM",name:"Mamou"},28:{code:"MAN",name:"Mandiana"},29:{code:"NZR",name:"Nzerekore"},30:{code:"PIT",name:"Pita"},31:{code:"SIG",name:"Siguiri"},32:{code:"TLM",name:"Telimele"},33:{code:"TOG",name:"Tougue"},34:{code:"YOM",name:"Yomou"}},GW:{1:{code:"BF",name:"Bafata Region"},2:{code:"BB",name:"Biombo Region"},3:{code:"BS",name:"Bissau Region"},4:{code:"BL",name:"Bolama Region"},5:{code:"CA",name:"Cacheu Region"},6:{code:"GA",name:"Gabu Region"},7:{code:"OI",name:"Oio Region"},8:{code:"QU",name:"Quinara Region"},9:{code:"TO",name:"Tombali Region"}},GY:{1:{code:"BW",name:"Barima-Waini"},2:{code:"CM",name:"Cuyuni-Mazaruni"},3:{code:"DM",name:"Demerara-Mahaica"},4:{code:"EC",name:"East Berbice-Corentyne"},5:{code:"EW",name:"Essequibo Islands-West Demerara"},6:{code:"MB",name:"Mahaica-Berbice"},7:{code:"PM",name:"Pomeroon-Supenaam"},8:{code:"PI",name:"Potaro-Siparuni"},9:{code:"UD",name:"Upper Demerara-Berbice"},10:{code:"UT",name:"Upper Takutu-Upper Essequibo"}},HT:{1:{code:"AR",name:"Artibonite"},2:{code:"CE",name:"Centre"},3:{code:"GA",name:"Grand'Anse"},4:{code:"ND",name:"Nord"},5:{code:"NE",name:"Nord-Est"},6:{code:"NO",name:"Nord-Ouest"},7:{code:"OU",name:"Ouest"},8:{code:"SD",name:"Sud"},9:{code:"SE",name:"Sud-Est"}},HM:{1:{code:"F",name:"Flat Island"},2:{code:"M",name:"McDonald Island"},3:{code:"S",name:"Shag Island"},4:{code:"H",name:"Heard Island"}},HN:{1:{code:"AT",name:"Atlantida"},2:{code:"CH",name:"Choluteca"},3:{code:"CL",name:"Colon"},4:{code:"CM",name:"Comayagua"},5:{code:"CP",name:"Copan"},6:{code:"CR",name:"Cortes"},7:{code:"PA",name:"El Paraiso"},8:{code:"FM",name:"Francisco Morazan"},9:{code:"GD",name:"Gracias a Dios"},10:{code:"IN",name:"Intibuca"},11:{code:"IB",name:"Islas de la Bahia (Bay Islands)"},12:{code:"PZ",name:"La Paz"},13:{code:"LE",name:"Lempira"},14:{code:"OC",name:"Ocotepeque"},15:{code:"OL",name:"Olancho"},16:{code:"SB",name:"Santa Barbara"},17:{code:"VA",name:"Valle"},18:{code:"YO",name:"Yoro"}},HK:{1:{code:"HCW",name:"Central and Western Hong Kong Is"},2:{code:"HEA",name:"Eastern Hong Kong Island"},3:{code:"HSO",name:"Southern Hong Kong Island"},4:{code:"HWC",name:"Wan Chai Hong Kong Island"},5:{code:"KKC",name:"Kowloon City Kowloon"},6:{code:"KKT",name:"Kwun Tong Kowloon"},7:{code:"KSS",name:"Sham Shui Po Kowloon"},8:{code:"KWT",name:"Wong Tai Sin Kowloon"},9:{code:"KYT",name:"Yau Tsim Mong Kowloon"},10:{code:"NIS",name:"Islands New Territories"},11:{code:"NKT",name:"Kwai Tsing New Territories"},12:{code:"NNO",name:"North New Territories"},13:{code:"NSK",name:"Sai Kung New Territories"},14:{code:"NST",name:"Sha Tin New Territories"},15:{code:"NTP",name:"Tai Po New Territories"},16:{code:"NTW",name:"Tsuen Wan New Territories"},17:{code:"NTM",name:"Tuen Mun New Territories"},18:{code:"NYL",name:"Yuen Long New Territories"}},HU:{1:{code:"BK",name:"Bacs-Kiskun"},2:{code:"BA",name:"Baranya"},3:{code:"BE",name:"Bekes"},4:{code:"BS",name:"Bekescsaba"},5:{code:"BZ",name:"Borsod-Abauj-Zemplen"},6:{code:"BU",name:"Budapest"},7:{code:"CS",name:"Csongrad"},8:{code:"DE",name:"Debrecen"},9:{code:"DU",name:"Dunaujvaros"},10:{code:"EG",name:"Eger"},11:{code:"FE",name:"Fejer"},12:{code:"GY",name:"Gyor"},13:{code:"GM",name:"Gyor-Moson-Sopron"},14:{code:"HB",name:"Hajdu-Bihar"},15:{code:"HE",name:"Heves"},16:{code:"HO",name:"Hodmezovasarhely"},17:{code:"JN",name:"Jasz-Nagykun-Szolnok"},18:{code:"KA",name:"Kaposvar"},19:{code:"KE",name:"Kecskemet"},20:{code:"KO",name:"Komarom-Esztergom"},21:{code:"MI",name:"Miskolc"},22:{code:"NA",name:"Nagykanizsa"},23:{code:"NO",name:"Nograd"},24:{code:"NY",name:"Nyiregyhaza"},25:{code:"PE",name:"Pecs"},26:{code:"PS",name:"Pest"},27:{code:"SO",name:"Somogy"},28:{code:"SP",name:"Sopron"},29:{code:"SS",name:"Szabolcs-Szatmar-Bereg"},30:{code:"SZ",name:"Szeged"},31:{code:"SE",name:"Szekesfehervar"},32:{code:"SL",name:"Szolnok"},33:{code:"SM",name:"Szombathely"},34:{code:"TA",name:"Tatabanya"},35:{code:"TO",name:"Tolna"},36:{code:"VA",name:"Vas"},37:{code:"VE",name:"Veszprem"},38:{code:"ZA",name:"Zala"},39:{code:"ZZ",name:"Zalaegerszeg"}},IS:{1:{code:"AL",name:"Austurland"},2:{code:"HF",name:"Hofuoborgarsvaeoi"},3:{code:"NE",name:"Norourland eystra"},4:{code:"NV",name:"Norourland vestra"},5:{code:"SL",name:"Suourland"},6:{code:"SN",name:"Suournes"},7:{code:"VF",name:"Vestfiroir"},8:{code:"VL",name:"Vesturland"}},IN:{1:{code:"AN",name:"Andaman and Nicobar Islands"},2:{code:"AP",name:"Andhra Pradesh"},3:{code:"AR",name:"Arunachal Pradesh"},4:{code:"AS",name:"Assam"},5:{code:"BI",name:"Bihar"},6:{code:"CH",name:"Chandigarh"},7:{code:"DA",name:"Dadra and Nagar Haveli"},8:{code:"DM",name:"Daman and Diu"},9:{code:"DE",name:"Delhi"},10:{code:"GO",name:"Goa"},11:{code:"GU",name:"Gujarat"},12:{code:"HA",name:"Haryana"},13:{code:"HP",name:"Himachal Pradesh"},14:{code:"JA",name:"Jammu and Kashmir"},15:{code:"KA",name:"Karnataka"},16:{code:"KE",name:"Kerala"},17:{code:"LI",name:"Lakshadweep Islands"},18:{code:"MP",name:"Madhya Pradesh"},19:{code:"MA",name:"Maharashtra"},20:{code:"MN",name:"Manipur"},21:{code:"ME",name:"Meghalaya"},22:{code:"MI",name:"Mizoram"},23:{code:"NA",name:"Nagaland"},24:{code:"OR",name:"Orissa"},25:{code:"PO",name:"Pondicherry"},26:{code:"PU",name:"Punjab"},27:{code:"RA",name:"Rajasthan"},28:{code:"SI",name:"Sikkim"},29:{code:"TN",name:"Tamil Nadu"},30:{code:"TR",name:"Tripura"},31:{code:"UP",name:"Uttar Pradesh"},32:{code:"WB",name:"West Bengal"}},ID:{1:{code:"DA",name:"Daista Aceh"},2:{code:"SU",name:"Sumatera Utara"},3:{code:"SB",name:"Sumatera Barat"},4:{code:"SI",name:"Riau"},5:{code:"JA",name:"Jambi"},6:{code:"SS",name:"Sumatera Selatan"},7:{code:"BE",name:"Bengkulu"},8:{code:"LA",name:"Lampung"},9:{code:"JK",name:"Dki Jakarta"},10:{code:"JB",name:"Jawa Barat"},11:{code:"JT",name:"Jawa Tengah"},12:{code:"DY",name:"Daista Yogyakarta"},13:{code:"JT",name:"Jawa Timur"},14:{code:"KB",name:"Kalimantan Barat"},15:{code:"KT",name:"Kalimantan Tengah"},16:{code:"KI",name:"Kalimantan Timur"},17:{code:"KS",name:"Kalimantan Selatan"},18:{code:"BA",name:"Bali"},19:{code:"NB",name:"Nusa Tenggara Barat"},20:{code:"NT",name:"Nusa Tenggara Timur"},21:{code:"SN",name:"Sulawesi Selatan"},22:{code:"ST",name:"Sulawesi Tengah"},23:{code:"SA",name:"Sulawesi Utara"},24:{code:"SG",name:"Sulawesi Tenggara"},25:{code:"MA",name:"Maluku"},26:{code:"MU",name:"Maluku Utara"},27:{code:"IJ",name:"Irian Jaya Timur"},28:{code:"IT",name:"Irian Jaya Tengah"},29:{code:"IB",name:"Irian Jawa Barat"},30:{code:"BT",name:"Banten"},31:{code:"BB",name:"Bangka Belitung"},32:{code:"GO",name:"Gorontalo"}},IR:{1:{code:"ARD",name:"Ardabil"},2:{code:"BSH",name:"Bushehr"},3:{code:"CMB",name:"Chahar Mahaal and Bakhtiari"},4:{code:"EAZ",name:"East Azarbaijan"},5:{code:"EFH",name:"Esfahan"},6:{code:"FAR",name:"Fars"},7:{code:"GIL",name:"Gilan"},8:{code:"GLS",name:"Golestan"},9:{code:"HMD",name:"Hamadan"},10:{code:"HRM",name:"Hormozgan"},11:{code:"ILM",name:"Ilam"},12:{code:"KBA",name:"Kohkiluyeh and Buyer Ahmad"},13:{code:"KRB",name:"Kerman"},14:{code:"KRD",name:"Kurdistan"},15:{code:"KRM",name:"Kermanshah"},16:{code:"KZT",name:"Khuzestan"},17:{code:"LRS",name:"Lorestan"},18:{code:"MKZ",name:"Markazi"},19:{code:"MZD",name:"Mazandaran"},20:{code:"NKH",name:"North Khorasan"},21:{code:"QAZ",name:"Qazvin"},22:{code:"QOM",name:"Qom"},23:{code:"RKH",name:"Razavi Khorasan"},24:{code:"SBL",name:"Sistan and Baluchistan"},25:{code:"SKH",name:"South Khorasan"},26:{code:"SMN",name:"Semnan"},27:{code:"TEH",name:"Tehran"},28:{code:"WEZ",name:"West Azarbaijan"},29:{code:"YZD",name:"Yazd"},30:{code:"ZAN",name:"Zanjan"}},IQ:{1:{code:"AB",name:"Al Anbar"},2:{code:"AL",name:"Arbil"},3:{code:"BA",name:"Al Basrah"},4:{code:"BB",name:"Babil"},5:{code:"BD",name:"Baghdad"},6:{code:"DH",name:"Dahuk"},7:{code:"DQ",name:"Dhi Qar"},8:{code:"DY",name:"Diyala"},9:{code:"KB",name:"Al Karbala"},10:{code:"MU",name:"Al Muthanna"},11:{code:"MY",name:"Maysan"},12:{code:"NJ",name:"An Najaf"},13:{code:"NN",name:"Ninawa"},14:{code:"QA",name:"Al Qadisyah"},15:{code:"SD",name:"Salah ad Din"},16:{code:"SL",name:"As Sulaymaniyah"},17:{code:"TM",name:"At Ta'mim"},18:{code:"WS",name:"Wasit"}},IE:{1:{code:"CA",name:"Carlow"},2:{code:"CV",name:"Cavan"},3:{code:"CL",name:"Clare"},4:{code:"CO",name:"Cork"},5:{code:"DO",name:"Donegal"},6:{code:"DU",name:"Dublin"},7:{code:"GA",name:"Galway"},8:{code:"KE",name:"Kerry"},9:{code:"KI",name:"Kildare"},10:{code:"KL",name:"Kilkenny"},11:{code:"LA",name:"Laois"},12:{code:"LE",name:"Leitrim"},13:{code:"LI",name:"Limerick"},14:{code:"LO",name:"Longford"},15:{code:"LU",name:"Louth"},16:{code:"MA",name:"Mayo"},17:{code:"ME",name:"Meath"},18:{code:"MO",name:"Monaghan"},19:{code:"OF",name:"Offaly"},20:{code:"RO",name:"Roscommon"},21:{code:"SL",name:"Sligo"},22:{code:"TI",name:"Tipperary"},23:{code:"WA",name:"Waterford"},24:{code:"WE",name:"Westmeath"},25:{code:"WX",name:"Wexford"},26:{code:"WI",name:"Wicklow"}},IL:{1:{code:"BS",name:"Be'er Sheva"},2:{code:"BH",name:"Bika'at Hayarden"},3:{code:"EA",name:"Eilat and Arava"},4:{code:"GA",name:"Galil"},5:{code:"HA",name:"Haifa"},6:{code:"JM",name:"Jehuda Mountains"},7:{code:"JE",name:"Jerusalem"},8:{code:"NE",name:"Negev"},10:{code:"SE",name:"Semaria"},11:{code:"SH",name:"Sharon"},12:{code:"TA",name:"Tel Aviv (Gosh Dan)"}},IT:{1:{code:"AG",name:"Agrigento"},2:{code:"AL",name:"Alessandria"},3:{code:"AN",name:"Ancona"},4:{code:"AO",name:"Aosta"},5:{code:"AR",name:"Arezzo"},6:{code:"AP",name:"Ascoli Piceno"},7:{code:"AT",name:"Asti"},8:{code:"AV",name:"Avellino"},9:{code:"BA",name:"Bari"},10:{code:"BL",name:"Belluno"},11:{code:"BN",name:"Benevento"},12:{code:"BG",name:"Bergamo"},13:{code:"BI",name:"Biella"},14:{code:"BO",name:"Bologna"},15:{code:"BZ",name:"Bolzano"},16:{code:"BS",name:"Brescia"},17:{code:"BR",name:"Brindisi"},18:{code:"CA",name:"Cagliari"},19:{code:"CL",name:"Caltanissetta"},20:{code:"CB",name:"Campobasso"},21:{code:"CE",name:"Caserta"},22:{code:"CT",name:"Catania"},23:{code:"CZ",name:"Catanzaro"},24:{code:"CH",name:"Chieti"},25:{code:"CO",name:"Como"},26:{code:"CS",name:"Cosenza"},27:{code:"CR",name:"Cremona"},28:{code:"KR",name:"Crotone"},29:{code:"CN",name:"Cuneo"},30:{code:"EN",name:"Enna"},31:{code:"FE",name:"Ferrara"},32:{code:"FI",name:"Firenze"},33:{code:"FG",name:"Foggia"},34:{code:"FO",name:"Forlì"},35:{code:"FR",name:"Frosinone"},36:{code:"GE",name:"Genova"},37:{code:"GO",name:"Gorizia"},38:{code:"GR",name:"Grosseto"},39:{code:"IM",name:"Imperia"},40:{code:"IS",name:"Isernia"},41:{code:"AQ",name:"Aquila"},42:{code:"SP",name:"La Spezia"},43:{code:"LT",name:"Latina"},44:{code:"LE",name:"Lecce"},45:{code:"LC",name:"Lecco"},46:{code:"LI",name:"Livorno"},47:{code:"LO",name:"Lodi"},48:{code:"LU",name:"Lucca"},49:{code:"MC",name:"Macerata"},50:{code:"MN",name:"Mantova"},51:{code:"MS",name:"Massa-Carrara"},52:{code:"MT",name:"Matera"},53:{code:"ME",name:"Messina"},54:{code:"MI",name:"Milano"},55:{code:"MO",name:"Modena"},56:{code:"NA",name:"Napoli"},57:{code:"NO",name:"Novara"},58:{code:"NU",name:"Nuoro"},59:{code:"OR",name:"Oristano"},60:{code:"PD",name:"Padova"},61:{code:"PA",name:"Palermo"},62:{code:"PR",name:"Parma"},63:{code:"PG",name:"Perugia"},64:{code:"PV",name:"Pavia"},65:{code:"PU",name:"Pesaro Urbino"},66:{code:"PE",name:"Pescara"},67:{code:"PC",name:"Piacenza"},68:{code:"PI",name:"Pisa"},69:{code:"PT",name:"Pistoia"},70:{code:"PN",name:"Pordenone"},71:{code:"PZ",name:"Potenza"},72:{code:"PO",name:"Prato"},73:{code:"RG",name:"Ragusa"},74:{code:"RA",name:"Ravenna"},75:{code:"RC",name:"Reggio Calabria"},76:{code:"RE",name:"Reggio Emilia"},77:{code:"RI",name:"Rieti"},78:{code:"RN",name:"Rimini"},79:{code:"RM",name:"Roma"},80:{code:"RO",name:"Rovigo"},81:{code:"SA",name:"Salerno"},82:{code:"SS",name:"Sassari"},83:{code:"SV",name:"Savona"},84:{code:"SI",name:"Siena"},85:{code:"SR",name:"Siracusa"},86:{code:"SO",name:"Sondrio"},87:{code:"TA",name:"Taranto"},88:{code:"TE",name:"Teramo"},89:{code:"TR",name:"Terni"},90:{code:"TO",name:"Torino"},91:{code:"TP",name:"Trapani"},92:{code:"TN",name:"Trento"},93:{code:"TV",name:"Treviso"},94:{code:"TS",name:"Trieste"},95:{code:"UD",name:"Udine"},96:{code:"VA",name:"Varese"},97:{code:"VE",name:"Venezia"},98:{code:"VB",name:"Verbania"},99:{code:"VC",name:"Vercelli"},100:{code:"VR",name:"Verona"},101:{code:"VV",name:"Vibo Valentia"},102:{code:"VI",name:"Vicenza"},103:{code:"VT",name:"Viterbo"},104:{code:"CI",name:"Carbonia-Iglesias"},105:{code:"VS",name:"Medio Campidano"},106:{code:"OG",name:"Ogliastra"},107:{code:"OT",name:"Olbia-Tempio"},108:{code:"MB",name:"Monza e Brianza"},109:{code:"FM",name:"Fermo"},110:{code:"BT",name:"Barletta-Andria-Trani"}},JM:{1:{code:"CLA",name:"Clarendon Parish"},2:{code:"HAN",name:"Hanover Parish"},3:{code:"KIN",name:"Kingston Parish"},4:{code:"MAN",name:"Manchester Parish"},5:{code:"POR",name:"Portland Parish"},6:{code:"AND",name:"Saint Andrew Parish"},7:{code:"ANN",name:"Saint Ann Parish"},8:{code:"CAT",name:"Saint Catherine Parish"},9:{code:"ELI",name:"Saint Elizabeth Parish"},10:{code:"JAM",name:"Saint James Parish"},11:{code:"MAR",name:"Saint Mary Parish"},12:{code:"THO",name:"Saint Thomas Parish"},13:{code:"TRL",name:"Trelawny Parish"},14:{code:"WML",name:"Westmoreland Parish"}},JP:{1:{code:"AI",name:"Aichi"},2:{code:"AK",name:"Akita"},3:{code:"AO",name:"Aomori"},4:{code:"CH",name:"Chiba"},5:{code:"EH",name:"Ehime"},6:{code:"FK",name:"Fukui"},7:{code:"FU",name:"Fukuoka"},8:{code:"FS",name:"Fukushima"},9:{code:"GI",name:"Gifu"},10:{code:"GU",name:"Gumma"},11:{code:"HI",name:"Hiroshima"},12:{code:"HO",name:"Hokkaido"},13:{code:"HY",name:"Hyogo"},14:{code:"IB",name:"Ibaraki"},15:{code:"IS",name:"Ishikawa"},16:{code:"IW",name:"Iwate"},17:{code:"KA",name:"Kagawa"},18:{code:"KG",name:"Kagoshima"},19:{code:"KN",name:"Kanagawa"},20:{code:"KO",name:"Kochi"},21:{code:"KU",name:"Kumamoto"},22:{code:"KY",name:"Kyoto"},23:{code:"MI",name:"Mie"},24:{code:"MY",name:"Miyagi"},25:{code:"MZ",name:"Miyazaki"},26:{code:"NA",name:"Nagano"},27:{code:"NG",name:"Nagasaki"},28:{code:"NR",name:"Nara"},29:{code:"NI",name:"Niigata"},30:{code:"OI",name:"Oita"},31:{code:"OK",name:"Okayama"},32:{code:"ON",name:"Okinawa"},33:{code:"OS",name:"Osaka"},34:{code:"SA",name:"Saga"},35:{code:"SI",name:"Saitama"},36:{code:"SH",name:"Shiga"},37:{code:"SM",name:"Shimane"},38:{code:"SZ",name:"Shizuoka"},39:{code:"TO",name:"Tochigi"},40:{code:"TS",name:"Tokushima"},41:{code:"TK",name:"Tokyo"},42:{code:"TT",name:"Tottori"},43:{code:"TY",name:"Toyama"},44:{code:"WA",name:"Wakayama"},45:{code:"YA",name:"Yamagata"},46:{code:"YM",name:"Yamaguchi"},47:{code:"YN",name:"Yamanashi"}},JO:{1:{code:"AM",name:"'Amman"},2:{code:"AJ",name:"Ajlun"},3:{code:"AA",name:"Al'Aqabah"},4:{code:"AB",name:"Al Balqa'"},5:{code:"AK",name:"Al Karak"},6:{code:"AL",name:"Al Mafraq"},7:{code:"AT",name:"At Tafilah"},8:{code:"AZ",name:"Az Zarqa'"},9:{code:"IR",name:"Irbid"},10:{code:"JA",name:"Jarash"},11:{code:"MA",name:"Ma'an"},12:{code:"MD",name:"Madaba"}},KZ:{1:{code:"AL",name:"Almaty"},2:{code:"AC",name:"Almaty City"},3:{code:"AM",name:"Aqmola"},4:{code:"AQ",name:"Aqtobe"},5:{code:"AS",name:"Astana City"},6:{code:"AT",name:"Atyrau"},7:{code:"BA",name:"Batys Qazaqstan"},8:{code:"BY",name:"Bayqongyr City"},9:{code:"MA",name:"Mangghystau"},10:{code:"ON",name:"Ongtustik Qazaqstan"},11:{code:"PA",name:"Pavlodar"},12:{code:"QA",name:"Qaraghandy"},13:{code:"QO",name:"Qostanay"},14:{code:"QY",name:"Qyzylorda"},15:{code:"SH",name:"Shyghys Qazaqstan"},16:{code:"SO",name:"Soltustik Qazaqstan"},17:{code:"ZH",name:"Zhambyl"}},KE:{1:{code:"CE",name:"Central"},2:{code:"CO",name:"Coast"},3:{code:"EA",name:"Eastern"},4:{code:"NA",name:"Nairobi Area"},5:{code:"NE",name:"North Eastern"},6:{code:"NY",name:"Nyanza"},7:{code:"RV",name:"Rift Valley"},8:{code:"WE",name:"Western"}},KI:{1:{code:"AG",name:"Abaiang"},2:{code:"AM",name:"Abemama"},3:{code:"AK",name:"Aranuka"},4:{code:"AO",name:"Arorae"},5:{code:"BA",name:"Banaba"},6:{code:"BE",name:"Beru"},7:{code:"bT",name:"Butaritari"},8:{code:"KA",name:"Kanton"},9:{code:"KR",name:"Kiritimati"},10:{code:"KU",name:"Kuria"},11:{code:"MI",name:"Maiana"},12:{code:"MN",name:"Makin"},13:{code:"ME",name:"Marakei"},14:{code:"NI",name:"Nikunau"},15:{code:"NO",name:"Nonouti"},16:{code:"ON",name:"Onotoa"},17:{code:"TT",name:"Tabiteuea"},18:{code:"TR",name:"Tabuaeran"},19:{code:"TM",name:"Tamana"},20:{code:"TW",name:"Tarawa"},21:{code:"TE",name:"Teraina"}},KP:{1:{code:"CHA",name:"Chagang-do"},2:{code:"HAB",name:"Hamgyong-bukto"},3:{code:"HAN",name:"Hamgyong-namdo"},4:{code:"HWB",name:"Hwanghae-bukto"},5:{code:"HWN",name:"Hwanghae-namdo"},6:{code:"KAN",name:"Kangwon-do"},7:{code:"PYB",name:"P'yongan-bukto"},8:{code:"PYN",name:"P'yongan-namdo"},9:{code:"YAN",name:"Ryanggang-do (Yanggang-do)"},10:{code:"NAJ",name:"Rason Directly Governed City"},11:{code:"PYO",name:"P'yongyang Special City"}},KR:{1:{code:"CO",name:"Ch'ungch'ong-bukto"},2:{code:"CH",name:"Ch'ungch'ong-namdo"},3:{code:"CD",name:"Cheju-do"},4:{code:"CB",name:"Cholla-bukto"},5:{code:"CN",name:"Cholla-namdo"},6:{code:"IG",name:"Inch'on-gwangyoksi"},7:{code:"KA",name:"Kangwon-do"},8:{code:"KG",name:"Kwangju-gwangyoksi"},9:{code:"KD",name:"Kyonggi-do"},10:{code:"KB",name:"Kyongsang-bukto"},11:{code:"KN",name:"Kyongsang-namdo"},12:{code:"PG",name:"Pusan-gwangyoksi"},13:{code:"SO",name:"Soul-t'ukpyolsi"},14:{code:"TA",name:"Taegu-gwangyoksi"},15:{code:"TG",name:"Taejon-gwangyoksi"}},KW:{1:{code:"AL",name:"Al'Asimah"},2:{code:"AA",name:"Al Ahmadi"},3:{code:"AF",name:"Al Farwaniyah"},4:{code:"AJ",name:"Al Jahra'"},5:{code:"HA",name:"Hawalli"}},KG:{1:{code:"GB",name:"Bishkek"},2:{code:"B",name:"Batken"},3:{code:"C",name:"Chu"},4:{code:"J",name:"Jalal-Abad"},5:{code:"N",name:"Naryn"},6:{code:"O",name:"Osh"},7:{code:"T",name:"Talas"},8:{code:"Y",name:"Ysyk-Kol"}},LA:{1:{code:"VT",name:"Vientiane"},2:{code:"AT",name:"Attapu"},3:{code:"BK",name:"Bokeo"},4:{code:"BL",name:"Bolikhamxai"},5:{code:"CH",name:"Champasak"},6:{code:"HO",name:"Houaphan"},7:{code:"KH",name:"Khammouan"},8:{code:"LM",name:"Louang Namtha"},9:{code:"LP",name:"Louangphabang"},10:{code:"OU",name:"Oudomxai"},11:{code:"PH",name:"Phongsali"},12:{code:"SL",name:"Salavan"},13:{code:"SV",name:"Savannakhet"},14:{code:"VI",name:"Vientiane"},15:{code:"XA",name:"Xaignabouli"},16:{code:"XE",name:"Xekong"},17:{code:"XI",name:"Xiangkhoang"},18:{code:"XN",name:"Xaisomboun"}},LV:{1:{code:"AIZ",name:"Aizkraukles Rajons"},2:{code:"ALU",name:"Aluksnes Rajons"},3:{code:"BAL",name:"Balvu Rajons"},4:{code:"BAU",name:"Bauskas Rajons"},5:{code:"CES",name:"Cesu Rajons"},6:{code:"DGR",name:"Daugavpils Rajons"},7:{code:"DOB",name:"Dobeles Rajons"},8:{code:"GUL",name:"Gulbenes Rajons"},9:{code:"JEK",name:"Jekabpils Rajons"},10:{code:"JGR",name:"Jelgavas Rajons"},11:{code:"KRA",name:"Kraslavas Rajons"},12:{code:"KUL",name:"Kuldigas Rajons"},13:{code:"LPR",name:"Liepajas Rajons"},14:{code:"LIM",name:"Limbazu Rajons"},15:{code:"LUD",name:"Ludzas Rajons"},16:{code:"MAD",name:"Madonas Rajons"},17:{code:"OGR",name:"Ogres Rajons"},18:{code:"PRE",name:"Preilu Rajons"},19:{code:"RZR",name:"Rezeknes Rajons"},20:{code:"RGR",name:"Rigas Rajons"},21:{code:"SAL",name:"Saldus Rajons"},22:{code:"TAL",name:"Talsu Rajons"},23:{code:"TUK",name:"Tukuma Rajons"},24:{code:"VLK",name:"Valkas Rajons"},25:{code:"VLM",name:"Valmieras Rajons"},26:{code:"VSR",name:"Ventspils Rajons"},27:{code:"DGV",name:"Daugavpils"},28:{code:"JGV",name:"Jelgava"},29:{code:"JUR",name:"Jurmala"},30:{code:"LPK",name:"Liepaja"},31:{code:"RZK",name:"Rezekne"},32:{code:"RGA",name:"Riga"},33:{code:"VSL",name:"Ventspils"}},LB:{1:{code:"BIN",name:"Bint Jbeil"},2:{code:"HAS",name:"Hasbaya"},3:{code:"MAR",name:"Marjeyoun"},4:{code:"NAB",name:"Nabatieh"},5:{code:"BAA",name:"Baalbek"},6:{code:"HER",name:"Hermel"},7:{code:"RAS",name:"Rashaya"},8:{code:"WES",name:"Western Beqaa"},9:{code:"ZAH",name:"Zahle"},10:{code:"AKK",name:"Akkar"},11:{code:"BAT",name:"Batroun"},12:{code:"BSH",name:"Bsharri"},13:{code:"KOU",name:"Koura"},14:{code:"MIN",name:"Miniyeh-Danniyeh"},15:{code:"TRI",name:"Tripoli"},16:{code:"ZGH",name:"Zgharta"},17:{code:"ALE",name:"Aley"},18:{code:"BAA",name:"Baabda"},19:{code:"BYB",name:"Byblos"},20:{code:"CHO",name:"Chouf"},21:{code:"KES",name:"Kesrwan"},22:{code:"MAT",name:"Matn"},23:{code:"JEZ",name:"Jezzine"},24:{code:"SID",name:"Sidon"},25:{code:"TYR",name:"Tyre"}},LS:{1:{code:"BE",name:"Berea"},2:{code:"BB",name:"Butha-Buthe"},3:{code:"LE",name:"Leribe"},4:{code:"MF",name:"Mafeteng"},5:{code:"MS",name:"Maseru"},6:{code:"MH",name:"Mohale's Hoek"},7:{code:"MK",name:"Mokhotlong"},8:{code:"QN",name:"Qacha's Nek"},9:{code:"QT",name:"Quthing"},10:{code:"TT",name:"Thaba-Tseka"}},LR:{1:{code:"BI",name:"Bomi"},2:{code:"BG",name:"Bong"},3:{code:"GB",name:"Grand Bassa"},4:{code:"CM",name:"Grand Cape Mount"},5:{code:"GG",name:"Grand Gedeh"},6:{code:"GK",name:"Grand Kru"},7:{code:"LO",name:"Lofa"},8:{code:"MG",name:"Margibi"},9:{code:"ML",name:"Maryland"},10:{code:"MS",name:"Montserrado"},11:{code:"NB",name:"Nimba"},12:{code:"RC",name:"River Cess"},13:{code:"SN",name:"Sinoe"}},LY:{1:{code:"AJ",name:"Ajdabiya"},2:{code:"AZ",name:"Al 'Aziziyah"},3:{code:"FA",name:"Al Fatih"},4:{code:"JA",name:"Al Jabal al Akhdar"},5:{code:"JU",name:"Al Jufrah"},6:{code:"KH",name:"Al Khums"},7:{code:"KU",name:"Al Kufrah"},8:{code:"NK",name:"An Nuqat al Khams"},9:{code:"AS",name:"Ash Shati'"},10:{code:"AW",name:"Awbari"},11:{code:"ZA",name:"Az Zawiyah"},12:{code:"BA",name:"Banghazi"},13:{code:"DA",name:"Darnah"},14:{code:"GD",name:"Ghadamis"},15:{code:"GY",name:"Gharyan"},16:{code:"MI",name:"Misratah"},17:{code:"MZ",name:"Murzuq"},18:{code:"SB",name:"Sabha"},19:{code:"SW",name:"Sawfajjin"},20:{code:"SU",name:"Surt"},21:{code:"TL",name:"Tarabulus (Tripoli)"},22:{code:"TH",name:"Tarhunah"},23:{code:"TU",name:"Tubruq"},24:{code:"YA",name:"Yafran"},25:{code:"ZL",name:"Zlitan"}},LI:{1:{code:"V",name:"Vaduz"},2:{code:"A",name:"Schaan"},3:{code:"B",name:"Balzers"},4:{code:"N",name:"Triesen"},5:{code:"E",name:"Eschen"},6:{code:"M",name:"Mauren"},7:{code:"T",name:"Triesenberg"},8:{code:"R",name:"Ruggell"},9:{code:"G",name:"Gamprin"},10:{code:"L",name:"Schellenberg"},11:{code:"P",name:"Planken"}},LT:{1:{code:"AL",name:"Alytus"},2:{code:"KA",name:"Kaunas"},3:{code:"KL",name:"Klaipeda"},4:{code:"MA",name:"Marijampole"},5:{code:"PA",name:"Panevezys"},6:{code:"SI",name:"Siauliai"},7:{code:"TA",name:"Taurage"},8:{code:"TE",name:"Telsiai"},9:{code:"UT",name:"Utena"},10:{code:"VI",name:"Vilnius"}},LU:{1:{code:"DD",name:"Diekirch"},2:{code:"DC",name:"Clervaux"},3:{code:"DR",name:"Redange"},4:{code:"DV",name:"Vianden"},5:{code:"DW",name:"Wiltz"},6:{code:"GG",name:"Grevenmacher"},7:{code:"GE",name:"Echternach"},8:{code:"GR",name:"Remich"},9:{code:"LL",name:"Luxembourg"},10:{code:"LC",name:"Capellen"},11:{code:"LE",name:"Esch-sur-Alzette"},12:{code:"LM",name:"Mersch"}},MO:{1:{code:"OLF",name:"Our Lady Fatima Parish"},2:{code:"ANT",name:"St. Anthony Parish"},3:{code:"LAZ",name:"St. Lazarus Parish"},4:{code:"CAT",name:"Cathedral Parish"},5:{code:"LAW",name:"St. Lawrence Parish"}},MK:{1:{code:"AER",name:"Aerodrom"},2:{code:"ARA",name:"Aračinovo"},3:{code:"BER",name:"Berovo"},4:{code:"BIT",name:"Bitola"},5:{code:"BOG",name:"Bogdanci"},6:{code:"BOG",name:"Bogovinje"},7:{code:"BOS",name:"Bosilovo"},8:{code:"BRV",name:"Brvenica"},9:{code:"BUT",name:"Butel"},10:{code:"ČAI",name:"Čair"},11:{code:"ČAš",name:"Čaška"},12:{code:"CEN",name:"Centar"},13:{code:"CEN",name:"Centar Župa"},14:{code:"Češ",name:"Češinovo-Obleš"},15:{code:"ČUČ",name:"Čučer-Sandevo"},16:{code:"DEB",name:"Debar"},17:{code:"DEB",name:"Debarca"},18:{code:"DEL",name:"Delčevo"},19:{code:"DEM",name:"Demir Hisar"},20:{code:"DEM",name:"Demir Kapija"},21:{code:"DOL",name:"Dolneni"},22:{code:"DRU",name:"Drugovo"},23:{code:"GAZ",name:"Gazi Baba"},24:{code:"GEV",name:"Gevgelija"},25:{code:"GJO",name:"Gjorče Petrov"},26:{code:"GOS",name:"Gostivar"},27:{code:"GRA",name:"Gradsko"},28:{code:"ILI",name:"Ilinden"},29:{code:"JEG",name:"Jegunovce"},30:{code:"KAR",name:"Karbinci"},31:{code:"KAR",name:"Karpoš"},32:{code:"KAV",name:"Kavadarci"},33:{code:"KIČ",name:"Kičevo"},34:{code:"KIS",name:"Kisela Voda"},35:{code:"KOč",name:"Kočani"},36:{code:"KON",name:"Konče"},37:{code:"KRA",name:"Kratovo"},38:{code:"KRI",name:"Kriva Palanka"},39:{code:"KRI",name:"Krivogaštani"},40:{code:"KRU",name:"Kruševo"},41:{code:"KUM",name:"Kumanovo"},42:{code:"LIP",name:"Lipkovo"},43:{code:"LOZ",name:"Lozovo"},44:{code:"MAK",name:"Makedonska Kamenica"},45:{code:"MAK",name:"Makedonski Brod"},46:{code:"MAV",name:"Mavrovo and Rostuša"},47:{code:"MOG",name:"Mogila"},48:{code:"NEG",name:"Negotino"},49:{code:"NOV",name:"Novaci"},50:{code:"NOV",name:"Novo Selo"},51:{code:"OHR",name:"Ohrid"},52:{code:"OSL",name:"Oslomej"},53:{code:"PEH",name:"Pehčevo"},54:{code:"PET",name:"Petrovec"},55:{code:"PLA",name:"Plasnica"},56:{code:"PRI",name:"Prilep"},57:{code:"PRO",name:"Probištip"},58:{code:"RAD",name:"Radoviš"},59:{code:"RAN",name:"Rankovce"},60:{code:"RES",name:"Resen"},61:{code:"ROS",name:"Rosoman"},62:{code:"SAR",name:"Saraj"},63:{code:"SOP",name:"Sopište"},64:{code:"STA",name:"Star Dojran"},65:{code:"STA",name:"Staro Nagoričane"},66:{code:"ŠTI",name:"Štip"},67:{code:"STR",name:"Struga"},68:{code:"STR",name:"Strumica"},69:{code:"STU",name:"Studeničani"},70:{code:"ŠUT",name:"Šuto Orizari"},71:{code:"SVE",name:"Sveti Nikole"},72:{code:"TEA",name:"Tearce"},73:{code:"TET",name:"Tetovo"},74:{code:"VAL",name:"Valandovo"},75:{code:"VAS",name:"Vasilevo"},76:{code:"VEL",name:"Veles"},77:{code:"VEV",name:"Vevčani"},78:{code:"VIN",name:"Vinica"},79:{code:"VRA",name:"Vraneštica"},80:{code:"VRA",name:"Vrapčište"},81:{code:"ZAJ",name:"Zajas"},82:{code:"ZEL",name:"Zelenikovo"},83:{code:"ŽEL",name:"Želino"},84:{code:"ZRN",name:"Zrnovci"}},MG:{1:{code:"AN",name:"Antananarivo"},2:{code:"AS",name:"Antsiranana"},3:{code:"FN",name:"Fianarantsoa"},4:{code:"MJ",name:"Mahajanga"},5:{code:"TM",name:"Toamasina"},6:{code:"TL",name:"Toliara"}},MW:{1:{code:"BLK",name:"Balaka"},2:{code:"BLT",name:"Blantyre"},3:{code:"CKW",name:"Chikwawa"},4:{code:"CRD",name:"Chiradzulu"},5:{code:"CTP",name:"Chitipa"},6:{code:"DDZ",name:"Dedza"},7:{code:"DWA",name:"Dowa"},8:{code:"KRG",name:"Karonga"},9:{code:"KSG",name:"Kasungu"},10:{code:"LKM",name:"Likoma"},11:{code:"LLG",name:"Lilongwe"},12:{code:"MCG",name:"Machinga"},13:{code:"MGC",name:"Mangochi"},14:{code:"MCH",name:"Mchinji"},15:{code:"MLJ",name:"Mulanje"},16:{code:"MWZ",name:"Mwanza"},17:{code:"MZM",name:"Mzimba"},18:{code:"NTU",name:"Ntcheu"},19:{code:"NKB",name:"Nkhata Bay"},20:{code:"NKH",name:"Nkhotakota"},21:{code:"NSJ",name:"Nsanje"},22:{code:"NTI",name:"Ntchisi"},23:{code:"PHL",name:"Phalombe"},24:{code:"RMP",name:"Rumphi"},25:{code:"SLM",name:"Salima"},26:{code:"THY",name:"Thyolo"},27:{code:"ZBA",name:"Zomba"}},MY:{1:{code:"Johor",name:"Johor"},2:{code:"Kedah",name:"Kedah"},3:{code:"Kelantan",name:"Kelantan"},4:{code:"Labuan",name:"Labuan"},5:{code:"Melaka",name:"Melaka"},6:{code:"Negeri Sembilan",name:"Negeri Sembilan"},7:{code:"Pahang",name:"Pahang"},8:{code:"Perak",name:"Perak"},9:{code:"Perlis",name:"Perlis"},10:{code:"Pulau Pinang",name:"Pulau Pinang"},11:{code:"Sabah",name:"Sabah"},12:{code:"Sarawak",name:"Sarawak"},13:{code:"Selangor",name:"Selangor"},14:{code:"Terengganu",name:"Terengganu"},15:{code:"Kuala Lumpur",name:"Kuala Lumpur"}},MV:{1:{code:"AAD",name:"Ari Atoll Dheknu"},2:{code:"AAU",name:"Ari Atoll Uthuru"},3:{code:"ADD",name:"Addu"},4:{code:"FAA",name:"Faadhippolhu"},5:{code:"FEA",name:"Felidhe Atoll"},6:{code:"FMU",name:"Fua Mulaku"},7:{code:"HAD",name:"Huvadhu Atoll Dhekunu"},8:{code:"HAU",name:"Huvadhu Atoll Uthuru"},9:{code:"HDH",name:"Hadhdhunmathi"},10:{code:"KLH",name:"Kolhumadulu"},11:{code:"MAA",name:"Male Atoll"},12:{code:"MAD",name:"Maalhosmadulu Dhekunu"},13:{code:"MAU",name:"Maalhosmadulu Uthuru"},14:{code:"MLD",name:"Miladhunmadulu Dhekunu"},15:{code:"MLU",name:"Miladhunmadulu Uthuru"},16:{code:"MUA",name:"Mulaku Atoll"},17:{code:"NAD",name:"Nilandhe Atoll Dhekunu"},18:{code:"NAU",name:"Nilandhe Atoll Uthuru"},19:{code:"THD",name:"Thiladhunmathi Dhekunu"},20:{code:"THU",name:"Thiladhunmathi Uthuru"}},ML:{1:{code:"GA",name:"Gao"},2:{code:"KY",name:"Kayes"},3:{code:"KD",name:"Kidal"},4:{code:"KL",name:"Koulikoro"},5:{code:"MP",name:"Mopti"},6:{code:"SG",name:"Segou"},7:{code:"SK",name:"Sikasso"},8:{code:"TB",name:"Tombouctou"},9:{code:"CD",name:"Bamako Capital District"}},MT:{1:{code:"ATT",name:"Attard"},2:{code:"BAL",name:"Balzan"},3:{code:"BGU",name:"Birgu"},4:{code:"BKK",name:"Birkirkara"},5:{code:"BRZ",name:"Birzebbuga"},6:{code:"BOR",name:"Bormla"},7:{code:"DIN",name:"Dingli"},8:{code:"FGU",name:"Fgura"},9:{code:"FLO",name:"Floriana"},10:{code:"GDJ",name:"Gudja"},11:{code:"GZR",name:"Gzira"},12:{code:"GRG",name:"Gargur"},13:{code:"GXQ",name:"Gaxaq"},14:{code:"HMR",name:"Hamrun"},15:{code:"IKL",name:"Iklin"},16:{code:"ISL",name:"Isla"},17:{code:"KLK",name:"Kalkara"},18:{code:"KRK",name:"Kirkop"},19:{code:"LIJ",name:"Lija"},20:{code:"LUQ",name:"Luqa"},21:{code:"MRS",name:"Marsa"},22:{code:"MKL",name:"Marsaskala"},23:{code:"MXL",name:"Marsaxlokk"},24:{code:"MDN",name:"Mdina"},25:{code:"MEL",name:"Melliea"},26:{code:"MGR",name:"Mgarr"},27:{code:"MST",name:"Mosta"},28:{code:"MQA",name:"Mqabba"},29:{code:"MSI",name:"Msida"},30:{code:"MTF",name:"Mtarfa"},31:{code:"NAX",name:"Naxxar"},32:{code:"PAO",name:"Paola"},33:{code:"PEM",name:"Pembroke"},34:{code:"PIE",name:"Pieta"},35:{code:"QOR",name:"Qormi"},36:{code:"QRE",name:"Qrendi"},37:{code:"RAB",name:"Rabat"},38:{code:"SAF",name:"Safi"},39:{code:"SGI",name:"San Giljan"},40:{code:"SLU",name:"Santa Lucija"},41:{code:"SPB",name:"San Pawl il-Bahar"},42:{code:"SGW",name:"San Gwann"},43:{code:"SVE",name:"Santa Venera"},44:{code:"SIG",name:"Siggiewi"},45:{code:"SLM",name:"Sliema"},46:{code:"SWQ",name:"Swieqi"},47:{code:"TXB",name:"Ta Xbiex"},48:{code:"TRX",name:"Tarxien"},49:{code:"VLT",name:"Valletta"},50:{code:"XGJ",name:"Xgajra"},51:{code:"ZBR",name:"Zabbar"},52:{code:"ZBG",name:"Zebbug"},53:{code:"ZJT",name:"Zejtun"},54:{code:"ZRQ",name:"Zurrieq"},55:{code:"FNT",name:"Fontana"},56:{code:"GHJ",name:"Ghajnsielem"},57:{code:"GHR",name:"Gharb"},58:{code:"GHS",name:"Ghasri"},59:{code:"KRC",name:"Kercem"},60:{code:"MUN",name:"Munxar"},61:{code:"NAD",name:"Nadur"},62:{code:"QAL",name:"Qala"},63:{code:"VIC",name:"Victoria"},64:{code:"SLA",name:"San Lawrenz"},65:{code:"SNT",name:"Sannat"},66:{code:"ZAG",name:"Xagra"},67:{code:"XEW",name:"Xewkija"},68:{code:"ZEB",name:"Zebbug"}},MH:{1:{code:"ALG",name:"Ailinginae"},2:{code:"ALL",name:"Ailinglaplap"},3:{code:"ALK",name:"Ailuk"},4:{code:"ARN",name:"Arno"},5:{code:"AUR",name:"Aur"},6:{code:"BKR",name:"Bikar"},7:{code:"BKN",name:"Bikini"},8:{code:"BKK",name:"Bokak"},9:{code:"EBN",name:"Ebon"},10:{code:"ENT",name:"Enewetak"},11:{code:"EKB",name:"Erikub"},12:{code:"JBT",name:"Jabat"},13:{code:"JLT",name:"Jaluit"},14:{code:"JEM",name:"Jemo"},15:{code:"KIL",name:"Kili"},16:{code:"KWJ",name:"Kwajalein"},17:{code:"LAE",name:"Lae"},18:{code:"LIB",name:"Lib"},19:{code:"LKP",name:"Likiep"},20:{code:"MJR",name:"Majuro"},21:{code:"MLP",name:"Maloelap"},22:{code:"MJT",name:"Mejit"},23:{code:"MIL",name:"Mili"},24:{code:"NMK",name:"Namorik"},25:{code:"NAM",name:"Namu"},26:{code:"RGL",name:"Rongelap"},27:{code:"RGK",name:"Rongrik"},28:{code:"TOK",name:"Toke"},29:{code:"UJA",name:"Ujae"},30:{code:"UJL",name:"Ujelang"},31:{code:"UTK",name:"Utirik"},32:{code:"WTH",name:"Wotho"},33:{code:"WTJ",name:"Wotje"}},MQ:{1:{code:"LAJ",name:"L'Ajoupa-Bouillon"},2:{code:"LES",name:"Les Anses-d'Arlet"},3:{code:"BAS",name:"Basse-Pointe"},4:{code:"BEL",name:"Bellefontaine"},5:{code:"LE",name:"Le Carbet"},6:{code:"CAS",name:"Case-Pilote"},7:{code:"LE",name:"Le Diamant"},8:{code:"DUC",name:"Ducos"},9:{code:"FON",name:"Fonds-Saint-Denis"},10:{code:"FOR",name:"Fort-De-France"},11:{code:"LE",name:"Le François"},12:{code:"GRA",name:"Grand'Rivière"},13:{code:"GRO",name:"Gros-Morne"},14:{code:"LE",name:"Le Lamentin"},15:{code:"LE",name:"Le Lorrain"},16:{code:"MAC",name:"Macouba"},17:{code:"LE",name:"Le Marigot"},18:{code:"LE",name:"Le Marin"},19:{code:"LE",name:"Le Morne-Rouge"},20:{code:"LE",name:"Le Morne-Vert"},21:{code:"LE",name:"Le Prêcheur"},22:{code:"RIV",name:"Rivière-Pilote"},23:{code:"RIV",name:"Rivière-Salée"},24:{code:"LE",name:"Le Robert"},25:{code:"SAI",name:"Sainte-Anne"},26:{code:"SAI",name:"Sainte-Luce"},27:{code:"SAI",name:"Sainte-Marie"},28:{code:"SAI",name:"Saint-Esprit"},29:{code:"SAI",name:"Saint-Joseph"},30:{code:"SAI",name:"Saint-Pierre"},31:{code:"SCH",name:"Schœlcher"},32:{code:"LA",name:"La Trinité"},33:{code:"LES",name:"Les Trois-Îlets"},34:{code:"LE",name:"Le Vauclin"}},MR:{1:{code:"AD",name:"Adrar"},2:{code:"AS",name:"Assaba"},3:{code:"BR",name:"Brakna"},4:{code:"DN",name:"Dakhlet Nouadhibou"},5:{code:"GO",name:"Gorgol"},6:{code:"GM",name:"Guidimaka"},7:{code:"HC",name:"Hodh Ech Chargui"},8:{code:"HG",name:"Hodh El Gharbi"},9:{code:"IN",name:"Inchiri"},10:{code:"TA",name:"Tagant"},11:{code:"TZ",name:"Tiris Zemmour"},12:{code:"TR",name:"Trarza"},13:{code:"NO",name:"Nouakchott"}},MU:{1:{code:"AG",name:"Agalega Islands"},2:{code:"BL",name:"Black River"},3:{code:"BR",name:"Beau Bassin-Rose Hill"},4:{code:"CC",name:"Cargados Carajos Shoals (Saint B)"},5:{code:"CU",name:"Curepipe"},6:{code:"FL",name:"Flacq"},7:{code:"GP",name:"Grand Port"},8:{code:"MO",name:"Moka"},9:{code:"PA",name:"Pamplemousses"},10:{code:"PL",name:"Port Louis"},11:{code:"PU",name:"Port Louis"},12:{code:"PW",name:"Plaines Wilhems"},13:{code:"QB",name:"Quatre Bornes"},14:{code:"RO",name:"Rodrigues"},15:{code:"RR",name:"Riviere du Rempart"},16:{code:"SA",name:"Savanne"},17:{code:"VP",name:"Vacoas-Phoenix"}},YT:{1:{code:"DZA",name:"Dzaoudzi"},2:{code:"PAM",name:"Pamandzi"},3:{code:"MAM",name:"Mamoudzou"},4:{code:"DEM",name:"Dembeni"},5:{code:"BAN",name:"Bandrele"},6:{code:"KAN",name:"Kani-Kéli"},7:{code:"BOU",name:"Bouéni"},8:{code:"CHI",name:"Chirongui"},9:{code:"SAD",name:"Sada"},10:{code:"OUA",name:"Ouangani"},11:{code:"CHI",name:"Chiconi"},12:{code:"TSI",name:"Tsingoni"},13:{code:"MTS",name:"M'Tsangamouji"},14:{code:"ACO",name:"Acoua"},15:{code:"MTS",name:"Mtsamboro"},16:{code:"BAN",name:"Bandraboua"},17:{code:"KOU",name:"Koungou"}},MX:{1:{code:"AGU",name:"Aguascalientes"},2:{code:"BCN",name:"Baja California Norte"},3:{code:"BCS",name:"Baja California Sur"},4:{code:"CAM",name:"Campeche"},5:{code:"CHP",name:"Chiapas"},6:{code:"CHH",name:"Chihuahua"},7:{code:"COA",name:"Coahuila de Zaragoza"},8:{code:"COL",name:"Colima"},9:{code:"DIF",name:"Distrito Federal"},10:{code:"DUR",name:"Durango"},11:{code:"GUA",name:"Guanajuato"},12:{code:"GRO",name:"Guerrero"},13:{code:"HID",name:"Hidalgo"},14:{code:"JAL",name:"Jalisco"},15:{code:"MEX",name:"Mexico"},16:{code:"MIC",name:"Michoacan de Ocampo"},17:{code:"MOR",name:"Morelos"},18:{code:"NAY",name:"Nayarit"},19:{code:"NLE",name:"Nuevo Leon"},20:{code:"OAX",name:"Oaxaca"},21:{code:"PUE",name:"Puebla"},22:{code:"QUE",name:"Queretaro de Arteaga"},23:{code:"ROO",name:"Quintana Roo"},24:{code:"SLP",name:"San Luis Potosi"},25:{code:"SIN",name:"Sinaloa"},26:{code:"SON",name:"Sonora"},27:{code:"TAB",name:"Tabasco"},28:{code:"TAM",name:"Tamaulipas"},29:{code:"TLA",name:"Tlaxcala"},30:{code:"VER",name:"Veracruz-Llave"},31:{code:"YUC",name:"Yucatan"},32:{code:"ZAC",name:"Zacatecas"}},FM:{1:{code:"C",name:"Chuuk"},2:{code:"K",name:"Kosrae"},3:{code:"P",name:"Pohnpei"},4:{code:"Y",name:"Yap"}},MD:{1:{code:"GA",name:"Gagauzia"},2:{code:"CU",name:"Chisinau"},3:{code:"BA",name:"Balti"},4:{code:"CA",name:"Cahul"},5:{code:"ED",name:"Edinet"},6:{code:"LA",name:"Lapusna"},7:{code:"OR",name:"Orhei"},8:{code:"SO",name:"Soroca"},9:{code:"TI",name:"Tighina"},10:{code:"UN",name:"Ungheni"},11:{code:"SN",name:"Stânga Nistrului"}},MC:{1:{code:"FV",name:"Fontvieille"},2:{code:"LC",name:"La Condamine"},3:{code:"MV",name:"Monaco-Ville"},4:{code:"MC",name:"Monte-Carlo"}},MN:{1:{code:"1",name:"Ulanbaatar"},2:{code:"035",name:"Orhon"},3:{code:"037",name:"Darhan uul"},4:{code:"039",name:"Hentiy"},5:{code:"041",name:"Hovsgol"},6:{code:"043",name:"Hovd"},7:{code:"046",name:"Uvs"},8:{code:"047",name:"Tov"},9:{code:"049",name:"Selenge"},10:{code:"051",name:"Suhbaatar"},11:{code:"053",name:"Omnogovi"},12:{code:"055",name:"Ovorhangay"},13:{code:"057",name:"Dzavhan"},14:{code:"059",name:"DundgovL"},15:{code:"061",name:"Dornod"},16:{code:"063",name:"Dornogov"},17:{code:"064",name:"Govi-Sumber"},18:{code:"065",name:"Govi-Altay"},19:{code:"067",name:"Bulgan"},20:{code:"069",name:"Bayanhongor"},21:{code:"071",name:"Bayan-Olgiy"},22:{code:"073",name:"Arhangay"}},MS:{1:{code:"A",name:"Saint Anthony"},2:{code:"G",name:"Saint Georges"},3:{code:"P",name:"Saint Peter"}},MA:{1:{code:"AGD",name:"Agadir"},2:{code:"HOC",name:"Al Hoceima"},3:{code:"AZI",name:"Azilal"},4:{code:"BME",name:"Beni Mellal"},5:{code:"BSL",name:"Ben Slimane"},6:{code:"BLM",name:"Boulemane"},7:{code:"CBL",name:"Casablanca"},8:{code:"CHA",name:"Chaouen"},9:{code:"EJA",name:"El Jadida"},10:{code:"EKS",name:"El Kelaa des Sraghna"},11:{code:"ERA",name:"Er Rachidia"},12:{code:"ESS",name:"Essaouira"},13:{code:"FES",name:"Fes"},14:{code:"FIG",name:"Figuig"},15:{code:"GLM",name:"Guelmim"},16:{code:"IFR",name:"Ifrane"},17:{code:"KEN",name:"Kenitra"},18:{code:"KHM",name:"Khemisset"},19:{code:"KHN",name:"Khenifra"},20:{code:"KHO",name:"Khouribga"},21:{code:"LYN",name:"Laayoune"},22:{code:"LAR",name:"Larache"},23:{code:"MRK",name:"Marrakech"},24:{code:"MKN",name:"Meknes"},25:{code:"NAD",name:"Nador"},26:{code:"ORZ",name:"Ouarzazate"},27:{code:"OUJ",name:"Oujda"},28:{code:"RSA",name:"Rabat-Sale"},29:{code:"SAF",name:"Safi"},30:{code:"SET",name:"Settat"},31:{code:"SKA",name:"Sidi Kacem"},32:{code:"TGR",name:"Tangier"},33:{code:"TAN",name:"Tan-Tan"},34:{code:"TAO",name:"Taounate"},35:{code:"TRD",name:"Taroudannt"},36:{code:"TAT",name:"Tata"},37:{code:"TAZ",name:"Taza"},38:{code:"TET",name:"Tetouan"},39:{code:"TIZ",name:"Tiznit"},40:{code:"ADK",name:"Ad Dakhla"},41:{code:"BJD",name:"Boujdour"},42:{code:"ESM",name:"Es Smara"}},MZ:{1:{code:"CD",name:"Cabo Delgado"},2:{code:"GZ",name:"Gaza"},3:{code:"IN",name:"Inhambane"},4:{code:"MN",name:"Manica"},5:{code:"MC",name:"Maputo (city)"},6:{code:"MP",name:"Maputo"},7:{code:"NA",name:"Nampula"},8:{code:"NI",name:"Niassa"},9:{code:"SO",name:"Sofala"},10:{code:"TE",name:"Tete"},11:{code:"ZA",name:"Zambezia"}},MM:{1:{code:"AY",name:"Ayeyarwady"},2:{code:"BG",name:"Bago"},3:{code:"MG",name:"Magway"},4:{code:"MD",name:"Mandalay"},5:{code:"SG",name:"Sagaing"},6:{code:"TN",name:"Tanintharyi"},7:{code:"YG",name:"Yangon"},8:{code:"CH",name:"Chin State"},9:{code:"KC",name:"Kachin State"},10:{code:"KH",name:"Kayah State"},11:{code:"KN",name:"Kayin State"},12:{code:"MN",name:"Mon State"},13:{code:"RK",name:"Rakhine State"},14:{code:"SH",name:"Shan State"}},NA:{1:{code:"CA",name:"Caprivi"},2:{code:"ER",name:"Erongo"},3:{code:"HA",name:"Hardap"},4:{code:"KR",name:"Karas"},5:{code:"KV",name:"Kavango"},6:{code:"KH",name:"Khomas"},7:{code:"KU",name:"Kunene"},8:{code:"OW",name:"Ohangwena"},9:{code:"OK",name:"Omaheke"},10:{code:"OT",name:"Omusati"},11:{code:"ON",name:"Oshana"},12:{code:"OO",name:"Oshikoto"},13:{code:"OJ",name:"Otjozondjupa"}},NR:{1:{code:"AO",name:"Aiwo"},2:{code:"AA",name:"Anabar"},3:{code:"AT",name:"Anetan"},4:{code:"AI",name:"Anibare"},5:{code:"BA",name:"Baiti"},6:{code:"BO",name:"Boe"},7:{code:"BU",name:"Buada"},8:{code:"DE",name:"Denigomodu"},9:{code:"EW",name:"Ewa"},10:{code:"IJ",name:"Ijuw"},11:{code:"ME",name:"Meneng"},12:{code:"NI",name:"Nibok"},13:{code:"UA",name:"Uaboe"},14:{code:"YA",name:"Yaren"}},NP:{1:{code:"BA",name:"Bagmati"},2:{code:"BH",name:"Bheri"},3:{code:"DH",name:"Dhawalagiri"},4:{code:"GA",name:"Gandaki"},5:{code:"JA",name:"Janakpur"},6:{code:"KA",name:"Karnali"},7:{code:"KO",name:"Kosi"},8:{code:"LU",name:"Lumbini"},9:{code:"MA",name:"Mahakali"},10:{code:"ME",name:"Mechi"},11:{code:"NA",name:"Narayani"},12:{code:"RA",name:"Rapti"},13:{code:"SA",name:"Sagarmatha"},14:{code:"SE",name:"Seti"}},NL:{1:{code:"DR",name:"Drenthe"},2:{code:"FL",name:"Flevoland"},3:{code:"FR",name:"Friesland"},4:{code:"GE",name:"Gelderland"},5:{code:"GR",name:"Groningen"},6:{code:"LI",name:"Limburg"},7:{code:"NB",name:"Noord Brabant"},8:{code:"NH",name:"Noord Holland"},9:{code:"OV",name:"Overijssel"},10:{code:"UT",name:"Utrecht"},11:{code:"ZE",name:"Zeeland"},12:{code:"ZH",name:"Zuid Holland"}},AN:{1:{code:"BON",name:"Bonaire"},2:{code:"CUR",name:"Curaçao"},3:{code:"SAB",name:"Saba"},4:{code:"SEU",name:"Sint Eustatius"},5:{code:"SMA",name:"Sint Maarten"}},NC:{1:{code:"L",name:"Iles Loyaute"},2:{code:"N",name:"Nord"},3:{code:"S",name:"Sud"}},NZ:{1:{code:"AUK",name:"Auckland"},2:{code:"BOP",name:"Bay of Plenty"},3:{code:"CAN",name:"Canterbury"},4:{code:"COR",name:"Coromandel"},5:{code:"GIS",name:"Gisborne"},6:{code:"FIO",name:"Fiordland"},7:{code:"HKB",name:"Hawke's Bay"},8:{code:"MBH",name:"Marlborough"},9:{code:"MWT",name:"Manawatu-Wanganui"},10:{code:"MCM",name:"Mt Cook-Mackenzie"},11:{code:"NSN",name:"Nelson"},12:{code:"NTL",name:"Northland"},13:{code:"OTA",name:"Otago"},14:{code:"STL",name:"Southland"},15:{code:"TKI",name:"Taranaki"},16:{code:"WGN",name:"Wellington"},17:{code:"WKO",name:"Waikato"},18:{code:"WAI",name:"Wairprarapa"},19:{code:"WTC",name:"West Coast"}},NI:{1:{code:"AN",name:"Atlantico Norte"},2:{code:"AS",name:"Atlantico Sur"},3:{code:"BO",name:"Boaco"},4:{code:"CA",name:"Carazo"},5:{code:"CI",name:"Chinandega"},6:{code:"CO",name:"Chontales"},7:{code:"ES",name:"Esteli"},8:{code:"GR",name:"Granada"},9:{code:"JI",name:"Jinotega"},10:{code:"LE",name:"Leon"},11:{code:"MD",name:"Madriz"},12:{code:"MN",name:"Managua"},13:{code:"MS",name:"Masaya"},14:{code:"MT",name:"Matagalpa"},15:{code:"NS",name:"Nuevo Segovia"},16:{code:"RS",name:"Rio San Juan"},17:{code:"RI",name:"Rivas"}},NE:{1:{code:"AG",name:"Agadez"},2:{code:"DF",name:"Diffa"},3:{code:"DS",name:"Dosso"},4:{code:"MA",name:"Maradi"},5:{code:"NM",name:"Niamey"},6:{code:"TH",name:"Tahoua"},7:{code:"TL",name:"Tillaberi"},8:{code:"ZD",name:"Zinder"}},NG:{1:{code:"AB",name:"Abia"},2:{code:"CT",name:"Abuja Federal Capital Territory"},3:{code:"AD",name:"Adamawa"},4:{code:"AK",name:"Akwa Ibom"},5:{code:"AN",name:"Anambra"},6:{code:"BC",name:"Bauchi"},7:{code:"BY",name:"Bayelsa"},8:{code:"BN",name:"Benue"},9:{code:"BO",name:"Borno"},10:{code:"CR",name:"Cross River"},11:{code:"DE",name:"Delta"},12:{code:"EB",name:"Ebonyi"},13:{code:"ED",name:"Edo"},14:{code:"EK",name:"Ekiti"},15:{code:"EN",name:"Enugu"},16:{code:"GO",name:"Gombe"},17:{code:"IM",name:"Imo"},18:{code:"JI",name:"Jigawa"},19:{code:"KD",name:"Kaduna"},20:{code:"KN",name:"Kano"},21:{code:"KT",name:"Katsina"},22:{code:"KE",name:"Kebbi"},23:{code:"KO",name:"Kogi"},24:{code:"KW",name:"Kwara"},25:{code:"LA",name:"Lagos"},26:{code:"NA",name:"Nassarawa"},27:{code:"NI",name:"Niger"},28:{code:"OG",name:"Ogun"},29:{code:"ONG",name:"Ondo"},30:{code:"OS",name:"Osun"},31:{code:"OY",name:"Oyo"},32:{code:"PL",name:"Plateau"},33:{code:"RI",name:"Rivers"},34:{code:"SO",name:"Sokoto"},35:{code:"TA",name:"Taraba"},36:{code:"YO",name:"Yobe"},37:{code:"ZA",name:"Zamfara"}},NU:{1:{code:"MAK",name:"Makefu"},2:{code:"TUA",name:"Tuapa"},3:{code:"NAM",name:"Namukulu"},4:{code:"HIK",name:"Hikutavake"},5:{code:"TOI",name:"Toi"},6:{code:"MUT",name:"Mutalau"},7:{code:"LAK",name:"Lakepa"},8:{code:"LIK",name:"Liku"},9:{code:"HAK",name:"Hakupu"},10:{code:"VAI",name:"Vaiea"},11:{code:"AVA",name:"Avatele"},12:{code:"TAM",name:"Tamakautoga"},13:{code:"ALO",name:"Alofi South"},14:{code:"ALO",name:"Alofi North"}},NF:{1:{code:"NOR",name:"Norfolk Island"}},MP:{1:{code:"N",name:"Northern Islands"},2:{code:"R",name:"Rota"},3:{code:"S",name:"Saipan"},4:{code:"T",name:"Tinian"}},NO:{1:{code:"AK",name:"Akershus"},2:{code:"AA",name:"Aust-Agder"},3:{code:"BU",name:"Buskerud"},4:{code:"FM",name:"Finnmark"},5:{code:"HM",name:"Hedmark"},6:{code:"HL",name:"Hordaland"},7:{code:"MR",name:"Møre og Romsdal"},8:{code:"NL",name:"Nordland"},9:{code:"NT",name:"Nord-Trøndelag"},10:{code:"OP",name:"Oppland"},11:{code:"OL",name:"Oslo"},12:{code:"RL",name:"Rogaland"},13:{code:"SJ",name:"Sogn og Fjordane"},14:{code:"ST",name:"Sør-Trøndelag"},15:{code:"SV",name:"Svalbard"},16:{code:"TM",name:"Telemark"},17:{code:"TR",name:"Troms"},18:{code:"VA",name:"Vest-Agder"},19:{code:"VF",name:"Vestfold"},20:{code:"OF",name:"Østfold"}},OM:{1:{code:"DA",name:"Ad Dakhiliyah"},2:{code:"BA",name:"Al Batinah"},3:{code:"WU",name:"Al Wusta"},4:{code:"SH",name:"Ash Sharqiyah"},5:{code:"ZA",name:"Az Zahirah"},6:{code:"MA",name:"Masqat"},7:{code:"MU",name:"Musandam"},8:{code:"ZU",name:"Zufar"}},PK:{1:{code:"B",name:"Balochistan"},2:{code:"T",name:"Federally Administered Tribal Ar"},3:{code:"I",name:"Islamabad Capital Territory"},4:{code:"N",name:"North-West Frontier"},5:{code:"P",name:"Punjab"},6:{code:"S",name:"Sindh"}},PW:{1:{code:"AM",name:"Aimeliik"},2:{code:"AR",name:"Airai"},3:{code:"AN",name:"Angaur"},4:{code:"HA",name:"Hatohobei"},5:{code:"KA",name:"Kayangel"},6:{code:"KO",name:"Koror"},7:{code:"ME",name:"Melekeok"},8:{code:"NA",name:"Ngaraard"},9:{code:"NG",name:"Ngarchelong"},10:{code:"ND",name:"Ngardmau"},11:{code:"NT",name:"Ngatpang"},12:{code:"NC",name:"Ngchesar"},13:{code:"NR",name:"Ngeremlengui"},14:{code:"NW",name:"Ngiwal"},15:{code:"PE",name:"Peleliu"},16:{code:"SO",name:"Sonsorol"}},PA:{1:{code:"BT",name:"Bocas del Toro"},2:{code:"CH",name:"Chiriqui"},3:{code:"CC",name:"Cocle"},4:{code:"CL",name:"Colon"},5:{code:"DA",name:"Darien"},6:{code:"HE",name:"Herrera"},7:{code:"LS",name:"Los Santos"},8:{code:"PA",name:"Panama"},9:{code:"SB",name:"San Blas"},10:{code:"VG",name:"Veraguas"}},PG:{1:{code:"BV",name:"Bougainville"},2:{code:"CE",name:"Central"},3:{code:"CH",name:"Chimbu"},4:{code:"EH",name:"Eastern Highlands"},5:{code:"EB",name:"East New Britain"},6:{code:"ES",name:"East Sepik"},7:{code:"EN",name:"Enga"},8:{code:"GU",name:"Gulf"},9:{code:"MD",name:"Madang"},10:{code:"MN",name:"Manus"},11:{code:"MB",name:"Milne Bay"},12:{code:"MR",name:"Morobe"},13:{code:"NC",name:"National Capital"},14:{code:"NI",name:"New Ireland"},15:{code:"NO",name:"Northern"},16:{code:"SA",name:"Sandaun"},17:{code:"SH",name:"Southern Highlands"},18:{code:"WE",name:"Western"},19:{code:"WH",name:"Western Highlands"},20:{code:"WB",name:"West New Britain"}},PY:{1:{code:"AG",name:"Alto Paraguay"},2:{code:"AN",name:"Alto Parana"},3:{code:"AM",name:"Amambay"},4:{code:"AS",name:"Asuncion"},5:{code:"BO",name:"Boqueron"},6:{code:"CG",name:"Caaguazu"},7:{code:"CZ",name:"Caazapa"},8:{code:"CN",name:"Canindeyu"},9:{code:"CE",name:"Central"},10:{code:"CC",name:"Concepcion"},11:{code:"CD",name:"Cordillera"},12:{code:"GU",name:"Guaira"},13:{code:"IT",name:"Itapua"},14:{code:"MI",name:"Misiones"},15:{code:"NE",name:"Neembucu"},16:{code:"PA",name:"Paraguari"},17:{code:"PH",name:"Presidente Hayes"},18:{code:"SP",name:"San Pedro"}},PE:{1:{code:"AM",name:"Amazonas"},2:{code:"AN",name:"Ancash"},3:{code:"AP",name:"Apurimac"},4:{code:"AR",name:"Arequipa"},5:{code:"AY",name:"Ayacucho"},6:{code:"CJ",name:"Cajamarca"},7:{code:"CL",name:"Callao"},8:{code:"CU",name:"Cusco"},9:{code:"HV",name:"Huancavelica"},10:{code:"HO",name:"Huanuco"},11:{code:"IC",name:"Ica"},12:{code:"JU",name:"Junin"},13:{code:"LD",name:"La Libertad"},14:{code:"LY",name:"Lambayeque"},15:{code:"LI",name:"Lima"},16:{code:"LO",name:"Loreto"},17:{code:"MD",name:"Madre de Dios"},18:{code:"MO",name:"Moquegua"},19:{code:"PA",name:"Pasco"},20:{code:"PI",name:"Piura"},21:{code:"PU",name:"Puno"},22:{code:"SM",name:"San Martin"},23:{code:"TA",name:"Tacna"},24:{code:"TU",name:"Tumbes"},25:{code:"UC",name:"Ucayali"}},PH:{1:{code:"ABR",name:"Abra"},2:{code:"ANO",name:"Agusan del Norte"},3:{code:"ASU",name:"Agusan del Sur"},4:{code:"AKL",name:"Aklan"},5:{code:"ALB",name:"Albay"},6:{code:"ANT",name:"Antique"},7:{code:"APY",name:"Apayao"},8:{code:"AUR",name:"Aurora"},9:{code:"BAS",name:"Basilan"},10:{code:"BTA",name:"Bataan"},11:{code:"BTE",name:"Batanes"},12:{code:"BTG",name:"Batangas"},13:{code:"BLR",name:"Biliran"},14:{code:"BEN",name:"Benguet"},15:{code:"BOL",name:"Bohol"},16:{code:"BUK",name:"Bukidnon"},17:{code:"BUL",name:"Bulacan"},18:{code:"CAG",name:"Cagayan"},19:{code:"CNO",name:"Camarines Norte"},20:{code:"CSU",name:"Camarines Sur"},21:{code:"CAM",name:"Camiguin"},22:{code:"CAP",name:"Capiz"},23:{code:"CAT",name:"Catanduanes"},24:{code:"CAV",name:"Cavite"},25:{code:"CEB",name:"Cebu"},26:{code:"CMP",name:"Compostela"},27:{code:"DNO",name:"Davao del Norte"},28:{code:"DSU",name:"Davao del Sur"},29:{code:"DOR",name:"Davao Oriental"},30:{code:"ESA",name:"Eastern Samar"},31:{code:"GUI",name:"Guimaras"},32:{code:"IFU",name:"Ifugao"},33:{code:"INO",name:"Ilocos Norte"},34:{code:"ISU",name:"Ilocos Sur"},35:{code:"ILO",name:"Iloilo"},36:{code:"ISA",name:"Isabela"},37:{code:"KAL",name:"Kalinga"},38:{code:"LAG",name:"Laguna"},39:{code:"LNO",name:"Lanao del Norte"},40:{code:"LSU",name:"Lanao del Sur"},41:{code:"UNI",name:"La Union"},42:{code:"LEY",name:"Leyte"},43:{code:"MAG",name:"Maguindanao"},44:{code:"MRN",name:"Marinduque"},45:{code:"MSB",name:"Masbate"},46:{code:"MIC",name:"Mindoro Occidental"},47:{code:"MIR",name:"Mindoro Oriental"},48:{code:"MSC",name:"Misamis Occidental"},49:{code:"MOR",name:"Misamis Oriental"},50:{code:"MOP",name:"Mountain"},51:{code:"NOC",name:"Negros Occidental"},52:{code:"NOR",name:"Negros Oriental"},53:{code:"NCT",name:"North Cotabato"},54:{code:"NSM",name:"Northern Samar"},55:{code:"NEC",name:"Nueva Ecija"},56:{code:"NVZ",name:"Nueva Vizcaya"},57:{code:"PLW",name:"Palawan"},58:{code:"PMP",name:"Pampanga"},59:{code:"PNG",name:"Pangasinan"},60:{code:"QZN",name:"Quezon"},61:{code:"QRN",name:"Quirino"},62:{code:"RIZ",name:"Rizal"},63:{code:"ROM",name:"Romblon"},64:{code:"SMR",name:"Samar"},65:{code:"SRG",name:"Sarangani"},66:{code:"SQJ",name:"Siquijor"},67:{code:"SRS",name:"Sorsogon"},68:{code:"SCO",name:"South Cotabato"},69:{code:"SLE",name:"Southern Leyte"},70:{code:"SKU",name:"Sultan Kudarat"},71:{code:"SLU",name:"Sulu"},72:{code:"SNO",name:"Surigao del Norte"},73:{code:"SSU",name:"Surigao del Sur"},74:{code:"TAR",name:"Tarlac"},75:{code:"TAW",name:"Tawi-Tawi"},76:{code:"ZBL",name:"Zambales"},77:{code:"ZNO",name:"Zamboanga del Norte"},78:{code:"ZSU",name:"Zamboanga del Sur"},79:{code:"ZSI",name:"Zamboanga Sibugay"}},PN:{1:{code:"PIT",name:"Pitcairn Island"}},PL:{1:{code:"DO",name:"Dolnośląskie"},2:{code:"KP",name:"Kujawsko-Pomorskie"},3:{code:"LL",name:"Lubelskie"},4:{code:"LU",name:"Lubuskie"},5:{code:"LO",name:"Łódzkie"},6:{code:"ML",name:"Małopolskie"},7:{code:"MZ",name:"Mazowieckie"},8:{code:"OP",name:"Opolskie"},9:{code:"PP",name:"Podkarpackie"},10:{code:"PL",name:"Podlaskie"},11:{code:"PM",name:"Pomorskie"},12:{code:"SL",name:"Śląskie"},13:{code:"SW",name:"Świętokrzyskie"},14:{code:"WM",name:"Warmińsko-Mazurskie"},15:{code:"WP",name:"Wielkopolskie"},16:{code:"ZA",name:"Zachodniopomorskie"}},PT:{1:{code:"AC",name:"Açores"},2:{code:"AV",name:"Aveiro"},3:{code:"BE",name:"Beja"},4:{code:"BR",name:"Braga"},5:{code:"BA",name:"Bragança"},6:{code:"CB",name:"Castelo Branco"},7:{code:"CO",name:"Coimbra"},8:{code:"EV",name:"évora"},9:{code:"FA",name:"Faro"},10:{code:"GU",name:"Guarda"},12:{code:"LE",name:"Leiria"},13:{code:"LI",name:"Lisboa"},14:{code:"ME",name:"Madeira"},15:{code:"PO",name:"Portalegre"},16:{code:"PR",name:"Porto"},17:{code:"SA",name:"Santarém"},18:{code:"SE",name:"SetÚbal"},19:{code:"VC",name:"Viana do Castelo"},20:{code:"VR",name:"Vila Real"},21:{code:"VI",name:"Viseu"}},PR:{1:{code:"A-A",name:"Añasco"},2:{code:"ADJ",name:"Adjuntas"},3:{code:"AGU",name:"Aguada"},4:{code:"AGU",name:"Aguadilla"},5:{code:"AGU",name:"Aguas Buenas"},6:{code:"AIB",name:"Aibonito"},7:{code:"ARE",name:"Arecibo"},8:{code:"ARR",name:"Arroyo"},9:{code:"BAR",name:"Barceloneta"},10:{code:"BAR",name:"Barranquitas"},11:{code:"BAY",name:"Bayamón"},12:{code:"CAB",name:"Cabo Rojo"},13:{code:"CAG",name:"Caguas"},14:{code:"CAM",name:"Camuy"},15:{code:"CAN",name:"Canóvanas"},16:{code:"CAR",name:"Carolina"},17:{code:"CAT",name:"Cataño"},18:{code:"CAY",name:"Cayey"},19:{code:"CEI",name:"Ceiba"},20:{code:"CIA",name:"Ciales"},21:{code:"CID",name:"Cidra"},22:{code:"COA",name:"Coamo"},23:{code:"COM",name:"Comerío"},24:{code:"COR",name:"Corozal"},25:{code:"CUL",name:"Culebra"},26:{code:"DOR",name:"Dorado"},27:{code:"FAJ",name:"Fajardo"},28:{code:"FLO",name:"Florida"},29:{code:"GUA",name:"Guayama"},30:{code:"GUA",name:"Guayanilla"},31:{code:"GUA",name:"Guaynabo"},32:{code:"GUR",name:"Gurabo"},33:{code:"GU¡",name:"Guánica"},34:{code:"HAT",name:"Hatillo"},35:{code:"HOR",name:"Hormigueros"},36:{code:"HUM",name:"Humacao"},37:{code:"ISA",name:"Isabela"},38:{code:"JAY",name:"Jayuya"},39:{code:"JUA",name:"Juana Díaz"},40:{code:"JUN",name:"Juncos"},41:{code:"LAJ",name:"Lajas"},42:{code:"LAR",name:"Lares"},43:{code:"LAS",name:"Las Marías"},44:{code:"LAS",name:"Las Piedras"},45:{code:"LOÕ",name:"Loíza"},46:{code:"LUQ",name:"Luquillo"},47:{code:"MAN",name:"Manatí"},48:{code:"MAR",name:"Maricao"},49:{code:"MAU",name:"Maunabo"},50:{code:"MAY",name:"Mayagüez"},51:{code:"MOC",name:"Moca"},52:{code:"MOR",name:"Morovis"},53:{code:"NAG",name:"Naguabo"},54:{code:"NAR",name:"Naranjito"},55:{code:"ORO",name:"Orocovis"},56:{code:"PAT",name:"Patillas"},57:{code:"PE-",name:"Peñuelas"},58:{code:"PON",name:"Ponce"},59:{code:"QUE",name:"Quebradillas"},60:{code:"RIN",name:"Rincón"},61:{code:"RIO",name:"Rio Grande"},62:{code:"SAB",name:"Sabana Grande"},63:{code:"SAL",name:"Salinas"},64:{code:"SAN",name:"San Germàn"},65:{code:"SAN",name:"San Juan"},66:{code:"SAN",name:"San Lorenzo"},67:{code:"SAN",name:"San Sebastiàn"},68:{code:"SAN",name:"Santa Isabel"},69:{code:"TOA",name:"Toa Alta"},70:{code:"TOA",name:"Toa Baja"},71:{code:"TRU",name:"Trujillo Alto"},72:{code:"UTU",name:"Utuado"},73:{code:"VEG",name:"Vega Alta"},74:{code:"VEG",name:"Vega Baja"},75:{code:"VIE",name:"Vieques"},76:{code:"VIL",name:"Villalba"},77:{code:"YAB",name:"Yabucoa"},78:{code:"YAU",name:"Yauco"}},QA:{1:{code:"DW",name:"Ad Dawhah"},2:{code:"GW",name:"Al Ghuwayriyah"},3:{code:"JM",name:"Al Jumayliyah"},4:{code:"KR",name:"Al Khawr"},5:{code:"WK",name:"Al Wakrah"},6:{code:"RN",name:"Ar Rayyan"},7:{code:"JB",name:"Jarayan al Batinah"},8:{code:"MS",name:"Madinat ash Shamal"},9:{code:"UD",name:"Umm Sa'id"},10:{code:"UL",name:"Umm Salal"}},RO:{1:{code:"AB",name:"Alba"},2:{code:"AR",name:"Arad"},3:{code:"AG",name:"Arges"},4:{code:"BC",name:"Bacau"},5:{code:"BH",name:"Bihor"},6:{code:"BN",name:"Bistrita-Nasaud"},7:{code:"BT",name:"Botosani"},8:{code:"BV",name:"Brasov"},9:{code:"BR",name:"Braila"},10:{code:"B",name:"Bucuresti"},11:{code:"BZ",name:"Buzau"},12:{code:"CS",name:"Caras-Severin"},13:{code:"CL",name:"Calarasi"},14:{code:"CJ",name:"Cluj"},15:{code:"CT",name:"Constanta"},16:{code:"CV",name:"Covasna"},17:{code:"DB",name:"Dimbovita"},18:{code:"DJ",name:"Dolj"},19:{code:"GL",name:"Galati"},20:{code:"GR",name:"Giurgiu"},21:{code:"GJ",name:"Gorj"},22:{code:"HR",name:"Harghita"},23:{code:"HD",name:"Hunedoara"},24:{code:"IL",name:"Ialomita"},25:{code:"IS",name:"Iasi"},26:{code:"IF",name:"Ilfov"},27:{code:"MM",name:"Maramures"},28:{code:"MH",name:"Mehedinti"},29:{code:"MS",name:"Mures"},30:{code:"NT",name:"Neamt"},31:{code:"OT",name:"Olt"},32:{code:"PH",name:"Prahova"},33:{code:"SM",name:"Satu-Mare"},34:{code:"SJ",name:"Salaj"},35:{code:"SB",name:"Sibiu"},36:{code:"SV",name:"Suceava"},37:{code:"TR",name:"Teleorman"},38:{code:"TM",name:"Timis"},39:{code:"TL",name:"Tulcea"},40:{code:"VS",name:"Vaslui"},41:{code:"VL",name:"Valcea"},42:{code:"VN",name:"Vrancea"}},RU:{1:{code:"AB",name:"Abakan"},2:{code:"AG",name:"Aginskoye"},3:{code:"AN",name:"Anadyr"},4:{code:"AR",name:"Arkahangelsk"},5:{code:"AS",name:"Astrakhan"},6:{code:"BA",name:"Barnaul"},7:{code:"BE",name:"Belgorod"},8:{code:"BI",name:"Birobidzhan"},9:{code:"BL",name:"Blagoveshchensk"},10:{code:"BR",name:"Bryansk"},11:{code:"CH",name:"Cheboksary"},12:{code:"CL",name:"Chelyabinsk"},13:{code:"CR",name:"Cherkessk"},14:{code:"CI",name:"Chita"},15:{code:"DU",name:"Dudinka"},16:{code:"EL",name:"Elista"},17:{code:"GO",name:"Gomo-Altaysk"},18:{code:"GA",name:"Gorno-Altaysk"},19:{code:"GR",name:"Groznyy"},20:{code:"IR",name:"Irkutsk"},21:{code:"IV",name:"Ivanovo"},22:{code:"IZ",name:"Izhevsk"},23:{code:"KA",name:"Kalinigrad"},24:{code:"KL",name:"Kaluga"},25:{code:"KS",name:"Kasnodar"},26:{code:"KZ",name:"Kazan"},27:{code:"KE",name:"Kemerovo"},28:{code:"KH",name:"Khabarovsk"},29:{code:"KM",name:"Khanty-Mansiysk"},30:{code:"KO",name:"Kostroma"},31:{code:"KR",name:"Krasnodar"},32:{code:"KN",name:"Krasnoyarsk"},33:{code:"KU",name:"Kudymkar"},34:{code:"KG",name:"Kurgan"},35:{code:"KK",name:"Kursk"},36:{code:"KY",name:"Kyzyl"},37:{code:"LI",name:"Lipetsk"},38:{code:"MA",name:"Magadan"},39:{code:"MK",name:"Makhachkala"},40:{code:"MY",name:"Maykop"},41:{code:"MO",name:"Moscow"},42:{code:"MU",name:"Murmansk"},43:{code:"NA",name:"Nalchik"},44:{code:"NR",name:"Naryan Mar"},45:{code:"NZ",name:"Nazran"},46:{code:"NI",name:"Nizhniy Novgorod"},47:{code:"NO",name:"Novgorod"},48:{code:"NV",name:"Novosibirsk"},49:{code:"OM",name:"Omsk"},50:{code:"OR",name:"Orel"},51:{code:"OE",name:"Orenburg"},52:{code:"PA",name:"Palana"},53:{code:"PE",name:"Penza"},54:{code:"PR",name:"Perm"},55:{code:"PK",name:"Petropavlovsk-Kamchatskiy"},56:{code:"PT",name:"Petrozavodsk"},57:{code:"PS",name:"Pskov"},58:{code:"RO",name:"Rostov-na-Donu"},59:{code:"RY",name:"Ryazan"},60:{code:"SL",name:"Salekhard"},61:{code:"SA",name:"Samara"},62:{code:"SR",name:"Saransk"},63:{code:"SV",name:"Saratov"},64:{code:"SM",name:"Smolensk"},65:{code:"SP",name:"St. Petersburg"},66:{code:"ST",name:"Stavropol"},67:{code:"SY",name:"Syktyvkar"},68:{code:"TA",name:"Tambov"},69:{code:"TO",name:"Tomsk"},70:{code:"TU",name:"Tula"},71:{code:"TR",name:"Tura"},72:{code:"TV",name:"Tver"},73:{code:"TY",name:"Tyumen"},74:{code:"UF",name:"Ufa"},75:{code:"UL",name:"Ul'yanovsk"},76:{code:"UU",name:"Ulan-Ude"},77:{code:"US",name:"Ust'-Ordynskiy"},78:{code:"VL",name:"Vladikavkaz"},79:{code:"VA",name:"Vladimir"},80:{code:"VV",name:"Vladivostok"},81:{code:"VG",name:"Volgograd"},82:{code:"VD",name:"Vologda"},83:{code:"VO",name:"Voronezh"},84:{code:"VY",name:"Vyatka"},85:{code:"YA",name:"Yakutsk"},86:{code:"YR",name:"Yaroslavl"},87:{code:"YE",name:"Yekaterinburg"},88:{code:"YO",name:"Yoshkar-Ola"}},RW:{1:{code:"BU",name:"Butare"},2:{code:"BY",name:"Byumba"},3:{code:"CY",name:"Cyangugu"},4:{code:"GK",name:"Gikongoro"},5:{code:"GS",name:"Gisenyi"},6:{code:"GT",name:"Gitarama"},7:{code:"KG",name:"Kibungo"},8:{code:"KY",name:"Kibuye"},9:{code:"KR",name:"Kigali Rurale"},10:{code:"KV",name:"Kigali-ville"},11:{code:"RU",name:"Ruhengeri"},12:{code:"UM",name:"Umutara"}},KN:{1:{code:"CCN",name:"Christ Church Nichola Town"},2:{code:"SAS",name:"Saint Anne Sandy Point"},3:{code:"SGB",name:"Saint George Basseterre"},4:{code:"SGG",name:"Saint George Gingerland"},5:{code:"SJW",name:"Saint James Windward"},6:{code:"SJC",name:"Saint John Capesterre"},7:{code:"SJF",name:"Saint John Figtree"},8:{code:"SMC",name:"Saint Mary Cayon"},9:{code:"CAP",name:"Saint Paul Capesterre"},10:{code:"CHA",name:"Saint Paul Charlestown"},11:{code:"SPB",name:"Saint Peter Basseterre"},12:{code:"STL",name:"Saint Thomas Lowland"},13:{code:"STM",name:"Saint Thomas Middle Island"},14:{code:"TPP",name:"Trinity Palmetto Point"}},LC:{1:{code:"AR",name:"Anse-la-Raye"},2:{code:"CA",name:"Castries"},3:{code:"CH",name:"Choiseul"},4:{code:"DA",name:"Dauphin"},5:{code:"DE",name:"Dennery"},6:{code:"GI",name:"Gros-Islet"},7:{code:"LA",name:"Laborie"},8:{code:"MI",name:"Micoud"},9:{code:"PR",name:"Praslin"},10:{code:"SO",name:"Soufriere"},11:{code:"VF",name:"Vieux-Fort"}},VC:{1:{code:"C",name:"Charlotte"},2:{code:"R",name:"Grenadines"},3:{code:"A",name:"Saint Andrew"},4:{code:"D",name:"Saint David"},5:{code:"G",name:"Saint George"},6:{code:"P",name:"Saint Patrick"}},WS:{1:{code:"AN",name:"A'ana"},2:{code:"AI",name:"Aiga-i-le-Tai"},3:{code:"AT",name:"Atua"},4:{code:"FA",name:"Fa'asaleleaga"},5:{code:"GE",name:"Gaga'emauga"},6:{code:"GF",name:"Gagaifomauga"},7:{code:"PA",name:"Palauli"},8:{code:"SA",name:"Satupa'itea"},9:{code:"TU",name:"Tuamasaga"},10:{code:"VF",name:"Va'a-o-Fonoti"},11:{code:"VS",name:"Vaisigano"}},SM:{1:{code:"AC",name:"Acquaviva"},2:{code:"BM",name:"Borgo Maggiore"},3:{code:"CH",name:"Chiesanuova"},4:{code:"DO",name:"Domagnano"},5:{code:"FA",name:"Faetano"},6:{code:"FI",name:"Fiorentino"},7:{code:"MO",name:"Montegiardino"},8:{code:"SM",name:"Citta di San Marino"},9:{code:"SE",name:"Serravalle"}},ST:{1:{code:"S",name:"Sao Tome"},2:{code:"P",name:"Principe"}},SA:{1:{code:"BH",name:"Al Bahah"},2:{code:"HS",name:"Al Hudud ash Shamaliyah"},3:{code:"JF",name:"Al Jawf"},4:{code:"MD",name:"Al Madinah"},5:{code:"QS",name:"Al Qasim"},6:{code:"RD",name:"Ar Riyad"},7:{code:"AQ",name:"Ash Sharqiyah (Eastern)"},8:{code:"AS",name:"'Asir"},9:{code:"HL",name:"Ha'il"},10:{code:"JZ",name:"Jizan"},11:{code:"ML",name:"Makkah"},12:{code:"NR",name:"Najran"},13:{code:"TB",name:"Tabuk"}},SN:{1:{code:"DA",name:"Dakar"},2:{code:"DI",name:"Diourbel"},3:{code:"FA",name:"Fatick"},4:{code:"KA",name:"Kaolack"},5:{code:"KO",name:"Kolda"},6:{code:"LO",name:"Louga"},7:{code:"MA",name:"Matam"},8:{code:"SL",name:"Saint-Louis"},9:{code:"TA",name:"Tambacounda"},10:{code:"TH",name:"Thies"},11:{code:"ZI",name:"Ziguinchor"}},SC:{1:{code:"AP",name:"Anse aux Pins"},2:{code:"AB",name:"Anse Boileau"},3:{code:"AE",name:"Anse Etoile"},4:{code:"AL",name:"Anse Louis"},5:{code:"AR",name:"Anse Royale"},6:{code:"BL",name:"Baie Lazare"},7:{code:"BS",name:"Baie Sainte Anne"},8:{code:"BV",name:"Beau Vallon"},9:{code:"BA",name:"Bel Air"},10:{code:"BO",name:"Bel Ombre"},11:{code:"CA",name:"Cascade"},12:{code:"GL",name:"Glacis"},13:{code:"GM",name:"Grand' Anse (on Mahe)"},14:{code:"GP",name:"Grand' Anse (on Praslin)"},15:{code:"DG",name:"La Digue"},16:{code:"RA",name:"La Riviere Anglaise"},17:{code:"MB",name:"Mont Buxton"},18:{code:"MF",name:"Mont Fleuri"},19:{code:"PL",name:"Plaisance"},20:{code:"PR",name:"Pointe La Rue"},21:{code:"PG",name:"Port Glaud"},22:{code:"SL",name:"Saint Louis"},23:{code:"TA",name:"Takamaka"}},SL:{1:{code:"E",name:"Eastern"},2:{code:"N",name:"Northern"},3:{code:"S",name:"Southern"},4:{code:"W",name:"Western"}},SK:{1:{code:"BA",name:"Banskobystricky"},2:{code:"BR",name:"Bratislavsky"},3:{code:"KO",name:"Kosicky"},4:{code:"NI",name:"Nitriansky"},5:{code:"PR",name:"Presovsky"},6:{code:"TC",name:"Trenciansky"},7:{code:"TV",name:"Trnavsky"},8:{code:"ZI",name:"Zilinsky"}},SI:{1:{code:"4",name:"Štajerska"},2:{code:"2A",name:"Gorenjska"},3:{code:"5",name:"Prekmurje"},4:{code:"3",name:"Koroška"},5:{code:"2B",name:"Notranjska"},6:{code:"1",name:"Primorska"},7:{code:"2C",name:"Dolenjska"},8:{code:"2C",name:"Bela Krajina"}},SB:{1:{code:"CE",name:"Central"},2:{code:"CH",name:"Choiseul"},3:{code:"GC",name:"Guadalcanal"},4:{code:"HO",name:"Honiara"},5:{code:"IS",name:"Isabel"},6:{code:"MK",name:"Makira"},7:{code:"ML",name:"Malaita"},8:{code:"RB",name:"Rennell and Bellona"},9:{code:"TM",name:"Temotu"},10:{code:"WE",name:"Western"}},SO:{1:{code:"AW",name:"Awdal"},2:{code:"BK",name:"Bakool"},3:{code:"BN",name:"Banaadir"},4:{code:"BR",name:"Bari"},5:{code:"BY",name:"Bay"},6:{code:"GA",name:"Galguduud"},7:{code:"GE",name:"Gedo"},8:{code:"HI",name:"Hiiraan"},9:{code:"JD",name:"Jubbada Dhexe"},10:{code:"JH",name:"Jubbada Hoose"},11:{code:"MU",name:"Mudug"},12:{code:"NU",name:"Nugaal"},13:{code:"SA",name:"Sanaag"},14:{code:"SD",name:"Shabeellaha Dhexe"},15:{code:"SH",name:"Shabeellaha Hoose"},16:{code:"SL",name:"Sool"},17:{code:"TO",name:"Togdheer"},18:{code:"WG",name:"Woqooyi Galbeed"}},ZA:{1:{code:"EC",name:"Eastern Cape"},2:{code:"FS",name:"Free State"},3:{code:"GT",name:"Gauteng"},4:{code:"KN",name:"KwaZulu-Natal"},5:{code:"LP",name:"Limpopo"},6:{code:"MP",name:"Mpumalanga"},7:{code:"NW",name:"North West"},8:{code:"NC",name:"Northern Cape"},9:{code:"WC",name:"Western Cape"}},ES:{1:{code:"CA",name:"La Coruña"},2:{code:"AL",name:"Álava"},3:{code:"AB",name:"Albacete"},4:{code:"AC",name:"Alicante"},5:{code:"AM",name:"Almeria"},6:{code:"AS",name:"Asturias"},7:{code:"AV",name:"Ávila"},8:{code:"BJ",name:"Badajoz"},9:{code:"IB",name:"Baleares"},10:{code:"BA",name:"Barcelona"},11:{code:"BU",name:"Burgos"},12:{code:"CC",name:"Cáceres"},13:{code:"CZ",name:"Cádiz"},14:{code:"CT",name:"Cantabria"},15:{code:"CL",name:"Castellón"},16:{code:"CE",name:"Ceuta"},17:{code:"CR",name:"Ciudad Real"},18:{code:"CD",name:"Córdoba"},19:{code:"CU",name:"Cuenca"},20:{code:"GI",name:"Gerona"},21:{code:"GD",name:"Granada"},22:{code:"GJ",name:"Guadalajara"},23:{code:"GP",name:"Guipúzcoa"},24:{code:"HL",name:"Huelva"},25:{code:"HS",name:"Huesca"},26:{code:"JN",name:"Jaén"},27:{code:"RJ",name:"La Rioja"},28:{code:"PM",name:"Las Palmas"},29:{code:"LE",name:"León"},30:{code:"LL",name:"Lérida"},31:{code:"LG",name:"Lugo"},32:{code:"MD",name:"Madrid"},33:{code:"MA",name:"Málaga"},34:{code:"ML",name:"Melilla"},35:{code:"MU",name:"Murcia"},36:{code:"NV",name:"Navarra"},37:{code:"OU",name:"Ourense"},38:{code:"PL",name:"Palencia"},39:{code:"PO",name:"Pontevedra"},40:{code:"SL",name:"Salamanca"},41:{code:"SC",name:"Santa Cruz de Tenerife"},42:{code:"SG",name:"Segovia"},43:{code:"SV",name:"Sevilla"},44:{code:"SO",name:"Soria"},45:{code:"TA",name:"Tarragona"},46:{code:"TE",name:"Teruel"},47:{code:"TO",name:"Toledo"},48:{code:"VC",name:"Valencia"},49:{code:"VD",name:"Valladolid"},50:{code:"VZ",name:"Vizcaya"},51:{code:"ZM",name:"Zamora"},52:{code:"ZR",name:"Zaragoza"}},LK:{1:{code:"CE",name:"Central"},2:{code:"EA",name:"Eastern"},3:{code:"NC",name:"North Central"},4:{code:"NO",name:"Northern"},5:{code:"NW",name:"North Western"},6:{code:"SA",name:"Sabaragamuwa"},7:{code:"SO",name:"Southern"},8:{code:"UV",name:"Uva"},9:{code:"WE",name:"Western"}},SH:{1:{code:"A",name:"Ascension"},2:{code:"S",name:"Saint Helena"},3:{code:"T",name:"Tristan da Cunha"}},PM:{1:{code:"P",name:"Saint Pierre"},2:{code:"M",name:"Miquelon"}},SD:{1:{code:"ANL",name:"A'ali an Nil"},2:{code:"BAM",name:"Al Bahr al Ahmar"},3:{code:"BRT",name:"Al Buhayrat"},4:{code:"JZR",name:"Al Jazirah"},5:{code:"KRT",name:"Al Khartum"},6:{code:"QDR",name:"Al Qadarif"},7:{code:"WDH",name:"Al Wahdah"},8:{code:"ANB",name:"An Nil al Abyad"},9:{code:"ANZ",name:"An Nil al Azraq"},10:{code:"ASH",name:"Ash Shamaliyah"},11:{code:"BJA",name:"Bahr al Jabal"},12:{code:"GIS",name:"Gharb al Istiwa'iyah"},13:{code:"GBG",name:"Gharb Bahr al Ghazal"},14:{code:"GDA",name:"Gharb Darfur"},15:{code:"GKU",name:"Gharb Kurdufan"},16:{code:"JDA",name:"Janub Darfur"},17:{code:"JKU",name:"Janub Kurdufan"},18:{code:"JQL",name:"Junqali"},19:{code:"KSL",name:"Kassala"},20:{code:"NNL",name:"Nahr an Nil"},21:{code:"SBG",name:"Shamal Bahr al Ghazal"},22:{code:"SDA",name:"Shamal Darfur"},23:{code:"SKU",name:"Shamal Kurdufan"},24:{code:"SIS",name:"Sharq al Istiwa'iyah"},25:{code:"SNR",name:"Sinnar"},26:{code:"WRB",name:"Warab"}},SR:{1:{code:"BR",name:"Brokopondo"},2:{code:"CM",name:"Commewijne"},3:{code:"CR",name:"Coronie"},4:{code:"MA",name:"Marowijne"},5:{code:"NI",name:"Nickerie"},6:{code:"PA",name:"Para"},7:{code:"PM",name:"Paramaribo"},9:{code:"SA",name:"Saramacca"},10:{code:"SI",name:"Sipaliwini"},11:{code:"WA",name:"Wanica"}},SZ:{1:{code:"H",name:"Hhohho"},2:{code:"L",name:"Lubombo"},3:{code:"M",name:"Manzini"},4:{code:"S",name:"Shishelweni"}},SE:{1:{code:"K",name:"Blekinge"},2:{code:"W",name:"Dalama"},3:{code:"I",name:"Gotland"},4:{code:"X",name:"Gävleborg"},5:{code:"N",name:"Halland"},6:{code:"Z",name:"Jämtland"},7:{code:"F",name:"Jönköping"},8:{code:"H",name:"Kalmar"},9:{code:"G",name:"Kronoberg"},10:{code:"BD",name:"Norrbotten"},11:{code:"M",name:"Skåne"},12:{code:"AB",name:"Stockholm"},13:{code:"D",name:"Södermanland"},14:{code:"C",name:"Uppsala"},15:{code:"S",name:"Värmland"},16:{code:"AC",name:"Västerbotten"},17:{code:"Y",name:"Västernorrland"},18:{code:"U",name:"Västmanland"},19:{code:"O",name:"Västra Götaland"},20:{code:"T",name:"Örebro"},21:{code:"E",name:"Östergötland"}},CH:{1:{code:"AG",name:"Aargau"},2:{code:"AR",name:"Appenzell Ausserrhoden"},3:{code:"AI",name:"Appenzell Innerrhoden"},4:{code:"BS",name:"Basel-Stadt"},5:{code:"BL",name:"Basel-Landschaft"},6:{code:"BE",name:"Bern"},7:{code:"FR",name:"Fribourg"},8:{code:"GE",name:"Genève"},9:{code:"GL",name:"Glarus"},10:{code:"GR",name:"Graubünden"},11:{code:"JU",name:"Jura"},12:{code:"LU",name:"Lucerne"},13:{code:"NE",name:"Neuchâtel"},14:{code:"NW",name:"Nidwalden"},15:{code:"OW",name:"Obwalden"},16:{code:"SG",name:"St. Gallen"},17:{code:"SH",name:"Schaffhausen"},18:{code:"SZ",name:"Schwyz"},19:{code:"SO",name:"Solothurn"},20:{code:"TG",name:"Thurgau"},21:{code:"TI",name:"Ticino"},22:{code:"UR",name:"Uri"},23:{code:"VS",name:"Valais"},24:{code:"VD",name:"Vaud"},25:{code:"ZG",name:"Zug"},26:{code:"ZH",name:"Zürich"}},SY:{1:{code:"HA",name:"Al Hasakah"},2:{code:"LA",name:"Al Ladhiqiyah"},3:{code:"QU",name:"Al Qunaytirah"},4:{code:"RQ",name:"Ar Raqqah"},5:{code:"SU",name:"As Suwayda"},6:{code:"DA",name:"Dara"},7:{code:"DZ",name:"Dayr az Zawr"},8:{code:"DI",name:"Dimashq"},9:{code:"HL",name:"Halab"},10:{code:"HM",name:"Hamah"},11:{code:"HI",name:"Hims"},12:{code:"ID",name:"Idlib"},13:{code:"RD",name:"Rif Dimashq"},14:{code:"TA",name:"Tartus"}},TW:{1:{code:"CH",name:"Chang-hua"},2:{code:"CI",name:"Chia-i"},3:{code:"HS",name:"Hsin-chu"},4:{code:"HL",name:"Hua-lien"},5:{code:"IL",name:"I-lan"},6:{code:"KH",name:"Kao-hsiung county"},7:{code:"KM",name:"Kin-men"},8:{code:"LC",name:"Lien-chiang"},9:{code:"ML",name:"Miao-li"},10:{code:"NT",name:"Nan-t'ou"},11:{code:"PH",name:"P'eng-hu"},12:{code:"PT",name:"P'ing-tung"},13:{code:"TG",name:"T'ai-chung"},14:{code:"TA",name:"T'ai-nan"},15:{code:"TP",name:"T'ai-pei county"},16:{code:"TT",name:"T'ai-tung"},17:{code:"TY",name:"T'ao-yuan"},18:{code:"YL",name:"Yun-lin"},19:{code:"CC",name:"Chia-i city"},20:{code:"CL",name:"Chi-lung"},21:{code:"HC",name:"Hsin-chu"},22:{code:"TH",name:"T'ai-chung"},23:{code:"TN",name:"T'ai-nan"},24:{code:"KC",name:"Kao-hsiung city"},25:{code:"TC",name:"T'ai-pei city"}},TJ:{1:{code:"GB",name:"Gorno-Badakhstan"},2:{code:"KT",name:"Khatlon"},3:{code:"SU",name:"Sughd"}},TZ:{1:{code:"AR",name:"Arusha"},2:{code:"DS",name:"Dar es Salaam"},3:{code:"DO",name:"Dodoma"},4:{code:"IR",name:"Iringa"},5:{code:"KA",name:"Kagera"},6:{code:"KI",name:"Kigoma"},7:{code:"KJ",name:"Kilimanjaro"},8:{code:"LN",name:"Lindi"},9:{code:"MY",name:"Manyara"},10:{code:"MR",name:"Mara"},11:{code:"MB",name:"Mbeya"},12:{code:"MO",name:"Morogoro"},13:{code:"MT",name:"Mtwara"},14:{code:"MW",name:"Mwanza"},15:{code:"PN",name:"Pemba North"},16:{code:"PS",name:"Pemba South"},17:{code:"PW",name:"Pwani"},18:{code:"RK",name:"Rukwa"},19:{code:"RV",name:"Ruvuma"},20:{code:"SH",name:"Shinyanga"},21:{code:"SI",name:"Singida"},22:{code:"TB",name:"Tabora"},23:{code:"TN",name:"Tanga"},24:{code:"ZC",name:"Zanzibar Central/South"},25:{code:"ZN",name:"Zanzibar North"},26:{code:"ZU",name:"Zanzibar Urban/West"}},TH:{1:{code:"Amnat Charoen",name:"Amnat Charoen"},2:{code:"Ang Thong",name:"Ang Thong"},3:{code:"Ayutthaya",name:"Ayutthaya"},4:{code:"Bangkok",name:"Bangkok"},5:{code:"Buriram",name:"Buriram"},6:{code:"Chachoengsao",name:"Chachoengsao"},7:{code:"Chai Nat",name:"Chai Nat"},8:{code:"Chaiyaphum",name:"Chaiyaphum"},9:{code:"Chanthaburi",name:"Chanthaburi"},10:{code:"Chiang Mai",name:"Chiang Mai"},11:{code:"Chiang Rai",name:"Chiang Rai"},12:{code:"Chon Buri",name:"Chon Buri"},13:{code:"Chumphon",name:"Chumphon"},14:{code:"Kalasin",name:"Kalasin"},15:{code:"Kamphaeng Phet",name:"Kamphaeng Phet"},16:{code:"Kanchanaburi",name:"Kanchanaburi"},17:{code:"Khon Kaen",name:"Khon Kaen"},18:{code:"Krabi",name:"Krabi"},19:{code:"Lampang",name:"Lampang"},20:{code:"Lamphun",name:"Lamphun"},21:{code:"Loei",name:"Loei"},22:{code:"Lop Buri",name:"Lop Buri"},23:{code:"Mae Hong Son",name:"Mae Hong Son"},24:{code:"Maha Sarakham",name:"Maha Sarakham"},25:{code:"Mukdahan",name:"Mukdahan"},26:{code:"Nakhon Nayok",name:"Nakhon Nayok"},27:{code:"Nakhon Pathom",name:"Nakhon Pathom"},28:{code:"Nakhon Phanom",name:"Nakhon Phanom"},29:{code:"Nakhon Ratchasima",name:"Nakhon Ratchasima"},30:{code:"Nakhon Sawan",name:"Nakhon Sawan"},31:{code:"Nakhon Si Thammarat",name:"Nakhon Si Thammarat"},32:{code:"Nan",name:"Nan"},33:{code:"Narathiwat",name:"Narathiwat"},34:{code:"Nong Bua Lamphu",name:"Nong Bua Lamphu"},35:{code:"Nong Khai",name:"Nong Khai"},36:{code:"Nonthaburi",name:"Nonthaburi"},37:{code:"Pathum Thani",name:"Pathum Thani"},38:{code:"Pattani",name:"Pattani"},39:{code:"Phangnga",name:"Phangnga"},40:{code:"Phatthalung",name:"Phatthalung"},41:{code:"Phayao",name:"Phayao"},42:{code:"Phetchabun",name:"Phetchabun"},43:{code:"Phetchaburi",name:"Phetchaburi"},44:{code:"Phichit",name:"Phichit"},45:{code:"Phitsanulok",name:"Phitsanulok"},46:{code:"Phrae",name:"Phrae"},47:{code:"Phuket",name:"Phuket"},48:{code:"Prachin Buri",name:"Prachin Buri"},49:{code:"Prachuap Khiri Khan",name:"Prachuap Khiri Khan"},50:{code:"Ranong",name:"Ranong"},51:{code:"Ratchaburi",name:"Ratchaburi"},52:{code:"Rayong",name:"Rayong"},53:{code:"Roi Et",name:"Roi Et"},54:{code:"Sa Kaeo",name:"Sa Kaeo"},55:{code:"Sakon Nakhon",name:"Sakon Nakhon"},56:{code:"Samut Prakan",name:"Samut Prakan"},57:{code:"Samut Sakhon",name:"Samut Sakhon"},58:{code:"Samut Songkhram",name:"Samut Songkhram"},59:{code:"Sara Buri",name:"Sara Buri"},60:{code:"Satun",name:"Satun"},61:{code:"Sing Buri",name:"Sing Buri"},62:{code:"Sisaket",name:"Sisaket"},63:{code:"Songkhla",name:"Songkhla"},64:{code:"Sukhothai",name:"Sukhothai"},65:{code:"Suphan Buri",name:"Suphan Buri"},66:{code:"Surat Thani",name:"Surat Thani"},67:{code:"Surin",name:"Surin"},68:{code:"Tak",name:"Tak"},69:{code:"Trang",name:"Trang"},70:{code:"Trat",name:"Trat"},71:{code:"Ubon Ratchathani",name:"Ubon Ratchathani"},72:{code:"Udon Thani",name:"Udon Thani"},73:{code:"Uthai Thani",name:"Uthai Thani"},74:{code:"Uttaradit",name:"Uttaradit"},75:{code:"Yala",name:"Yala"},76:{code:"Yasothon",name:"Yasothon"}},TG:{1:{code:"K",name:"Kara"},2:{code:"P",name:"Plateaux"},3:{code:"S",name:"Savanes"},4:{code:"C",name:"Centrale"},5:{code:"M",name:"Maritime"}},TK:{1:{code:"A",name:"Atafu"},2:{code:"F",name:"Fakaofo"},3:{code:"N",name:"Nukunonu"}},TO:{1:{code:"H",name:"Ha'apai"},2:{code:"T",name:"Tongatapu"},3:{code:"V",name:"Vava'u"}},TT:{1:{code:"CT",name:"Couva/Tabaquite/Talparo"},2:{code:"DM",name:"Diego Martin"},3:{code:"MR",name:"Mayaro/Rio Claro"},4:{code:"PD",name:"Penal/Debe"},5:{code:"PT",name:"Princes Town"},6:{code:"SG",name:"Sangre Grande"},7:{code:"SL",name:"San Juan/Laventille"},8:{code:"SI",name:"Siparia"},9:{code:"TP",name:"Tunapuna/Piarco"},10:{code:"PS",name:"Port of Spain"},11:{code:"SF",name:"San Fernando"},12:{code:"AR",name:"Arima"},13:{code:"PF",name:"Point Fortin"},14:{code:"CH",name:"Chaguanas"},15:{code:"TO",name:"Tobago"}},TN:{1:{code:"AR",name:"Ariana"},2:{code:"BJ",name:"Beja"},3:{code:"BA",name:"Ben Arous"},4:{code:"BI",name:"Bizerte"},5:{code:"GB",name:"Gabes"},6:{code:"GF",name:"Gafsa"},7:{code:"JE",name:"Jendouba"},8:{code:"KR",name:"Kairouan"},9:{code:"KS",name:"Kasserine"},10:{code:"KB",name:"Kebili"},11:{code:"KF",name:"Kef"},12:{code:"MH",name:"Mahdia"},13:{code:"MN",name:"Manouba"},14:{code:"ME",name:"Medenine"},15:{code:"MO",name:"Monastir"},16:{code:"NA",name:"Nabeul"},17:{code:"SF",name:"Sfax"},18:{code:"SD",name:"Sidi"},19:{code:"SL",name:"Siliana"},20:{code:"SO",name:"Sousse"},21:{code:"TA",name:"Tataouine"},22:{code:"TO",name:"Tozeur"},23:{code:"TU",name:"Tunis"},24:{code:"ZA",name:"Zaghouan"}},TR:{1:{code:"ADA",name:"Adana"},2:{code:"ADI",name:"Adiyaman"},3:{code:"AFY",name:"Afyonkarahisar"},4:{code:"AGR",name:"Agri"},5:{code:"AKS",name:"Aksaray"},6:{code:"AMA",name:"Amasya"},7:{code:"ANK",name:"Ankara"},8:{code:"ANT",name:"Antalya"},9:{code:"ARD",name:"Ardahan"},10:{code:"ART",name:"Artvin"},11:{code:"AYI",name:"Aydin"},12:{code:"BAL",name:"Balikesir"},13:{code:"BAR",name:"Bartin"},14:{code:"BAT",name:"Batman"},15:{code:"BAY",name:"Bayburt"},16:{code:"BIL",name:"Bilecik"},17:{code:"BIN",name:"Bingol"},18:{code:"BIT",name:"Bitlis"},19:{code:"BOL",name:"Bolu"},20:{code:"BRD",name:"Burdur"},21:{code:"BRS",name:"Bursa"},22:{code:"CKL",name:"Canakkale"},23:{code:"CKR",name:"Cankiri"},24:{code:"COR",name:"Corum"},25:{code:"DEN",name:"Denizli"},26:{code:"DIY",name:"Diyarbakir"},27:{code:"DUZ",name:"Duzce"},28:{code:"EDI",name:"Edirne"},29:{code:"ELA",name:"Elazig"},30:{code:"EZC",name:"Erzincan"},31:{code:"EZR",name:"Erzurum"},32:{code:"ESK",name:"Eskisehir"},33:{code:"GAZ",name:"Gaziantep"},34:{code:"GIR",name:"Giresun"},35:{code:"GMS",name:"Gumushane"},36:{code:"HKR",name:"Hakkari"},37:{code:"HTY",name:"Hatay"},38:{code:"IGD",name:"Igdir"},39:{code:"ISP",name:"Isparta"},40:{code:"IST",name:"Istanbul"},41:{code:"IZM",name:"Izmir"},42:{code:"KAH",name:"Kahramanmaras"},43:{code:"KRB",name:"Karabuk"},44:{code:"KRM",name:"Karaman"},45:{code:"KRS",name:"Kars"},46:{code:"KAS",name:"Kastamonu"},47:{code:"KAY",name:"Kayseri"},48:{code:"KLS",name:"Kilis"},49:{code:"KRK",name:"Kirikkale"},50:{code:"KLR",name:"Kirklareli"},51:{code:"KRH",name:"Kirsehir"},52:{code:"KOC",name:"Kocaeli"},53:{code:"KON",name:"Konya"},54:{code:"KUT",name:"Kutahya"},55:{code:"MAL",name:"Malatya"},56:{code:"MAN",name:"Manisa"},57:{code:"MAR",name:"Mardin"},58:{code:"MER",name:"Mersin"},59:{code:"MUG",name:"Mugla"},60:{code:"MUS",name:"Mus"},61:{code:"NEV",name:"Nevsehir"},62:{code:"NIG",name:"Nigde"},63:{code:"ORD",name:"Ordu"},64:{code:"OSM",name:"Osmaniye"},65:{code:"RIZ",name:"Rize"},66:{code:"SAK",name:"Sakarya"},67:{code:"SAM",name:"Samsun"},68:{code:"SAN",name:"Sanliurfa"},69:{code:"SII",name:"Siirt"},70:{code:"SIN",name:"Sinop"},71:{code:"SIR",name:"Sirnak"},72:{code:"SIV",name:"Sivas"},73:{code:"TEL",name:"Tekirdag"},74:{code:"TOK",name:"Tokat"},75:{code:"TRA",name:"Trabzon"},76:{code:"TUN",name:"Tunceli"},77:{code:"USK",name:"Usak"},78:{code:"VAN",name:"Van"},79:{code:"YAL",name:"Yalova"},80:{code:"YOZ",name:"Yozgat"},81:{code:"ZON",name:"Zonguldak"}},TM:{1:{code:"A",name:"Ahal Welayaty"},2:{code:"B",name:"Balkan Welayaty"},3:{code:"D",name:"Dashhowuz Welayaty"},4:{code:"L",name:"Lebap Welayaty"},5:{code:"M",name:"Mary Welayaty"}},TC:{1:{code:"AC",name:"Ambergris Cays"},2:{code:"DC",name:"Dellis Cay"},3:{code:"FC",name:"French Cay"},4:{code:"LW",name:"Little Water Cay"},5:{code:"RC",name:"Parrot Cay"},6:{code:"PN",name:"Pine Cay"},7:{code:"SL",name:"Salt Cay"},8:{code:"GT",name:"Grand Turk"},9:{code:"SC",name:"South Caicos"},10:{code:"EC",name:"East Caicos"},11:{code:"MC",name:"Middle Caicos"},12:{code:"NC",name:"North Caicos"},13:{code:"PR",name:"Providenciales"},14:{code:"WC",name:"West Caicos"}},TV:{1:{code:"NMG",name:"Nanumanga"},2:{code:"NLK",name:"Niulakita"},3:{code:"NTO",name:"Niutao"},4:{code:"FUN",name:"Funafuti"},5:{code:"NME",name:"Nanumea"},6:{code:"NUI",name:"Nui"},7:{code:"NFT",name:"Nukufetau"},8:{code:"NLL",name:"Nukulaelae"},9:{code:"VAI",name:"Vaitupu"}},UG:{1:{code:"KAL",name:"Kalangala"},2:{code:"KMP",name:"Kampala"},3:{code:"KAY",name:"Kayunga"},4:{code:"KIB",name:"Kiboga"},5:{code:"LUW",name:"Luwero"},6:{code:"MAS",name:"Masaka"},7:{code:"MPI",name:"Mpigi"},8:{code:"MUB",name:"Mubende"},9:{code:"MUK",name:"Mukono"},10:{code:"NKS",name:"Nakasongola"},11:{code:"RAK",name:"Rakai"},12:{code:"SEM",name:"Sembabule"},13:{code:"WAK",name:"Wakiso"},14:{code:"BUG",name:"Bugiri"},15:{code:"BUS",name:"Busia"},16:{code:"IGA",name:"Iganga"},17:{code:"JIN",name:"Jinja"},18:{code:"KAB",name:"Kaberamaido"},19:{code:"KML",name:"Kamuli"},20:{code:"KPC",name:"Kapchorwa"},21:{code:"KTK",name:"Katakwi"},22:{code:"KUM",name:"Kumi"},23:{code:"MAY",name:"Mayuge"},24:{code:"MBA",name:"Mbale"},25:{code:"PAL",name:"Pallisa"},26:{code:"SIR",name:"Sironko"},27:{code:"SOR",name:"Soroti"},28:{code:"TOR",name:"Tororo"},29:{code:"ADJ",name:"Adjumani"},30:{code:"APC",name:"Apac"},31:{code:"ARU",name:"Arua"},32:{code:"GUL",name:"Gulu"},33:{code:"KIT",name:"Kitgum"},34:{code:"KOT",name:"Kotido"},35:{code:"LIR",name:"Lira"},36:{code:"MRT",name:"Moroto"},37:{code:"MOY",name:"Moyo"},38:{code:"NAK",name:"Nakapiripirit"},39:{code:"NEB",name:"Nebbi"},40:{code:"PAD",name:"Pader"},41:{code:"YUM",name:"Yumbe"},42:{code:"BUN",name:"Bundibugyo"},43:{code:"BSH",name:"Bushenyi"},44:{code:"HOI",name:"Hoima"},45:{code:"KBL",name:"Kabale"},46:{code:"KAR",name:"Kabarole"},47:{code:"KAM",name:"Kamwenge"},48:{code:"KAN",name:"Kanungu"},49:{code:"KAS",name:"Kasese"},50:{code:"KBA",name:"Kibaale"},51:{code:"KIS",name:"Kisoro"},52:{code:"KYE",name:"Kyenjojo"},53:{code:"MSN",name:"Masindi"},54:{code:"MBR",name:"Mbarara"},55:{code:"NTU",name:"Ntungamo"},56:{code:"RUK",name:"Rukungiri"}},UA:{1:{code:"CK",name:"Cherkasy"},2:{code:"CH",name:"Chernihiv"},3:{code:"CV",name:"Chernivtsi"},4:{code:"CR",name:"Crimea"},5:{code:"DN",name:"Dnipropetrovs'k"},6:{code:"DO",name:"Donets'k"},7:{code:"IV",name:"Ivano-Frankivs'k"},8:{code:"KL",name:"Kharkiv Kherson"},9:{code:"KM",name:"Khmel'nyts'kyy"},10:{code:"KR",name:"Kirovohrad"},11:{code:"KV",name:"Kiev"},12:{code:"KY",name:"Kyyiv"},13:{code:"LU",name:"Luhans'k"},14:{code:"LV",name:"L'viv"},15:{code:"MY",name:"Mykolayiv"},16:{code:"OD",name:"Odesa"},17:{code:"PO",name:"Poltava"},18:{code:"RI",name:"Rivne"},19:{code:"SE",name:"Sevastopol"},20:{code:"SU",name:"Sumy"},21:{code:"TE",name:"Ternopil'"},22:{code:"VI",name:"Vinnytsya"},23:{code:"VO",name:"Volyn'"},24:{code:"ZK",name:"Zakarpattya"},25:{code:"ZA",name:"Zaporizhzhya"},26:{code:"ZH",name:"Zhytomyr"}},AE:{1:{code:"AZ",name:"Abu Zaby"},2:{code:"AJ",name:"'Ajman"},3:{code:"FU",name:"Al Fujayrah"},4:{code:"SH",name:"Ash Shariqah"},5:{code:"DU",name:"Dubayy"},6:{code:"RK",name:"R'as al Khaymah"},7:{code:"UQ",name:"Umm al Qaywayn"}},GB:{1:{code:"ABN",name:"Aberdeen"},2:{code:"ABNS",name:"Aberdeenshire"},3:{code:"ANG",name:"Anglesey"},4:{code:"AGS",name:"Angus"},5:{code:"ARY",name:"Argyll and Bute"},6:{code:"BEDS",name:"Bedfordshire"},7:{code:"BERKS",name:"Berkshire"},8:{code:"BLA",name:"Blaenau Gwent"},9:{code:"BRI",name:"Bridgend"},10:{code:"BSTL",name:"Bristol"},11:{code:"BUCKS",name:"Buckinghamshire"},12:{code:"CAE",name:"Caerphilly"},13:{code:"CAMBS",name:"Cambridgeshire"},14:{code:"CDF",name:"Cardiff"},15:{code:"CARM",name:"Carmarthenshire"},16:{code:"CDGN",name:"Ceredigion"},17:{code:"CHES",name:"Cheshire"},18:{code:"CLACK",name:"Clackmannanshire"},19:{code:"CON",name:"Conwy"},20:{code:"CORN",name:"Cornwall"},21:{code:"DNBG",name:"Denbighshire"},22:{code:"DERBY",name:"Derbyshire"},23:{code:"DVN",name:"Devon"},24:{code:"DOR",name:"Dorset"},25:{code:"DGL",name:"Dumfries and Galloway"},26:{code:"DUND",name:"Dundee"},27:{code:"DHM",name:"Durham"},28:{code:"ARYE",name:"East Ayrshire"},29:{code:"DUNBE",name:"East Dunbartonshire"},30:{code:"LOTE",name:"East Lothian"},31:{code:"RENE",name:"East Renfrewshire"},32:{code:"ERYS",name:"East Riding of Yorkshire"},33:{code:"SXE",name:"East Sussex"},34:{code:"EDIN",name:"Edinburgh"},35:{code:"ESX",name:"Essex"},36:{code:"FALK",name:"Falkirk"},37:{code:"FFE",name:"Fife"},38:{code:"FLINT",name:"Flintshire"},39:{code:"GLAS",name:"Glasgow"},40:{code:"GLOS",name:"Gloucestershire"},41:{code:"LDN",name:"Greater London"},42:{code:"MCH",name:"Greater Manchester"},43:{code:"GDD",name:"Gwynedd"},44:{code:"HANTS",name:"Hampshire"},45:{code:"HWR",name:"Herefordshire"},46:{code:"HERTS",name:"Hertfordshire"},47:{code:"HLD",name:"Highlands"},48:{code:"IVER",name:"Inverclyde"},49:{code:"IOW",name:"Isle of Wight"},50:{code:"KNT",name:"Kent"},51:{code:"LANCS",name:"Lancashire"},52:{code:"LEICS",name:"Leicestershire"},53:{code:"LINCS",name:"Lincolnshire"},54:{code:"MSY",name:"Merseyside"},55:{code:"MERT",name:"Merthyr Tydfil"},56:{code:"MLOT",name:"Midlothian"},57:{code:"MMOUTH",name:"Monmouthshire"},58:{code:"MORAY",name:"Moray"},59:{code:"NPRTAL",name:"Neath Port Talbot"},60:{code:"NEWPT",name:"Newport"},61:{code:"NOR",name:"Norfolk"},62:{code:"ARYN",name:"North Ayrshire"},63:{code:"LANN",name:"North Lanarkshire"},64:{code:"YSN",name:"North Yorkshire"},65:{code:"NHM",name:"Northamptonshire"},66:{code:"NLD",name:"Northumberland"},67:{code:"NOT",name:"Nottinghamshire"},68:{code:"ORK",name:"Orkney Islands"},69:{code:"OFE",name:"Oxfordshire"},70:{code:"PEM",name:"Pembrokeshire"},71:{code:"PERTH",name:"Perth and Kinross"},72:{code:"PWS",name:"Powys"},73:{code:"REN",name:"Renfrewshire"},74:{code:"RHON",name:"Rhondda Cynon Taff"},75:{code:"RUT",name:"Rutland"},76:{code:"BOR",name:"Scottish Borders"},77:{code:"SHET",name:"Shetland Islands"},78:{code:"SPE",name:"Shropshire"},79:{code:"SOM",name:"Somerset"},80:{code:"ARYS",name:"South Ayrshire"},81:{code:"LANS",name:"South Lanarkshire"},82:{code:"YSS",name:"South Yorkshire"},83:{code:"SFD",name:"Staffordshire"},84:{code:"STIR",name:"Stirling"},85:{code:"SFK",name:"Suffolk"},86:{code:"SRY",name:"Surrey"},87:{code:"SWAN",name:"Swansea"},88:{code:"TORF",name:"Torfaen"},89:{code:"TWR",name:"Tyne and Wear"},90:{code:"VGLAM",name:"Vale of Glamorgan"},91:{code:"WARKS",name:"Warwickshire"},92:{code:"WDUN",name:"West Dunbartonshire"},93:{code:"WLOT",name:"West Lothian"},94:{code:"WMD",name:"West Midlands"},95:{code:"SXW",name:"West Sussex"},96:{code:"YSW",name:"West Yorkshire"},97:{code:"WIL",name:"Western Isles"},98:{code:"WLT",name:"Wiltshire"},99:{code:"WORCS",name:"Worcestershire"},100:{code:"WRX",name:"Wrexham"}},US:{1:{code:"AL",name:"Alabama"},2:{code:"AK",name:"Alaska"},3:{code:"AS",name:"American Samoa"},4:{code:"AZ",name:"Arizona"},5:{code:"AR",name:"Arkansas"},6:{code:"AF",name:"Armed Forces Africa"},7:{code:"AA",name:"Armed Forces Americas"},8:{code:"AC",name:"Armed Forces Canada"},9:{code:"AE",name:"Armed Forces Europe"},10:{code:"AM",name:"Armed Forces Middle East"},11:{code:"AP",name:"Armed Forces Pacific"},12:{code:"CA",name:"California"},13:{code:"CO",name:"Colorado"},14:{code:"CT",name:"Connecticut"},15:{code:"DE",name:"Delaware"},16:{code:"DC",name:"District of Columbia"},17:{code:"FM",name:"Federated States Of Micronesia"},18:{code:"FL",name:"Florida"},19:{code:"GA",name:"Georgia"},20:{code:"GU",name:"Guam"},21:{code:"HI",name:"Hawaii"},22:{code:"ID",name:"Idaho"},23:{code:"IL",name:"Illinois"},24:{code:"IN",name:"Indiana"},25:{code:"IA",name:"Iowa"},26:{code:"KS",name:"Kansas"},27:{code:"KY",name:"Kentucky"},28:{code:"LA",name:"Louisiana"},29:{code:"ME",name:"Maine"},30:{code:"MH",name:"Marshall Islands"},31:{code:"MD",name:"Maryland"},32:{code:"MA",name:"Massachusetts"},33:{code:"MI",name:"Michigan"},34:{code:"MN",name:"Minnesota"},35:{code:"MS",name:"Mississippi"},36:{code:"MO",name:"Missouri"},37:{code:"MT",name:"Montana"},38:{code:"NE",name:"Nebraska"},39:{code:"NV",name:"Nevada"},40:{code:"NH",name:"New Hampshire"},41:{code:"NJ",name:"New Jersey"},42:{code:"NM",name:"New Mexico"},43:{code:"NY",name:"New York"},44:{code:"NC",name:"North Carolina"},45:{code:"ND",name:"North Dakota"},46:{code:"MP",name:"Northern Mariana Islands"},47:{code:"OH",name:"Ohio"},48:{code:"OK",name:"Oklahoma"},49:{code:"OR",name:"Oregon"},50:{code:"PW",name:"Palau"},51:{code:"PA",name:"Pennsylvania"},52:{code:"PR",name:"Puerto Rico"},53:{code:"RI",name:"Rhode Island"},54:{code:"SC",name:"South Carolina"},55:{code:"SD",name:"South Dakota"},56:{code:"TN",name:"Tennessee"},57:{code:"TX",name:"Texas"},58:{code:"UT",name:"Utah"},59:{code:"VT",name:"Vermont"},60:{code:"VI",name:"Virgin Islands"},61:{code:"VA",name:"Virginia"},62:{code:"WA",name:"Washington"},63:{code:"WV",name:"West Virginia"},64:{code:"WI",name:"Wisconsin"},65:{code:"WY",name:"Wyoming"}},UM:{1:{code:"BI",name:"Baker Island"},2:{code:"HI",name:"Howland Island"},3:{code:"JI",name:"Jarvis Island"},4:{code:"JA",name:"Johnston Atoll"},5:{code:"KR",name:"Kingman Reef"},6:{code:"MA",name:"Midway Atoll"},7:{code:"NI",name:"Navassa Island"},8:{code:"PA",name:"Palmyra Atoll"},9:{code:"WI",name:"Wake Island"}},UY:{1:{code:"AR",name:"Artigas"},2:{code:"CA",name:"Canelones"},3:{code:"CL",name:"Cerro Largo"},4:{code:"CO",name:"Colonia"},5:{code:"DU",name:"Durazno"},6:{code:"FS",name:"Flores"},7:{code:"FA",name:"Florida"},8:{code:"LA",name:"Lavalleja"},9:{code:"MA",name:"Maldonado"},10:{code:"MO",name:"Montevideo"},11:{code:"PA",name:"Paysandu"},12:{code:"RN",name:"Rio Negro"},13:{code:"RV",name:"Rivera"},14:{code:"RO",name:"Rocha"},15:{code:"SL",name:"Salto"},16:{code:"SJ",name:"San Jose"},17:{code:"SO",name:"Soriano"},18:{code:"TA",name:"Tacuarembo"},19:{code:"TT",name:"Treinta y Tres"}},UZ:{1:{code:"AN",name:"Andijon"},2:{code:"BU",name:"Buxoro"},3:{code:"FA",name:"Farg'ona"},4:{code:"JI",name:"Jizzax"},5:{code:"NG",name:"Namangan"},6:{code:"NW",name:"Navoiy"},7:{code:"QA",name:"Qashqadaryo"},8:{code:"QR",name:"Qoraqalpog'iston Republikasi"},9:{code:"SA",name:"Samarqand"},10:{code:"SI",name:"Sirdaryo"},11:{code:"SU",name:"Surxondaryo"},12:{code:"TK",name:"Toshkent City"},13:{code:"TO",name:"Toshkent Region"},14:{code:"XO",name:"Xorazm"}},VU:{1:{code:"MA",name:"Malampa"},2:{code:"PE",name:"Penama"},3:{code:"SA",name:"Sanma"},4:{code:"SH",name:"Shefa"},5:{code:"TA",name:"Tafea"},6:{code:"TO",name:"Torba"}},VE:{1:{code:"AM",name:"Amazonas"},2:{code:"AN",name:"Anzoategui"},3:{code:"AP",name:"Apure"},4:{code:"AR",name:"Aragua"},5:{code:"BA",name:"Barinas"},6:{code:"BO",name:"Bolivar"},7:{code:"CA",name:"Carabobo"},8:{code:"CO",name:"Cojedes"},9:{code:"DA",name:"Delta Amacuro"},10:{code:"DF",name:"Dependencias Federales"},11:{code:"DI",name:"Distrito Federal"},12:{code:"FA",name:"Falcon"},13:{code:"GU",name:"Guarico"},14:{code:"LA",name:"Lara"},15:{code:"ME",name:"Merida"},16:{code:"MI",name:"Miranda"},17:{code:"MO",name:"Monagas"},18:{code:"NE",name:"Nueva Esparta"},19:{code:"PO",name:"Portuguesa"},20:{code:"SU",name:"Sucre"},21:{code:"TA",name:"Tachira"},22:{code:"TR",name:"Trujillo"},23:{code:"VA",name:"Vargas"},24:{code:"YA",name:"Yaracuy"},25:{code:"ZU",name:"Zulia"}},VN:{1:{code:"AG",name:"An Giang"},2:{code:"BG",name:"Bac Giang"},3:{code:"BK",name:"Bac Kan"},4:{code:"BL",name:"Bac Lieu"},5:{code:"BC",name:"Bac Ninh"},6:{code:"BR",name:"Ba Ria-Vung Tau"},7:{code:"BN",name:"Ben Tre"},8:{code:"BH",name:"Binh Dinh"},9:{code:"BU",name:"Binh Duong"},10:{code:"BP",name:"Binh Phuoc"},11:{code:"BT",name:"Binh Thuan"},12:{code:"CM",name:"Ca Mau"},13:{code:"CT",name:"Can Tho"},14:{code:"CB",name:"Cao Bang"},15:{code:"DL",name:"Dak Lak"},16:{code:"DG",name:"Dak Nong"},17:{code:"DN",name:"Da Nang"},18:{code:"DB",name:"Dien Bien"},19:{code:"DI",name:"Dong Nai"},20:{code:"DT",name:"Dong Thap"},21:{code:"GL",name:"Gia Lai"},22:{code:"HG",name:"Ha Giang"},23:{code:"HD",name:"Hai Duong"},24:{code:"HP",name:"Hai Phong"},25:{code:"HM",name:"Ha Nam"},26:{code:"HI",name:"Ha Noi"},27:{code:"HT",name:"Ha Tay"},28:{code:"HH",name:"Ha Tinh"},29:{code:"HB",name:"Hoa Binh"},30:{code:"HC",name:"Ho Chin Minh"},31:{code:"HU",name:"Hau Giang"},32:{code:"HY",name:"Hung Yen"}},VI:{1:{code:"C",name:"Saint Croix"},2:{code:"J",name:"Saint John"},3:{code:"T",name:"Saint Thomas"}},WF:{1:{code:"A",name:"Alo"},2:{code:"S",name:"Sigave"},3:{code:"W",name:"Wallis"}},YE:{1:{code:"AB",name:"Abyan"},2:{code:"AD",name:"Adan"},3:{code:"AM",name:"Amran"},4:{code:"BA",name:"Al Bayda"},5:{code:"DA",name:"Ad Dali"},6:{code:"DH",name:"Dhamar"},7:{code:"HD",name:"Hadramawt"},8:{code:"HJ",name:"Hajjah"},9:{code:"HU",name:"Al Hudaydah"},10:{code:"IB",name:"Ibb"},11:{code:"JA",name:"Al Jawf"},12:{code:"LA",name:"Lahij"},13:{code:"MA",name:"Ma'rib"},14:{code:"MR",name:"Al Mahrah"},15:{code:"MW",name:"Al Mahwit"},16:{code:"SD",name:"Sa'dah"},17:{code:"SN",name:"San'a"},18:{code:"SH",name:"Shabwah"},19:{code:"TA",name:"Ta'izz"}},YU:{1:{code:"KOS",name:"Kosovo"},2:{code:"MON",name:"Montenegro"},3:{code:"SER",name:"Serbia"},4:{code:"VOJ",name:"Vojvodina"}},ZR:{1:{code:"BC",name:"Bas-Congo"},2:{code:"BN",name:"Bandundu"},3:{code:"EQ",name:"Equateur"},4:{code:"KA",name:"Katanga"},5:{code:"KE",name:"Kasai-Oriental"},6:{code:"KN",name:"Kinshasa"},7:{code:"KW",name:"Kasai-Occidental"},8:{code:"MA",name:"Maniema"},9:{code:"NK",name:"Nord-Kivu"},10:{code:"OR",name:"Orientale"},11:{code:"SK",name:"Sud-Kivu"}},ZM:{1:{code:"CE",name:"Central"},2:{code:"CB",name:"Copperbelt"},3:{code:"EA",name:"Eastern"},4:{code:"LP",name:"Luapula"},5:{code:"LK",name:"Lusaka"},6:{code:"NO",name:"Northern"},7:{code:"NW",name:"North-Western"},8:{code:"SO",name:"Southern"},9:{code:"WE",name:"Western"}},ZW:{1:{code:"BU",name:"Bulawayo"},2:{code:"HA",name:"Harare"},3:{code:"ML",name:"Manicaland"},4:{code:"MC",name:"Mashonaland Central"},5:{code:"ME",name:"Mashonaland East"},6:{code:"MW",name:"Mashonaland West"},7:{code:"MV",name:"Masvingo"},8:{code:"MN",name:"Matabeleland North"},9:{code:"MS",name:"Matabeleland South"},10:{code:"MD",name:"Midlands"}}},BFHTimePickerDelimiter=":",BFHTimePickerModes={am:"AM",pm:"PM"},BFHTimezonesList={AF:{"Asia/Kabul":"Kabul"},AL:{"Europe/Tirane":"Tirane"},DZ:{"Africa/Algiers":"Algiers"},AS:{"Pacific/Pago_Pago":"Pago Pago"},AD:{"Europe/Andorra":"Andorra"},AO:{"Africa/Luanda":"Luanda"},AI:{"America/Anguilla":"Anguilla"},AQ:{"Antarctica/Casey":"Casey","Antarctica/Davis":"Davis","Antarctica/DumontDUrville":"DumontDUrville","Antarctica/Macquarie":"Macquarie","Antarctica/Mawson":"Mawson","Antarctica/McMurdo":"McMurdo","Antarctica/Palmer":"Palmer","Antarctica/Rothera":"Rothera","Antarctica/South_Pole":"South Pole","Antarctica/Syowa":"Syowa","Antarctica/Vostok":"Vostok"},AG:{"America/Antigua":"Antigua"},AR:{"America/Argentina/Buenos_Aires":"Argentina / Buenos Aires","America/Argentina/Catamarca":"Argentina / Catamarca","America/Argentina/Cordoba":"Argentina / Cordoba","America/Argentina/Jujuy":"Argentina / Jujuy","America/Argentina/La_Rioja":"Argentina / La Rioja","America/Argentina/Mendoza":"Argentina / Mendoza","America/Argentina/Rio_Gallegos":"Argentina / Rio Gallegos","America/Argentina/Salta":"Argentina / Salta","America/Argentina/San_Juan":"Argentina / San Juan","America/Argentina/San_Luis":"Argentina / San Luis","America/Argentina/Tucuman":"Argentina / Tucuman","America/Argentina/Ushuaia":"Argentina / Ushuaia"},AM:{"Asia/Yerevan":"Yerevan"},AW:{"America/Aruba":"Aruba"},AU:{"Australia/Adelaide":"Adelaide","Australia/Brisbane":"Brisbane","Australia/Broken_Hill":"Broken Hill","Australia/Currie":"Currie","Australia/Darwin":"Darwin","Australia/Eucla":"Eucla","Australia/Hobart":"Hobart","Australia/Lindeman":"Lindeman","Australia/Lord_Howe":"Lord Howe","Australia/Melbourne":"Melbourne","Australia/Perth":"Perth","Australia/Sydney":"Sydney"},AT:{"Europe/Vienna":"Vienna"},AZ:{"Asia/Baku":"Baku"},BH:{"Asia/Bahrain":"Bahrain"},BD:{"Asia/Dhaka":"Dhaka"},BB:{"America/Barbados":"Barbados"},BY:{"Europe/Minsk":"Minsk"},BE:{"Europe/Brussels":"Brussels"},BZ:{"America/Belize":"Belize"},BJ:{"Africa/Porto-Novo":"Porto-Novo"},BM:{"Atlantic/Bermuda":"Bermuda"},BT:{"Asia/Thimphu":"Thimphu"},BO:{"America/La_Paz":"La Paz"},BA:{"Europe/Sarajevo":"Sarajevo"},BW:{"Africa/Gaborone":"Gaborone"},BR:{"America/Araguaina":"Araguaina","America/Bahia":"Bahia","America/Belem":"Belem","America/Boa_Vista":"Boa Vista","America/Campo_Grande":"Campo Grande","America/Cuiaba":"Cuiaba","America/Eirunepe":"Eirunepe","America/Fortaleza":"Fortaleza","America/Maceio":"Maceio","America/Manaus":"Manaus","America/Noronha":"Noronha","America/Porto_Velho":"Porto Velho","America/Recife":"Recife","America/Rio_Branco":"Rio Branco","America/Santarem":"Santarem","America/Sao_Paulo":"Sao Paulo"},VG:{"America/Tortola":"Tortola"},BN:{"Asia/Brunei":"Brunei"},BG:{"Europe/Sofia":"Sofia"},BF:{"Africa/Ouagadougou":"Ouagadougou"},BI:{"Africa/Bujumbura":"Bujumbura"},CI:{"Africa/Abidjan":"Abidjan"},KH:{"Asia/Phnom_Penh":"Phnom Penh"},CM:{"Africa/Douala":"Douala"},CA:{"America/Atikokan":"Atikokan","America/Blanc-Sablon":"Blanc-Sablon","America/Cambridge_Bay":"Cambridge Bay","America/Creston":"Creston","America/Dawson":"Dawson","America/Dawson_Creek":"Dawson Creek","America/Edmonton":"Edmonton","America/Glace_Bay":"Glace Bay","America/Goose_Bay":"Goose Bay","America/Halifax":"Halifax","America/Inuvik":"Inuvik","America/Iqaluit":"Iqaluit","America/Moncton":"Moncton","America/Montreal":"Montreal","America/Nipigon":"Nipigon","America/Pangnirtung":"Pangnirtung","America/Rainy_River":"Rainy River","America/Rankin_Inlet":"Rankin Inlet","America/Regina":"Regina","America/Resolute":"Resolute","America/St_Johns":"St Johns","America/Swift_Current":"Swift Current","America/Thunder_Bay":"Thunder Bay","America/Toronto":"Toronto","America/Vancouver":"Vancouver","America/Whitehorse":"Whitehorse","America/Winnipeg":"Winnipeg","America/Yellowknife":"Yellowknife"},CV:{"Atlantic/Cape_Verde":"Cape Verde"},KY:{"America/Cayman":"Cayman"},CF:{"Africa/Bangui":"Bangui"},TD:{"Africa/Ndjamena":"Ndjamena"},CL:{"America/Santiago":"Santiago","Pacific/Easter":"Easter"},CN:{"Asia/Chongqing":"Chongqing","Asia/Harbin":"Harbin","Asia/Kashgar":"Kashgar","Asia/Shanghai":"Shanghai","Asia/Urumqi":"Urumqi"},CO:{"America/Bogota":"Bogota"},KM:{"Indian/Comoro":"Comoro"},CG:{"Africa/Brazzaville":"Brazzaville"},CR:{"America/Costa_Rica":"Costa Rica"},HR:{"Europe/Zagreb":"Zagreb"},CU:{"America/Havana":"Havana"},CY:{"Asia/Nicosia":"Nicosia"},CZ:{"Europe/Prague":"Prague"},CD:{"Africa/Kinshasa":"Kinshasa","Africa/Lubumbashi":"Lubumbashi"},DK:{"Europe/Copenhagen":"Copenhagen"},DJ:{"Africa/Djibouti":"Djibouti"},DM:{"America/Dominica":"Dominica"},DO:{"America/Santo_Domingo":"Santo Domingo"},TP:{},EC:{"America/Guayaquil":"Guayaquil","Pacific/Galapagos":"Galapagos"},EG:{"Africa/Cairo":"Cairo"},SV:{"America/El_Salvador":"El Salvador"},GQ:{"Africa/Malabo":"Malabo"},ER:{"Africa/Asmara":"Asmara"},EE:{"Europe/Tallinn":"Tallinn"},ET:{"Africa/Addis_Ababa":"Addis Ababa"},FO:{"Atlantic/Faroe":"Faroe"},FK:{"Atlantic/Stanley":"Stanley"},FJ:{"Pacific/Fiji":"Fiji"},FI:{"Europe/Helsinki":"Helsinki"},MK:{"Europe/Skopje":"Skopje"},FR:{"Europe/Paris":"Paris"},GA:{"Africa/Libreville":"Libreville"},GE:{"Asia/Tbilisi":"Tbilisi"},DE:{"Europe/Berlin":"Berlin"},GH:{"Africa/Accra":"Accra"},GR:{"Europe/Athens":"Athens"},GL:{"America/Danmarkshavn":"Danmarkshavn","America/Godthab":"Godthab","America/Scoresbysund":"Scoresbysund","America/Thule":"Thule"},GD:{"America/Grenada":"Grenada"},GU:{"Pacific/Guam":"Guam"},GT:{"America/Guatemala":"Guatemala"},GN:{"Africa/Conakry":"Conakry"},GW:{"Africa/Bissau":"Bissau"},GY:{"America/Guyana":"Guyana"},HT:{"America/Port-au-Prince":"Port-au-Prince"},HN:{"America/Tegucigalpa":"Tegucigalpa"},HK:{"Asia/Hong_Kong":"Hong Kong"},HU:{"Europe/Budapest":"Budapest"},IS:{"Atlantic/Reykjavik":"Reykjavik"},IN:{"Asia/Kolkata":"Kolkata"},ID:{"Asia/Jakarta":"Jakarta","Asia/Jayapura":"Jayapura","Asia/Makassar":"Makassar","Asia/Pontianak":"Pontianak"},IR:{"Asia/Tehran":"Tehran"},IQ:{"Asia/Baghdad":"Baghdad"},IE:{"Europe/Dublin":"Dublin"},IL:{"Asia/Jerusalem":"Jerusalem"},IT:{"Europe/Rome":"Rome"},JM:{"America/Jamaica":"Jamaica"},JP:{"Asia/Tokyo":"Tokyo"},JO:{"Asia/Amman":"Amman"},KZ:{"Asia/Almaty":"Almaty","Asia/Aqtau":"Aqtau","Asia/Aqtobe":"Aqtobe","Asia/Oral":"Oral","Asia/Qyzylorda":"Qyzylorda"},KE:{"Africa/Nairobi":"Nairobi"},KI:{"Pacific/Enderbury":"Enderbury","Pacific/Kiritimati":"Kiritimati","Pacific/Tarawa":"Tarawa"},KW:{"Asia/Kuwait":"Kuwait"},KG:{"Asia/Bishkek":"Bishkek"},LA:{"Asia/Vientiane":"Vientiane"},LV:{"Europe/Riga":"Riga"},LB:{"Asia/Beirut":"Beirut"},LS:{"Africa/Maseru":"Maseru"},LR:{"Africa/Monrovia":"Monrovia"},LY:{"Africa/Tripoli":"Tripoli"},LI:{"Europe/Vaduz":"Vaduz"},LT:{"Europe/Vilnius":"Vilnius"},LU:{"Europe/Luxembourg":"Luxembourg"},MO:{"Asia/Macau":"Macau"},MG:{"Indian/Antananarivo":"Antananarivo"},MW:{"Africa/Blantyre":"Blantyre"},MY:{"Asia/Kuala_Lumpur":"Kuala Lumpur","Asia/Kuching":"Kuching"},MV:{"Indian/Maldives":"Maldives"},ML:{"Africa/Bamako":"Bamako"},MT:{"Europe/Malta":"Malta"},MH:{"Pacific/Kwajalein":"Kwajalein","Pacific/Majuro":"Majuro"},MR:{"Africa/Nouakchott":"Nouakchott"},MU:{"Indian/Mauritius":"Mauritius"},MX:{"America/Bahia_Banderas":"Bahia Banderas","America/Cancun":"Cancun","America/Chihuahua":"Chihuahua","America/Hermosillo":"Hermosillo","America/Matamoros":"Matamoros","America/Mazatlan":"Mazatlan","America/Merida":"Merida","America/Mexico_City":"Mexico City","America/Monterrey":"Monterrey","America/Ojinaga":"Ojinaga","America/Santa_Isabel":"Santa Isabel","America/Tijuana":"Tijuana"},FM:{"Pacific/Chuuk":"Chuuk","Pacific/Kosrae":"Kosrae","Pacific/Pohnpei":"Pohnpei"},MD:{"Europe/Chisinau":"Chisinau"},MC:{"Europe/Monaco":"Monaco"},MN:{"Asia/Choibalsan":"Choibalsan","Asia/Hovd":"Hovd","Asia/Ulaanbaatar":"Ulaanbaatar"},ME:{"Europe/Podgorica":"Podgorica"},MS:{"America/Montserrat":"Montserrat"},MA:{"Africa/Casablanca":"Casablanca"},MZ:{"Africa/Maputo":"Maputo"},MM:{"Asia/Rangoon":"Rangoon"},NA:{"Africa/Windhoek":"Windhoek"},NR:{"Pacific/Nauru":"Nauru"},NP:{"Asia/Kathmandu":"Kathmandu"},NL:{"Europe/Amsterdam":"Amsterdam"},AN:{},NZ:{"Pacific/Auckland":"Auckland","Pacific/Chatham":"Chatham"},NI:{"America/Managua":"Managua"},NE:{"Africa/Niamey":"Niamey"},NG:{"Africa/Lagos":"Lagos"},NF:{"Pacific/Norfolk":"Norfolk"},KP:{"Asia/Pyongyang":"Pyongyang"},MP:{"Pacific/Saipan":"Saipan"},NO:{"Europe/Oslo":"Oslo"},OM:{"Asia/Muscat":"Muscat"},PK:{"Asia/Karachi":"Karachi"},PW:{"Pacific/Palau":"Palau"},PA:{"America/Panama":"Panama"},PG:{"Pacific/Port_Moresby":"Port Moresby"},PY:{"America/Asuncion":"Asuncion"},PE:{"America/Lima":"Lima"},PH:{"Asia/Manila":"Manila"},PN:{"Pacific/Pitcairn":"Pitcairn"},PL:{"Europe/Warsaw":"Warsaw"},PT:{"Atlantic/Azores":"Azores","Atlantic/Madeira":"Madeira","Europe/Lisbon":"Lisbon"},PR:{"America/Puerto_Rico":"Puerto Rico"},QA:{"Asia/Qatar":"Qatar"},RO:{"Europe/Bucharest":"Bucharest"},RU:{"Asia/Anadyr":"Anadyr","Asia/Irkutsk":"Irkutsk","Asia/Kamchatka":"Kamchatka","Asia/Krasnoyarsk":"Krasnoyarsk","Asia/Magadan":"Magadan","Asia/Novokuznetsk":"Novokuznetsk","Asia/Novosibirsk":"Novosibirsk","Asia/Omsk":"Omsk","Asia/Sakhalin":"Sakhalin","Asia/Vladivostok":"Vladivostok","Asia/Yakutsk":"Yakutsk","Asia/Yekaterinburg":"Yekaterinburg","Europe/Kaliningrad":"Kaliningrad","Europe/Moscow":"Moscow","Europe/Samara":"Samara","Europe/Volgograd":"Volgograd"},RW:{"Africa/Kigali":"Kigali"},ST:{"Africa/Sao_Tome":"Sao Tome"},SH:{"Atlantic/St_Helena":"St Helena"},KN:{"America/St_Kitts":"St Kitts"},LC:{"America/St_Lucia":"St Lucia"},VC:{"America/St_Vincent":"St Vincent"},WS:{"Pacific/Apia":"Apia"},SM:{"Europe/San_Marino":"San Marino"},SA:{"Asia/Riyadh":"Riyadh"},SN:{"Africa/Dakar":"Dakar"},RS:{"Europe/Belgrade":"Belgrade"},SC:{"Indian/Mahe":"Mahe"},SL:{"Africa/Freetown":"Freetown"},SG:{"Asia/Singapore":"Singapore"},SK:{"Europe/Bratislava":"Bratislava"},SI:{"Europe/Ljubljana":"Ljubljana"},SB:{"Pacific/Guadalcanal":"Guadalcanal"},SO:{"Africa/Mogadishu":"Mogadishu"},ZA:{"Africa/Johannesburg":"Johannesburg"},GS:{"Atlantic/South_Georgia":"South Georgia"},KR:{"Asia/Seoul":"Seoul"},ES:{"Africa/Ceuta":"Ceuta","Atlantic/Canary":"Canary","Europe/Madrid":"Madrid"},LK:{"Asia/Colombo":"Colombo"},SD:{"Africa/Khartoum":"Khartoum"},SR:{"America/Paramaribo":"Paramaribo"},SZ:{"Africa/Mbabane":"Mbabane"},SE:{"Europe/Stockholm":"Stockholm"},CH:{"Europe/Zurich":"Zurich"},SY:{"Asia/Damascus":"Damascus"},TW:{"Asia/Taipei":"Taipei"},TJ:{"Asia/Dushanbe":"Dushanbe"},TZ:{"Africa/Dar_es_Salaam":"Dar es Salaam"},TH:{"Asia/Bangkok":"Bangkok"},BS:{"America/Nassau":"Nassau"},GM:{"Africa/Banjul":"Banjul"},TG:{"Africa/Lome":"Lome"},TO:{"Pacific/Tongatapu":"Tongatapu"},TT:{"America/Port_of_Spain":"Port of Spain"},TN:{"Africa/Tunis":"Tunis"},TR:{"Europe/Istanbul":"Istanbul"},TM:{"Asia/Ashgabat":"Ashgabat"},TC:{"America/Grand_Turk":"Grand Turk"},TV:{"Pacific/Funafuti":"Funafuti"},VI:{"America/St_Thomas":"St Thomas"},UG:{"Africa/Kampala":"Kampala"},UA:{"Europe/Kiev":"Kiev","Europe/Simferopol":"Simferopol","Europe/Uzhgorod":"Uzhgorod","Europe/Zaporozhye":"Zaporozhye"},AE:{"Asia/Dubai":"Dubai"},GB:{"Europe/London":"London"},US:{"America/Adak":"Adak","America/Anchorage":"Anchorage","America/Boise":"Boise","America/Chicago":"Chicago","America/Denver":"Denver","America/Detroit":"Detroit","America/Indiana/Indianapolis":"Indiana / Indianapolis","America/Indiana/Knox":"Indiana / Knox","America/Indiana/Marengo":"Indiana / Marengo","America/Indiana/Petersburg":"Indiana / Petersburg","America/Indiana/Tell_City":"Indiana / Tell City","America/Indiana/Vevay":"Indiana / Vevay","America/Indiana/Vincennes":"Indiana / Vincennes","America/Indiana/Winamac":"Indiana / Winamac","America/Juneau":"Juneau","America/Kentucky/Louisville":"Kentucky / Louisville","America/Kentucky/Monticello":"Kentucky / Monticello","America/Los_Angeles":"Los Angeles","America/Menominee":"Menominee","America/Metlakatla":"Metlakatla","America/New_York":"New York","America/Nome":"Nome","America/North_Dakota/Beulah":"North Dakota / Beulah","America/North_Dakota/Center":"North Dakota / Center","America/North_Dakota/New_Salem":"North Dakota / New Salem","America/Phoenix":"Phoenix","America/Shiprock":"Shiprock","America/Sitka":"Sitka","America/Yakutat":"Yakutat","Pacific/Honolulu":"Honolulu"},UY:{"America/Montevideo":"Montevideo"},UZ:{"Asia/Samarkand":"Samarkand","Asia/Tashkent":"Tashkent"},VU:{"Pacific/Efate":"Efate"},VA:{"Europe/Vatican":"Vatican"},VE:{"America/Caracas":"Caracas"},VN:{"Asia/Ho_Chi_Minh":"Ho Chi Minh"},EH:{"Africa/El_Aaiun":"El Aaiun"},YE:{"Asia/Aden":"Aden"},ZM:{"Africa/Lusaka":"Lusaka"},ZW:{"Africa/Harare":"Harare"}}; ++function(a){"use strict";function b(a){var b=a.toString(16);return 1===b.length?"0"+b:b}function c(a,c,d){return"#"+b(a)+b(c)+b(d)}function d(){var b;a(f).each(function(c){return b=e(a(this)),b.hasClass("open")?(b.trigger(c=a.Event("hide.bfhcolorpicker")),c.isDefaultPrevented()?!0:(b.removeClass("open").trigger("hidden.bfhcolorpicker"),void 0)):!0})}function e(a){return a.closest(".bfh-colorpicker")}var f="[data-toggle=bfh-colorpicker]",g=function(b,c){this.options=a.extend({},a.fn.bfhcolorpicker.defaults,c),this.$element=a(b),this.initPopover()};g.prototype={constructor:g,initPalette:function(){var a,b,c;a=this.$element.find("canvas"),b=a[0].getContext("2d"),c=b.createLinearGradient(0,0,a.width(),0),c.addColorStop(0,"rgb(255, 255, 255)"),c.addColorStop(.1,"rgb(255, 0, 0)"),c.addColorStop(.25,"rgb(255, 0, 255)"),c.addColorStop(.4,"rgb(0, 0, 255)"),c.addColorStop(.55,"rgb(0, 255, 255)"),c.addColorStop(.7,"rgb(0, 255, 0)"),c.addColorStop(.85,"rgb(255, 255, 0)"),c.addColorStop(1,"rgb(255, 0, 0)"),b.fillStyle=c,b.fillRect(0,0,b.canvas.width,b.canvas.height),c=b.createLinearGradient(0,0,0,a.height()),c.addColorStop(0,"rgba(255, 255, 255, 1)"),c.addColorStop(.5,"rgba(255, 255, 255, 0)"),c.addColorStop(.5,"rgba(0, 0, 0, 0)"),c.addColorStop(1,"rgba(0, 0, 0, 1)"),b.fillStyle=c,b.fillRect(0,0,b.canvas.width,b.canvas.height)},initPopover:function(){var a,b;a="",b="","right"===this.options.align?b='<span class="input-group-addon"><span class="bfh-colorpicker-icon"></span></span>':a='<span class="input-group-addon"><span class="bfh-colorpicker-icon"></span></span>',this.$element.html('<div class="input-group bfh-colorpicker-toggle" data-toggle="bfh-colorpicker">'+a+'<input type="text" name="'+this.options.name+'" class="'+this.options.input+'" placeholder="'+this.options.placeholder+'" readonly>'+b+"</div>"+'<div class="bfh-colorpicker-popover">'+'<canvas class="bfh-colorpicker-palette" width="384" height="256"></canvas>'+"</div>"),this.$element.on("click.bfhcolorpicker.data-api touchstart.bfhcolorpicker.data-api",f,g.prototype.toggle).on("mousedown.bfhcolorpicker.data-api","canvas",g.prototype.mouseDown).on("click.bfhcolorpicker.data-api touchstart.bfhcolorpicker.data-api",".bfh-colorpicker-popover",function(){return!1}),this.initPalette(),this.$element.val(this.options.color)},updateVal:function(a,b){var d,e,f,g,h,i,j;h=5,d=this.$element.find("canvas"),e=d[0].getContext("2d"),f=a-d.offset().left,g=b-d.offset().top,f=Math.round(f/h)*h,g=Math.round(g/h)*h,0>f&&(f=0),f>=d.width()&&(f=d.width()-1),0>g&&(g=0),g>d.height()&&(g=d.height()),i=e.getImageData(f,g,1,1),j=c(i.data[0],i.data[1],i.data[2]),j!==this.$element.val()&&(this.$element.val(j),this.$element.trigger("change.bfhcolorpicker"))},mouseDown:function(){var b,c;b=a(this),c=e(b),a(document).on("mousemove.bfhcolorpicker.data-api",{colorpicker:c},g.prototype.mouseMove).one("mouseup.bfhcolorpicker.data-api",{colorpicker:c},g.prototype.mouseUp)},mouseMove:function(a){var b;b=a.data.colorpicker,b.data("bfhcolorpicker").updateVal(a.pageX,a.pageY)},mouseUp:function(b){var c;c=b.data.colorpicker,c.data("bfhcolorpicker").updateVal(b.pageX,b.pageY),a(document).off("mousemove.bfhcolorpicker.data-api"),c.data("bfhcolorpicker").options.close===!0&&d()},toggle:function(b){var c,f,g;if(c=a(this),f=e(c),f.is(".disabled")||void 0!==f.attr("disabled"))return!0;if(g=f.hasClass("open"),d(),!g){if(f.trigger(b=a.Event("show.bfhcolorpicker")),b.isDefaultPrevented())return!0;f.toggleClass("open").trigger("shown.bfhcolorpicker"),c.focus()}return!1}};var h=a.fn.bfhcolorpicker;a.fn.bfhcolorpicker=function(b){return this.each(function(){var c,d,e;c=a(this),d=c.data("bfhcolorpicker"),e="object"==typeof b&&b,this.type="bfhcolorpicker",d||c.data("bfhcolorpicker",d=new g(this,e)),"string"==typeof b&&d[b].call(c)})},a.fn.bfhcolorpicker.Constructor=g,a.fn.bfhcolorpicker.defaults={align:"left",input:"form-control",placeholder:"",name:"",color:"#000000",close:!0},a.fn.bfhcolorpicker.noConflict=function(){return a.fn.bfhcolorpicker=h,this};var i;a.valHooks.div&&(i=a.valHooks.div),a.valHooks.div={get:function(b){return a(b).hasClass("bfh-colorpicker")?a(b).find('input[type="text"]').val():i?i.get(b):void 0},set:function(b,c){if(a(b).hasClass("bfh-colorpicker"))a(b).find(".bfh-colorpicker-icon").css("background-color",c),a(b).find('input[type="text"]').val(c);else if(i)return i.set(b,c)}},a(document).ready(function(){a("div.bfh-colorpicker").each(function(){var b;b=a(this),b.bfhcolorpicker(b.data())})}),a(document).on("click.bfhcolorpicker.data-api",d)}(window.jQuery),+function(a){"use strict";var b=function(b,c){this.options=a.extend({},a.fn.bfhcountries.defaults,c),this.$element=a(b),this.$element.is("select")&&this.addCountries(),this.$element.hasClass("bfh-selectbox")&&this.addBootstrapCountries(),this.$element.is("span")&&this.displayCountry()};b.prototype={constructor:b,getCountries:function(){var b,c;if(this.options.available){if("string"==typeof this.options.available){c=[],this.options.available=this.options.available.split(",");for(b in BFHCountriesList)BFHCountriesList.hasOwnProperty(b)&&a.inArray(b,this.options.available)>=0&&(c[b]=BFHCountriesList[b])}else c=this.options.available;return c}return BFHCountriesList},addCountries:function(){var a,b,c;a=this.options.country,c=this.getCountries(),this.$element.html(""),this.options.blank===!0&&this.$element.append('<option value=""></option>');for(b in c)c.hasOwnProperty(b)&&this.$element.append('<option value="'+b+'">'+c[b]+"</option>");this.$element.val(a)},addBootstrapCountries:function(){var a,b,c,d,e,f;d=this.options.country,a=this.$element.find('input[type="hidden"]'),b=this.$element.find(".bfh-selectbox-option"),c=this.$element.find("[role=option]"),f=this.getCountries(),c.html(""),this.options.blank===!0&&c.append('<li><a tabindex="-1" href="#" data-option=""></a></li>');for(e in f)f.hasOwnProperty(e)&&(this.options.flags===!0?c.append('<li><a tabindex="-1" href="#" data-option="'+e+'"><i class="glyphicon bfh-flag-'+e+'"></i>'+f[e]+"</a></li>"):c.append('<li><a tabindex="-1" href="#" data-option="'+e+'">'+f[e]+"</a></li>"));this.$element.val(d)},displayCountry:function(){var a;a=this.options.country,this.options.flags===!0?this.$element.html('<i class="glyphicon bfh-flag-'+a+'"></i> '+BFHCountriesList[a]):this.$element.html(BFHCountriesList[a])}};var c=a.fn.bfhcountries;a.fn.bfhcountries=function(c){return this.each(function(){var d,e,f;d=a(this),e=d.data("bfhcountries"),f="object"==typeof c&&c,e||d.data("bfhcountries",e=new b(this,f)),"string"==typeof c&&e[c].call(d)})},a.fn.bfhcountries.Constructor=b,a.fn.bfhcountries.defaults={country:"",available:"",flags:!1,blank:!0},a.fn.bfhcountries.noConflict=function(){return a.fn.bfhcountries=c,this},a(document).ready(function(){a("form select.bfh-countries, span.bfh-countries, div.bfh-countries").each(function(){var b;b=a(this),b.hasClass("bfh-selectbox")&&b.bfhselectbox(b.data()),b.bfhcountries(b.data())})})}(window.jQuery),+function(a){"use strict";var b=function(b,c){this.options=a.extend({},a.fn.bfhcurrencies.defaults,c),this.$element=a(b),this.$element.is("select")&&this.addCurrencies(),this.$element.hasClass("bfh-selectbox")&&this.addBootstrapCurrencies(),this.$element.is("span")&&this.displayCurrency()};b.prototype={constructor:b,getCurrencies:function(){var b,c;if(this.options.available){c=[],this.options.available=this.options.available.split(",");for(b in BFHCurrenciesList)BFHCurrenciesList.hasOwnProperty(b)&&a.inArray(b,this.options.available)>=0&&(c[b]=BFHCurrenciesList[b]);return c}return BFHCurrenciesList},addCurrencies:function(){var a,b,c;a=this.options.currency,c=this.getCurrencies(),this.$element.html(""),this.options.blank===!0&&this.$element.append('<option value=""></option>');for(b in c)c.hasOwnProperty(b)&&this.$element.append('<option value="'+b+'">'+c[b].label+"</option>");this.$element.val(a)},addBootstrapCurrencies:function(){var a,b,c,d,e,f,g;d=this.options.currency,a=this.$element.find('input[type="hidden"]'),b=this.$element.find(".bfh-selectbox-option"),c=this.$element.find("[role=option]"),f=this.getCurrencies(),c.html(""),this.options.blank===!0&&c.append('<li><a tabindex="-1" href="#" data-option=""></a></li>');for(e in f)f.hasOwnProperty(e)&&(this.options.flags===!0?(g=f[e].currencyflag?f[e].currencyflag:e.substr(0,2),c.append('<li><a tabindex="-1" href="#" data-option="'+e+'"><i class="glyphicon bfh-flag-'+g+'"></i>'+f[e].label+"</a></li>")):c.append('<li><a tabindex="-1" href="#" data-option="'+e+'">'+f[e].label+"</a></li>"));this.$element.val(d)},displayCurrency:function(){var a,b;a=this.options.currency,this.options.flags===!0?(b=BFHCurrenciesList[a].currencyflag?BFHCurrenciesList[a].currencyflag:a.substr(0,2),this.$element.html('<i class="glyphicon bfh-flag-'+b+'"></i> '+BFHCurrenciesList[a].label)):this.$element.html(BFHCurrenciesList[a].label)}};var c=a.fn.bfhcurrencies;a.fn.bfhcurrencies=function(c){return this.each(function(){var d,e,f;d=a(this),e=d.data("bfhcurrencies"),f="object"==typeof c&&c,e||d.data("bfhcurrencies",e=new b(this,f)),"string"==typeof c&&e[c].call(d)})},a.fn.bfhcurrencies.Constructor=b,a.fn.bfhcurrencies.defaults={currency:"",available:"",flags:!1,blank:!0},a.fn.bfhcurrencies.noConflict=function(){return a.fn.bfhcurrencies=c,this},a(document).ready(function(){a("form select.bfh-currencies, span.bfh-currencies, div.bfh-currencies").each(function(){var b;b=a(this),b.hasClass("bfh-selectbox")&&b.bfhselectbox(b.data()),b.bfhcurrencies(b.data())})})}(window.jQuery),+function(a){"use strict";function b(a,b){return new Date(b,a,0).getDate()}function c(a,b,c){return new Date(b,a,c).getDay()}function d(a,b,c,d){return b+=1,b=String(b),d=String(d),1===b.length&&(b="0"+b),1===d.length&&(d="0"+d),a.replace("m",b).replace("y",c).replace("d",d)}function e(a,b,c){var d,e,f;d=[{part:"m",position:a.indexOf("m")},{part:"y",position:a.indexOf("y")},{part:"d",position:a.indexOf("d")}],d.sort(function(a,b){return a.position-b.position}),f=b.match(/(\d+)/g);for(e in d)if(d.hasOwnProperty(e)&&d[e].part===c)return Number(f[e]).toString()}function f(){var b;a(h).each(function(c){return b=g(a(this)),b.hasClass("open")?(b.trigger(c=a.Event("hide.bfhdatepicker")),c.isDefaultPrevented()?!0:(b.removeClass("open").trigger("hidden.bfhdatepicker"),void 0)):!0})}function g(a){return a.closest(".bfh-datepicker")}var h="[data-toggle=bfh-datepicker]",i=function(b,c){this.options=a.extend({},a.fn.bfhdatepicker.defaults,c),this.$element=a(b),this.initCalendar()};i.prototype={constructor:i,setDate:function(){var a,b,c;a=this.options.date,c=this.options.format,""===a||"today"===a||void 0===a?(b=new Date,"today"===a&&this.$element.val(d(c,b.getMonth(),b.getFullYear(),b.getDate())),this.$element.data("month",b.getMonth()),this.$element.data("year",b.getFullYear())):(this.$element.val(a),this.$element.data("month",Number(e(c,a,"m")-1)),this.$element.data("year",Number(e(c,a,"y"))))},setDateLimit:function(a,b){var c,d;d=this.options.format,""!==a?(this.$element.data(b+"limit",!0),"today"===a?(c=new Date,this.$element.data(b+"day",c.getDate()),this.$element.data(b+"month",c.getMonth()),this.$element.data(b+"year",c.getFullYear())):(this.$element.data(b+"day",Number(e(d,a,"d"))),this.$element.data(b+"month",Number(e(d,a,"m")-1)),this.$element.data(b+"year",Number(e(d,a,"y"))))):this.$element.data(b+"limit",!1)},initCalendar:function(){var a,b,c;a="",b="",c="",""!==this.options.icon&&("right"===this.options.align?b='<span class="input-group-addon"><i class="'+this.options.icon+'"></i></span>':a='<span class="input-group-addon"><i class="'+this.options.icon+'"></i></span>',c="input-group"),this.$element.html('<div class="'+c+' bfh-datepicker-toggle" data-toggle="bfh-datepicker">'+a+'<input type="text" name="'+this.options.name+'" class="'+this.options.input+'" placeholder="'+this.options.placeholder+'" readonly>'+b+"</div>"+'<div class="bfh-datepicker-calendar">'+'<table class="calendar table table-bordered">'+"<thead>"+'<tr class="months-header">'+'<th class="month" colspan="4">'+'<a class="previous" href="#"><i class="glyphicon glyphicon-chevron-left"></i></a>'+"<span></span>"+'<a class="next" href="#"><i class="glyphicon glyphicon-chevron-right"></i></a>'+"</th>"+'<th class="year" colspan="3">'+'<a class="previous" href="#"><i class="glyphicon glyphicon-chevron-left"></i></a>'+"<span></span>"+'<a class="next" href="#"><i class="glyphicon glyphicon-chevron-right"></i></a>'+"</th>"+"</tr>"+'<tr class="days-header">'+"</tr>"+"</thead>"+"<tbody>"+"</tbody>"+"</table>"+"</div>"),this.$element.on("click.bfhdatepicker.data-api touchstart.bfhdatepicker.data-api",h,i.prototype.toggle).on("click.bfhdatepicker.data-api touchstart.bfhdatepicker.data-api",".bfh-datepicker-calendar > table.calendar .month > .previous",i.prototype.previousMonth).on("click.bfhdatepicker.data-api touchstart.bfhdatepicker.data-api",".bfh-datepicker-calendar > table.calendar .month > .next",i.prototype.nextMonth).on("click.bfhdatepicker.data-api touchstart.bfhdatepicker.data-api",".bfh-datepicker-calendar > table.calendar .year > .previous",i.prototype.previousYear).on("click.bfhdatepicker.data-api touchstart.bfhdatepicker.data-api",".bfh-datepicker-calendar > table.calendar .year > .next",i.prototype.nextYear).on("click.bfhdatepicker.data-api touchstart.bfhdatepicker.data-api",".bfh-datepicker-calendar > table.calendar td:not(.off)",i.prototype.select).on("click.bfhdatepicker.data-api touchstart.bfhdatepicker.data-api",".bfh-datepicker-calendar > table.calendar",function(){return!1}),this.setDate(),this.setDateLimit(this.options.min,"lower"),this.setDateLimit(this.options.max,"higher"),this.updateCalendar()},updateCalendarHeader:function(a,b,c){var d,e;for(a.find("table > thead > tr > th.month > span").text(BFHMonthsList[b]),a.find("table > thead > tr > th.year > span").text(c),d=a.find("table > thead > tr.days-header"),d.html(""),e=BFHDayOfWeekStart;e<BFHDaysList.length;e+=1)d.append("<th>"+BFHDaysList[e]+"</th>");for(e=0;BFHDayOfWeekStart>e;e+=1)d.append("<th>"+BFHDaysList[e]+"</th>")},checkMinDate:function(a,b,c){var d,e,f,g;return d=this.$element.data("lowerlimit"),d===!0&&(e=this.$element.data("lowerday"),f=this.$element.data("lowermonth"),g=this.$element.data("loweryear"),e>a&&b===f&&c===g||f>b&&c===g||g>c)?!0:!1},checkMaxDate:function(a,b,c){var d,e,f,g;return d=this.$element.data("higherlimit"),d===!0&&(e=this.$element.data("higherday"),f=this.$element.data("highermonth"),g=this.$element.data("higheryear"),a>e&&b===f&&c===g||b>f&&c===g||c>g)?!0:!1},checkToday:function(a,b,c){var d;return d=new Date,a===d.getDate()&&b===d.getMonth()&&c===d.getFullYear()?!0:!1},updateCalendarDays:function(a,d,e){var f,g,h,i,j,k,l;for(f=a.find("table > tbody").html(""),g=b(d,e),h=b(d+1,e),i=c(d,e,1),j=c(d,e,h),k="",l=0;(i-BFHDayOfWeekStart+7)%7>l;l+=1)k+='<td class="off">'+(g-(i-BFHDayOfWeekStart+7)%7+l+1)+"</td>";for(l=1;h>=l;l+=1)k+=this.checkMinDate(l,d,e)?'<td data-day="'+l+'" class="off">'+l+"</td>":this.checkMaxDate(l,d,e)?'<td data-day="'+l+'" class="off">'+l+"</td>":this.checkToday(l,d,e)?'<td data-day="'+l+'" class="today">'+l+"</td>":'<td data-day="'+l+'">'+l+"</td>",c(d,e,l)===(6+BFHDayOfWeekStart)%7&&(f.append("<tr>"+k+"</tr>"),k="");for(l=1;(7-(j+1-BFHDayOfWeekStart+7)%7)%7+1>=l;l+=1)k+='<td class="off">'+l+"</td>",l===(7-(j+1-BFHDayOfWeekStart+7)%7)%7&&f.append("<tr>"+k+"</tr>")},updateCalendar:function(){var a,b,c;a=this.$element.find(".bfh-datepicker-calendar"),b=this.$element.data("month"),c=this.$element.data("year"),this.updateCalendarHeader(a,b,c),this.updateCalendarDays(a,b,c)},previousMonth:function(){var b,c,d;return b=a(this),c=g(b),0===Number(c.data("month"))?(c.data("month",11),c.data("year",Number(c.data("year"))-1)):c.data("month",Number(c.data("month"))-1),d=c.data("bfhdatepicker"),d.updateCalendar(),!1},nextMonth:function(){var b,c,d;return b=a(this),c=g(b),11===Number(c.data("month"))?(c.data("month",0),c.data("year",Number(c.data("year"))+1)):c.data("month",Number(c.data("month"))+1),d=c.data("bfhdatepicker"),d.updateCalendar(),!1},previousYear:function(){var b,c,d;return b=a(this),c=g(b),c.data("year",Number(c.data("year"))-1),d=c.data("bfhdatepicker"),d.updateCalendar(),!1},nextYear:function(){var b,c,d;return b=a(this),c=g(b),c.data("year",Number(c.data("year"))+1),d=c.data("bfhdatepicker"),d.updateCalendar(),!1},select:function(b){var c,e,h,i,j,k;c=a(this),b.preventDefault(),b.stopPropagation(),e=g(c),h=e.data("bfhdatepicker"),i=e.data("month"),j=e.data("year"),k=c.data("day"),e.val(d(h.options.format,i,j,k)),e.trigger("change.bfhdatepicker"),h.options.close===!0&&f()},toggle:function(b){var c,d,e;if(c=a(this),d=g(c),d.is(".disabled")||void 0!==d.attr("disabled"))return!0;if(e=d.hasClass("open"),f(),!e){if(d.trigger(b=a.Event("show.bfhdatepicker")),b.isDefaultPrevented())return!0;d.toggleClass("open").trigger("shown.bfhdatepicker"),c.focus()}return!1}};var j=a.fn.bfhdatepicker;a.fn.bfhdatepicker=function(b){return this.each(function(){var c,d,e;c=a(this),d=c.data("bfhdatepicker"),e="object"==typeof b&&b,this.type="bfhdatepicker",d||c.data("bfhdatepicker",d=new i(this,e)),"string"==typeof b&&d[b].call(c)})},a.fn.bfhdatepicker.Constructor=i,a.fn.bfhdatepicker.defaults={icon:"glyphicon glyphicon-calendar",align:"left",input:"form-control",placeholder:"",name:"",date:"today",format:"m/d/y",min:"",max:"",close:!0},a.fn.bfhdatepicker.noConflict=function(){return a.fn.bfhdatepicker=j,this};var k;a.valHooks.div&&(k=a.valHooks.div),a.valHooks.div={get:function(b){return a(b).hasClass("bfh-datepicker")?a(b).find('input[type="text"]').val():k?k.get(b):void 0},set:function(b,c){if(a(b).hasClass("bfh-datepicker"))a(b).find('input[type="text"]').val(c);else if(k)return k.set(b,c)}},a(document).ready(function(){a("div.bfh-datepicker").each(function(){var b;b=a(this),b.bfhdatepicker(b.data())})}),a(document).on("click.bfhdatepicker.data-api",f)}(window.jQuery),+function(a){"use strict";var b=function(b,c){this.options=a.extend({},a.fn.bfhfonts.defaults,c),this.$element=a(b),this.$element.is("select")&&this.addFonts(),this.$element.hasClass("bfh-selectbox")&&this.addBootstrapFonts()};b.prototype={constructor:b,getFonts:function(){var b,c;if(this.options.available){c=[],this.options.available=this.options.available.split(",");for(b in BFHFontsList)BFHFontsList.hasOwnProperty(b)&&a.inArray(b,this.options.available)>=0&&(c[b]=BFHFontsList[b]);return c}return BFHFontsList},addFonts:function(){var a,b,c;a=this.options.font,c=this.getFonts(),this.$element.html(""),this.options.blank===!0&&this.$element.append('<option value=""></option>');for(b in c)c.hasOwnProperty(b)&&this.$element.append('<option value="'+b+'">'+b+"</option>");this.$element.val(a)},addBootstrapFonts:function(){var a,b,c,d,e,f;d=this.options.font,a=this.$element.find('input[type="hidden"]'),b=this.$element.find(".bfh-selectbox-option"),c=this.$element.find("[role=option]"),f=this.getFonts(),c.html(""),this.options.blank===!0&&c.append('<li><a tabindex="-1" href="#" data-option=""></a></li>');for(e in f)f.hasOwnProperty(e)&&c.append('<li><a tabindex="-1" href="#" style=\'font-family: '+f[e]+"' data-option=\""+e+'">'+e+"</a></li>");this.$element.val(d)}};var c=a.fn.bfhfonts;a.fn.bfhfonts=function(c){return this.each(function(){var d,e,f;d=a(this),e=d.data("bfhfonts"),f="object"==typeof c&&c,e||d.data("bfhfonts",e=new b(this,f)),"string"==typeof c&&e[c].call(d)})},a.fn.bfhfonts.Constructor=b,a.fn.bfhfonts.defaults={font:"",available:"",blank:!0},a.fn.bfhfonts.noConflict=function(){return a.fn.bfhfonts=c,this},a(document).ready(function(){a("form select.bfh-fonts, span.bfh-fonts, div.bfh-fonts").each(function(){var b;b=a(this),b.hasClass("bfh-selectbox")&&b.bfhselectbox(b.data()),b.bfhfonts(b.data())})})}(window.jQuery),+function(a){"use strict";var b=function(b,c){this.options=a.extend({},a.fn.bfhfontsizes.defaults,c),this.$element=a(b),this.$element.is("select")&&this.addFontSizes(),this.$element.hasClass("bfh-selectbox")&&this.addBootstrapFontSizes()};b.prototype={constructor:b,getFontsizes:function(){var b,c;if(this.options.available){c=[],this.options.available=this.options.available.split(",");for(b in BFHFontSizesList)BFHFontSizesList.hasOwnProperty(b)&&a.inArray(b,this.options.available)>=0&&(c[b]=BFHFontSizesList[b]);return c}return BFHFontSizesList},addFontSizes:function(){var a,b,c;a=this.options.fontsize,c=this.getFontsizes(),this.$element.html(""),this.options.blank===!0&&this.$element.append('<option value=""></option>');for(b in c)c.hasOwnProperty(b)&&this.$element.append('<option value="'+b+'">'+c[b]+"</option>");this.$element.val(a)},addBootstrapFontSizes:function(){var a,b,c,d,e,f;d=this.options.fontsize,a=this.$element.find('input[type="hidden"]'),b=this.$element.find(".bfh-selectbox-option"),c=this.$element.find("[role=option]"),f=this.getFontsizes(),c.html(""),this.options.blank===!0&&c.append('<li><a tabindex="-1" href="#" data-option=""></a></li>');for(e in f)f.hasOwnProperty(e)&&c.append('<li><a tabindex="-1" href="#" data-option="'+e+'">'+f[e]+"</a></li>");this.$element.val(d)}};var c=a.fn.bfhfontsizes;a.fn.bfhfontsizes=function(c){return this.each(function(){var d,e,f;d=a(this),e=d.data("bfhfontsizes"),f="object"==typeof c&&c,e||d.data("bfhfontsizes",e=new b(this,f)),"string"==typeof c&&e[c].call(d)})},a.fn.bfhfontsizes.Constructor=b,a.fn.bfhfontsizes.defaults={fontsize:"",available:"",blank:!0},a.fn.bfhfontsizes.noConflict=function(){return a.fn.bfhfontsizes=c,this},a(document).ready(function(){a("form select.bfh-fontsizes, span.bfh-fontsizes, div.bfh-fontsizes").each(function(){var b;b=a(this),b.hasClass("bfh-selectbox")&&b.bfhselectbox(b.data()),b.bfhfontsizes(b.data())})})}(window.jQuery),+function(a){"use strict";var b=function(b,c){this.options=a.extend({},a.fn.bfhgooglefonts.defaults,c),this.$element=a(b),this.$element.is("select")&&this.addFonts(),this.$element.hasClass("bfh-selectbox")&&this.addBootstrapFonts()};b.prototype={constructor:b,getFonts:function(){var b,c;if(c=[],this.options.subset)for(b in BFHGoogleFontsList.items)BFHGoogleFontsList.items.hasOwnProperty(b)&&a.inArray(this.options.subset,BFHGoogleFontsList.items[b].subsets)>=0&&(c[BFHGoogleFontsList.items[b].family]={info:BFHGoogleFontsList.items[b],index:parseInt(b,10)});else if(this.options.available){this.options.available=this.options.available.split(",");for(b in BFHGoogleFontsList.items)BFHGoogleFontsList.items.hasOwnProperty(b)&&a.inArray(BFHGoogleFontsList.items[b].family,this.options.available)>=0&&(c[BFHGoogleFontsList.items[b].family]={info:BFHGoogleFontsList.items[b],index:parseInt(b,10)})}else for(b in BFHGoogleFontsList.items)BFHGoogleFontsList.items.hasOwnProperty(b)&&(c[BFHGoogleFontsList.items[b].family]={info:BFHGoogleFontsList.items[b],index:parseInt(b,10)});return c},addFonts:function(){var a,b,c;a=this.options.font,c=this.getFonts(),this.$element.html(""),this.options.blank===!0&&this.$element.append('<option value=""></option>');for(b in c)c.hasOwnProperty(b)&&this.$element.append('<option value="'+c[b].info.family+'">'+c[b].info.family+"</option>");this.$element.val(a)},addBootstrapFonts:function(){var a,b,c,d,e,f;d=this.options.font,a=this.$element.find('input[type="hidden"]'),b=this.$element.find(".bfh-selectbox-option"),c=this.$element.find("[role=option]"),f=this.getFonts(),c.html(""),this.options.blank===!0&&c.append('<li><a tabindex="-1" href="#" data-option="" style="background-image: none;"></a></li>');for(e in f)f.hasOwnProperty(e)&&c.append('<li><a tabindex="-1" href="#" style="background-position: 0 -'+(30*f[e].index-2)+'px;" data-option="'+f[e].info.family+'">'+f[e].info.family+"</a></li>");this.$element.val(d)}};var c=a.fn.bfhgooglefonts;a.fn.bfhgooglefonts=function(c){return this.each(function(){var d,e,f;d=a(this),e=d.data("bfhgooglefonts"),f="object"==typeof c&&c,e||d.data("bfhgooglefonts",e=new b(this,f)),"string"==typeof c&&e[c].call(d)})},a.fn.bfhgooglefonts.Constructor=b,a.fn.bfhgooglefonts.defaults={font:"",available:"",subset:"",blank:!0},a.fn.bfhgooglefonts.noConflict=function(){return a.fn.bfhgooglefonts=c,this},a(document).ready(function(){a("form select.bfh-googlefonts, span.bfh-googlefonts, div.bfh-googlefonts").each(function(){var b;b=a(this),b.hasClass("bfh-selectbox")&&b.bfhselectbox(b.data()),b.bfhgooglefonts(b.data())})})}(window.jQuery),+function(a){"use strict";var b=function(b,c){this.options=a.extend({},a.fn.bfhlanguages.defaults,c),this.$element=a(b),this.$element.is("select")&&this.addLanguages(),this.$element.is("span")&&this.displayLanguage(),this.$element.hasClass("bfh-selectbox")&&this.addBootstrapLanguages()};b.prototype={constructor:b,getLanguages:function(){var a,b,c;if(this.options.available){c=[],this.options.available=this.options.available.split(",");for(b in this.options.available)this.options.available.hasOwnProperty(b)&&(-1!==this.options.available[b].indexOf("_")?(a=this.options.available[b].split("_"),c[a[0]]={name:BFHLanguagesList[a[0]],country:a[1]}):c[this.options.available[b]]=BFHLanguagesList[this.options.available[b]]);return c}return BFHLanguagesList},addLanguages:function(){var a,b,c;a=this.options.language,b=this.getLanguages(),this.$element.html(""),this.options.blank===!0&&this.$element.append('<option value=""></option>');for(c in b)b.hasOwnProperty(c)&&(b[c].hasOwnProperty("name")?this.$element.append('<option value="'+c+"_"+b[c].country+'">'+b[c].name.toProperCase()+" ("+BFHCountriesList[b[c].country]+")</option>"):this.$element.append('<option value="'+c+'">'+b[c].toProperCase()+"</option>"));this.$element.val(a)},addBootstrapLanguages:function(){var a,b,c,d,e,f;d=this.options.language,a=this.$element.find('input[type="hidden"]'),b=this.$element.find(".bfh-selectbox-option"),c=this.$element.find("[role=option]"),e=this.getLanguages(),c.html(""),this.options.blank===!0&&c.append('<li><a tabindex="-1" href="#" data-option=""></a></li>');for(f in e)e.hasOwnProperty(f)&&(e[f].hasOwnProperty("name")?this.options.flags===!0?c.append('<li><a tabindex="-1" href="#" data-option="'+f+"_"+e[f].country+'"><i class="glyphicon bfh-flag-'+e[f].country+'"></i>'+e[f].name.toProperCase()+"</a></li>"):c.append('<li><a tabindex="-1" href="#" data-option="'+f+"_"+e[f].country+'">'+e[f].name.toProperCase()+" ("+BFHCountriesList[e[f].country]+")</a></li>"):c.append('<li><a tabindex="-1" href="#" data-option="'+f+'">'+e[f]+"</a></li>"));this.$element.val(d)},displayLanguage:function(){var a;a=this.options.language,-1!==a.indexOf("_")?(a=a.split("_"),this.options.flags===!0?this.$element.html('<i class="glyphicon bfh-flag-'+a[1]+'"></i> '+BFHLanguagesList[a[0]].toProperCase()):this.$element.html(BFHLanguagesList[a[0]].toProperCase()+" ("+BFHCountriesList[a[1]]+")")):this.$element.html(BFHLanguagesList[a].toProperCase())}};var c=a.fn.bfhlanguages;a.fn.bfhlanguages=function(c){return this.each(function(){var d,e,f;d=a(this),e=d.data("bfhlanguages"),f="object"==typeof c&&c,e||d.data("bfhlanguages",e=new b(this,f)),"string"==typeof c&&e[c].call(d)})},a.fn.bfhlanguages.Constructor=b,a.fn.bfhlanguages.defaults={language:"",available:"",flags:!1,blank:!0},a.fn.bfhlanguages.noConflict=function(){return a.fn.bfhlanguages=c,this},a(document).ready(function(){a("form select.bfh-languages, span.bfh-languages, div.bfh-languages").each(function(){var b;b=a(this),b.hasClass("bfh-selectbox")&&b.bfhselectbox(b.data()),b.bfhlanguages(b.data())})}),String.prototype.toProperCase=function(){return this.replace(/\w\S*/g,function(a){return a.charAt(0).toUpperCase()+a.substr(1).toLowerCase()})}}(window.jQuery),+function(a){"use strict";var b=function(b,c){this.options=a.extend({},a.fn.bfhnumber.defaults,c),this.$element=a(b),this.initInput()};b.prototype={constructor:b,initInput:function(){this.options.buttons===!0&&(this.$element.wrap('<div class="input-group"></div>'),this.$element.parent().append('<span class="input-group-addon bfh-number-btn inc"><span class="glyphicon glyphicon-chevron-up"></span></span>'),this.$element.parent().append('<span class="input-group-addon bfh-number-btn dec"><span class="glyphicon glyphicon-chevron-down"></span></span>')),this.$element.on("change.bfhnumber.data-api",b.prototype.change),this.options.keyboard===!0&&this.$element.on("keydown.bfhnumber.data-api",b.prototype.keydown),this.options.buttons===!0&&this.$element.parent().on("mousedown.bfhnumber.data-api",".inc",b.prototype.btninc).on("mousedown.bfhnumber.data-api",".dec",b.prototype.btndec),this.formatNumber()},keydown:function(b){var c;if(c=a(this).data("bfhnumber"),c.$element.is(".disabled")||void 0!==c.$element.attr("disabled"))return!0;switch(b.which){case 38:c.increment();break;case 40:c.decrement()}return!0},mouseup:function(a){var b,c,d;b=a.data.btn,c=b.$element.data("timer"),d=b.$element.data("interval"),clearTimeout(c),clearInterval(d)},btninc:function(){var c,d;return c=a(this).parent().find(".bfh-number").data("bfhnumber"),c.$element.is(".disabled")||void 0!==c.$element.attr("disabled")?!0:(c.increment(),d=setTimeout(function(){var a;a=setInterval(function(){c.increment()},80),c.$element.data("interval",a)},750),c.$element.data("timer",d),a(document).one("mouseup",{btn:c},b.prototype.mouseup),!0)},btndec:function(){var c,d;return c=a(this).parent().find(".bfh-number").data("bfhnumber"),c.$element.is(".disabled")||void 0!==c.$element.attr("disabled")?!0:(c.decrement(),d=setTimeout(function(){var a;a=setInterval(function(){c.decrement()},80),c.$element.data("interval",a)},750),c.$element.data("timer",d),a(document).one("mouseup",{btn:c},b.prototype.mouseup),!0)},change:function(){var b;return b=a(this).data("bfhnumber"),b.$element.is(".disabled")||void 0!==b.$element.attr("disabled")?!0:(b.formatNumber(),!0)},increment:function(){var a;a=this.getValue(),a+=1,this.$element.val(a).change()},decrement:function(){var a;a=this.getValue(),a-=1,this.$element.val(a).change()},getValue:function(){var a;return a=this.$element.val(),"-1"!==a&&(a=String(a).replace(/\D/g,"")),0===String(a).length&&(a=this.options.min),parseInt(a)},formatNumber:function(){var a,b,c,d;if(a=this.getValue(),a>this.options.max&&(a=this.options.wrap===!0?this.options.min:this.options.max),a<this.options.min&&(a=this.options.wrap===!0?this.options.max:this.options.min),this.options.zeros===!0)for(b=String(this.options.max).length,c=String(a).length,d=c;b>d;d+=1)a="0"+a;a!==this.$element.val()&&this.$element.val(a)}};var c=a.fn.bfhnumber;a.fn.bfhnumber=function(c){return this.each(function(){var d,e,f;d=a(this),e=d.data("bfhnumber"),f="object"==typeof c&&c,e||d.data("bfhnumber",e=new b(this,f)),"string"==typeof c&&e[c].call(d)})},a.fn.bfhnumber.Constructor=b,a.fn.bfhnumber.defaults={min:0,max:9999,zeros:!1,keyboard:!0,buttons:!0,wrap:!1},a.fn.bfhnumber.noConflict=function(){return a.fn.bfhnumber=c,this},a(document).ready(function(){a('form input[type="text"].bfh-number, form input[type="number"].bfh-number').each(function(){var b;b=a(this),b.bfhnumber(b.data())})})}(window.jQuery),+function(a){"use strict";function b(a,b){var c,d,e,f;for(c="",b=String(b).replace(/\D/g,""),d=0,e=0;d<a.length;d+=1)/\d/g.test(a.charAt(d))?a.charAt(d)===b.charAt(e)?(c+=b.charAt(e),e+=1):c+=a.charAt(d):"d"!==a.charAt(d)?(""!==b.charAt(e)||"+"===a.charAt(d))&&(c+=a.charAt(d)):""===b.charAt(e)?c+="":(c+=b.charAt(e),e+=1);return f=a.charAt(c.length),"d"!==f&&(c+=f),c}function c(a){var b,c=0;return document.selection?(a.focus(),b=document.selection.createRange(),b.moveStart("character",-a.value.length),c=b.text.length):(a.selectionStart||0===a.selectionStart)&&(c=a.selectionStart),c}function d(a,b){var c;document.selection?(a.focus(),c=document.selection.createRange(),c.moveStart("character",-a.value.length),c.moveStart("character",b),c.moveEnd("character",0),c.select()):(a.selectionStart||0===a.selectionStart)&&(a.selectionStart=b,a.selectionEnd=b,a.focus())}var e=function(b,c){this.options=a.extend({},a.fn.bfhphone.defaults,c),this.$element=a(b),(this.$element.is('input[type="text"]')||this.$element.is('input[type="tel"]'))&&this.addFormatter(),this.$element.is("span")&&this.displayFormatter() +};e.prototype={constructor:e,addFormatter:function(){var b;""!==this.options.country&&(b=a(document).find("#"+this.options.country),0!==b.length?(this.options.format=BFHPhoneFormatList[b.val()],b.on("change",{phone:this},this.changeCountry)):this.options.format=BFHPhoneFormatList[this.options.country]),this.$element.on("keyup.bfhphone.data-api",e.prototype.change),this.loadFormatter()},loadFormatter:function(){var a;a=b(this.options.format,this.$element.val()),this.$element.val(a)},displayFormatter:function(){var a;""!==this.options.country&&(this.options.format=BFHPhoneFormatList[this.options.country]),a=b(this.options.format,this.options.number),this.$element.html(a)},changeCountry:function(b){var c,d;c=a(this),d=b.data.phone,d.$element.val(String(d.$element.val()).replace(/\+\d*/g,"")),d.options.format=BFHPhoneFormatList[c.val()],d.loadFormatter()},change:function(e){var f,g,h,i;return f=a(this).data("bfhphone"),f.$element.is(".disabled")||void 0!==f.$element.attr("disabled")?!0:(g=c(f.$element[0]),h=!1,g===f.$element.val().length&&(h=!0),8===e.which&&"d"!==f.options.format.charAt(f.$element.val().length)&&f.$element.val(String(f.$element.val()).substring(0,f.$element.val().length-1)),i=b(f.options.format,f.$element.val()),i===f.$element.val()?!0:(f.$element.val(i),h&&(g=f.$element.val().length),d(f.$element[0],g),!0))}};var f=a.fn.bfhphone;a.fn.bfhphone=function(b){return this.each(function(){var c,d,f;c=a(this),d=c.data("bfhphone"),f="object"==typeof b&&b,d||c.data("bfhphone",d=new e(this,f)),"string"==typeof b&&d[b].call(c)})},a.fn.bfhphone.Constructor=e,a.fn.bfhphone.defaults={format:"",number:"",country:""},a.fn.bfhphone.noConflict=function(){return a.fn.bfhphone=f,this},a(document).ready(function(){a('form input[type="text"].bfh-phone, form input[type="tel"].bfh-phone, span.bfh-phone').each(function(){var b;b=a(this),b.bfhphone(b.data())})})}(window.jQuery),+function(a){"use strict";function b(){var b;a(d).each(function(d){return b=c(a(this)),b.hasClass("open")?(b.trigger(d=a.Event("hide.bfhselectbox")),d.isDefaultPrevented()?!0:(b.removeClass("open").trigger("hidden.bfhselectbox"),void 0)):!0})}function c(a){return a.closest(".bfh-selectbox")}var d="[data-toggle=bfh-selectbox]",e=function(b,c){this.options=a.extend({},a.fn.bfhselectbox.defaults,c),this.$element=a(b),this.initSelectBox()};e.prototype={constructor:e,initSelectBox:function(){var b;b="",this.$element.find("div").each(function(){b=b+'<li><a tabindex="-1" href="#" data-option="'+a(this).data("value")+'">'+a(this).html()+"</a></li>"}),this.$element.html('<input type="hidden" name="'+this.options.name+'" value="">'+'<a class="bfh-selectbox-toggle '+this.options.input+'" role="button" data-toggle="bfh-selectbox" href="#">'+'<span class="bfh-selectbox-option"></span>'+'<span class="'+this.options.icon+' selectbox-caret"></span>'+"</a>"+'<div class="bfh-selectbox-options">'+'<div role="listbox">'+'<ul role="option">'+"</ul>"+"</div>"+"</div>"),this.$element.find("[role=option]").html(b),this.options.filter===!0&&this.$element.find(".bfh-selectbox-options").prepend('<div class="bfh-selectbox-filter-container"><input type="text" class="bfh-selectbox-filter form-control"></div>'),this.$element.val(this.options.value),this.$element.on("click.bfhselectbox.data-api touchstart.bfhselectbox.data-api",d,e.prototype.toggle).on("keydown.bfhselectbox.data-api",d+", [role=option]",e.prototype.keydown).on("mouseenter.bfhselectbox.data-api","[role=option] > li > a",e.prototype.mouseenter).on("click.bfhselectbox.data-api","[role=option] > li > a",e.prototype.select).on("click.bfhselectbox.data-api",".bfh-selectbox-filter",function(){return!1}).on("propertychange.bfhselectbox.data-api change.bfhselectbox.data-api input.bfhselectbox.data-api paste.bfhselectbox.data-api",".bfh-selectbox-filter",e.prototype.filter)},toggle:function(d){var e,f,g;if(e=a(this),f=c(e),f.is(".disabled")||void 0!==f.attr("disabled"))return!0;if(g=f.hasClass("open"),b(),!g){if(f.trigger(d=a.Event("show.bfhselectbox")),d.isDefaultPrevented())return!0;f.toggleClass("open").trigger("shown.bfhselectbox").find('[role=option] > li > [data-option="'+f.val()+'"]').focus()}return!1},filter:function(){var b,d,e;b=a(this),d=c(b),e=a("[role=option] li a",d),e.hide().filter(function(){return-1!==a(this).text().toUpperCase().indexOf(b.val().toUpperCase())}).show()},keydown:function(b){var f,g,h,i,j;return/(38|40|27)/.test(b.keyCode)?(f=a(this),b.preventDefault(),b.stopPropagation(),h=c(f),i=h.hasClass("open"),!i||i&&27===b.keyCode?(27===b.which&&h.find(d).focus(),f.click()):(g=a("[role=option] li:not(.divider) a:visible",h),g.length?(a("body").off("mouseenter.bfh-selectbox.data-api","[role=option] > li > a",e.prototype.mouseenter),j=g.index(g.filter(":focus")),38===b.keyCode&&j>0&&(j-=1),40===b.keyCode&&j<g.length-1&&(j+=1),j||(j=0),g.eq(j).focus(),a("body").on("mouseenter.bfh-selectbox.data-api","[role=option] > li > a",e.prototype.mouseenter),void 0):!0)):!0},mouseenter:function(){var b;b=a(this),b.focus()},select:function(d){var e,f;return e=a(this),d.preventDefault(),d.stopPropagation(),e.is(".disabled")||void 0!==e.attr("disabled")?!0:(f=c(e),f.val(e.data("option")),f.trigger("change.bfhselectbox"),b(),void 0)}};var f=a.fn.bfhselectbox;a.fn.bfhselectbox=function(b){return this.each(function(){var c,d,f;c=a(this),d=c.data("bfhselectbox"),f="object"==typeof b&&b,this.type="bfhselectbox",d||c.data("bfhselectbox",d=new e(this,f)),"string"==typeof b&&d[b].call(c)})},a.fn.bfhselectbox.Constructor=e,a.fn.bfhselectbox.defaults={icon:"caret",input:"form-control",name:"",value:"",filter:!1},a.fn.bfhselectbox.noConflict=function(){return a.fn.bfhselectbox=f,this};var g;a.valHooks.div&&(g=a.valHooks.div),a.valHooks.div={get:function(b){return a(b).hasClass("bfh-selectbox")?a(b).find('input[type="hidden"]').val():g?g.get(b):void 0},set:function(b,c){var d,e;if(a(b).hasClass("bfh-selectbox"))d=a(b),d.find("li a[data-option='"+c+"']").length>0?e=d.find("li a[data-option='"+c+"']").html():d.find("li a").length>0?e=d.find("li a").eq(0).html():(c="",e=""),d.find('input[type="hidden"]').val(c),d.find(".bfh-selectbox-option").html(e);else if(g)return g.set(b,c)}},a(document).ready(function(){a("div.bfh-selectbox").each(function(){var b;b=a(this),b.bfhselectbox(b.data())})}),a(document).on("click.bfhselectbox.data-api",b)}(window.jQuery),+function(a){"use strict";var b=function(b,c){this.options=a.extend({},a.fn.bfhslider.defaults,c),this.$element=a(b),this.initSlider()};b.prototype={constructor:b,initSlider:function(){""===this.options.value&&(this.options.value=this.options.min),this.$element.html('<input type="hidden" name="'+this.options.name+'" value="">'+'<div class="bfh-slider-handle"><div class="bfh-slider-value"></div></div>'),this.$element.find('input[type="hidden"]').val(this.options.value),this.updateHandle(this.options.value),this.$element.on("mousedown.bfhslider.data-api",b.prototype.mouseDown)},updateHandle:function(a){var b,c,d,e;e=this.options.max-this.options.min,c=this.$element.width(),d=this.$element.position().left,b=Math.round((a-this.options.min)*(c-20)/e+d),this.$element.find(".bfh-slider-handle").css("left",b+"px"),this.$element.find(".bfh-slider-value").text(a)},updateVal:function(a){var b,c,d,e,f;return f=this.options.max-this.options.min,b=this.$element.width(),c=this.$element.offset().left,d=c+b,c>a&&(a=c),a+20>d&&(a=d),e=(a-c)/b,e=Math.ceil(e*f+this.options.min),e===this.$element.val()?!0:(this.$element.val(e),this.$element.trigger("change.bfhslider"),void 0)},mouseDown:function(){var c;return c=a(this),c.is(".disabled")||void 0!==c.attr("disabled")?!0:(a(document).on("mousemove.bfhslider.data-api",{slider:c},b.prototype.mouseMove).one("mouseup.bfhslider.data-api",{slider:c},b.prototype.mouseUp),void 0)},mouseMove:function(a){var b;b=a.data.slider,b.data("bfhslider").updateVal(a.pageX)},mouseUp:function(b){var c;c=b.data.slider,c.data("bfhslider").updateVal(b.pageX),a(document).off("mousemove.bfhslider.data-api")}};var c=a.fn.bfhslider;a.fn.bfhslider=function(c){return this.each(function(){var d,e,f;d=a(this),e=d.data("bfhslider"),f="object"==typeof c&&c,this.type="bfhslider",e||d.data("bfhslider",e=new b(this,f)),"string"==typeof c&&e[c].call(d)})},a.fn.bfhslider.Constructor=b,a.fn.bfhslider.defaults={name:"",value:"",min:0,max:100},a.fn.bfhslider.noConflict=function(){return a.fn.bfhslider=c,this};var d;a.valHooks.div&&(d=a.valHooks.div),a.valHooks.div={get:function(b){return a(b).hasClass("bfh-slider")?a(b).find('input[type="hidden"]').val():d?d.get(b):void 0},set:function(b,c){if(a(b).hasClass("bfh-slider"))a(b).find('input[type="hidden"]').val(c),a(b).data("bfhslider").updateHandle(c);else if(d)return d.set(b,c)}},a(document).ready(function(){a("div.bfh-slider").each(function(){var b;b=a(this),b.bfhslider(b.data())})})}(window.jQuery),+function(a){"use strict";var b=function(b,c){this.options=a.extend({},a.fn.bfhstates.defaults,c),this.$element=a(b),this.$element.is("select")&&this.addStates(),this.$element.hasClass("bfh-selectbox")&&this.addBootstrapStates(),this.$element.is("span")&&this.displayState()};b.prototype={constructor:b,addStates:function(){var b,c;b=this.options.country,""!==b&&(c=a(document).find("#"+b),0!==c.length&&(b=c.val(),c.on("change",{state:this},this.changeCountry))),this.loadStates(b)},loadStates:function(a){var b,c;b=this.options.state,this.$element.html(""),this.options.blank===!0&&this.$element.append('<option value=""></option>');for(c in BFHStatesList[a])BFHStatesList[a].hasOwnProperty(c)&&this.$element.append('<option value="'+BFHStatesList[a][c].code+'">'+BFHStatesList[a][c].name+"</option>");this.$element.val(b)},changeCountry:function(b){var c,d,e;c=a(this),d=b.data.state,e=c.val(),d.loadStates(e)},addBootstrapStates:function(){var b,c;b=this.options.country,""!==b&&(c=a(document).find("#"+b),0!==c.length&&(b=c.find('input[type="hidden"]').val(),c.on("change.bfhselectbox",{state:this},this.changeBootstrapCountry))),this.loadBootstrapStates(b)},loadBootstrapStates:function(a){var b,c,d,e,f,g;e=this.options.state,f="",b=this.$element.find('input[type="hidden"]'),c=this.$element.find(".bfh-selectbox-option"),d=this.$element.find("[role=option]"),d.html(""),this.options.blank===!0&&d.append('<li><a tabindex="-1" href="#" data-option=""></a></li>');for(g in BFHStatesList[a])BFHStatesList[a].hasOwnProperty(g)&&(d.append('<li><a tabindex="-1" href="#" data-option="'+BFHStatesList[a][g].code+'">'+BFHStatesList[a][g].name+"</a></li>"),BFHStatesList[a][g].code===e&&(f=BFHStatesList[a][g].name));this.$element.val(e)},changeBootstrapCountry:function(b){var c,d,e;c=a(this),d=b.data.state,e=c.val(),d.loadBootstrapStates(e)},displayState:function(){var a,b,c,d;a=this.options.country,b=this.options.state,c="";for(d in BFHStatesList[a])if(BFHStatesList[a].hasOwnProperty(d)&&BFHStatesList[a][d].code===b){c=BFHStatesList[a][d].name;break}this.$element.html(c)}};var c=a.fn.bfhstates;a.fn.bfhstates=function(c){return this.each(function(){var d,e,f;d=a(this),e=d.data("bfhstates"),f="object"==typeof c&&c,e||d.data("bfhstates",e=new b(this,f)),"string"==typeof c&&e[c].call(d)})},a.fn.bfhstates.Constructor=b,a.fn.bfhstates.defaults={country:"",state:"",blank:!0},a.fn.bfhstates.noConflict=function(){return a.fn.bfhstates=c,this},a(document).ready(function(){a("form select.bfh-states, span.bfh-states, div.bfh-states").each(function(){var b;b=a(this),b.hasClass("bfh-selectbox")&&b.bfhselectbox(b.data()),b.bfhstates(b.data())})})}(window.jQuery),+function(a){"use strict";function b(a,b){return a=String(a),1===a.length&&(a="0"+a),b=String(b),1===b.length&&(b="0"+b),a+BFHTimePickerDelimiter+b}function c(){var b;a(e).each(function(c){return b=d(a(this)),b.hasClass("open")?(b.trigger(c=a.Event("hide.bfhtimepicker")),c.isDefaultPrevented()?!0:(b.removeClass("open").trigger("hidden.bfhtimepicker"),void 0)):!0})}function d(a){return a.closest(".bfh-timepicker")}var e="[data-toggle=bfh-timepicker]",f=function(b,c){this.options=a.extend({},a.fn.bfhtimepicker.defaults,c),this.$element=a(b),this.initPopover()};f.prototype={constructor:f,setTime:function(){var a,c,d,e,f,g,h;a=this.options.time,g="",h="",""===a||"now"===a||void 0===a?(c=new Date,e=c.getHours(),f=c.getMinutes(),"12h"===this.options.mode&&(e>12?(e-=12,g=" "+BFHTimePickerModes.pm,h="pm"):(g=" "+BFHTimePickerModes.am,h="am")),"now"===a&&this.$element.find('.bfh-timepicker-toggle > input[type="text"]').val(b(e,f)+g),this.$element.data("hour",e),this.$element.data("minute",f),this.$element.data("mode",h)):(d=String(a).split(BFHTimePickerDelimiter),e=d[0],f=d[1],"12h"===this.options.mode&&(d=String(f).split(" "),f=d[0],h=d[1]===BFHTimePickerModes.pm?"pm":"am"),this.$element.find('.bfh-timepicker-toggle > input[type="text"]').val(a),this.$element.data("hour",e),this.$element.data("minute",f),this.$element.data("mode",h))},initPopover:function(){var b,c,d,g,h;b="",c="",d="",""!==this.options.icon&&("right"===this.options.align?c='<span class="input-group-addon"><i class="'+this.options.icon+'"></i></span>':b='<span class="input-group-addon"><i class="'+this.options.icon+'"></i></span>',d="input-group"),g="",h="23","12h"===this.options.mode&&(g='<td><div class="bfh-selectbox" data-input="'+this.options.input+'" data-value="am">'+'<div data-value="am">'+BFHTimePickerModes.am+"</div>"+'<div data-value="pm">'+BFHTimePickerModes.pm+"</div>"+"</div>",h="11"),this.$element.html('<div class="'+d+' bfh-timepicker-toggle" data-toggle="bfh-timepicker">'+b+'<input type="text" name="'+this.options.name+'" class="'+this.options.input+'" placeholder="'+this.options.placeholder+'" readonly>'+c+"</div>"+'<div class="bfh-timepicker-popover">'+'<table class="table">'+"<tbody>"+"<tr>"+'<td class="hour">'+'<input type="text" class="'+this.options.input+' bfh-number" data-min="0" data-max="'+h+'" data-zeros="true" data-wrap="true">'+"</td>"+'<td class="separator">'+BFHTimePickerDelimiter+"</td>"+'<td class="minute">'+'<input type="text" class="'+this.options.input+' bfh-number" data-min="0" data-max="59" data-zeros="true" data-wrap="true">'+"</td>"+g+"</tr>"+"</tbody>"+"</table>"+"</div>"),this.$element.on("click.bfhtimepicker.data-api touchstart.bfhtimepicker.data-api",e,f.prototype.toggle).on("click.bfhtimepicker.data-api touchstart.bfhtimepicker.data-api",".bfh-timepicker-popover > table",function(){return!1}),this.$element.find(".bfh-number").each(function(){var b;b=a(this),b.bfhnumber(b.data()),b.on("change",f.prototype.change)}),this.$element.find(".bfh-selectbox").each(function(){var b;b=a(this),b.bfhselectbox(b.data()),b.on("change.bfhselectbox",f.prototype.change)}),this.setTime(),this.updatePopover()},updatePopover:function(){var a,b,c;a=this.$element.data("hour"),b=this.$element.data("minute"),c=this.$element.data("mode"),this.$element.find(".hour input[type=text]").val(a).change(),this.$element.find(".minute input[type=text]").val(b).change(),this.$element.find(".bfh-selectbox").val(c)},change:function(){var b,c,e,f;return b=a(this),c=d(b),e=c.data("bfhtimepicker"),e&&"undefined"!==e&&(f="","12h"===e.options.mode&&(f=" "+BFHTimePickerModes[c.find(".bfh-selectbox").val()]),c.find('.bfh-timepicker-toggle > input[type="text"]').val(c.find(".hour input[type=text]").val()+BFHTimePickerDelimiter+c.find(".minute input[type=text]").val()+f),c.trigger("change.bfhtimepicker")),!1},toggle:function(b){var e,f,g;if(e=a(this),f=d(e),f.is(".disabled")||void 0!==f.attr("disabled"))return!0;if(g=f.hasClass("open"),c(),!g){if(f.trigger(b=a.Event("show.bfhtimepicker")),b.isDefaultPrevented())return!0;f.toggleClass("open").trigger("shown.bfhtimepicker"),e.focus()}return!1}};var g=a.fn.bfhtimepicker;a.fn.bfhtimepicker=function(b){return this.each(function(){var c,d,e;c=a(this),d=c.data("bfhtimepicker"),e="object"==typeof b&&b,this.type="bfhtimepicker",d||c.data("bfhtimepicker",d=new f(this,e)),"string"==typeof b&&d[b].call(c)})},a.fn.bfhtimepicker.Constructor=f,a.fn.bfhtimepicker.defaults={icon:"glyphicon glyphicon-time",align:"left",input:"form-control",placeholder:"",name:"",time:"now",mode:"24h"},a.fn.bfhtimepicker.noConflict=function(){return a.fn.bfhtimepicker=g,this};var h;a.valHooks.div&&(h=a.valHooks.div),a.valHooks.div={get:function(b){return a(b).hasClass("bfh-timepicker")?a(b).find('.bfh-timepicker-toggle > input[type="text"]').val():h?h.get(b):void 0},set:function(b,c){var d;if(a(b).hasClass("bfh-timepicker"))d=a(b).data("bfhtimepicker"),d.options.time=c,d.setTime(),d.updatePopover();else if(h)return h.set(b,c)}},a(document).ready(function(){a("div.bfh-timepicker").each(function(){var b;b=a(this),b.bfhtimepicker(b.data())})}),a(document).on("click.bfhtimepicker.data-api",c)}(window.jQuery),+function(a){"use strict";var b=function(b,c){this.options=a.extend({},a.fn.bfhtimezones.defaults,c),this.$element=a(b),this.$element.is("select")&&this.addTimezones(),this.$element.hasClass("bfh-selectbox")&&this.addBootstrapTimezones()};b.prototype={constructor:b,addTimezones:function(){var b,c;b=this.options.country,""!==b&&(c=a(document).find("#"+b),0!==c.length&&(b=c.val(),c.on("change",{timezone:this},this.changeCountry))),this.loadTimezones(b)},loadTimezones:function(a){var b,c;b=this.options.timezone,this.$element.html(""),this.options.blank===!0&&this.$element.append('<option value=""></option>');for(c in BFHTimezonesList[a])BFHTimezonesList[a].hasOwnProperty(c)&&this.$element.append('<option value="'+c+'">'+BFHTimezonesList[a][c]+"</option>");this.$element.val(b)},changeCountry:function(b){var c,d,e;c=a(this),d=b.data.timezone,e=c.val(),d.loadTimezones(e)},addBootstrapTimezones:function(){var b,c;b=this.options.country,""!==b&&(c=a(document).find("#"+b),0!==c.length&&(b=c.find('input[type="hidden"]').val(),c.on("change.bfhselectbox",{timezone:this},this.changeBootstrapCountry))),this.loadBootstrapTimezones(b)},loadBootstrapTimezones:function(a){var b,c,d,e,f;e=this.options.timezone,b=this.$element.find('input[type="hidden"]'),c=this.$element.find(".bfh-selectbox-option"),d=this.$element.find("[role=option]"),d.html(""),this.options.blank===!0&&d.append('<li><a tabindex="-1" href="#" data-option=""></a></li>');for(f in BFHTimezonesList[a])BFHTimezonesList[a].hasOwnProperty(f)&&d.append('<li><a tabindex="-1" href="#" data-option="'+f+'">'+BFHTimezonesList[a][f]+"</a></li>");this.$element.val(e)},changeBootstrapCountry:function(b){var c,d,e;c=a(this),d=b.data.timezone,e=c.val(),d.loadBootstrapTimezones(e)}};var c=a.fn.bfhtimezones;a.fn.bfhtimezones=function(c){return this.each(function(){var d,e,f;d=a(this),e=d.data("bfhtimezones"),f="object"==typeof c&&c,e||d.data("bfhtimezones",e=new b(this,f)),"string"==typeof c&&e[c].call(d)})},a.fn.bfhtimezones.Constructor=b,a.fn.bfhtimezones.defaults={country:"",timezone:"",blank:!0},a.fn.bfhtimezones.noConflict=function(){return a.fn.bfhtimezones=c,this},a(document).ready(function(){a("form select.bfh-timezones, div.bfh-timezones").each(function(){var b;b=a(this),b.hasClass("bfh-selectbox")&&b.bfhselectbox(b.data()),b.bfhtimezones(b.data())})})}(window.jQuery); \ No newline at end of file diff --git a/gui/slick/js/newShow.js b/gui/slick/js/newShow.js index 47d27308e030d59835ee83604a7bb649eb8a1816..b58d0cab00bfc0f8618b1742a5e51f6a927f9ca0 100644 --- a/gui/slick/js/newShow.js +++ b/gui/slick/js/newShow.js @@ -1,34 +1,5 @@ $(document).ready(function () { - function populateSelect() { - if (!$('#nameToSearch').length) { - return; - } - - if ($('#indexerLangSelect option').length <= 1) { - $.getJSON(sbRoot + '/home/addShows/getIndexerLanguages', {}, function (data) { - var selected, resultStr = ''; - - if (data.results.length === 0) { - resultStr = '<option value="en" selected="selected">en</option>'; - } else { - $.each(data.results, function (index, obj) { - if (resultStr == '') { - selected = ' selected="selected"'; - } else { - selected = ''; - } - - resultStr += '<option value="' + obj + '"' + selected + '>' + obj + '</option>'; - }); - } - - $('#indexerLangSelect').html(resultStr); - $('#indexerLangSelect').change(function () { searchIndexers(); }); - }); - } - } - var searchRequestXhr = null; function searchIndexers() { @@ -68,7 +39,7 @@ $(document).ready(function () { var whichSeries = obj.join('|'); - resultStr += '<input type="radio" id="whichSeries" name="whichSeries" value="' + whichSeries + '"' + checked + ' /> '; + resultStr += '<input type="radio" id="whichSeries" name="whichSeries" value="' + whichSeries.replace(/"/g, "") + '"' + checked + ' /> '; if (data.langid && data.langid != "") { resultStr += '<a href="' + anonURL + obj[2] + obj[3] + '&lid=' + data.langid + '" onclick=\"window.open(this.href, \'_blank\'); return false;\" ><b>' + obj[4] + '</b></a>'; } else { @@ -136,7 +107,6 @@ $(document).ready(function () { formid: 'addShowForm', revealfx: ['slide', 500], oninit: function () { - populateSelect(); updateSampleText(); if ($('input:hidden[name=whichSeries]').length && $('#fullShowPath').length) { goToStep(3); diff --git a/gui/slick/js/restart.js b/gui/slick/js/restart.js index 017beff8a8e796130b0edf7fae23429c2a531c0d..1ee32d09fa3b3a36e361842f94e5586e0cf0f30e 100644 --- a/gui/slick/js/restart.js +++ b/gui/slick/js/restart.js @@ -1,79 +1,65 @@ -if (sbHttpsEnabled != "False" && sbHttpsEnabled != 0) { - var sb_base_url = 'https://' + sbHost + ':' + sbHttpPort + sbRoot; -} else { - var sb_base_url = 'http://' + sbHost + ':' + sbHttpPort + sbRoot; -} - -var base_url = window.location.protocol + '//' + window.location.host + sbRoot; -var is_alive_url = sbRoot + '/home/is_alive/'; -var timeout_id; -var current_pid = ''; -var num_restart_waits = 0; - -function is_alive() { - timeout_id = 0; - $.get(is_alive_url, function(data) { - - // if it's still initalizing then just wait and try again - if (data.msg == 'nope') { - $('#shut_down_loading').hide(); - $('#shut_down_success').show(); - $('#restart_message').show(); - setTimeout('is_alive()', 1000); - } else { - // if this is before we've even shut down then just try again later - if (current_pid == '' || data.msg == current_pid) { - current_pid = data.msg; - setTimeout(is_alive, 1000); - - // if we're ready to go then redirect to new url - } else { - $('#restart_loading').hide(); - $('#restart_success').show(); - $('#refresh_message').show(); - window.location = sb_base_url + '/home/'; - } - } - }, 'jsonp'); -} - $(document).ready(function() { - - is_alive(); - - $('#shut_down_message').ajaxError(function(e, jqxhr, settings, exception) { - num_restart_waits += 1; - - $('#shut_down_loading').hide(); - $('#shut_down_success').show(); - $('#restart_message').show(); - is_alive_url = sb_base_url + '/home/is_alive/'; - - // if https is enabled or you are currently on https and the port or protocol changed just wait 5 seconds then redirect. - // This is because the ajax will fail if the cert is untrusted or the the http ajax requst from https will fail because of mixed content error. - if ((sbHttpsEnabled != "False" && sbHttpsEnabled != 0) || window.location.protocol == "https:") { - if (base_url != sb_base_url) { - timeout_id = 1; - setTimeout(function(){ - $('#restart_loading').hide(); - $('#restart_success').show(); - $('#refresh_message').show(); - }, 3000); - setTimeout("window.location = sb_base_url + '/home/'", 5000); - } - } - - // if it is taking forever just give up - if (num_restart_waits > 90) { - $('#restart_loading').hide(); - $('#restart_failure').show(); - $('#restart_fail_message').show(); - return; - } - - if (timeout_id == 0) { - timeout_id = setTimeout('is_alive()', 1000); - } - }); - -}); \ No newline at end of file + window.console_debug = false; + window.console_prefix = 'Restart: '; + window.current_pid = ''; + + var is_alive_url = sbRoot + '/home/is_alive/'; + + var check_isAlive = setInterval(is_alive, 1000); + + function is_alive() { + // Setup error detection + $.ajaxSetup({ + error: ajax_error + }); + + var jqxhr = $.get(is_alive_url, function(data) { + if (data.msg == 'nope') { + // if it's still initializing then just wait and try again + if (console_debug) { + console.log(console_prefix + 'is_alive: Sickrage is starting.'); + } + $('#shut_down_loading').hide(); + $('#shut_down_success').show(); + $('#restart_message').show(); + } else { + // if this is before we've even shut down then just try again later + if (console_debug) { + console.log(console_prefix + 'is_alive: Sickrage is shutdowning.'); + } + if (current_pid === '' || data.msg == current_pid) { + current_pid = data.msg; + // if we're ready to go then redirect to new url + } else { + clearInterval(check_isAlive); + if (console_debug) { + console.log(console_prefix + 'is_alive: Setting redirect.'); + } + $('#restart_loading').hide(); + $('#restart_success').show(); + $('#refresh_message').show(); + setTimeout(function(){window.location = sbRoot + '/home/';}, 5000); + } + } + + }, 'jsonp'); + + jqxhr.fail(function() { + ajax_error(); + }); + } + + function ajax_error(x, e) { + if (console_debug) { + if (x.status === 0) { + console.log(console_prefix + 'is_alive: Sickrage is not responding.'); + } else if (x.status == 404) { + console.log(console_prefix + 'is_alive: Requested URL not found.'); + } else if (x.status == 500) { + console.log(console_prefix + 'is_alive: Internel Server Error.'); + } else { + console.log(console_prefix + 'is_alive: Unknow Error.\n' + x.responseText); + } + } + } +}); diff --git a/lib/cachecontrol/__init__.py b/lib/cachecontrol/__init__.py index c18e70c0083037533fb1a99debfbc55d100efc26..9247f08e6975810e95c43e1544688a942b0bc456 100644 --- a/lib/cachecontrol/__init__.py +++ b/lib/cachecontrol/__init__.py @@ -5,3 +5,6 @@ Make it easy to import from cachecontrol without long namespaces. from .wrapper import CacheControl from .adapter import CacheControlAdapter from .controller import CacheController + +from requests.packages import urllib3 +urllib3.disable_warnings() diff --git a/lib/requests/__init__.py b/lib/requests/__init__.py index bba190029e71b1f143e7de71e849051cb2ff37a7..0ec356603c48601fc1d30e9e61d430473a427063 100644 --- a/lib/requests/__init__.py +++ b/lib/requests/__init__.py @@ -13,7 +13,7 @@ Requests is an HTTP library, written in Python, for human beings. Basic GET usage: >>> import requests - >>> r = requests.get('http://python.org') + >>> r = requests.get('https://www.python.org') >>> r.status_code 200 >>> 'Python is a programming language' in r.content @@ -22,7 +22,7 @@ usage: ... or POST: >>> payload = dict(key1='value1', key2='value2') - >>> r = requests.post("http://httpbin.org/post", data=payload) + >>> r = requests.post('http://httpbin.org/post', data=payload) >>> print(r.text) { ... @@ -36,17 +36,17 @@ usage: The other HTTP methods are supported - see `requests.api`. Full documentation is at <http://python-requests.org>. -:copyright: (c) 2014 by Kenneth Reitz. +:copyright: (c) 2015 by Kenneth Reitz. :license: Apache 2.0, see LICENSE for more details. """ __title__ = 'requests' -__version__ = '2.3.0' -__build__ = 0x020300 +__version__ = '2.5.1' +__build__ = 0x020501 __author__ = 'Kenneth Reitz' __license__ = 'Apache 2.0' -__copyright__ = 'Copyright 2014 Kenneth Reitz' +__copyright__ = 'Copyright 2015 Kenneth Reitz' # Attempt to enable urllib3's SNI support, if possible try: diff --git a/lib/requests/adapters.py b/lib/requests/adapters.py index 0f297ab25a639b0ba7aa433ad3993e31a0252412..c892853b295c339005c846ca3777a1f1479d1dee 100644 --- a/lib/requests/adapters.py +++ b/lib/requests/adapters.py @@ -9,23 +9,27 @@ and maintain connections. """ import socket -import copy from .models import Response +from .packages.urllib3 import Retry from .packages.urllib3.poolmanager import PoolManager, proxy_from_url from .packages.urllib3.response import HTTPResponse from .packages.urllib3.util import Timeout as TimeoutSauce -from .compat import urlparse, basestring, urldefrag, unquote +from .compat import urlparse, basestring from .utils import (DEFAULT_CA_BUNDLE_PATH, get_encoding_from_headers, - except_on_missing_scheme, get_auth_from_url) + prepend_scheme_if_needed, get_auth_from_url, urldefragauth) from .structures import CaseInsensitiveDict -from .packages.urllib3.exceptions import MaxRetryError -from .packages.urllib3.exceptions import TimeoutError -from .packages.urllib3.exceptions import SSLError as _SSLError +from .packages.urllib3.exceptions import ConnectTimeoutError from .packages.urllib3.exceptions import HTTPError as _HTTPError +from .packages.urllib3.exceptions import MaxRetryError from .packages.urllib3.exceptions import ProxyError as _ProxyError +from .packages.urllib3.exceptions import ProtocolError +from .packages.urllib3.exceptions import ReadTimeoutError +from .packages.urllib3.exceptions import SSLError as _SSLError +from .packages.urllib3.exceptions import ResponseError from .cookies import extract_cookies_to_jar -from .exceptions import ConnectionError, Timeout, SSLError, ProxyError +from .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError, + ProxyError, RetryError) from .auth import _basic_auth_str DEFAULT_POOLBLOCK = False @@ -57,13 +61,17 @@ class HTTPAdapter(BaseAdapter): :param pool_connections: The number of urllib3 connection pools to cache. :param pool_maxsize: The maximum number of connections to save in the pool. :param int max_retries: The maximum number of retries each connection - should attempt. Note, this applies only to failed connections and - timeouts, never to requests where the server returns a response. + should attempt. Note, this applies only to failed DNS lookups, socket + connections and connection timeouts, never to requests where data has + made it to the server. By default, Requests does not retry failed + connections. If you need granular control over the conditions under + which we retry a request, import urllib3's ``Retry`` class and pass + that instead. :param pool_block: Whether the connection pool should block for connections. Usage:: - >>> import lib.requests + >>> import requests >>> s = requests.Session() >>> a = requests.adapters.HTTPAdapter(max_retries=3) >>> s.mount('http://', a) @@ -74,7 +82,10 @@ class HTTPAdapter(BaseAdapter): def __init__(self, pool_connections=DEFAULT_POOLSIZE, pool_maxsize=DEFAULT_POOLSIZE, max_retries=DEFAULT_RETRIES, pool_block=DEFAULT_POOLBLOCK): - self.max_retries = max_retries + if max_retries == DEFAULT_RETRIES: + self.max_retries = Retry(0, read=False) + else: + self.max_retries = Retry.from_int(max_retries) self.config = {} self.proxy_manager = {} @@ -102,14 +113,17 @@ class HTTPAdapter(BaseAdapter): self.init_poolmanager(self._pool_connections, self._pool_maxsize, block=self._pool_block) - def init_poolmanager(self, connections, maxsize, block=DEFAULT_POOLBLOCK): - """Initializes a urllib3 PoolManager. This method should not be called - from user code, and is only exposed for use when subclassing the + def init_poolmanager(self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs): + """Initializes a urllib3 PoolManager. + + This method should not be called from user code, and is only + exposed for use when subclassing the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. :param connections: The number of urllib3 connection pools to cache. :param maxsize: The maximum number of connections to save in the pool. :param block: Block when no free connections are available. + :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager. """ # save these values for pickling self._pool_connections = connections @@ -117,7 +131,30 @@ class HTTPAdapter(BaseAdapter): self._pool_block = block self.poolmanager = PoolManager(num_pools=connections, maxsize=maxsize, - block=block) + block=block, strict=True, **pool_kwargs) + + def proxy_manager_for(self, proxy, **proxy_kwargs): + """Return urllib3 ProxyManager for the given proxy. + + This method should not be called from user code, and is only + exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param proxy: The proxy to return a urllib3 ProxyManager for. + :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager. + :returns: ProxyManager + """ + if not proxy in self.proxy_manager: + proxy_headers = self.proxy_headers(proxy) + self.proxy_manager[proxy] = proxy_from_url( + proxy, + proxy_headers=proxy_headers, + num_pools=self._pool_connections, + maxsize=self._pool_maxsize, + block=self._pool_block, + **proxy_kwargs) + + return self.proxy_manager[proxy] def cert_verify(self, conn, url, verify, cert): """Verify a SSL certificate. This method should not be called from user @@ -204,18 +241,9 @@ class HTTPAdapter(BaseAdapter): proxy = proxies.get(urlparse(url.lower()).scheme) if proxy: - except_on_missing_scheme(proxy) - proxy_headers = self.proxy_headers(proxy) - - if not proxy in self.proxy_manager: - self.proxy_manager[proxy] = proxy_from_url( - proxy, - proxy_headers=proxy_headers, - num_pools=self._pool_connections, - maxsize=self._pool_maxsize, - block=self._pool_block) - - conn = self.proxy_manager[proxy].connection_from_url(url) + proxy = prepend_scheme_if_needed(proxy, 'http') + proxy_manager = self.proxy_manager_for(proxy) + conn = proxy_manager.connection_from_url(url) else: # Only scheme should be lower case parsed = urlparse(url) @@ -250,7 +278,7 @@ class HTTPAdapter(BaseAdapter): proxy = proxies.get(scheme) if proxy and scheme != 'https': - url, _ = urldefrag(request.url) + url = urldefragauth(request.url) else: url = request.path_url @@ -297,7 +325,10 @@ class HTTPAdapter(BaseAdapter): :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. :param stream: (optional) Whether to stream the request content. - :param timeout: (optional) The timeout on the request. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a (`connect timeout, read + timeout <user/advanced.html#timeouts>`_) tuple. + :type timeout: float or tuple :param verify: (optional) Whether to verify SSL certificates. :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. @@ -311,7 +342,18 @@ class HTTPAdapter(BaseAdapter): chunked = not (request.body is None or 'Content-Length' in request.headers) - timeout = TimeoutSauce(connect=timeout, read=timeout) + if isinstance(timeout, tuple): + try: + connect, read = timeout + timeout = TimeoutSauce(connect=connect, read=read) + except ValueError as e: + # this may raise a string formatting error. + err = ("Invalid timeout {0}. Pass a (connect, read) " + "timeout tuple, or a single float to set " + "both timeouts to the same value".format(timeout)) + raise ValueError(err) + else: + timeout = TimeoutSauce(connect=timeout, read=timeout) try: if not chunked: @@ -369,10 +411,16 @@ class HTTPAdapter(BaseAdapter): # All is well, return the connection to the pool. conn._put_conn(low_conn) - except socket.error as sockerr: - raise ConnectionError(sockerr, request=request) + except (ProtocolError, socket.error) as err: + raise ConnectionError(err, request=request) except MaxRetryError as e: + if isinstance(e.reason, ConnectTimeoutError): + raise ConnectTimeout(e, request=request) + + if isinstance(e.reason, ResponseError): + raise RetryError(e, request=request) + raise ConnectionError(e, request=request) except _ProxyError as e: @@ -381,14 +429,9 @@ class HTTPAdapter(BaseAdapter): except (_SSLError, _HTTPError) as e: if isinstance(e, _SSLError): raise SSLError(e, request=request) - elif isinstance(e, TimeoutError): - raise Timeout(e, request=request) + elif isinstance(e, ReadTimeoutError): + raise ReadTimeout(e, request=request) else: raise - r = self.build_response(request, resp) - - if not stream: - r.content - - return r \ No newline at end of file + return self.build_response(request, resp) diff --git a/lib/requests/api.py b/lib/requests/api.py index 01d853d5cae6fd270027f19407eae3d266fd38d7..1469b05c4997c5347ee8b25d4598f0d4e06b58b6 100644 --- a/lib/requests/api.py +++ b/lib/requests/api.py @@ -22,12 +22,17 @@ def request(method, url, **kwargs): :param url: URL for the new :class:`Request` object. :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`. :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`. :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`. - :param files: (optional) Dictionary of 'name': file-like-objects (or {'name': ('filename', fileobj)}) for multipart encoding upload. + :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': ('filename', fileobj)}``) for multipart encoding upload. :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth. - :param timeout: (optional) Float describing the timeout of the request in seconds. + :param timeout: (optional) How long to wait for the server to send data + before giving up, as a float, or a (`connect timeout, read timeout + <user/advanced.html#timeouts>`_) tuple. + :type timeout: float or tuple :param allow_redirects: (optional) Boolean. Set to True if POST/PUT/DELETE redirect following is allowed. + :type allow_redirects: bool :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy. :param verify: (optional) if ``True``, the SSL cert will be verified. A CA_BUNDLE path can also be provided. :param stream: (optional) if ``False``, the response content will be immediately downloaded. @@ -41,7 +46,12 @@ def request(method, url, **kwargs): """ session = sessions.Session() - return session.request(method=method, url=url, **kwargs) + response = session.request(method=method, url=url, **kwargs) + # By explicitly closing the session, we avoid leaving sockets open which + # can trigger a ResourceWarning in some cases, and look like a memory leak + # in others. + session.close() + return response def get(url, **kwargs): @@ -77,15 +87,16 @@ def head(url, **kwargs): return request('head', url, **kwargs) -def post(url, data=None, **kwargs): +def post(url, data=None, json=None, **kwargs): """Sends a POST request. Returns :class:`Response` object. :param url: URL for the new :class:`Request` object. :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. :param \*\*kwargs: Optional arguments that ``request`` takes. """ - return request('post', url, data=data, **kwargs) + return request('post', url, data=data, json=json, **kwargs) def put(url, data=None, **kwargs): diff --git a/lib/requests/auth.py b/lib/requests/auth.py index 9f831b7ad03c97357bf298ec12c914d20343f45a..b950181d9e4839a7c1ace822db7f401438317e66 100644 --- a/lib/requests/auth.py +++ b/lib/requests/auth.py @@ -16,7 +16,8 @@ from base64 import b64encode from .compat import urlparse, str from .cookies import extract_cookies_to_jar -from .utils import parse_dict_header +from .utils import parse_dict_header, to_native_string +from .status_codes import codes CONTENT_TYPE_FORM_URLENCODED = 'application/x-www-form-urlencoded' CONTENT_TYPE_MULTI_PART = 'multipart/form-data' @@ -25,7 +26,11 @@ CONTENT_TYPE_MULTI_PART = 'multipart/form-data' def _basic_auth_str(username, password): """Returns a Basic Auth string.""" - return 'Basic ' + b64encode(('%s:%s' % (username, password)).encode('latin1')).strip().decode('latin1') + authstr = 'Basic ' + to_native_string( + b64encode(('%s:%s' % (username, password)).encode('latin1')).strip() + ) + + return authstr class AuthBase(object): @@ -62,6 +67,7 @@ class HTTPDigestAuth(AuthBase): self.nonce_count = 0 self.chal = {} self.pos = None + self.num_401_calls = 1 def build_digest_header(self, method, url): @@ -146,6 +152,11 @@ class HTTPDigestAuth(AuthBase): return 'Digest %s' % (base) + def handle_redirect(self, r, **kwargs): + """Reset num_401_calls counter on redirects.""" + if r.is_redirect: + self.num_401_calls = 1 + def handle_401(self, r, **kwargs): """Takes the given response and tries digest-auth, if needed.""" @@ -158,7 +169,7 @@ class HTTPDigestAuth(AuthBase): if 'digest' in s_auth.lower() and num_401_calls < 2: - setattr(self, 'num_401_calls', num_401_calls + 1) + self.num_401_calls += 1 pat = re.compile(r'digest ', flags=re.IGNORECASE) self.chal = parse_dict_header(pat.sub('', s_auth, count=1)) @@ -178,7 +189,7 @@ class HTTPDigestAuth(AuthBase): return _r - setattr(self, 'num_401_calls', 1) + self.num_401_calls = 1 return r def __call__(self, r): @@ -188,6 +199,11 @@ class HTTPDigestAuth(AuthBase): try: self.pos = r.body.tell() except AttributeError: - pass + # In the case of HTTPDigestAuth being reused and the body of + # the previous request was a file-like object, pos has the + # file position of the previous body. Ensure it's set to + # None. + self.pos = None r.register_hook('response', self.handle_401) + r.register_hook('response', self.handle_redirect) return r diff --git a/lib/requests/certs.py b/lib/requests/certs.py index bc00826191d77f9c180ab29623ea25171bb87dbd..07e64750703903bd3971aa7536f6605ae65d6759 100644 --- a/lib/requests/certs.py +++ b/lib/requests/certs.py @@ -11,14 +11,15 @@ If you are packaging Requests, e.g., for a Linux distribution or a managed environment, you can change the definition of where() to return a separately packaged CA bundle. """ - import os.path - -def where(): - """Return the preferred certificate bundle.""" - # vendored bundle inside Requests - return os.path.join(os.path.dirname(__file__), 'cacert.pem') +try: + from certifi import where +except ImportError: + def where(): + """Return the preferred certificate bundle.""" + # vendored bundle inside Requests + return os.path.join(os.path.dirname(__file__), 'cacert.pem') if __name__ == '__main__': print(where()) diff --git a/lib/requests/compat.py b/lib/requests/compat.py index bdf10d6a9f9c0c073f85ca3cbdbc6c12eca610cd..c07726ee45ddd8140c6037ff9d493b283e8070b2 100644 --- a/lib/requests/compat.py +++ b/lib/requests/compat.py @@ -75,7 +75,9 @@ is_solaris = ('solar==' in str(sys.platform).lower()) # Complete guess. try: import simplejson as json -except ImportError: +except (ImportError, SyntaxError): + # simplejson does not support Python 3.2, it throws a SyntaxError + # because of u'...' Unicode literals. import json # --------- @@ -90,7 +92,6 @@ if is_py2: from Cookie import Morsel from StringIO import StringIO from .packages.urllib3.packages.ordered_dict import OrderedDict - from httplib import IncompleteRead builtin_str = str bytes = str @@ -106,7 +107,6 @@ elif is_py3: from http.cookies import Morsel from io import StringIO from collections import OrderedDict - from http.client import IncompleteRead builtin_str = str str = str diff --git a/lib/requests/cookies.py b/lib/requests/cookies.py index 831c49c6d276fe387cf7264edbc44c44585542b8..6969fe5cc4e37fd687e064e42b3d7eeb4cc7b3b5 100644 --- a/lib/requests/cookies.py +++ b/lib/requests/cookies.py @@ -157,26 +157,28 @@ class CookieConflictError(RuntimeError): class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping): - """Compatibility class; is a cookielib.CookieJar, but exposes a dict interface. + """Compatibility class; is a cookielib.CookieJar, but exposes a dict + interface. This is the CookieJar we create by default for requests and sessions that don't specify one, since some clients may expect response.cookies and session.cookies to support dict operations. - Don't use the dict interface internally; it's just for compatibility with - with external client code. All `requests` code should work out of the box - with externally provided instances of CookieJar, e.g., LWPCookieJar and - FileCookieJar. - - Caution: dictionary operations that are normally O(1) may be O(n). + Requests does not use the dict interface internally; it's just for + compatibility with external client code. All requests code should work + out of the box with externally provided instances of ``CookieJar``, e.g. + ``LWPCookieJar`` and ``FileCookieJar``. Unlike a regular CookieJar, this class is pickleable. - """ + .. warning:: dictionary operations that are normally O(1) may be O(n). + """ def get(self, name, default=None, domain=None, path=None): """Dict-like get() that also supports optional domain and path args in order to resolve naming collisions from using one cookie jar over - multiple domains. Caution: operation is O(n), not O(1).""" + multiple domains. + + .. warning:: operation is O(n), not O(1).""" try: return self._find_no_duplicates(name, domain, path) except KeyError: @@ -199,37 +201,38 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping): return c def iterkeys(self): - """Dict-like iterkeys() that returns an iterator of names of cookies from the jar. - See itervalues() and iteritems().""" + """Dict-like iterkeys() that returns an iterator of names of cookies + from the jar. See itervalues() and iteritems().""" for cookie in iter(self): yield cookie.name def keys(self): - """Dict-like keys() that returns a list of names of cookies from the jar. - See values() and items().""" + """Dict-like keys() that returns a list of names of cookies from the + jar. See values() and items().""" return list(self.iterkeys()) def itervalues(self): - """Dict-like itervalues() that returns an iterator of values of cookies from the jar. - See iterkeys() and iteritems().""" + """Dict-like itervalues() that returns an iterator of values of cookies + from the jar. See iterkeys() and iteritems().""" for cookie in iter(self): yield cookie.value def values(self): - """Dict-like values() that returns a list of values of cookies from the jar. - See keys() and items().""" + """Dict-like values() that returns a list of values of cookies from the + jar. See keys() and items().""" return list(self.itervalues()) def iteritems(self): - """Dict-like iteritems() that returns an iterator of name-value tuples from the jar. - See iterkeys() and itervalues().""" + """Dict-like iteritems() that returns an iterator of name-value tuples + from the jar. See iterkeys() and itervalues().""" for cookie in iter(self): yield cookie.name, cookie.value def items(self): - """Dict-like items() that returns a list of name-value tuples from the jar. - See keys() and values(). Allows client-code to call "dict(RequestsCookieJar) - and get a vanilla python dict of key value pairs.""" + """Dict-like items() that returns a list of name-value tuples from the + jar. See keys() and values(). Allows client-code to call + ``dict(RequestsCookieJar)`` and get a vanilla python dict of key value + pairs.""" return list(self.iteritems()) def list_domains(self): @@ -259,8 +262,9 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping): return False # there is only one domain in jar def get_dict(self, domain=None, path=None): - """Takes as an argument an optional domain and path and returns a plain old - Python dict of name-value pairs of cookies that meet the requirements.""" + """Takes as an argument an optional domain and path and returns a plain + old Python dict of name-value pairs of cookies that meet the + requirements.""" dictionary = {} for cookie in iter(self): if (domain is None or cookie.domain == domain) and (path is None @@ -269,21 +273,24 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping): return dictionary def __getitem__(self, name): - """Dict-like __getitem__() for compatibility with client code. Throws exception - if there are more than one cookie with name. In that case, use the more - explicit get() method instead. Caution: operation is O(n), not O(1).""" + """Dict-like __getitem__() for compatibility with client code. Throws + exception if there are more than one cookie with name. In that case, + use the more explicit get() method instead. + + .. warning:: operation is O(n), not O(1).""" return self._find_no_duplicates(name) def __setitem__(self, name, value): - """Dict-like __setitem__ for compatibility with client code. Throws exception - if there is already a cookie of that name in the jar. In that case, use the more - explicit set() method instead.""" + """Dict-like __setitem__ for compatibility with client code. Throws + exception if there is already a cookie of that name in the jar. In that + case, use the more explicit set() method instead.""" self.set(name, value) def __delitem__(self, name): - """Deletes a cookie given a name. Wraps cookielib.CookieJar's remove_cookie_by_name().""" + """Deletes a cookie given a name. Wraps ``cookielib.CookieJar``'s + ``remove_cookie_by_name()``.""" remove_cookie_by_name(self, name) def set_cookie(self, cookie, *args, **kwargs): @@ -300,10 +307,11 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping): super(RequestsCookieJar, self).update(other) def _find(self, name, domain=None, path=None): - """Requests uses this method internally to get cookie values. Takes as args name - and optional domain and path. Returns a cookie.value. If there are conflicting cookies, - _find arbitrarily chooses one. See _find_no_duplicates if you want an exception thrown - if there are conflicting cookies.""" + """Requests uses this method internally to get cookie values. Takes as + args name and optional domain and path. Returns a cookie.value. If + there are conflicting cookies, _find arbitrarily chooses one. See + _find_no_duplicates if you want an exception thrown if there are + conflicting cookies.""" for cookie in iter(self): if cookie.name == name: if domain is None or cookie.domain == domain: @@ -313,10 +321,11 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping): raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path)) def _find_no_duplicates(self, name, domain=None, path=None): - """__get_item__ and get call _find_no_duplicates -- never used in Requests internally. - Takes as args name and optional domain and path. Returns a cookie.value. - Throws KeyError if cookie is not found and CookieConflictError if there are - multiple cookies that match name and optionally domain and path.""" + """Both ``__get_item__`` and ``get`` call this function: it's never + used elsewhere in Requests. Takes as args name and optional domain and + path. Returns a cookie.value. Throws KeyError if cookie is not found + and CookieConflictError if there are multiple cookies that match name + and optionally domain and path.""" toReturn = None for cookie in iter(self): if cookie.name == name: @@ -440,7 +449,7 @@ def merge_cookies(cookiejar, cookies): """ if not isinstance(cookiejar, cookielib.CookieJar): raise ValueError('You can only merge into CookieJar') - + if isinstance(cookies, dict): cookiejar = cookiejar_from_dict( cookies, cookiejar=cookiejar, overwrite=False) diff --git a/lib/requests/exceptions.py b/lib/requests/exceptions.py index a4ee9d630c21fde0041e6ce13e14345368fb3a7e..89135a802eb1a87e15aa5d3e8a94ed0fce50273b 100644 --- a/lib/requests/exceptions.py +++ b/lib/requests/exceptions.py @@ -44,7 +44,23 @@ class SSLError(ConnectionError): class Timeout(RequestException): - """The request timed out.""" + """The request timed out. + + Catching this error will catch both + :exc:`~requests.exceptions.ConnectTimeout` and + :exc:`~requests.exceptions.ReadTimeout` errors. + """ + + +class ConnectTimeout(ConnectionError, Timeout): + """The request timed out while trying to connect to the remote server. + + Requests that produced this error are safe to retry. + """ + + +class ReadTimeout(Timeout): + """The server did not send any data in the allotted amount of time.""" class URLRequired(RequestException): @@ -73,3 +89,11 @@ class ChunkedEncodingError(RequestException): class ContentDecodingError(RequestException, BaseHTTPError): """Failed to decode response content""" + + +class StreamConsumedError(RequestException, TypeError): + """The content for this response was already consumed""" + + +class RetryError(RequestException): + """Custom retries logic failed""" diff --git a/lib/requests/models.py b/lib/requests/models.py index e2fa09f8cefa31960d3a6c48844adecbb2423146..b728c84e41b2e547ab12e37caa235f94b756f630 100644 --- a/lib/requests/models.py +++ b/lib/requests/models.py @@ -19,31 +19,35 @@ from .cookies import cookiejar_from_dict, get_cookie_header from .packages.urllib3.fields import RequestField from .packages.urllib3.filepost import encode_multipart_formdata from .packages.urllib3.util import parse_url -from .packages.urllib3.exceptions import DecodeError +from .packages.urllib3.exceptions import ( + DecodeError, ReadTimeoutError, ProtocolError, LocationParseError) from .exceptions import ( - HTTPError, RequestException, MissingSchema, InvalidURL, - ChunkedEncodingError, ContentDecodingError) + HTTPError, MissingSchema, InvalidURL, ChunkedEncodingError, + ContentDecodingError, ConnectionError, StreamConsumedError) from .utils import ( guess_filename, get_auth_from_url, requote_uri, stream_decode_response_unicode, to_key_val_list, parse_header_links, iter_slices, guess_json_utf, super_len, to_native_string) from .compat import ( cookielib, urlunparse, urlsplit, urlencode, str, bytes, StringIO, - is_py2, chardet, json, builtin_str, basestring, IncompleteRead) + is_py2, chardet, json, builtin_str, basestring) from .status_codes import codes #: The set of HTTP status codes that indicate an automatically #: processable redirect. REDIRECT_STATI = ( - codes.moved, # 301 - codes.found, # 302 - codes.other, # 303 - codes.temporary_moved, # 307 + codes.moved, # 301 + codes.found, # 302 + codes.other, # 303 + codes.temporary_redirect, # 307 + codes.permanent_redirect, # 308 ) DEFAULT_REDIRECT_LIMIT = 30 CONTENT_CHUNK_SIZE = 10 * 1024 ITER_CHUNK_SIZE = 512 +json_dumps = json.dumps + class RequestEncodingMixin(object): @property @@ -187,7 +191,8 @@ class Request(RequestHooksMixin): :param url: URL to send. :param headers: dictionary of headers to send. :param files: dictionary of {filename: fileobject} files to multipart upload. - :param data: the body to attach the request. If a dictionary is provided, form-encoding will take place. + :param data: the body to attach to the request. If a dictionary is provided, form-encoding will take place. + :param json: json for the body to attach to the request (if data is not specified). :param params: dictionary of URL parameters to append to the URL. :param auth: Auth handler or (user, pass) tuple. :param cookies: dictionary or CookieJar of cookies to attach to this request. @@ -210,7 +215,8 @@ class Request(RequestHooksMixin): params=None, auth=None, cookies=None, - hooks=None): + hooks=None, + json=None): # Default empty dicts for dict params. data = [] if data is None else data @@ -228,6 +234,7 @@ class Request(RequestHooksMixin): self.headers = headers self.files = files self.data = data + self.json = json self.params = params self.auth = auth self.cookies = cookies @@ -244,6 +251,7 @@ class Request(RequestHooksMixin): headers=self.headers, files=self.files, data=self.data, + json=self.json, params=self.params, auth=self.auth, cookies=self.cookies, @@ -287,14 +295,15 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): self.hooks = default_hooks() def prepare(self, method=None, url=None, headers=None, files=None, - data=None, params=None, auth=None, cookies=None, hooks=None): + data=None, params=None, auth=None, cookies=None, hooks=None, + json=None): """Prepares the entire request with the given parameters.""" self.prepare_method(method) self.prepare_url(url, params) self.prepare_headers(headers) self.prepare_cookies(cookies) - self.prepare_body(data, files) + self.prepare_body(data, files, json) self.prepare_auth(auth, url) # Note that prepare_auth must be last to enable authentication schemes # such as OAuth to work on a fully prepared request. @@ -309,8 +318,8 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): p = PreparedRequest() p.method = self.method p.url = self.url - p.headers = self.headers.copy() - p._cookies = self._cookies.copy() + p.headers = self.headers.copy() if self.headers is not None else None + p._cookies = self._cookies.copy() if self._cookies is not None else None p.body = self.body p.hooks = self.hooks return p @@ -324,21 +333,27 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): def prepare_url(self, url, params): """Prepares the given HTTP URL.""" #: Accept objects that have string representations. - try: - url = unicode(url) - except NameError: - # We're on Python 3. - url = str(url) - except UnicodeDecodeError: - pass - - # Don't do any URL preparation for oddball schemes + #: We're unable to blindy call unicode/str functions + #: as this will include the bytestring indicator (b'') + #: on python 3.x. + #: https://github.com/kennethreitz/requests/pull/2238 + if isinstance(url, bytes): + url = url.decode('utf8') + else: + url = unicode(url) if is_py2 else str(url) + + # Don't do any URL preparation for non-HTTP schemes like `mailto`, + # `data` etc to work around exceptions from `url_parse`, which + # handles RFC 3986 only. if ':' in url and not url.lower().startswith('http'): self.url = url return # Support for unicode domain names and paths. - scheme, auth, host, port, path, query, fragment = parse_url(url) + try: + scheme, auth, host, port, path, query, fragment = parse_url(url) + except LocationParseError as e: + raise InvalidURL(*e.args) if not scheme: raise MissingSchema("Invalid URL {0!r}: No schema supplied. " @@ -395,7 +410,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): else: self.headers = CaseInsensitiveDict() - def prepare_body(self, data, files): + def prepare_body(self, data, files, json=None): """Prepares the given HTTP body data.""" # Check if file, fo, generator, iterator. @@ -406,11 +421,13 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): content_type = None length = None + if json is not None: + content_type = 'application/json' + body = json_dumps(json) + is_stream = all([ hasattr(data, '__iter__'), - not isinstance(data, basestring), - not isinstance(data, list), - not isinstance(data, dict) + not isinstance(data, (basestring, list, tuple, dict)) ]) try: @@ -433,9 +450,9 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): if files: (body, content_type) = self._encode_files(files, data) else: - if data: + if data and json is None: body = self._encode_params(data) - if isinstance(data, str) or isinstance(data, builtin_str) or hasattr(data, 'read'): + if isinstance(data, basestring) or hasattr(data, 'read'): content_type = None else: content_type = 'application/x-www-form-urlencoded' @@ -443,7 +460,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): self.prepare_content_length(body) # Add content-type if it wasn't explicitly provided. - if (content_type) and (not 'content-type' in self.headers): + if content_type and ('content-type' not in self.headers): self.headers['Content-Type'] = content_type self.body = body @@ -457,7 +474,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): l = super_len(body) if l: self.headers['Content-Length'] = builtin_str(l) - elif self.method not in ('GET', 'HEAD'): + elif (self.method not in ('GET', 'HEAD')) and (self.headers.get('Content-Length') is None): self.headers['Content-Length'] = '0' def prepare_auth(self, auth, url=''): @@ -558,6 +575,10 @@ class Response(object): #: and the arrival of the response (as a timedelta) self.elapsed = datetime.timedelta(0) + #: The :class:`PreparedRequest <PreparedRequest>` object to which this + #: is a response. + self.request = None + def __getstate__(self): # Consume everything; accessing the content attribute makes # sure the content has been fully read. @@ -596,7 +617,7 @@ class Response(object): def ok(self): try: self.raise_for_status() - except RequestException: + except HTTPError: return False return True @@ -607,6 +628,11 @@ class Response(object): """ return ('location' in self.headers and self.status_code in REDIRECT_STATI) + @property + def is_permanent_redirect(self): + """True if this Response one of the permanant versions of redirect""" + return ('location' in self.headers and self.status_code in (codes.moved_permanently, codes.permanent_redirect)) + @property def apparent_encoding(self): """The apparent encoding, provided by the chardet library""" @@ -618,21 +644,22 @@ class Response(object): large responses. The chunk size is the number of bytes it should read into memory. This is not necessarily the length of each item returned as decoding can take place. - """ - if self._content_consumed: - # simulate reading small chunks of the content - return iter_slices(self._content, chunk_size) + If decode_unicode is True, content will be decoded using the best + available encoding based on the response. + """ def generate(): try: # Special case for urllib3. try: for chunk in self.raw.stream(chunk_size, decode_content=True): yield chunk - except IncompleteRead as e: + except ProtocolError as e: raise ChunkedEncodingError(e) except DecodeError as e: raise ContentDecodingError(e) + except ReadTimeoutError as e: + raise ConnectionError(e) except AttributeError: # Standard file-like object. while True: @@ -643,14 +670,21 @@ class Response(object): self._content_consumed = True - gen = generate() + if self._content_consumed and isinstance(self._content, bool): + raise StreamConsumedError() + # simulate reading small chunks of the content + reused_chunks = iter_slices(self._content, chunk_size) + + stream_chunks = generate() + + chunks = reused_chunks if self._content_consumed else stream_chunks if decode_unicode: - gen = stream_decode_response_unicode(gen, self) + chunks = stream_decode_response_unicode(chunks, self) - return gen + return chunks - def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=None): + def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=None, delimiter=None): """Iterates over the response data, one line at a time. When stream=True is set on the request, this avoids reading the content at once into memory for large responses. @@ -662,7 +696,11 @@ class Response(object): if pending is not None: chunk = pending + chunk - lines = chunk.splitlines() + + if delimiter: + lines = chunk.split(delimiter) + else: + lines = chunk.splitlines() if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]: pending = lines.pop() @@ -793,8 +831,8 @@ class Response(object): raise HTTPError(http_error_msg, response=self) def close(self): - """Closes the underlying file descriptor and releases the connection - back to the pool. + """Releases the connection back to the pool. Once this method has been + called the underlying ``raw`` object must not be accessed again. *Note: Should not normally need to be called explicitly.* """ diff --git a/lib/requests/packages/__init__.py b/lib/requests/packages/__init__.py index d62c4b7111b3d547f853379e4840b44cb96c6000..ec6a9e0646d6c1122bbd98858889ce6523f1f9f0 100644 --- a/lib/requests/packages/__init__.py +++ b/lib/requests/packages/__init__.py @@ -1,3 +1,95 @@ +""" +Copyright (c) Donald Stufft, pip, and individual contributors + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +""" from __future__ import absolute_import -from . import urllib3 +import sys + + +class VendorAlias(object): + + def __init__(self): + self._vendor_name = __name__ + self._vendor_pkg = self._vendor_name + "." + + def find_module(self, fullname, path=None): + if fullname.startswith(self._vendor_pkg): + return self + + def load_module(self, name): + # Ensure that this only works for the vendored name + if not name.startswith(self._vendor_pkg): + raise ImportError( + "Cannot import %s, must be a subpackage of '%s'." % ( + name, self._vendor_name, + ) + ) + + # Check to see if we already have this item in sys.modules, if we do + # then simply return that. + if name in sys.modules: + return sys.modules[name] + + # Check to see if we can import the vendor name + try: + # We do this dance here because we want to try and import this + # module without hitting a recursion error because of a bunch of + # VendorAlias instances on sys.meta_path + real_meta_path = sys.meta_path[:] + try: + sys.meta_path = [ + m for m in sys.meta_path + if not isinstance(m, VendorAlias) + ] + __import__(name) + module = sys.modules[name] + finally: + # Re-add any additions to sys.meta_path that were made while + # during the import we just did, otherwise things like + # requests.packages.urllib3.poolmanager will fail. + for m in sys.meta_path: + if m not in real_meta_path: + real_meta_path.append(m) + + # Restore sys.meta_path with any new items. + sys.meta_path = real_meta_path + except ImportError: + # We can't import the vendor name, so we'll try to import the + # "real" name. + real_name = name[len(self._vendor_pkg):] + try: + __import__(real_name) + module = sys.modules[real_name] + except ImportError: + raise ImportError("No module named '%s'" % (name,)) + + # If we've gotten here we've found the module we're looking for, either + # as part of our vendored package, or as the real name, so we'll add + # it to sys.modules as the vendored name so that we don't have to do + # the lookup again. + sys.modules[name] = module + + # Finally, return the loaded module + return module + + +sys.meta_path.append(VendorAlias()) diff --git a/lib/requests/packages/chardet/__init__.py b/lib/requests/packages/chardet/__init__.py index e4f0799d621d277d529d057ce680abfc61beb123..82c2a48d2905ce17924cafbf35c09b61e8ee4504 100644 --- a/lib/requests/packages/chardet/__init__.py +++ b/lib/requests/packages/chardet/__init__.py @@ -15,7 +15,7 @@ # 02110-1301 USA ######################### END LICENSE BLOCK ######################### -__version__ = "2.2.1" +__version__ = "2.3.0" from sys import version_info diff --git a/lib/requests/packages/chardet/chardetect.py b/lib/requests/packages/chardet/chardetect.py old mode 100644 new mode 100755 index ecd0163be726bf513048c69d47770527829e8143..ffe892f25db3c7e2f8a57e29a7c981476a5eecf0 --- a/lib/requests/packages/chardet/chardetect.py +++ b/lib/requests/packages/chardet/chardetect.py @@ -12,34 +12,68 @@ Example:: If no paths are provided, it takes its input from stdin. """ + +from __future__ import absolute_import, print_function, unicode_literals + +import argparse +import sys from io import open -from sys import argv, stdin +from chardet import __version__ from chardet.universaldetector import UniversalDetector -def description_of(file, name='stdin'): - """Return a string describing the probable encoding of a file.""" +def description_of(lines, name='stdin'): + """ + Return a string describing the probable encoding of a file or + list of strings. + + :param lines: The lines to get the encoding of. + :type lines: Iterable of bytes + :param name: Name of file or collection of lines + :type name: str + """ u = UniversalDetector() - for line in file: + for line in lines: u.feed(line) u.close() result = u.result if result['encoding']: - return '%s: %s with confidence %s' % (name, - result['encoding'], - result['confidence']) + return '{0}: {1} with confidence {2}'.format(name, result['encoding'], + result['confidence']) else: - return '%s: no result' % name + return '{0}: no result'.format(name) -def main(): - if len(argv) <= 1: - print(description_of(stdin)) - else: - for path in argv[1:]: - with open(path, 'rb') as f: - print(description_of(f, path)) +def main(argv=None): + ''' + Handles command line arguments and gets things started. + + :param argv: List of arguments, as if specified on the command-line. + If None, ``sys.argv[1:]`` is used instead. + :type argv: list of str + ''' + # Get command line arguments + parser = argparse.ArgumentParser( + description="Takes one or more file paths and reports their detected \ + encodings", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + conflict_handler='resolve') + parser.add_argument('input', + help='File whose encoding we would like to determine.', + type=argparse.FileType('rb'), nargs='*', + default=[sys.stdin]) + parser.add_argument('--version', action='version', + version='%(prog)s {0}'.format(__version__)) + args = parser.parse_args(argv) + + for f in args.input: + if f.isatty(): + print("You are running chardetect interactively. Press " + + "CTRL-D twice at the start of a blank line to signal the " + + "end of your input. If you want help, run chardetect " + + "--help\n", file=sys.stderr) + print(description_of(f, f.name)) if __name__ == '__main__': diff --git a/lib/requests/packages/chardet/jpcntx.py b/lib/requests/packages/chardet/jpcntx.py index f7f69ba4cdaba120b5d8c6932e6f7eb4c60a0913..59aeb6a87893b030a0ffceb93a460752eef75e92 100644 --- a/lib/requests/packages/chardet/jpcntx.py +++ b/lib/requests/packages/chardet/jpcntx.py @@ -177,6 +177,12 @@ class JapaneseContextAnalysis: return -1, 1 class SJISContextAnalysis(JapaneseContextAnalysis): + def __init__(self): + self.charset_name = "SHIFT_JIS" + + def get_charset_name(self): + return self.charset_name + def get_order(self, aBuf): if not aBuf: return -1, 1 @@ -184,6 +190,8 @@ class SJISContextAnalysis(JapaneseContextAnalysis): first_char = wrap_ord(aBuf[0]) if ((0x81 <= first_char <= 0x9F) or (0xE0 <= first_char <= 0xFC)): charLen = 2 + if (first_char == 0x87) or (0xFA <= first_char <= 0xFC): + self.charset_name = "CP932" else: charLen = 1 diff --git a/lib/requests/packages/chardet/latin1prober.py b/lib/requests/packages/chardet/latin1prober.py index ad695f57a728421cd920cc3772fb31141d1e0b29..eef3573543c8becb8976c8b1743d9fc6c04d1149 100644 --- a/lib/requests/packages/chardet/latin1prober.py +++ b/lib/requests/packages/chardet/latin1prober.py @@ -129,11 +129,11 @@ class Latin1Prober(CharSetProber): if total < 0.01: confidence = 0.0 else: - confidence = ((self._mFreqCounter[3] / total) - - (self._mFreqCounter[1] * 20.0 / total)) + confidence = ((self._mFreqCounter[3] - self._mFreqCounter[1] * 20.0) + / total) if confidence < 0.0: confidence = 0.0 # lower the confidence of latin1 so that other more accurate # detector can take priority. - confidence = confidence * 0.5 + confidence = confidence * 0.73 return confidence diff --git a/lib/requests/packages/chardet/mbcssm.py b/lib/requests/packages/chardet/mbcssm.py index 3f93cfb045c01e072de4c448d2b5bb2e25438b9b..efe678ca0394b2e0faf7051bbd86df86d54f2b51 100644 --- a/lib/requests/packages/chardet/mbcssm.py +++ b/lib/requests/packages/chardet/mbcssm.py @@ -353,7 +353,7 @@ SJIS_cls = ( 2,2,2,2,2,2,2,2, # 68 - 6f 2,2,2,2,2,2,2,2, # 70 - 77 2,2,2,2,2,2,2,1, # 78 - 7f - 3,3,3,3,3,3,3,3, # 80 - 87 + 3,3,3,3,3,2,2,3, # 80 - 87 3,3,3,3,3,3,3,3, # 88 - 8f 3,3,3,3,3,3,3,3, # 90 - 97 3,3,3,3,3,3,3,3, # 98 - 9f @@ -369,9 +369,8 @@ SJIS_cls = ( 2,2,2,2,2,2,2,2, # d8 - df 3,3,3,3,3,3,3,3, # e0 - e7 3,3,3,3,3,4,4,4, # e8 - ef - 4,4,4,4,4,4,4,4, # f0 - f7 - 4,4,4,4,4,0,0,0 # f8 - ff -) + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,0,0,0) # f8 - ff SJIS_st = ( @@ -571,5 +570,3 @@ UTF8SMModel = {'classTable': UTF8_cls, 'stateTable': UTF8_st, 'charLenTable': UTF8CharLenTable, 'name': 'UTF-8'} - -# flake8: noqa diff --git a/lib/requests/packages/chardet/sjisprober.py b/lib/requests/packages/chardet/sjisprober.py index b173614e6827b6f73eda8774a9e87f64e76a952d..cd0e9e7078b38741e9e610d7b9a92a78369a3eb9 100644 --- a/lib/requests/packages/chardet/sjisprober.py +++ b/lib/requests/packages/chardet/sjisprober.py @@ -47,7 +47,7 @@ class SJISProber(MultiByteCharSetProber): self._mContextAnalyzer.reset() def get_charset_name(self): - return "SHIFT_JIS" + return self._mContextAnalyzer.get_charset_name() def feed(self, aBuf): aLen = len(aBuf) diff --git a/lib/requests/packages/chardet/universaldetector.py b/lib/requests/packages/chardet/universaldetector.py index 9a03ad3d89ac2be24738a70bcf2798608edd56ab..476522b999646b99ace47492210595cb457690c3 100644 --- a/lib/requests/packages/chardet/universaldetector.py +++ b/lib/requests/packages/chardet/universaldetector.py @@ -71,9 +71,9 @@ class UniversalDetector: if not self._mGotData: # If the data starts with BOM, we know it is UTF - if aBuf[:3] == codecs.BOM: + if aBuf[:3] == codecs.BOM_UTF8: # EF BB BF UTF-8 with BOM - self.result = {'encoding': "UTF-8", 'confidence': 1.0} + self.result = {'encoding': "UTF-8-SIG", 'confidence': 1.0} elif aBuf[:4] == codecs.BOM_UTF32_LE: # FF FE 00 00 UTF-32, little-endian BOM self.result = {'encoding': "UTF-32LE", 'confidence': 1.0} diff --git a/lib/requests/packages/urllib3/__init__.py b/lib/requests/packages/urllib3/__init__.py index 73071f7001b5a7b6973f2d7f8985c98ca23d1d71..d7592ae7918e86d2a7937f413a96dd89a0f5426d 100644 --- a/lib/requests/packages/urllib3/__init__.py +++ b/lib/requests/packages/urllib3/__init__.py @@ -1,9 +1,3 @@ -# urllib3/__init__.py -# Copyright 2008-2013 Andrey Petrov and contributors (see CONTRIBUTORS.txt) -# -# This module is part of urllib3 and is released under -# the MIT License: http://www.opensource.org/licenses/mit-license.php - """ urllib3 - Thread-safe connection pooling and re-using. """ @@ -23,7 +17,10 @@ from . import exceptions from .filepost import encode_multipart_formdata from .poolmanager import PoolManager, ProxyManager, proxy_from_url from .response import HTTPResponse -from .util import make_headers, get_host, Timeout +from .util.request import make_headers +from .util.url import get_host +from .util.timeout import Timeout +from .util.retry import Retry # Set default logging handler to avoid "No handler found" warnings. @@ -51,8 +48,19 @@ def add_stderr_logger(level=logging.DEBUG): handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s')) logger.addHandler(handler) logger.setLevel(level) - logger.debug('Added an stderr logging handler to logger: %s' % __name__) + logger.debug('Added a stderr logging handler to logger: %s' % __name__) return handler # ... Clean up. del NullHandler + + +# Set security warning to always go off by default. +import warnings +warnings.simplefilter('always', exceptions.SecurityWarning) + +def disable_warnings(category=exceptions.HTTPWarning): + """ + Helper for quickly disabling all urllib3 warnings. + """ + warnings.simplefilter('ignore', category) diff --git a/lib/requests/packages/urllib3/_collections.py b/lib/requests/packages/urllib3/_collections.py index 5907b0dc7c45a5fa379d312e99e069b147137797..784342a4eb5939ef7682c581dad219d3dee67316 100644 --- a/lib/requests/packages/urllib3/_collections.py +++ b/lib/requests/packages/urllib3/_collections.py @@ -1,10 +1,4 @@ -# urllib3/_collections.py -# Copyright 2008-2013 Andrey Petrov and contributors (see CONTRIBUTORS.txt) -# -# This module is part of urllib3 and is released under -# the MIT License: http://www.opensource.org/licenses/mit-license.php - -from collections import MutableMapping +from collections import Mapping, MutableMapping try: from threading import RLock except ImportError: # Platform-specific: No threads available @@ -20,9 +14,10 @@ try: # Python 2.7+ from collections import OrderedDict except ImportError: from .packages.ordered_dict import OrderedDict +from .packages.six import iterkeys, itervalues -__all__ = ['RecentlyUsedContainer'] +__all__ = ['RecentlyUsedContainer', 'HTTPHeaderDict'] _Null = object() @@ -90,8 +85,7 @@ class RecentlyUsedContainer(MutableMapping): def clear(self): with self.lock: # Copy pointers to all values, then wipe the mapping - # under Python 2, this copies the list of values twice :-| - values = list(self._container.values()) + values = list(itervalues(self._container)) self._container.clear() if self.dispose_func: @@ -100,4 +94,105 @@ class RecentlyUsedContainer(MutableMapping): def keys(self): with self.lock: - return self._container.keys() + return list(iterkeys(self._container)) + + +class HTTPHeaderDict(MutableMapping): + """ + :param headers: + An iterable of field-value pairs. Must not contain multiple field names + when compared case-insensitively. + + :param kwargs: + Additional field-value pairs to pass in to ``dict.update``. + + A ``dict`` like container for storing HTTP Headers. + + Field names are stored and compared case-insensitively in compliance with + RFC 7230. Iteration provides the first case-sensitive key seen for each + case-insensitive pair. + + Using ``__setitem__`` syntax overwrites fields that compare equal + case-insensitively in order to maintain ``dict``'s api. For fields that + compare equal, instead create a new ``HTTPHeaderDict`` and use ``.add`` + in a loop. + + If multiple fields that are equal case-insensitively are passed to the + constructor or ``.update``, the behavior is undefined and some will be + lost. + + >>> headers = HTTPHeaderDict() + >>> headers.add('Set-Cookie', 'foo=bar') + >>> headers.add('set-cookie', 'baz=quxx') + >>> headers['content-length'] = '7' + >>> headers['SET-cookie'] + 'foo=bar, baz=quxx' + >>> headers['Content-Length'] + '7' + + If you want to access the raw headers with their original casing + for debugging purposes you can access the private ``._data`` attribute + which is a normal python ``dict`` that maps the case-insensitive key to a + list of tuples stored as (case-sensitive-original-name, value). Using the + structure from above as our example: + + >>> headers._data + {'set-cookie': [('Set-Cookie', 'foo=bar'), ('set-cookie', 'baz=quxx')], + 'content-length': [('content-length', '7')]} + """ + + def __init__(self, headers=None, **kwargs): + self._data = {} + if headers is None: + headers = {} + self.update(headers, **kwargs) + + def add(self, key, value): + """Adds a (name, value) pair, doesn't overwrite the value if it already + exists. + + >>> headers = HTTPHeaderDict(foo='bar') + >>> headers.add('Foo', 'baz') + >>> headers['foo'] + 'bar, baz' + """ + self._data.setdefault(key.lower(), []).append((key, value)) + + def getlist(self, key): + """Returns a list of all the values for the named field. Returns an + empty list if the key doesn't exist.""" + return self[key].split(', ') if key in self else [] + + def copy(self): + h = HTTPHeaderDict() + for key in self._data: + for rawkey, value in self._data[key]: + h.add(rawkey, value) + return h + + def __eq__(self, other): + if not isinstance(other, Mapping): + return False + other = HTTPHeaderDict(other) + return dict((k1, self[k1]) for k1 in self._data) == \ + dict((k2, other[k2]) for k2 in other._data) + + def __getitem__(self, key): + values = self._data[key.lower()] + return ', '.join(value[1] for value in values) + + def __setitem__(self, key, value): + self._data[key.lower()] = [(key, value)] + + def __delitem__(self, key): + del self._data[key.lower()] + + def __len__(self): + return len(self._data) + + def __iter__(self): + for headers in itervalues(self._data): + yield headers[0][0] + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, dict(self.items())) diff --git a/lib/requests/packages/urllib3/connection.py b/lib/requests/packages/urllib3/connection.py index c7d5b77dcc316f9590184f21c5bf2ff484bb2f3b..e5de769d8c501aaced9e174574efdc67188a3fff 100644 --- a/lib/requests/packages/urllib3/connection.py +++ b/lib/requests/packages/urllib3/connection.py @@ -1,88 +1,155 @@ -# urllib3/connection.py -# Copyright 2008-2013 Andrey Petrov and contributors (see CONTRIBUTORS.txt) -# -# This module is part of urllib3 and is released under -# the MIT License: http://www.opensource.org/licenses/mit-license.php - +import datetime +import sys import socket from socket import timeout as SocketTimeout +import warnings +from .packages import six -try: # Python 3 +try: # Python 3 from http.client import HTTPConnection as _HTTPConnection, HTTPException except ImportError: from httplib import HTTPConnection as _HTTPConnection, HTTPException + class DummyConnection(object): "Used to detect a failed ConnectionCls import." pass -try: # Compiled with SSL? - ssl = None + +try: # Compiled with SSL? HTTPSConnection = DummyConnection + import ssl + BaseSSLError = ssl.SSLError +except (ImportError, AttributeError): # Platform-specific: No SSL. + ssl = None class BaseSSLError(BaseException): pass - try: # Python 3 - from http.client import HTTPSConnection as _HTTPSConnection - except ImportError: - from httplib import HTTPSConnection as _HTTPSConnection - import ssl - BaseSSLError = ssl.SSLError +try: # Python 3: + # Not a no-op, we're adding this to the namespace so it can be imported. + ConnectionError = ConnectionError +except NameError: # Python 2: + class ConnectionError(Exception): + pass -except (ImportError, AttributeError): # Platform-specific: No SSL. - pass from .exceptions import ( ConnectTimeoutError, + SystemTimeWarning, + SecurityWarning, ) from .packages.ssl_match_hostname import match_hostname -from .util import ( - assert_fingerprint, + +from .util.ssl_ import ( resolve_cert_reqs, resolve_ssl_version, ssl_wrap_socket, + assert_fingerprint, ) +from .util import connection + port_by_scheme = { 'http': 80, 'https': 443, } +RECENT_DATE = datetime.date(2014, 1, 1) + class HTTPConnection(_HTTPConnection, object): + """ + Based on httplib.HTTPConnection but provides an extra constructor + backwards-compatibility layer between older and newer Pythons. + + Additional keyword parameters are used to configure attributes of the connection. + Accepted parameters include: + + - ``strict``: See the documentation on :class:`urllib3.connectionpool.HTTPConnectionPool` + - ``source_address``: Set the source address for the current connection. + + .. note:: This is ignored for Python 2.6. It is only applied for 2.7 and 3.x + + - ``socket_options``: Set specific options on the underlying socket. If not specified, then + defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling + Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy. + + For example, if you wish to enable TCP Keep Alive in addition to the defaults, + you might pass:: + + HTTPConnection.default_socket_options + [ + (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1), + ] + + Or you may want to disable the defaults by passing an empty list (e.g., ``[]``). + """ + default_port = port_by_scheme['http'] - # By default, disable Nagle's Algorithm. - tcp_nodelay = 1 + #: Disable Nagle's algorithm by default. + #: ``[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]`` + default_socket_options = [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)] + + #: Whether this connection verifies the host's certificate. + is_verified = False + + def __init__(self, *args, **kw): + if six.PY3: # Python 3 + kw.pop('strict', None) + + # Pre-set source_address in case we have an older Python like 2.6. + self.source_address = kw.get('source_address') + + if sys.version_info < (2, 7): # Python 2.6 + # _HTTPConnection on Python 2.6 will balk at this keyword arg, but + # not newer versions. We can still use it when creating a + # connection though, so we pop it *after* we have saved it as + # self.source_address. + kw.pop('source_address', None) + + #: The socket options provided by the user. If no options are + #: provided, we use the default options. + self.socket_options = kw.pop('socket_options', self.default_socket_options) + + # Superclass also sets self.source_address in Python 2.7+. + _HTTPConnection.__init__(self, *args, **kw) def _new_conn(self): - """ Establish a socket connection and set nodelay settings on it + """ Establish a socket connection and set nodelay settings on it. - :return: a new socket connection + :return: New socket connection. """ + extra_kw = {} + if self.source_address: + extra_kw['source_address'] = self.source_address + + if self.socket_options: + extra_kw['socket_options'] = self.socket_options + try: - conn = socket.create_connection( - (self.host, self.port), - self.timeout, - self.source_address, - ) - except AttributeError: # Python 2.6 - conn = socket.create_connection( - (self.host, self.port), - self.timeout, - ) - conn.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, - self.tcp_nodelay) + conn = connection.create_connection( + (self.host, self.port), self.timeout, **extra_kw) + + except SocketTimeout: + raise ConnectTimeoutError( + self, "Connection to %s timed out. (connect timeout=%s)" % + (self.host, self.timeout)) + return conn def _prepare_conn(self, conn): self.sock = conn + # the _tunnel_host attribute was added in python 2.6.3 (via + # http://hg.python.org/cpython/rev/0f57b30a152f) so pythons 2.6(0-2) do + # not have them. if getattr(self, '_tunnel_host', None): # TODO: Fix tunnel so it doesn't depend on self.sock state. self._tunnel() + # Mark this connection as not reusable + self.auto_open = 0 def connect(self): conn = self._new_conn() @@ -93,15 +160,18 @@ class HTTPSConnection(HTTPConnection): default_port = port_by_scheme['https'] def __init__(self, host, port=None, key_file=None, cert_file=None, - strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, - source_address=None): - try: - HTTPConnection.__init__(self, host, port, strict, timeout, source_address) - except TypeError: # Python 2.6 - HTTPConnection.__init__(self, host, port, strict, timeout) + strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, **kw): + + HTTPConnection.__init__(self, host, port, strict=strict, + timeout=timeout, **kw) + self.key_file = key_file self.cert_file = cert_file + # Required property for Google AppEngine 1.9.0 which otherwise causes + # HTTPS requests to go out as HTTP. (See Issue #356) + self._protocol = 'https' + def connect(self): conn = self._new_conn() self._prepare_conn(conn) @@ -116,6 +186,7 @@ class VerifiedHTTPSConnection(HTTPSConnection): cert_reqs = None ca_certs = None ssl_version = None + assert_fingerprint = None def set_cert(self, key_file=None, cert_file=None, cert_reqs=None, ca_certs=None, @@ -130,46 +201,59 @@ class VerifiedHTTPSConnection(HTTPSConnection): def connect(self): # Add certificate verification - try: - sock = socket.create_connection( - address=(self.host, self.port), - timeout=self.timeout, - ) - except SocketTimeout: - raise ConnectTimeoutError( - self, "Connection to %s timed out. (connect timeout=%s)" % - (self.host, self.timeout)) - - sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, - self.tcp_nodelay) + conn = self._new_conn() resolved_cert_reqs = resolve_cert_reqs(self.cert_reqs) resolved_ssl_version = resolve_ssl_version(self.ssl_version) - # the _tunnel_host attribute was added in python 2.6.3 (via - # http://hg.python.org/cpython/rev/0f57b30a152f) so pythons 2.6(0-2) do - # not have them. + hostname = self.host if getattr(self, '_tunnel_host', None): - self.sock = sock + # _tunnel_host was added in Python 2.6.3 + # (See: http://hg.python.org/cpython/rev/0f57b30a152f) + + self.sock = conn # Calls self._set_hostport(), so self.host is # self._tunnel_host below. self._tunnel() + # Mark this connection as not reusable + self.auto_open = 0 + + # Override the host with the one we're requesting data from. + hostname = self._tunnel_host + + is_time_off = datetime.date.today() < RECENT_DATE + if is_time_off: + warnings.warn(( + 'System time is way off (before {0}). This will probably ' + 'lead to SSL verification errors').format(RECENT_DATE), + SystemTimeWarning + ) # Wrap socket using verification with the root certs in # trusted_root_certs - self.sock = ssl_wrap_socket(sock, self.key_file, self.cert_file, + self.sock = ssl_wrap_socket(conn, self.key_file, self.cert_file, cert_reqs=resolved_cert_reqs, ca_certs=self.ca_certs, - server_hostname=self.host, + server_hostname=hostname, ssl_version=resolved_ssl_version) - if resolved_cert_reqs != ssl.CERT_NONE: - if self.assert_fingerprint: - assert_fingerprint(self.sock.getpeercert(binary_form=True), - self.assert_fingerprint) - elif self.assert_hostname is not False: - match_hostname(self.sock.getpeercert(), - self.assert_hostname or self.host) + if self.assert_fingerprint: + assert_fingerprint(self.sock.getpeercert(binary_form=True), + self.assert_fingerprint) + elif resolved_cert_reqs != ssl.CERT_NONE \ + and self.assert_hostname is not False: + cert = self.sock.getpeercert() + if not cert.get('subjectAltName', ()): + warnings.warn(( + 'Certificate has no `subjectAltName`, falling back to check for a `commonName` for now. ' + 'This feature is being removed by major browsers and deprecated by RFC 2818. ' + '(See https://github.com/shazow/urllib3/issues/497 for details.)'), + SecurityWarning + ) + match_hostname(cert, self.assert_hostname or hostname) + + self.is_verified = (resolved_cert_reqs == ssl.CERT_REQUIRED + or self.assert_fingerprint is not None) if ssl: diff --git a/lib/requests/packages/urllib3/connectionpool.py b/lib/requests/packages/urllib3/connectionpool.py index 243d700ee8fef8a0efa0f07620ebecfc292a8c2c..8bdf228ffe1fcc308e7f9c3a98cac7bc19b17f3f 100644 --- a/lib/requests/packages/urllib3/connectionpool.py +++ b/lib/requests/packages/urllib3/connectionpool.py @@ -1,16 +1,12 @@ -# urllib3/connectionpool.py -# Copyright 2008-2013 Andrey Petrov and contributors (see CONTRIBUTORS.txt) -# -# This module is part of urllib3 and is released under -# the MIT License: http://www.opensource.org/licenses/mit-license.php - import errno import logging +import sys +import warnings from socket import error as SocketError, timeout as SocketTimeout import socket -try: # Python 3 +try: # Python 3 from queue import LifoQueue, Empty, Full except ImportError: from Queue import LifoQueue, Empty, Full @@ -19,14 +15,16 @@ except ImportError: from .exceptions import ( ClosedPoolError, - ConnectTimeoutError, + ProtocolError, EmptyPoolError, HostChangedError, + LocationValueError, MaxRetryError, + ProxyError, + ReadTimeoutError, SSLError, TimeoutError, - ReadTimeoutError, - ProxyError, + InsecureRequestWarning, ) from .packages.ssl_match_hostname import CertificateError from .packages import six @@ -34,16 +32,15 @@ from .connection import ( port_by_scheme, DummyConnection, HTTPConnection, HTTPSConnection, VerifiedHTTPSConnection, - HTTPException, BaseSSLError, + HTTPException, BaseSSLError, ConnectionError ) from .request import RequestMethods from .response import HTTPResponse -from .util import ( - assert_fingerprint, - get_host, - is_connection_dropped, - Timeout, -) + +from .util.connection import is_connection_dropped +from .util.retry import Retry +from .util.timeout import Timeout +from .util.url import get_host xrange = six.moves.xrange @@ -52,8 +49,8 @@ log = logging.getLogger(__name__) _Default = object() -## Pool objects +## Pool objects class ConnectionPool(object): """ Base class for all connection pools, such as @@ -64,10 +61,11 @@ class ConnectionPool(object): QueueCls = LifoQueue def __init__(self, host, port=None): - # httplib doesn't like it when we include brackets in ipv6 addresses - host = host.strip('[]') + if not host: + raise LocationValueError("No host specified.") - self.host = host + # httplib doesn't like it when we include brackets in ipv6 addresses + self.host = host.strip('[]') self.port = port def __str__(self): @@ -77,6 +75,7 @@ class ConnectionPool(object): # This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252 _blocking_errnos = set([errno.EAGAIN, errno.EWOULDBLOCK]) + class HTTPConnectionPool(ConnectionPool, RequestMethods): """ Thread-safe connection pool for one host. @@ -121,6 +120,9 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): Headers to include with all requests, unless other headers are given explicitly. + :param retries: + Retry configuration to use by default with requests in this pool. + :param _proxy: Parsed proxy URL, should not be used directly, instead, see :class:`urllib3.connectionpool.ProxyManager`" @@ -128,6 +130,10 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): :param _proxy_headers: A dictionary with proxy headers, should not be used directly, instead, see :class:`urllib3.connectionpool.ProxyManager`" + + :param \**conn_kw: + Additional parameters are used to create fresh :class:`urllib3.connection.HTTPConnection`, + :class:`urllib3.connection.HTTPSConnection` instances. """ scheme = 'http' @@ -135,18 +141,22 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): def __init__(self, host, port=None, strict=False, timeout=Timeout.DEFAULT_TIMEOUT, maxsize=1, block=False, - headers=None, _proxy=None, _proxy_headers=None): + headers=None, retries=None, + _proxy=None, _proxy_headers=None, + **conn_kw): ConnectionPool.__init__(self, host, port) RequestMethods.__init__(self, headers) self.strict = strict - # This is for backwards compatibility and can be removed once a timeout - # can only be set to a Timeout object if not isinstance(timeout, Timeout): timeout = Timeout.from_float(timeout) + if retries is None: + retries = Retry.DEFAULT + self.timeout = timeout + self.retries = retries self.pool = self.QueueCls(maxsize) self.block = block @@ -161,6 +171,13 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): # These are mostly for testing and debugging purposes. self.num_connections = 0 self.num_requests = 0 + self.conn_kw = conn_kw + + if self.proxy: + # Enable Nagle's algorithm for proxies, to avoid packet fragmentation. + # We cannot know if the user has added default socket options, so we cannot replace the + # list. + self.conn_kw.setdefault('socket_options', []) def _new_conn(self): """ @@ -170,17 +187,9 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): log.info("Starting new HTTP connection (%d): %s" % (self.num_connections, self.host)) - extra_params = {} - if not six.PY3: # Python 2 - extra_params['strict'] = self.strict - conn = self.ConnectionCls(host=self.host, port=self.port, timeout=self.timeout.connect_timeout, - **extra_params) - if self.proxy is not None: - # Enable Nagle's algorithm for proxies, to avoid packet - # fragmentation. - conn.tcp_nodelay = 0 + strict=self.strict, **self.conn_kw) return conn def _get_conn(self, timeout=None): @@ -199,7 +208,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): try: conn = self.pool.get(block=self.block, timeout=timeout) - except AttributeError: # self.pool is None + except AttributeError: # self.pool is None raise ClosedPoolError(self, "Pool is closed.") except Empty: @@ -213,6 +222,11 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): if conn and is_connection_dropped(conn): log.info("Resetting dropped connection: %s" % self.host) conn.close() + if getattr(conn, 'auto_open', 1) == 0: + # This is a proxied connection that has been mutated by + # httplib._tunnel() and cannot be reused (since it would + # attempt to bypass the proxy) + conn = None return conn or self._new_conn() @@ -232,19 +246,30 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): """ try: self.pool.put(conn, block=False) - return # Everything is dandy, done. + return # Everything is dandy, done. except AttributeError: # self.pool is None. pass except Full: # This should never happen if self.block == True - log.warning("HttpConnectionPool is full, discarding connection: %s" - % self.host) + log.warning( + "Connection pool is full, discarding connection: %s" % + self.host) # Connection never got put back into the pool, close it. if conn: conn.close() + def _validate_conn(self, conn): + """ + Called right before a request is made, after the socket is created. + """ + pass + + def _prepare_proxy(self, conn): + # Nothing to do for HTTP connections. + pass + def _get_timeout(self, timeout): """ Helper that always returns a :class:`urllib3.util.Timeout` """ if timeout is _Default: @@ -257,6 +282,23 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): # can be removed later return Timeout.from_float(timeout) + def _raise_timeout(self, err, url, timeout_value): + """Is the error actually a timeout? Will raise a ReadTimeout or pass""" + + if isinstance(err, SocketTimeout): + raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) + + # See the above comment about EAGAIN in Python 3. In Python 2 we have + # to specifically catch it and throw the timeout error + if hasattr(err, 'errno') and err.errno in _blocking_errnos: + raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) + + # Catch possible read timeouts thrown as SSL errors. If not the + # case, rethrow the original. We need to do this because of: + # http://bugs.python.org/issue10272 + if 'timed out' in str(err) or 'did not complete (read)' in str(err): # Python 2.6 + raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) + def _make_request(self, conn, method, url, timeout=_Default, **httplib_request_kw): """ @@ -276,23 +318,26 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): self.num_requests += 1 timeout_obj = self._get_timeout(timeout) + timeout_obj.start_connect() + conn.timeout = timeout_obj.connect_timeout + # Trigger any extra validation we need to do. try: - timeout_obj.start_connect() - conn.timeout = timeout_obj.connect_timeout - # conn.request() calls httplib.*.request, not the method in - # urllib3.request. It also calls makefile (recv) on the socket. - conn.request(method, url, **httplib_request_kw) - except SocketTimeout: - raise ConnectTimeoutError( - self, "Connection to %s timed out. (connect timeout=%s)" % - (self.host, timeout_obj.connect_timeout)) + self._validate_conn(conn) + except (SocketTimeout, BaseSSLError) as e: + # Py2 raises this as a BaseSSLError, Py3 raises it as socket timeout. + self._raise_timeout(err=e, url=url, timeout_value=conn.timeout) + raise + + # conn.request() calls httplib.*.request, not the method in + # urllib3.request. It also calls makefile (recv) on the socket. + conn.request(method, url, **httplib_request_kw) # Reset the timeout for the recv() on the socket read_timeout = timeout_obj.read_timeout # App Engine doesn't have a sock attr - if hasattr(conn, 'sock'): + if getattr(conn, 'sock', None): # In Python 3 socket.py will catch EAGAIN and return None when you # try and read into the file pointer created by http.client, which # instead raises a BadStatusLine exception. Instead of catching @@ -300,41 +345,20 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): # timeouts, check for a zero timeout before making the request. if read_timeout == 0: raise ReadTimeoutError( - self, url, - "Read timed out. (read timeout=%s)" % read_timeout) + self, url, "Read timed out. (read timeout=%s)" % read_timeout) if read_timeout is Timeout.DEFAULT_TIMEOUT: conn.sock.settimeout(socket.getdefaulttimeout()) - else: # None or a value + else: # None or a value conn.sock.settimeout(read_timeout) # Receive the response from the server try: - try: # Python 2.7+, use buffering of HTTP responses + try: # Python 2.7+, use buffering of HTTP responses httplib_response = conn.getresponse(buffering=True) - except TypeError: # Python 2.6 and older + except TypeError: # Python 2.6 and older httplib_response = conn.getresponse() - except SocketTimeout: - raise ReadTimeoutError( - self, url, "Read timed out. (read timeout=%s)" % read_timeout) - - except BaseSSLError as e: - # Catch possible read timeouts thrown as SSL errors. If not the - # case, rethrow the original. We need to do this because of: - # http://bugs.python.org/issue10272 - if 'timed out' in str(e) or \ - 'did not complete (read)' in str(e): # Python 2.6 - raise ReadTimeoutError(self, url, "Read timed out.") - - raise - - except SocketError as e: # Platform-specific: Python 2 - # See the above comment about EAGAIN in Python 3. In Python 2 we - # have to specifically catch it and throw the timeout error - if e.errno in _blocking_errnos: - raise ReadTimeoutError( - self, url, - "Read timed out. (read timeout=%s)" % read_timeout) - + except (SocketTimeout, BaseSSLError, SocketError) as e: + self._raise_timeout(err=e, url=url, timeout_value=read_timeout) raise # AppEngine doesn't have a version attr. @@ -358,7 +382,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): conn.close() except Empty: - pass # Done. + pass # Done. def is_same_host(self, url): """ @@ -379,7 +403,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): return (scheme, host, port) == (self.scheme, self.host, self.port) - def urlopen(self, method, url, body=None, headers=None, retries=3, + def urlopen(self, method, url, body=None, headers=None, retries=None, redirect=True, assert_same_host=True, timeout=_Default, pool_timeout=None, release_conn=None, **response_kw): """ @@ -413,11 +437,25 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): these headers completely replace any pool-specific headers. :param retries: - Number of retries to allow before raising a MaxRetryError exception. + Configure the number of retries to allow before raising a + :class:`~urllib3.exceptions.MaxRetryError` exception. + + Pass ``None`` to retry until you receive a response. Pass a + :class:`~urllib3.util.retry.Retry` object for fine-grained control + over different types of retries. + Pass an integer number to retry connection errors that many times, + but no other types of errors. Pass zero to never retry. + + If ``False``, then retries are disabled and any exception is raised + immediately. Also, instead of raising a MaxRetryError on redirects, + the redirect response will be returned. + + :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, - 303, 307, 308). Each redirect counts as a retry. + 303, 307, 308). Each redirect counts as a retry. Disabling retries + will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is @@ -451,15 +489,15 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): if headers is None: headers = self.headers - if retries < 0: - raise MaxRetryError(self, url) + if not isinstance(retries, Retry): + retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = response_kw.get('preload_content', True) # Check host if assert_same_host and not self.is_same_host(url): - raise HostChangedError(self, url, retries - 1) + raise HostChangedError(self, url, retries) conn = None @@ -470,13 +508,24 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): headers = headers.copy() headers.update(self.proxy_headers) + # Must keep the exception bound to a separate variable or else Python 3 + # complains about UnboundLocalError. + err = None + try: - # Request a connection from the queue + # Request a connection from the queue. + timeout_obj = self._get_timeout(timeout) conn = self._get_conn(timeout=pool_timeout) - # Make the request on the httplib connection object + conn.timeout = timeout_obj.connect_timeout + + is_new_proxy_conn = self.proxy is not None and not getattr(conn, 'sock', None) + if is_new_proxy_conn: + self._prepare_proxy(conn) + + # Make the request on the httplib connection object. httplib_response = self._make_request(conn, method, url, - timeout=timeout, + timeout=timeout_obj, body=body, headers=headers) # If we're going to release the connection in ``finally:``, then @@ -497,38 +546,38 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): # ``response.read()``) except Empty: - # Timed out by queue + # Timed out by queue. raise EmptyPoolError(self, "No pool connections are available.") - except BaseSSLError as e: + except (BaseSSLError, CertificateError) as e: + # Close the connection. If a connection is reused on which there + # was a Certificate error, the next request will certainly raise + # another Certificate error. + if conn: + conn.close() + conn = None raise SSLError(e) - except CertificateError as e: - # Name mismatch - raise SSLError(e) + except (TimeoutError, HTTPException, SocketError, ConnectionError) as e: + if conn: + # Discard the connection for these exceptions. It will be + # be replaced during the next _get_conn() call. + conn.close() + conn = None - except TimeoutError as e: - # Connection broken, discard. - conn = None - # Save the error off for retry logic. - err = e + stacktrace = sys.exc_info()[2] + if isinstance(e, SocketError) and self.proxy: + e = ProxyError('Cannot connect to proxy.', e) + elif isinstance(e, (SocketError, HTTPException)): + e = ProtocolError('Connection aborted.', e) - if retries == 0: - raise + retries = retries.increment(method, url, error=e, + _pool=self, _stacktrace=stacktrace) + retries.sleep() - except (HTTPException, SocketError) as e: - # Connection broken, discard. It will be replaced next _get_conn(). - conn = None - # This is necessary so we can access e below + # Keep track of the error for the retry warning. err = e - if retries == 0: - if isinstance(e, SocketError) and self.proxy is not None: - raise ProxyError('Cannot connect to proxy. ' - 'Socket error: %s.' % e) - else: - raise MaxRetryError(self, url, e) - finally: if release_conn: # Put the connection back to be reused. If the connection is @@ -538,9 +587,9 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): if not conn: # Try again - log.warn("Retrying (%d attempts remain) after connection " - "broken by '%r': %s" % (retries, err, url)) - return self.urlopen(method, url, body, headers, retries - 1, + log.warning("Retrying (%r) after connection " + "broken by '%r': %s" % (retries, err, url)) + return self.urlopen(method, url, body, headers, retries, redirect, assert_same_host, timeout=timeout, pool_timeout=pool_timeout, release_conn=release_conn, **response_kw) @@ -550,11 +599,31 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): if redirect_location: if response.status == 303: method = 'GET' + + try: + retries = retries.increment(method, url, response=response, _pool=self) + except MaxRetryError: + if retries.raise_on_redirect: + raise + return response + log.info("Redirecting %s -> %s" % (url, redirect_location)) return self.urlopen(method, redirect_location, body, headers, - retries - 1, redirect, assert_same_host, - timeout=timeout, pool_timeout=pool_timeout, - release_conn=release_conn, **response_kw) + retries=retries, redirect=redirect, + assert_same_host=assert_same_host, + timeout=timeout, pool_timeout=pool_timeout, + release_conn=release_conn, **response_kw) + + # Check if we should retry the HTTP response. + if retries.is_forced_retry(method, status_code=response.status): + retries = retries.increment(method, url, response=response, _pool=self) + retries.sleep() + log.info("Forced retry: %s" % url) + return self.urlopen(method, url, body, headers, + retries=retries, redirect=redirect, + assert_same_host=assert_same_host, + timeout=timeout, pool_timeout=pool_timeout, + release_conn=release_conn, **response_kw) return response @@ -581,15 +650,17 @@ class HTTPSConnectionPool(HTTPConnectionPool): ConnectionCls = HTTPSConnection def __init__(self, host, port=None, - strict=False, timeout=None, maxsize=1, - block=False, headers=None, + strict=False, timeout=Timeout.DEFAULT_TIMEOUT, maxsize=1, + block=False, headers=None, retries=None, _proxy=None, _proxy_headers=None, key_file=None, cert_file=None, cert_reqs=None, ca_certs=None, ssl_version=None, - assert_hostname=None, assert_fingerprint=None): + assert_hostname=None, assert_fingerprint=None, + **conn_kw): HTTPConnectionPool.__init__(self, host, port, strict, timeout, maxsize, - block, headers, _proxy, _proxy_headers) + block, headers, retries, _proxy, _proxy_headers, + **conn_kw) self.key_file = key_file self.cert_file = cert_file self.cert_reqs = cert_reqs @@ -613,18 +684,25 @@ class HTTPSConnectionPool(HTTPConnectionPool): assert_fingerprint=self.assert_fingerprint) conn.ssl_version = self.ssl_version - if self.proxy is not None: - # Python 2.7+ - try: - set_tunnel = conn.set_tunnel - except AttributeError: # Platform-specific: Python 2.6 - set_tunnel = conn._set_tunnel + return conn + + def _prepare_proxy(self, conn): + """ + Establish tunnel connection early, because otherwise httplib + would improperly set Host: header to proxy's IP:port. + """ + # Python 2.7+ + try: + set_tunnel = conn.set_tunnel + except AttributeError: # Platform-specific: Python 2.6 + set_tunnel = conn._set_tunnel + + if sys.version_info <= (2, 6, 4) and not self.proxy_headers: # Python 2.6.4 and older + set_tunnel(self.host, self.port) + else: set_tunnel(self.host, self.port, self.proxy_headers) - # Establish tunnel connection early, because otherwise httplib - # would improperly set Host: header to proxy's IP:port. - conn.connect() - return conn + conn.connect() def _new_conn(self): """ @@ -645,20 +723,29 @@ class HTTPSConnectionPool(HTTPConnectionPool): actual_host = self.proxy.host actual_port = self.proxy.port - extra_params = {} - if not six.PY3: # Python 2 - extra_params['strict'] = self.strict - conn = self.ConnectionCls(host=actual_host, port=actual_port, timeout=self.timeout.connect_timeout, - **extra_params) - if self.proxy is not None: - # Enable Nagle's algorithm for proxies, to avoid packet - # fragmentation. - conn.tcp_nodelay = 0 + strict=self.strict, **self.conn_kw) return self._prepare_conn(conn) + def _validate_conn(self, conn): + """ + Called right before a request is made, after the socket is created. + """ + super(HTTPSConnectionPool, self)._validate_conn(conn) + + # Force connect early to allow us to validate the connection. + if not getattr(conn, 'sock', None): # AppEngine might not have `.sock` + conn.connect() + + if not conn.is_verified: + warnings.warn(( + 'Unverified HTTPS request is being made. ' + 'Adding certificate verification is strongly advised. See: ' + 'https://urllib3.readthedocs.org/en/latest/security.html'), + InsecureRequestWarning) + def connection_from_url(url, **kw): """ @@ -675,7 +762,7 @@ def connection_from_url(url, **kw): :class:`.ConnectionPool`. Useful for specifying things like timeout, maxsize, headers, etc. - Example: :: + Example:: >>> conn = connection_from_url('http://google.com/') >>> r = conn.request('GET', '/') diff --git a/lib/requests/packages/urllib3/contrib/ntlmpool.py b/lib/requests/packages/urllib3/contrib/ntlmpool.py index b8cd933034cc48ef733209850380ec4ebdc79e10..c6b266f5d1803a036f6e9de6bdc7ec4be7af6350 100644 --- a/lib/requests/packages/urllib3/contrib/ntlmpool.py +++ b/lib/requests/packages/urllib3/contrib/ntlmpool.py @@ -1,9 +1,3 @@ -# urllib3/contrib/ntlmpool.py -# Copyright 2008-2013 Andrey Petrov and contributors (see CONTRIBUTORS.txt) -# -# This module is part of urllib3 and is released under -# the MIT License: http://www.opensource.org/licenses/mit-license.php - """ NTLM authenticating pool, contributed by erikcederstran diff --git a/lib/requests/packages/urllib3/contrib/pyopenssl.py b/lib/requests/packages/urllib3/contrib/pyopenssl.py index c3df278b1e3e00ee1528b66203e3368a3f71a00a..ee657fb3f2905560165e005280d9af9b5b58628d 100644 --- a/lib/requests/packages/urllib3/contrib/pyopenssl.py +++ b/lib/requests/packages/urllib3/contrib/pyopenssl.py @@ -1,4 +1,7 @@ -'''SSL with SNI_-support for Python 2. +'''SSL with SNI_-support for Python 2. Follow these instructions if you would +like to verify SSL certificates in Python 2. Note, the default libraries do +*not* do certificate checking; you need to do additional work to validate +certificates yourself. This needs the following packages installed: @@ -6,9 +9,15 @@ This needs the following packages installed: * ndg-httpsclient (tested with 0.3.2) * pyasn1 (tested with 0.1.6) -To activate it call :func:`~urllib3.contrib.pyopenssl.inject_into_urllib3`. -This can be done in a ``sitecustomize`` module, or at any other time before -your application begins using ``urllib3``, like this:: +You can install them with the following command: + + pip install pyopenssl ndg-httpsclient pyasn1 + +To activate certificate checking, call +:func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code +before you begin making HTTP requests. This can be done in a ``sitecustomize`` +module, or at any other time before your application begins using ``urllib3``, +like this:: try: import urllib3.contrib.pyopenssl @@ -20,7 +29,7 @@ Now you can use :mod:`urllib3` as you normally would, and it will support SNI when the required modules are installed. Activating this module also has the positive side effect of disabling SSL/TLS -encryption in Python 2 (see `CRIME attack`_). +compression in Python 2 (see `CRIME attack`_). If you want to configure the default list of supported cipher suites, you can set the ``urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST`` variable. @@ -29,24 +38,26 @@ Module Variables ---------------- :var DEFAULT_SSL_CIPHER_LIST: The list of supported SSL/TLS cipher suites. - Default: ``EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA256 - EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EDH+aRSA EECDH RC4 !aNULL !eNULL !LOW !3DES - !MD5 !EXP !PSK !SRP !DSS'`` + Default: ``ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES: + ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS`` .. _sni: https://en.wikipedia.org/wiki/Server_Name_Indication .. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit) ''' -from ndg.httpsclient.ssl_peer_verification import SUBJ_ALT_NAME_SUPPORT -from ndg.httpsclient.subj_alt_name import SubjectAltName as BaseSubjectAltName +try: + from ndg.httpsclient.ssl_peer_verification import SUBJ_ALT_NAME_SUPPORT + from ndg.httpsclient.subj_alt_name import SubjectAltName as BaseSubjectAltName +except SyntaxError as e: + raise ImportError(e) + import OpenSSL.SSL from pyasn1.codec.der import decoder as der_decoder from pyasn1.type import univ, constraint -from socket import _fileobject +from socket import _fileobject, timeout import ssl import select -from cStringIO import StringIO from .. import connection from .. import util @@ -74,12 +85,22 @@ _openssl_verify = { + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT, } -# Default SSL/TLS cipher list. -# Recommendation by https://community.qualys.com/blogs/securitylabs/2013/08/05/ -# configuring-apache-nginx-and-openssl-for-forward-secrecy -DEFAULT_SSL_CIPHER_LIST = 'EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM ' + \ - 'EECDH+ECDSA+SHA256 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EDH+aRSA ' + \ - 'EECDH RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS' +# A secure default. +# Sources for more information on TLS ciphers: +# +# - https://wiki.mozilla.org/Security/Server_Side_TLS +# - https://www.ssllabs.com/projects/best-practices/index.html +# - https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ +# +# The general intent is: +# - Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE), +# - prefer ECDHE over DHE for better performance, +# - prefer any AES-GCM over any AES-CBC for better performance and security, +# - use 3DES as fallback which is secure but slow, +# - disable NULL authentication, MD5 MACs and DSS for security reasons. +DEFAULT_SSL_CIPHER_LIST = "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:" + \ + "ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:" + \ + "!aNULL:!MD5:!DSS" orig_util_HAS_SNI = util.HAS_SNI @@ -142,193 +163,73 @@ def get_subj_alt_name(peer_cert): return dns_name -class fileobject(_fileobject): - - def read(self, size=-1): - # Use max, disallow tiny reads in a loop as they are very inefficient. - # We never leave read() with any leftover data from a new recv() call - # in our internal buffer. - rbufsize = max(self._rbufsize, self.default_bufsize) - # Our use of StringIO rather than lists of string objects returned by - # recv() minimizes memory usage and fragmentation that occurs when - # rbufsize is large compared to the typical return value of recv(). - buf = self._rbuf - buf.seek(0, 2) # seek end - if size < 0: - # Read until EOF - self._rbuf = StringIO() # reset _rbuf. we consume it via buf. - while True: - try: - data = self._sock.recv(rbufsize) - except OpenSSL.SSL.WantReadError: - continue - if not data: - break - buf.write(data) - return buf.getvalue() - else: - # Read until size bytes or EOF seen, whichever comes first - buf_len = buf.tell() - if buf_len >= size: - # Already have size bytes in our buffer? Extract and return. - buf.seek(0) - rv = buf.read(size) - self._rbuf = StringIO() - self._rbuf.write(buf.read()) - return rv - - self._rbuf = StringIO() # reset _rbuf. we consume it via buf. - while True: - left = size - buf_len - # recv() will malloc the amount of memory given as its - # parameter even though it often returns much less data - # than that. The returned data string is short lived - # as we copy it into a StringIO and free it. This avoids - # fragmentation issues on many platforms. - try: - data = self._sock.recv(left) - except OpenSSL.SSL.WantReadError: - continue - if not data: - break - n = len(data) - if n == size and not buf_len: - # Shortcut. Avoid buffer data copies when: - # - We have no data in our buffer. - # AND - # - Our call to recv returned exactly the - # number of bytes we were asked to read. - return data - if n == left: - buf.write(data) - del data # explicit free - break - assert n <= left, "recv(%d) returned %d bytes" % (left, n) - buf.write(data) - buf_len += n - del data # explicit free - #assert buf_len == buf.tell() - return buf.getvalue() - - def readline(self, size=-1): - buf = self._rbuf - buf.seek(0, 2) # seek end - if buf.tell() > 0: - # check if we already have it in our buffer - buf.seek(0) - bline = buf.readline(size) - if bline.endswith('\n') or len(bline) == size: - self._rbuf = StringIO() - self._rbuf.write(buf.read()) - return bline - del bline - if size < 0: - # Read until \n or EOF, whichever comes first - if self._rbufsize <= 1: - # Speed up unbuffered case - buf.seek(0) - buffers = [buf.read()] - self._rbuf = StringIO() # reset _rbuf. we consume it via buf. - data = None - recv = self._sock.recv - while True: - try: - while data != "\n": - data = recv(1) - if not data: - break - buffers.append(data) - except OpenSSL.SSL.WantReadError: - continue - break - return "".join(buffers) - - buf.seek(0, 2) # seek end - self._rbuf = StringIO() # reset _rbuf. we consume it via buf. - while True: - try: - data = self._sock.recv(self._rbufsize) - except OpenSSL.SSL.WantReadError: - continue - if not data: - break - nl = data.find('\n') - if nl >= 0: - nl += 1 - buf.write(data[:nl]) - self._rbuf.write(data[nl:]) - del data - break - buf.write(data) - return buf.getvalue() - else: - # Read until size bytes or \n or EOF seen, whichever comes first - buf.seek(0, 2) # seek end - buf_len = buf.tell() - if buf_len >= size: - buf.seek(0) - rv = buf.read(size) - self._rbuf = StringIO() - self._rbuf.write(buf.read()) - return rv - self._rbuf = StringIO() # reset _rbuf. we consume it via buf. - while True: - try: - data = self._sock.recv(self._rbufsize) - except OpenSSL.SSL.WantReadError: - continue - if not data: - break - left = size - buf_len - # did we just receive a newline? - nl = data.find('\n', 0, left) - if nl >= 0: - nl += 1 - # save the excess data to _rbuf - self._rbuf.write(data[nl:]) - if buf_len: - buf.write(data[:nl]) - break - else: - # Shortcut. Avoid data copy through buf when returning - # a substring of our first recv(). - return data[:nl] - n = len(data) - if n == size and not buf_len: - # Shortcut. Avoid data copy through buf when - # returning exactly all of our first recv(). - return data - if n >= left: - buf.write(data[:left]) - self._rbuf.write(data[left:]) - break - buf.write(data) - buf_len += n - #assert buf_len == buf.tell() - return buf.getvalue() - - class WrappedSocket(object): - '''API-compatibility wrapper for Python OpenSSL's Connection-class.''' + '''API-compatibility wrapper for Python OpenSSL's Connection-class. - def __init__(self, connection, socket): + Note: _makefile_refs, _drop() and _reuse() are needed for the garbage + collector of pypy. + ''' + + def __init__(self, connection, socket, suppress_ragged_eofs=True): self.connection = connection self.socket = socket + self.suppress_ragged_eofs = suppress_ragged_eofs + self._makefile_refs = 0 def fileno(self): return self.socket.fileno() def makefile(self, mode, bufsize=-1): - return fileobject(self.connection, mode, bufsize) + self._makefile_refs += 1 + return _fileobject(self, mode, bufsize, close=True) + + def recv(self, *args, **kwargs): + try: + data = self.connection.recv(*args, **kwargs) + except OpenSSL.SSL.SysCallError as e: + if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'): + return b'' + else: + raise + except OpenSSL.SSL.ZeroReturnError as e: + if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: + return b'' + else: + raise + except OpenSSL.SSL.WantReadError: + rd, wd, ed = select.select( + [self.socket], [], [], self.socket.gettimeout()) + if not rd: + raise timeout('The read operation timed out') + else: + return self.recv(*args, **kwargs) + else: + return data def settimeout(self, timeout): return self.socket.settimeout(timeout) + def _send_until_done(self, data): + while True: + try: + return self.connection.send(data) + except OpenSSL.SSL.WantWriteError: + _, wlist, _ = select.select([], [self.socket], [], + self.socket.gettimeout()) + if not wlist: + raise timeout() + continue + def sendall(self, data): - return self.connection.sendall(data) + while len(data): + sent = self._send_until_done(data) + data = data[sent:] def close(self): - return self.connection.shutdown() + if self._makefile_refs < 1: + return self.connection.shutdown() + else: + self._makefile_refs -= 1 def getpeercert(self, binary_form=False): x509 = self.connection.get_peer_certificate() @@ -351,6 +252,15 @@ class WrappedSocket(object): ] } + def _reuse(self): + self._makefile_refs += 1 + + def _drop(self): + if self._makefile_refs < 1: + self.close() + else: + self._makefile_refs -= 1 + def _verify_callback(cnx, x509, err_no, err_depth, return_code): return err_no == 0 @@ -361,6 +271,7 @@ def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None, ssl_version=None): ctx = OpenSSL.SSL.Context(_openssl_versions[ssl_version]) if certfile: + keyfile = keyfile or certfile # Match behaviour of the normal python ssl library ctx.use_certificate_file(certfile) if keyfile: ctx.use_privatekey_file(keyfile) @@ -371,6 +282,8 @@ def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None, ctx.load_verify_locations(ca_certs, None) except OpenSSL.SSL.Error as e: raise ssl.SSLError('bad ca_certs: %r' % ca_certs, e) + else: + ctx.set_default_verify_paths() # Disable TLS compression to migitate CRIME attack (issue #309) OP_NO_COMPRESSION = 0x20000 diff --git a/lib/requests/packages/urllib3/exceptions.py b/lib/requests/packages/urllib3/exceptions.py index 98ef9abc7f054d586dc44b08f21476f54b00e79b..0c6fd3c51b7486ebf105b26d9799e6208f00ad18 100644 --- a/lib/requests/packages/urllib3/exceptions.py +++ b/lib/requests/packages/urllib3/exceptions.py @@ -1,9 +1,3 @@ -# urllib3/exceptions.py -# Copyright 2008-2013 Andrey Petrov and contributors (see CONTRIBUTORS.txt) -# -# This module is part of urllib3 and is released under -# the MIT License: http://www.opensource.org/licenses/mit-license.php - ## Base Exceptions @@ -11,6 +5,11 @@ class HTTPError(Exception): "Base exception used by this module." pass +class HTTPWarning(Warning): + "Base warning used by this module." + pass + + class PoolError(HTTPError): "Base exception for errors caused within a pool." @@ -49,19 +48,32 @@ class DecodeError(HTTPError): pass +class ProtocolError(HTTPError): + "Raised when something unexpected happens mid-request/response." + pass + + +#: Renamed to ProtocolError but aliased for backwards compatibility. +ConnectionError = ProtocolError + + ## Leaf Exceptions class MaxRetryError(RequestError): - "Raised when the maximum number of retries is exceeded." + """Raised when the maximum number of retries is exceeded. + + :param pool: The connection pool + :type pool: :class:`~urllib3.connectionpool.HTTPConnectionPool` + :param string url: The requested Url + :param exceptions.Exception reason: The underlying error + + """ def __init__(self, pool, url, reason=None): self.reason = reason - message = "Max retries exceeded with url: %s" % url - if reason: - message += " (Caused by %s: %s)" % (type(reason), reason) - else: - message += " (Caused by redirect)" + message = "Max retries exceeded with url: %s (Caused by %r)" % ( + url, reason) RequestError.__init__(self, pool, url, message) @@ -111,7 +123,12 @@ class ClosedPoolError(PoolError): pass -class LocationParseError(ValueError, HTTPError): +class LocationValueError(ValueError, HTTPError): + "Raised when there is something wrong with a given URL input." + pass + + +class LocationParseError(LocationValueError): "Raised when get_host or similar fails to parse the URL input." def __init__(self, location): @@ -119,3 +136,24 @@ class LocationParseError(ValueError, HTTPError): HTTPError.__init__(self, message) self.location = location + + +class ResponseError(HTTPError): + "Used as a container for an error reason supplied in a MaxRetryError." + GENERIC_ERROR = 'too many error responses' + SPECIFIC_ERROR = 'too many {status_code} error responses' + + +class SecurityWarning(HTTPWarning): + "Warned when perfoming security reducing actions" + pass + + +class InsecureRequestWarning(SecurityWarning): + "Warned when making an unverified HTTPS request." + pass + + +class SystemTimeWarning(SecurityWarning): + "Warned when system time is suspected to be wrong" + pass diff --git a/lib/requests/packages/urllib3/fields.py b/lib/requests/packages/urllib3/fields.py index ed017657a29baae4193aa15ebe5d35c9185f084e..c853f8d56b5b2b5cb0d81dbb15e5e7245a1806d2 100644 --- a/lib/requests/packages/urllib3/fields.py +++ b/lib/requests/packages/urllib3/fields.py @@ -1,9 +1,3 @@ -# urllib3/fields.py -# Copyright 2008-2013 Andrey Petrov and contributors (see CONTRIBUTORS.txt) -# -# This module is part of urllib3 and is released under -# the MIT License: http://www.opensource.org/licenses/mit-license.php - import email.utils import mimetypes @@ -15,7 +9,7 @@ def guess_content_type(filename, default='application/octet-stream'): Guess the "Content-Type" of a file. :param filename: - The filename to guess the "Content-Type" of using :mod:`mimetimes`. + The filename to guess the "Content-Type" of using :mod:`mimetypes`. :param default: If no "Content-Type" can be guessed, default to `default`. """ @@ -78,9 +72,10 @@ class RequestField(object): """ A :class:`~urllib3.fields.RequestField` factory from old-style tuple parameters. - Supports constructing :class:`~urllib3.fields.RequestField` from parameter - of key/value strings AND key/filetuple. A filetuple is a (filename, data, MIME type) - tuple where the MIME type is optional. For example: :: + Supports constructing :class:`~urllib3.fields.RequestField` from + parameter of key/value strings AND key/filetuple. A filetuple is a + (filename, data, MIME type) tuple where the MIME type is optional. + For example:: 'foo': 'bar', 'fakefile': ('foofile.txt', 'contents of foofile'), @@ -125,8 +120,8 @@ class RequestField(object): 'Content-Disposition' fields. :param header_parts: - A sequence of (k, v) typles or a :class:`dict` of (k, v) to format as - `k1="v1"; k2="v2"; ...`. + A sequence of (k, v) typles or a :class:`dict` of (k, v) to format + as `k1="v1"; k2="v2"; ...`. """ parts = [] iterable = header_parts @@ -158,7 +153,8 @@ class RequestField(object): lines.append('\r\n') return '\r\n'.join(lines) - def make_multipart(self, content_disposition=None, content_type=None, content_location=None): + def make_multipart(self, content_disposition=None, content_type=None, + content_location=None): """ Makes this request field into a multipart request field. @@ -172,6 +168,10 @@ class RequestField(object): """ self.headers['Content-Disposition'] = content_disposition or 'form-data' - self.headers['Content-Disposition'] += '; '.join(['', self._render_parts((('name', self._name), ('filename', self._filename)))]) + self.headers['Content-Disposition'] += '; '.join([ + '', self._render_parts( + (('name', self._name), ('filename', self._filename)) + ) + ]) self.headers['Content-Type'] = content_type self.headers['Content-Location'] = content_location diff --git a/lib/requests/packages/urllib3/filepost.py b/lib/requests/packages/urllib3/filepost.py index e8b30bddf2e631e3d349854a44434e45ebf0a2a7..0fbf488dfeeb92abdf5b2923f82566fd8ee0216a 100644 --- a/lib/requests/packages/urllib3/filepost.py +++ b/lib/requests/packages/urllib3/filepost.py @@ -1,11 +1,4 @@ -# urllib3/filepost.py -# Copyright 2008-2013 Andrey Petrov and contributors (see CONTRIBUTORS.txt) -# -# This module is part of urllib3 and is released under -# the MIT License: http://www.opensource.org/licenses/mit-license.php - import codecs -import mimetypes from uuid import uuid4 from io import BytesIO @@ -38,10 +31,10 @@ def iter_field_objects(fields): i = iter(fields) for field in i: - if isinstance(field, RequestField): - yield field - else: - yield RequestField.from_tuples(*field) + if isinstance(field, RequestField): + yield field + else: + yield RequestField.from_tuples(*field) def iter_fields(fields): diff --git a/lib/requests/packages/urllib3/packages/ordered_dict.py b/lib/requests/packages/urllib3/packages/ordered_dict.py index 7f8ee15436061292aa8227e691f91903c6210a04..4479363cc45b5c7e0588072ccc19cab03fecce28 100644 --- a/lib/requests/packages/urllib3/packages/ordered_dict.py +++ b/lib/requests/packages/urllib3/packages/ordered_dict.py @@ -2,7 +2,6 @@ # Passes Python2.7's test suite and incorporates all the latest updates. # Copyright 2009 Raymond Hettinger, released under the MIT License. # http://code.activestate.com/recipes/576693/ - try: from thread import get_ident as _get_ident except ImportError: diff --git a/lib/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py b/lib/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py index 3aa5b2e19024c6e247e6a55f7aefb643c357b3f7..dd59a75fd305dda8a588bc9a6c98471edafbf88c 100644 --- a/lib/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py +++ b/lib/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py @@ -7,7 +7,7 @@ except ImportError: from backports.ssl_match_hostname import CertificateError, match_hostname except ImportError: # Our vendored copy - from _implementation import CertificateError, match_hostname + from ._implementation import CertificateError, match_hostname # Not needed, but documenting what we provide. __all__ = ('CertificateError', 'match_hostname') diff --git a/lib/requests/packages/urllib3/poolmanager.py b/lib/requests/packages/urllib3/poolmanager.py index f18ff2bb7ef2a6407322c5db011957600bccfcab..515dc96219b187c20272456f1b9f1d5f325d021f 100644 --- a/lib/requests/packages/urllib3/poolmanager.py +++ b/lib/requests/packages/urllib3/poolmanager.py @@ -1,9 +1,3 @@ -# urllib3/poolmanager.py -# Copyright 2008-2014 Andrey Petrov and contributors (see CONTRIBUTORS.txt) -# -# This module is part of urllib3 and is released under -# the MIT License: http://www.opensource.org/licenses/mit-license.php - import logging try: # Python 3 @@ -14,8 +8,10 @@ except ImportError: from ._collections import RecentlyUsedContainer from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool from .connectionpool import port_by_scheme +from .exceptions import LocationValueError from .request import RequestMethods -from .util import parse_url +from .util.url import parse_url +from .util.retry import Retry __all__ = ['PoolManager', 'ProxyManager', 'proxy_from_url'] @@ -49,7 +45,7 @@ class PoolManager(RequestMethods): Additional parameters are used to create fresh :class:`urllib3.connectionpool.ConnectionPool` instances. - Example: :: + Example:: >>> manager = PoolManager(num_pools=2) >>> r = manager.request('GET', 'http://google.com/') @@ -102,10 +98,11 @@ class PoolManager(RequestMethods): ``urllib3.connectionpool.port_by_scheme``. """ - scheme = scheme or 'http' + if not host: + raise LocationValueError("No host specified.") + scheme = scheme or 'http' port = port or port_by_scheme.get(scheme, 80) - pool_key = (scheme, host, port) with self.pools.lock: @@ -118,6 +115,7 @@ class PoolManager(RequestMethods): # Make a fresh ConnectionPool of the desired type pool = self._new_pool(scheme, host, port) self.pools[pool_key] = pool + return pool def connection_from_url(self, url): @@ -161,13 +159,18 @@ class PoolManager(RequestMethods): # Support relative URLs for redirecting. redirect_location = urljoin(url, redirect_location) - # RFC 2616, Section 10.3.4 + # RFC 7231, Section 6.4.4 if response.status == 303: method = 'GET' - log.info("Redirecting %s -> %s" % (url, redirect_location)) - kw['retries'] = kw.get('retries', 3) - 1 # Persist retries countdown + retries = kw.get('retries') + if not isinstance(retries, Retry): + retries = Retry.from_int(retries, redirect=redirect) + + kw['retries'] = retries.increment(method, redirect_location) kw['redirect'] = redirect + + log.info("Redirecting %s -> %s" % (url, redirect_location)) return self.urlopen(method, redirect_location, **kw) @@ -208,12 +211,16 @@ class ProxyManager(PoolManager): if not proxy.port: port = port_by_scheme.get(proxy.scheme, 80) proxy = proxy._replace(port=port) + + assert proxy.scheme in ("http", "https"), \ + 'Not supported proxy scheme %s' % proxy.scheme + self.proxy = proxy self.proxy_headers = proxy_headers or {} - assert self.proxy.scheme in ("http", "https"), \ - 'Not supported proxy scheme %s' % self.proxy.scheme + connection_pool_kw['_proxy'] = self.proxy connection_pool_kw['_proxy_headers'] = self.proxy_headers + super(ProxyManager, self).__init__( num_pools, headers, **connection_pool_kw) @@ -248,10 +255,10 @@ class ProxyManager(PoolManager): # For proxied HTTPS requests, httplib sets the necessary headers # on the CONNECT to the proxy. For HTTP, we'll definitely # need to set 'Host' at the very least. - kw['headers'] = self._set_proxy_headers(url, kw.get('headers', - self.headers)) + headers = kw.get('headers', self.headers) + kw['headers'] = self._set_proxy_headers(url, headers) - return super(ProxyManager, self).urlopen(method, url, redirect, **kw) + return super(ProxyManager, self).urlopen(method, url, redirect=redirect, **kw) def proxy_from_url(url, **kw): diff --git a/lib/requests/packages/urllib3/request.py b/lib/requests/packages/urllib3/request.py index 2a92cc208343fcf2110ab59d654afaabeaeaab59..b08d6c92746a0d9952b6d9e3875dd125b7416af8 100644 --- a/lib/requests/packages/urllib3/request.py +++ b/lib/requests/packages/urllib3/request.py @@ -1,9 +1,3 @@ -# urllib3/request.py -# Copyright 2008-2013 Andrey Petrov and contributors (see CONTRIBUTORS.txt) -# -# This module is part of urllib3 and is released under -# the MIT License: http://www.opensource.org/licenses/mit-license.php - try: from urllib.parse import urlencode except ImportError: @@ -26,8 +20,8 @@ class RequestMethods(object): Specifically, - :meth:`.request_encode_url` is for sending requests whose fields are encoded - in the URL (such as GET, HEAD, DELETE). + :meth:`.request_encode_url` is for sending requests whose fields are + encoded in the URL (such as GET, HEAD, DELETE). :meth:`.request_encode_body` is for sending requests whose fields are encoded in the *body* of the request using multipart or www-form-urlencoded @@ -51,7 +45,7 @@ class RequestMethods(object): def urlopen(self, method, url, body=None, headers=None, encode_multipart=True, multipart_boundary=None, - **kw): # Abstract + **kw): # Abstract raise NotImplemented("Classes extending RequestMethods must implement " "their own ``urlopen`` method.") @@ -61,8 +55,8 @@ class RequestMethods(object): ``fields`` based on the ``method`` used. This is a convenience method that requires the least amount of manual - effort. It can be used in most situations, while still having the option - to drop down to more specific methods when necessary, such as + effort. It can be used in most situations, while still having the + option to drop down to more specific methods when necessary, such as :meth:`request_encode_url`, :meth:`request_encode_body`, or even the lowest level :meth:`urlopen`. """ @@ -70,12 +64,12 @@ class RequestMethods(object): if method in self._encode_url_methods: return self.request_encode_url(method, url, fields=fields, - headers=headers, - **urlopen_kw) + headers=headers, + **urlopen_kw) else: return self.request_encode_body(method, url, fields=fields, - headers=headers, - **urlopen_kw) + headers=headers, + **urlopen_kw) def request_encode_url(self, method, url, fields=None, **urlopen_kw): """ @@ -94,18 +88,18 @@ class RequestMethods(object): the body. This is useful for request methods like POST, PUT, PATCH, etc. When ``encode_multipart=True`` (default), then - :meth:`urllib3.filepost.encode_multipart_formdata` is used to encode the - payload with the appropriate content type. Otherwise + :meth:`urllib3.filepost.encode_multipart_formdata` is used to encode + the payload with the appropriate content type. Otherwise :meth:`urllib.urlencode` is used with the 'application/x-www-form-urlencoded' content type. Multipart encoding must be used when posting files, and it's reasonably - safe to use it in other times too. However, it may break request signing, - such as with OAuth. + safe to use it in other times too. However, it may break request + signing, such as with OAuth. Supports an optional ``fields`` parameter of key/value strings AND key/filetuple. A filetuple is a (filename, data, MIME type) tuple where - the MIME type is optional. For example: :: + the MIME type is optional. For example:: fields = { 'foo': 'bar', @@ -119,23 +113,29 @@ class RequestMethods(object): When uploading a file, providing a filename (the first parameter of the tuple) is optional but recommended to best mimick behavior of browsers. - Note that if ``headers`` are supplied, the 'Content-Type' header will be - overwritten because it depends on the dynamic random boundary string + Note that if ``headers`` are supplied, the 'Content-Type' header will + be overwritten because it depends on the dynamic random boundary string which is used to compose the body of the request. The random boundary string can be explicitly set with the ``multipart_boundary`` parameter. """ - if encode_multipart: - body, content_type = encode_multipart_formdata(fields or {}, - boundary=multipart_boundary) - else: - body, content_type = (urlencode(fields or {}), - 'application/x-www-form-urlencoded') - if headers is None: headers = self.headers - headers_ = {'Content-Type': content_type} - headers_.update(headers) + extra_kw = {'headers': {}} + + if fields: + if 'body' in urlopen_kw: + raise TypeError('request got values for both \'fields\' and \'body\', can only specify one.') + + if encode_multipart: + body, content_type = encode_multipart_formdata(fields, boundary=multipart_boundary) + else: + body, content_type = urlencode(fields), 'application/x-www-form-urlencoded' + + extra_kw['body'] = body + extra_kw['headers'] = {'Content-Type': content_type} + + extra_kw['headers'].update(headers) + extra_kw.update(urlopen_kw) - return self.urlopen(method, url, body=body, headers=headers_, - **urlopen_kw) + return self.urlopen(method, url, **extra_kw) diff --git a/lib/requests/packages/urllib3/response.py b/lib/requests/packages/urllib3/response.py index 6a1fe1a77ccc5c3a2702d978cc70cb74b0cbbc85..e69de95733ad2cdcc2fc5fb019116e09f0ec4a86 100644 --- a/lib/requests/packages/urllib3/response.py +++ b/lib/requests/packages/urllib3/response.py @@ -1,20 +1,13 @@ -# urllib3/response.py -# Copyright 2008-2013 Andrey Petrov and contributors (see CONTRIBUTORS.txt) -# -# This module is part of urllib3 and is released under -# the MIT License: http://www.opensource.org/licenses/mit-license.php - - -import logging import zlib import io +from socket import timeout as SocketTimeout -from .exceptions import DecodeError +from ._collections import HTTPHeaderDict +from .exceptions import ProtocolError, DecodeError, ReadTimeoutError from .packages.six import string_types as basestring, binary_type -from .util import is_fp_closed - +from .connection import HTTPException, BaseSSLError +from .util.response import is_fp_closed -log = logging.getLogger(__name__) class DeflateDecoder(object): @@ -55,7 +48,10 @@ class HTTPResponse(io.IOBase): HTTP Response container. Backwards-compatible to httplib's HTTPResponse but the response ``body`` is - loaded and decoded on-demand when the ``data`` property is accessed. + loaded and decoded on-demand when the ``data`` property is accessed. This + class is also compatible with the Python standard library's :mod:`io` + module, and can hence be treated as a readable object in the context of that + framework. Extra parameters for behaviour not present in httplib.HTTPResponse: @@ -79,7 +75,10 @@ class HTTPResponse(io.IOBase): def __init__(self, body='', headers=None, status=0, version=0, reason=None, strict=0, preload_content=True, decode_content=True, original_response=None, pool=None, connection=None): - self.headers = headers or {} + + self.headers = HTTPHeaderDict() + if headers: + self.headers.update(headers) self.status = status self.version = version self.reason = reason @@ -87,11 +86,14 @@ class HTTPResponse(io.IOBase): self.decode_content = decode_content self._decoder = None - self._body = body if body and isinstance(body, basestring) else None + self._body = None self._fp = None self._original_response = original_response self._fp_bytes_read = 0 + if body and isinstance(body, (basestring, binary_type)): + self._body = body + self._pool = pool self._connection = connection @@ -159,8 +161,8 @@ class HTTPResponse(io.IOBase): after having ``.read()`` the file object. (Overridden if ``amt`` is set.) """ - # Note: content-encoding value should be case-insensitive, per RFC 2616 - # Section 3.5 + # Note: content-encoding value should be case-insensitive, per RFC 7230 + # Section 3.2 content_encoding = self.headers.get('content-encoding', '').lower() if self._decoder is None: if content_encoding in self.CONTENT_DECODERS: @@ -174,23 +176,42 @@ class HTTPResponse(io.IOBase): flush_decoder = False try: - if amt is None: - # cStringIO doesn't like amt=None - data = self._fp.read() - flush_decoder = True - else: - cache_content = False - data = self._fp.read(amt) - if amt != 0 and not data: # Platform-specific: Buggy versions of Python. - # Close the connection when no data is returned - # - # This is redundant to what httplib/http.client _should_ - # already do. However, versions of python released before - # December 15, 2012 (http://bugs.python.org/issue16298) do not - # properly close the connection in all cases. There is no harm - # in redundantly calling close. - self._fp.close() + try: + if amt is None: + # cStringIO doesn't like amt=None + data = self._fp.read() flush_decoder = True + else: + cache_content = False + data = self._fp.read(amt) + if amt != 0 and not data: # Platform-specific: Buggy versions of Python. + # Close the connection when no data is returned + # + # This is redundant to what httplib/http.client _should_ + # already do. However, versions of python released before + # December 15, 2012 (http://bugs.python.org/issue16298) do + # not properly close the connection in all cases. There is + # no harm in redundantly calling close. + self._fp.close() + flush_decoder = True + + except SocketTimeout: + # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but + # there is yet no clean way to get at it from this context. + raise ReadTimeoutError(self._pool, None, 'Read timed out.') + + except BaseSSLError as e: + # FIXME: Is there a better way to differentiate between SSLErrors? + if not 'read operation timed out' in str(e): # Defensive: + # This shouldn't happen but just in case we're missing an edge + # case, let's avoid swallowing SSL errors. + raise + + raise ReadTimeoutError(self._pool, None, 'Read timed out.') + + except HTTPException as e: + # This includes IncompleteRead. + raise ProtocolError('Connection broken: %r' % e, e) self._fp_bytes_read += len(data) @@ -200,8 +221,7 @@ class HTTPResponse(io.IOBase): except (IOError, zlib.error) as e: raise DecodeError( "Received response with content-encoding: %s, but " - "failed to decode it." % content_encoding, - e) + "failed to decode it." % content_encoding, e) if flush_decoder and decode_content and self._decoder: buf = self._decoder.decompress(binary_type()) @@ -238,7 +258,6 @@ class HTTPResponse(io.IOBase): if data: yield data - @classmethod def from_httplib(ResponseCls, r, **response_kw): """ @@ -249,17 +268,9 @@ class HTTPResponse(io.IOBase): with ``original_response=r``. """ - # Normalize headers between different versions of Python - headers = {} + headers = HTTPHeaderDict() for k, v in r.getheaders(): - # Python 3: Header keys are returned capitalised - k = k.lower() - - has_value = headers.get(k) - if has_value: # Python 3: Repeating header keys are unmerged. - v = ', '.join([has_value, v]) - - headers[k] = v + headers.add(k, v) # HTTPResponse objects in Python 3 don't have a .strict attribute strict = getattr(r, 'strict', 0) @@ -301,7 +312,7 @@ class HTTPResponse(io.IOBase): elif hasattr(self._fp, "fileno"): return self._fp.fileno() else: - raise IOError("The file-like object this HTTPResponse is wrapped " + raise IOError("The file-like object this HTTPResponse is wrapped " "around has no file descriptor") def flush(self): @@ -309,4 +320,14 @@ class HTTPResponse(io.IOBase): return self._fp.flush() def readable(self): + # This method is required for `io` module compatibility. return True + + def readinto(self, b): + # This method is required for `io` module compatibility. + temp = self.read(len(b)) + if len(temp) == 0: + return 0 + else: + b[:len(temp)] = temp + return len(temp) diff --git a/lib/requests/packages/urllib3/util.py b/lib/requests/packages/urllib3/util.py deleted file mode 100644 index bd266317ff5e89535df7d101eff489b7ac3e9a90..0000000000000000000000000000000000000000 --- a/lib/requests/packages/urllib3/util.py +++ /dev/null @@ -1,648 +0,0 @@ -# urllib3/util.py -# Copyright 2008-2013 Andrey Petrov and contributors (see CONTRIBUTORS.txt) -# -# This module is part of urllib3 and is released under -# the MIT License: http://www.opensource.org/licenses/mit-license.php - - -from base64 import b64encode -from binascii import hexlify, unhexlify -from collections import namedtuple -from hashlib import md5, sha1 -from socket import error as SocketError, _GLOBAL_DEFAULT_TIMEOUT -import time - -try: - from select import poll, POLLIN -except ImportError: # `poll` doesn't exist on OSX and other platforms - poll = False - try: - from select import select - except ImportError: # `select` doesn't exist on AppEngine. - select = False - -try: # Test for SSL features - SSLContext = None - HAS_SNI = False - - import ssl - from ssl import wrap_socket, CERT_NONE, PROTOCOL_SSLv23 - from ssl import SSLContext # Modern SSL? - from ssl import HAS_SNI # Has SNI? -except ImportError: - pass - -from .packages import six -from .exceptions import LocationParseError, SSLError, TimeoutStateError - - -_Default = object() -# The default timeout to use for socket connections. This is the attribute used -# by httplib to define the default timeout - - -def current_time(): - """ - Retrieve the current time, this function is mocked out in unit testing. - """ - return time.time() - - -class Timeout(object): - """ - Utility object for storing timeout values. - - Example usage: - - .. code-block:: python - - timeout = urllib3.util.Timeout(connect=2.0, read=7.0) - pool = HTTPConnectionPool('www.google.com', 80, timeout=timeout) - pool.request(...) # Etc, etc - - :param connect: - The maximum amount of time to wait for a connection attempt to a server - to succeed. Omitting the parameter will default the connect timeout to - the system default, probably `the global default timeout in socket.py - <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_. - None will set an infinite timeout for connection attempts. - - :type connect: integer, float, or None - - :param read: - The maximum amount of time to wait between consecutive - read operations for a response from the server. Omitting - the parameter will default the read timeout to the system - default, probably `the global default timeout in socket.py - <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_. - None will set an infinite timeout. - - :type read: integer, float, or None - - :param total: - This combines the connect and read timeouts into one; the read timeout - will be set to the time leftover from the connect attempt. In the - event that both a connect timeout and a total are specified, or a read - timeout and a total are specified, the shorter timeout will be applied. - - Defaults to None. - - :type total: integer, float, or None - - .. note:: - - Many factors can affect the total amount of time for urllib3 to return - an HTTP response. Specifically, Python's DNS resolver does not obey the - timeout specified on the socket. Other factors that can affect total - request time include high CPU load, high swap, the program running at a - low priority level, or other behaviors. The observed running time for - urllib3 to return a response may be greater than the value passed to - `total`. - - In addition, the read and total timeouts only measure the time between - read operations on the socket connecting the client and the server, - not the total amount of time for the request to return a complete - response. For most requests, the timeout is raised because the server - has not sent the first byte in the specified time. This is not always - the case; if a server streams one byte every fifteen seconds, a timeout - of 20 seconds will not ever trigger, even though the request will - take several minutes to complete. - - If your goal is to cut off any request after a set amount of wall clock - time, consider having a second "watcher" thread to cut off a slow - request. - """ - - #: A sentinel object representing the default timeout value - DEFAULT_TIMEOUT = _GLOBAL_DEFAULT_TIMEOUT - - def __init__(self, total=None, connect=_Default, read=_Default): - self._connect = self._validate_timeout(connect, 'connect') - self._read = self._validate_timeout(read, 'read') - self.total = self._validate_timeout(total, 'total') - self._start_connect = None - - def __str__(self): - return '%s(connect=%r, read=%r, total=%r)' % ( - type(self).__name__, self._connect, self._read, self.total) - - - @classmethod - def _validate_timeout(cls, value, name): - """ Check that a timeout attribute is valid - - :param value: The timeout value to validate - :param name: The name of the timeout attribute to validate. This is used - for clear error messages - :return: the value - :raises ValueError: if the type is not an integer or a float, or if it - is a numeric value less than zero - """ - if value is _Default: - return cls.DEFAULT_TIMEOUT - - if value is None or value is cls.DEFAULT_TIMEOUT: - return value - - try: - float(value) - except (TypeError, ValueError): - raise ValueError("Timeout value %s was %s, but it must be an " - "int or float." % (name, value)) - - try: - if value < 0: - raise ValueError("Attempted to set %s timeout to %s, but the " - "timeout cannot be set to a value less " - "than 0." % (name, value)) - except TypeError: # Python 3 - raise ValueError("Timeout value %s was %s, but it must be an " - "int or float." % (name, value)) - - return value - - @classmethod - def from_float(cls, timeout): - """ Create a new Timeout from a legacy timeout value. - - The timeout value used by httplib.py sets the same timeout on the - connect(), and recv() socket requests. This creates a :class:`Timeout` - object that sets the individual timeouts to the ``timeout`` value passed - to this function. - - :param timeout: The legacy timeout value - :type timeout: integer, float, sentinel default object, or None - :return: a Timeout object - :rtype: :class:`Timeout` - """ - return Timeout(read=timeout, connect=timeout) - - def clone(self): - """ Create a copy of the timeout object - - Timeout properties are stored per-pool but each request needs a fresh - Timeout object to ensure each one has its own start/stop configured. - - :return: a copy of the timeout object - :rtype: :class:`Timeout` - """ - # We can't use copy.deepcopy because that will also create a new object - # for _GLOBAL_DEFAULT_TIMEOUT, which socket.py uses as a sentinel to - # detect the user default. - return Timeout(connect=self._connect, read=self._read, - total=self.total) - - def start_connect(self): - """ Start the timeout clock, used during a connect() attempt - - :raises urllib3.exceptions.TimeoutStateError: if you attempt - to start a timer that has been started already. - """ - if self._start_connect is not None: - raise TimeoutStateError("Timeout timer has already been started.") - self._start_connect = current_time() - return self._start_connect - - def get_connect_duration(self): - """ Gets the time elapsed since the call to :meth:`start_connect`. - - :return: the elapsed time - :rtype: float - :raises urllib3.exceptions.TimeoutStateError: if you attempt - to get duration for a timer that hasn't been started. - """ - if self._start_connect is None: - raise TimeoutStateError("Can't get connect duration for timer " - "that has not started.") - return current_time() - self._start_connect - - @property - def connect_timeout(self): - """ Get the value to use when setting a connection timeout. - - This will be a positive float or integer, the value None - (never timeout), or the default system timeout. - - :return: the connect timeout - :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None - """ - if self.total is None: - return self._connect - - if self._connect is None or self._connect is self.DEFAULT_TIMEOUT: - return self.total - - return min(self._connect, self.total) - - @property - def read_timeout(self): - """ Get the value for the read timeout. - - This assumes some time has elapsed in the connection timeout and - computes the read timeout appropriately. - - If self.total is set, the read timeout is dependent on the amount of - time taken by the connect timeout. If the connection time has not been - established, a :exc:`~urllib3.exceptions.TimeoutStateError` will be - raised. - - :return: the value to use for the read timeout - :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None - :raises urllib3.exceptions.TimeoutStateError: If :meth:`start_connect` - has not yet been called on this object. - """ - if (self.total is not None and - self.total is not self.DEFAULT_TIMEOUT and - self._read is not None and - self._read is not self.DEFAULT_TIMEOUT): - # in case the connect timeout has not yet been established. - if self._start_connect is None: - return self._read - return max(0, min(self.total - self.get_connect_duration(), - self._read)) - elif self.total is not None and self.total is not self.DEFAULT_TIMEOUT: - return max(0, self.total - self.get_connect_duration()) - else: - return self._read - - -class Url(namedtuple('Url', ['scheme', 'auth', 'host', 'port', 'path', 'query', 'fragment'])): - """ - Datastructure for representing an HTTP URL. Used as a return value for - :func:`parse_url`. - """ - slots = () - - def __new__(cls, scheme=None, auth=None, host=None, port=None, path=None, query=None, fragment=None): - return super(Url, cls).__new__(cls, scheme, auth, host, port, path, query, fragment) - - @property - def hostname(self): - """For backwards-compatibility with urlparse. We're nice like that.""" - return self.host - - @property - def request_uri(self): - """Absolute path including the query string.""" - uri = self.path or '/' - - if self.query is not None: - uri += '?' + self.query - - return uri - - @property - def netloc(self): - """Network location including host and port""" - if self.port: - return '%s:%d' % (self.host, self.port) - return self.host - - -def split_first(s, delims): - """ - Given a string and an iterable of delimiters, split on the first found - delimiter. Return two split parts and the matched delimiter. - - If not found, then the first part is the full input string. - - Example: :: - - >>> split_first('foo/bar?baz', '?/=') - ('foo', 'bar?baz', '/') - >>> split_first('foo/bar?baz', '123') - ('foo/bar?baz', '', None) - - Scales linearly with number of delims. Not ideal for large number of delims. - """ - min_idx = None - min_delim = None - for d in delims: - idx = s.find(d) - if idx < 0: - continue - - if min_idx is None or idx < min_idx: - min_idx = idx - min_delim = d - - if min_idx is None or min_idx < 0: - return s, '', None - - return s[:min_idx], s[min_idx+1:], min_delim - - -def parse_url(url): - """ - Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is - performed to parse incomplete urls. Fields not provided will be None. - - Partly backwards-compatible with :mod:`urlparse`. - - Example: :: - - >>> parse_url('http://google.com/mail/') - Url(scheme='http', host='google.com', port=None, path='/', ...) - >>> parse_url('google.com:80') - Url(scheme=None, host='google.com', port=80, path=None, ...) - >>> parse_url('/foo?bar') - Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...) - """ - - # While this code has overlap with stdlib's urlparse, it is much - # simplified for our needs and less annoying. - # Additionally, this implementations does silly things to be optimal - # on CPython. - - scheme = None - auth = None - host = None - port = None - path = None - fragment = None - query = None - - # Scheme - if '://' in url: - scheme, url = url.split('://', 1) - - # Find the earliest Authority Terminator - # (http://tools.ietf.org/html/rfc3986#section-3.2) - url, path_, delim = split_first(url, ['/', '?', '#']) - - if delim: - # Reassemble the path - path = delim + path_ - - # Auth - if '@' in url: - # Last '@' denotes end of auth part - auth, url = url.rsplit('@', 1) - - # IPv6 - if url and url[0] == '[': - host, url = url.split(']', 1) - host += ']' - - # Port - if ':' in url: - _host, port = url.split(':', 1) - - if not host: - host = _host - - if port: - # If given, ports must be integers. - if not port.isdigit(): - raise LocationParseError("Failed to parse: %s" % url) - port = int(port) - else: - # Blank ports are cool, too. (rfc3986#section-3.2.3) - port = None - - elif not host and url: - host = url - - if not path: - return Url(scheme, auth, host, port, path, query, fragment) - - # Fragment - if '#' in path: - path, fragment = path.split('#', 1) - - # Query - if '?' in path: - path, query = path.split('?', 1) - - return Url(scheme, auth, host, port, path, query, fragment) - - -def get_host(url): - """ - Deprecated. Use :func:`.parse_url` instead. - """ - p = parse_url(url) - return p.scheme or 'http', p.hostname, p.port - - -def make_headers(keep_alive=None, accept_encoding=None, user_agent=None, - basic_auth=None, proxy_basic_auth=None): - """ - Shortcuts for generating request headers. - - :param keep_alive: - If ``True``, adds 'connection: keep-alive' header. - - :param accept_encoding: - Can be a boolean, list, or string. - ``True`` translates to 'gzip,deflate'. - List will get joined by comma. - String will be used as provided. - - :param user_agent: - String representing the user-agent you want, such as - "python-urllib3/0.6" - - :param basic_auth: - Colon-separated username:password string for 'authorization: basic ...' - auth header. - - :param proxy_basic_auth: - Colon-separated username:password string for 'proxy-authorization: basic ...' - auth header. - - Example: :: - - >>> make_headers(keep_alive=True, user_agent="Batman/1.0") - {'connection': 'keep-alive', 'user-agent': 'Batman/1.0'} - >>> make_headers(accept_encoding=True) - {'accept-encoding': 'gzip,deflate'} - """ - headers = {} - if accept_encoding: - if isinstance(accept_encoding, str): - pass - elif isinstance(accept_encoding, list): - accept_encoding = ','.join(accept_encoding) - else: - accept_encoding = 'gzip,deflate' - headers['accept-encoding'] = accept_encoding - - if user_agent: - headers['user-agent'] = user_agent - - if keep_alive: - headers['connection'] = 'keep-alive' - - if basic_auth: - headers['authorization'] = 'Basic ' + \ - b64encode(six.b(basic_auth)).decode('utf-8') - - if proxy_basic_auth: - headers['proxy-authorization'] = 'Basic ' + \ - b64encode(six.b(proxy_basic_auth)).decode('utf-8') - - return headers - - -def is_connection_dropped(conn): # Platform-specific - """ - Returns True if the connection is dropped and should be closed. - - :param conn: - :class:`httplib.HTTPConnection` object. - - Note: For platforms like AppEngine, this will always return ``False`` to - let the platform handle connection recycling transparently for us. - """ - sock = getattr(conn, 'sock', False) - if not sock: # Platform-specific: AppEngine - return False - - if not poll: - if not select: # Platform-specific: AppEngine - return False - - try: - return select([sock], [], [], 0.0)[0] - except SocketError: - return True - - # This version is better on platforms that support it. - p = poll() - p.register(sock, POLLIN) - for (fno, ev) in p.poll(0.0): - if fno == sock.fileno(): - # Either data is buffered (bad), or the connection is dropped. - return True - - -def resolve_cert_reqs(candidate): - """ - Resolves the argument to a numeric constant, which can be passed to - the wrap_socket function/method from the ssl module. - Defaults to :data:`ssl.CERT_NONE`. - If given a string it is assumed to be the name of the constant in the - :mod:`ssl` module or its abbrevation. - (So you can specify `REQUIRED` instead of `CERT_REQUIRED`. - If it's neither `None` nor a string we assume it is already the numeric - constant which can directly be passed to wrap_socket. - """ - if candidate is None: - return CERT_NONE - - if isinstance(candidate, str): - res = getattr(ssl, candidate, None) - if res is None: - res = getattr(ssl, 'CERT_' + candidate) - return res - - return candidate - - -def resolve_ssl_version(candidate): - """ - like resolve_cert_reqs - """ - if candidate is None: - return PROTOCOL_SSLv23 - - if isinstance(candidate, str): - res = getattr(ssl, candidate, None) - if res is None: - res = getattr(ssl, 'PROTOCOL_' + candidate) - return res - - return candidate - - -def assert_fingerprint(cert, fingerprint): - """ - Checks if given fingerprint matches the supplied certificate. - - :param cert: - Certificate as bytes object. - :param fingerprint: - Fingerprint as string of hexdigits, can be interspersed by colons. - """ - - # Maps the length of a digest to a possible hash function producing - # this digest. - hashfunc_map = { - 16: md5, - 20: sha1 - } - - fingerprint = fingerprint.replace(':', '').lower() - - digest_length, rest = divmod(len(fingerprint), 2) - - if rest or digest_length not in hashfunc_map: - raise SSLError('Fingerprint is of invalid length.') - - # We need encode() here for py32; works on py2 and p33. - fingerprint_bytes = unhexlify(fingerprint.encode()) - - hashfunc = hashfunc_map[digest_length] - - cert_digest = hashfunc(cert).digest() - - if not cert_digest == fingerprint_bytes: - raise SSLError('Fingerprints did not match. Expected "{0}", got "{1}".' - .format(hexlify(fingerprint_bytes), - hexlify(cert_digest))) - -def is_fp_closed(obj): - """ - Checks whether a given file-like object is closed. - - :param obj: - The file-like object to check. - """ - if hasattr(obj, 'fp'): - # Object is a container for another file-like object that gets released - # on exhaustion (e.g. HTTPResponse) - return obj.fp is None - - return obj.closed - - -if SSLContext is not None: # Python 3.2+ - def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None, - ca_certs=None, server_hostname=None, - ssl_version=None): - """ - All arguments except `server_hostname` have the same meaning as for - :func:`ssl.wrap_socket` - - :param server_hostname: - Hostname of the expected certificate - """ - context = SSLContext(ssl_version) - context.verify_mode = cert_reqs - - # Disable TLS compression to migitate CRIME attack (issue #309) - OP_NO_COMPRESSION = 0x20000 - context.options |= OP_NO_COMPRESSION - - if ca_certs: - try: - context.load_verify_locations(ca_certs) - # Py32 raises IOError - # Py33 raises FileNotFoundError - except Exception as e: # Reraise as SSLError - raise SSLError(e) - if certfile: - # FIXME: This block needs a test. - context.load_cert_chain(certfile, keyfile) - if HAS_SNI: # Platform-specific: OpenSSL with enabled SNI - return context.wrap_socket(sock, server_hostname=server_hostname) - return context.wrap_socket(sock) - -else: # Python 3.1 and earlier - def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None, - ca_certs=None, server_hostname=None, - ssl_version=None): - return wrap_socket(sock, keyfile=keyfile, certfile=certfile, - ca_certs=ca_certs, cert_reqs=cert_reqs, - ssl_version=ssl_version) diff --git a/lib/requests/packages/urllib3/util/__init__.py b/lib/requests/packages/urllib3/util/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8becc81433b79c81d2206de64d99443625aff300 --- /dev/null +++ b/lib/requests/packages/urllib3/util/__init__.py @@ -0,0 +1,24 @@ +# For backwards compatibility, provide imports that used to be here. +from .connection import is_connection_dropped +from .request import make_headers +from .response import is_fp_closed +from .ssl_ import ( + SSLContext, + HAS_SNI, + assert_fingerprint, + resolve_cert_reqs, + resolve_ssl_version, + ssl_wrap_socket, +) +from .timeout import ( + current_time, + Timeout, +) + +from .retry import Retry +from .url import ( + get_host, + parse_url, + split_first, + Url, +) diff --git a/lib/requests/packages/urllib3/util/connection.py b/lib/requests/packages/urllib3/util/connection.py new file mode 100644 index 0000000000000000000000000000000000000000..2156993a0c413c1e1c0cb5395105eeb4ba9d6a47 --- /dev/null +++ b/lib/requests/packages/urllib3/util/connection.py @@ -0,0 +1,97 @@ +import socket +try: + from select import poll, POLLIN +except ImportError: # `poll` doesn't exist on OSX and other platforms + poll = False + try: + from select import select + except ImportError: # `select` doesn't exist on AppEngine. + select = False + + +def is_connection_dropped(conn): # Platform-specific + """ + Returns True if the connection is dropped and should be closed. + + :param conn: + :class:`httplib.HTTPConnection` object. + + Note: For platforms like AppEngine, this will always return ``False`` to + let the platform handle connection recycling transparently for us. + """ + sock = getattr(conn, 'sock', False) + if sock is False: # Platform-specific: AppEngine + return False + if sock is None: # Connection already closed (such as by httplib). + return True + + if not poll: + if not select: # Platform-specific: AppEngine + return False + + try: + return select([sock], [], [], 0.0)[0] + except socket.error: + return True + + # This version is better on platforms that support it. + p = poll() + p.register(sock, POLLIN) + for (fno, ev) in p.poll(0.0): + if fno == sock.fileno(): + # Either data is buffered (bad), or the connection is dropped. + return True + + +# This function is copied from socket.py in the Python 2.7 standard +# library test suite. Added to its signature is only `socket_options`. +def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + source_address=None, socket_options=None): + """Connect to *address* and return the socket object. + + Convenience function. Connect to *address* (a 2-tuple ``(host, + port)``) and return the socket object. Passing the optional + *timeout* parameter will set the timeout on the socket instance + before attempting to connect. If no *timeout* is supplied, the + global default timeout setting returned by :func:`getdefaulttimeout` + is used. If *source_address* is set it must be a tuple of (host, port) + for the socket to bind as a source address before making the connection. + An host of '' or port 0 tells the OS to use the default. + """ + + host, port = address + err = None + for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM): + af, socktype, proto, canonname, sa = res + sock = None + try: + sock = socket.socket(af, socktype, proto) + + # If provided, set socket level options before connecting. + # This is the only addition urllib3 makes to this function. + _set_socket_options(sock, socket_options) + + if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT: + sock.settimeout(timeout) + if source_address: + sock.bind(source_address) + sock.connect(sa) + return sock + + except socket.error as _: + err = _ + if sock is not None: + sock.close() + + if err is not None: + raise err + else: + raise socket.error("getaddrinfo returns an empty list") + + +def _set_socket_options(sock, options): + if options is None: + return + + for opt in options: + sock.setsockopt(*opt) diff --git a/lib/requests/packages/urllib3/util/request.py b/lib/requests/packages/urllib3/util/request.py new file mode 100644 index 0000000000000000000000000000000000000000..bc64f6b1fb6440f90e4f2fbb3220a82f9899816f --- /dev/null +++ b/lib/requests/packages/urllib3/util/request.py @@ -0,0 +1,71 @@ +from base64 import b64encode + +from ..packages.six import b + +ACCEPT_ENCODING = 'gzip,deflate' + + +def make_headers(keep_alive=None, accept_encoding=None, user_agent=None, + basic_auth=None, proxy_basic_auth=None, disable_cache=None): + """ + Shortcuts for generating request headers. + + :param keep_alive: + If ``True``, adds 'connection: keep-alive' header. + + :param accept_encoding: + Can be a boolean, list, or string. + ``True`` translates to 'gzip,deflate'. + List will get joined by comma. + String will be used as provided. + + :param user_agent: + String representing the user-agent you want, such as + "python-urllib3/0.6" + + :param basic_auth: + Colon-separated username:password string for 'authorization: basic ...' + auth header. + + :param proxy_basic_auth: + Colon-separated username:password string for 'proxy-authorization: basic ...' + auth header. + + :param disable_cache: + If ``True``, adds 'cache-control: no-cache' header. + + Example:: + + >>> make_headers(keep_alive=True, user_agent="Batman/1.0") + {'connection': 'keep-alive', 'user-agent': 'Batman/1.0'} + >>> make_headers(accept_encoding=True) + {'accept-encoding': 'gzip,deflate'} + """ + headers = {} + if accept_encoding: + if isinstance(accept_encoding, str): + pass + elif isinstance(accept_encoding, list): + accept_encoding = ','.join(accept_encoding) + else: + accept_encoding = ACCEPT_ENCODING + headers['accept-encoding'] = accept_encoding + + if user_agent: + headers['user-agent'] = user_agent + + if keep_alive: + headers['connection'] = 'keep-alive' + + if basic_auth: + headers['authorization'] = 'Basic ' + \ + b64encode(b(basic_auth)).decode('utf-8') + + if proxy_basic_auth: + headers['proxy-authorization'] = 'Basic ' + \ + b64encode(b(proxy_basic_auth)).decode('utf-8') + + if disable_cache: + headers['cache-control'] = 'no-cache' + + return headers diff --git a/lib/requests/packages/urllib3/util/response.py b/lib/requests/packages/urllib3/util/response.py new file mode 100644 index 0000000000000000000000000000000000000000..45fff55246e591cc3337f731d989c37133847850 --- /dev/null +++ b/lib/requests/packages/urllib3/util/response.py @@ -0,0 +1,22 @@ +def is_fp_closed(obj): + """ + Checks whether a given file-like object is closed. + + :param obj: + The file-like object to check. + """ + + try: + # Check via the official file-like-object way. + return obj.closed + except AttributeError: + pass + + try: + # Check if the object is a container for another file-like object that + # gets released on exhaustion (e.g. HTTPResponse). + return obj.fp is None + except AttributeError: + pass + + raise ValueError("Unable to determine whether fp is closed.") diff --git a/lib/requests/packages/urllib3/util/retry.py b/lib/requests/packages/urllib3/util/retry.py new file mode 100644 index 0000000000000000000000000000000000000000..7e0959df37c1be566c2ff83bf1bbf84a11467a45 --- /dev/null +++ b/lib/requests/packages/urllib3/util/retry.py @@ -0,0 +1,285 @@ +import time +import logging + +from ..exceptions import ( + ConnectTimeoutError, + MaxRetryError, + ProtocolError, + ReadTimeoutError, + ResponseError, +) +from ..packages import six + + +log = logging.getLogger(__name__) + + +class Retry(object): + """ Retry configuration. + + Each retry attempt will create a new Retry object with updated values, so + they can be safely reused. + + Retries can be defined as a default for a pool:: + + retries = Retry(connect=5, read=2, redirect=5) + http = PoolManager(retries=retries) + response = http.request('GET', 'http://example.com/') + + Or per-request (which overrides the default for the pool):: + + response = http.request('GET', 'http://example.com/', retries=Retry(10)) + + Retries can be disabled by passing ``False``:: + + response = http.request('GET', 'http://example.com/', retries=False) + + Errors will be wrapped in :class:`~urllib3.exceptions.MaxRetryError` unless + retries are disabled, in which case the causing exception will be raised. + + :param int total: + Total number of retries to allow. Takes precedence over other counts. + + Set to ``None`` to remove this constraint and fall back on other + counts. It's a good idea to set this to some sensibly-high value to + account for unexpected edge cases and avoid infinite retry loops. + + Set to ``0`` to fail on the first retry. + + Set to ``False`` to disable and imply ``raise_on_redirect=False``. + + :param int connect: + How many connection-related errors to retry on. + + These are errors raised before the request is sent to the remote server, + which we assume has not triggered the server to process the request. + + Set to ``0`` to fail on the first retry of this type. + + :param int read: + How many times to retry on read errors. + + These errors are raised after the request was sent to the server, so the + request may have side-effects. + + Set to ``0`` to fail on the first retry of this type. + + :param int redirect: + How many redirects to perform. Limit this to avoid infinite redirect + loops. + + A redirect is a HTTP response with a status code 301, 302, 303, 307 or + 308. + + Set to ``0`` to fail on the first retry of this type. + + Set to ``False`` to disable and imply ``raise_on_redirect=False``. + + :param iterable method_whitelist: + Set of uppercased HTTP method verbs that we should retry on. + + By default, we only retry on methods which are considered to be + indempotent (multiple requests with the same parameters end with the + same state). See :attr:`Retry.DEFAULT_METHOD_WHITELIST`. + + :param iterable status_forcelist: + A set of HTTP status codes that we should force a retry on. + + By default, this is disabled with ``None``. + + :param float backoff_factor: + A backoff factor to apply between attempts. urllib3 will sleep for:: + + {backoff factor} * (2 ^ ({number of total retries} - 1)) + + seconds. If the backoff_factor is 0.1, then :func:`.sleep` will sleep + for [0.1s, 0.2s, 0.4s, ...] between retries. It will never be longer + than :attr:`Retry.MAX_BACKOFF`. + + By default, backoff is disabled (set to 0). + + :param bool raise_on_redirect: Whether, if the number of redirects is + exhausted, to raise a MaxRetryError, or to return a response with a + response code in the 3xx range. + """ + + DEFAULT_METHOD_WHITELIST = frozenset([ + 'HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS', 'TRACE']) + + #: Maximum backoff time. + BACKOFF_MAX = 120 + + def __init__(self, total=10, connect=None, read=None, redirect=None, + method_whitelist=DEFAULT_METHOD_WHITELIST, status_forcelist=None, + backoff_factor=0, raise_on_redirect=True, _observed_errors=0): + + self.total = total + self.connect = connect + self.read = read + + if redirect is False or total is False: + redirect = 0 + raise_on_redirect = False + + self.redirect = redirect + self.status_forcelist = status_forcelist or set() + self.method_whitelist = method_whitelist + self.backoff_factor = backoff_factor + self.raise_on_redirect = raise_on_redirect + self._observed_errors = _observed_errors # TODO: use .history instead? + + def new(self, **kw): + params = dict( + total=self.total, + connect=self.connect, read=self.read, redirect=self.redirect, + method_whitelist=self.method_whitelist, + status_forcelist=self.status_forcelist, + backoff_factor=self.backoff_factor, + raise_on_redirect=self.raise_on_redirect, + _observed_errors=self._observed_errors, + ) + params.update(kw) + return type(self)(**params) + + @classmethod + def from_int(cls, retries, redirect=True, default=None): + """ Backwards-compatibility for the old retries format.""" + if retries is None: + retries = default if default is not None else cls.DEFAULT + + if isinstance(retries, Retry): + return retries + + redirect = bool(redirect) and None + new_retries = cls(retries, redirect=redirect) + log.debug("Converted retries value: %r -> %r" % (retries, new_retries)) + return new_retries + + def get_backoff_time(self): + """ Formula for computing the current backoff + + :rtype: float + """ + if self._observed_errors <= 1: + return 0 + + backoff_value = self.backoff_factor * (2 ** (self._observed_errors - 1)) + return min(self.BACKOFF_MAX, backoff_value) + + def sleep(self): + """ Sleep between retry attempts using an exponential backoff. + + By default, the backoff factor is 0 and this method will return + immediately. + """ + backoff = self.get_backoff_time() + if backoff <= 0: + return + time.sleep(backoff) + + def _is_connection_error(self, err): + """ Errors when we're fairly sure that the server did not receive the + request, so it should be safe to retry. + """ + return isinstance(err, ConnectTimeoutError) + + def _is_read_error(self, err): + """ Errors that occur after the request has been started, so we should + assume that the server began processing it. + """ + return isinstance(err, (ReadTimeoutError, ProtocolError)) + + def is_forced_retry(self, method, status_code): + """ Is this method/status code retryable? (Based on method/codes whitelists) + """ + if self.method_whitelist and method.upper() not in self.method_whitelist: + return False + + return self.status_forcelist and status_code in self.status_forcelist + + def is_exhausted(self): + """ Are we out of retries? """ + retry_counts = (self.total, self.connect, self.read, self.redirect) + retry_counts = list(filter(None, retry_counts)) + if not retry_counts: + return False + + return min(retry_counts) < 0 + + def increment(self, method=None, url=None, response=None, error=None, _pool=None, _stacktrace=None): + """ Return a new Retry object with incremented retry counters. + + :param response: A response object, or None, if the server did not + return a response. + :type response: :class:`~urllib3.response.HTTPResponse` + :param Exception error: An error encountered during the request, or + None if the response was received successfully. + + :return: A new ``Retry`` object. + """ + if self.total is False and error: + # Disabled, indicate to re-raise the error. + raise six.reraise(type(error), error, _stacktrace) + + total = self.total + if total is not None: + total -= 1 + + _observed_errors = self._observed_errors + connect = self.connect + read = self.read + redirect = self.redirect + cause = 'unknown' + + if error and self._is_connection_error(error): + # Connect retry? + if connect is False: + raise six.reraise(type(error), error, _stacktrace) + elif connect is not None: + connect -= 1 + _observed_errors += 1 + + elif error and self._is_read_error(error): + # Read retry? + if read is False: + raise six.reraise(type(error), error, _stacktrace) + elif read is not None: + read -= 1 + _observed_errors += 1 + + elif response and response.get_redirect_location(): + # Redirect retry? + if redirect is not None: + redirect -= 1 + cause = 'too many redirects' + + else: + # Incrementing because of a server error like a 500 in + # status_forcelist and a the given method is in the whitelist + _observed_errors += 1 + cause = ResponseError.GENERIC_ERROR + if response and response.status: + cause = ResponseError.SPECIFIC_ERROR.format( + status_code=response.status) + + new_retry = self.new( + total=total, + connect=connect, read=read, redirect=redirect, + _observed_errors=_observed_errors) + + if new_retry.is_exhausted(): + raise MaxRetryError(_pool, url, error or ResponseError(cause)) + + log.debug("Incremented Retry for (url='%s'): %r" % (url, new_retry)) + + return new_retry + + + def __repr__(self): + return ('{cls.__name__}(total={self.total}, connect={self.connect}, ' + 'read={self.read}, redirect={self.redirect})').format( + cls=type(self), self=self) + + +# For backwards compatibility (equivalent to pre-v1.9): +Retry.DEFAULT = Retry(3) diff --git a/lib/requests/packages/urllib3/util/ssl_.py b/lib/requests/packages/urllib3/util/ssl_.py new file mode 100644 index 0000000000000000000000000000000000000000..a788b1b98c63150fe70021d96d2b8e1d45579019 --- /dev/null +++ b/lib/requests/packages/urllib3/util/ssl_.py @@ -0,0 +1,254 @@ +from binascii import hexlify, unhexlify +from hashlib import md5, sha1 + +from ..exceptions import SSLError + + +SSLContext = None +HAS_SNI = False +create_default_context = None + +import errno +import ssl + +try: # Test for SSL features + from ssl import wrap_socket, CERT_NONE, PROTOCOL_SSLv23 + from ssl import HAS_SNI # Has SNI? +except ImportError: + pass + + +try: + from ssl import OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION +except ImportError: + OP_NO_SSLv2, OP_NO_SSLv3 = 0x1000000, 0x2000000 + OP_NO_COMPRESSION = 0x20000 + +try: + from ssl import _DEFAULT_CIPHERS +except ImportError: + _DEFAULT_CIPHERS = ( + 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:' + 'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:ECDH+RC4:' + 'DH+RC4:RSA+RC4:!aNULL:!eNULL:!MD5' + ) + +try: + from ssl import SSLContext # Modern SSL? +except ImportError: + import sys + + class SSLContext(object): # Platform-specific: Python 2 & 3.1 + supports_set_ciphers = sys.version_info >= (2, 7) + + def __init__(self, protocol_version): + self.protocol = protocol_version + # Use default values from a real SSLContext + self.check_hostname = False + self.verify_mode = ssl.CERT_NONE + self.ca_certs = None + self.options = 0 + self.certfile = None + self.keyfile = None + self.ciphers = None + + def load_cert_chain(self, certfile, keyfile): + self.certfile = certfile + self.keyfile = keyfile + + def load_verify_locations(self, location): + self.ca_certs = location + + def set_ciphers(self, cipher_suite): + if not self.supports_set_ciphers: + raise TypeError( + 'Your version of Python does not support setting ' + 'a custom cipher suite. Please upgrade to Python ' + '2.7, 3.2, or later if you need this functionality.' + ) + self.ciphers = cipher_suite + + def wrap_socket(self, socket, server_hostname=None): + kwargs = { + 'keyfile': self.keyfile, + 'certfile': self.certfile, + 'ca_certs': self.ca_certs, + 'cert_reqs': self.verify_mode, + 'ssl_version': self.protocol, + } + if self.supports_set_ciphers: # Platform-specific: Python 2.7+ + return wrap_socket(socket, ciphers=self.ciphers, **kwargs) + else: # Platform-specific: Python 2.6 + return wrap_socket(socket, **kwargs) + + +def assert_fingerprint(cert, fingerprint): + """ + Checks if given fingerprint matches the supplied certificate. + + :param cert: + Certificate as bytes object. + :param fingerprint: + Fingerprint as string of hexdigits, can be interspersed by colons. + """ + + # Maps the length of a digest to a possible hash function producing + # this digest. + hashfunc_map = { + 16: md5, + 20: sha1 + } + + fingerprint = fingerprint.replace(':', '').lower() + digest_length, odd = divmod(len(fingerprint), 2) + + if odd or digest_length not in hashfunc_map: + raise SSLError('Fingerprint is of invalid length.') + + # We need encode() here for py32; works on py2 and p33. + fingerprint_bytes = unhexlify(fingerprint.encode()) + + hashfunc = hashfunc_map[digest_length] + + cert_digest = hashfunc(cert).digest() + + if not cert_digest == fingerprint_bytes: + raise SSLError('Fingerprints did not match. Expected "{0}", got "{1}".' + .format(hexlify(fingerprint_bytes), + hexlify(cert_digest))) + + +def resolve_cert_reqs(candidate): + """ + Resolves the argument to a numeric constant, which can be passed to + the wrap_socket function/method from the ssl module. + Defaults to :data:`ssl.CERT_NONE`. + If given a string it is assumed to be the name of the constant in the + :mod:`ssl` module or its abbrevation. + (So you can specify `REQUIRED` instead of `CERT_REQUIRED`. + If it's neither `None` nor a string we assume it is already the numeric + constant which can directly be passed to wrap_socket. + """ + if candidate is None: + return CERT_NONE + + if isinstance(candidate, str): + res = getattr(ssl, candidate, None) + if res is None: + res = getattr(ssl, 'CERT_' + candidate) + return res + + return candidate + + +def resolve_ssl_version(candidate): + """ + like resolve_cert_reqs + """ + if candidate is None: + return PROTOCOL_SSLv23 + + if isinstance(candidate, str): + res = getattr(ssl, candidate, None) + if res is None: + res = getattr(ssl, 'PROTOCOL_' + candidate) + return res + + return candidate + + +def create_urllib3_context(ssl_version=None, cert_reqs=ssl.CERT_REQUIRED, + options=None, ciphers=None): + """All arguments have the same meaning as ``ssl_wrap_socket``. + + By default, this function does a lot of the same work that + ``ssl.create_default_context`` does on Python 3.4+. It: + + - Disables SSLv2, SSLv3, and compression + - Sets a restricted set of server ciphers + + If you wish to enable SSLv3, you can do:: + + from urllib3.util import ssl_ + context = ssl_.create_urllib3_context() + context.options &= ~ssl_.OP_NO_SSLv3 + + You can do the same to enable compression (substituting ``COMPRESSION`` + for ``SSLv3`` in the last line above). + + :param ssl_version: + The desired protocol version to use. This will default to + PROTOCOL_SSLv23 which will negotiate the highest protocol that both + the server and your installation of OpenSSL support. + :param cert_reqs: + Whether to require the certificate verification. This defaults to + ``ssl.CERT_REQUIRED``. + :param options: + Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``, + ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``. + :param ciphers: + Which cipher suites to allow the server to select. + :returns: + Constructed SSLContext object with specified options + :rtype: SSLContext + """ + context = SSLContext(ssl_version or ssl.PROTOCOL_SSLv23) + + if options is None: + options = 0 + # SSLv2 is easily broken and is considered harmful and dangerous + options |= OP_NO_SSLv2 + # SSLv3 has several problems and is now dangerous + options |= OP_NO_SSLv3 + # Disable compression to prevent CRIME attacks for OpenSSL 1.0+ + # (issue #309) + options |= OP_NO_COMPRESSION + + context.options |= options + + if getattr(context, 'supports_set_ciphers', True): # Platform-specific: Python 2.6 + context.set_ciphers(ciphers or _DEFAULT_CIPHERS) + + context.verify_mode = cert_reqs + if getattr(context, 'check_hostname', None) is not None: # Platform-specific: Python 3.2 + context.check_hostname = (context.verify_mode == ssl.CERT_REQUIRED) + return context + + +def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None, + ca_certs=None, server_hostname=None, + ssl_version=None, ciphers=None, ssl_context=None): + """ + All arguments except for server_hostname and ssl_context have the same + meaning as they do when using :func:`ssl.wrap_socket`. + + :param server_hostname: + When SNI is supported, the expected hostname of the certificate + :param ssl_context: + A pre-made :class:`SSLContext` object. If none is provided, one will + be created using :func:`create_urllib3_context`. + :param ciphers: + A string of ciphers we wish the client to support. This is not + supported on Python 2.6 as the ssl module does not support it. + """ + context = ssl_context + if context is None: + context = create_urllib3_context(ssl_version, cert_reqs, + ciphers=ciphers) + + if ca_certs: + try: + context.load_verify_locations(ca_certs) + except IOError as e: # Platform-specific: Python 2.6, 2.7, 3.2 + raise SSLError(e) + # Py33 raises FileNotFoundError which subclasses OSError + # These are not equivalent unless we check the errno attribute + except OSError as e: # Platform-specific: Python 3.3 and beyond + if e.errno == errno.ENOENT: + raise SSLError(e) + raise + if certfile: + context.load_cert_chain(certfile, keyfile) + if HAS_SNI: # Platform-specific: OpenSSL with enabled SNI + return context.wrap_socket(sock, server_hostname=server_hostname) + return context.wrap_socket(sock) diff --git a/lib/requests/packages/urllib3/util/timeout.py b/lib/requests/packages/urllib3/util/timeout.py new file mode 100644 index 0000000000000000000000000000000000000000..ea7027f3f5f531aef55069ff848612df266821ee --- /dev/null +++ b/lib/requests/packages/urllib3/util/timeout.py @@ -0,0 +1,240 @@ +# The default socket timeout, used by httplib to indicate that no timeout was +# specified by the user +from socket import _GLOBAL_DEFAULT_TIMEOUT +import time + +from ..exceptions import TimeoutStateError + +# A sentinel value to indicate that no timeout was specified by the user in +# urllib3 +_Default = object() + +def current_time(): + """ + Retrieve the current time. This function is mocked out in unit testing. + """ + return time.time() + + +class Timeout(object): + """ Timeout configuration. + + Timeouts can be defined as a default for a pool:: + + timeout = Timeout(connect=2.0, read=7.0) + http = PoolManager(timeout=timeout) + response = http.request('GET', 'http://example.com/') + + Or per-request (which overrides the default for the pool):: + + response = http.request('GET', 'http://example.com/', timeout=Timeout(10)) + + Timeouts can be disabled by setting all the parameters to ``None``:: + + no_timeout = Timeout(connect=None, read=None) + response = http.request('GET', 'http://example.com/, timeout=no_timeout) + + + :param total: + This combines the connect and read timeouts into one; the read timeout + will be set to the time leftover from the connect attempt. In the + event that both a connect timeout and a total are specified, or a read + timeout and a total are specified, the shorter timeout will be applied. + + Defaults to None. + + :type total: integer, float, or None + + :param connect: + The maximum amount of time to wait for a connection attempt to a server + to succeed. Omitting the parameter will default the connect timeout to + the system default, probably `the global default timeout in socket.py + <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_. + None will set an infinite timeout for connection attempts. + + :type connect: integer, float, or None + + :param read: + The maximum amount of time to wait between consecutive + read operations for a response from the server. Omitting + the parameter will default the read timeout to the system + default, probably `the global default timeout in socket.py + <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_. + None will set an infinite timeout. + + :type read: integer, float, or None + + .. note:: + + Many factors can affect the total amount of time for urllib3 to return + an HTTP response. + + For example, Python's DNS resolver does not obey the timeout specified + on the socket. Other factors that can affect total request time include + high CPU load, high swap, the program running at a low priority level, + or other behaviors. + + In addition, the read and total timeouts only measure the time between + read operations on the socket connecting the client and the server, + not the total amount of time for the request to return a complete + response. For most requests, the timeout is raised because the server + has not sent the first byte in the specified time. This is not always + the case; if a server streams one byte every fifteen seconds, a timeout + of 20 seconds will not trigger, even though the request will take + several minutes to complete. + + If your goal is to cut off any request after a set amount of wall clock + time, consider having a second "watcher" thread to cut off a slow + request. + """ + + #: A sentinel object representing the default timeout value + DEFAULT_TIMEOUT = _GLOBAL_DEFAULT_TIMEOUT + + def __init__(self, total=None, connect=_Default, read=_Default): + self._connect = self._validate_timeout(connect, 'connect') + self._read = self._validate_timeout(read, 'read') + self.total = self._validate_timeout(total, 'total') + self._start_connect = None + + def __str__(self): + return '%s(connect=%r, read=%r, total=%r)' % ( + type(self).__name__, self._connect, self._read, self.total) + + @classmethod + def _validate_timeout(cls, value, name): + """ Check that a timeout attribute is valid. + + :param value: The timeout value to validate + :param name: The name of the timeout attribute to validate. This is + used to specify in error messages. + :return: The validated and casted version of the given value. + :raises ValueError: If the type is not an integer or a float, or if it + is a numeric value less than zero. + """ + if value is _Default: + return cls.DEFAULT_TIMEOUT + + if value is None or value is cls.DEFAULT_TIMEOUT: + return value + + try: + float(value) + except (TypeError, ValueError): + raise ValueError("Timeout value %s was %s, but it must be an " + "int or float." % (name, value)) + + try: + if value < 0: + raise ValueError("Attempted to set %s timeout to %s, but the " + "timeout cannot be set to a value less " + "than 0." % (name, value)) + except TypeError: # Python 3 + raise ValueError("Timeout value %s was %s, but it must be an " + "int or float." % (name, value)) + + return value + + @classmethod + def from_float(cls, timeout): + """ Create a new Timeout from a legacy timeout value. + + The timeout value used by httplib.py sets the same timeout on the + connect(), and recv() socket requests. This creates a :class:`Timeout` + object that sets the individual timeouts to the ``timeout`` value + passed to this function. + + :param timeout: The legacy timeout value. + :type timeout: integer, float, sentinel default object, or None + :return: Timeout object + :rtype: :class:`Timeout` + """ + return Timeout(read=timeout, connect=timeout) + + def clone(self): + """ Create a copy of the timeout object + + Timeout properties are stored per-pool but each request needs a fresh + Timeout object to ensure each one has its own start/stop configured. + + :return: a copy of the timeout object + :rtype: :class:`Timeout` + """ + # We can't use copy.deepcopy because that will also create a new object + # for _GLOBAL_DEFAULT_TIMEOUT, which socket.py uses as a sentinel to + # detect the user default. + return Timeout(connect=self._connect, read=self._read, + total=self.total) + + def start_connect(self): + """ Start the timeout clock, used during a connect() attempt + + :raises urllib3.exceptions.TimeoutStateError: if you attempt + to start a timer that has been started already. + """ + if self._start_connect is not None: + raise TimeoutStateError("Timeout timer has already been started.") + self._start_connect = current_time() + return self._start_connect + + def get_connect_duration(self): + """ Gets the time elapsed since the call to :meth:`start_connect`. + + :return: Elapsed time. + :rtype: float + :raises urllib3.exceptions.TimeoutStateError: if you attempt + to get duration for a timer that hasn't been started. + """ + if self._start_connect is None: + raise TimeoutStateError("Can't get connect duration for timer " + "that has not started.") + return current_time() - self._start_connect + + @property + def connect_timeout(self): + """ Get the value to use when setting a connection timeout. + + This will be a positive float or integer, the value None + (never timeout), or the default system timeout. + + :return: Connect timeout. + :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None + """ + if self.total is None: + return self._connect + + if self._connect is None or self._connect is self.DEFAULT_TIMEOUT: + return self.total + + return min(self._connect, self.total) + + @property + def read_timeout(self): + """ Get the value for the read timeout. + + This assumes some time has elapsed in the connection timeout and + computes the read timeout appropriately. + + If self.total is set, the read timeout is dependent on the amount of + time taken by the connect timeout. If the connection time has not been + established, a :exc:`~urllib3.exceptions.TimeoutStateError` will be + raised. + + :return: Value to use for the read timeout. + :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None + :raises urllib3.exceptions.TimeoutStateError: If :meth:`start_connect` + has not yet been called on this object. + """ + if (self.total is not None and + self.total is not self.DEFAULT_TIMEOUT and + self._read is not None and + self._read is not self.DEFAULT_TIMEOUT): + # In case the connect timeout has not yet been established. + if self._start_connect is None: + return self._read + return max(0, min(self.total - self.get_connect_duration(), + self._read)) + elif self.total is not None and self.total is not self.DEFAULT_TIMEOUT: + return max(0, self.total - self.get_connect_duration()) + else: + return self._read diff --git a/lib/requests/packages/urllib3/util/url.py b/lib/requests/packages/urllib3/util/url.py new file mode 100644 index 0000000000000000000000000000000000000000..b2ec834fe721a55195c25d4495b48c1bdaefcd5f --- /dev/null +++ b/lib/requests/packages/urllib3/util/url.py @@ -0,0 +1,212 @@ +from collections import namedtuple + +from ..exceptions import LocationParseError + + +url_attrs = ['scheme', 'auth', 'host', 'port', 'path', 'query', 'fragment'] + + +class Url(namedtuple('Url', url_attrs)): + """ + Datastructure for representing an HTTP URL. Used as a return value for + :func:`parse_url`. + """ + slots = () + + def __new__(cls, scheme=None, auth=None, host=None, port=None, path=None, + query=None, fragment=None): + return super(Url, cls).__new__(cls, scheme, auth, host, port, path, + query, fragment) + + @property + def hostname(self): + """For backwards-compatibility with urlparse. We're nice like that.""" + return self.host + + @property + def request_uri(self): + """Absolute path including the query string.""" + uri = self.path or '/' + + if self.query is not None: + uri += '?' + self.query + + return uri + + @property + def netloc(self): + """Network location including host and port""" + if self.port: + return '%s:%d' % (self.host, self.port) + return self.host + + @property + def url(self): + """ + Convert self into a url + + This function should more or less round-trip with :func:`.parse_url`. The + returned url may not be exactly the same as the url inputted to + :func:`.parse_url`, but it should be equivalent by the RFC (e.g., urls + with a blank port will have : removed). + + Example: :: + + >>> U = parse_url('http://google.com/mail/') + >>> U.url + 'http://google.com/mail/' + >>> Url('http', 'username:password', 'host.com', 80, + ... '/path', 'query', 'fragment').url + 'http://username:password@host.com:80/path?query#fragment' + """ + scheme, auth, host, port, path, query, fragment = self + url = '' + + # We use "is not None" we want things to happen with empty strings (or 0 port) + if scheme is not None: + url += scheme + '://' + if auth is not None: + url += auth + '@' + if host is not None: + url += host + if port is not None: + url += ':' + str(port) + if path is not None: + url += path + if query is not None: + url += '?' + query + if fragment is not None: + url += '#' + fragment + + return url + + def __str__(self): + return self.url + +def split_first(s, delims): + """ + Given a string and an iterable of delimiters, split on the first found + delimiter. Return two split parts and the matched delimiter. + + If not found, then the first part is the full input string. + + Example:: + + >>> split_first('foo/bar?baz', '?/=') + ('foo', 'bar?baz', '/') + >>> split_first('foo/bar?baz', '123') + ('foo/bar?baz', '', None) + + Scales linearly with number of delims. Not ideal for large number of delims. + """ + min_idx = None + min_delim = None + for d in delims: + idx = s.find(d) + if idx < 0: + continue + + if min_idx is None or idx < min_idx: + min_idx = idx + min_delim = d + + if min_idx is None or min_idx < 0: + return s, '', None + + return s[:min_idx], s[min_idx+1:], min_delim + + +def parse_url(url): + """ + Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is + performed to parse incomplete urls. Fields not provided will be None. + + Partly backwards-compatible with :mod:`urlparse`. + + Example:: + + >>> parse_url('http://google.com/mail/') + Url(scheme='http', host='google.com', port=None, path='/mail/', ...) + >>> parse_url('google.com:80') + Url(scheme=None, host='google.com', port=80, path=None, ...) + >>> parse_url('/foo?bar') + Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...) + """ + + # While this code has overlap with stdlib's urlparse, it is much + # simplified for our needs and less annoying. + # Additionally, this implementations does silly things to be optimal + # on CPython. + + if not url: + # Empty + return Url() + + scheme = None + auth = None + host = None + port = None + path = None + fragment = None + query = None + + # Scheme + if '://' in url: + scheme, url = url.split('://', 1) + + # Find the earliest Authority Terminator + # (http://tools.ietf.org/html/rfc3986#section-3.2) + url, path_, delim = split_first(url, ['/', '?', '#']) + + if delim: + # Reassemble the path + path = delim + path_ + + # Auth + if '@' in url: + # Last '@' denotes end of auth part + auth, url = url.rsplit('@', 1) + + # IPv6 + if url and url[0] == '[': + host, url = url.split(']', 1) + host += ']' + + # Port + if ':' in url: + _host, port = url.split(':', 1) + + if not host: + host = _host + + if port: + # If given, ports must be integers. + if not port.isdigit(): + raise LocationParseError(url) + port = int(port) + else: + # Blank ports are cool, too. (rfc3986#section-3.2.3) + port = None + + elif not host and url: + host = url + + if not path: + return Url(scheme, auth, host, port, path, query, fragment) + + # Fragment + if '#' in path: + path, fragment = path.split('#', 1) + + # Query + if '?' in path: + path, query = path.split('?', 1) + + return Url(scheme, auth, host, port, path, query, fragment) + +def get_host(url): + """ + Deprecated. Use :func:`.parse_url` instead. + """ + p = parse_url(url) + return p.scheme or 'http', p.hostname, p.port diff --git a/lib/requests/sessions.py b/lib/requests/sessions.py index 425db22ca6fbe6e422b1e6dd61f9185915adf372..4f3069635332a9fe3284e332eccb7d1e38f62fe4 100644 --- a/lib/requests/sessions.py +++ b/lib/requests/sessions.py @@ -12,24 +12,32 @@ import os from collections import Mapping from datetime import datetime -from .compat import cookielib, OrderedDict, urljoin, urlparse, builtin_str +from .auth import _basic_auth_str +from .compat import cookielib, OrderedDict, urljoin, urlparse from .cookies import ( cookiejar_from_dict, extract_cookies_to_jar, RequestsCookieJar, merge_cookies) from .models import Request, PreparedRequest, DEFAULT_REDIRECT_LIMIT from .hooks import default_hooks, dispatch_hook from .utils import to_key_val_list, default_headers, to_native_string -from .exceptions import TooManyRedirects, InvalidSchema +from .exceptions import ( + TooManyRedirects, InvalidSchema, ChunkedEncodingError, ContentDecodingError) +from .packages.urllib3._collections import RecentlyUsedContainer from .structures import CaseInsensitiveDict from .adapters import HTTPAdapter -from .utils import requote_uri, get_environ_proxies, get_netrc_auth +from .utils import ( + requote_uri, get_environ_proxies, get_netrc_auth, should_bypass_proxies, + get_auth_from_url +) from .status_codes import codes # formerly defined here, reexposed here for backward compatibility from .models import REDIRECT_STATI +REDIRECT_CACHE_SIZE = 1000 + def merge_setting(request_setting, session_setting, dict_class=OrderedDict): """ @@ -86,11 +94,21 @@ class SessionRedirectMixin(object): """Receives a Response. Returns a generator of Responses.""" i = 0 + hist = [] # keep track of history while resp.is_redirect: prepared_request = req.copy() - resp.content # Consume socket so it can be released + if i > 0: + # Update history and keep track of redirects. + hist.append(resp) + new_hist = list(hist) + resp.history = new_hist + + try: + resp.content # Consume socket so it can be released + except (ChunkedEncodingError, ContentDecodingError, RuntimeError): + resp.raw.read(decode_content=False) if i >= self.max_redirects: raise TooManyRedirects('Exceeded %s redirects.' % self.max_redirects) @@ -110,17 +128,20 @@ class SessionRedirectMixin(object): parsed = urlparse(url) url = parsed.geturl() - # Facilitate non-RFC2616-compliant 'location' headers + # Facilitate relative 'location' headers, as allowed by RFC 7231. # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource') # Compliant with RFC3986, we percent encode the url. - if not urlparse(url).netloc: + if not parsed.netloc: url = urljoin(resp.url, requote_uri(url)) else: url = requote_uri(url) prepared_request.url = to_native_string(url) + # Cache the url, unless it redirects to itself. + if resp.is_permanent_redirect and req.url != prepared_request.url: + self.redirect_cache[req.url] = prepared_request.url - # http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4 + # http://tools.ietf.org/html/rfc7231#section-6.4.4 if (resp.status_code == codes.see_other and method != 'HEAD'): method = 'GET' @@ -138,7 +159,7 @@ class SessionRedirectMixin(object): prepared_request.method = method # https://github.com/kennethreitz/requests/issues/1084 - if resp.status_code not in (codes.temporary, codes.resume): + if resp.status_code not in (codes.temporary_redirect, codes.permanent_redirect): if 'Content-Length' in prepared_request.headers: del prepared_request.headers['Content-Length'] @@ -154,22 +175,15 @@ class SessionRedirectMixin(object): prepared_request._cookies.update(self.cookies) prepared_request.prepare_cookies(prepared_request._cookies) - if 'Authorization' in headers: - # If we get redirected to a new host, we should strip out any - # authentication headers. - original_parsed = urlparse(resp.request.url) - redirect_parsed = urlparse(url) - - if (original_parsed.hostname != redirect_parsed.hostname): - del headers['Authorization'] + # Rebuild auth and proxy information. + proxies = self.rebuild_proxies(prepared_request, proxies) + self.rebuild_auth(prepared_request, resp) - # .netrc might have more auth for us. - new_auth = get_netrc_auth(url) if self.trust_env else None - if new_auth is not None: - prepared_request.prepare_auth(new_auth) + # Override the original request. + req = prepared_request resp = self.send( - prepared_request, + req, stream=stream, timeout=timeout, verify=verify, @@ -183,6 +197,68 @@ class SessionRedirectMixin(object): i += 1 yield resp + def rebuild_auth(self, prepared_request, response): + """ + When being redirected we may want to strip authentication from the + request to avoid leaking credentials. This method intelligently removes + and reapplies authentication where possible to avoid credential loss. + """ + headers = prepared_request.headers + url = prepared_request.url + + if 'Authorization' in headers: + # If we get redirected to a new host, we should strip out any + # authentication headers. + original_parsed = urlparse(response.request.url) + redirect_parsed = urlparse(url) + + if (original_parsed.hostname != redirect_parsed.hostname): + del headers['Authorization'] + + # .netrc might have more auth for us on our new host. + new_auth = get_netrc_auth(url) if self.trust_env else None + if new_auth is not None: + prepared_request.prepare_auth(new_auth) + + return + + def rebuild_proxies(self, prepared_request, proxies): + """ + This method re-evaluates the proxy configuration by considering the + environment variables. If we are redirected to a URL covered by + NO_PROXY, we strip the proxy configuration. Otherwise, we set missing + proxy keys for this URL (in case they were stripped by a previous + redirect). + + This method also replaces the Proxy-Authorization header where + necessary. + """ + headers = prepared_request.headers + url = prepared_request.url + scheme = urlparse(url).scheme + new_proxies = proxies.copy() if proxies is not None else {} + + if self.trust_env and not should_bypass_proxies(url): + environ_proxies = get_environ_proxies(url) + + proxy = environ_proxies.get(scheme) + + if proxy: + new_proxies.setdefault(scheme, environ_proxies[scheme]) + + if 'Proxy-Authorization' in headers: + del headers['Proxy-Authorization'] + + try: + username, password = get_auth_from_url(new_proxies[scheme]) + except KeyError: + username, password = None, None + + if username and password: + headers['Proxy-Authorization'] = _basic_auth_str(username, password) + + return new_proxies + class Session(SessionRedirectMixin): """A Requests session. @@ -198,9 +274,10 @@ class Session(SessionRedirectMixin): """ __attrs__ = [ - 'headers', 'cookies', 'auth', 'timeout', 'proxies', 'hooks', - 'params', 'verify', 'cert', 'prefetch', 'adapters', 'stream', - 'trust_env', 'max_redirects'] + 'headers', 'cookies', 'auth', 'proxies', 'hooks', 'params', 'verify', + 'cert', 'prefetch', 'adapters', 'stream', 'trust_env', + 'max_redirects', + ] def __init__(self): @@ -253,6 +330,9 @@ class Session(SessionRedirectMixin): self.mount('https://', HTTPAdapter()) self.mount('http://', HTTPAdapter()) + # Only store 1000 redirects to prevent using infinite memory + self.redirect_cache = RecentlyUsedContainer(REDIRECT_CACHE_SIZE) + def __enter__(self): return self @@ -290,6 +370,7 @@ class Session(SessionRedirectMixin): url=request.url, files=request.files, data=request.data, + json=request.json, headers=merge_setting(request.headers, self.headers, dict_class=CaseInsensitiveDict), params=merge_setting(request.params, self.params), auth=merge_setting(auth, self.auth), @@ -311,7 +392,8 @@ class Session(SessionRedirectMixin): hooks=None, stream=None, verify=None, - cert=None): + cert=None, + json=None): """Constructs a :class:`Request <Request>`, prepares it and sends it. Returns :class:`Response <Response>` object. @@ -321,17 +403,22 @@ class Session(SessionRedirectMixin): string for the :class:`Request`. :param data: (optional) Dictionary or bytes to send in the body of the :class:`Request`. + :param json: (optional) json to send in the body of the + :class:`Request`. :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`. :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`. - :param files: (optional) Dictionary of 'filename': file-like-objects + :param files: (optional) Dictionary of ``'filename': file-like-objects`` for multipart encoding upload. :param auth: (optional) Auth tuple or callable to enable Basic/Digest/Custom HTTP Auth. - :param timeout: (optional) Float describing the timeout of the - request in seconds. - :param allow_redirects: (optional) Boolean. Set to True by default. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a (`connect timeout, read + timeout <user/advanced.html#timeouts>`_) tuple. + :type timeout: float or tuple + :param allow_redirects: (optional) Set to True by default. + :type allow_redirects: bool :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy. :param stream: (optional) whether to immediately download the response @@ -342,7 +429,7 @@ class Session(SessionRedirectMixin): If Tuple, ('cert', 'key') pair. """ - method = builtin_str(method) + method = to_native_string(method) # Create the Request. req = Request( @@ -351,6 +438,7 @@ class Session(SessionRedirectMixin): headers = headers, files = files, data = data or {}, + json = json, params = params or {}, auth = auth, cookies = cookies, @@ -360,36 +448,16 @@ class Session(SessionRedirectMixin): proxies = proxies or {} - # Gather clues from the surrounding environment. - if self.trust_env: - # Set environment's proxies. - env_proxies = get_environ_proxies(url) or {} - for (k, v) in env_proxies.items(): - proxies.setdefault(k, v) - - # Look for configuration. - if not verify and verify is not False: - verify = os.environ.get('REQUESTS_CA_BUNDLE') - - # Curl compatibility. - if not verify and verify is not False: - verify = os.environ.get('CURL_CA_BUNDLE') - - # Merge all the kwargs. - proxies = merge_setting(proxies, self.proxies) - stream = merge_setting(stream, self.stream) - verify = merge_setting(verify, self.verify) - cert = merge_setting(cert, self.cert) + settings = self.merge_environment_settings( + prep.url, proxies, stream, verify, cert + ) # Send the request. send_kwargs = { - 'stream': stream, 'timeout': timeout, - 'verify': verify, - 'cert': cert, - 'proxies': proxies, 'allow_redirects': allow_redirects, } + send_kwargs.update(settings) resp = self.send(prep, **send_kwargs) return resp @@ -424,15 +492,16 @@ class Session(SessionRedirectMixin): kwargs.setdefault('allow_redirects', False) return self.request('HEAD', url, **kwargs) - def post(self, url, data=None, **kwargs): + def post(self, url, data=None, json=None, **kwargs): """Sends a POST request. Returns :class:`Response` object. :param url: URL for the new :class:`Request` object. :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json to send in the body of the :class:`Request`. :param \*\*kwargs: Optional arguments that ``request`` takes. """ - return self.request('POST', url, data=data, **kwargs) + return self.request('POST', url, data=data, json=json, **kwargs) def put(self, url, data=None, **kwargs): """Sends a PUT request. Returns :class:`Response` object. @@ -477,6 +546,14 @@ class Session(SessionRedirectMixin): if not isinstance(request, PreparedRequest): raise ValueError('You can only send PreparedRequests.') + checked_urls = set() + while request.url in self.redirect_cache: + checked_urls.add(request.url) + new_url = self.redirect_cache.get(request.url) + if new_url in checked_urls: + break + request.url = new_url + # Set up variables needed for resolve_redirects and dispatching of hooks allow_redirects = kwargs.pop('allow_redirects', True) stream = kwargs.get('stream') @@ -527,10 +604,37 @@ class Session(SessionRedirectMixin): history.insert(0, r) # Get the last request made r = history.pop() - r.history = tuple(history) + r.history = history + + if not stream: + r.content return r + def merge_environment_settings(self, url, proxies, stream, verify, cert): + """Check the environment and merge it with some settings.""" + # Gather clues from the surrounding environment. + if self.trust_env: + # Set environment's proxies. + env_proxies = get_environ_proxies(url) or {} + for (k, v) in env_proxies.items(): + proxies.setdefault(k, v) + + # Look for requests environment configuration and be compatible + # with cURL. + if verify is True or verify is None: + verify = (os.environ.get('REQUESTS_CA_BUNDLE') or + os.environ.get('CURL_CA_BUNDLE')) + + # Merge all the kwargs. + proxies = merge_setting(proxies, self.proxies) + stream = merge_setting(stream, self.stream) + verify = merge_setting(verify, self.verify) + cert = merge_setting(cert, self.cert) + + return {'verify': verify, 'proxies': proxies, 'stream': stream, + 'cert': cert} + def get_adapter(self, url): """Returns the appropriate connnection adapter for the given URL.""" for (prefix, adapter) in self.adapters.items(): @@ -558,12 +662,19 @@ class Session(SessionRedirectMixin): self.adapters[key] = self.adapters.pop(key) def __getstate__(self): - return dict((attr, getattr(self, attr, None)) for attr in self.__attrs__) + state = dict((attr, getattr(self, attr, None)) for attr in self.__attrs__) + state['redirect_cache'] = dict(self.redirect_cache) + return state def __setstate__(self, state): + redirect_cache = state.pop('redirect_cache', {}) for attr, value in state.items(): setattr(self, attr, value) + self.redirect_cache = RecentlyUsedContainer(REDIRECT_CACHE_SIZE) + for redirect, to in redirect_cache.items(): + self.redirect_cache[redirect] = to + def session(): """Returns a :class:`Session` for context-management.""" diff --git a/lib/requests/status_codes.py b/lib/requests/status_codes.py index ed7a8660a6f6085861ba3fea10a50487dfb5d351..e0887f210a716d620bde38056db40fe987af9bbe 100644 --- a/lib/requests/status_codes.py +++ b/lib/requests/status_codes.py @@ -30,7 +30,8 @@ _codes = { 305: ('use_proxy',), 306: ('switch_proxy',), 307: ('temporary_redirect', 'temporary_moved', 'temporary'), - 308: ('resume_incomplete', 'resume'), + 308: ('permanent_redirect', + 'resume_incomplete', 'resume',), # These 2 to be removed in 3.0 # Client Error. 400: ('bad_request', 'bad'), diff --git a/lib/requests/structures.py b/lib/requests/structures.py index a1759137aa0e30e91f428b6129d6712f6e06f643..3e5f2faa2ecab02bd720bbff2179d80077af8e55 100644 --- a/lib/requests/structures.py +++ b/lib/requests/structures.py @@ -8,30 +8,7 @@ Data structures that power Requests. """ -import os import collections -from itertools import islice - - -class IteratorProxy(object): - """docstring for IteratorProxy""" - def __init__(self, i): - self.i = i - # self.i = chain.from_iterable(i) - - def __iter__(self): - return self.i - - def __len__(self): - if hasattr(self.i, '__len__'): - return len(self.i) - if hasattr(self.i, 'len'): - return self.i.len - if hasattr(self.i, 'fileno'): - return os.fstat(self.i.fileno()).st_size - - def read(self, n): - return "".join(islice(self.i, None, n)) class CaseInsensitiveDict(collections.MutableMapping): @@ -46,7 +23,7 @@ class CaseInsensitiveDict(collections.MutableMapping): case of the last key to be set, and ``iter(instance)``, ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()`` will contain case-sensitive keys. However, querying and contains - testing is case insensitive: + testing is case insensitive:: cid = CaseInsensitiveDict() cid['Accept'] = 'application/json' @@ -106,8 +83,7 @@ class CaseInsensitiveDict(collections.MutableMapping): return CaseInsensitiveDict(self._store.values()) def __repr__(self): - return '%s(%r)' % (self.__class__.__name__, dict(self.items())) - + return str(dict(self.items())) class LookupDict(dict): """Dictionary lookup object.""" diff --git a/lib/requests/utils.py b/lib/requests/utils.py index 4d648bc5fa92a56d3995ac5d560545b90529c348..74679414471b02a8bd6e806dc2a6e47f4a9c18d3 100644 --- a/lib/requests/utils.py +++ b/lib/requests/utils.py @@ -19,15 +19,16 @@ import re import sys import socket import struct +import warnings from . import __version__ from . import certs from .compat import parse_http_list as _parse_list_header from .compat import (quote, urlparse, bytes, str, OrderedDict, unquote, is_py2, - builtin_str, getproxies, proxy_bypass) + builtin_str, getproxies, proxy_bypass, urlunparse) from .cookies import RequestsCookieJar, cookiejar_from_dict from .structures import CaseInsensitiveDict -from .exceptions import MissingSchema, InvalidURL +from .exceptions import InvalidURL _hush_pyflakes = (RequestsCookieJar,) @@ -61,7 +62,7 @@ def super_len(o): return os.fstat(fileno).st_size if hasattr(o, 'getvalue'): - # e.g. BytesIO, cStringIO.StringI + # e.g. BytesIO, cStringIO.StringIO return len(o.getvalue()) @@ -114,7 +115,7 @@ def get_netrc_auth(url): def guess_filename(obj): """Tries to guess the filename of the given object.""" name = getattr(obj, 'name', None) - if name and name[0] != '<' and name[-1] != '>': + if name and isinstance(name, builtin_str) and name[0] != '<' and name[-1] != '>': return os.path.basename(name) @@ -287,6 +288,11 @@ def get_encodings_from_content(content): :param content: bytestring to extract encodings from. """ + warnings.warn(( + 'In requests 3.0, get_encodings_from_content will be removed. For ' + 'more information, please see the discussion on issue #2266. (This' + ' warning should only appear once.)'), + DeprecationWarning) charset_re = re.compile(r'<meta.*?charset=["\']*(.+?)["\'>]', flags=re.I) pragma_re = re.compile(r'<meta.*?content=["\']*;?charset=(.+?)["\'>]', flags=re.I) @@ -351,12 +357,14 @@ def get_unicode_from_response(r): Tried: 1. charset from content-type - - 2. every encodings from ``<meta ... charset=XXX>`` - - 3. fall back and replace all unicode characters + 2. fall back and replace all unicode characters """ + warnings.warn(( + 'In requests 3.0, get_unicode_from_response will be removed. For ' + 'more information, please see the discussion on issue #2266. (This' + ' warning should only appear once.)'), + DeprecationWarning) tried_encodings = [] @@ -466,9 +474,10 @@ def is_valid_cidr(string_network): return True -def get_environ_proxies(url): - """Return a dict of environment proxies.""" - +def should_bypass_proxies(url): + """ + Returns whether we should bypass proxies or not. + """ get_proxy = lambda k: os.environ.get(k) or os.environ.get(k.upper()) # First check whether no_proxy is defined. If it is, check that the URL @@ -486,13 +495,13 @@ def get_environ_proxies(url): for proxy_ip in no_proxy: if is_valid_cidr(proxy_ip): if address_in_network(ip, proxy_ip): - return {} + return True else: for host in no_proxy: if netloc.endswith(host) or netloc.split(':')[0].endswith(host): # The URL does match something in no_proxy, so we don't want # to apply the proxies on this URL. - return {} + return True # If the system proxy settings indicate that this URL should be bypassed, # don't proxy. @@ -506,12 +515,16 @@ def get_environ_proxies(url): bypass = False if bypass: - return {} + return True + + return False - # If we get here, we either didn't have no_proxy set or we're not going - # anywhere that no_proxy applies to, and the system settings don't require - # bypassing the proxy for the current URL. - return getproxies() +def get_environ_proxies(url): + """Return a dict of environment proxies.""" + if should_bypass_proxies(url): + return {} + else: + return getproxies() def default_user_agent(name="python-requests"): @@ -549,7 +562,8 @@ def default_headers(): return CaseInsensitiveDict({ 'User-Agent': default_user_agent(), 'Accept-Encoding': ', '.join(('gzip', 'deflate')), - 'Accept': '*/*' + 'Accept': '*/*', + 'Connection': 'keep-alive', }) @@ -564,7 +578,7 @@ def parse_header_links(value): replace_chars = " '\"" - for val in value.split(","): + for val in re.split(", *<", value): try: url, params = val.split(";", 1) except ValueError: @@ -622,13 +636,18 @@ def guess_json_utf(data): return None -def except_on_missing_scheme(url): - """Given a URL, raise a MissingSchema exception if the scheme is missing. - """ - scheme, netloc, path, params, query, fragment = urlparse(url) +def prepend_scheme_if_needed(url, new_scheme): + '''Given a URL that may or may not have a scheme, prepend the given scheme. + Does not replace a present scheme with the one provided as an argument.''' + scheme, netloc, path, params, query, fragment = urlparse(url, new_scheme) - if not scheme: - raise MissingSchema('Proxy URLs must have explicit schemes.') + # urlparse is a finicky beast, and sometimes decides that there isn't a + # netloc present. Assume that it's being over-cautious, and switch netloc + # and path if urlparse decided there was no netloc. + if not netloc: + netloc, path = path, netloc + + return urlunparse((scheme, netloc, path, params, query, fragment)) def get_auth_from_url(url): @@ -661,3 +680,18 @@ def to_native_string(string, encoding='ascii'): out = string.decode(encoding) return out + + +def urldefragauth(url): + """ + Given a url remove the fragment and the authentication part + """ + scheme, netloc, path, params, query, fragment = urlparse(url) + + # see func:`prepend_scheme_if_needed` + if not netloc: + netloc, path = path, netloc + + netloc = netloc.rsplit('@', 1)[-1] + + return urlunparse((scheme, netloc, path, params, query, '')) diff --git a/lib/rtorrent/__init__.py b/lib/rtorrent/__init__.py index 290ef11581342d412f7df1e9d73fea9bb0f31ec7..c24f608f177036bbf7b4687a60125cc0d0b98fe3 100644 --- a/lib/rtorrent/__init__.py +++ b/lib/rtorrent/__init__.py @@ -22,15 +22,16 @@ import os.path import time import xmlrpclib -from rtorrent.common import find_torrent, \ - is_valid_port, convert_version_tuple_to_str -from rtorrent.lib.torrentparser import TorrentParser -from rtorrent.lib.xmlrpc.http import HTTPServerProxy -from rtorrent.lib.xmlrpc.scgi import SCGIServerProxy -from rtorrent.rpc import Method -from rtorrent.lib.xmlrpc.basic_auth import BasicAuthTransport -from rtorrent.torrent import Torrent -from rtorrent.group import Group +from rtorrent.common import (find_torrent, # @UnresolvedImport + is_valid_port, # @UnresolvedImport + convert_version_tuple_to_str) # @UnresolvedImport +from rtorrent.lib.torrentparser import TorrentParser # @UnresolvedImport +from rtorrent.lib.xmlrpc.http import HTTPServerProxy # @UnresolvedImport +from rtorrent.lib.xmlrpc.scgi import SCGIServerProxy # @UnresolvedImport +from rtorrent.rpc import Method # @UnresolvedImport +from rtorrent.lib.xmlrpc.requests_transport import RequestsTransport # @UnresolvedImport @IgnorePep8 +from rtorrent.torrent import Torrent # @UnresolvedImport +from rtorrent.group import Group # @UnresolvedImport import rtorrent.rpc # @UnresolvedImport __version__ = "0.2.9" @@ -43,11 +44,12 @@ MIN_RTORRENT_VERSION_STR = convert_version_tuple_to_str(MIN_RTORRENT_VERSION) class RTorrent: + """ Create a new rTorrent connection """ rpc_prefix = None def __init__(self, uri, username=None, password=None, - verify=False, sp=None, sp_kwargs=None): + verify=False, sp=None, sp_kwargs=None, tp_kwargs=None): self.uri = uri # : From X{__init__(self, url)} self.username = username @@ -59,6 +61,10 @@ class RTorrent: self.sp = sp elif self.schema in ['http', 'https']: self.sp = HTTPServerProxy + if self.schema == 'https': + self.isHttps = True + else: + self.isHttps = False elif self.schema == 'scgi': self.sp = SCGIServerProxy else: @@ -66,6 +72,8 @@ class RTorrent: self.sp_kwargs = sp_kwargs or {} + self.tp_kwargs = tp_kwargs or {} + self.torrents = [] # : List of L{Torrent} instances self._rpc_methods = [] # : List of rTorrent RPC methods self._torrent_cache = [] @@ -80,9 +88,30 @@ class RTorrent: if self.schema == 'scgi': raise NotImplementedError() + if 'authtype' not in self.tp_kwargs: + authtype = None + else: + authtype = self.tp_kwargs['authtype'] + + if 'check_ssl_cert' not in self.tp_kwargs: + check_ssl_cert = True + else: + check_ssl_cert = self.tp_kwargs['check_ssl_cert'] + + if 'proxies' not in self.tp_kwargs: + proxies = None + else: + proxies = self.tp_kwargs['proxies'] + return self.sp( self.uri, - transport=BasicAuthTransport(self.username, self.password), + transport=RequestsTransport( + use_https=self.isHttps, + authtype=authtype, + username=self.username, + password=self.password, + check_ssl_cert=check_ssl_cert, + proxies=proxies), **self.sp_kwargs ) @@ -90,8 +119,10 @@ class RTorrent: def _verify_conn(self): # check for rpc methods that should be available - assert "system.client_version" in self._get_rpc_methods(), "Required RPC method not available." - assert "system.library_version" in self._get_rpc_methods(), "Required RPC method not available." + assert "system.client_version" in self._get_rpc_methods( + ), "Required RPC method not available." + assert "system.library_version" in self._get_rpc_methods( + ), "Required RPC method not available." # minimum rTorrent version check assert self._meets_version_requirement() is True,\ @@ -152,7 +183,8 @@ class RTorrent: for result in results: results_dict = {} # build results_dict - for m, r in zip(retriever_methods, result[1:]): # result[0] is the info_hash + # result[0] is the info_hash + for m, r in zip(retriever_methods, result[1:]): results_dict[m.varname] = rtorrent.rpc.process_result(m, r) self.torrents.append( @@ -199,7 +231,7 @@ class RTorrent: return(func_name) - def load_magnet(self, magneturl, info_hash, start=False, verbose=False, verify_load=True): + def load_magnet(self, magneturl, info_hash, start=False, verbose=False, verify_load=True): # @IgnorePep8 p = self._get_conn() @@ -231,13 +263,13 @@ class RTorrent: while i < MAX_RETRIES: for torrent in self.get_torrents(): if torrent.info_hash == info_hash: - if str(info_hash) not in str(torrent.name) : + if str(info_hash) not in str(torrent.name): time.sleep(1) i += 1 return(torrent) - def load_torrent(self, torrent, start=False, verbose=False, verify_load=True): + def load_torrent(self, torrent, start=False, verbose=False, verify_load=True): # @IgnorePep8 """ Loads torrent into rTorrent (with various enhancements) @@ -354,7 +386,7 @@ class RTorrent: if persistent is True: p.group.insert_persistent_view('', name) else: - assert view is not None, "view parameter required on non-persistent groups" + assert view is not None, "view parameter required on non-persistent groups" # @IgnorePep8 p.group.insert('', name, view) self._update_rpc_methods() diff --git a/lib/rtorrent/lib/xmlrpc/requests_transport.py b/lib/rtorrent/lib/xmlrpc/requests_transport.py new file mode 100644 index 0000000000000000000000000000000000000000..d5e28743c860b98d5d25376c1f1e3f409fb9a121 --- /dev/null +++ b/lib/rtorrent/lib/xmlrpc/requests_transport.py @@ -0,0 +1,188 @@ +# Copyright (c) 2013-2015 Alexandre Beloin, <alexandre.beloin@gmail.com> +# +# 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 3 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, see <http://www.gnu.org/licenses/>. + +"""A transport for Python2/3 xmlrpc library using requests + +Support: +-SSL with Basic and Digest authentication +-Proxies +""" + +try: + import xmlrpc.client as xmlrpc_client +except ImportError: + import xmlrpclib as xmlrpc_client + +import traceback + +import requests +from requests.exceptions import RequestException +from requests.auth import HTTPBasicAuth +from requests.auth import HTTPDigestAuth +from requests.packages.urllib3 import disable_warnings # @UnresolvedImport + + +class RequestsTransport(xmlrpc_client.Transport): + + """Transport class for xmlrpc using requests""" + + def __init__(self, use_https=True, authtype=None, username=None, + password=None, check_ssl_cert=True, proxies=None): + """Inits RequestsTransport. + + Args: + use_https: If true, https else http + authtype: None, basic or digest + username: Username + password: Password + check_ssl_cert: Check SSL certificate + proxies: A dict of proxies( + Ex: {"http": "http://10.10.1.10:3128", + "https": "http://10.10.1.10:1080",}) + + Raises: + ValueError: Invalid info + """ + # Python 2 can't use super on old style class. + if issubclass(xmlrpc_client.Transport, object): + super(RequestsTransport, self).__init__() + else: + xmlrpc_client.Transport.__init__(self) + + self.user_agent = "Python Requests/" + requests.__version__ + + self._use_https = use_https + self._check_ssl_cert = check_ssl_cert + + if authtype == "basic" or authtype == "digest": + self._authtype = authtype + else: + raise ValueError( + "Supported authentication are: basic and digest") + if authtype and (not username or not password): + raise ValueError( + "Username and password required when using authentication") + + self._username = username + self._password = password + if proxies is None: + self._proxies = {} + else: + self._proxies = proxies + + def request(self, host, handler, request_body, verbose=0): + """Replace the xmlrpc request function. + + Process xmlrpc request via requests library. + + Args: + host: Target host + handler: Target PRC handler. + request_body: XML-RPC request body. + verbose: Debugging flag. + + Returns: + Parsed response. + + Raises: + RequestException: Error in requests + """ + if verbose: + self._debug() + + if not self._check_ssl_cert: + disable_warnings() + + headers = {'User-Agent': self.user_agent, 'Content-Type': 'text/xml', } + + # Need to be done because the schema(http or https) is lost in + # xmlrpc.Transport's init. + if self._use_https: + url = "https://{host}/{handler}".format(host=host, handler=handler) + else: + url = "http://{host}/{handler}".format(host=host, handler=handler) + + # TODO Construct kwargs query instead + try: + if self._authtype == "basic": + response = requests.post( + url, + data=request_body, + headers=headers, + verify=self._check_ssl_cert, + auth=HTTPBasicAuth( + self._username, self._password), + proxies=self._proxies) + elif self._authtype == "digest": + response = requests.post( + url, + data=request_body, + headers=headers, + verify=self._check_ssl_cert, + auth=HTTPDigestAuth( + self._username, self._password), + proxies=self._proxies) + else: + response = requests.post( + url, + data=request_body, + headers=headers, + verify=self._check_ssl_cert, + proxies=self._proxies) + + response.raise_for_status() + except RequestException as error: + raise xmlrpc_client.ProtocolError(url, + error.message, + traceback.format_exc(), + response.headers) + + return self.parse_response(response) + + def parse_response(self, response): + """Replace the xmlrpc parse_response function. + + Parse response. + + Args: + response: Requests return data + + Returns: + Response tuple and target method. + """ + p, u = self.getparser() + p.feed(response.text) + p.close() + return u.close() + + def _debug(self): + """Debug requests module. + + Enable verbose logging from requests + """ + # TODO Ugly + import logging + try: + import http.client as http_client + except ImportError: + import httplib as http_client + + http_client.HTTPConnection.debuglevel = 1 + + logging.basicConfig() + logging.getLogger().setLevel(logging.DEBUG) + requests_log = logging.getLogger("requests.packages.urllib3") + requests_log.setLevel(logging.DEBUG) + requests_log.propagate = True diff --git a/lib/subliminal/api.py b/lib/subliminal/api.py index f95fda3b482aa4b7f6b9fbe7e5d0eb6e54d4c290..867fafea456ae442dab4919f9dc8d116729c1afd 100644 --- a/lib/subliminal/api.py +++ b/lib/subliminal/api.py @@ -20,6 +20,7 @@ from .core import (SERVICES, LANGUAGE_INDEX, SERVICE_INDEX, SERVICE_CONFIDENCE, group_by_video, key_subtitles) from .language import language_set, language_list, LANGUAGES import logging +import sys __all__ = ['list_subtitles', 'download_subtitles'] @@ -48,7 +49,7 @@ def list_subtitles(paths, languages=None, services=None, force=True, multi=False if isinstance(paths, basestring): paths = [paths] if any([not isinstance(p, unicode) for p in paths]): - logger.warning(u'Not all entries are unicode') + logger.warning(u'Not all entries are unicode') if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') results = [] service_instances = {} tasks = create_list_tasks(paths, languages, services, force, multi, cache_dir, max_depth, scan_filter) @@ -57,7 +58,7 @@ def list_subtitles(paths, languages=None, services=None, force=True, multi=False result = consume_task(task, service_instances) results.append((task.video, result)) except: - logger.error(u'Error consuming task %r' % task, exc_info=True) + logger.error(u'Error consuming task %r' % task, exc_info=True) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') for service_instance in service_instances.itervalues(): service_instance.terminate() return group_by_video(results) @@ -106,7 +107,7 @@ def download_subtitles(paths, languages=None, services=None, force=True, multi=F result = consume_task(task, service_instances) results.append((task.video, result)) except: - logger.error(u'Error consuming task %r' % task, exc_info=True) + logger.error(u'Error consuming task %r' % task, exc_info=True) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') for service_instance in service_instances.itervalues(): service_instance.terminate() return group_by_video(results) diff --git a/lib/subliminal/async.py b/lib/subliminal/async.py index ff42764b830ae94640addffcd8e2e4496b37f6c1..6e5af16fe84ac853f9856eab4b3b65c6a498461c 100644 --- a/lib/subliminal/async.py +++ b/lib/subliminal/async.py @@ -23,6 +23,7 @@ from .tasks import StopTask import Queue import logging import threading +import sys __all__ = ['Worker', 'Pool'] @@ -47,11 +48,11 @@ class Worker(threading.Thread): result = consume_task(task, self.services) self.results.put((task.video, result)) except: - logger.error(u'Exception raised in worker %s' % self.name, exc_info=True) + logger.error(u'Exception raised in worker %s' % self.name, exc_info=True) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') finally: self.tasks.task_done() self.terminate() - logger.debug(u'Thread %s terminated' % self.name) + logger.debug(u'Thread %s terminated' % self.name) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') def terminate(self): """Terminate instantiated services""" @@ -59,7 +60,7 @@ class Worker(threading.Thread): try: service.terminate() except: - logger.error(u'Exception raised when terminating service %s' % service_name, exc_info=True) + logger.error(u'Exception raised when terminating service %s' % service_name, exc_info=True) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') class Pool(object): @@ -116,7 +117,7 @@ class Pool(object): if isinstance(paths, basestring): paths = [paths] if any([not isinstance(p, unicode) for p in paths]): - logger.warning(u'Not all entries are unicode') + logger.warning(u'Not all entries are unicode') if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') tasks = create_list_tasks(paths, languages, services, force, multi, cache_dir, max_depth, scan_filter) for task in tasks: self.tasks.put(task) diff --git a/lib/subliminal/cache.py b/lib/subliminal/cache.py index 31275e00ef151d05184bfdf195f41a0fe01ee71a..e8e08c3bda2279c9118b878752ecf746fa19434d 100644 --- a/lib/subliminal/cache.py +++ b/lib/subliminal/cache.py @@ -24,6 +24,7 @@ try: import cPickle as pickle except ImportError: import pickle +import sys __all__ = ['Cache', 'cachedmethod'] @@ -55,18 +56,18 @@ class Cache(object): self.cache[service_name] = defaultdict(dict) filename = self.cache_location(service_name) - logger.debug(u'Cache: loading cache from %s' % filename) + logger.debug(u'Cache: loading cache from %s' % filename) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') try: self.cache[service_name] = pickle.load(open(filename, 'rb')) except IOError: - logger.info('Cache: Cache file "%s" doesn\'t exist, creating it' % filename) + logger.info('Cache: Cache file "%s" doesn\'t exist, creating it' % filename) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') except EOFError: - logger.error('Cache: cache file "%s" is corrupted... Removing it.' % filename) + logger.error('Cache: cache file "%s" is corrupted... Removing it.' % filename) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') os.remove(filename) def save(self, service_name): filename = self.cache_location(service_name) - logger.debug(u'Cache: saving cache to %s' % filename) + logger.debug(u'Cache: saving cache to %s' % filename) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') with self.lock: pickle.dump(self.cache[service_name], open(filename, 'wb')) @@ -121,7 +122,7 @@ def cachedmethod(function): if key in func_cache: result = func_cache[key] - logger.debug(u'Using cached value for %s(%s), returns: %s' % (func_key, key, result)) + logger.debug(u'Using cached value for %s(%s), returns: %s' % (func_key, key, result)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return result result = function(*args) diff --git a/lib/subliminal/core.py b/lib/subliminal/core.py index 0ecbf3f654144c401cbb370329fd6bb797735722..27c45cabce3e6b4e826bbe1c4d0a8aaef5d433c9 100644 --- a/lib/subliminal/core.py +++ b/lib/subliminal/core.py @@ -26,6 +26,7 @@ from itertools import groupby import bs4 import guessit import logging +import sys __all__ = ['SERVICES', 'LANGUAGE_INDEX', 'SERVICE_INDEX', 'SERVICE_CONFIDENCE', 'MATCHING_CONFIDENCE', @@ -56,7 +57,7 @@ def create_list_tasks(paths, languages, services, force, multi, cache_dir, max_d scan_result = [] for p in paths: scan_result.extend(scan(p, max_depth, scan_filter)) - logger.debug(u'Found %d videos in %r with maximum depth %d' % (len(scan_result), paths, max_depth)) + logger.debug(u'Found %d videos in %r with maximum depth %d' % (len(scan_result), paths, max_depth)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') tasks = [] config = ServiceConfig(multi, cache_dir) services = filter_services(services) @@ -66,19 +67,19 @@ def create_list_tasks(paths, languages, services, force, multi, cache_dir, max_d if not force and multi: wanted_languages -= detected_languages if not wanted_languages: - logger.debug(u'No need to list multi subtitles %r for %r because %r detected' % (languages, video, detected_languages)) + logger.debug(u'No need to list multi subtitles %r for %r because %r detected' % (languages, video, detected_languages)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') continue if not force and not multi and Language('Undetermined') in detected_languages: - logger.debug(u'No need to list single subtitles %r for %r because one detected' % (languages, video)) + logger.debug(u'No need to list single subtitles %r for %r because one detected' % (languages, video)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') continue - logger.debug(u'Listing subtitles %r for %r with services %r' % (wanted_languages, video, services)) + logger.debug(u'Listing subtitles %r for %r with services %r' % (wanted_languages, video, services)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') for service_name in services: mod = __import__('services.' + service_name, globals=globals(), locals=locals(), fromlist=['Service'], level=-1) service = mod.Service if not service.check_validity(video, wanted_languages): continue task = ListTask(video, wanted_languages & service.languages, service_name, config) - logger.debug(u'Created task %r' % task) + logger.debug(u'Created task %r' % task) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') tasks.append(task) return tasks @@ -101,12 +102,12 @@ def create_download_tasks(subtitles_by_video, languages, multi): continue if not multi: task = DownloadTask(video, list(subtitles)) - logger.debug(u'Created task %r' % task) + logger.debug(u'Created task %r' % task) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') tasks.append(task) continue for _, by_language in groupby(subtitles, lambda s: languages.index(s.language)): task = DownloadTask(video, list(by_language)) - logger.debug(u'Created task %r' % task) + logger.debug(u'Created task %r' % task) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') tasks.append(task) return tasks @@ -125,7 +126,7 @@ def consume_task(task, services=None): """ if services is None: services = {} - logger.info(u'Consuming %r' % task) + logger.info(u'Consuming %r' % task) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') result = None if isinstance(task, ListTask): service = get_service(services, task.service, config=task.config) @@ -138,10 +139,10 @@ def consume_task(task, services=None): result = [subtitle] break except DownloadFailedError: - logger.warning(u'Could not download subtitle %r, trying next' % subtitle) + logger.warning(u'Could not download subtitle %r, trying next' % subtitle) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') continue if result is None: - logger.error(u'No subtitles could be downloaded for video %r' % task.video) + logger.error(u'No subtitles could be downloaded for video %r' % task.video) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return result @@ -159,7 +160,7 @@ def matching_confidence(video, subtitle): guess = guessit.guess_file_info(subtitle.release, 'autodetect') video_keywords = get_keywords(video.guess) subtitle_keywords = get_keywords(guess) | subtitle.keywords - logger.debug(u'Video keywords %r - Subtitle keywords %r' % (video_keywords, subtitle_keywords)) + logger.debug(u'Video keywords %r - Subtitle keywords %r' % (video_keywords, subtitle_keywords)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') replacement = {'keywords': len(video_keywords & subtitle_keywords)} if isinstance(video, Episode): replacement.update({'series': 0, 'season': 0, 'episode': 0}) @@ -182,11 +183,11 @@ def matching_confidence(video, subtitle): if 'year' in guess and guess['year'] == video.year: replacement['year'] = 1 else: - logger.debug(u'Not able to compute confidence for %r' % video) + logger.debug(u'Not able to compute confidence for %r' % video) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return 0.0 - logger.debug(u'Found %r' % replacement) + logger.debug(u'Found %r' % replacement) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') confidence = float(int(matching_format.format(**replacement), 2)) / float(int(best, 2)) - logger.info(u'Computed confidence %.4f for %r and %r' % (confidence, video, subtitle)) + logger.info(u'Computed confidence %.4f for %r and %r' % (confidence, video, subtitle)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return confidence @@ -271,6 +272,6 @@ def filter_services(services): mod = __import__('services.' + service_name, globals=globals(), locals=locals(), fromlist=['Service'], level=-1) service = mod.Service if service.required_features is not None and bs4.builder_registry.lookup(*service.required_features) is None: - logger.warning(u'Service %s not available: none of available features could be used. One of %r required' % (service_name, service.required_features)) + logger.warning(u'Service %s not available: none of available features could be used. One of %r required' % (service_name, service.required_features)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') filtered_services.remove(service_name) return filtered_services diff --git a/lib/subliminal/language.py b/lib/subliminal/language.py index 6403bcc0a562e8504348377572be37debe2f6f7f..baf724c363d66b98132ac5445790ed789c1d1e09 100644 --- a/lib/subliminal/language.py +++ b/lib/subliminal/language.py @@ -18,6 +18,7 @@ from .utils import to_unicode import re import logging +import sys logger = logging.getLogger("subliminal") @@ -846,12 +847,14 @@ class Language(object): try: self.country = Country(country, countries) except ValueError: - logger.warning(u'Country %s could not be identified' % country) + logger.warning(u'Country %s could not be identified' % country) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') if strict: raise # Language + Country format #TODO: Improve this part + if language is None: + language = 'und' if country is None: for regexp in [r.match(language) for r in self.with_country_regexps]: if regexp: @@ -859,7 +862,7 @@ class Language(object): try: self.country = Country(regexp.group(2), countries) except ValueError: - logger.warning(u'Country %s could not be identified' % country) + logger.warning(u'Country %s could not be identified' % country) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') if strict: raise break diff --git a/lib/subliminal/services/__init__.py b/lib/subliminal/services/__init__.py index c52dd5dc6ad6ff2d65b8dd8397496a1731be1276..3c24f2ee7e426211b28c8f7f0cb765793f41df5c 100644 --- a/lib/subliminal/services/__init__.py +++ b/lib/subliminal/services/__init__.py @@ -24,6 +24,7 @@ import os import requests import threading import zipfile +import sys __all__ = ['ServiceBase', 'ServiceConfig'] @@ -80,7 +81,7 @@ class ServiceBase(object): def init(self): """Initialize connection""" - logger.debug(u'Initializing %s' % self.__class__.__name__) + logger.debug(u'Initializing %s' % self.__class__.__name__) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') self.session = requests.session() self.session.headers.update({'User-Agent': self.user_agent}) @@ -104,7 +105,7 @@ class ServiceBase(object): def terminate(self): """Terminate connection""" - logger.debug(u'Terminating %s' % self.__class__.__name__) + logger.debug(u'Terminating %s' % self.__class__.__name__) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') def get_code(self, language): """Get the service code for a :class:`~subliminal.language.Language` @@ -136,7 +137,7 @@ class ServiceBase(object): return self.language_map[code] language = Language(code, strict=False) if language == Language('Undetermined'): - logger.warning(u'Code %s could not be identified as a language for %s' % (code, self.__class__.__name__)) + logger.warning(u'Code %s could not be identified as a language for %s' % (code, self.__class__.__name__)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return language def query(self, *args): @@ -176,10 +177,10 @@ class ServiceBase(object): """ languages = (languages & cls.languages) - language_set(['Undetermined']) if not languages: - logger.debug(u'No language available for service %s' % cls.__name__.lower()) + logger.debug(u'No language available for service %s' % cls.__name__.lower()) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return False if cls.require_video and not video.exists or not isinstance(video, tuple(cls.videos)): - logger.debug(u'%r is not valid for service %s' % (video, cls.__name__.lower())) + logger.debug(u'%r is not valid for service %s' % (video, cls.__name__.lower())) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return False return True @@ -190,17 +191,17 @@ class ServiceBase(object): :param string filepath: destination path """ - logger.info(u'Downloading %s in %s' % (url, filepath)) + logger.info(u'Downloading %s in %s' % (url, filepath)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') try: r = self.session.get(url, timeout = 10, headers = {'Referer': url, 'User-Agent': self.user_agent}) with open(filepath, 'wb') as f: f.write(r.content) except Exception as e: - logger.error(u'Download failed: %s' % e) + logger.error(u'Download failed: %s' % e) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') if os.path.exists(filepath): os.remove(filepath) raise DownloadFailedError(str(e)) - logger.debug(u'Download finished') + logger.debug(u'Download finished') if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') def download_zip_file(self, url, filepath): """Attempt to download a zip file and extract any subtitle file from it, if any. @@ -210,7 +211,7 @@ class ServiceBase(object): :param string filepath: destination path for the subtitle """ - logger.info(u'Downloading %s in %s' % (url, filepath)) + logger.info(u'Downloading %s in %s' % (url, filepath)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') try: zippath = filepath + '.zip' r = self.session.get(url, timeout = 10, headers = {'Referer': url, 'User-Agent': self.user_agent}) @@ -232,13 +233,13 @@ class ServiceBase(object): zipsub.close() os.remove(zippath) except Exception as e: - logger.error(u'Download %s failed: %s' % (url, e)) + logger.error(u'Download %s failed: %s' % (url, e)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') if os.path.exists(zippath): os.remove(zippath) if os.path.exists(filepath): os.remove(filepath) raise DownloadFailedError(str(e)) - logger.debug(u'Download finished') + logger.debug(u'Download finished') if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') class ServiceConfig(object): diff --git a/lib/subliminal/services/addic7ed.py b/lib/subliminal/services/addic7ed.py index 665c5708adcca009190532a770af7e22741755fb..bc1ee5c96ce02c6b0b1893cec506f4d757ba744b 100644 --- a/lib/subliminal/services/addic7ed.py +++ b/lib/subliminal/services/addic7ed.py @@ -27,6 +27,7 @@ from bs4 import BeautifulSoup import logging import os import re +import sys logger = logging.getLogger("subliminal") @@ -65,12 +66,12 @@ class Addic7ed(ServiceBase): def query(self, filepath, languages, keywords, series, season, episode): - logger.debug(u'Getting subtitles for %s season %d episode %d with languages %r' % (series, season, episode, languages)) + logger.debug(u'Getting subtitles for %s season %d episode %d with languages %r' % (series, season, episode, languages)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') self.init_cache() try: series_id = self.get_series_id(series.lower()) except KeyError: - logger.debug(u'Could not find series id for %s' % series) + logger.debug(u'Could not find series id for %s' % series) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] r = self.session.get('%s/show/%d&season=%d' % (self.server_url, series_id, season)) soup = BeautifulSoup(r.content, self.required_features) @@ -80,20 +81,20 @@ class Addic7ed(ServiceBase): if int(cells[0].text.strip()) != season or int(cells[1].text.strip()) != episode: continue if cells[6].text.strip(): - logger.debug(u'Skipping hearing impaired') + logger.debug(u'Skipping hearing impaired') if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') continue sub_status = cells[5].text.strip() if sub_status != 'Completed': - logger.debug(u'Wrong subtitle status %s' % sub_status) + logger.debug(u'Wrong subtitle status %s' % sub_status) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') continue sub_language = self.get_language(cells[3].text.strip()) if sub_language not in languages: - logger.debug(u'Language %r not in wanted languages %r' % (sub_language, languages)) + logger.debug(u'Language %r not in wanted languages %r' % (sub_language, languages)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') continue sub_keywords = split_keyword(cells[4].text.strip().lower()) #TODO: Maybe allow empty keywords here? (same in Subtitulos) if keywords and not keywords & sub_keywords: - logger.debug(u'None of subtitle keywords %r in %r' % (sub_keywords, keywords)) + logger.debug(u'None of subtitle keywords %r in %r' % (sub_keywords, keywords)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') continue sub_link = '%s/%s' % (self.server_url, cells[9].a['href']) sub_path = get_subtitle_path(filepath, sub_language, self.config.multi) @@ -102,7 +103,7 @@ class Addic7ed(ServiceBase): return subtitles def download(self, subtitle): - logger.info(u'Downloading %s in %s' % (subtitle.link, subtitle.path)) + logger.info(u'Downloading %s in %s' % (subtitle.link, subtitle.path)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') try: r = self.session.get(subtitle.link, headers={'Referer': subtitle.link, 'User-Agent': self.user_agent}) soup = BeautifulSoup(r.content, self.required_features) @@ -111,11 +112,11 @@ class Addic7ed(ServiceBase): with open(subtitle.path, 'wb') as f: f.write(r.content) except Exception as e: - logger.error(u'Download failed: %s' % e) + logger.error(u'Download failed: %s' % e) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') if os.path.exists(subtitle.path): os.remove(subtitle.path) raise DownloadFailedError(str(e)) - logger.debug(u'Download finished') + logger.debug(u'Download finished') if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return subtitle diff --git a/lib/subliminal/services/bierdopje.py b/lib/subliminal/services/bierdopje.py index 8642afb89fba2331895aac6d292968a207070228..44c2829fb9ef36a8533e2d72ba443aba34f17bf7 100644 --- a/lib/subliminal/services/bierdopje.py +++ b/lib/subliminal/services/bierdopje.py @@ -29,7 +29,7 @@ try: import cPickle as pickle except ImportError: import pickle - +import sys logger = logging.getLogger("subliminal") @@ -48,16 +48,16 @@ class BierDopje(ServiceBase): def get_show_id(self, series): r = self.session.get('%sGetShowByName/%s' % (self.server_url, urllib.quote(series.lower()))) if r.status_code != 200: - logger.error(u'Request %s returned status code %d' % (r.url, r.status_code)) + logger.error(u'Request %s returned status code %d' % (r.url, r.status_code)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return None soup = BeautifulSoup(r.content, self.required_features) if soup.status.contents[0] == 'false': - logger.debug(u'Could not find show %s' % series) + logger.debug(u'Could not find show %s' % series) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return None return int(soup.showid.contents[0]) def load_cache(self): - logger.debug(u'Loading showids from cache...') + logger.debug(u'Loading showids from cache...') if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') with self.lock: with open(self.showids_cache, 'r') as f: self.showids = pickle.load(f) @@ -78,14 +78,14 @@ class BierDopje(ServiceBase): raise ServiceError('One or more parameter missing') subtitles = [] for language in languages: - logger.debug(u'Getting subtitles for %s %d season %d episode %d with language %s' % (request_source, request_id, season, episode, language.alpha2)) + logger.debug(u'Getting subtitles for %s %d season %d episode %d with language %s' % (request_source, request_id, season, episode, language.alpha2)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') r = self.session.get('%sGetAllSubsFor/%s/%s/%s/%s/%s' % (self.server_url, request_id, season, episode, language.alpha2, request_is_tvdbid)) if r.status_code != 200: - logger.error(u'Request %s returned status code %d' % (r.url, r.status_code)) + logger.error(u'Request %s returned status code %d' % (r.url, r.status_code)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] soup = BeautifulSoup(r.content, self.required_features) if soup.status.contents[0] == 'false': - logger.debug(u'Could not find subtitles for %s %d season %d episode %d with language %s' % (request_source, request_id, season, episode, language.alpha2)) + logger.debug(u'Could not find subtitles for %s %d season %d episode %d with language %s' % (request_source, request_id, season, episode, language.alpha2)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') continue path = get_subtitle_path(filepath, language, self.config.multi) for result in soup.results('result'): diff --git a/lib/subliminal/services/itasa.py b/lib/subliminal/services/itasa.py index f726a156e670ac369a860bc003d31ce52ead8fb6..685da34e347e017f89078d47a99f1a4c2e09a642 100644 --- a/lib/subliminal/services/itasa.py +++ b/lib/subliminal/services/itasa.py @@ -30,6 +30,7 @@ import requests import zipfile import StringIO import guessit +import sys from sickbeard.common import Quality @@ -117,7 +118,7 @@ class Itasa(ServiceBase): break if not season_link: - logger.debug(u'Could not find season %s for series %s' % (series, str(season))) + logger.debug(u'Could not find season %s for series %s' % (series, str(season))) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return None r = self.session.get(season_link) @@ -133,7 +134,7 @@ class Itasa(ServiceBase): #If we want SDTV we are just on the right page so quality link will be None if not quality == Quality.SDTV and not quality_link: - logger.debug(u'Could not find a subtitle with required quality for series %s season %s' % (series, str(season))) + logger.debug(u'Could not find a subtitle with required quality for series %s season %s' % (series, str(season))) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return None all_episodes = soup.find('div', attrs = {'id' : 'remositoryfilelisting'}) @@ -152,18 +153,18 @@ class Itasa(ServiceBase): def query(self, filepath, languages, keywords, series, season, episode): - logger.debug(u'Getting subtitles for %s season %d episode %d with languages %r' % (series, season, episode, languages)) + logger.debug(u'Getting subtitles for %s season %d episode %d with languages %r' % (series, season, episode, languages)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') self.init_cache() try: series = series.lower().replace('(','').replace(')','') series_id = self.get_series_id(series) except KeyError: - logger.debug(u'Could not find series id for %s' % series) + logger.debug(u'Could not find series id for %s' % series) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] episode_id = self.get_episode_id(series, series_id, season, episode, Quality.nameQuality(filepath)) if not episode_id: - logger.debug(u'Could not find subtitle for series %s' % series) + logger.debug(u'Could not find subtitle for series %s' % series) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] r = self.session.get(self.server_url + 'index.php?option=com_remository&Itemid=6&func=fileinfo&id=' + episode_id) @@ -178,7 +179,7 @@ class Itasa(ServiceBase): def download(self, subtitle): - logger.info(u'Downloading %s in %s' % (subtitle.link, subtitle.path)) + logger.info(u'Downloading %s in %s' % (subtitle.link, subtitle.path)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') try: r = self.session.get(subtitle.link, headers={'Referer': self.server_url, 'User-Agent': self.user_agent}) zipcontent = StringIO.StringIO(r.content) @@ -211,6 +212,6 @@ class Itasa(ServiceBase): os.remove(subtitle.path) raise DownloadFailedError(str(e)) - logger.debug(u'Download finished') + logger.debug(u'Download finished') if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') Service = Itasa \ No newline at end of file diff --git a/lib/subliminal/services/opensubtitles.py b/lib/subliminal/services/opensubtitles.py index cc75248ed8bacc65931ba653a15c891aa9481207..245b467b14a1de04e78b1ce2dd2b29b13a93f33f 100644 --- a/lib/subliminal/services/opensubtitles.py +++ b/lib/subliminal/services/opensubtitles.py @@ -25,7 +25,7 @@ import gzip import logging import os.path import xmlrpclib - +import sys logger = logging.getLogger("subliminal") @@ -115,10 +115,10 @@ class OpenSubtitles(ServiceBase): raise ServiceError('One or more parameter missing') for search in searches: search['sublanguageid'] = ','.join(self.get_code(l) for l in languages) - logger.debug(u'Getting subtitles %r with token %s' % (searches, self.token)) + logger.debug(u'Getting subtitles %r with token %s' % (searches, self.token)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') results = self.server.SearchSubtitles(self.token, searches) if not results['data']: - logger.debug(u'Could not find subtitles for %r with token %s' % (searches, self.token)) + logger.debug(u'Could not find subtitles for %r with token %s' % (searches, self.token)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] subtitles = [] for result in results['data']: diff --git a/lib/subliminal/services/podnapisi.py b/lib/subliminal/services/podnapisi.py index be02dd51d5b13dd9dd1b3e67718cff2026da8d61..d80e35d21e7665a367c2bd70b3bd7c3ad29ff57b 100644 --- a/lib/subliminal/services/podnapisi.py +++ b/lib/subliminal/services/podnapisi.py @@ -24,6 +24,7 @@ from ..videos import Episode, Movie from hashlib import md5, sha256 import logging import xmlrpclib +import sys logger = logging.getLogger("subliminal") @@ -69,10 +70,10 @@ class Podnapisi(ServiceBase): def query(self, filepath, languages, moviehash): results = self.server.search(self.token, [moviehash]) if results['status'] != 200: - logger.error('Search failed with error code %d' % results['status']) + logger.error('Search failed with error code %d' % results['status']) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] if not results['results'] or not results['results'][moviehash]['subtitles']: - logger.debug(u'Could not find subtitles for %r with token %s' % (moviehash, self.token)) + logger.debug(u'Could not find subtitles for %r with token %s' % (moviehash, self.token)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] subtitles = [] for result in results['results'][moviehash]['subtitles']: diff --git a/lib/subliminal/services/podnapisiweb.py b/lib/subliminal/services/podnapisiweb.py index 57397b751e94466a921e7ca7ae38d2135d084bc0..0be0152965c842ee7bb543ec60d85db18291c8a3 100644 --- a/lib/subliminal/services/podnapisiweb.py +++ b/lib/subliminal/services/podnapisiweb.py @@ -26,6 +26,7 @@ import guessit import logging import re from subliminal.subtitles import get_subtitle_path +import sys logger = logging.getLogger("subliminal") @@ -93,13 +94,13 @@ class PodnapisiWeb(ServiceBase): params['sR'] = keywords r = self.session.get(self.server_url + '/ppodnapisi/search', params=params) if r.status_code != 200: - logger.error(u'Request %s returned status code %d' % (r.url, r.status_code)) + logger.error(u'Request %s returned status code %d' % (r.url, r.status_code)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] subtitles = [] soup = BeautifulSoup(r.content, self.required_features) for sub in soup('subtitle'): if 'n' in sub.flags: - logger.debug(u'Skipping hearing impaired') + logger.debug(u'Skipping hearing impaired') if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') continue language = self.get_language(sub.languageId.text) confidence = float(sub.rating.text) / 5.0 diff --git a/lib/subliminal/services/subscenter.py b/lib/subliminal/services/subscenter.py index 3646c50b73dae3cc21b0c70863ef9a339b5ffa19..e20cccaa3302b1145250271110405a7f480b18f5 100644 --- a/lib/subliminal/services/subscenter.py +++ b/lib/subliminal/services/subscenter.py @@ -24,6 +24,7 @@ from ..language import language_set from ..subtitles import get_subtitle_path, ResultSubtitle from ..videos import Episode, Movie from ..utils import to_unicode, get_keywords +import sys logger = logging.getLogger("subliminal") @@ -57,7 +58,7 @@ class Subscenter(ServiceBase): episode, title) def query(self, filepath, languages=None, keywords=None, series=None, season=None, episode=None, title=None): - logger.debug(u'Getting subtitles for %s season %d episode %d with languages %r' % (series, season, episode, languages)) + logger.debug(u'Getting subtitles for %s season %d episode %d with languages %r' % (series, season, episode, languages)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') # Converts the title to Subscenter format by replacing whitespaces and removing specific chars. if series and season and episode: # Search for a TV show. @@ -72,7 +73,7 @@ class Subscenter(ServiceBase): url = self.server_url + 'cinemast/data/movie/sb/' + slugified_title + '/' else: raise ServiceError('One or more parameters are missing') - logger.debug('Searching subtitles %r', {'title': title, 'season': season, 'episode': episode}) + logger.debug('Searching subtitles %r', {'title': title, 'season': season, 'episode': episode}) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') response = self.session.get(url) if response.status_code != 200: raise ServiceError('Request failed with status code %d' % response.status_code) diff --git a/lib/subliminal/services/subswiki.py b/lib/subliminal/services/subswiki.py index 9f9a341413b91bdc24f2803743f6b94f095f1662..4e8039fe4c4c89ad8404bb4ac73472709f2e1fe5 100644 --- a/lib/subliminal/services/subswiki.py +++ b/lib/subliminal/services/subswiki.py @@ -24,6 +24,7 @@ from ..videos import Episode, Movie from bs4 import BeautifulSoup import logging import urllib +import sys logger = logging.getLogger("subliminal") @@ -55,41 +56,41 @@ class SubsWiki(ServiceBase): request_series = series.lower().replace(' ', '_') if isinstance(request_series, unicode): request_series = request_series.encode('utf-8') - logger.debug(u'Getting subtitles for %s season %d episode %d with languages %r' % (series, season, episode, languages)) + logger.debug(u'Getting subtitles for %s season %d episode %d with languages %r' % (series, season, episode, languages)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') r = self.session.get('%s/serie/%s/%s/%s/' % (self.server_url, urllib.quote(request_series), season, episode)) if r.status_code == 404: - logger.debug(u'Could not find subtitles for %s season %d episode %d with languages %r' % (series, season, episode, languages)) + logger.debug(u'Could not find subtitles for %s season %d episode %d with languages %r' % (series, season, episode, languages)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] elif movie and year: request_movie = movie.title().replace(' ', '_') if isinstance(request_movie, unicode): request_movie = request_movie.encode('utf-8') - logger.debug(u'Getting subtitles for %s (%d) with languages %r' % (movie, year, languages)) + logger.debug(u'Getting subtitles for %s (%d) with languages %r' % (movie, year, languages)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') r = self.session.get('%s/film/%s_(%d)' % (self.server_url, urllib.quote(request_movie), year)) if r.status_code == 404: - logger.debug(u'Could not find subtitles for %s (%d) with languages %r' % (movie, year, languages)) + logger.debug(u'Could not find subtitles for %s (%d) with languages %r' % (movie, year, languages)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] else: raise ServiceError('One or more parameter missing') if r.status_code != 200: - logger.error(u'Request %s returned status code %d' % (r.url, r.status_code)) + logger.error(u'Request %s returned status code %d' % (r.url, r.status_code)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] soup = BeautifulSoup(r.content, self.required_features) subtitles = [] for sub in soup('td', {'class': 'NewsTitle'}): sub_keywords = split_keyword(sub.b.string.lower()) if keywords and not keywords & sub_keywords: - logger.debug(u'None of subtitle keywords %r in %r' % (sub_keywords, keywords)) + logger.debug(u'None of subtitle keywords %r in %r' % (sub_keywords, keywords)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') continue for html_language in sub.parent.parent.find_all('td', {'class': 'language'}): language = self.get_language(html_language.string.strip()) if language not in languages: - logger.debug(u'Language %r not in wanted languages %r' % (language, languages)) + logger.debug(u'Language %r not in wanted languages %r' % (language, languages)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') continue html_status = html_language.find_next_sibling('td') status = html_status.strong.string.strip() if status != 'Completado': - logger.debug(u'Wrong subtitle status %s' % status) + logger.debug(u'Wrong subtitle status %s' % status) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') continue path = get_subtitle_path(filepath, language, self.config.multi) subtitle = ResultSubtitle(path, language, self.__class__.__name__.lower(), '%s%s' % (self.server_url, html_status.find_next('td').find('a')['href'])) diff --git a/lib/subliminal/services/subtitulos.py b/lib/subliminal/services/subtitulos.py index 6dd085a3b4eb41ad1056f8f8182b21806ca47e54..9beba36fb0af8cb6a287ba656d8306d22d53cc08 100644 --- a/lib/subliminal/services/subtitulos.py +++ b/lib/subliminal/services/subtitulos.py @@ -25,6 +25,7 @@ import logging import re import unicodedata import urllib +import sys logger = logging.getLogger("subliminal") @@ -55,30 +56,30 @@ class Subtitulos(ServiceBase): request_series = series.lower().replace(' ', '-').replace('&', '@').replace('(','').replace(')','') if isinstance(request_series, unicode): request_series = unicodedata.normalize('NFKD', request_series).encode('ascii', 'ignore') - logger.debug(u'Getting subtitles for %s season %d episode %d with languages %r' % (series, season, episode, languages)) + logger.debug(u'Getting subtitles for %s season %d episode %d with languages %r' % (series, season, episode, languages)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') r = self.session.get('%s/%s/%sx%.2d' % (self.server_url, urllib.quote(request_series), season, episode)) if r.status_code == 404: - logger.debug(u'Could not find subtitles for %s season %d episode %d with languages %r' % (series, season, episode, languages)) + logger.debug(u'Could not find subtitles for %s season %d episode %d with languages %r' % (series, season, episode, languages)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] if r.status_code != 200: - logger.error(u'Request %s returned status code %d' % (r.url, r.status_code)) + logger.error(u'Request %s returned status code %d' % (r.url, r.status_code)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] soup = BeautifulSoup(r.content, self.required_features) subtitles = [] for sub in soup('div', {'id': 'version'}): sub_keywords = split_keyword(self.release_pattern.search(sub.find('p', {'class': 'title-sub'}).contents[1]).group(1).lower()) if keywords and not keywords & sub_keywords: - logger.debug(u'None of subtitle keywords %r in %r' % (sub_keywords, keywords)) + logger.debug(u'None of subtitle keywords %r in %r' % (sub_keywords, keywords)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') continue for html_language in sub.findAllNext('ul', {'class': 'sslist'}): language = self.get_language(html_language.findNext('li', {'class': 'li-idioma'}).find('strong').contents[0].string.strip()) if language not in languages: - logger.debug(u'Language %r not in wanted languages %r' % (language, languages)) + logger.debug(u'Language %r not in wanted languages %r' % (language, languages)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') continue html_status = html_language.findNext('li', {'class': 'li-estado green'}) status = html_status.contents[0].string.strip() if status != 'Completado': - logger.debug(u'Wrong subtitle status %s' % status) + logger.debug(u'Wrong subtitle status %s' % status) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') continue path = get_subtitle_path(filepath, language, self.config.multi) subtitle = ResultSubtitle(path, language, self.__class__.__name__.lower(), html_status.findNext('span', {'class': 'descargar green'}).find('a')['href'], diff --git a/lib/subliminal/services/thesubdb.py b/lib/subliminal/services/thesubdb.py index 93787ad62e203ed3aa0c5c9e7dc0bfe89fb1d880..754fc3f774ff136741a653de7c86b2ce4607c513 100644 --- a/lib/subliminal/services/thesubdb.py +++ b/lib/subliminal/services/thesubdb.py @@ -20,6 +20,7 @@ from ..language import language_set, Language from ..subtitles import get_subtitle_path, ResultSubtitle from ..videos import Episode, Movie, UnknownVideo import logging +import sys logger = logging.getLogger("subliminal") @@ -43,10 +44,10 @@ class TheSubDB(ServiceBase): def query(self, filepath, moviehash, languages): r = self.session.get(self.server_url, params={'action': 'search', 'hash': moviehash}) if r.status_code == 404: - logger.debug(u'Could not find subtitles for hash %s' % moviehash) + logger.debug(u'Could not find subtitles for hash %s' % moviehash) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] if r.status_code != 200: - logger.error(u'Request %s returned status code %d' % (r.url, r.status_code)) + logger.error(u'Request %s returned status code %d' % (r.url, r.status_code)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] available_languages = language_set(r.content.split(',')) #this is needed becase for theSubDB pt languages is Portoguese Brazil and not Portoguese# @@ -55,7 +56,7 @@ class TheSubDB(ServiceBase): available_languages = available_languages - language_set(['pt']) | language_set(['pb']) languages &= available_languages if not languages: - logger.debug(u'Could not find subtitles for hash %s with languages %r (only %r available)' % (moviehash, languages, available_languages)) + logger.debug(u'Could not find subtitles for hash %s with languages %r (only %r available)' % (moviehash, languages, available_languages)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] subtitles = [] for language in languages: diff --git a/lib/subliminal/services/tvsubtitles.py b/lib/subliminal/services/tvsubtitles.py index 5d056aaa200508d46fb1078ccd7efde9da4a7d19..4e932c746b53df6840b9c010978bb1a427406fea 100644 --- a/lib/subliminal/services/tvsubtitles.py +++ b/lib/subliminal/services/tvsubtitles.py @@ -24,6 +24,7 @@ from ..videos import Episode from bs4 import BeautifulSoup import logging import re +import sys logger = logging.getLogger("subliminal") @@ -33,7 +34,7 @@ def match(pattern, string): try: return re.search(pattern, string).group(1) except AttributeError: - logger.debug(u'Could not match %r on %r' % (pattern, string)) + logger.debug(u'Could not match %r on %r' % (pattern, string)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return None @@ -116,13 +117,13 @@ class TvSubtitles(ServiceBase): return self.query(video.path or video.release, languages, get_keywords(video.guess), video.series, video.season, video.episode) def query(self, filepath, languages, keywords, series, season, episode): - logger.debug(u'Getting subtitles for %s season %d episode %d with languages %r' % (series, season, episode, languages)) + logger.debug(u'Getting subtitles for %s season %d episode %d with languages %r' % (series, season, episode, languages)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') self.init_cache() sid = self.get_likely_series_id(series.lower()) try: ep_id = self.get_episode_id(sid, season, episode) except KeyError: - logger.debug(u'Could not find episode id for %s season %d episode %d' % (series, season, episode)) + logger.debug(u'Could not find episode id for %s season %d episode %d' % (series, season, episode)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] subids = self.get_sub_ids(ep_id) # filter the subtitles with our queried languages diff --git a/lib/subliminal/services/usub.py b/lib/subliminal/services/usub.py index d7d076775f701140f11d6f3073c9b8d45714468d..593625f7aa38143f7d40881009bc932d32279121 100644 --- a/lib/subliminal/services/usub.py +++ b/lib/subliminal/services/usub.py @@ -24,6 +24,7 @@ from ..videos import Episode from bs4 import BeautifulSoup import logging import urllib +import sys logger = logging.getLogger("subliminal") @@ -46,11 +47,11 @@ class Usub(ServiceBase): request_series = series.lower().replace(' ', '-') if isinstance(request_series, unicode): request_series = request_series.encode('utf-8') - logger.debug(u'Getting subtitles for %s season %d episode %d with language %r' % (series, season, episode, languages)) + logger.debug(u'Getting subtitles for %s season %d episode %d with language %r' % (series, season, episode, languages)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') r = self.session.get('%s/%s/saison_%s' % (self.server_url, urllib.quote(request_series),season)) if r.status_code == 404: print "Error 404" - logger.debug(u'Could not find subtitles for %s' % (series)) + logger.debug(u'Could not find subtitles for %s' % (series)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] else: print "One or more parameter missing" @@ -59,7 +60,7 @@ class Usub(ServiceBase): ## Check if we didn't got an big and nasty http error if r.status_code != 200: print u'Request %s returned status code %d' % (r.url, r.status_code) - logger.error(u'Request %s returned status code %d' % (r.url, r.status_code)) + logger.error(u'Request %s returned status code %d' % (r.url, r.status_code)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] ## Editing episode informations to be able to use it with our search diff --git a/lib/subliminal/videos.py b/lib/subliminal/videos.py index 9d533b2bed5cbdc699a837efa166688e4561d34c..b348964fc284cbfc6216c9be452c018b1fc6e09c 100644 --- a/lib/subliminal/videos.py +++ b/lib/subliminal/videos.py @@ -25,6 +25,7 @@ import logging import mimetypes import os import struct +import sys from sickbeard import encodingKludge as ek import sickbeard @@ -53,14 +54,15 @@ class Video(object): """ def __init__(self, path, guess, imdbid=None): - self.release = path self.guess = guess self.imdbid = imdbid self._path = None self.hashes = {} - - if isinstance(path, unicode): - path = path.encode('utf-8') + + if isinstance(path, str): + path = unicode(path.encode('utf-8')) + + self.release = path if os.path.exists(path): self._path = path @@ -133,9 +135,9 @@ class Video(object): video_infos = None try: video_infos = enzyme.parse(self.path) - logger.debug(u'Succeeded parsing %s with enzyme: %r' % (self.path, video_infos)) + logger.debug(u'Succeeded parsing %s with enzyme: %r' % (self.path, video_infos)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') except: - logger.debug(u'Failed parsing %s with enzyme' % self.path) + logger.debug(u'Failed parsing %s with enzyme' % self.path) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') if isinstance(video_infos, enzyme.core.AVContainer): results.extend([subtitles.EmbeddedSubtitle.from_enzyme(self.path, s) for s in video_infos.subtitles]) # cannot use glob here because it chokes if there are any square @@ -225,19 +227,20 @@ def scan(entry, max_depth=3, scan_filter=None, depth=0): :rtype: list of (:class:`Video`, [:class:`~subliminal.subtitles.Subtitle`]) """ - if isinstance(entry, unicode): - entry = entry.encode('utf-8') + + if isinstance(entry, str): + entry = unicode(entry.encode('utf-8')) if depth > max_depth and max_depth != 0: # we do not want to search the whole file system except if max_depth = 0 return [] if os.path.isdir(entry): # a dir? recurse - logger.debug(u'Scanning directory %s with depth %d/%d' % (entry, depth, max_depth)) + logger.debug(u'Scanning directory %s with depth %d/%d' % (entry, depth, max_depth)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') result = [] for e in os.listdir(entry): result.extend(scan(os.path.join(entry, e), max_depth, scan_filter, depth + 1)) return result if os.path.isfile(entry) or depth == 0: - logger.debug(u'Scanning file %s with depth %d/%d' % (entry, depth, max_depth)) + logger.debug(u'Scanning file %s with depth %d/%d' % (entry, depth, max_depth)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') if depth != 0: # trust the user: only check for valid format if recursing if mimetypes.guess_type(entry)[0] not in MIMETYPES and os.path.splitext(entry)[1] not in EXTENSIONS: return [] @@ -245,7 +248,7 @@ def scan(entry, max_depth=3, scan_filter=None, depth=0): return [] video = Video.from_path(entry) return [(video, video.scan())] - logger.warning(u'Scanning entry %s failed with depth %d/%d' % (entry, depth, max_depth)) + logger.warning(u'Scanning entry %s failed with depth %d/%d' % (entry, depth, max_depth)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return [] # anything else @@ -276,7 +279,7 @@ def hash_opensubtitles(path): filehash += l_value filehash = filehash & 0xFFFFFFFFFFFFFFFF returnedhash = '%016x' % filehash - logger.debug(u'Computed OpenSubtitle hash %s for %s' % (returnedhash, path)) + logger.debug(u'Computed OpenSubtitle hash %s for %s' % (returnedhash, path)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return returnedhash @@ -296,5 +299,5 @@ def hash_thesubdb(path): f.seek(-readsize, os.SEEK_END) data += f.read(readsize) returnedhash = hashlib.md5(data).hexdigest() - logger.debug(u'Computed TheSubDB hash %s for %s' % (returnedhash, path)) + logger.debug(u'Computed TheSubDB hash %s for %s' % (returnedhash, path)) if sys.platform != 'win32' else logger.debug('Log line suppressed on windows') return returnedhash diff --git a/lib/trakt/trakt.py b/lib/trakt/trakt.py index 4fd9d37e6848df14227ed083c5520e08ca3639e8..d2f615a6cf2bc01a85e820ac5b0aafdc36482997 100644 --- a/lib/trakt/trakt.py +++ b/lib/trakt/trakt.py @@ -29,7 +29,7 @@ class TraktAPI(): data=json.dumps(data), timeout=self.timeout, verify=self.verify) resp.raise_for_status() resp = resp.json() - except (requests.HTTPError, requests.ConnectionError) as e: + except requests.RequestException as e: code = getattr(e.response, 'status_code', None) if not code: # This is pretty much a fatal error if there is no status_code @@ -68,7 +68,7 @@ class TraktAPI(): # convert response to json resp = resp.json() - except (requests.HTTPError, requests.ConnectionError) as e: + except requests.RequestException as e: code = getattr(e.response, 'status_code', None) if not code: # This is pretty much a fatal error if there is no status_code diff --git a/lib/unrar2/rar_exceptions.py b/lib/unrar2/rar_exceptions.py index d90d1c8dbd9b4c465cbd4bb5d457d19b9094c44b..4ed3ac237b26aec25e4e29bb3b3d3749d6298536 100644 --- a/lib/unrar2/rar_exceptions.py +++ b/lib/unrar2/rar_exceptions.py @@ -28,3 +28,7 @@ class InvalidRARArchive(Exception): pass class FileOpenError(Exception): pass class IncorrectRARPassword(Exception): pass class InvalidRARArchiveUsage(Exception): pass +class FatalRARError(Exception): pass +class CRCRARError(Exception): pass +class NoFileToExtract(Exception): pass +class GenericRARError(Exception): pass diff --git a/lib/unrar2/unix.py b/lib/unrar2/unix.py index 12cced4859c83e95a14133b99f79041b102dd2fe..e39e5ad3ae4c489db087f80783aaea686f2213f5 100644 --- a/lib/unrar2/unix.py +++ b/lib/unrar2/unix.py @@ -63,9 +63,12 @@ class RarFileImplementation(object): global rar_executable_version self.password = password + proc = self.call('v', []) + stdoutdata, stderrdata = proc.communicate() - stdoutdata, stderrdata = self.call('v', []).communicate() - + # Use unrar return code if available + self._check_returncode(proc.returncode) + for line in stderrdata.splitlines(): if line.strip().startswith("Cannot open"): raise FileOpenError @@ -123,7 +126,11 @@ class RarFileImplementation(object): def infoiter(self): command = "v" if rar_executable_version == 4 else "l" - stdoutdata, stderrdata = self.call(command, ['c-']).communicate() + proc = self.call(command, ['c-']) + stdoutdata, stderrdata = proc.communicate() + + # Use unrar return code if available + self._check_returncode(proc.returncode) for line in stderrdata.splitlines(): if line.strip().startswith("Cannot open"): @@ -135,7 +142,7 @@ class RarFileImplementation(object): while not line.startswith('-----------'): if line.strip().endswith('is not RAR archive'): raise InvalidRARArchive - if line.startswith("CRC failed") or line.startswith("Checksum error"): + if line.startswith("CRC failed") or line.startswith("Checksum error") or line.startswith("checksum error"): raise IncorrectRARPassword line = source.next() line = source.next() @@ -210,9 +217,46 @@ class RarFileImplementation(object): names.append(path) proc = self.call(command, options, names) stdoutdata, stderrdata = proc.communicate() - if stderrdata.find("CRC failed")>=0 or stderrdata.find("Checksum error")>=0: - raise IncorrectRARPassword - return res + + # Use unrar return code if available + self._check_returncode(proc.returncode) + + if stderrdata.find("CRC failed")>=0 or stderrdata.find("Checksum error")>=0 or stderrdata.find("checksum error")>=0: + raise CRCRARError + if stderrdata.find("No files to extract")>=0: + raise NoFileToExtract + if stderrdata.find("Bad archive")>=0: + raise FatalRARError + + return res + + def _check_returncode(self, returncode): + # RAR exit code from unrarsrc-5.2.1.tar.gz/errhnd.hpp + RARX_SUCCESS = 0 + RARX_WARNING = 1 + RARX_FATAL = 2 + RARX_CRC = 3 + RARX_LOCK = 4 + RARX_WRITE = 5 + RARX_OPEN = 6 + RARX_USERERROR = 7 + RARX_MEMORY = 8 + RARX_CREATE = 9 + RARX_NOFILES = 10 + RARX_BADPWD = 11 + RARX_USERBREAK = 255 + + if returncode != RARX_SUCCESS: + if returncode == RARX_FATAL: + raise FatalRARError + elif returncode == RARX_CRC: + raise CRCRARError + elif returncode == RARX_BADPWD: + raise IncorrectRARPassword + elif returncode == RARX_NOFILES: + raise NoFileToExtract + else: + raise GenericRARError def destruct(self): pass diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py index 1963036ce0473a05b9f33618395e2743e48017df..9ca4047022bd7dbaed0924d9f5fd84610ca78320 100755 --- a/sickbeard/__init__.py +++ b/sickbeard/__init__.py @@ -24,6 +24,7 @@ import socket import os import re import os.path +import shutil from threading import Lock import sys @@ -34,7 +35,7 @@ from sickbeard import providers, metadata, config, webserveInit from sickbeard.providers.generic import GenericProvider from providers import ezrss, btn, newznab, womble, thepiratebay, oldpiratebay, torrentleech, kat, iptorrents, \ omgwtfnzbs, scc, hdtorrents, torrentday, hdbits, hounddawgs, nextgen, speedcd, nyaatorrents, fanzub, torrentbytes, animezb, \ - freshontv, bitsoup, t411, tokyotoshokan + freshontv, bitsoup, t411, tokyotoshokan, shazbat, rarbg, alpharatio, tntvillage from sickbeard.config import CheckSection, check_setting_int, check_setting_str, check_setting_float, ConfigMigrator, \ naming_ep_type from sickbeard import searchBacklog, showUpdater, versionChecker, properFinder, autoPostProcesser, \ @@ -49,9 +50,13 @@ from indexers.indexer_exceptions import indexer_shownotfound, indexer_showincomp indexer_episodenotfound, indexer_attributenotfound, indexer_seasonnotfound, indexer_userabort, indexerExcepts from sickbeard.common import SD, SKIPPED, NAMING_REPEAT from sickbeard.databases import mainDB, cache_db, failed_db +from sickbeard.helpers import ex from lib.configobj import ConfigObj +from lib import requests +requests.packages.urllib3.disable_warnings() + PID = None CFG = None @@ -221,6 +226,7 @@ UPDATE_FREQUENCY = None DAILYSEARCH_STARTUP = False BACKLOG_FREQUENCY = None BACKLOG_STARTUP = False +SHOWUPDATE_HOUR = 3 DEFAULT_AUTOPOSTPROCESSER_FREQUENCY = 10 DEFAULT_DAILYSEARCH_FREQUENCY = 40 @@ -241,6 +247,7 @@ AIRDATE_EPISODES = False PROCESS_AUTOMATICALLY = False KEEP_PROCESSED_DIR = False PROCESS_METHOD = None +DELRARCONTENTS = False MOVE_ASSOCIATED_FILES = False POSTPONE_IF_SYNC_FILES = True NFO_RENAME = True @@ -288,6 +295,7 @@ TORRENT_LABEL = '' TORRENT_LABEL_ANIME = '' TORRENT_VERIFY_CERT = False TORRENT_RPCURL = 'transmission' +TORRENT_AUTH_TYPE = 'none' USE_KODI = False KODI_ALWAYS_ON = True @@ -404,7 +412,7 @@ TRAKT_USE_RECOMMENDED = False TRAKT_SYNC = False TRAKT_DEFAULT_INDEXER = None TRAKT_DISABLE_SSL_VERIFY = False -TRAKT_TIMEOUT = 30 +TRAKT_TIMEOUT = 60 USE_PYTIVO = False PYTIVO_NOTIFY_ONSNATCH = False @@ -482,6 +490,7 @@ EXTRA_SCRIPTS = [] IGNORE_WORDS = "german,french,core2hd,dutch,swedish,reenc,MrLss" REQUIRE_WORDS = "" +SYNC_FILES = "!sync,lftp-pget-status,part,bts" CALENDAR_UNPROTECTED = False @@ -504,7 +513,7 @@ def initialize(consoleLogging=True): HANDLE_REVERSE_PROXY, USE_NZBS, USE_TORRENTS, NZB_METHOD, NZB_DIR, DOWNLOAD_PROPERS, RANDOMIZE_PROVIDERS, CHECK_PROPERS_INTERVAL, ALLOW_HIGH_PRIORITY, TORRENT_METHOD, \ SAB_USERNAME, SAB_PASSWORD, SAB_APIKEY, SAB_CATEGORY, SAB_CATEGORY_ANIME, SAB_HOST, \ NZBGET_USERNAME, NZBGET_PASSWORD, NZBGET_CATEGORY, NZBGET_CATEGORY_ANIME, NZBGET_PRIORITY, NZBGET_HOST, NZBGET_USE_HTTPS, backlogSearchScheduler, \ - TORRENT_USERNAME, TORRENT_PASSWORD, TORRENT_HOST, TORRENT_PATH, TORRENT_SEED_TIME, TORRENT_PAUSED, TORRENT_HIGH_BANDWIDTH, TORRENT_LABEL, TORRENT_LABEL_ANIME, TORRENT_VERIFY_CERT, TORRENT_RPCURL, \ + TORRENT_USERNAME, TORRENT_PASSWORD, TORRENT_HOST, TORRENT_PATH, TORRENT_SEED_TIME, TORRENT_PAUSED, TORRENT_HIGH_BANDWIDTH, TORRENT_LABEL, TORRENT_LABEL_ANIME, TORRENT_VERIFY_CERT, TORRENT_RPCURL, TORRENT_AUTH_TYPE, \ USE_KODI, KODI_ALWAYS_ON, KODI_NOTIFY_ONSNATCH, KODI_NOTIFY_ONDOWNLOAD, KODI_NOTIFY_ONSUBTITLEDOWNLOAD, KODI_UPDATE_FULL, KODI_UPDATE_ONLYFIRST, \ KODI_UPDATE_LIBRARY, KODI_HOST, KODI_USERNAME, KODI_PASSWORD, BACKLOG_FREQUENCY, \ USE_TRAKT, TRAKT_USERNAME, TRAKT_PASSWORD, TRAKT_REMOVE_WATCHLIST, TRAKT_USE_WATCHLIST, TRAKT_METHOD_ADD, TRAKT_START_PAUSED, traktCheckerScheduler, TRAKT_USE_RECOMMENDED, TRAKT_SYNC, TRAKT_DEFAULT_INDEXER, TRAKT_REMOVE_SERIESLIST, TRAKT_DISABLE_SSL_VERIFY, TRAKT_TIMEOUT, \ @@ -520,7 +529,7 @@ def initialize(consoleLogging=True): USE_PUSHALOT, PUSHALOT_NOTIFY_ONSNATCH, PUSHALOT_NOTIFY_ONDOWNLOAD, PUSHALOT_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHALOT_AUTHORIZATIONTOKEN, \ USE_PUSHBULLET, PUSHBULLET_NOTIFY_ONSNATCH, PUSHBULLET_NOTIFY_ONDOWNLOAD, PUSHBULLET_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHBULLET_API, PUSHBULLET_DEVICE, \ versionCheckScheduler, VERSION_NOTIFY, AUTO_UPDATE, NOTIFY_ON_UPDATE, PROCESS_AUTOMATICALLY, UNPACK, CPU_PRESET, \ - KEEP_PROCESSED_DIR, PROCESS_METHOD, TV_DOWNLOAD_DIR, MIN_DAILYSEARCH_FREQUENCY, DEFAULT_UPDATE_FREQUENCY, MIN_UPDATE_FREQUENCY, UPDATE_FREQUENCY, \ + KEEP_PROCESSED_DIR, PROCESS_METHOD, DELRARCONTENTS, TV_DOWNLOAD_DIR, MIN_DAILYSEARCH_FREQUENCY, DEFAULT_UPDATE_FREQUENCY, MIN_UPDATE_FREQUENCY, UPDATE_FREQUENCY, \ showQueueScheduler, searchQueueScheduler, ROOT_DIRS, CACHE_DIR, ACTUAL_CACHE_DIR, TIMEZONE_DISPLAY, \ NAMING_PATTERN, NAMING_MULTI_EP, NAMING_ANIME_MULTI_EP, NAMING_FORCE_FOLDERS, NAMING_ABD_PATTERN, NAMING_CUSTOM_ABD, NAMING_SPORTS_PATTERN, NAMING_CUSTOM_SPORTS, NAMING_ANIME_PATTERN, NAMING_CUSTOM_ANIME, NAMING_STRIP_YEAR, \ RENAME_EPISODES, AIRDATE_EPISODES, properFinderScheduler, PROVIDER_ORDER, autoPostProcesserScheduler, \ @@ -533,13 +542,13 @@ def initialize(consoleLogging=True): USE_SYNOLOGYNOTIFIER, SYNOLOGYNOTIFIER_NOTIFY_ONSNATCH, SYNOLOGYNOTIFIER_NOTIFY_ONDOWNLOAD, SYNOLOGYNOTIFIER_NOTIFY_ONSUBTITLEDOWNLOAD, \ USE_EMAIL, EMAIL_HOST, EMAIL_PORT, EMAIL_TLS, EMAIL_USER, EMAIL_PASSWORD, EMAIL_FROM, EMAIL_NOTIFY_ONSNATCH, EMAIL_NOTIFY_ONDOWNLOAD, EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD, EMAIL_LIST, \ USE_LISTVIEW, METADATA_KODI, METADATA_KODI_12PLUS, METADATA_MEDIABROWSER, METADATA_PS3, metadata_provider_dict, \ - NEWZBIN, NEWZBIN_USERNAME, NEWZBIN_PASSWORD, GIT_PATH, MOVE_ASSOCIATED_FILES, POSTPONE_IF_SYNC_FILES, dailySearchScheduler, NFO_RENAME, \ + NEWZBIN, NEWZBIN_USERNAME, NEWZBIN_PASSWORD, GIT_PATH, MOVE_ASSOCIATED_FILES, SYNC_FILES, POSTPONE_IF_SYNC_FILES, dailySearchScheduler, NFO_RENAME, \ GUI_NAME, HOME_LAYOUT, HISTORY_LAYOUT, DISPLAY_SHOW_SPECIALS, COMING_EPS_LAYOUT, COMING_EPS_SORT, COMING_EPS_DISPLAY_PAUSED, COMING_EPS_MISSED_RANGE, DISPLAY_FILESIZE, FUZZY_DATING, TRIM_ZERO, DATE_PRESET, TIME_PRESET, TIME_PRESET_W_SECONDS, THEME_NAME, \ POSTER_SORTBY, POSTER_SORTDIR, \ METADATA_WDTV, METADATA_TIVO, METADATA_MEDE8ER, IGNORE_WORDS, REQUIRE_WORDS, CALENDAR_UNPROTECTED, CREATE_MISSING_SHOW_DIRS, \ ADD_SHOWS_WO_DIR, USE_SUBTITLES, SUBTITLES_LANGUAGES, SUBTITLES_DIR, SUBTITLES_SERVICES_LIST, SUBTITLES_SERVICES_ENABLED, SUBTITLES_HISTORY, SUBTITLES_FINDER_FREQUENCY, SUBTITLES_MULTI, subtitlesFinderScheduler, \ USE_FAILED_DOWNLOADS, DELETE_FAILED, ANON_REDIRECT, LOCALHOST_IP, TMDB_API_KEY, DEBUG, PROXY_SETTING, PROXY_INDEXERS, \ - AUTOPOSTPROCESSER_FREQUENCY, DEFAULT_AUTOPOSTPROCESSER_FREQUENCY, MIN_AUTOPOSTPROCESSER_FREQUENCY, \ + AUTOPOSTPROCESSER_FREQUENCY, SHOWUPDATE_HOUR, DEFAULT_AUTOPOSTPROCESSER_FREQUENCY, MIN_AUTOPOSTPROCESSER_FREQUENCY, \ ANIME_DEFAULT, NAMING_ANIME, ANIMESUPPORT, USE_ANIDB, ANIDB_USERNAME, ANIDB_PASSWORD, ANIDB_USE_MYLIST, \ ANIME_SPLIT_HOME, SCENE_DEFAULT, PLAY_VIDEOS, DOWNLOAD_URL, BACKLOG_DAYS, GIT_ORG, GIT_REPO, GIT_USERNAME, GIT_PASSWORD, \ GIT_AUTOISSUES, gh @@ -575,10 +584,6 @@ def initialize(consoleLogging=True): GIT_USERNAME = check_setting_str(CFG, 'General', 'git_username', '') GIT_PASSWORD = check_setting_str(CFG, 'General', 'git_password', '', censor_log=True) - # github api - try:gh = Github(user_agent="SiCKRAGE").get_organization(GIT_ORG).get_repo(GIT_REPO) - except:gh = None - # debugging DEBUG = bool(check_setting_int(CFG, 'General', 'debug', 0)) @@ -594,6 +599,13 @@ def initialize(consoleLogging=True): # init logging logger.initLogging(consoleLogging=consoleLogging, fileLogging=fileLogging, debugLogging=DEBUG) + # github api + try: + gh = Github(user_agent="SiCKRAGE").get_organization(GIT_ORG).get_repo(GIT_REPO) + except Exception as e: + gh = None + logger.log('Unable to setup github properly, github will not be available. Error: {0}'.format(ex(e)),logger.WARNING) + # git reset on update GIT_RESET = bool(check_setting_int(CFG, 'General', 'git_reset', 0)) @@ -627,6 +639,37 @@ def initialize(consoleLogging=True): logger.log(u"!!! Creating local cache dir failed, using system default", logger.ERROR) CACHE_DIR = None + # Check if we need to perform a restore of the cache folder + try: + restoreDir = os.path.join(DATA_DIR, 'restore') + if os.path.exists(restoreDir) and os.path.exists(os.path.join(restoreDir, 'cache')): + def restoreCache(srcDir, dstDir): + import ntpath + + def path_leaf(path): + head, tail = ntpath.split(path) + return tail or ntpath.basename(head) + + try: + if os.path.isdir(dstDir): + bakFilename = '{0}-{1}'.format(path_leaf(dstDir), datetime.datetime.strftime(datetime.datetime.now(), '%Y%m%d_%H%M%S')) + shutil.move(dstDir, os.path.join(ntpath.dirname(dstDir), bakFilename)) + + shutil.move(srcDir, dstDir) + logger.log(u"Restore: restoring cache successful", logger.INFO) + except Exception as e: + logger.log(u"Restore: restoring cache failed: {0}".format(str(e)), logger.ERROR) + + restoreCache(os.path.join(restoreDir, 'cache'), CACHE_DIR) + except Exception as e: + logger.log(u"Restore: restoring cache failed: {0}".format(str(e)), logger.ERROR) + finally: + if os.path.exists(os.path.join(DATA_DIR, 'restore')): + try: + shutil.rmtree(os.path.join(DATA_DIR, 'restore')) + except Exception as e: + logger.log(u"Restore: Unable to remove the restore directory: {0}".format(str(e)), logger.ERROR) + # clean cache folders if CACHE_DIR: helpers.clearCache() @@ -765,6 +808,10 @@ def initialize(consoleLogging=True): if UPDATE_FREQUENCY < MIN_UPDATE_FREQUENCY: UPDATE_FREQUENCY = MIN_UPDATE_FREQUENCY + SHOWUPDATE_HOUR = check_setting_int(CFG, 'General', 'showupdate_hour', 3) + if SHOWUPDATE_HOUR > 23: SHOWUPDATE_HOUR = 0; + elif SHOWUPDATE_HOUR < 0: SHOWUPDATE_HOUR = 0; + BACKLOG_DAYS = check_setting_int(CFG, 'General', 'backlog_days', 7) NZB_DIR = check_setting_str(CFG, 'Blackhole', 'nzb_dir', '') @@ -777,8 +824,10 @@ def initialize(consoleLogging=True): AIRDATE_EPISODES = bool(check_setting_int(CFG, 'General', 'airdate_episodes', 0)) KEEP_PROCESSED_DIR = bool(check_setting_int(CFG, 'General', 'keep_processed_dir', 1)) PROCESS_METHOD = check_setting_str(CFG, 'General', 'process_method', 'copy' if KEEP_PROCESSED_DIR else 'move') + DELRARCONTENTS = bool(check_setting_int(CFG, 'General', 'del_rar_contents', 0)) MOVE_ASSOCIATED_FILES = bool(check_setting_int(CFG, 'General', 'move_associated_files', 0)) POSTPONE_IF_SYNC_FILES = bool(check_setting_int(CFG, 'General', 'postpone_if_sync_files', 1)) + SYNC_FILES = check_setting_str(CFG, 'General', 'sync_files', SYNC_FILES) NFO_RENAME = bool(check_setting_int(CFG, 'General', 'nfo_rename', 1)) CREATE_MISSING_SHOW_DIRS = bool(check_setting_int(CFG, 'General', 'create_missing_show_dirs', 0)) ADD_SHOWS_WO_DIR = bool(check_setting_int(CFG, 'General', 'add_shows_wo_dir', 0)) @@ -817,6 +866,7 @@ def initialize(consoleLogging=True): TORRENT_LABEL_ANIME = check_setting_str(CFG, 'TORRENT', 'torrent_label_anime', '') TORRENT_VERIFY_CERT = bool(check_setting_int(CFG, 'TORRENT', 'torrent_verify_cert', 0)) TORRENT_RPCURL = check_setting_str(CFG, 'TORRENT', 'torrent_rpcurl', 'transmission') + TORRENT_AUTH_TYPE = check_setting_str(CFG, 'TORRENT', 'torrent_auth_type', '') USE_KODI = bool(check_setting_int(CFG, 'KODI', 'use_kodi', 0)) KODI_ALWAYS_ON = bool(check_setting_int(CFG, 'KODI', 'kodi_always_on', 1)) @@ -1112,6 +1162,13 @@ def initialize(consoleLogging=True): curTorrentProvider.getID() + '_enable_backlog', 1)) + if hasattr(curTorrentProvider, 'cat'): + curTorrentProvider.cat = check_setting_int(CFG, curTorrentProvider.getID().upper(), + curTorrentProvider.getID() + '_cat', 0) + if hasattr(curTorrentProvider, 'subtitle'): + curTorrentProvider.subtitle = bool(check_setting_int(CFG, curTorrentProvider.getID().upper(), + curTorrentProvider.getID() + '_subtitle', 0)) + for curNzbProvider in [curProvider for curProvider in providers.sortedProviderList() if curProvider.providerType == GenericProvider.NZB]: curNzbProvider.enabled = bool( @@ -1194,7 +1251,7 @@ def initialize(consoleLogging=True): showUpdateScheduler = scheduler.Scheduler(showUpdater.ShowUpdater(), cycleTime=datetime.timedelta(hours=1), threadName="SHOWUPDATER", - start_time=datetime.time(hour=3)) # 3 AM + start_time=datetime.time(hour=SHOWUPDATE_HOUR)) # 3 AM # searchers searchQueueScheduler = scheduler.Scheduler(search_queue.SearchQueue(), @@ -1486,6 +1543,7 @@ def save_config(): new_config['General']['dailysearch_frequency'] = int(DAILYSEARCH_FREQUENCY) new_config['General']['backlog_frequency'] = int(BACKLOG_FREQUENCY) new_config['General']['update_frequency'] = int(UPDATE_FREQUENCY) + new_config['General']['showupdate_hour'] = int(SHOWUPDATE_HOUR) new_config['General']['download_propers'] = int(DOWNLOAD_PROPERS) new_config['General']['randomize_providers'] = int(RANDOMIZE_PROVIDERS) new_config['General']['check_propers_interval'] = CHECK_PROPERS_INTERVAL @@ -1539,7 +1597,9 @@ def save_config(): new_config['General']['tv_download_dir'] = TV_DOWNLOAD_DIR new_config['General']['keep_processed_dir'] = int(KEEP_PROCESSED_DIR) new_config['General']['process_method'] = PROCESS_METHOD + new_config['General']['del_rar_contents'] = int(DELRARCONTENTS) new_config['General']['move_associated_files'] = int(MOVE_ASSOCIATED_FILES) + new_config['General']['sync_files'] = SYNC_FILES new_config['General']['postpone_if_sync_files'] = int(POSTPONE_IF_SYNC_FILES) new_config['General']['nfo_rename'] = int(NFO_RENAME) new_config['General']['process_automatically'] = int(PROCESS_AUTOMATICALLY) @@ -1618,6 +1678,12 @@ def save_config(): if hasattr(curTorrentProvider, 'enable_backlog'): new_config[curTorrentProvider.getID().upper()][curTorrentProvider.getID() + '_enable_backlog'] = int( curTorrentProvider.enable_backlog) + if hasattr(curTorrentProvider, 'cat'): + new_config[curTorrentProvider.getID().upper()][curTorrentProvider.getID() + '_cat'] = int( + curTorrentProvider.cat) + if hasattr(curTorrentProvider, 'subtitle'): + new_config[curTorrentProvider.getID().upper()][curTorrentProvider.getID() + '_subtitle'] = int( + curTorrentProvider.subtitle) for curNzbProvider in [curProvider for curProvider in providers.sortedProviderList() if curProvider.providerType == GenericProvider.NZB]: @@ -1683,6 +1749,7 @@ def save_config(): new_config['TORRENT']['torrent_label_anime'] = TORRENT_LABEL_ANIME new_config['TORRENT']['torrent_verify_cert'] = int(TORRENT_VERIFY_CERT) new_config['TORRENT']['torrent_rpcurl'] = TORRENT_RPCURL + new_config['TORRENT']['torrent_auth_type'] = TORRENT_AUTH_TYPE new_config['KODI'] = {} new_config['KODI']['use_kodi'] = int(USE_KODI) diff --git a/sickbeard/clients/generic.py b/sickbeard/clients/generic.py index 9f8e3d696f2d41860f794a7795d286969c89acd4..aebecded3f039212402729e42910de7fbd336a0c 100644 --- a/sickbeard/clients/generic.py +++ b/sickbeard/clients/generic.py @@ -51,19 +51,19 @@ class GenericClient(object): self.response = self.session.__getattribute__(method)(self.url, params=params, data=data, files=files, timeout=120, verify=False) except requests.exceptions.ConnectionError, e: - logger.log(self.name + u': Unable to connect ' + ex(e), logger.ERROR) + logger.log(self.name + u': Unable to connect ' + str(e), logger.ERROR) return False except (requests.exceptions.MissingSchema, requests.exceptions.InvalidURL): logger.log(self.name + u': Invalid Host', logger.ERROR) return False except requests.exceptions.HTTPError, e: - logger.log(self.name + u': Invalid HTTP Request ' + ex(e), logger.ERROR) + logger.log(self.name + u': Invalid HTTP Request ' + str(e), logger.ERROR) return False except requests.exceptions.Timeout, e: - logger.log(self.name + u': Connection Timeout ' + ex(e), logger.ERROR) + logger.log(self.name + u': Connection Timeout ' + str(e), logger.ERROR) return False except Exception, e: - logger.log(self.name + u': Unknown exception raised when send torrent to ' + self.name + ': ' + ex(e), + logger.log(self.name + u': Unknown exception raised when send torrent to ' + self.name + ': ' + str(e), logger.ERROR) return False @@ -199,7 +199,7 @@ class GenericClient(object): except Exception, e: logger.log(self.name + u': Failed Sending Torrent', logger.ERROR) - logger.log(self.name + u': Exception raised when sending torrent: ' + ex(e), logger.DEBUG) + logger.log(self.name + u': Exception raised when sending torrent: ' + str(result) + u'. Error: ' + str(e), logger.DEBUG) return r_code return r_code diff --git a/sickbeard/clients/rtorrent.py b/sickbeard/clients/rtorrent.py index 82f760461c36f511f53f7bf323b2d532effcfc1c..3a8a865d73e6c4d24fa799b01357b8dd0a1d2154 100644 --- a/sickbeard/clients/rtorrent.py +++ b/sickbeard/clients/rtorrent.py @@ -37,8 +37,15 @@ class rTorrentAPI(GenericClient): if not self.host: return + tp_kwargs = {} + if sickbeard.TORRENT_AUTH_TYPE is not 'none': + tp_kwargs['authtype'] = sickbeard.TORRENT_AUTH_TYPE + + if not sickbeard.TORRENT_VERIFY_CERT: + tp_kwargs['check_ssl_cert'] = False + if self.username and self.password: - self.auth = RTorrent(self.host, self.username, self.password) + self.auth = RTorrent(self.host, self.username, self.password, True, tp_kwargs=tp_kwargs) else: self.auth = RTorrent(self.host, None, None, True) diff --git a/sickbeard/helpers.py b/sickbeard/helpers.py index 83c5ca086362cd4fa783274fd9334df08c81ea96..7d0503e75420750d6b9aabd5b21fbe7502d8e74f 100644 --- a/sickbeard/helpers.py +++ b/sickbeard/helpers.py @@ -19,6 +19,7 @@ from __future__ import with_statement import os +import ctypes import random import re import shutil @@ -130,7 +131,9 @@ def replaceExtension(filename, newExt): def isSyncFile(filename): extension = filename.rpartition(".")[2].lower() - if extension == '!sync' or extension == 'lftp-pget-status' or extension == 'part' or extension == 'bts': + #if extension == '!sync' or extension == 'lftp-pget-status' or extension == 'part' or extension == 'bts': + syncfiles = sickbeard.SYNC_FILES + if extension in syncfiles.split(","): return True else: return False @@ -189,6 +192,7 @@ def sanitizeFileName(name): # remove bad chars from the filename name = re.sub(r'[\\/\*]', '-', name) name = re.sub(r'[:"<>|?]', '', name) + name = re.sub(ur'\u2122', '', name) # Trade Mark Sign # remove leading/trailing periods and spaces name = name.strip(' .') @@ -284,21 +288,22 @@ def searchIndexerForShowID(regShowName, indexer=None, indexer_id=None, ui=None): continue try: - seriesname = search.seriesname + seriesname = search[0]['seriesname'] except: seriesname = None try: - series_id = search.id + series_id = search[0]['id'] except: series_id = None if not (seriesname and series_id): continue - - if str(name).lower() == str(seriesname).lower and not indexer_id: + ShowObj = findCertainShow(sickbeard.showList, int(series_id)) + #Check if we can find the show in our list (if not, it's not the right show) + if (indexer_id is None) and (ShowObj is not None) and (ShowObj.indexerid == int(series_id)): return (seriesname, i, int(series_id)) - elif int(indexer_id) == int(series_id): + elif (indexer_id is not None) and (int(indexer_id) == int(series_id)): return (seriesname, i, int(indexer_id)) if indexer: @@ -951,8 +956,21 @@ def is_hidden_folder(folder): On Linux based systems hidden folders start with . (dot) folder: Full path of folder to check """ + def is_hidden(filepath): + name = os.path.basename(os.path.abspath(filepath)) + return name.startswith('.') or has_hidden_attribute(filepath) + + def has_hidden_attribute(filepath): + try: + attrs = ctypes.windll.kernel32.GetFileAttributesW(unicode(filepath)) + assert attrs != -1 + result = bool(attrs & 2) + except (AttributeError, AssertionError): + result = False + return result + if ek.ek(os.path.isdir, folder): - if ek.ek(os.path.basename, folder).startswith('.'): + if is_hidden(folder): return True return False @@ -994,16 +1012,20 @@ def set_up_anidb_connection(): if not sickbeard.ADBA_CONNECTION: anidb_logger = lambda x: logger.log("ANIDB: " + str(x), logger.DEBUG) - sickbeard.ADBA_CONNECTION = adba.Connection(keepAlive=True, log=anidb_logger) - - if not sickbeard.ADBA_CONNECTION.authed(): try: - sickbeard.ADBA_CONNECTION.auth(sickbeard.ANIDB_USERNAME, sickbeard.ANIDB_PASSWORD) - except Exception, e: - logger.log(u"exception msg: " + str(e)) + sickbeard.ADBA_CONNECTION = adba.Connection(keepAlive=True, log=anidb_logger) + except Exception as e: + logger.log(u"anidb exception msg: " + str(e)) return False - else: - return True + + try: + if not sickbeard.ADBA_CONNECTION.authed(): + sickbeard.ADBA_CONNECTION.auth(sickbeard.ANIDB_USERNAME, sickbeard.ANIDB_PASSWORD) + else: + return True + except Exception as e: + logger.log(u"anidb exception msg: " + str(e)) + return False return sickbeard.ADBA_CONNECTION.authed() @@ -1053,6 +1075,41 @@ def extractZip(archive, targetDir): return False +def backupConfigZip(fileList, archive, arcname = None): + try: + a = zipfile.ZipFile(archive, 'w', zipfile.ZIP_DEFLATED) + for f in fileList: + a.write(f, os.path.relpath(f, arcname)) + a.close() + return True + except Exception as e: + logger.log(u"Zip creation error: " + str(e), logger.ERROR) + return False + + +def restoreConfigZip(archive, targetDir): + import ntpath + try: + if not os.path.exists(targetDir): + os.mkdir(targetDir) + else: + def path_leaf(path): + head, tail = ntpath.split(path) + return tail or ntpath.basename(head) + bakFilename = '{0}-{1}'.format(path_leaf(targetDir), datetime.datetime.strftime(datetime.datetime.now(), '%Y%m%d_%H%M%S')) + shutil.move(targetDir, os.path.join(ntpath.dirname(targetDir), bakFilename)) + + zip_file = zipfile.ZipFile(archive, 'r') + for member in zip_file.namelist(): + zip_file.extract(member, targetDir) + zip_file.close() + return True + except Exception as e: + logger.log(u"Zip extraction error: " + str(e), logger.ERROR) + shutil.rmtree(targetDir) + return False + + def mapIndexersToShow(showObj): mapped = {} diff --git a/sickbeard/logger.py b/sickbeard/logger.py index 0ae2d68e4c485b4a0ed39f6b680fe54c92ef80cb..9b2b7dfa1ab68d54cb41c081cbbbe4272cd7552b 100644 --- a/sickbeard/logger.py +++ b/sickbeard/logger.py @@ -28,6 +28,7 @@ import platform import sickbeard from sickbeard import classes, encodingKludge as ek from github import Github, InputFileContent +import codecs # log levels ERROR = logging.ERROR @@ -105,7 +106,7 @@ class Logger(object): # console log handler if self.consoleLogging: console = logging.StreamHandler() - console.setFormatter(CensoredFormatter('%(asctime)s %(levelname)s::%(message)s', '%H:%M:%S')) + console.setFormatter(CensoredFormatter(u'%(asctime)s %(levelname)s::%(message)s', '%H:%M:%S')) console.setLevel(INFO if not self.debugLogging else DEBUG) for logger in self.loggers: @@ -114,7 +115,7 @@ class Logger(object): # rotating log file handler if self.fileLogging: rfh = logging.handlers.RotatingFileHandler(self.logFile, maxBytes=sickbeard.LOG_SIZE, backupCount=sickbeard.LOG_NR, encoding='utf-8') - rfh.setFormatter(CensoredFormatter('%(asctime)s %(levelname)-8s %(message)s', '%Y-%m-%d %H:%M:%S')) + rfh.setFormatter(CensoredFormatter(u'%(asctime)s %(levelname)-8s %(message)s', '%Y-%m-%d %H:%M:%S')) rfh.setLevel(DEBUG) for logger in self.loggers: @@ -156,7 +157,7 @@ class Logger(object): # read log file log_data = None if self.logFile and os.path.isfile(self.logFile): - with ek.ek(open, self.logFile) as f: + with ek.ek(codecs.open, *[self.logFile, 'r', 'utf-8']) as f: log_data = f.readlines() log_data = [line for line in reversed(log_data)] diff --git a/sickbeard/metadata/mede8er.py b/sickbeard/metadata/mede8er.py index f140d54bdc141b371315cdbca1e1931b3ec72088..64db23f7c98aad2410fb806d1d117468290272f7 100644 --- a/sickbeard/metadata/mede8er.py +++ b/sickbeard/metadata/mede8er.py @@ -304,7 +304,7 @@ class Mede8erMetadata(mediabrowser.MediaBrowserMetadata): Overview.text = "" mpaa = etree.SubElement(episode, "mpaa") - if myShow["contentrating"] != None: + if getattr(myShow, 'contentrating', None) is not None: mpaa.text = myShow["contentrating"] if not ep_obj.relatedEps: diff --git a/sickbeard/name_parser/regexes.py b/sickbeard/name_parser/regexes.py index ec9543a32a6525015d1bb8e281dff10941447718..74852087e857d5dc7de5030c18b9a3a178aa120c 100644 --- a/sickbeard/name_parser/regexes.py +++ b/sickbeard/name_parser/regexes.py @@ -198,6 +198,18 @@ normal_regexes = [ ] anime_regexes = [ + ('anime_horriblesubs', + # [HorribleSubs] Maria the Virgin Witch - 01 [720p].mkv + ''' + ^(?:\[(?P<release_group>HorribleSubs)\][\s\.]) + (?:(?P<series_name>.+?)[\s\.]-[\s\.]) + (?P<ep_ab_num>((?!(1080|720|480)[pi]))\d{1,3}) + (-(?P<extra_ab_ep_num>((?!(1080|720|480)[pi])|(?![hx].?264))\d{1,3}))? + (?:v(?P<version>[0-9]))? + (?:[\w\.\s]*) + (?:(?:(?:[\[\(])(?P<extra_info>\d{3,4}[xp]?\d{0,4}[\.\w\s-]*)(?:[\]\)]))|(?:\d{3,4}[xp])) + .*? + '''), ('anime_ultimate', """ ^(?:\[(?P<release_group>.+?)\][ ._-]*) diff --git a/sickbeard/notifiers/emailnotify.py b/sickbeard/notifiers/emailnotify.py index d8ffb379baffe4b6aeb8d0cc7ea5e71a0f4b943b..02255ac4da3584884880032ba7ad2f6590516193 100644 --- a/sickbeard/notifiers/emailnotify.py +++ b/sickbeard/notifiers/emailnotify.py @@ -22,6 +22,7 @@ import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText +from email.utils import formatdate import re @@ -42,12 +43,13 @@ class EmailNotifier: msg['Subject'] = 'SickRage: Test Message' msg['From'] = smtp_from msg['To'] = to + msg['Date'] = formatdate(localtime=True) return self._sendmail(host, port, smtp_from, use_tls, user, pwd, [to], msg, True) def notify_snatch(self, ep_name, title="Snatched:"): """ Send a notification that an episode was snatched - + ep_name: The name of the episode that was snatched title: The title of the notification (optional) """ @@ -76,6 +78,7 @@ class EmailNotifier: msg['Subject'] = 'Snatched: ' + ep_name msg['From'] = sickbeard.EMAIL_FROM msg['To'] = ','.join(to) + msg['Date'] = formatdate(localtime=True) if self._sendmail(sickbeard.EMAIL_HOST, sickbeard.EMAIL_PORT, sickbeard.EMAIL_FROM, sickbeard.EMAIL_TLS, sickbeard.EMAIL_USER, sickbeard.EMAIL_PASSWORD, to, msg): logger.log("Snatch notification sent to [%s] for '%s'" % (to, ep_name), logger.DEBUG) @@ -109,11 +112,12 @@ class EmailNotifier: try: msg = MIMEText(ep_name) except: - mag = 'Episode Downloaded' + msg = MIMEText('Episode Downloaded') msg['Subject'] = 'Downloaded: ' + ep_name msg['From'] = sickbeard.EMAIL_FROM msg['To'] = ','.join(to) + msg['Date'] = formatdate(localtime=True) if self._sendmail(sickbeard.EMAIL_HOST, sickbeard.EMAIL_PORT, sickbeard.EMAIL_FROM, sickbeard.EMAIL_TLS, sickbeard.EMAIL_USER, sickbeard.EMAIL_PASSWORD, to, msg): logger.log("Download notification sent to [%s] for '%s'" % (to, ep_name), logger.DEBUG) @@ -147,7 +151,7 @@ class EmailNotifier: try: msg = MIMEText(ep_name + ": " + lang) except: - msg = "Episode Subtitle Downloaded" + msg = MIMEText("Episode Subtitle Downloaded") msg['Subject'] = lang + ' Subtitle Downloaded: ' + ep_name msg['From'] = sickbeard.EMAIL_FROM diff --git a/sickbeard/notifiers/kodi.py b/sickbeard/notifiers/kodi.py index 1b33cd22511ca4a06e4b9c9e6644bab2dcd9426d..7b4bd3c6e991d6a92ef28be450fea5e815b427e6 100644 --- a/sickbeard/notifiers/kodi.py +++ b/sickbeard/notifiers/kodi.py @@ -397,7 +397,7 @@ class KODINotifier: logger.log(u"KODI JSON response: " + str(result), logger.DEBUG) return result # need to return response for parsing except ValueError, e: - logger.log(u"Unable to decode JSON: " + response, logger.WARNING) + logger.log(u"Unable to decode JSON: " + str(response.read()), logger.WARNING) return False except IOError, e: diff --git a/sickbeard/postProcessor.py b/sickbeard/postProcessor.py index e3f230236e87e4ff0c98f60eaf7bb1bf13f353c0..f19f55043634ca9b089fad5a0ddd3eae54ccbe7c 100644 --- a/sickbeard/postProcessor.py +++ b/sickbeard/postProcessor.py @@ -145,7 +145,7 @@ class PostProcessor(object): logger.DEBUG) return PostProcessor.DOESNT_EXIST - def list_associated_files(self, file_path, base_name_only=False, subtitles_only=False): + def list_associated_files(self, file_path, base_name_only=False, subtitles_only=False, subfolders=False): """ For a given file path searches for files with the same name but different extension and returns their absolute paths @@ -179,7 +179,11 @@ class PostProcessor(object): # don't confuse glob with chars we didn't mean to use base_name = re.sub(r'[\[\]\*\?]', r'[\g<0>]', base_name) - for associated_file_path in ek.ek(recursive_glob, self.folder_path, base_name + '*'): + if subfolders: + filelist = ek.ek(recursive_glob, self.folder_path, base_name + '*') + else: + filelist = ek.ek(glob.glob, base_name + '*') + for associated_file_path in filelist: # only add associated to list if associated_file_path == file_path: continue diff --git a/sickbeard/processTV.py b/sickbeard/processTV.py index ded1e8cad02e45192fee6893176b7933f4247ca8..7da8dc368475f0b550baaddfdfd00941de6a9390 100644 --- a/sickbeard/processTV.py +++ b/sickbeard/processTV.py @@ -68,9 +68,11 @@ def delete_folder(folder, check_empty=True): return True -def delete_files(processPath, notwantedFiles, result): +def delete_files(processPath, notwantedFiles, result, force=False): - if not result.result: + if not result.result and force: + result.output += logHelper(u"Forcing deletion of files, even though last result was not success", logger.DEBUG) + elif not result.result: return #Delete all file not needed @@ -176,6 +178,11 @@ def processDir(dirName, nzbName=None, process_method=None, force=False, is_prior delete_files(path, rarContent, result) for video in set(videoFiles) - set(videoInRar): result.result = process_media(path, [video], nzbName, process_method, force, is_priority, result) + elif sickbeard.DELRARCONTENTS and videoInRar: + result.result = process_media(path, videoInRar, nzbName, process_method, force, is_priority, result) + delete_files(path, rarContent, result, True) + for video in set(videoFiles) - set(videoInRar): + result.result = process_media(path, [video], nzbName, process_method, force, is_priority, result) else: for video in videoFiles: result.result = process_media(path, [video], nzbName, process_method, force, is_priority, result) @@ -207,6 +214,11 @@ def processDir(dirName, nzbName=None, process_method=None, force=False, is_prior process_media(processPath, set(videoFiles) - set(videoInRar), nzbName, process_method, force, is_priority, result) delete_files(processPath, rarContent, result) + elif sickbeard.DELRARCONTENTS and videoInRar: + process_media(processPath, videoInRar, nzbName, process_method, force, is_priority, result) + process_media(processPath, set(videoFiles) - set(videoInRar), nzbName, process_method, force, + is_priority, result) + delete_files(processPath, rarContent, result, True) else: process_media(processPath, videoFiles, nzbName, process_method, force, is_priority, result) @@ -251,7 +263,7 @@ def validateDir(path, dirName, nzbNameOriginal, failed, result): process_failed(os.path.join(path, dirName), nzbNameOriginal, result) return False - if helpers.is_hidden_folder(dirName): + if helpers.is_hidden_folder(os.path.join(path, dirName)): result.output += logHelper(u"Ignoring hidden folder: " + dirName, logger.DEBUG) return False @@ -341,6 +353,27 @@ def unRAR(path, rarFiles, force, result): if basename not in unpacked_files: unpacked_files.append(basename) del rar_handle + + except FatalRARError: + result.output += logHelper(u"Failed Unrar archive {0}: Unrar: Fatal Error".format(archive), logger.ERROR) + result.result = False + continue + except CRCRARError: + result.output += logHelper(u"Failed Unrar archive {0}: Unrar: Archive CRC Error".format(archive), logger.ERROR) + result.result = False + continue + except IncorrectRARPassword: + result.output += logHelper(u"Failed Unrar archive {0}: Unrar: Invalid Password".format(archive), logger.ERROR) + result.result = False + continue + except NoFileToExtract: + result.output += logHelper(u"Failed Unrar archive (0): Unrar: No file to extract, file already exist?".format(archive), logger.ERROR) + result.result = False + continue + except GenericRARError: + result.output += logHelper(u"Failed Unrar archive {0}: Unrar: Generic Error".format(archive), logger.ERROR) + result.result = False + continue except Exception, e: result.output += logHelper(u"Failed Unrar archive " + archive + ': ' + ex(e), logger.ERROR) result.result = False diff --git a/sickbeard/providers/__init__.py b/sickbeard/providers/__init__.py index a1d5474c26ca0f1514c32feb7c11af0d05489f60..d8af81879bdbc31a3594973c07e0367773d34abe 100755 --- a/sickbeard/providers/__init__.py +++ b/sickbeard/providers/__init__.py @@ -40,6 +40,10 @@ __all__ = ['ezrss', 'bitsoup', 't411', 'tokyotoshokan', + 'alpharatio', + 'shazbat', + 'rarbg', + 'tntvillage', ] import sickbeard diff --git a/sickbeard/providers/alpharatio.py b/sickbeard/providers/alpharatio.py new file mode 100755 index 0000000000000000000000000000000000000000..be7fd45799df4fc73b6fe61145080a8cb24d793a --- /dev/null +++ b/sickbeard/providers/alpharatio.py @@ -0,0 +1,278 @@ +# Author: Bill Nasty +# URL: https://github.com/SiCKRAGETV/SickRage +# +# This file is part of SickRage. +# +# SickRage 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 3 of the License, or +# (at your option) any later version. +# +# SickRage 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 SickRage. If not, see <http://www.gnu.org/licenses/>. + +import re +import traceback +import datetime +import urlparse + +import sickbeard +import generic + +from sickbeard.common import Quality, cpu_presets +from sickbeard import logger +from sickbeard import tvcache +from sickbeard import db +from sickbeard import classes +from sickbeard import helpers +from sickbeard import show_name_helpers +from sickbeard.common import Overview +from sickbeard.exceptions import ex +from sickbeard import clients +from lib import requests +from lib.requests import exceptions +from sickbeard.bs4_parser import BS4Parser +from lib.unidecode import unidecode +from sickbeard.helpers import sanitizeSceneName + +class AlphaRatioProvider(generic.TorrentProvider): + + def __init__(self): + + generic.TorrentProvider.__init__(self, "AlphaRatio") + + self.supportsBacklog = True + + self.enabled = False + self.username = None + self.password = None + self.ratio = None + self.minseed = None + self.minleech = None + + self.cache = AlphaRatioCache(self) + + self.urls = {'base_url': 'https://alpharatio.cc/', + 'login': 'https://alpharatio.cc/login.php', + 'detail': 'https://alpharatio.cc/torrents.php?torrentid=%s', + 'search': 'https://alpharatio.cc/torrents.php?searchstr=%s%s', + 'download': 'https://alpharatio.cc/%s', + } + + self.catagories = "&filter_cat[1]=1&filter_cat[2]=1&filter_cat[3]=1&filter_cat[4]=1&filter_cat[5]=1" + + self.url = self.urls['base_url'] + + def isEnabled(self): + return self.enabled + + def imageName(self): + return 'alpharatio.png' + + def getQuality(self, item, anime=False): + + quality = Quality.sceneQuality(item[0], anime) + return quality + + def _doLogin(self): + login_params = {'username': self.username, + 'password': self.password, + 'remember_me': 'on', + 'login': 'submit', + } + + self.session = requests.Session() + + try: + response = self.session.post(self.urls['login'], data=login_params, timeout=30, verify=False) + except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError), e: + logger.log(u'Unable to connect to ' + self.name + ' provider: ' + ex(e), logger.ERROR) + return False + + if re.search('Invalid Username/password', response.text) \ + or re.search('<title>Login :: AlphaRatio.cc</title>', response.text) \ + or response.status_code == 401: + logger.log(u'Invalid username or password for ' + self.name + ' Check your settings', logger.ERROR) + return False + + return True + + def _get_season_search_strings(self, ep_obj): + + search_string = {'Season': []} + for show_name in set(show_name_helpers.allPossibleShowNames(self.show)): + if ep_obj.show.air_by_date or ep_obj.show.sports: + ep_string = show_name + ' ' + str(ep_obj.airdate).split('-')[0] + elif ep_obj.show.anime: + ep_string = show_name + ' ' + "%d" % ep_obj.scene_absolute_number + else: + ep_string = show_name + ' S%02d' % int(ep_obj.scene_season) #1) showName SXX + + search_string['Season'].append(ep_string) + + return [search_string] + + def _get_episode_search_strings(self, ep_obj, add_string=''): + + search_string = {'Episode': []} + + if not ep_obj: + return [] + + if self.show.air_by_date: + for show_name in set(show_name_helpers.allPossibleShowNames(self.show)): + ep_string = sanitizeSceneName(show_name) + ' ' + \ + str(ep_obj.airdate).replace('-', '|') + search_string['Episode'].append(ep_string) + elif self.show.sports: + for show_name in set(show_name_helpers.allPossibleShowNames(self.show)): + ep_string = sanitizeSceneName(show_name) + ' ' + \ + str(ep_obj.airdate).replace('-', '|') + '|' + \ + ep_obj.airdate.strftime('%b') + search_string['Episode'].append(ep_string) + elif self.show.anime: + for show_name in set(show_name_helpers.allPossibleShowNames(self.show)): + ep_string = sanitizeSceneName(show_name) + ' ' + \ + "%i" % int(ep_obj.scene_absolute_number) + search_string['Episode'].append(ep_string) + else: + for show_name in set(show_name_helpers.allPossibleShowNames(self.show)): + ep_string = show_name_helpers.sanitizeSceneName(show_name) + ' ' + \ + sickbeard.config.naming_ep_type[2] % {'seasonnumber': ep_obj.scene_season, + 'episodenumber': ep_obj.scene_episode} + ' %s' % add_string + + search_string['Episode'].append(re.sub('\s+', ' ', ep_string)) + + return [search_string] + + def _doSearch(self, search_params, search_mode='eponly', epcount=0, age=0): + + results = [] + items = {'Season': [], 'Episode': [], 'RSS': []} + + if not self._doLogin(): + return results + + for mode in search_params.keys(): + for search_string in search_params[mode]: + + if isinstance(search_string, unicode): + search_string = unidecode(search_string) + + searchURL = self.urls['search'] % (search_string, self.catagories) + + data = self.getURL(searchURL) + if not data: + continue + + try: + with BS4Parser(data, features=["html5lib", "permissive"]) as html: + torrent_table = html.find('table', attrs={'id': 'torrent_table'}) + torrent_rows = torrent_table.find_all('tr') if torrent_table else [] + + #Continue only if one Release is found + if len(torrent_rows) < 2: + logger.log(u"The Data returned from " + self.name + " does not contain any torrents", + logger.DEBUG) + continue + + for result in torrent_rows[1:]: + cells = result.find_all('td') + link = result.find('a', attrs = {'dir': 'ltr'}) + url = result.find('a', attrs = {'title': 'Download'}) + + try: + title = link.contents[0] + download_url = self.urls['download'] % (url['href']) + id = link['href'].replace('torrents.php?id=', '').split('&')[0] + seeders = cells[len(cells)-2].string + leechers = cells[len(cells)-1].string + except (AttributeError, TypeError): + continue + + #Filter unseeded torrent + if mode != 'RSS' and (seeders < self.minseed or leechers < self.minleech): + continue + + if not title or not download_url: + continue + + item = title, download_url, id, seeders, leechers + logger.log(u"Found result: " + title + "(" + searchURL + ")", logger.DEBUG) + + items[mode].append(item) + + except Exception, e: + logger.log(u"Failed parsing " + self.name + " Traceback: " + traceback.format_exc(), logger.ERROR) + + #For each search mode sort all the items by seeders + items[mode].sort(key=lambda tup: tup[3], reverse=True) + + results += items[mode] + + return results + + def _get_title_and_url(self, item): + + title, url, id, seeders, leechers = item + + if title: + title = u'' + title + title = title.replace(' ', '.') + + if url: + url = str(url).replace('&', '&') + + return (title, url) + + def findPropers(self, search_date=datetime.datetime.today()): + + results = [] + + myDB = db.DBConnection() + sqlResults = myDB.select( + 'SELECT s.show_name, e.showid, e.season, e.episode, e.status, e.airdate FROM tv_episodes AS e' + + ' INNER JOIN tv_shows AS s ON (e.showid = s.indexer_id)' + + ' WHERE e.airdate >= ' + str(search_date.toordinal()) + + ' AND (e.status IN (' + ','.join([str(x) for x in Quality.DOWNLOADED]) + ')' + + ' OR (e.status IN (' + ','.join([str(x) for x in Quality.SNATCHED]) + ')))' + ) + + if not sqlResults: + return [] + + for sqlshow in sqlResults: + self.show = helpers.findCertainShow(sickbeard.showList, int(sqlshow["showid"])) + if self.show: + curEp = self.show.getEpisode(int(sqlshow["season"]), int(sqlshow["episode"])) + + searchString = self._get_episode_search_strings(curEp, add_string='PROPER|REPACK') + + for item in self._doSearch(searchString[0]): + title, url = self._get_title_and_url(item) + results.append(classes.Proper(title, url, datetime.datetime.today(), self.show)) + + return results + + def seedRatio(self): + return self.ratio + +class AlphaRatioCache(tvcache.TVCache): + + def __init__(self, provider): + + tvcache.TVCache.__init__(self, provider) + + # only poll AlphaRatio every 20 minutes max + self.minTime = 20 + + def _getRSSData(self): + search_params = {'RSS': ['']} + return {'entries': self.provider._doSearch(search_params)} + +provider = AlphaRatioProvider() diff --git a/sickbeard/providers/btn.py b/sickbeard/providers/btn.py index 23689cc22cd8ac596bcd91b82220667d96d16896..5b6a86e10c8771d052be8f2b4db229b2f262dc05 100644 --- a/sickbeard/providers/btn.py +++ b/sickbeard/providers/btn.py @@ -22,6 +22,7 @@ import socket import math import sickbeard import generic +import itertools from sickbeard import classes from sickbeard import scene_exceptions @@ -29,6 +30,10 @@ from sickbeard import logger from sickbeard import tvcache from sickbeard.helpers import sanitizeSceneName from sickbeard.exceptions import ex, AuthException +from sickbeard.common import MULTI_EP_RESULT, SEASON_RESULT, USER_AGENT +from sickbeard import db +from sickbeard.name_parser.parser import NameParser, InvalidNameException, InvalidShowException +from sickbeard.common import Quality from lib import jsonrpclib from datetime import datetime @@ -290,6 +295,204 @@ class BTNProvider(generic.TorrentProvider): def seedRatio(self): return self.ratio + def findSearchResults(self, show, episodes, search_mode, manualSearch=False): + + self._checkAuth() + self.show = show + + results = {} + itemList = [] + + searched_scene_season = None + for epObj in episodes: + # search cache for episode result + cacheResult = self.cache.searchCache(epObj, manualSearch) + if cacheResult: + if epObj.episode not in results: + results[epObj.episode] = cacheResult + else: + results[epObj.episode].extend(cacheResult) + + # found result, search next episode + continue + + # skip if season already searched + if len(episodes) > 1 and search_mode == 'sponly' and searched_scene_season == epObj.scene_season: + continue + + # mark season searched for season pack searches so we can skip later on + searched_scene_season = epObj.scene_season + + if search_mode == 'sponly': + # get season search results + for curString in self._get_season_search_strings(epObj): + itemList += self._doSearch(curString, search_mode, len(episodes)) + else: + # get single episode search results + for curString in self._get_episode_search_strings(epObj): + itemList += self._doSearch(curString, search_mode, len(episodes)) + + # if we found what we needed already from cache then return results and exit + if len(results) == len(episodes): + return results + + # sort list by quality + if len(itemList): + items = {} + itemsUnknown = [] + for item in itemList: + quality = self.getQuality(item, anime=show.is_anime) + if quality == Quality.UNKNOWN: + itemsUnknown += [item] + else: + if quality not in items: + items[quality] = [item] + else: + items[quality].append(item) + + itemList = list(itertools.chain(*[v for (k, v) in sorted(items.items(), reverse=True)])) + itemList += itemsUnknown if itemsUnknown else [] + + # filter results + cl = [] + for item in itemList: + (title, url) = self._get_title_and_url(item) + + # parse the file name + try: + myParser = NameParser(False, convert=True) + parse_result = myParser.parse(title) + except InvalidNameException: + logger.log(u"Unable to parse the filename " + title + " into a valid episode", logger.DEBUG) # @UndefinedVariable + continue + except InvalidShowException: + logger.log(u"Unable to parse the filename " + title + " into a valid show", logger.DEBUG) + continue + + showObj = parse_result.show + quality = parse_result.quality + release_group = parse_result.release_group + version = parse_result.version + + addCacheEntry = False + if not (showObj.air_by_date or showObj.sports): + if search_mode == 'sponly': + if len(parse_result.episode_numbers): + logger.log( + u"This is supposed to be a season pack search but the result " + title + " is not a valid season pack, skipping it", + logger.DEBUG) + addCacheEntry = True + if len(parse_result.episode_numbers) and ( + parse_result.season_number not in set([ep.season for ep in episodes]) or not [ep for ep in episodes if + ep.scene_episode in parse_result.episode_numbers]): + logger.log( + u"The result " + title + " doesn't seem to be a valid episode that we are trying to snatch, ignoring", + logger.DEBUG) + addCacheEntry = True + else: + if not len(parse_result.episode_numbers) and parse_result.season_number and not [ep for ep in + episodes if + ep.season == parse_result.season_number and ep.episode in parse_result.episode_numbers]: + logger.log( + u"The result " + title + " doesn't seem to be a valid season that we are trying to snatch, ignoring", + logger.DEBUG) + addCacheEntry = True + elif len(parse_result.episode_numbers) and not [ep for ep in episodes if + ep.season == parse_result.season_number and ep.episode in parse_result.episode_numbers]: + logger.log( + u"The result " + title + " doesn't seem to be a valid episode that we are trying to snatch, ignoring", + logger.DEBUG) + addCacheEntry = True + + if not addCacheEntry: + # we just use the existing info for normal searches + actual_season = parse_result.season_number + actual_episodes = parse_result.episode_numbers + else: + if not (parse_result.is_air_by_date): + logger.log( + u"This is supposed to be a date search but the result " + title + " didn't parse as one, skipping it", + logger.DEBUG) + addCacheEntry = True + else: + airdate = parse_result.air_date.toordinal() + myDB = db.DBConnection() + sql_results = myDB.select( + "SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?", + [showObj.indexerid, airdate]) + + if len(sql_results) != 1: + logger.log( + u"Tried to look up the date for the episode " + title + " but the database didn't give proper results, skipping it", + logger.WARNING) + addCacheEntry = True + + if not addCacheEntry: + actual_season = int(sql_results[0]["season"]) + actual_episodes = [int(sql_results[0]["episode"])] + + # add parsed result to cache for usage later on + if addCacheEntry: + logger.log(u"Adding item from search to cache: " + title, logger.DEBUG) + ci = self.cache._addCacheEntry(title, url, parse_result=parse_result) + if ci is not None: + cl.append(ci) + continue + + # make sure we want the episode + wantEp = True + for epNo in actual_episodes: + if not showObj.wantEpisode(actual_season, epNo, quality, manualSearch): + wantEp = False + break + + if not wantEp: + logger.log( + u"Ignoring result " + title + " because we don't want an episode that is " + + Quality.qualityStrings[ + quality], logger.DEBUG) + + continue + + logger.log(u"Found result " + title + " at " + url, logger.DEBUG) + + # make a result object + epObj = [] + for curEp in actual_episodes: + epObj.append(showObj.getEpisode(actual_season, curEp)) + + result = self.getResult(epObj) + result.show = showObj + result.url = url + result.name = title + result.quality = quality + result.release_group = release_group + result.version = version + result.content = None + + if len(epObj) == 1: + epNum = epObj[0].episode + logger.log(u"Single episode result.", logger.DEBUG) + elif len(epObj) > 1: + epNum = MULTI_EP_RESULT + logger.log(u"Separating multi-episode result to check for later - result contains episodes: " + str( + parse_result.episode_numbers), logger.DEBUG) + elif len(epObj) == 0: + epNum = SEASON_RESULT + logger.log(u"Separating full season result to check for later", logger.DEBUG) + + if epNum not in results: + results[epNum] = [result] + else: + results[epNum].append(result) + + # check if we have items to add to cache + if len(cl) > 0: + myDB = self.cache._getDB() + myDB.mass_action(cl) + + return results + class BTNCache(tvcache.TVCache): def __init__(self, provider): diff --git a/sickbeard/providers/freshontv.py b/sickbeard/providers/freshontv.py index e06e9bad6866c63a8b06b8263eb00c3740068d7b..ac83e30529ae1b74fdadfff891b642dc4abb78f3 100755 --- a/sickbeard/providers/freshontv.py +++ b/sickbeard/providers/freshontv.py @@ -19,6 +19,7 @@ import re import traceback import datetime +import time import urlparse import sickbeard import generic @@ -104,28 +105,36 @@ class FreshOnTVProvider(generic.TorrentProvider): try: response = self.session.post(self.urls['login'], data=login_params, timeout=30, verify=False) - except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError), e: + except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError) as e: logger.log(u'Unable to connect to ' + self.name + ' provider: ' + ex(e), logger.ERROR) return False - if re.search('Username does not exist in the userbase or the account is not confirmed yet.', response.text): - logger.log(u'Invalid username or password for ' + self.name + ' Check your settings', logger.ERROR) - return False + if re.search('/logout.php', response.text): + logger.log(u'Login to ' + self.name + ' was successful.', logger.DEBUG) - try: - if requests.utils.dict_from_cookiejar(self.session.cookies)['uid'] and requests.utils.dict_from_cookiejar(self.session.cookies)['pass']: - self._uid = requests.utils.dict_from_cookiejar(self.session.cookies)['uid'] - self._hash = requests.utils.dict_from_cookiejar(self.session.cookies)['pass'] + try: + if requests.utils.dict_from_cookiejar(self.session.cookies)['uid'] and requests.utils.dict_from_cookiejar(self.session.cookies)['pass']: + self._uid = requests.utils.dict_from_cookiejar(self.session.cookies)['uid'] + self._hash = requests.utils.dict_from_cookiejar(self.session.cookies)['pass'] + + self.cookies = {'uid': self._uid, + 'pass': self._hash + } + return True + except: + logger.log(u'Unable to obtain cookie for FreshOnTV', logger.ERROR) + return False + + else: + logger.log(u'Login to ' + self.name + ' was unsuccessful.', logger.DEBUG) + if re.search('Username does not exist in the userbase or the account is not confirmed yet.', response.text): + logger.log(u'Invalid username or password for ' + self.name + ' Check your settings', logger.ERROR) - self.cookies = {'uid': self._uid, - 'pass': self._hash - } - return True - except: - pass + if re.search('DDoS protection by CloudFlare', response.text): + logger.log(u'Unable to login to ' + self.name + ' due to CloudFlare DDoS javascript check.', logger.ERROR) + + return False - logger.log(u'Unable to obtain cookie for FreshOnTV', logger.ERROR) - return False def _get_season_search_strings(self, ep_obj): @@ -191,66 +200,119 @@ class FreshOnTVProvider(generic.TorrentProvider): if isinstance(search_string, unicode): search_string = unidecode(search_string) - searchURL = self.urls['search'] % (freeleech, search_string) - logger.log(u"Search string: " + searchURL, logger.DEBUG) + init_html = self.getURL(searchURL) + max_page_number = 0 - # returns top 15 results by default, expandable in user profile to 100 - data = self.getURL(searchURL) - if not data: + if not init_html: + logger.log(u"The opening search response from " + self.name + " is empty.",logger.DEBUG) continue try: - with BS4Parser(data, features=["html5lib", "permissive"]) as html: - torrent_table = html.find('table', attrs={'class': 'frame'}) - torrent_rows = torrent_table.findChildren('tr') if torrent_table else [] - - #Continue only if one Release is found - if len(torrent_rows) < 2: - logger.log(u"The Data returned from " + self.name + " do not contains any torrent", - logger.DEBUG) - continue + with BS4Parser(init_html, features=["html5lib", "permissive"]) as init_soup: + + #Check to see if there is more than 1 page of results + pager = init_soup.find('div', {'class': 'pager'}) + if pager: + page_links = pager.find_all('a', href=True) + else: + page_links = [] + + if len(page_links) > 0: + for lnk in page_links: + link_text = lnk.text.strip() + if link_text.isdigit(): + page_int = int(link_text) + if page_int > max_page_number: + max_page_number = page_int + + #limit page number to 15 just in case something goes wrong + if max_page_number > 15: + max_page_number = 15 + #limit RSS search + if max_page_number > 3 and mode is 'RSS': + max_page_number = 3 + except: + logger.log(u"BS4 parser unable to process response " + self.name + " Traceback: " + traceback.format_exc(), logger.ERROR) + continue - # skip colheader - for result in torrent_rows[1:]: - cells = result.findChildren('td') + data_response_list = [] + data_response_list.append(init_html) - link = cells[1].find('a', attrs = {'class': 'torrent_name_link'}) - #skip if torrent has been nuked due to poor quality - if cells[1].find('img', alt='Nuked') != None: - continue + #Freshon starts counting pages from zero, even though it displays numbers from 1 + if max_page_number > 1: + for i in range(1, max_page_number): - torrent_id = link['href'].replace('/details.php?id=', '') + time.sleep(1) + page_searchURL = searchURL + '&page=' + str(i) + logger.log(u"Search string: " + page_searchURL, logger.DEBUG) + page_html = self.getURL(page_searchURL) + if not page_html: + logger.log(u"The search response for page number " + str(i) + " is empty." + self.name,logger.DEBUG) + continue - try: - if link.has_key('title'): - title = cells[1].find('a', {'class': 'torrent_name_link'})['title'] - else: - title = link.contents[0] - download_url = self.urls['download'] % (torrent_id) - id = int(torrent_id) + data_response_list.append(page_html) - seeders = int(cells[8].find('a', {'class': 'link'}).span.contents[0].strip()) - leechers = int(cells[9].find('a', {'class': 'link'}).contents[0].strip()) - except (AttributeError, TypeError): - continue + try: - #Filter unseeded torrent - if mode != 'RSS' and (seeders < self.minseed or leechers < self.minleech): - continue + for data_response in data_response_list: - if not title or not download_url: - continue + with BS4Parser(data_response, features=["html5lib", "permissive"]) as html: - item = title, download_url, id, seeders, leechers - logger.log(u"Found result: " + title + "(" + searchURL + ")", logger.DEBUG) + torrent_rows = html.findAll("tr", {"class": re.compile('torrent_[0-9]*')}) - items[mode].append(item) + #Continue only if a Release is found + if len(torrent_rows) == 0: + logger.log(u"The Data returned from " + self.name + " does not contain any torrent", logger.DEBUG) + continue - except Exception, e: - logger.log(u"Failed parsing " + self.name + " Traceback: " + traceback.format_exc(), logger.ERROR) + for individual_torrent in torrent_rows: + + #skip if torrent has been nuked due to poor quality + if individual_torrent.find('img', alt='Nuked') != None: + continue + + try: + title = individual_torrent.find('a', {'class': 'torrent_name_link'})['title'] + except: + logger.log(u"Unable to parse torrent title " + self.name + " Traceback: " + traceback.format_exc(), logger.DEBUG) + continue + + try: + details_url = individual_torrent.find('a', {'class': 'torrent_name_link'})['href'] + id = int((re.match('.*?([0-9]+)$', details_url).group(1)).strip()) + download_url = self.urls['download'] % (str(id)) + except: + logger.log(u"Unable to parse torrent id & download url " + self.name + " Traceback: " + traceback.format_exc(), logger.DEBUG) + continue + + try: + seeders = int(individual_torrent.find('td', {'class': 'table_seeders'}).find('span').text.strip()) + except: + logger.log(u"Unable to parse torrent seeders content " + self.name + " Traceback: " + traceback.format_exc(), logger.DEBUG) + seeders = 1 + try: + leechers = int(individual_torrent.find('td', {'class': 'table_leechers'}).find('a').text.strip()) + except: + logger.log(u"Unable to parse torrent leechers content " + self.name + " Traceback: " + traceback.format_exc(), logger.DEBUG) + leechers = 0 + + #Filter unseeded torrent + if mode != 'RSS' and (seeders < self.minseed or leechers < self.minleech): + continue + + if not title or not download_url: + continue + + item = title, download_url, id, seeders, leechers + logger.log(u"Found result: " + title + " (" + searchURL + ")", logger.DEBUG) + + items[mode].append(item) + + except Exception as e: + logger.log(u"Failed parsing " + " Traceback: " + traceback.format_exc(), logger.DEBUG) #For each search mode sort all the items by seeders items[mode].sort(key=lambda tup: tup[3], reverse=True) diff --git a/sickbeard/providers/generic.py b/sickbeard/providers/generic.py index be602a5b3c93e4667ee02c4e2f073b83640d3bb9..a835dad70095225e47b6fa55cb07bb62ab4a4fc1 100644 --- a/sickbeard/providers/generic.py +++ b/sickbeard/providers/generic.py @@ -504,7 +504,7 @@ class ProviderProxy: def _buildURL(self, url): """ Return the Proxyfied URL of the page """ if self.isEnabled(): - url = self.getProxyURL() + self.param + urllib.quote_plus(url) + self.option + url = self.getProxyURL() + self.param + urllib.quote_plus(url.encode('UTF-8')) + self.option logger.log(u"Proxified URL: " + url, logger.DEBUG) return url @@ -517,4 +517,4 @@ class ProviderProxy: else: regx = re.sub('//1', '', regx) - return regx \ No newline at end of file + return regx diff --git a/sickbeard/providers/hounddawgs.py b/sickbeard/providers/hounddawgs.py index 978236a9d06cbadf73ccb7407efd73727318603e..ac51d2d8081dd0cd240b452dfebe40f68728a061 100644 --- a/sickbeard/providers/hounddawgs.py +++ b/sickbeard/providers/hounddawgs.py @@ -56,9 +56,9 @@ class HoundDawgsProvider(generic.TorrentProvider): self.cache = HoundDawgsCache(self) - self.urls = {'base_url': 'http://192.99.10.104/', - 'search': 'http://192.99.10.104/torrents.php?type=&userid=&searchstr=%s&searchimdb=&searchtags=&order_by=s3&order_way=desc&%s', - 'login': 'http://192.99.10.104/login.php', + self.urls = {'base_url': 'https://hounddawgs.org/', + 'search': 'https://hounddawgs.org/torrents.php?type=&userid=&searchstr=%s&searchimdb=&searchtags=&order_by=s3&order_way=desc&%s', + 'login': 'https://hounddawgs.org/login.php', } self.url = self.urls['base_url'] @@ -154,9 +154,10 @@ class HoundDawgsProvider(generic.TorrentProvider): items = {'Season': [], 'Episode': [], 'RSS': []} if not self._doLogin(): - return [] + return results for mode in search_params.keys(): + for search_string in search_params[mode]: if isinstance(search_string, unicode): @@ -214,20 +215,14 @@ class HoundDawgsProvider(generic.TorrentProvider): download_url = self.urls['base_url']+allAs[0].attrs['href'] id = link.replace(self.urls['base_url']+'torrents.php?id=','') - seeders = int(torrent[7].string) - leechers = int(torrent[8].string) except (AttributeError, TypeError): continue - #Filter unseeded torrent - if mode != 'RSS' and (seeders < self.minseed or leechers < self.minleech): - continue - if not title or not download_url: continue - item = title, download_url, id, seeders, leechers + item = title, download_url logger.log(u"Found result: " + title + "(" + download_url + ")", logger.DEBUG) items[mode].append(item) @@ -235,16 +230,13 @@ class HoundDawgsProvider(generic.TorrentProvider): except Exception, e: logger.log(u"Failed parsing " + self.name + " Traceback: " + traceback.format_exc(), logger.ERROR) - #For each search mode sort all the items by seeders - items[mode].sort(key=lambda tup: tup[3], reverse=True) - results += items[mode] return results def _get_title_and_url(self, item): - title, url, id, seeders, leechers = item + title, url = item if title: title = u'' + title diff --git a/sickbeard/providers/iptorrents.py b/sickbeard/providers/iptorrents.py index 0d2d0d6b62de5da5731e3f436e3d68b39d5b01d1..246db5c3d5c857bcf7da8950d70d4c8088849525 100644 --- a/sickbeard/providers/iptorrents.py +++ b/sickbeard/providers/iptorrents.py @@ -150,6 +150,9 @@ class IPTorrentsProvider(generic.TorrentProvider): return [search_string] + def findSearchResults(self, show, episodes, search_mode, manualSearch=False): + return generic.TorrentProvider.findSearchResults(self, show, episodes, 'eponly', manualSearch) + def _doSearch(self, search_params, search_mode='eponly', epcount=0, age=0): results = [] diff --git a/sickbeard/providers/oldpiratebay.py b/sickbeard/providers/oldpiratebay.py index fb0a6503e1325c93097a8a3282c22cfa22e746ad..d6731e5cdabf2f7b6122f84039fa46681105b004 100644 --- a/sickbeard/providers/oldpiratebay.py +++ b/sickbeard/providers/oldpiratebay.py @@ -23,6 +23,7 @@ import re import urllib, urllib2, urlparse import sys import os +import traceback import datetime import sickbeard @@ -36,6 +37,7 @@ from sickbeard import tvcache from sickbeard import helpers from sickbeard import clients from sickbeard.show_name_helpers import allPossibleShowNames, sanitizeSceneName +from sickbeard.bs4_parser import BS4Parser from sickbeard.common import Overview from sickbeard.exceptions import ex from sickbeard import encodingKludge as ek @@ -114,54 +116,62 @@ class OldPirateBayProvider(generic.TorrentProvider): fileName = None - fileURL = self.url + 'ajax_details_filelist.php?id=' + str(torrent_id) + fileURL = self.url + 'torrent/' + str(torrent_id) data = self.getURL(fileURL) if not data: return None - filesList = re.findall('<td.+>(.*?)</td>', data) + try: + with BS4Parser(data, features=["html5lib", "permissive"]) as soup: + files_tbody = soup.find('div', attrs={'class': 'description-files'}).find('tbody') + if (not files_tbody): + return None + files = [] + rows = files_tbody.find_all('tr') + for row in rows: + files.append(row.find_all('td')[1].text) - if not filesList: - logger.log(u"Unable to get the torrent file list for " + title, logger.ERROR) + videoFiles = filter(lambda x: x.rpartition(".")[2].lower() in mediaExtensions, files) - videoFiles = filter(lambda x: x.rpartition(".")[2].lower() in mediaExtensions, filesList) + #Filtering SingleEpisode/MultiSeason Torrent + if len(videoFiles) < ep_number or len(videoFiles) > float(ep_number * 1.1): + logger.log(u"Result " + title + " have " + str( + ep_number) + " episode and episodes retrived in torrent are " + str(len(videoFiles)), logger.DEBUG) + logger.log( + u"Result " + title + " Seem to be a Single Episode or MultiSeason torrent, skipping result...", + logger.DEBUG) + return None - #Filtering SingleEpisode/MultiSeason Torrent - if len(videoFiles) < ep_number or len(videoFiles) > float(ep_number * 1.1): - logger.log( - u"Result " + title + " have " + str(ep_number) + " episode and episodes retrived in torrent are " + str( - len(videoFiles)), logger.DEBUG) - logger.log(u"Result " + title + " Seem to be a Single Episode or MultiSeason torrent, skipping result...", - logger.DEBUG) - return None + if Quality.sceneQuality(title) != Quality.UNKNOWN: + return title - if Quality.sceneQuality(title) != Quality.UNKNOWN: - return title + for fileName in videoFiles: + quality = Quality.sceneQuality(os.path.basename(fileName)) + if quality != Quality.UNKNOWN: break - for fileName in videoFiles: - quality = Quality.sceneQuality(os.path.basename(fileName)) - if quality != Quality.UNKNOWN: break + if fileName is not None and quality == Quality.UNKNOWN: + quality = Quality.assumeQuality(os.path.basename(fileName)) - if fileName is not None and quality == Quality.UNKNOWN: - quality = Quality.assumeQuality(os.path.basename(fileName)) + if quality == Quality.UNKNOWN: + logger.log(u"Unable to obtain a Season Quality for " + title, logger.DEBUG) + return None - if quality == Quality.UNKNOWN: - logger.log(u"Unable to obtain a Season Quality for " + title, logger.DEBUG) - return None + try: + myParser = NameParser(showObj=self.show) + parse_result = myParser.parse(fileName) + except (InvalidNameException, InvalidShowException): + return None - try: - myParser = NameParser(showObj=self.show) - parse_result = myParser.parse(fileName) - except (InvalidNameException, InvalidShowException): - return None + logger.log(u"Season quality for " + title + " is " + Quality.qualityStrings[quality], logger.DEBUG) - logger.log(u"Season quality for " + title + " is " + Quality.qualityStrings[quality], logger.DEBUG) + if parse_result.series_name and parse_result.season_number: + title = parse_result.series_name + ' S%02d' % int( + parse_result.season_number) + ' ' + self._reverseQuality(quality) - if parse_result.series_name and parse_result.season_number: - title = parse_result.series_name + ' S%02d' % int(parse_result.season_number) + ' ' + self._reverseQuality( - quality) + return title - return title + except Exception, e: + logger.log(u"Failed parsing " + self.name + " Traceback: " + traceback.format_exc(), logger.ERROR) def _get_season_search_strings(self, ep_obj): @@ -229,7 +239,7 @@ class OldPirateBayProvider(generic.TorrentProvider): if mode != 'RSS': searchURL = self.searchurl % (urllib.quote(search_string)) else: - searchURL = self.url + 'tv/latest/' + searchURL = self.url + 'search?iht=8&sort=-created_at' logger.log(u"Search string: " + searchURL, logger.DEBUG) @@ -245,7 +255,6 @@ class OldPirateBayProvider(generic.TorrentProvider): title = torrent.group('title').replace('_', '.') #Do not know why but SickBeard skip release with '_' in name url = torrent.group('url') - print 'torrent url: ' + url id = int(torrent.group('id')) seeders = int(torrent.group('seeders')) leechers = int(torrent.group('leechers')) diff --git a/sickbeard/providers/rarbg.py b/sickbeard/providers/rarbg.py new file mode 100644 index 0000000000000000000000000000000000000000..60400539b9685e8dcb6872162069ffba51fc933b --- /dev/null +++ b/sickbeard/providers/rarbg.py @@ -0,0 +1,289 @@ +# -*- coding: latin-1 -*- +# Author: djoole <bobby.djoole@gmail.com> +# Author: CoRpO <corpo@gruk.org> +# URL: http://code.google.com/p/sickbeard/ +# +# This file is part of Sick Beard. +# +# Sick Beard 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 3 of the License, or +# (at your option) any later version. +# +# Sick Beard 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 Sick Beard. If not, see <http://www.gnu.org/licenses/>. + +import traceback +import time +import re +import datetime +import sickbeard +import generic +import cookielib +import urllib +import urllib2 + +from lib import requests +from lib.requests import exceptions + +from sickbeard.common import USER_AGENT, Quality, cpu_presets +from sickbeard import logger +from sickbeard import tvcache +from sickbeard import show_name_helpers +from sickbeard.bs4_parser import BS4Parser +from sickbeard import db +from sickbeard import helpers +from sickbeard import classes +from sickbeard.helpers import sanitizeSceneName +from sickbeard.exceptions import ex + + +class RarbgProvider(generic.TorrentProvider): + + def __init__(self): + generic.TorrentProvider.__init__(self, "Rarbg") + + self.supportsBacklog = True + self.enabled = False + + self.cache = RarbgCache(self) + + self.ratio = None + + self.cookies = cookielib.CookieJar() + self.cookie = cookielib.Cookie(version=0, name='7fAY799j', value='VtdTzG69', port=None, port_specified=False, domain='rarbg.com', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False) + self.cookies.set_cookie(self.cookie) + self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookies)) + self.opener.addheaders=[('User-agent', 'Mozilla/5.0')] + + self.urls = {'base_url': 'https://rarbg.com/torrents.php', + 'search': 'https://rarbg.com/torrents.php?search=%s&category=%s&page=%s', + 'download': 'https://rarbg.com/download.php?id=%s&f=%s', + } + + self.url = self.urls['base_url'] + + self.subcategories = [18,41] + self.pages = [1,2,3,4,5] + + + def getURL(self, url, post_data=None, params=None, timeout=30, json=False): + logger.log(u"Rarbg downloading url :" + url, logger.DEBUG) + request = urllib2.Request(url) + content = self.opener.open(request) + return content.read() + + + def isEnabled(self): + return self.enabled + + def imageName(self): + return 'rarbg.png' + + def getQuality(self, item, anime=False): + quality = Quality.sceneQuality(item[0], anime) + return quality + +# def _doLogin(self): +# login_params = {'login': self.username, +# 'password': self.password, +# } +# +# self.session = requests.Session() +# +# try: +# response = self.session.post(self.urls['login_page'], data=login_params, timeout=30, verify=False) +# response = self.session.get(self.urls['base_url'], timeout=30, verify=False) +# except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError), e: +# logger.log(u'Unable to connect to ' + self.name + ' provider: ' + ex(e), logger.ERROR) +# return False +# +# if not re.search('/users/logout/', response.text.lower()): +# logger.log(u'Invalid username or password for ' + self.name + ' Check your settings', logger.ERROR) +# return False +# +# return True + + def _get_season_search_strings(self, ep_obj): + + search_string = {'Season': []} + for show_name in set(show_name_helpers.allPossibleShowNames(self.show)): + if ep_obj.show.air_by_date or ep_obj.show.sports: + ep_string = show_name + '.' + str(ep_obj.airdate).split('-')[0] + elif ep_obj.show.anime: + ep_string = show_name + '.' + "%d" % ep_obj.scene_absolute_number + else: + ep_string = show_name + '.S%02d' % int(ep_obj.scene_season) #1) showName.SXX + + search_string['Season'].append(ep_string) + + return [search_string] + + def _get_episode_search_strings(self, ep_obj, add_string=''): + + search_string = {'Episode': []} + + if not ep_obj: + return [] + + if self.show.air_by_date: + for show_name in set(show_name_helpers.allPossibleShowNames(self.show)): + ep_string = sanitizeSceneName(show_name) + '.' + \ + str(ep_obj.airdate).replace('-', '|') + search_string['Episode'].append(ep_string) + elif self.show.sports: + for show_name in set(show_name_helpers.allPossibleShowNames(self.show)): + ep_string = sanitizeSceneName(show_name) + '.' + \ + str(ep_obj.airdate).replace('-', '|') + '|' + \ + ep_obj.airdate.strftime('%b') + search_string['Episode'].append(ep_string) + elif self.show.anime: + for show_name in set(show_name_helpers.allPossibleShowNames(self.show)): + ep_string = sanitizeSceneName(show_name) + '.' + \ + "%i" % int(ep_obj.scene_absolute_number) + search_string['Episode'].append(ep_string) + else: + for show_name in set(show_name_helpers.allPossibleShowNames(self.show)): + ep_string = show_name_helpers.sanitizeSceneName(show_name) + '.' + \ + sickbeard.config.naming_ep_type[2] % {'seasonnumber': ep_obj.scene_season, + 'episodenumber': ep_obj.scene_episode} + ' %s' % add_string + + search_string['Episode'].append(re.sub('\s+', '.', ep_string)) + + return [search_string] + + def _doSearch(self, search_params, search_mode='eponly', epcount=0, age=0): + + results = [] + items = {'Season': [], 'Episode': [], 'RSS': []} + + # Get cookie + #dummy = self.getURL(self.url) + +# if not self._doLogin(): +# return results + + for mode in search_params.keys(): + + for search_string in search_params[mode]: + + for sc in self.subcategories: + + for page in self.pages: + + searchURL = self.urls['search'] % (urllib.quote(search_string.encode('UTF-8')), sc, page) + logger.log(u"" + self.name + " search page URL: " + searchURL, logger.DEBUG) + + data = self.getURL(searchURL) + if not data: + continue + + try: + with BS4Parser(data, features=["html5lib", "permissive"]) as html: + resultsTable = html.find('table', attrs={'class': 'lista2t'}) + + if not resultsTable: + logger.log(u"The Data returned from " + self.name + " do not contains any torrent", + logger.DEBUG) + continue + + entries = resultsTable.find("tbody").findAll("tr") + + if len(entries) > 0: + for result in entries: + + try: + link = result.find('a', title=True) + torrentName = link['title'] + torrent_name = str(torrentName) + torrentId = result.find_all('td')[1].find_all('a')[0]['href'][1:].replace( + 'torrent/', '') + torrent_download_url = (self.urls['download'] % (torrentId, urllib.quote(torrent_name) + '-[rarbg.com].torrent')).encode('utf8') + except (AttributeError, TypeError): + continue + + if not torrent_name or not torrent_download_url: + continue + + item = torrent_name, torrent_download_url + logger.log(u"Found result: " + torrent_name + " (" + torrent_download_url + ")", + logger.DEBUG) + items[mode].append(item) + + else: + logger.log(u"The Data returned from " + self.name + " do not contains any torrent", + logger.WARNING) + continue + + if len(entries) < 25: + break + + except Exception, e: + logger.log(u"Failed parsing " + self.name + " Traceback: " + traceback.format_exc(), + logger.ERROR) + results += items[mode] + + return results + + def _get_title_and_url(self, item): + + title, url = item + + if title: + title = u'' + title + title = title.replace(' ', '.') + + if url: + url = str(url).replace('&', '&') + + return title, url + + def findPropers(self, search_date=datetime.datetime.today()): + + results = [] + + myDB = db.DBConnection() + sqlResults = myDB.select( + 'SELECT s.show_name, e.showid, e.season, e.episode, e.status, e.airdate FROM tv_episodes AS e' + + ' INNER JOIN tv_shows AS s ON (e.showid = s.indexer_id)' + + ' WHERE e.airdate >= ' + str(search_date.toordinal()) + + ' AND (e.status IN (' + ','.join([str(x) for x in Quality.DOWNLOADED]) + ')' + + ' OR (e.status IN (' + ','.join([str(x) for x in Quality.SNATCHED]) + ')))' + ) + + if not sqlResults: + return [] + + for sqlshow in sqlResults: + self.show = helpers.findCertainShow(sickbeard.showList, int(sqlshow["showid"])) + if self.show: + curEp = self.show.getEpisode(int(sqlshow["season"]), int(sqlshow["episode"])) + searchString = self._get_episode_search_strings(curEp, add_string='PROPER|REPACK') + + for item in self._doSearch(searchString[0]): + title, url = self._get_title_and_url(item) + results.append(classes.Proper(title, url, datetime.datetime.today(), self.show)) + + return results + + def seedRatio(self): + return self.ratio + +class RarbgCache(tvcache.TVCache): + def __init__(self, provider): + tvcache.TVCache.__init__(self, provider) + + # Only poll Rarbg every 30 minutes max + self.minTime = 30 + + def _getRSSData(self): + search_params = {'RSS': ['']} + return {'entries': self.provider._doSearch(search_params)} + + +provider = RarbgProvider() diff --git a/sickbeard/providers/scc.py b/sickbeard/providers/scc.py index 45c1092c55c8c939b2936ee285ffea442ef44dde..2e236441211c588153080445c147678435174fb3 100644 --- a/sickbeard/providers/scc.py +++ b/sickbeard/providers/scc.py @@ -176,7 +176,7 @@ class SCCProvider(generic.TorrentProvider): if isinstance(search_string, unicode): search_string = unidecode(search_string) - if mode == 'Season': + if mode == 'Season' and search_mode == 'sponly': searchURLS += [self.urls['archive'] % (search_string)] else: searchURLS += [self.urls['search'] % (search_string, self.categories)] @@ -185,7 +185,10 @@ class SCCProvider(generic.TorrentProvider): for searchURL in searchURLS: logger.log(u"Search string: " + searchURL, logger.DEBUG) - data += [x for x in [self.getURL(searchURL)] if x] + try: + data += [x for x in [self.getURL(searchURL)] if x] + except Exception as e: + logger.log(u"Unable to fetch data reason: {0}".format(str(e)), logger.WARNING) if not len(data): continue diff --git a/sickbeard/providers/shazbat.py b/sickbeard/providers/shazbat.py new file mode 100644 index 0000000000000000000000000000000000000000..d723a838278465ca483ec3559da790c458186c5c --- /dev/null +++ b/sickbeard/providers/shazbat.py @@ -0,0 +1,93 @@ +# Author: Nic Wolfe <nic@wolfeden.ca> +# URL: http://code.google.com/p/sickbeard/ +# +# This file is part of SickRage. +# +# SickRage 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 3 of the License, or +# (at your option) any later version. +# +# SickRage 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 SickRage. If not, see <http://www.gnu.org/licenses/>. + +try: + import xml.etree.cElementTree as etree +except ImportError: + import elementtree.ElementTree as etree + +import sickbeard +import generic + +from sickbeard.exceptions import ex, AuthException +from sickbeard import helpers +from sickbeard import logger +from sickbeard import tvcache + + +class ShazbatProvider(generic.TorrentProvider): + def __init__(self): + + generic.TorrentProvider.__init__(self, "Shazbat.tv") + + self.supportsBacklog = False + + self.enabled = False + self.passkey = None + self.ratio = None + self.options = None + + self.cache = ShazbatCache(self) + + self.urls = {'base_url': 'http://www.shazbat.tv/'} + self.url = self.urls['base_url'] + + def isEnabled(self): + return self.enabled + + def imageName(self): + return 'shazbat.png' + + def _checkAuth(self): + if not self.passkey: + raise AuthException("Your authentication credentials for " + self.name + " are missing, check your config.") + + return True + + def _checkAuthFromData(self, data): + if not self.passkey: + self._checkAuth() + elif not (data['entries'] and data['feed']): + logger.log(u"Incorrect authentication credentials for " + self.name, logger.DEBUG) + raise AuthException( + u"Your authentication credentials for " + self.name + " are incorrect, check your config") + + return True + + def seedRatio(self): + return self.ratio + + +class ShazbatCache(tvcache.TVCache): + def __init__(self, provider): + tvcache.TVCache.__init__(self, provider) + + # only poll Shazbat feed every 15 minutes max + self.minTime = 15 + + def _getRSSData(self): + + rss_url = self.provider.url + 'rss/recent?passkey=' + provider.passkey + '&fname=true' + logger.log(self.provider.name + u" cache update URL: " + rss_url, logger.DEBUG) + + return self.getRSSFeed(rss_url, items=['entries', 'feed']) + + def _checkAuth(self, data): + return self.provider._checkAuthFromData(data) + +provider = ShazbatProvider() diff --git a/sickbeard/providers/thepiratebay.py b/sickbeard/providers/thepiratebay.py index 1c1e285e699e5974390c06e22adadd0b5e865552..76f4f2c53cf5717e024b66c420dad79dadca0687 100644 --- a/sickbeard/providers/thepiratebay.py +++ b/sickbeard/providers/thepiratebay.py @@ -122,7 +122,9 @@ class ThePirateBayProvider(generic.TorrentProvider): filesList = re.findall('<td.+>(.*?)</td>', data) if not filesList: - logger.log(u"Unable to get the torrent file list for " + title, logger.ERROR) + # disabled errormsg for now + # logger.log(u"Unable to get the torrent file list for " + title, logger.ERROR) + return None videoFiles = filter(lambda x: x.rpartition(".")[2].lower() in mediaExtensions, filesList) diff --git a/sickbeard/providers/tntvillage.py b/sickbeard/providers/tntvillage.py new file mode 100644 index 0000000000000000000000000000000000000000..387743c7ebabfc7c3365cf91396665412a86d4e2 --- /dev/null +++ b/sickbeard/providers/tntvillage.py @@ -0,0 +1,486 @@ +# Author: Giovanni Borri +# Modified by gborri, https://github.com/gborri for TNTVillage +# +# This file is part of SickRage. +# +# SickRage 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 3 of the License, or +# (at your option) any later version. +# +# SickRage 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 SickRage. If not, see <http://www.gnu.org/licenses/>. + +import re +import traceback +import datetime +import urlparse +import sickbeard +import generic +from sickbeard.common import Quality, cpu_presets +from sickbeard import logger +from sickbeard import tvcache +from sickbeard import db +from sickbeard import classes +from sickbeard import helpers +from sickbeard import show_name_helpers +from sickbeard.exceptions import ex, AuthException +from sickbeard import clients +from lib import requests +from lib.requests import exceptions +from sickbeard.bs4_parser import BS4Parser +from lib.unidecode import unidecode +from sickbeard.helpers import sanitizeSceneName + +category_excluded = { + 'Sport' : 22, + 'Teatro' : 23, + 'Video Musicali' : 21, + 'Film' : 4, + 'Musica' : 2, + 'Students Releases' : 13, + 'E Books' : 3, + 'Linux' : 6, + 'Macintosh' : 9, + 'Windows Software' : 10, + 'Pc Game' : 11, + 'Playstation 2' : 12, + 'Wrestling' : 24, + 'Varie' : 25, + 'Xbox' : 26, + 'Immagini sfondi' : 27, + 'Altri Giochi' : 28, + 'Fumetteria' : 30, + 'Trash' : 31, + 'PlayStation 1' : 32, + 'PSP Portable' : 33, + 'A Book' : 34, + 'Podcast' : 35, + 'Edicola' : 36, + 'Mobile' : 37, + } + +class TNTVillageProvider(generic.TorrentProvider): + def __init__(self): + + generic.TorrentProvider.__init__(self, "TNTVillage") + + self.supportsBacklog = True + + self.enabled = False + self._uid = None + self._hash = None + self.username = None + self.password = None + self.ratio = None + self.cat = None + self.page = 10 + self.subtitle = None + self.minseed = None + self.minleech = None + + self.hdtext = [ + ' Versione 720p', + ' V 720p', + ' V HEVC', + ' V HEVC', + ' Versione 1080p', + ' 720p HEVC', + ' Ver 720', + ' 720p HEVC', + ' 720p', + ] + + self.category_dict = { + 'Serie TV' : 29, + 'Cartoni' : 8, + 'Anime' : 7, + 'Programmi e Film TV' : 1, + 'Documentari' : 14, + 'All' : 0, + } + + self.urls = {'base_url' : 'http://forum.tntvillage.scambioetico.org', + 'login' : 'http://forum.tntvillage.scambioetico.org/index.php?act=Login&CODE=01', + 'detail' : 'http://forum.tntvillage.scambioetico.org/index.php?showtopic=%s', + 'search' : 'http://forum.tntvillage.scambioetico.org/?act=allreleases&%s', + 'search_page' : 'http://forum.tntvillage.scambioetico.org/?act=allreleases&st={0}&{1}', + 'download' : 'http://forum.tntvillage.scambioetico.org/index.php?act=Attach&type=post&id=%s', + } + + self.url = self.urls['base_url'] + + self.cache = TNTVillageCache(self) + + self.categories = "cat=29" + + self.cookies = None + + def isEnabled(self): + return self.enabled + + def imageName(self): + return 'tntvillage.png' + + def getQuality(self, item, anime=False): + + quality = Quality.sceneQuality(item[0], anime) + return quality + + def _checkAuth(self): + + if not self.username or not self.password: + raise AuthException("Your authentication credentials for " + self.name + " are missing, check your config.") + + return True + + def _doLogin(self): + + login_params = {'UserName': self.username, + 'PassWord': self.password, + 'CookieDate': 1, + 'submit': 'Connettiti al Forum', + } + + try: + response = self.session.post(self.urls['login'], data=login_params, timeout=30, verify=False) + except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError), e: + logger.log(u'Unable to connect to ' + self.name + ' provider: ' + ex(e), logger.ERROR) + return False + + if re.search('Sono stati riscontrati i seguenti errori', response.text) \ + or re.search('<title>Connettiti</title>', response.text) \ + or response.status_code == 401: + logger.log(u'Invalid username or password for ' + self.name + ' Check your settings', logger.ERROR) + return False + + return True + + def _get_season_search_strings(self, ep_obj): + + search_string = {'Season': []} + for show_name in set(show_name_helpers.allPossibleShowNames(self.show)): + if ep_obj.show.air_by_date or ep_obj.show.sports: + ep_string = show_name + ' ' + str(ep_obj.airdate).split('-')[0] + elif ep_obj.show.anime: + ep_string = show_name + ' ' + "%d" % ep_obj.scene_absolute_number + else: + ep_string = show_name + ' S%02d' % int(ep_obj.scene_season) #1) showName SXX + + search_string['Season'].append(ep_string) + + + return [search_string] + + def _get_episode_search_strings(self, ep_obj, add_string=''): + + search_string = {'Episode': []} + + if not ep_obj: + return [] + + if self.show.air_by_date: + for show_name in set(show_name_helpers.allPossibleShowNames(self.show)): + ep_string = sanitizeSceneName(show_name) + ' ' + \ + str(ep_obj.airdate).replace('-', '|') + search_string['Episode'].append(ep_string) + elif self.show.sports: + for show_name in set(show_name_helpers.allPossibleShowNames(self.show)): + ep_string = sanitizeSceneName(show_name) + ' ' + \ + str(ep_obj.airdate).replace('-', '|') + '|' + \ + ep_obj.airdate.strftime('%b') + search_string['Episode'].append(ep_string) + elif self.show.anime: + for show_name in set(show_name_helpers.allPossibleShowNames(self.show)): + ep_string = sanitizeSceneName(show_name) + ' ' + \ + "%i" % int(ep_obj.scene_absolute_number) + search_string['Episode'].append(ep_string) + else: + for show_name in set(show_name_helpers.allPossibleShowNames(self.show)): + ep_string = show_name_helpers.sanitizeSceneName(show_name) + ' ' + \ + sickbeard.config.naming_ep_type[2] % {'seasonnumber': ep_obj.scene_season, + 'episodenumber': ep_obj.scene_episode} + ' %s' % add_string + + search_string['Episode'].append(re.sub('\s+', ' ', ep_string)) + + return [search_string] + + def _reverseQuality(self, quality): + + quality_string = '' + + if quality == Quality.SDTV: + quality_string = ' HDTV x264' + if quality == Quality.SDDVD: + quality_string = ' DVDRIP' + elif quality == Quality.HDTV: + quality_string = ' 720p HDTV x264' + elif quality == Quality.FULLHDTV: + quality_string = ' 1080p HDTV x264' + elif quality == Quality.RAWHDTV: + quality_string = ' 1080i HDTV mpeg2' + elif quality == Quality.HDWEBDL: + quality_string = ' 720p WEB-DL h264' + elif quality == Quality.FULLHDWEBDL: + quality_string = ' 1080p WEB-DL h264' + elif quality == Quality.HDBLURAY: + quality_string = ' 720p Bluray x264' + elif quality == Quality.FULLHDBLURAY: + quality_string = ' 1080p Bluray x264' + + return quality_string + + def _episodeQuality(self,torrent_rows): + """ + Return The quality from the scene episode HTML row. + """ + + file_quality='' + releaser='' + + img_all = (torrent_rows.find_all('td'))[1].find_all('img') + + if len(img_all) > 0: + for type in img_all: + try: + + file_quality = file_quality + " " + type['src'].replace("style_images/mkportal-636/","").replace(".gif","").replace(".png","") + + except Exception, e: + logger.log(u"Failed parsing " + self.name + " Traceback: " + traceback.format_exc(), logger.ERROR) + + else: + file_quality = (torrent_rows.find_all('td'))[1].get_text() + logger.log(u"file_quality: " + str(file_quality), logger.DEBUG) + + checkName = lambda list, func: func([re.search(x, file_quality, re.I) for x in list]) + + dvdOptions = checkName(["dvd", "dvdrip", "dvdmux", "DVD9", "DVD5"], any) + blueRayOptions = checkName(["BD","BDmux", "BDrip", "BRrip", "Bluray"], any) + sdOptions = checkName(["h264", "divx", "XviD", "tv", "TVrip", "SATRip", "DTTrip", "Mpeg2"], any) + hdOptions = checkName(["720p"], any) + fullHD = checkName(["1080p", "fullHD"], any) + + if len(img_all) > 0: + file_quality = (torrent_rows.find_all('td'))[1].get_text() + + webdl = checkName(["webdl", "webmux", "webrip", "dl-webmux", "web-dlmux", "webdl-mux", "web-dl", "webdlmux", "dlmux"], any) + + logger.log(u"dvdOptions: " + str(dvdOptions) + ", blueRayOptions: " + str(blueRayOptions) + ", sdOptions: " + str(sdOptions) + ", hdOptions: " + str(hdOptions) + ", fullHD: " + str(fullHD) + ", webdl: " + str(webdl), logger.DEBUG) + + if sdOptions and not dvdOptions and not fullHD and not hdOptions: + return Quality.SDTV + elif dvdOptions: + return Quality.SDDVD + elif hdOptions and not blueRayOptions and not fullHD and not webdl: + return Quality.HDTV + elif not hdOptions and not blueRayOptions and fullHD and not webdl: + return Quality.FULLHDTV + elif hdOptions and not blueRayOptions and not fullHD and webdl: + return Quality.HDWEBDL + elif not hdOptions and not blueRayOptions and fullHD and webdl: + return Quality.FULLHDWEBDL + elif blueRayOptions and hdOptions and not fullHD: + return Quality.HDBLURAY + elif blueRayOptions and fullHD and not hdOptions: + return Quality.FULLHDBLURAY + else: + return Quality.UNKNOWN + + def _is_italian(self,torrent_rows): + + is_italian = 0 + + name='' + + span_tag = (torrent_rows.find_all('td'))[1].find('b').find('span') + + name = str(span_tag) + name = name.split('sub')[0] + + if re.search("ita", name, re.I): + logger.log(u"Found Italian Language", logger.DEBUG) + is_italian=1 + + return is_italian + + def _doSearch(self, search_params, search_mode='eponly', epcount=0, age=0): + + results = [] + items = {'Season': [], 'Episode': [], 'RSS': []} + + self.categories = "cat=" + str(self.cat) + + if not self._doLogin(): + return results + + for mode in search_params.keys(): + for search_string in search_params[mode]: + + if isinstance(search_string, unicode): + search_string = unidecode(search_string) + + if mode == 'RSS': + self.page = 2 + + last_page=0 + y=int(self.page) + + if search_string == '': + continue + + search_string = str(search_string).replace('.', ' ') + + for x in range(0,y): + + z=x*20 + if last_page: + break + + logger.log(u"Page: " + str(x) + " of " + str(y), logger.DEBUG) + + if mode != 'RSS': + searchURL = (self.urls['search_page'] + '&filter={2}').format(z,self.categories,search_string) + else: + searchURL = self.urls['search_page'].format(z,self.categories) + + logger.log(u"Search string: " + searchURL, logger.DEBUG) + + data = self.getURL(searchURL) + if not data: + logger.log(u"data is empty", logger.DEBUG) + continue + + try: + with BS4Parser(data, features=["html5lib", "permissive"]) as html: + torrent_table = html.find('table', attrs = {'class' : 'copyright'}) + torrent_rows = torrent_table.find_all('tr') if torrent_table else [] + + #Continue only if one Release is found + logger.log(u"Num of Row: "+ str(len(torrent_rows)), logger.DEBUG) + + if len(torrent_rows)<3: + logger.log(u"The Data returned from " + self.name + " do not contains any torrent", + logger.DEBUG) + last_page=1 + continue + + if len(torrent_rows) < 42: + last_page=1 + + for result in torrent_table.find_all('tr')[2:]: + + try: + link = result.find('td').find('a') + title = link.string + id = ((result.find_all('td')[8].find('a'))['href'])[-8:] + download_url = self.urls['download'] % (id) + leechers = result.find_all('td')[3].find_all('td')[1].text + leechers = int(leechers.strip('[]')) + seeders = result.find_all('td')[3].find_all('td')[2].text + seeders = int(seeders.strip('[]')) + except (AttributeError, TypeError): + continue + + if mode != 'RSS' and (seeders < self.minseed or leechers < self.minleech): + continue + + if not title or not download_url: + continue + + logger.log(u"name: " + title + "", logger.DEBUG) + filename_qt = self._reverseQuality(self._episodeQuality(result)) + for text in self.hdtext: + title = title.replace(text,filename_qt) + + if Quality.nameQuality(title) == Quality.UNKNOWN: + title += filename_qt + + logger.log(u"name, inserted quallity: " + title + "", logger.DEBUG) + + item = title, download_url, id, seeders, leechers + logger.log(u"Found result: " + title + "(" + searchURL + ")", logger.DEBUG) + + if not self._is_italian(result) and not self.subtitle: + logger.log(u"Subtitled, Skipped", logger.DEBUG) + continue + else: + logger.log(u"Not Subtitled or Forced, Got It!", logger.DEBUG) + + items[mode].append(item) + + except Exception, e: + logger.log(u"Failed parsing " + self.name + " Traceback: " + traceback.format_exc(), logger.ERROR) + + #For each search mode sort all the items by seeders + items[mode].sort(key=lambda tup: tup[3], reverse=True) + + results += items[mode] + + return results + + def _get_title_and_url(self, item): + + title, url, id, seeders, leechers = item + + if title: + title = u'' + title + title = title.replace(' ', '.') + + if url: + url = str(url).replace('&', '&') + + return (title, url) + + def findPropers(self, search_date=datetime.datetime.today()): + + results = [] + + myDB = db.DBConnection() + sqlResults = myDB.select( + 'SELECT s.show_name, e.showid, e.season, e.episode, e.status, e.airdate FROM tv_episodes AS e' + + ' INNER JOIN tv_shows AS s ON (e.showid = s.indexer_id)' + + ' WHERE e.airdate >= ' + str(search_date.toordinal()) + + ' AND (e.status IN (' + ','.join([str(x) for x in Quality.DOWNLOADED]) + ')' + + ' OR (e.status IN (' + ','.join([str(x) for x in Quality.SNATCHED]) + ')))' + ) + + if not sqlResults: + return [] + + for sqlshow in sqlResults: + self.show = curshow = helpers.findCertainShow(sickbeard.showList, int(sqlshow["showid"])) + if not self.show: continue + curEp = curshow.getEpisode(int(sqlshow["season"]), int(sqlshow["episode"])) + + searchString = self._get_episode_search_strings(curEp, add_string='PROPER|REPACK') + + for item in self._doSearch(searchString[0]): + title, url = self._get_title_and_url(item) + results.append(classes.Proper(title, url, datetime.datetime.today(), self.show)) + + return results + + def seedRatio(self): + return self.ratio + + +class TNTVillageCache(tvcache.TVCache): + def __init__(self, provider): + + tvcache.TVCache.__init__(self, provider) + + # only poll TNTVillage every 30 minutes max + self.minTime = 30 + + def _getRSSData(self): + search_params = {'RSS': []} + return {'entries': self.provider._doSearch(search_params)} + + +provider = TNTVillageProvider() diff --git a/sickbeard/sbdatetime.py b/sickbeard/sbdatetime.py index 0e7ebf5250477ae6193db2af2198c3b8a76824bc..c3c34cdad68ef4575c84650607fb479adab8d57f 100644 --- a/sickbeard/sbdatetime.py +++ b/sickbeard/sbdatetime.py @@ -101,6 +101,7 @@ class static_or_instance(object): # subclass datetime.datetime to add function to display custom date and time formats class sbdatetime(datetime.datetime): has_locale = True + en_US_norm = locale.normalize('en_US.utf-8') @static_or_instance def convert_to_setting(self, dt=None): @@ -131,8 +132,12 @@ class sbdatetime(datetime.datetime): try: if sbdatetime.has_locale: locale.setlocale(locale.LC_TIME, 'en_US') - except: - sbdatetime.has_locale = False + except Exception as e: + try: + if sbdatetime.has_locale: + locale.setlocale(locale.LC_TIME, sbdatetime.en_US_norm) + except: + sbdatetime.has_locale = False strt = '' try: @@ -212,7 +217,11 @@ class sbdatetime(datetime.datetime): if sbdatetime.has_locale: locale.setlocale(locale.LC_TIME, 'en_US') except: - sbdatetime.has_locale = False + try: + if sbdatetime.has_locale: + locale.setlocale(locale.LC_TIME, sbdatetime.en_US_norm) + except: + sbdatetime.has_locale = False if t_preset is not None: strd += u', ' + dt.strftime(t_preset) elif show_seconds: @@ -228,7 +237,11 @@ class sbdatetime(datetime.datetime): if sbdatetime.has_locale: locale.setlocale(locale.LC_TIME, 'en_US') except: - sbdatetime.has_locale = False + try: + if sbdatetime.has_locale: + locale.setlocale(locale.LC_TIME, sbdatetime.en_US_norm) + except: + sbdatetime.has_locale = False if t_preset is not None: strd += u', ' + self.strftime(t_preset) elif show_seconds: diff --git a/sickbeard/scene_numbering.py b/sickbeard/scene_numbering.py index 85b70f80896cb551469c1bc343f1c9b7c805ba23..e72fae4c02fb274d26c85a6d6c0ec864c4acc874 100644 --- a/sickbeard/scene_numbering.py +++ b/sickbeard/scene_numbering.py @@ -35,6 +35,7 @@ except ImportError: from sickbeard import logger from sickbeard import db from sickbeard.exceptions import ex +from sickbeard import helpers def get_scene_numbering(indexer_id, indexer, season, episode, fallback_to_xem=True): """ @@ -222,6 +223,10 @@ def set_scene_numbering(indexer_id, indexer, season=None, episode=None, absolute "UPDATE scene_numbering SET scene_absolute_number = ? WHERE indexer = ? and indexer_id = ? and absolute_number = ?", [sceneAbsolute, indexer, indexer_id, absolute_number]) + #Reload data from DB so that cache and db are in sync + show = helpers.findCertainShow(sickbeard.showList, indexer_id) + show.flushEpisodes() + def find_xem_numbering(indexer_id, indexer, season, episode): """ diff --git a/sickbeard/search.py b/sickbeard/search.py index 63a476bd626eef4ae40f6aa84675d702fc640573..c649826290af4f2c9d511b55c2be2e428ce13efe 100644 --- a/sickbeard/search.py +++ b/sickbeard/search.py @@ -464,6 +464,10 @@ def searchProviders(show, episodes, manualSearch=False): searchCount = 0 search_mode = curProvider.search_mode + # Always search for episode when manually searching when in sponly and fallback false + if search_mode == 'sponly' and manualSearch == True and curProvider.search_fallback == False: + search_mode = 'eponly' + while(True): searchCount += 1 diff --git a/sickbeard/traktChecker.py b/sickbeard/traktChecker.py index 84c68b074b597aba469eec194f1f789b5b4ff1f6..dfe5b5ac590d2abe2d361968a5f28b9820a45c88 100644 --- a/sickbeard/traktChecker.py +++ b/sickbeard/traktChecker.py @@ -53,8 +53,8 @@ class TraktChecker(): # sync trakt.tv library with sickrage library if sickbeard.TRAKT_SYNC: self.syncLibrary() - except Exception: - logger.log(traceback.format_exc(), logger.DEBUG) + except Exception as e: + logger.log('Trakt: Error Syncing library. Reason: {0}'.format(str(e)), logger.DEBUG) def findShow(self, indexer, indexerid): traktShow = None diff --git a/sickbeard/tv.py b/sickbeard/tv.py index 5b2b29171afc88063d8bcd7378a2b76bb1915858..9ba4cc00f0eb6fcddb9b217b076fd00497e2cd90 100644 --- a/sickbeard/tv.py +++ b/sickbeard/tv.py @@ -50,6 +50,9 @@ from sickbeard import notifiers from sickbeard import postProcessor from sickbeard import subtitles from sickbeard import history +from sickbeard import sbdatetime +from sickbeard import network_timezones +from dateutil.tz import * from sickbeard import encodingKludge as ek @@ -1276,8 +1279,9 @@ class TVShow(object): if epStatus == DOWNLOADED and curQuality == Quality.UNKNOWN: return Overview.QUAL elif epStatus in (SNATCHED, SNATCHED_PROPER, SNATCHED_BEST): + if curQuality < maxBestQuality: + return Overview.QUAL return Overview.SNATCHED - # if they don't want re-downloads then we call it good if they have anything elif maxBestQuality == None: return Overview.GOOD # if they have one but it's not the best they want then mark it as qual @@ -1419,7 +1423,7 @@ class TVEpisode(object): helpers.chmodAsParent(subtitle.path) except Exception as e: - logger.log("Error occurred when downloading subtitles: " + traceback.format_exc(), logger.ERROR) + logger.log("Error occurred when downloading subtitles: " + str(e), logger.ERROR) return if sickbeard.SUBTITLES_MULTI: @@ -2153,7 +2157,27 @@ class TVEpisode(object): show_name = re.sub("\(\d+\)$", "", self.show.name).rstrip() else: show_name = self.show.name - + + #try to get the release group + rel_grp = {}; + rel_grp["SiCKRAGE"] = 'SiCKRAGE'; + if hasattr(self, 'location'): #from the location name + rel_grp['location'] = release_group(self.show, self.location); + if (rel_grp['location'] == ''): del rel_grp['location'] + if hasattr(self, '_release_group'): #from the release group field in db + rel_grp['database'] = self._release_group; + if (rel_grp['database'] == ''): del rel_grp['database'] + if hasattr(self, 'release_name'): #from the release name field in db + rel_grp['release_name'] = release_group(self.show, self.release_name); + if (rel_grp['release_name'] == ''): del rel_grp['release_name'] + + # use release_group, release_name, location in that order + if ('database' in rel_grp): relgrp = 'database' + elif ('release_name' in rel_grp): relgrp = 'release_name' + elif ('location' in rel_grp): relgrp = 'location' + else: relgrp = 'SiCKRAGE' + + return { '%SN': show_name, '%S.N': dot(show_name), @@ -2175,7 +2199,7 @@ class TVEpisode(object): '%AB': '%(#)03d' % {'#': self.absolute_number}, '%XAB': '%(#)03d' % {'#': self.scene_absolute_number}, '%RN': release_name(self.release_name), - '%RG': release_group(self.show, self.release_name), + '%RG': rel_grp[relgrp], '%AD': str(self.airdate).replace('-', ' '), '%A.D': str(self.airdate).replace('-', '.'), '%A_D': us(str(self.airdate)), @@ -2223,21 +2247,30 @@ class TVEpisode(object): replace_map = self._replace_map() result_name = pattern - - # if there's no release group then replace it with a reasonable facsimile + + # if there's no release group in the db, let the user know we replaced it + if (not hasattr(self, '_release_group') and (not replace_map['%RG'] == 'SiCKRAGE')): + logger.log(u"Episode has no release group, replacing it with '" + replace_map['%RG'] + "'", logger.DEBUG); + self._release_group = replace_map['%RG'] #if release_group is not in the db, put it there + elif ((self._release_group == '') and (not replace_map['%RG'] == 'SiCKRAGE')): + logger.log(u"Episode has no release group, replacing it with '" + replace_map['%RG'] + "'", logger.DEBUG); + self._release_group = replace_map['%RG'] #if release_group is not in the db, put it there + + # if there's no release name then replace it with a reasonable facsimile if not replace_map['%RN']: + if self.show.air_by_date or self.show.sports: - result_name = result_name.replace('%RN', '%S.N.%A.D.%E.N-SiCKRAGE') - result_name = result_name.replace('%rn', '%s.n.%A.D.%e.n-sickrage') + result_name = result_name.replace('%RN', '%S.N.%A.D.%E.N-' + replace_map['%RG']) + result_name = result_name.replace('%rn', '%s.n.%A.D.%e.n-' + replace_map['%RG'].lower()) + elif anime_type != 3: - result_name = result_name.replace('%RN', '%S.N.%AB.%E.N-SiCKRAGE') - result_name = result_name.replace('%rn', '%s.n.%ab.%e.n-sickrage') + result_name = result_name.replace('%RN', '%S.N.%AB.%E.N-' + replace_map['%RG']) + result_name = result_name.replace('%rn', '%s.n.%ab.%e.n-' + replace_map['%RG'].lower()) + else: - result_name = result_name.replace('%RN', '%S.N.S%0SE%0E.%E.N-SiCKRAGE') - result_name = result_name.replace('%rn', '%s.n.s%0se%0e.%e.n-sickrage') - - result_name = result_name.replace('%RG', 'SICKRAGE') - result_name = result_name.replace('%rg', 'sickrage') + result_name = result_name.replace('%RN', '%S.N.S%0SE%0E.%E.N-' + replace_map['%RG']) + result_name = result_name.replace('%rn', '%s.n.s%0se%0e.%e.n-' + replace_map['%RG'].lower()) + logger.log(u"Episode has no release name, replacing it with a generic one: " + result_name, logger.DEBUG) if not replace_map['%RT']: @@ -2458,11 +2491,11 @@ class TVEpisode(object): return related_files = postProcessor.PostProcessor(self.location).list_associated_files( - self.location, base_name_only=True) + self.location, base_name_only=True, subfolders=True) if self.show.subtitles and sickbeard.SUBTITLES_DIR != '': related_subs = postProcessor.PostProcessor(self.location).list_associated_files(sickbeard.SUBTITLES_DIR, - subtitles_only=True) + subtitles_only=True, subfolders=True) absolute_proper_subs_path = ek.ek(os.path.join, sickbeard.SUBTITLES_DIR, self.formatted_filename()) logger.log(u"Files associated to " + self.location + ": " + str(related_files), logger.DEBUG) @@ -2529,9 +2562,12 @@ class TVEpisode(object): min = int((airs.group(2), min)[None is airs.group(2)]) airtime = datetime.time(hr, min) - airdatetime = datetime.datetime.combine(self.airdate, airtime) + if sickbeard.TIMEZONE_DISPLAY == 'local': + airdatetime = sbdatetime.sbdatetime.convert_to_setting( network_timezones.parse_date_time(datetime.date.toordinal(self.airdate), self.show.airs, self.show.network)) + else: + airdatetime = datetime.datetime.combine(self.airdate, airtime).replace(tzinfo=tzlocal()) - filemtime = datetime.datetime.fromtimestamp(os.path.getmtime(self.location)) + filemtime = datetime.datetime.fromtimestamp(os.path.getmtime(self.location)).replace(tzinfo=tzlocal()) if filemtime != airdatetime: import time diff --git a/sickbeard/webapi.py b/sickbeard/webapi.py index 9e882a25307da20ee44b9941a51aecf628e352cc..fa4b614b59d9935c822806e0935ddb30c46e5e8c 100644 --- a/sickbeard/webapi.py +++ b/sickbeard/webapi.py @@ -38,6 +38,7 @@ from sickbeard import network_timezones, sbdatetime from sickbeard.exceptions import ex from sickbeard.common import Quality, Overview, qualityPresetStrings, statusStrings, SNATCHED, SNATCHED_PROPER, DOWNLOADED, SKIPPED, UNAIRED, IGNORED, ARCHIVED, WANTED, UNKNOWN from sickbeard.webserve import WebRoot +import codecs try: import json @@ -1318,7 +1319,7 @@ class CMD_Logs(ApiCall): data = [] if os.path.isfile(logger.logFile): - with ek.ek(open, logger.logFile) as f: + with ek.ek(codecs.open, *[logger.logFile, 'r', 'utf-8']) as f: data = f.readlines() regex = "^(\d\d\d\d)\-(\d\d)\-(\d\d)\s*(\d\d)\:(\d\d):(\d\d)\s*([A-Z]+)\s*(.+?)\s*\:\:\s*(.*)$" diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index 06aa237a635fc4c4bd626d96d5dca55ee321422b..88b2c9e62c8ab03c095db8e9ffc85943030dd13b 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -24,6 +24,7 @@ import time import urllib import re import datetime +import codecs import sickbeard from sickbeard import config, sab @@ -87,7 +88,14 @@ class html_entities(CheetahFilter): elif val is None: filtered = '' elif isinstance(val, str): - filtered = val.decode(sickbeard.SYS_ENCODING).encode('ascii', 'xmlcharrefreplace') + try: + filtered = val.decode(sickbeard.SYS_ENCODING).encode('ascii', 'xmlcharrefreplace') + except UnicodeDecodeError as e: + logger.log(u'Unable to decode using {0}, trying utf-8. Error is: {1}'.format(sickbeard.SYS_ENCODING, ex(e)),logger.DEBUG) + try: + filtered = val.decode('utf-8').encode('ascii', 'xmlcharrefreplace') + except UnicodeDecodeError as e: + logger.log(u'Unable to decode using utf-8, Error is {0}.'.format(ex(e)),logger.ERROR) else: filtered = self.filter(str(val)) @@ -185,10 +193,29 @@ class BaseHandler(RequestHandler): </html>""" % (error, error, trace_info, request_info, sickbeard.WEB_ROOT)) def redirect(self, url, permanent=False, status=None): + """Sends a redirect to the given (optionally relative) URL. + + ----->>>>> NOTE: Removed self.finish <<<<<----- + + If the ``status`` argument is specified, that value is used as the + HTTP status code; otherwise either 301 (permanent) or 302 + (temporary) is chosen based on the ``permanent`` argument. + The default is 302 (temporary). + """ + import urlparse + from tornado.escape import utf8 if not url.startswith(sickbeard.WEB_ROOT): url = sickbeard.WEB_ROOT + url - super(BaseHandler, self).redirect(url, permanent, status) + if self._headers_written: + raise Exception("Cannot redirect after headers have been written") + if status is None: + status = 301 if permanent else 302 + else: + assert isinstance(status, int) and 300 <= status <= 399 + self.set_status(status) + self.set_header("Location", urlparse.urljoin(utf8(self.request.uri), + utf8(url))) def get_current_user(self, *args, **kwargs): if not isinstance(self, UI) and sickbeard.WEB_USERNAME and sickbeard.WEB_PASSWORD: @@ -204,23 +231,23 @@ class WebHandler(BaseHandler): executor = ThreadPoolExecutor(50) - @coroutine - @asynchronous @authenticated + @coroutine def get(self, route, *args, **kwargs): try: # route -> method obj route = route.strip('/').replace('.', '_') or 'index' method = getattr(self, route) - # process request async - self.async_call(method, callback=self.async_done) + results = yield self.async_call(method) + self.finish(results) + except: logger.log('Failed doing webui request "%s": %s' % (route, traceback.format_exc()), logger.DEBUG) raise HTTPError(404) @run_on_executor - def async_call(self, function, callback=None): + def async_call(self, function): try: kwargs = self.request.arguments for arg, value in kwargs.items(): @@ -228,22 +255,11 @@ class WebHandler(BaseHandler): kwargs[arg] = value[0] result = function(**kwargs) - if callback: - callback(result) return result except: logger.log('Failed doing webui callback: %s' % (traceback.format_exc()), logger.ERROR) raise - def async_done(self, results): - try: - if results: - self.finish(results) - except: - logger.log('Failed sending webui reponse: %s' % (traceback.format_exc()), logger.DEBUG) - raise - - # post uses get method post = get @@ -1060,6 +1076,64 @@ class Home(WebRoot): if str(pid) != str(sickbeard.PID): return self.redirect('/home/') + def _keeplatestbackup(backupDir): + import glob + files = glob.glob(os.path.join(backupDir,'*.zip')) + if not files: + return True + now = time.time() + newest = files[0], now - os.path.getctime(files[0]) + for file in files[1:]: + age = now - os.path.getctime(file) + if age < newest[1]: + newest = file, age + files.remove(newest[0]) + + for file in files: + os.remove(file) + + # TODO: Merge with backup in helpers + def _backup(backupDir=None): + if backupDir: + source = [os.path.join(sickbeard.DATA_DIR, 'sickbeard.db'), sickbeard.CONFIG_FILE] + source.append(os.path.join(sickbeard.DATA_DIR, 'failed.db')) + source.append(os.path.join(sickbeard.DATA_DIR, 'cache.db')) + target = os.path.join(backupDir, 'sickrage-' + time.strftime('%Y%m%d%H%M%S') + '.zip') + + for (path, dirs, files) in os.walk(sickbeard.CACHE_DIR, topdown=True): + for dirname in dirs: + if path == sickbeard.CACHE_DIR and dirname not in ['images']: + dirs.remove(dirname) + for filename in files: + source.append(os.path.join(path, filename)) + + if helpers.backupConfigZip(source, target, sickbeard.DATA_DIR): + return True + else: + return False + else: + return False + + # Do a system backup + ui.notifications.message('Backup', 'Config backup in progress...') + try: + backupDir = os.path.join(sickbeard.DATA_DIR, 'backup') + if not os.path.isdir(backupDir): + os.mkdir(backupDir) + + _keeplatestbackup(backupDir) + + if _backup(backupDir): + ui.notifications.message('Backup', 'Config backup successful, updating...') + else: + ui.notifications.message('Backup', 'Config backup failed, aborting update') + return self.redirect('/home/') + + except Exception as e: + ui.notifications.message('Backup', 'Config backup failed, aborting update') + logger.log('Update: Config backup failed. Error: {0}'.format(ex(e)),logger.DEBUG) + return self.redirect('/home/') + if sickbeard.versionCheckScheduler.action.update(): # do a hard restart sickbeard.events.put(sickbeard.events.SystemEvent.RESTART) @@ -1071,9 +1145,41 @@ class Home(WebRoot): "Update wasn't successful, not restarting. Check your log for more information.") def branchCheckout(self, branch): - sickbeard.BRANCH = branch - ui.notifications.message('Checking out branch: ', branch) - return self.update(sickbeard.PID) + if sickbeard.BRANCH != branch: + sickbeard.BRANCH = branch + ui.notifications.message('Checking out branch: ', branch) + return self.update(sickbeard.PID) + else: + ui.notifications.message('Already on branch: ', branch) + return self.redirect('/home') + + def getDBcompare(self, branchDest=None): + from lib import requests + from lib.requests.exceptions import RequestException + if not branchDest: + return json.dumps({ "status": "error", 'message': 'branchDest empty' }) + try: + response = requests.get("https://raw.githubusercontent.com/SICKRAGETV/SickRage/" + str(branchDest) +"/sickbeard/databases/mainDB.py") + response.raise_for_status() + match = re.search(r"MAX_DB_VERSION\s=\s(?P<version>\d{2,3})",response.text) + branchDestDBversion = int(match.group('version')) + myDB = db.DBConnection() + branchCurrDBversion = myDB.checkDBVersion() + if branchDestDBversion > branchCurrDBversion: + logger.log(u"Checkout branch has a new DB version - Upgrade", logger.DEBUG) + return json.dumps({ "status": "success", 'message': 'upgrade' }) + elif branchDestDBversion == branchCurrDBversion: + logger.log(u"Checkout branch has the same DB version - Equal", logger.DEBUG) + return json.dumps({ "status": "success", 'message': 'equal' }) + else: + logger.log(u"Checkout branch has an old DB version - Downgrade", logger.DEBUG) + return json.dumps({ "status": "success", 'message': 'downgrade' }) + except RequestException as e: + logger.log(u"Checkout branch couldn't compare DB version - Requests error", logger.ERROR) + return json.dumps({ "status": "error", 'message': 'Requests error' }) + except Exception as e: + logger.log(u"Checkout branch couldn't compare DB version - General exception", logger.ERROR) + return json.dumps({ "status": "error", 'message': 'General exception' }) def displayShow(self, show=None): @@ -1227,6 +1333,7 @@ class Home(WebRoot): rls_require_words=None, anime=None, blackWords=None, whiteWords=None, blacklist=None, whitelist=None, scene=None, defaultEpStatus=None): + anidb_failed = False if show is None: errString = "Invalid show ID: " + str(show) if directCall: @@ -1269,9 +1376,13 @@ class Home(WebRoot): t.blacklist = bwl.blackDict["release_group"] t.groups = [] - if helpers.set_up_anidb_connection(): - anime = adba.Anime(sickbeard.ADBA_CONNECTION, name=showObj.name) - t.groups = anime.get_groups() + if helpers.set_up_anidb_connection() and not anidb_failed: + try: + anime = adba.Anime(sickbeard.ADBA_CONNECTION, name=showObj.name) + t.groups = anime.get_groups() + except Exception as e: + anidb_failed = True + ui.notifications.error('Unable to retreive Fansub Groups from AniDB.') with showObj.lock: t.show = showObj @@ -1328,15 +1439,20 @@ class Home(WebRoot): if whitelist: whitelist = whitelist.split(",") shortWhiteList = [] - if helpers.set_up_anidb_connection(): - for groupName in whitelist: - group = sickbeard.ADBA_CONNECTION.group(gname=groupName) - for line in group.datalines: - if line["shortname"]: - shortWhiteList.append(line["shortname"]) - else: - if not groupName in shortWhiteList: - shortWhiteList.append(groupName) + if helpers.set_up_anidb_connection() and not anidb_failed: + try: + for groupName in whitelist: + group = sickbeard.ADBA_CONNECTION.group(gname=groupName) + for line in group.datalines: + if line["shortname"]: + shortWhiteList.append(line["shortname"]) + else: + if not groupName in shortWhiteList: + shortWhiteList.append(groupName) + except Exception as e: + anidb_failed = True + ui.notifications.error('Unable to retreive data from AniDB.') + shortWhiteList = whitelist else: shortWhiteList = whitelist bwl.set_white_keywords_for("release_group", shortWhiteList) @@ -1346,15 +1462,20 @@ class Home(WebRoot): if blacklist: blacklist = blacklist.split(",") shortBlacklist = [] - if helpers.set_up_anidb_connection(): - for groupName in blacklist: - group = sickbeard.ADBA_CONNECTION.group(gname=groupName) - for line in group.datalines: - if line["shortname"]: - shortBlacklist.append(line["shortname"]) - else: - if not groupName in shortBlacklist: - shortBlacklist.append(groupName) + if helpers.set_up_anidb_connection() and not anidb_failed: + try: + for groupName in blacklist: + group = sickbeard.ADBA_CONNECTION.group(gname=groupName) + for line in group.datalines: + if line["shortname"]: + shortBlacklist.append(line["shortname"]) + else: + if not groupName in shortBlacklist: + shortBlacklist.append(groupName) + except Exception as e: + anidb_failed = True + ui.notifications.error('Unable to retreive data from AniDB.') + shortBlacklist = blacklist else: shortBlacklist = blacklist bwl.set_black_keywords_for("release_group", shortBlacklist) @@ -1474,7 +1595,11 @@ class Home(WebRoot): if sickbeard.USE_TRAKT and sickbeard.TRAKT_SYNC: # remove show from trakt.tv library - sickbeard.traktCheckerScheduler.action.removeShowFromTraktLibrary(showObj) + try: + sickbeard.traktCheckerScheduler.action.removeShowFromTraktLibrary(showObj) + except traktException as e: + logger.log("Trakt: Unable to delete show: {0}. Error: {1}".format(showObj.name, ex(e)),logger.ERROR) + return self._genericMessage("Error", "Unable to delete show: {0}".format(showObj.name)) showObj.deleteShow(bool(full)) @@ -1809,6 +1934,7 @@ class Home(WebRoot): def getManualSearchStatus(self, show=None, season=None): def getEpisodes(searchThread, searchstatus): results = [] + showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(searchThread.show.indexerid)) if isinstance(searchThread, sickbeard.search_queue.ManualSearchQueueItem): results.append({'episode': searchThread.segment.episode, @@ -1816,7 +1942,8 @@ class Home(WebRoot): 'season': searchThread.segment.season, 'searchstatus': searchstatus, 'status': statusStrings[searchThread.segment.status], - 'quality': self.getQualityClass(searchThread.segment)}) + 'quality': self.getQualityClass(searchThread.segment), + 'overview': Overview.overviewStrings[showObj.getOverview(int(searchThread.segment.status or -1))]}) else: for epObj in searchThread.segment: results.append({'episode': epObj.episode, @@ -1824,12 +1951,16 @@ class Home(WebRoot): 'season': epObj.season, 'searchstatus': searchstatus, 'status': statusStrings[epObj.status], - 'quality': self.getQualityClass(epObj)}) + 'quality': self.getQualityClass(epObj), + 'overview': Overview.overviewStrings[showObj.getOverview(int(epObj.status or -1))]}) return results episodes = [] + if not show and not season: + return json.dumps({'show': show, 'episodes': episodes}) + # Queued Searches searchstatus = 'queued' for searchThread in sickbeard.searchQueueScheduler.action.get_all_ep_from_queue(show): @@ -3480,7 +3611,7 @@ class ConfigGeneral(Config): def saveGeneral(self, log_dir=None, log_nr = 5, log_size = 1048576, web_port=None, web_log=None, encryption_version=None, web_ipv6=None, update_shows_on_start=None, trash_remove_show=None, trash_rotate_logs=None, update_frequency=None, - launch_browser=None, web_username=None, + launch_browser=None, showupdate_hour=3, web_username=None, api_key=None, indexer_default=None, timezone_display=None, cpu_preset=None, web_password=None, version_notify=None, enable_https=None, https_cert=None, https_key=None, handle_reverse_proxy=None, sort_article=None, auto_update=None, notify_on_update=None, @@ -3496,6 +3627,7 @@ class ConfigGeneral(Config): sickbeard.PLAY_VIDEOS = config.checkbox_to_value(play_videos) sickbeard.DOWNLOAD_URL = download_url sickbeard.LAUNCH_BROWSER = config.checkbox_to_value(launch_browser) + sickbeard.SHOWUPDATE_HOUR = config.to_int(showupdate_hour) config.change_VERSION_NOTIFY(config.checkbox_to_value(version_notify)) sickbeard.AUTO_UPDATE = config.checkbox_to_value(auto_update) sickbeard.NOTIFY_ON_UPDATE = config.checkbox_to_value(notify_on_update) @@ -3596,13 +3728,18 @@ class ConfigBackupRestore(Config): if backupDir: source = [os.path.join(sickbeard.DATA_DIR, 'sickbeard.db'), sickbeard.CONFIG_FILE] + source.append(os.path.join(sickbeard.DATA_DIR, 'failed.db')) + source.append(os.path.join(sickbeard.DATA_DIR, 'cache.db')) target = os.path.join(backupDir, 'sickrage-' + time.strftime('%Y%m%d%H%M%S') + '.zip') - for (dir, _, files) in os.walk(sickbeard.CACHE_DIR): - for f in files: - source.append(os.path.join(dir, f)) + for (path, dirs, files) in os.walk(sickbeard.CACHE_DIR, topdown=True): + for dirname in dirs: + if path == sickbeard.CACHE_DIR and dirname not in ['images']: + dirs.remove(dirname) + for filename in files: + source.append(os.path.join(path, filename)) - if helpers.makeZip(source, target): + if helpers.backupConfigZip(source, target, sickbeard.DATA_DIR): finalResult += "Successful backup to " + target else: finalResult += "Backup FAILED" @@ -3622,7 +3759,7 @@ class ConfigBackupRestore(Config): source = backupFile target_dir = os.path.join(sickbeard.DATA_DIR, 'restore') - if helpers.extractZip(source, target_dir): + if helpers.restoreConfigZip(source, target_dir): finalResult += "Successfully extracted restore files to " + target_dir finalResult += "<br>Restart sickrage to complete the restore." else: @@ -3652,11 +3789,11 @@ class ConfigSearch(Config): nzbget_host=None, nzbget_use_https=None, backlog_days=None, backlog_frequency=None, dailysearch_frequency=None, nzb_method=None, torrent_method=None, usenet_retention=None, download_propers=None, check_propers_interval=None, allow_high_priority=None, - randomize_providers=None, backlog_startup=None, dailysearch_startup=None, - torrent_dir=None, torrent_username=None, torrent_password=None, torrent_host=None, + randomize_providers=None, backlog_startup=None, use_failed_downloads=None, delete_failed=None, + dailysearch_startup=None, torrent_dir=None, torrent_username=None, torrent_password=None, torrent_host=None, torrent_label=None, torrent_label_anime=None, torrent_path=None, torrent_verify_cert=None, torrent_seed_time=None, torrent_paused=None, torrent_high_bandwidth=None, - torrent_rpcurl=None, ignore_words=None, require_words=None): + torrent_rpcurl=None, torrent_auth_type = None, ignore_words=None, require_words=None): results = [] @@ -3690,6 +3827,8 @@ class ConfigSearch(Config): sickbeard.DAILYSEARCH_STARTUP = config.checkbox_to_value(dailysearch_startup) sickbeard.BACKLOG_STARTUP = config.checkbox_to_value(backlog_startup) + sickbeard.USE_FAILED_DOWNLOADS = config.checkbox_to_value(use_failed_downloads) + sickbeard.DELETE_FAILED = config.checkbox_to_value(delete_failed) sickbeard.SAB_USERNAME = sab_username sickbeard.SAB_PASSWORD = sab_password @@ -3717,6 +3856,7 @@ class ConfigSearch(Config): sickbeard.TORRENT_HIGH_BANDWIDTH = config.checkbox_to_value(torrent_high_bandwidth) sickbeard.TORRENT_HOST = config.clean_url(torrent_host) sickbeard.TORRENT_RPCURL = torrent_rpcurl + sickbeard.TORRENT_AUTH_TYPE = torrent_auth_type sickbeard.save_config() @@ -3745,9 +3885,9 @@ class ConfigPostProcessing(Config): def savePostProcessing(self, naming_pattern=None, naming_multi_ep=None, kodi_data=None, kodi_12plus_data=None, mediabrowser_data=None, sony_ps3_data=None, wdtv_data=None, tivo_data=None, mede8er_data=None, - keep_processed_dir=None, process_method=None, process_automatically=None, + keep_processed_dir=None, process_method=None, del_rar_contents=None, process_automatically=None, rename_episodes=None, airdate_episodes=None, unpack=None, - move_associated_files=None, postpone_if_sync_files=None, nfo_rename=None, + move_associated_files=None, sync_files=None, postpone_if_sync_files=None, nfo_rename=None, tv_download_dir=None, naming_custom_abd=None, naming_anime=None, naming_abd_pattern=None, naming_strip_year=None, use_failed_downloads=None, @@ -3789,10 +3929,12 @@ class ConfigPostProcessing(Config): sickbeard.KEEP_PROCESSED_DIR = config.checkbox_to_value(keep_processed_dir) sickbeard.PROCESS_METHOD = process_method + sickbeard.DELRARCONTENTS = config.checkbox_to_value(del_rar_contents) sickbeard.EXTRA_SCRIPTS = [x.strip() for x in extra_scripts.split('|') if x.strip()] sickbeard.RENAME_EPISODES = config.checkbox_to_value(rename_episodes) sickbeard.AIRDATE_EPISODES = config.checkbox_to_value(airdate_episodes) sickbeard.MOVE_ASSOCIATED_FILES = config.checkbox_to_value(move_associated_files) + sickbeard.SYNC_FILES = sync_files sickbeard.POSTPONE_IF_SYNC_FILES = config.checkbox_to_value(postpone_if_sync_files) sickbeard.NAMING_CUSTOM_ABD = config.checkbox_to_value(naming_custom_abd) sickbeard.NAMING_CUSTOM_SPORTS = config.checkbox_to_value(naming_custom_sports) @@ -4317,6 +4459,19 @@ class ConfigProviders(Config): except: curTorrentProvider.enable_backlog = 0 # these exceptions are actually catching unselected checkboxes + if hasattr(curTorrentProvider, 'cat'): + try: + curTorrentProvider.cat = int(str(kwargs[curTorrentProvider.getID() + '_cat']).strip()) + except: + curTorrentProvider.cat = 0 + + if hasattr(curTorrentProvider, 'subtitle'): + try: + curTorrentProvider.subtitle = config.checkbox_to_value( + kwargs[curTorrentProvider.getID() + '_subtitle']) + except: + curTorrentProvider.subtitle = 0 + for curNzbProvider in [curProvider for curProvider in sickbeard.providers.sortedProviderList() if curProvider.providerType == sickbeard.GenericProvider.NZB]: @@ -4723,23 +4878,45 @@ class ErrorLogs(WebRoot): return t.respond() def haveErrors(self): - if len(classes.ErrorViewer.errors) > 0: + if len(classes.ErrorViewer.errors) > 0 and sickbeard.GIT_USERNAME and sickbeard.GIT_PASSWORD and sickbeard.GIT_AUTOISSUES == 1: return True def clearerrors(self): classes.ErrorViewer.clear() return self.redirect("/errorlogs/") - def viewlog(self, minLevel=logger.INFO, maxLines=500): + def viewlog(self, minLevel=logger.INFO, logFilter="<NONE>",logSearch=None, maxLines=500): t = PageTemplate(rh=self, file="viewlogs.tmpl") t.submenu = self.ErrorLogsMenu() minLevel = int(minLevel) + logNameFilters = {'<NONE>': u'<No Filter>', + 'DAILYSEARCHER': u'Daily Searcher', + 'BACKLOG': u'Backlog', + 'SHOWUPDATER': u'Show Updater', + 'CHECKVERSION': u'Check Version', + 'SHOWQUEUE': u'Show Queue', + 'SEARCHQUEUE': u'Search Queue', + 'FINDPROPERS': u'Find Propers', + 'POSTPROCESSER': u'Postprocesser', + 'FINDSUBTITLES': u'Find Subtitles', + 'TRAKTCHECKER': u'Trakt Checker', + 'EVENT': u'Event', + 'ERROR': u'Error', + 'TORNADO': u'Tornado', + 'Thread': u'Thread', + 'MAIN': u'Main' + } + + if logFilter not in logNameFilters: + logFilter = '<NONE>' + + data = [] if os.path.isfile(logger.logFile): - with ek.ek(open, logger.logFile) as f: + with ek.ek(codecs.open, *[logger.logFile, 'r', 'utf-8']) as f: data = f.readlines() regex = "^(\d\d\d\d)\-(\d\d)\-(\d\d)\s*(\d\d)\:(\d\d):(\d\d)\s*([A-Z]+)\s*(.+?)\s*\:\:\s*(.*)$" @@ -4757,11 +4934,15 @@ class ErrorLogs(WebRoot): if match: level = match.group(7) + logName = match.group(8) if level not in logger.reverseNames: lastLine = False continue - if logger.reverseNames[level] >= minLevel: + if logSearch and logSearch.lower() in x.lower(): + lastLine = True + finalData.append(x) + elif not logSearch and logger.reverseNames[level] >= minLevel and (logFilter == '<NONE>' or logName.startswith(logFilter)): lastLine = True finalData.append(x) else: @@ -4780,6 +4961,9 @@ class ErrorLogs(WebRoot): t.logLines = result t.minLevel = minLevel + t.logNameFilters = logNameFilters + t.logFilter = logFilter + t.logSearch = logSearch return t.respond()