administrator/0000755774276600352300000000000011564472367017464 5ustar nf.mortgageoriginatorseminarswwwadministrator/backups/0000755774276600352300000000000011564474763021116 5ustar nf.mortgageoriginatorseminarswwwadministrator/backups/index.html0000644774276600352300000000000011564474663023100 0ustar nf.mortgageoriginatorseminarswwwamember/0000755774276600352300000000000011717042277016205 5ustar nf.mortgageoriginatorseminarswwwamember/aff.php0000644774276600352300000002212611613276244017453 0ustar nf.mortgageoriginatorseminarswwwget_user($member_id); $u['is_affiliate'] = 1; $db->update_user($member_id, $u); if($config['aff']['mail_signup_user']) check_aff_signup_email_sent($member_id); return true; } function display_links($member_id){ global $config, $t, $db; /// $links = array(); foreach ((array)$config['aff']['links'] as $k => $l){ $l['url'] = aff_make_url($l['url'], 'l'.$k, $member_id); $l['code'] = "$l[title]"; $links[ ] = $l; } $t->assign('links', $links); /// $banners = array(); foreach ((array)$config['aff']['banners'] as $k=>$l){ $l['url'] = aff_make_url($l['url'], 'b'.$k, $member_id); $alt = htmlspecialchars($l[alt]); $wc = ($w=$l['width']) ? "width=$w" : ""; $hc = ($h=$l['height']) ? "height=$h" : ""; $l['code'] = "\"$alt\""; $banners[] = $l; } $t->assign('banners', $banners); /// $t->display('aff_links.html'); } function get_ym_options(){ $res = array(); $y = date('Y'); $m = date('m'); for ($i=0;$i<36;$i++){ $res[ $y."_".$m ] = date('F 01-t, Y', strtotime("{$y}-{$m}-01")); $m--; if ($m <= 0) { $m = 12; $y--; } } return $res; } function get_default_ym(){ $y = date('Y'); $m = date('m'); $m -= 0; if ($m <= 0){ $y--; $m = 12 - $m; } return "{$y}_{$m}"; } function display_stats($member_id, $vars){ global $db, $t; $t->assign('year_month_options', get_ym_options()); $t->assign('default_month', get_default_ym()); if ($vars['year_month'] == '') $vars['year_month'] = get_default_ym(); list($y, $m) = split('_', $vars['year_month']); $y = sprintf('%04d', $y); $m = sprintf('%02d', $m); $dat1 = "{$y}-{$m}-01"; $dat2 = date('Y-m-t', strtotime($dat1)); $dattm1 = date('Ymd000000', strtotime($dat1)); $dattm2 = date('Ymd235959', strtotime($dat2)); $totaldays = date('t', strtotime($dat1)); $days = array(); $total = array(); for ($i=1;$i<=$totaldays;$i++) $days[$i] = array('dat' => sprintf("$y-$m-%02d", $i)); // get clicks for the month $q = $db->query("SELECT DAYOFMONTH(ac.time), COUNT(log_id), COUNT(DISTINCT(remote_addr)) FROM {$db->config[prefix]}aff_clicks ac WHERE aff_id=$member_id AND ac.time BETWEEN $dattm1 AND $dattm2 GROUP BY DAYOFMONTH(ac.time) "); while (list($d, $r, $u) = mysql_fetch_row($q)){ $days[$d]['raw'] = $r; $days[$d]['uniq'] = $u; } // get total clicks for the month $q = $db->query("SELECT COUNT(log_id), COUNT(DISTINCT(remote_addr)) FROM {$db->config[prefix]}aff_clicks ac WHERE aff_id=$member_id AND ac.time BETWEEN $dattm1 AND $dattm2 "); while (list($r, $u) = mysql_fetch_row($q)){ $total['raw'] = $r; $total['uniq'] = $u; } // get comissions for the month $q = $db->query("SELECT DAYOFMONTH(ac.date), COUNT(commission_id), SUM(IF(record_type='debit', amount, 0)), SUM(IF(record_type='credit', amount, 0)), SUM(IF(record_type='debit', 1, 0)) FROM {$db->config[prefix]}aff_commission ac WHERE aff_id=$member_id AND ac.date BETWEEN '$dat1' AND '$dat2' GROUP BY DAYOFMONTH(ac.date) "); while (list($d, $cnt, $deb, $cre, $deb_count) = mysql_fetch_row($q)){ $days[$d]['trans'] = $cnt; $days[$d]['debit'] = $deb != 0 ? -$deb." ($deb_count)" : ''; $days[$d]['credit'] = $cre; if ($deb || $cre) $days[$d]['total'] = $cre - $deb; $total['trans'] += $cnt; $total['debit'] += $deb; $total['credit'] += $cre; $total['total'] += $days[$d]['total']; } $total['debit'] = $total['debit'] != 0 ? -$total['debit'] : ''; $t->assign('days', $days); $t->assign('total', $total); /// top 20 referrers $q = $db->query("SELECT referrer, COUNT(log_id) as clog_id, COUNT(DISTINCT(remote_addr)) as cremote_addr FROM {$db->config[prefix]}aff_clicks ac WHERE aff_id=$member_id AND referrer > '' AND ac.time BETWEEN $dattm1 AND $dattm2 GROUP BY referrer ORDER BY clog_id DESC, cremote_addr DESC LIMIT 0,20 "); $refs = array(); while (list($ref, $raw, $uniq) = mysql_fetch_row($q)){ $refs[] = array( 'raw' => $raw, 'uniq' => $uniq, 'ref' => $ref ); } $t->assign('refs', $refs); $t->display("aff_stats.html"); } function display_payout_info($member_id, $u, $err=array()){ global $t, $config, $db; $t->assign('u', $u); $t->assign('error', $err); $t->assign('aff_payout_types', $m=aff_get_payout_methods(1)); $t->display("aff_payout_info.html"); } function update_payout_info($member_id, $u){ global $db; foreach ($u as $k => $v) $u[$k] = str_replace('"', "'", strip_tags($v)); $err = array(); $user = $db->get_user($member_id); $user['aff_payout_type'] = $u['aff_payout_type']; if ($u['aff_payout_type'] == 'paypal'){ if ($u['aff_paypal_email'] == ''){ $err[] = _AFF_ERROR_1; return $err; } $user['data']['aff_paypal_email'] = $u['aff_paypal_email']; } elseif ($u['aff_payout_type'] == 'check'){ if ($u['aff_check_payable_to'] == ''){ $err[] = _AFF_ERROR_2; return $err; } $user['data']['aff_check_payable_to'] = $u['aff_check_payable_to']; $user['street'] = $u['street']; $user['city'] = $u['city']; $user['state'] = $u['state']; $user['zip'] = $u['zip']; $user['country'] = $u['country']; } elseif ($u['aff_payout_type'] == 'stormpay'){ if ($u['aff_stormpay_email'] == ''){ $err[] = _AFF_ERROR_3; return $err; } $user['data']['aff_stormpay_email'] = $u['aff_stormpay_email']; } elseif ($u['aff_payout_type'] == 'ikobo'){ if ($u['aff_ikobo_email'] == ''){ $err[] = _AFF_ERROR_4; return $err; } $user['data']['aff_ikobo_email'] = $u['aff_ikobo_email']; } elseif ($u['aff_payout_type'] == 'moneybookers'){ if ($u['aff_moneybookers_email'] == ''){ $err[] = _AFF_ERROR_5; return $err; } $user['data']['aff_moneybookers_email'] = $u['aff_moneybookers_email']; } elseif ($u['aff_payout_type'] == 'egold'){ if ($u['aff_egold_id'] == ''){ $err[] = _AFF_ERROR_6; return $err; } $user['data']['aff_egold_id'] = $u['aff_egold_id']; } elseif ($u['aff_payout_type'] == 'safepay'){ if ($u['aff_safepay_email'] == ''){ $err[] = _AFF_ERROR_9; return $err; } $user['data']['aff_safepay_email'] = $u['aff_safepay_email']; } elseif ($u['aff_payout_type'] == ''){ // } else { $err[] = _AFF_ERROR_7; return; // unknown payout type } $db->update_user($member_id, $user); return $err; } switch ($vars['action']){ case 'enable_aff': enable_aff($member_id); display_links($member_id); break; case 'links': display_links($member_id); break; case 'stats': display_stats($member_id, $vars); break; case 'payout_info': if ($vars['save'] && !$vars['type_change']){ $u = $vars; $u['data'] = $vars; $err = update_payout_info($member_id, $vars); if (!$err) { $u = $db->get_user($member_id); } } else $u = $db->get_user($member_id); if ($vars['type_change']) $u['aff_payout_type'] = $vars['aff_payout_type']; display_payout_info($member_id, $u, $err); break; default: fatal_error(sprintf(_AFF_ERROR_8,$vars[action]), 0); } ?> amember/aff.inc.php0000644774276600352300000004756311573171450020235 0ustar nf.mortgageoriginatorseminarswww 'PayPal payment', 'check' => 'Offline check', 'egold' => 'E-Gold', 'stormpay' => 'StormPay', 'ikobo' => 'iKobo', 'moneybookers' => 'MoneyBookers', 'safepay' => 'SafePaySolutions' ); function aff_get_payout_methods($only_enabled=0){ global $config; $res = $GLOBALS['payout_methods']; if ($only_enabled){ foreach ($res as $k=>$v) if (!in_array($k, (array)$config['aff']['payout_methods'])) unset($res[$k]); } return $res; } function aff_config(){ global $config; config_set_notebook_comment('Affiliates', 'affiliate program configuration'); add_config_field('aff.payout_methods', 'Accepted Payout methods', 'multi_select', "affiliate can choose a method for payout comissions.
If nothing will be selected, comissions will not be included to automated
payout report. ", "Affiliates", '', '', '', array( 'store_type' => 1, 'options' => aff_get_payout_methods() )); add_config_field('aff.aff_commission', 'Affiliate commission for first payment', 'integer', "affiliate comissions for first payment, ex.: 1.5 or 2.5%", "Affiliates", '', '', ''); add_config_field('aff.aff_commission_rec', 'Affiliate commission for the following payments', 'integer', "affiliate comissions for the following payments, ex.: 1.5 or 2.5%", "Affiliates", '', '', ''); add_config_field('aff.aff_commission2', '2 Tier - Affiliate commission for the first payment', 'integer', 'affiliate comissions for referrer of the affiliate, can be set to
percentage of commission received by immediate affiliate only, ex.: 1.5 or 15%
in first case 2 tier affiliate will get USD 1.5 for each sale,
in second case 2 tier affiliate will receive 15% of all related
affiliate commissions', "Affiliates", '', '', ''); add_config_field('aff.aff_commission_rec2', '2 Tier - Affiliate commission for the following payments', 'integer', 'affiliate comissions for referrer of the affiliate, can be set to
percentage of commission received by immediate affiliate only, ex.: 1.5 or 15%
in first case 2 tier affiliate will get USD 1.5 for each sale,
in second case 2 tier affiliate will receive 15% of all related
affiliate commissions', "Affiliates", '', '', ''); add_config_field('aff.cookie_lifetime', 'Affiliate cookie lifetime', 'integer', "how long (in days) store cookies about referrer.
So if customer will return to the site later, comission will be
paid to referring affiliate. ", "Affiliates", '', '', '', array('default'=>365)); add_config_field('aff.only_first', 'Pay only first commission', 'checkbox', "affiliate will get commision only for first purchase.
In case of recurring payments, only one (first) commission will
be generated. ", "Affiliates", '', '', '', array( 'store_type' => 1 )); add_config_field('aff.do_not_pay_for_free_subscriptions', 'Do not give commision for free subscriptions', 'select', "sale commission will not be credited to affiliate account
if user subscribed to free subscription. Of course, it only affects
'fixed' affiliate commissions. ", "Affiliates", '', '', '', array( 'store_type' => 1, 'options' => array('' => 'Give Commission even for free subscriptions', 1 => 'Do not give commissions for free subscriptions') )); add_config_field('aff.signup_type', 'Affiliates Signup Type', 'select', "affiliate will get commision only for first purchase.
In case of recurring payments, only one (first) commission will
be generated. ", "Affiliates", '', '', '', array( 'store_type' => 1, 'options' => array('' => 'Default - user have to click link to become affiliate', 1 => 'All new members automatically become affiliates', 2 => 'Only admin can enable user as an affiliate') )); add_config_field('aff.mail_sale_admin', 'E-Mail commission to admin', 'checkbox', "when new sale commission credited to affiliate account
send an e-mail message to admin ", "Affiliates", '', 'email_checkbox_get', '', array( 'store_type' => 1, )); add_config_field('aff.mail_sale_user', 'E-Mail commission to customer', 'checkbox', "when new sale commission credited to affiliate account
send an e-mail message to affiliate ", "Affiliates", '', 'email_checkbox_get', '', array( 'store_type' => 1, )); add_config_field('aff.mail_signup_user', 'Send Signup E-Mail to Affiliate', 'checkbox', "send email when affiliate will signup ", "Affiliates", '', 'email_checkbox_get', '', array( 'store_type' => 1, )); } function aff_set_cookie($aff_id){ global $config; $aff_id = intval($aff_id); if (!$aff_id) return; $d = $_SERVER['HTTP_HOST']; $k = 'amember_aff_id'; $v = $aff_id; $tm = time() + $config['aff']['cookie_lifetime'] * 3600 * 24; if (preg_match('/([^\.]+)\.(org|com|net|biz|info)$/', $d, $regs)) setcookie($k,$v,$tm,"/",".{$regs[1]}.{$regs[2]}"); else setcookie($k,$v,$tm,"/"); } function aff_decrypt($s){ // easy encryption to hide texts in URL $from = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $to = 'nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM'; return strtr($s, $from, $to); } function aff_encrypt($s){ // easy encryption to hide texts in URL return aff_decrypt($s); } function aff_make_url($url, $link_id, $aff_id){ global $config; return "$config[root_url]/go.php?r=$aff_id&i=$link_id"; // return "$config[root_url]/go.php?r=$aff_id&l=".urlencode(aff_encrypt($url)); } function aff_get_commission($product_id, $is_first, $aff_id=0, $paid='', $tier=1){ global $config, $db; $pr = $db->get_product($product_id); $fa = ($tier == 1) ? '' : $tier; $cf = ($pr['aff_commission'.$fa] != '') ? $pr['aff_commission'.$fa] : $config['aff']['aff_commission'.$fa]; $cr = ($pr['aff_commission_rec'.$fa] != '') ? $pr['aff_commission_rec'.$fa] : $config['aff']['aff_commission_rec'.$fa]; $cexp = $is_first ? $cf : $cr; if (preg_match('/^([\d\.]+)\s*\%$/', $cexp, $regs)){ // % return round($regs[1] * 0.01 * $paid, 2); } else { // absolute return $cexp; } return 0; } function add_affiliate_commission($payment_id, $receipt_id='', $amount=''){ global $db, $config; if ($GLOBALS['amember_ignore_aff_commission'] > 0) return; $oldp = $db->get_payment($payment_id); /// affiliate thing if (!$oldp['member_id']) return; $u = $db->get_user($oldp['member_id']); $aff_id = $u['aff_id']; if ($aff_id){ if ($u['member_id'] == $aff_id) return; // don't credit affiliate himself $pl = $db->get_user_payments($oldp['member_id'], 1); $is_first = 1; if (count($pl)) foreach ($pl as $v){ $orig_id = $v['data'][0]['ORIG_ID']; if ($v['payment_id'] == $payment_id) continue; if ($orig_id && ($oldp['payment_id'] == $orig_id)) continue; if ($orig_id && ($oldp['data'][0]['ORIG_ID'] == $orig_id)) continue; $is_first = 0; break; } if ($config['aff']['only_first'] && !$is_first){ return; } if ($amount == '') $amount = $oldp['amount']; if ($amount<=0.0 && $config['aff']['do_not_pay_for_free_subscriptions']) return; $commission = aff_get_commission($oldp['product_id'], $is_first, $aff_id, $amount, 1); if ($commission){ $db->aff_add_commission($aff_id, $commission, $payment_id, $receipt_id, $oldp['product_id'], $is_first, false, 1); // calculate 2-tier commission $aff = $db->get_user($aff_id); $aff_id2 = $aff['aff_id']; // find second-tier affiliate if(!$aff_id2) return; $commission2 = aff_get_commission($oldp['product_id'], $is_first, $aff_id, $commission, 2); if(!$commission2) return; $db->aff_add_commission($aff_id2, $commission2, $payment_id, $receipt_id, $oldp['product_id'], $is_first, false, 2); } } } function aff_get_payout($dat2, $payout_method){ global $db, $config; $payout_method = $db->escape($payout_method); if ($payout_method == 'ALL') $payout_where = " 1 "; else $payout_where = " m.aff_payout_type = '$payout_method' "; $prefix = $db->config['prefix']; $q = $db->query($s = "SELECT m.*, SUM(c.amount) as credit_amount FROM {$prefix}members m LEFT JOIN {$prefix}aff_commission c ON (m.member_id = c.aff_id AND c.record_type='credit' AND ifnull(c.payout_id,'')='' AND c.date <= '$dat2') WHERE $payout_where GROUP BY m.member_id HAVING credit_amount > 0 "); $rows = array(); while ($r = mysql_fetch_assoc($q)){ if ($r['data']) $r['data'] = $db->decode_data($r['data']); $rows[$r['member_id']] = $r; } ### $q = $db->query($s = "SELECT m.*, SUM(c1.amount) as debit_amount, SUM(IF(record_type='debit', 1, 0)) as debit_count FROM {$prefix}members m LEFT JOIN {$prefix}aff_commission c1 ON (m.member_id = c1.aff_id AND c1.record_type='debit' AND ifnull(c1.payout_id, '') = '' AND c1.date <= '$dat2') WHERE $payout_where GROUP BY m.member_id HAVING debit_amount > 0 "); while ($r = mysql_fetch_assoc($q)){ $i = $r['member_id']; if ($rows[$i]['member_id']) $rows[$i]['debit_amount'] = $r['debit_amount'] != 0 ? -$r['debit_amount']." (".$r['debit_count'].")" : ''; else { $r['credit_amount'] = 0.0; $rows[$i] = $r; } } foreach ($rows as $k=>$r){ $r['account_id'] = ""; switch ($r['aff_payout_type']) { case 'stormpay': if ($payout_method == 'ALL') $r['account_id'] .= 'StormPay: '; $r['account_id'] .= $r['data']['aff_stormpay_email']; break; case 'ikobo': if ($payout_method == 'ALL') $r['account_id'] .= 'iKobo: '; $r['account_id'] .= $r['data']['aff_ikobo_email']; break; case 'moneybookers': if ($payout_method == 'ALL') $r['account_id'] .= 'MoneyBookers: '; $r['account_id'] .= $r['data']['aff_moneybookers_email']; break; case 'egold': if ($payout_method == 'ALL') $r['account_id'] .= 'E-Gold: '; $r['account_id'] .= $r['data']['aff_egold_id']; break; case 'paypal': if ($payout_method == 'ALL') $r['account_id'] .= 'PayPal: '; $r['account_id'] .= $r['data']['aff_paypal_email']; break; case 'safepay': if ($payout_method == 'ALL') $r['account_id'] .= 'SafePaySolutions: '; $r['account_id'] .= $r['data']['aff_safepay_email']; break; default: $r['account_id'] = ' '; break; } $rows[$k] = $r; $rows[$k]['to_pay'] = $s = sprintf('%.2f', $r['credit_amount'] + $r['debit_amount']); if (!$s) $rows[$k]['to_pay'] = ''; } return $rows; } function aff_pay_commissions($dat2, $rows, $payout_id){ global $db; $payout_id = $db->escape($payout_id); foreach ($rows as $k=>$r){ $db->query("UPDATE {$db->config[prefix]}aff_commission SET payout_id='$payout_id' WHERE aff_id='$r[member_id]' AND date <= '$dat2' AND payout_id IS NULL "); } } function aff_pay_commission_paypal($dat1, $dat2, $payout_method, $rows){ header('Cache-Control: maxage=3600'); header('Pragma: public'); header("Content-type: application/csv"); $tm = time(); header("Content-Disposition: attachment; filename=paypal-commission-$tm.txt"); foreach ($rows as $r){ $r['to_pay'] = sprintf('%.2f', $r['to_pay']); print "{$r[data][aff_paypal_email]}\t$r[to_pay]\tUSD\t$r[member_id]\tAffiliate commission for $dat1 - $dat2\r\n"; } } function aff_pay_commission_check($dat1, $dat2, $payout_method, $rows){ header('Cache-Control: maxage=3600'); header('Pragma: public'); header("Content-type: application/csv"); $tm = time(); header("Content-Disposition: attachment; filename=check-commission-$tm.csv"); print "First Name;Last Name;Street Address;City;State;ZIP;Country;Check Amount\n"; foreach ($rows as $r){ $r['to_pay'] = sprintf('%.2f', $r['to_pay']); print "$r[name_f];$r[name_l];$r[street];$r[city];$r[state];$r[zip];$r[country];$r[to_pay]\n"; } } function aff_pay_commission_stormpay($dat1, $dat2, $payout_method, $rows){ header('Cache-Control: maxage=3600'); header('Pragma: public'); header("Content-type: application/csv"); $tm = time(); header("Content-Disposition: attachment; filename=stormpay-commission-$tm.csv"); print "StormPay Account ID; Amount\n"; foreach ($rows as $r){ $r['to_pay'] = sprintf('%.2f', $r['to_pay']); print "{$r[data][aff_stormpay_email]};$r[to_pay]\n"; } } function aff_pay_commission_ikobo($dat1, $dat2, $payout_method, $rows){ header('Cache-Control: maxage=3600'); header('Pragma: public'); header("Content-type: application/csv"); $tm = time(); header("Content-Disposition: attachment; filename=ikobo-commission-$tm.csv"); print "iKobo Account ID; Amount\n"; foreach ($rows as $r){ $r['to_pay'] = sprintf('%.2f', $r['to_pay']); print "{$r[data][aff_ikobo_email]};$r[to_pay]\n"; } } function aff_pay_commission_moneybookers($dat1, $dat2, $payout_method, $rows){ header('Cache-Control: maxage=3600'); header('Pragma: public'); header("Content-type: application/csv"); $tm = time(); header("Content-Disposition: attachment; filename=moneybookers-commission-$tm.csv"); print "MoneyBookers Account ID; Amount\n"; foreach ($rows as $r){ $r['to_pay'] = sprintf('%.2f', $r['to_pay']); print "{$r[data][aff_moneybookers_email]};$r[to_pay]\n"; } } function aff_pay_commission_egold($dat1, $dat2, $payout_method, $rows){ global $db; header('Cache-Control: maxage=3600'); header('Pragma: public'); header("Content-type: application/csv"); $tm = time(); header("Content-Disposition: attachment; filename=egold-commission-$tm.csv"); print "E-Gold Account ID; Amount\n"; foreach ($rows as $r){ $r['to_pay'] = sprintf('%.2f', $r['to_pay']); print "{$r[data][aff_egold_id]};$r[to_pay]\n"; } } function aff_pay_commission_safepay($dat1, $dat2, $payout_method, $rows){ header('Cache-Control: maxage=3600'); header('Pragma: public'); header("Content-type: application/csv"); $tm = time(); header("Content-Disposition: attachment; filename=safepay-commission-$tm.txt"); foreach ($rows as $r){ $r['to_pay'] = sprintf('%.2f', $r['to_pay']); print "\"{$r[data][aff_safepay_email]}\";\"$r[to_pay]\";\"Affiliate commission for $dat1 - $dat2\"\r\n"; } } function aff_get_member_links($u){ global $config; if (!$u['is_affiliate'] && ($config['aff']['signup_type'] == '')){ return array($config['root_url']."/aff.php?action=enable_aff" => _AFF_ADVERTISE_SITE); } elseif ($u['is_affiliate']) { return array($config['root_url']."/aff_member.php" => _AFF_MEMBER_AREA); } } function aff_make_affiliate($member_id){ global $db, $_AFF_MAKE_AFFILIATE,$config; if ($_AFF_MAKE_AFFILIATE) return; if ($member_id <= 0) return; $u = $db->get_user($member_id); $u['is_affiliate'] = 1; $_AFF_MAKE_AFFILIATE = 1; $db->update_user($member_id, $u); if($config['aff']['mail_signup_user']) check_aff_signup_email_sent($member_id); unset($_AFF_MAKE_AFFILIATE); } global $config; if ($config['use_affiliates']){ /**/ add_product_field('aff_commission', 'Affiliate commission for first payment', 'text', 'affiliate comissions for first payment, ex.: 1.5 or 2.5%'); add_product_field('aff_commission_rec', 'Affiliate commission for the following payments', 'text', 'affiliate comissions for following payments, ex.: 0 or 5%'); add_product_field('aff_commission2', '2 Tier - Affiliate commission for first payment', 'text', 'affiliate comissions for referrer of the affiliate'); add_product_field('aff_commission_rec2', '2 Tier - Affiliate commission for the following payments', 'text', 'affiliate comissions for referrer of the affiliate'); add_member_field( 'aff_signup_email_sent', 'Affiliate Signup Email Sent', 'hidden', '', '', array('hidden_anywhere' => 1)); /**/ if (in_array('paypal', (array)$config['aff']['payout_methods'])){ add_member_field('aff_paypal_email', _AFF_MEMBER_F1_1, 'text', '', '', array('hidden_anywhere' => 1)); } if (in_array('stormpay', (array)$config['aff']['payout_methods'])){ add_member_field('aff_stormpay_email', _AFF_MEMBER_F2_1, 'text', '', '', array('hidden_anywhere' => 1)); } if (in_array('ikobo', (array)$config['aff']['payout_methods'])){ add_member_field('aff_ikobo_email', _AFF_MEMBER_F3_1, 'text', '', '', array('hidden_anywhere' => 1)); } if (in_array('moneybookers', (array)$config['aff']['payout_methods'])){ add_member_field('aff_moneybookers_email', _AFF_MEMBER_F4_1, 'text', '', '', array('hidden_anywhere' => 1)); } if (in_array('egold', (array)$config['aff']['payout_methods'])){ add_member_field('aff_egold_id', _AFF_MEMBER_F5_1, 'text', '', '', array('hidden_anywhere' => 1)); } if (in_array('check', (array)$config['aff']['payout_methods'])){ add_member_field('aff_check_payable_to', _AFF_MEMBER_F6_1, 'text', '', '', array('hidden_anywhere' => 1)); } if (in_array('safepay', (array)$config['aff']['payout_methods'])){ add_member_field('aff_safepay_email', _AFF_MEMBER_F7_1, 'text', '', '', array('hidden_anywhere' => 1)); } setup_plugin_hook('finish_waiting_payment', 'add_affiliate_commission'); setup_plugin_hook('get_member_links', 'aff_get_member_links'); if ($config['aff']['signup_type'] == 1){ setup_plugin_hook('update_users', 'aff_make_affiliate'); } } function check_aff_signup_email_sent($member_id){ global $db,$config; $user = $db->get_user($member_id); if(!$user['data']['aff_signup_email_sent']){ mail_signup_affiliate($member_id); $user['data']['aff_signup_email_sent']++; $db->update_user($member_id, $user); } } ?>amember/aff_member.php0000644774276600352300000001276311573171450021006 0ustar nf.mortgageoriginatorseminarswwwget_user($member_id); if ($u['is_affiliate'] == '0') { //fatal_error ('Error. Affiliate members area only.'); $url = $config['root_url'] . "/member.php"; html_redirect($url, 0, _MEMBER_PLEASE_WAIT, _MEMBER_REDIRECTING); exit(); } if ($member_id <= 0) die(_AFF_INTERNAL_ERROR); $vars = get_input_vars(); if (($_SESSION['_amember_user']['email_verified'] < 0) && ($config['verify_email'])){ $u = $_SESSION['_amember_user']; $v = md5($u['member_id'].$u['login'].$u['email']); fatal_error(sprintf(_MEMBER_ERROR_1,"
","
","
","", ""), 1,1); } /// redirect to make F5 key (Refresh) working if (strlen($_POST['amember_pass']) && ($_SERVER["REQUEST_METHOD"] == 'POST')){ $url = $PHP_SELF; srand(time()); if (!preg_match('/\?/', $url)) $url .= "?r=". rand(10000,99999); html_redirect($url, 0, _MEMBER_PLEASE_WAIT, _MEMBER_REDIRECTING); exit(); } //////////////////////////////////////////////////////////////////////// function display_stats($member_id, $vars){ global $db, $t,$config; $y = date('Y'); $m = date('n'); $months = array(); $total = array(); for ($i=0;$i<12;$i++) { //$months[$y."-".$m] = array( 'dat' => date( 'F 0-t, Y', strtotime("{$y}-{$m}-01") ) ); $months[$y."_".$m] = array( 'dat' => date( 'F, Y', strtotime("{$y}-{$m}-01") ) ); $m--; if ($m <= 0) { $m = 12; $y--; } } $m = sprintf('%02d', $m); $dat1 = "{$y}-{$m}-01"; $dat2 = date('Y-m-t'); $dattm1 = date('Ym01000000', strtotime($dat1)); $dattm2 = date('Ymt235959', strtotime($dat2)); // get clicks for the month $q = $db->query("SELECT CONCAT(YEAR(ac.time),'_',MONTH(ac.time)) AS point, COUNT(log_id), COUNT(DISTINCT(remote_addr)) FROM {$db->config[prefix]}aff_clicks ac WHERE aff_id=$member_id AND ac.time BETWEEN $dattm1 AND $dattm2 GROUP BY point "); while (list($d, $r, $u) = mysql_fetch_row($q)){ $months[$d]['raw'] = $r; $months[$d]['uniq'] = $u; } // get total clicks for the month $q = $db->query("SELECT COUNT(log_id), COUNT(DISTINCT(remote_addr)) FROM {$db->config[prefix]}aff_clicks ac WHERE aff_id=$member_id AND ac.time BETWEEN $dattm1 AND $dattm2 "); while (list($r, $u) = mysql_fetch_row($q)){ $total['raw'] = $r; $total['uniq'] = $u; } // get comissions for the month $q = $db->query("SELECT CONCAT(YEAR(ac.date),'_',MONTH(ac.date)) AS point, COUNT(commission_id), SUM(IF(record_type='debit', amount, 0)), SUM(IF(record_type='credit', amount, 0)) FROM {$db->config[prefix]}aff_commission ac WHERE aff_id=$member_id AND ac.date BETWEEN '$dat1' AND '$dat2' GROUP BY point "); while (list($d, $cnt, $deb, $cre) = mysql_fetch_row($q)){ $months[$d]['trans'] = $cnt; $months[$d]['debit'] = $deb != 0 ? -$deb : ''; $months[$d]['credit'] = $cre; if ($deb || $cre) //$months[$d]['total'] = $cre + $deb; $months[$d]['total'] = $cre - $deb; $total['trans'] += $cnt; $total['debit'] += $deb; $total['credit'] += $cre; $total['total'] += $months[$d]['total']; } $total['debit'] = $total['debit'] != 0 ? -$total['debit'] : ''; $t->assign('months', $months); $t->assign('total', $total); $q = $db->query("select payout_id, sum(if(record_type='credit', amount, -amount)) as pamount from {$db->config[prefix]}aff_commission where aff_id=$member_id and payout_id != '' and payout_id is not null group by payout_id order by payout_id desc"); while($r = mysql_fetch_assoc($q)){ $d = strtotime($r[payout_id]); $r[payout_id] = strftime($config[date_format], $d); $payouts[] = $r; } $t->assign("payouts", $payouts); return $t->fetch("aff_month_stats.html"); } ///////////////////////// MAIN ///////////////////////////////////////// $_amember_id = $_SESSION['_amember_id']; $vars = get_input_vars(); $aff_stats = display_stats($member_id, $vars); //$member_links = plugin_get_member_links($_SESSION['_amember_user']); $member_links = array($config['root_url']."/aff.php?action=links" => _AFF_GET_BANS_LINKS, $config['root_url']."/aff.php?action=stats" => _AFF_REVIEW_STAT, $config['root_url']."/aff.php?action=payout_info" => _AFF_UPDATE_PAYOUT ); $t->assign('member_links', $member_links); $t->assign('aff_stats', $aff_stats); $t->display('aff_member.html'); ?> amember/aff_signup.php0000644774276600352300000002421111573171450021033 0ustar nf.mortgageoriginatorseminarswww"]/', $vars['name_f'])){ $error[] = _SIGNUP_PLEASE_ENTER_FNAME; } if (!strlen($vars['name_l'])){ $error[] = _SIGNUP_PLEASE_ENTER_LNAME; } if (preg_match('/[<>"]/', $vars['name_l'])){ $error[] = _SIGNUP_PLEASE_ENTER_LNAME; } if (preg_match('/[^0-9a-zA-Z_ ]+/', $vars['login'])){ $error[] = _SIGNUP_INVALID_USERNAME; } elseif (strlen($vars['login']) < $config['login_min_length']){ $error[] = sprintf(_SIGNUP_INVALID_USERNAME_2,$config['login_min_length']); } elseif (!$member_id=$db->check_uniq_login($vars['login'], $vars['email'], $vars['pass0'], 1)){ $error[] = sprintf(_SIGNUP_INVALID_USERNAME_3,$vars[login]); } if (!check_email($vars['email'])){ $error[] = _SIGNUP_PLEASE_ENTER_EMAIL; } elseif (($config['unique_email'] && $member_id <= 0) && $db->users_find_by_string($vars['email'], 'email', 1)){ $error[] = _SIGNUP_INVALID_EMAIL_1.'
'.sprintf(_SIGNUP_INVALID_EMAIL_2,'','','
'); } if (!strlen($vars['pass0'])){ $error[] = _SIGNUP_PLEASE_ENTER_PSWD; } elseif (strlen($vars['pass0']) < $config['pass_min_length']){ $ll = $config[pass_min_length]; $error[] = sprintf(_SIGNUP_INVALID_PASS_1,$ll); } if ($vars['pass0'] != $vars['pass1']){ $error[] = _SIGNUP_INVALID_PASS_2; } if (!strlen($vars['aff_payout_type']) && count(aff_get_payout_methods(1)) > 1){ $error[] = _AFF_SIGNUP_PLEASE_PAYOUT_TYPE; } $error = array_merge($error, plugin_validate_signup_form($vars, 'affiliate_signup')); return !count($error); } ############################################################################### # SHOW_FORM # # get vars from database and plugins # display $GLOBAL[error] if it set # substitute previous entered parameters using Smarty # function show_form(){ global $t; global $error; global $db, $config, $vars; $t->assign('error', $error); plugin_fill_in_signup_form($_REQUEST); $t->assign('additional_fields_html', get_additional_fields_html($vars, 'affiliate_signup')); $t->assign('aff_payout_types', aff_get_payout_methods(1)); $is_affiliate = '2'; $newsletter_threads = $db->get_signup_threads_c($is_affiliate); $t->assign('newsletter_threads', $newsletter_threads); $t->display('aff_signup.html'); } function auto_login_and_move_subscriptions ($member_id){ global $db, $config; settype($member_id, 'integer'); if ($member_id <= 0) return; $u = $db->get_user($member_id); if (!$u) return; if ($config['auto_login_after_signup']){ $_SESSION['_amember_login'] = $u['login']; $_SESSION['_amember_pass'] = $u['pass']; } if($config['aff']['mail_signup_user']) check_aff_signup_email_sent($member_id); $g = $db->get_guest_by_email($u['email']); if (count($g) > 0 && $g['guest_id'] > 0){ $guest_id = $g['guest_id']; $threads = $db->get_guest_threads($guest_id); $threads = array_keys($threads); if (count($threads) > 0){ $db->add_member_threads($member_id, $threads); $db->delete_guest_threads($guest_id); } $db->delete_guest($guest_id); } } ############################################################################### ## ## M A I N ## ############################################################################### $t = & new_smarty(); $error = ''; $vars = & get_input_vars(); plugin_display_signup_form(); $error = array(); unset($member_id); if ($vars['continue_signup']){ $u = $db->get_user($vars['member_id']); if (!$u['member_id']) fatal_error(_SIGNUP_INCORRECT_LINK, 1); $md5 = md5($u['login'].$u['pass'].$vars['member_id']); if ($md5 != $vars['md5']) fatal_error(_SIGNUP_INCORRECT_LINK, 1); $u['email_verified'] = 1; $db->update_user($u['member_id'], $u); auto_login_and_move_subscriptions($u['member_id']); header("Location: ".$config['root_url']."/thanks.php"); exit(); } // verificate CAPTCHA if (($vars['do_affiliate'] || $vars['do_agreement']) && $config['use_captcha_signup'] && !$_SESSION['amember_captcha_verified']){ if (($vars['captcha'] != '') && (strtolower($vars['captcha']) == $_SESSION['amember_captcha'])){ $_SESSION['amember_captcha_verified'] = true; } else { $error[] = _SIGNUP_CAPTCHA_ERROR; } } if ($vars['do_agreement']){ if (!$vars['i_agree']){ $error[] = _SIGNUP_USER_AGREEMENT; display_agreement($vars['data']); exit(); } $vars = unserialize($vars['data']); $vars['i_agree']++; foreach ($vars as $k=>$v) $t->_smarty_vars['request'][$k] = $v; } if (!$config['login_dont_lowercase']) $vars['login'] = strtolower($vars['login']); if ($config['generate_login']) $vars['login'] = generate_login($vars); if ($config['generate_pass']) $vars['pass'] = $vars['pass0'] = $vars['pass1'] = generate_password($vars); ///// if ( $vars['do_affiliate'] && check_form() ){ /* //check for agreement $display_agreement = 0; foreach ((array)$vars['product_id'] as $pid){ $product = $db->get_product($pid); if ($product['need_agreement']) $display_agreement++; } if ($display_agreement && !$vars['i_agree']){ display_agreement(serialize($vars)); // defined in the product.inc.php exit(); } */ $login = $vars['login']; do { // to easy exit using break() $member_id = $db->check_uniq_login($vars['login'], $vars['email'], $vars['pass0'], 1); $member_id_exists = 0; if ($config['verify_email']) $vars['email_verified'] = -1; if ($GLOBALS['_LANG_SELECTED'] != get_default_lang()){ $vars['selected_lang'] = $GLOBALS['_LANG_SELECTED']; } if (!$vars['aff_payout_type']){ // if payout type not selected $payout_methods = aff_get_payout_methods(1); if (count($payout_methods) == 1) { // if there is only one payout type $payout_methods = array_keys($payout_methods); $vars['aff_payout_type'] = $payout_methods[0]; } } if ($member_id < 0) { $member_id = $db->add_pending_user($vars); $is_affiliate = '2'; //only affiliate if ($db->get_signup_threads_c($is_affiliate) && $vars['to_subscribe']) $db->subscribe_member ($member_id, $is_affiliate); $member = $db->get_user($member_id); $member['is_affiliate'] = $is_affiliate; /* No unsubscribe new members! if (!$vars['to_subscribe']) $member['unsubscribed']='1'; */ $db->update_user($member_id, $member); } elseif (!$member_id) die(_SIGNUP_LOGIN_EXISTS); else { $member_id_exists++; //we found existing user with the same params // then will clean CC parameters if any $member = $db->get_user($member_id); $is_affiliate = '1'; //member & affiliate if ($db->get_signup_threads_c('2') && $vars['to_subscribe']) $db->subscribe_member ($member_id, '2'); // subscribe ONLY as affiliate !!! $member['is_affiliate'] = $is_affiliate; if (!$vars['to_subscribe']) $member['unsubscribed']='1'; $member['data']['cc-hidden']=''; $member['data']['cc-expire']=''; $member['data']['cc']=''; $member['data']['cc_street']=''; $member['data']['cc_city']=''; $member['data']['cc_state']=''; $member['data']['cc_zip']=''; $member['data']['cc_country']=''; foreach ($vars as $k=>$v) $member[$k] = $v; $db->update_user($member_id, $member); } $additional_values = array(); foreach ($payment_additional_fields as $f){ $fname = $f['name']; if (isset($vars[$fname])) $additional_values[$fname] = $vars[$fname]; } if ($error) { $db->delete_user($member_id); break; } if ($config['verify_email']){ global $db; $u = $db->get_user($member_id); $md5 = md5($u['login'].$u['pass'].$member_id); mail_verification_email($u, $config['root_url']."/aff_signup.php?continue_signup=1&member_id=$member_id&member_id_exists=$member_id_exists&md5=$md5"); $t->assign('user', $u); $t->display("email_verify.html"); exit(); } unset($_SESSION['amember_captcha_verified']); auto_login_and_move_subscriptions ($member_id); //header("Location: ".$config['root_url']."/aff_member.php"); $url = $config['root_url'] . "/aff_member.php"; html_redirect($url, 0, _AFF_MEMBER_THANK_YOU, _AFF_MEMBER_REDIRECTING); exit(); } while (0); } show_form(); ?> amember/ajax.php0000644774276600352300000000666311573171451017651 0ustar nf.mortgageoriginatorseminarswwwencode($resp); return true; } function ajaxError($msg){ ajaxResponse(array('msg' => $msg)); } function ajaxGetStates($vars){ return ajaxResponse(db_getStatesForCountry($vars['country'])); } function ajaxCheckUniqLogin($vars){ global $db, $config; $login = htmlentities($vars['login']); $res = array('msg' => '', 'errorCode' => 0); do { // check for valid login first if ($vars['login'] == '') { $res['msg'] = sprintf(_SIGNUP_INVALID_USERNAME_2, $config['login_min_length'], $config['login_max_length']); $res['errorCode'] = 2; break; } if (strlen($vars['login']) < $config['login_min_length'] || strlen($vars['login']) > $config['login_max_length']){ $res['msg'] = sprintf(_SIGNUP_INVALID_USERNAME_2, $config['login_min_length'], $config['login_max_length']); $res['errorCode'] = 3; break; } if (!preg_match(getLoginRegex(), $vars['login'])){ $res['msg'] = $config['login_disallow_spaces'] ? _SIGNUP_INVALID_USERNAME : _SIGNUP_INVALID_USERNAME_W_SPACES; $res['errorCode'] = 4; break; } // check if it is available $r = $db->check_uniq_login($vars['login'], $vars['email'], $vars['pass'], 1); if (!$r){ $res['msg'] = sprintf(_UNIQ_LOGIN_EXSTS_TEXT, htmlentities($login)) . ".
" . _UNIQ_LOGIN_EXSTS_TEXT_1 . "
" . sprintf(_UNIQ_LOGIN_EXSTS_TEXT_2, "", ""); $res['errorCode'] = 1; break; } else { $res['msg'] = sprintf(_UNIQ_LOGIN_FREE_TEXT, htmlentities($login)); $res['errorCode'] = 0; break; } } while (false); return ajaxResponse($res); } function ajaxCheckCoupon($vars){ global $db, $config; $coupon = htmlentities($vars['coupon']); $res = array('msg' => '', 'errorCode' => 0); $ret = $db->coupon_get($vars['coupon']); if (!is_array($ret) || !$ret['coupon_id']){ $res['msg'] = $ret; $res['errorCode'] = 1; } return ajaxResponse($res); } header("Content-type: text/plain; charset=UTF-8"); $vars = get_input_vars(); $vars['do'] = preg_replace('/[^a-zA-Z0-9_.,-]/', '', $vars['do']); switch ($vars['do']){ case 'get_states': ajaxGetStates($vars); break; case 'check_uniq_login': ajaxCheckUniqLogin($vars); break; case 'check_coupon': ajaxCheckCoupon($vars); break; default: ajaxError('Unknown Request: ' . $vars['do']); } amember/amember.sql0000644774276600352300000007037511613276243020347 0ustar nf.mortgageoriginatorseminarswww############################################################### # # # aMember MySQL DATABASE DUMP # # # # This file is to use with amember/setup.php only # # It cannot be loaded to MySQL as is. # # # ############################################################### # Table structure for table 'access_log' CREATE TABLE @DB_MYSQL_PREFIX@access_log( log_id int(11) NOT NULL auto_increment, member_id int(11) NOT NULL, time timestamp(14) NOT NULL, url varchar(255) default NULL, remote_addr varchar(15) default NULL, referrer varchar(255) default NULL, PRIMARY KEY (log_id), INDEX (member_id, time, remote_addr), INDEX (time) ) ; # # Table structure for table 'aff_clicks' # CREATE TABLE @DB_MYSQL_PREFIX@aff_clicks( log_id int(11) NOT NULL auto_increment, aff_id int(11) NOT NULL, time timestamp(14) NOT NULL, url varchar(255) default NULL, remote_addr varchar(15) default NULL, referrer varchar(255) default NULL, PRIMARY KEY (log_id), INDEX (aff_id, time, remote_addr), INDEX (time) ) ; # # Table structure for table 'cron_run' # CREATE TABLE @DB_MYSQL_PREFIX@cron_run ( id int(11) NOT NULL default '0', time datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (id) ); # # Table structure for table 'error_log' # CREATE TABLE @DB_MYSQL_PREFIX@error_log ( log_id int(11) NOT NULL auto_increment, member_id int(11) default '0', time timestamp(14) NOT NULL, url varchar(255) default NULL, remote_addr varchar(15) default NULL, referrer varchar(255) default NULL, error text, PRIMARY KEY (log_id) ) ; # # Table structure for table 'members' # CREATE TABLE @DB_MYSQL_PREFIX@members ( member_id int(11) NOT NULL auto_increment, login varchar(32) NOT NULL, pass varchar(32) default NULL, email varchar(64) default NULL, name_f varchar(32) NOT NULL default '', name_l varchar(32) NOT NULL default '', street varchar(255) default NULL, city varchar(255) default NULL, state varchar(255) default NULL, zip varchar(255) default NULL, country varchar(255) default NULL, is_male smallint(6) default NULL, added datetime NOT NULL default '0000-00-00 00:00:00', remote_addr varchar(15) default NULL, data text NOT NULL, PRIMARY KEY (member_id), UNIQUE KEY login (login) ) ; # # Table structure for table 'payments' # CREATE TABLE @DB_MYSQL_PREFIX@payments ( payment_id int(11) NOT NULL auto_increment, member_id int(11) NOT NULL , product_id int(11) NOT NULL , begin_date date NOT NULL , expire_date date NOT NULL , paysys_id varchar(32) NOT NULL default '', receipt_id varchar(32) NOT NULL default '', amount decimal(12,2) NOT NULL default '0.00', completed smallint(6) default '0', remote_addr varchar(15) NOT NULL default '', data text, time timestamp(14) NOT NULL, PRIMARY KEY (payment_id), KEY member_id (member_id) ) ; # # Table structure for table 'products' # CREATE TABLE @DB_MYSQL_PREFIX@products ( product_id int(11) NOT NULL auto_increment, title varchar(255) NOT NULL default '', description text, price decimal(12,2) default NULL, data text, PRIMARY KEY (product_id) ) ; #### *** 1.9.1 *** CREATE TABLE @DB_MYSQL_PREFIX@coupon ( coupon_id int(11) unsigned NOT NULL auto_increment PRIMARY KEY, batch_id int(10) unsigned NOT NULL, code varchar(32) NOT NULL, comment varchar(64), discount varchar(32) NOT NULL, begin_date date, expire_date date, locked tinyint(3) unsigned NOT NULL, product_id varchar(255), use_count int(11), member_use_count int(11), used_count int(11), used_for text, data text, UNIQUE KEY code (code) ); CREATE TABLE @DB_MYSQL_PREFIX@config ( config_id int(11) NOT NULL auto_increment PRIMARY KEY, name varchar(64) NOT NULL, type smallint(6) default '0', value varchar(255) , blob_value blob, UNIQUE KEY name (name) ); CREATE TABLE @DB_MYSQL_PREFIX@aff_commission ( commission_id int(11) NOT NULL auto_increment PRIMARY KEY, aff_id int NOT NULL, date DATE NOT NULL, amount DECIMAL(12,2), record_type char(16) NOT NULL, payment_id int NOT NULL, receipt_id char(32) NOT NULL, product_id int not null, is_first int not null, payout_id char(32), tier smallint default 1, INDEX aff_id (aff_id, date), UNIQUE KEY payment (payment_id, receipt_id, record_type, tier) ); CREATE TABLE @DB_MYSQL_PREFIX@folders ( folder_id int(11) NOT NULL auto_increment, path varchar(255) NOT NULL default '', url varchar(255) NOT NULL default '', method varchar(64) default NULL, product_ids varchar(64) NOT NULL default '', files_content blob, PRIMARY KEY (folder_id), UNIQUE KEY path (path), UNIQUE KEY url (url) ); CREATE TABLE @DB_MYSQL_PREFIX@admin_log ( log_id int(11) NOT NULL auto_increment, dattm datetime, admin_id int(11), ip varchar(32), tablename varchar(32) NOT NULL, record_id int(11) NOT NULL, message text, admin_login varchar(32) default NULL, PRIMARY KEY (log_id) ); CREATE TABLE @DB_MYSQL_PREFIX@admins ( admin_id int(11) NOT NULL auto_increment, login varchar(32) NOT NULL default '', pass varchar(40) NOT NULL default '', last_login datetime default NULL, last_ip varchar(32) default NULL, last_session varchar(32) default NULL, email varchar(255) default NULL, super_user smallint(6) NOT NULL default '0', perms text, PRIMARY KEY (admin_id), UNIQUE KEY login (login) ); #### fill-in config values REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('root_url', 0, '@ROOT_URL@', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('root_surl', 0, '@ROOT_SURL@', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('admin_email', 0, '@ADMIN_EMAIL@', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('generate_login', 0, '0', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('login_min_length', 0, '4', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('login_max_length', 0, '32', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('generate_pass', 0, '0', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('pass_min_length', 0, '4', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('pass_max_length', 0, '32', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('clear_access_log', 0, '1', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('clear_access_log_days', 0, '7', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('max_ip_count', 0, '5', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('max_ip_period', 0, '1440', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('select_multiple_products', 0, '0', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('multi_title', 0, 'Membership', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('use_coupons', 0, '0', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('date_format', 0, '%m/%d/%Y', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('time_format', 0, '%m/%d/%Y %H:%M:%S', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('send_signup_mail', 0, '1', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('mail_expire', 0, '0', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('mail_expire_days', 0, '1', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('use_address_info', 0, '0', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('unique_email', 0, '1', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('curl', 0, '@CURL_PATH@', ''); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('profile_fields', 1, '', 'a:4:{i:0;s:5:"pass0";i:1;s:6:"name_f";i:2;s:6:"name_l";i:3;s:5:"email";}'); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('license', 2, '', '@LICENSE@'); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('plugins.payment', 1, '', '@PAYMENT_PLUGINS@'); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('plugins.protect', 1, '', '@PROTECT_PLUGINS@'); REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value,blob_value) VALUES ('lang.list', 1, '', 'a:1:{i:0;s:10:"en:English";}'); REPLACE INTO @DB_MYSQL_PREFIX@admins (login, pass, email, super_user) VALUES ('@ADMIN_LOGIN@', '@ADMIN_PASS@', '@ADMIN_EMAIL@', 1); MODIFY @DB_MYSQL_PREFIX@members FIELD status smallint NOT NULL DEFAULT 0; MODIFY @DB_MYSQL_PREFIX@members FIELD aff_id int; MODIFY @DB_MYSQL_PREFIX@members FIELD is_affiliate tinyint(4); MODIFY @DB_MYSQL_PREFIX@members FIELD aff_payout_type varchar(32); MODIFY @DB_MYSQL_PREFIX@members FIELD unsubscribed tinyint(4) DEFAULT 0; MODIFY @DB_MYSQL_PREFIX@members FIELD email_verified tinyint(4) DEFAULT 0; ### add affiliate id field if it don't exists MODIFY @DB_MYSQL_PREFIX@payments FIELD aff_id int NOT NULL; ### add payer_id field if it don't exists MODIFY @DB_MYSQL_PREFIX@payments FIELD payer_id VARCHAR(255) NOT NULL; ### add indexes MODIFY @DB_MYSQL_PREFIX@payments INDEX payer_id (payer_id); MODIFY @DB_MYSQL_PREFIX@admin_log INDEX al (tablename, record_id); MODIFY @DB_MYSQL_PREFIX@aff_commission INDEX ac (date); ### 1.9.3RC.. ## MODIFY @DB_MYSQL_PREFIX@coupon FIELD use_count int NOT NULL DEFAULT 0; MODIFY @DB_MYSQL_PREFIX@coupon FIELD member_use_count int NOT NULL DEFAULT 0; MODIFY @DB_MYSQL_PREFIX@coupon FIELD used_count int NOT NULL DEFAULT 0; MODIFY @DB_MYSQL_PREFIX@payments FIELD coupon_id int NOT NULL; MODIFY @DB_MYSQL_PREFIX@payments INDEX coupon_id (coupon_id); MODIFY @DB_MYSQL_PREFIX@payments FIELD tm_added datetime NOT NULL; MODIFY @DB_MYSQL_PREFIX@payments INDEX tm_added (tm_added, product_id); MODIFY @DB_MYSQL_PREFIX@payments FIELD tm_completed datetime NULL; MODIFY @DB_MYSQL_PREFIX@payments INDEX tm_completed (tm_completed, product_id); CREATE TABLE @DB_MYSQL_PREFIX@failed_login ( failed_login_id int(11) NOT NULL auto_increment, ip char(15) NOT NULL, login_type int(11) NOT NULL, failed_logins int(11) NOT NULL, last_failed int(11) NOT NULL, PRIMARY KEY (failed_login_id), UNIQUE KEY ip (ip, login_type) ); ## 300 ## MODIFY @DB_MYSQL_PREFIX@members FIELD security_code VARCHAR(40); MODIFY @DB_MYSQL_PREFIX@members FIELD securitycode_expire DATETIME; REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value) VALUES ('auto_login_after_signup', 0, '1'); CREATE TABLE @DB_MYSQL_PREFIX@newsletter_thread ( thread_id int(10) unsigned NOT NULL auto_increment, title varchar(60) NOT NULL default '', description text, is_active smallint NOT NULL default 1, blob_available_to blob default NULL, blob_auto_subscribe blob default NULL, PRIMARY KEY (thread_id) ); CREATE TABLE @DB_MYSQL_PREFIX@newsletter_archive ( archive_id int(10) unsigned NOT NULL auto_increment, threads varchar(255) NOT NULL default '', subject varchar(255) NOT NULL default '', message text, add_date datetime, PRIMARY KEY (archive_id) ); CREATE TABLE @DB_MYSQL_PREFIX@newsletter_guest ( guest_id int(10) unsigned NOT NULL auto_increment, guest_name varchar(60) NOT NULL default '', guest_email varchar(60) NOT NULL default '', PRIMARY KEY (guest_id) ); CREATE TABLE @DB_MYSQL_PREFIX@newsletter_guest_subscriptions ( guest_subscription_id int(10) unsigned NOT NULL auto_increment, guest_id int(10) unsigned NOT NULL, thread_id int(10) unsigned NOT NULL, PRIMARY KEY (guest_subscription_id) ); CREATE TABLE @DB_MYSQL_PREFIX@newsletter_member_subscriptions ( member_subscription_id int(10) unsigned NOT NULL auto_increment, member_id int(10) unsigned NOT NULL, thread_id int(10) unsigned NOT NULL, PRIMARY KEY (member_subscription_id) ); CREATE TABLE @DB_MYSQL_PREFIX@email_templates ( email_template_id int(11) NOT NULL auto_increment, name varchar(32) NOT NULL default '', lang varchar(16) NOT NULL default '', format enum('text','html','multipart') NOT NULL default 'text', subject varchar(255) NOT NULL default '', txt mediumtext NOT NULL, plain_txt mediumtext, attachments mediumtext, product_id int(11) default NULL, `day` int(11) default NULL, PRIMARY KEY (email_template_id) ); ## insert e-mail templates INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (1, 'verify_email', 'en', 'text', '{$config.site_title} - Account Verification', 'Hello {$user.name_f} {$user.name_l},\r\n\r\nYou (or someone else) has just registered an account on {$config.site_title}.\r\nClicking on the link below will activate the account:\r\n{$url}\r\n\r\n--\r\nBest Regards,\r\n{$config.site_title}\r\n{$config.root_url}', '', '', NULL, NULL); INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (2, 'send_pending_email', 'en', 'text', 'Pending Payment', 'Dear {$name_f} {$name_l},\r\n\r\nThank you for signup. Your payment status is PENDING.\r\nPlease complete payment as described.\r\n\r\n Your User ID: {$login} \r\n Your Password: {$pass}\r\n\r\nYour may log-on to your member pages at:\r\n{$config.root_url}/member.php\r\nand check your subscription status.\r\n\r\nBest Regards,\r\nSite Team\r\n', '', '', NULL, NULL); INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (3, 'mail_not_completed', 'en', 'text', '{$config.site_title} - Signup is not finished', 'Dear {$name_f} {$name_l},\r\n\r\nThank you for signup! Unfortunately, you have not finished\r\npayment yet. If you have any troubles with payment,\r\ndon''t hesitate to contact us using the following \r\nemail address: {$config.admin_email}.\r\n\r\nDespite the fact that your payment is not completed,\r\na customer record has been created for you. \r\nYou may login to members area using the following \r\nURL :\r\n {$config.root_url}/member.php\r\nYou member details are:\r\n Your User ID: {$login} \r\n Your Password: {$pass}\r\n\r\nAfter logging-in, you may use "Add/Renew Subscription" controls\r\nto complete your payment.\r\n\r\n--\r\nBest Regards,\r\n{$config.site_title}\r\n{$config.root_url}', '', '', NULL, 1); INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (4, 'send_signup_mail', 'en', 'text', '{$config.site_title} - Membership Information', 'Dear {$name_f} {$name_l},\r\n\r\nThank you for subscribing on {$config.site_title}!\r\n\r\n Your User ID: {$login} \r\n Your Password: {$pass}\r\n\r\nLog-on to your member pages at:\r\n{$config.root_url}/member.php\r\n\r\n--\r\nBest Regards,\r\n{$config.site_title}\r\n{$config.root_url}', '', '', NULL, NULL); INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (5, 'send_payment_mail', 'en', 'text', '{$config.site_title} - Payment Receipt', 'Thank you for your order. You may find order details below:\r\n\r\nYour Invoice Number {$payment.payment_id} from {$payment.tm_completed|date_format:$config.date_format}\r\n\r\n{"Product/Subscription Title"|string_format:"%-50s"} Price\r\n-----------------------------------------------------------\r\n{foreach from=$products item=p}\r\n{$p.title|string_format:"%-50s"} {$config.currency|default:"$"}{$p.price}\r\n{/foreach}\r\n-----------------------------------------------------------\r\n{"Subtotal"|string_format:"%-50s"} {$config.currency|default:"$"}{$subtotal|string_format:"%.2f"}\r\n{if $payment.data.COUPON_DISCOUNT ne "" }\r\n{"Discount"|string_format:"%-50s"} {$config.currency|default:"$"}{$payment.data.COUPON_DISCOUNT|string_format:"%.2f"}\r\n{/if}\r\n{if $payment.data.TAX_AMOUNT ne ""}\r\n{"Tax Amount"|string_format:"%-50s"} {$config.currency|default:"$"}{$payment.data.TAX_AMOUNT|string_format:"%.2f"}\r\n{/if}\r\n-----------------------------------------------------------\r\n{"Total"|string_format:"%-50s"} {$config.currency|default:"$"}{$total|string_format:"%.2f"}\r\n\r\n--\r\nBest Regards,\r\n{$config.site_title}\r\n{$config.root_url}', '', '', NULL, NULL); INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (6, 'send_payment_admin', 'en', 'text', '{$config.site_title} *** New Payment', 'New payment completed:\r\n Product: {$product.title}\r\n Amount: {$config.currency|default:"$"}{$payment.amount}\r\n Period: {$payment.begin_date|date_format:$config.date_format} - {$payment.expire_date|date_format:$config.date_format}\r\n\r\n User details:\r\n Username: {$user.login}\r\n Email: {$user.email}\r\n Name: {$user.name_f} {$user.name_l}\r\n\r\n--\r\nBest Regards,\r\n{$config.site_title}\r\n{$config.root_url}', '', '', NULL, NULL); INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (7, 'mail_expire', 'en', 'text', '{$config.site_title} - Your Subscription Expires', 'Dear {$name_f} {$name_l},\r\n\r\nYour subscription on {$config.site_title} expires {$payment.expire_date|date_format:"%m/%d/%Y"}.\r\n\r\nPlease log-on to membership information page at:\r\n{$config.root_url}/member.php\r\nand renew your subscription.\r\n\r\nYour login details:\r\n Your User ID: {$login} \r\n Your Password: {$pass}\r\n\r\nThank you for your attention!\r\n--\r\nBest Regards,\r\n{$config.site_title}\r\n{$config.root_url}', '', '', NULL, 1); INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (8, 'mail_cancel_admin', 'en', 'text', '{$config.site_title} - User subscription cancelled', 'User {$user.login}, "{$user.name_f} {$user.name_l}" <{$user.email}>\r\nhas cancelled recurring subscription #{$payment.payment_id} to product\r\n{$product.title}.\r\n\r\n--\r\nBest Regards,\r\n{$config.site_title}\r\n{$config.root_url}', '', '', NULL, NULL); INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (9, 'mail_cancel_member', 'en', 'text', '{$config.site_title} - Subscription cancelled', 'Dear {$user.name_f} {$user.name_l},\r\n\r\nYour subscription to "{$product.title}" cancelled. Feel free to subscribe \r\nagain, you can do it here:\r\n {$config.root_url}/member.php\r\n\r\n--\r\nBest Regards,\r\n{$config.site_title}\r\n{$config.root_url}', '', '', NULL, NULL); INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (10, 'cc_rebill_failed', 'en', 'text', '{$config.site_title} Subscription Renewal Failed', 'Hello {$user.name_f} {$user.name_l},\r\n\r\nYour subscription was not renewed automatically by membership system\r\ndue to payment failure: "{$error}".\r\n\r\n{* If subscription has been pro-rated. *}\r\n{if $new_expire ne "" }\r\nBilling attempt will be automatically repeated {$new_expire|date_format:$config.date_format},\r\nplease add funds to your card or update your credit card information.\r\n{/if}\r\n\r\nYou may update your credit card info here: \r\n{$config.root_url}/member.php\r\n\r\nThank you for attention!\r\n\r\n--\r\nBest Regards,\r\n{$config.site_title}\r\n{$config.root_url}', '', '', NULL, NULL); INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (11, 'cc_rebill_success', 'en', 'text', '{$config.site_title} Subscription Renewed', 'Hello {$user.name_f} {$user.name_l},\r\n\r\nYour subscription has been renewed automatically by our membership system.\r\nYour credit card was charged on ${$payment.amount}.\r\n\r\nNext renewal date: {$payment.expire_date|date_format:$config.date_format}\r\n\r\nYou may login to membership info page at :\r\n{$config.root_url}/member.php\r\n\r\nThank you!\r\n\r\n--\r\nBest Regards,\r\n{$config.site_title}\r\n{$config.root_url}', '', '', NULL, NULL); INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (12, 'card_expires', 'en', 'text', 'Credit Card Expiration', 'Hello {$user.name_f} {$user.name_l},\r\n\r\nYour credit card that we have on file for recurring billing will expire\r\non {$expires}. Next recurring billing for "{$product.title}"\r\nis sheduled for {$payment.expire_date|date_format:$config.date_format}.\r\n\r\nTo avoid any interruption of your subscription, please visit page\r\n{$config.root_url}/member.php\r\nand update your credit card information. \r\n\r\nThank you!\r\n\r\n--\r\nBest Regards,\r\n{$config.site_title}\r\n{$config.root_url}', '', '', NULL, NULL); INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (13, 'aff.mail_sale_admin', 'en', 'text', '** Affiliate Commission', 'Dear admin,\r\n\r\nNew sale has been made with using of affiliate link.\r\nYou may find sale details below:\r\n\r\n----\r\nAffilate: {$affiliate.member_id} / {$affiliate.login} / {$affiliate.email} \r\n {$affiliate.name_f} {$affiliate.name_l} / {$affiliate.remote_addr}\r\nNew Member: {$user.member_id} / {$user.login} / {$user.email} \r\n {$user.name_f} {$user.name_l} / {$user.remote_addr}\r\nPayment REF: {$payment.payment_id}\r\nTotal: {$payment.amount}\r\nProduct ordered: {$product.title}\r\nCommission paid: {$commission}\r\n----\r\n\r\n', '', '', NULL, NULL); INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (14, 'aff.mail_sale_user', 'en', 'text', '** Affiliate Sale', 'Dear {$affiliate.name_f} {$affiliate.name_l},\r\n\r\nNew sale has been made by your affiliate link and \r\ncommission credited to your balance. You may find \r\nsale details below:\r\n\r\n----\r\nPayment REF: {$payment.payment_id}\r\nTotal: {$payment.amount}\r\nProduct ordered: {$product.title}\r\nYour commission: {$commission}\r\n----\r\n\r\n', '', '', NULL, NULL); INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (15, 'max_ip_actions', 'en', 'text', '*** Account Sharing Violation Detected', 'There is an automated message from aMember Pro script. \r\nAn account violation has been detected for the following\r\ncustomer:\r\n User details:\r\n Username: {$user.login}\r\n Email: {$user.email}\r\n Name: {$user.name_f} {$user.name_l}\r\n{if $config.max_ip_actions ne "2"}\r\nCustomer account has been automatically locked.\r\n{/if}\r\n \r\nIt has reached configured limit of {$config.max_ip_count} IP within\r\n{$config.max_ip_period} minutes. Please login into aMember CP and review\r\nhis access log. \r\n\r\nIf it looks like a script mistake, you may disable sharing violation checking \r\nfor this user in the "User Profile", or disable it globally at aMember CP -> \r\nSetup -> Advanced by setting "Max Number of IP" to something like "99999".\r\n \r\n--\r\nYour aMember Pro script \r\n{$config.root_url}/admin/', '', '', NULL, NULL); INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (16, 'manually_approve', 'en', 'text', '{$config.site_title} Your signup is pending', 'Dear {$name_f} {$name_l},\r\n\r\nThank you for subscribing!\r\n\r\nWe review all payments manually, so your payment \r\nstatus is pending. You will receive email when your\r\naccount will be approved. Thank you for your patience.\r\n--\r\nBest Regards,\r\n{$config.site_title}\r\n{$config.root_url}', '', '', NULL, NULL); INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (17, 'verify_guest', 'en', 'text', '{$config.site_title} - Newsletter Subscription', 'Dear {$name},\r\n\r\nYou signed up for a guest subscription on {$config.site_title}.\r\n\r\nTo confirm subscription please follow a link:\r\n {$link}\r\n\r\n--\r\nBest Regards,\r\n{$config.site_title}\r\n{$config.root_url}', '', '', NULL, NULL); INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (18, 'send_pass', 'en', 'text', '{$config.site_title} - Lost Password', 'Dear {$name_f} {$name_l},\r\n\r\nYou have requested your member log-in information.\r\n\r\n Your User ID: {$login}\r\n\r\n Your Password: {$pass}\r\n\r\nLog-in to member pages at:\r\n {$config.root_url}/member.php\r\n\r\n--\r\nBest Regards,\r\n{$config.site_title}\r\n{$config.root_url}', '', '', NULL, NULL); INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (19, 'send_security_code', 'en', 'text', 'Your Lost Password', 'Dear {$name_f} {$name_l},\r\n\r\nYou have requested your member log-in information.\r\n\r\n Your User ID: {$login}\r\n\r\nFollow a link below to change your password:\r\n {$config.root_url}/sendpass.php?s={$code}\r\n \r\nThis link will be active {$hours} hour(s).\r\n\r\n--\r\nBest Regards,\r\n{$config.site_title}\r\n{$config.root_url}', '', '', NULL, NULL); MODIFY @DB_MYSQL_PREFIX@newsletter_guest FIELD security_code VARCHAR(40); MODIFY @DB_MYSQL_PREFIX@newsletter_guest FIELD securitycode_expire DATETIME; MODIFY @DB_MYSQL_PREFIX@newsletter_guest_subscriptions FIELD security_code VARCHAR(40); MODIFY @DB_MYSQL_PREFIX@newsletter_guest_subscriptions FIELD securitycode_expire DATETIME; ## 301 ## MODIFY @DB_MYSQL_PREFIX@payments FIELD tax_amount decimal(12,2) NOT NULL default '0.00'; MODIFY @DB_MYSQL_PREFIX@newsletter_archive FIELD is_html smallint NOT NULL default 0; MODIFY @DB_MYSQL_PREFIX@folders FIELD product_ids text NOT NULL; ## 308 ## MODIFY @DB_MYSQL_PREFIX@admins FIELD pass varchar(128) NOT NULL default ''; CREATE TABLE @DB_MYSQL_PREFIX@countries ( country_id INT NOT NULL auto_increment PRIMARY KEY, country char(2) NOT NULL, title varchar(64), tag int default NULL, UNIQUE (country) ); CREATE TABLE @DB_MYSQL_PREFIX@states ( state_id int NOT NULL auto_increment PRIMARY KEY, state char(12) NOT NULL, country char(2) NOT NULL, title varchar(64), UNIQUE(state), INDEX (country) ); MODIFY @DB_MYSQL_PREFIX@coupon FIELD is_recurring smallint not null default 0; MODIFY @DB_MYSQL_PREFIX@aff_commission FIELD tier smallint default 1; MODIFY @DB_MYSQL_PREFIX@aff_commission UNIQUE INDEX payment (payment_id, receipt_id, record_type, tier); MODIFY @DB_MYSQL_PREFIX@newsletter_member_subscriptions FIELD status smallint NOT NULL default 1; ## 311 ## MODIFY @DB_MYSQL_PREFIX@countries FIELD status ENUM( 'added', 'changed' ) default NULL; MODIFY @DB_MYSQL_PREFIX@states FIELD status ENUM( 'added', 'changed' ) default NULL; MODIFY @DB_MYSQL_PREFIX@states FIELD tag int default 0; # Table structure for table 'products_links' for incremental content plugin CREATE TABLE @DB_MYSQL_PREFIX@products_links( link_id int(11) NOT NULL auto_increment, link_product_id int(11) NOT NULL, link_start_delay varchar(10) NOT NULL, link_duration varchar(10) NOT NULL, link_url varchar(255) default NULL, link_title varchar(255) default NULL, link_path varchar(255) default NULL, link_protected smallint(6) default '0', time timestamp(14) NOT NULL, PRIMARY KEY (link_id), INDEX (link_product_id), INDEX (time) ); MODIFY @DB_MYSQL_PREFIX@products_links FIELD link_group_id int default 0; # Table structure for table 'products_links_groups' CREATE TABLE @DB_MYSQL_PREFIX@products_links_groups ( id int(11) NOT NULL auto_increment, title varchar(255) NOT NULL , description varchar(255) default NULL , priority int(11) default '0', PRIMARY KEY (id) ); ## 313 ## CREATE TABLE @DB_MYSQL_PREFIX@rebill_log ( rebill_log_id int not null auto_increment PRIMARY KEY, added_tm datetime not null, payment_date date not null, payment_id int not null, rebill_payment_id int not null, amount decimal(12,2) not null, status smallint default null, status_tm datetime, status_msg varchar(255), index (payment_id) ); ## 314 ## MODIFY @DB_MYSQL_PREFIX@coupon FIELD member_id int not null default 0; ## 319 ## MODIFY @DB_MYSQL_PREFIX@products_links FIELD link_comment text NOT NULL; MODIFY @DB_MYSQL_PREFIX@products_links FIELD link_files_path text NOT NULL; ## 320 ## INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (20, 'verify_email_profile', 'en', 'text', '{$config.site_title} - Email Verification', 'Hello {$user.name_f} {$user.name_l},\r\n\r\nYou (or someone else) has just changed email address in your account on {$config.site_title}.\r\nClicking on the link below will approve this change:\r\n\r\n{$url}\r\n\r\nPlease note that email address will be changed in your profile only if you will click on above link.\r\nIf you didn\'t request email address change just disregard this message.\r\n--\r\nBest Regards,\r\n{$config.site_title}\r\n{$config.root_url}', '', '', NULL, NULL); INSERT INTO @DB_MYSQL_PREFIX@email_templates VALUES (21, 'aff.mail_signup_user', 'en', 'text', '{$config.site_title} - Affiliate Information', 'Dear {$name_f} {$name_l},\r\n\r\nThank you for signup to affiliate programm on {$config.site_title}!\r\n\r\n Your User ID: {$login} \r\n Your Password: {$pass}\r\n\r\nLog-on to your affiliate area at:\r\n{$config.root_url}/aff_member.php\r\nYour affiliate link:\r\n{$config.root_url}/go.php?r={$user.member_id}\r\n--\r\nBest Regards,\r\n{$config.site_title}\r\n{$config.root_url}', '', '', NULL, NULL); ## ALL ## ### keep this last line, don't forget to increase db_version in common.inc.php REPLACE INTO @DB_MYSQL_PREFIX@config (name,type,value) VALUES ('db_version', 0, '320'); ###amember/cancel.php0000644774276600352300000000205411573171451020141 0ustar nf.mortgageoriginatorseminarswwwdisplay("cancel.html"); ?> amember/captcha.php0000644774276600352300000000507611573171451020326 0ustar nf.mortgageoriginatorseminarswwwgetKeyString(); amember/common.inc.php0000644774276600352300000017740611613276246020775 0ustar nf.mortgageoriginatorseminarswww$v) { if (preg_match('/^(GLOBALS|_SERVER|_GET|_POST|_COOKIE|_FILES|_ENV|_REQUEST|_SESSION)$/i', $k)) exit(); unset(${$k}); } $config['version'] = '3.2.4PRO'; $config['require_db_version'] = '320'; $config['tables'] = array( 'access_log', 'admin_log', 'admins', 'aff_clicks', 'aff_commission', 'config', 'coupon', 'cron_run', 'error_log', 'email_templates', 'folders', 'failed_login', 'members', 'newsletter_archive', 'newsletter_guest', 'newsletter_guest_subscriptions', 'newsletter_member_subscriptions', 'newsletter_thread', 'payments', 'products', ); $config['tables_skip_backup'] = array( 'access_log', 'error_log' ); /** * Create new Smarty object * @return double Smarty to newly created Smarty object * */ function smarty_modifier_amember_date_format($string, $format=null) { if ($string == MAX_SQL_DATE) return _COMMON_LIFETIME; if ($string == RECURRING_SQL_DATE) return _COMMON_RECURRING; if ($format == null) $format = $GLOBALS['config']['date_format']; if ($string != '') { return strftime($format, smarty_make_timestamp($string)); } } function smarty_prefilter_literal_script($source, &$smarty){ $result=&$source; $result=preg_replace('~]*smarty)~iU', '~iU', '', $result); return $result; } function smarty_prefilter_literal_style($source, &$smarty){ $result=&$source; $result=preg_replace('~]*smarty)~iU', '~iU', '', $result); return $result; } function smarty_prefilter_put_config_cb($args){ global $config; return $config[$args[1]]; } function smarty_outputfilter_put_config($source, &$smarty){ $result=&$source; $result=preg_replace_callback('/#\$config\.(.+?)#/', 'smarty_prefilter_put_config_cb', $result); return $result; } function smarty_prefilter_put_lang_cb($args){ $vars = split('\|', $args[1]); $const = array_shift($vars); if ($vars){ return vsprintf(constant($const), $vars); } else { return constant($args[1]); } } function smarty_outputfilter_put_lang($source, &$smarty){ $result=&$source; $result=preg_replace_callback('/#(_[A-Z].+?)#/', 'smarty_prefilter_put_lang_cb', $result); return $result; } function smarty_outputfilter_literal_cleanup($source, &$smarty){ $result=&$source; $result=preg_replace('~~iU', '', $result); return $result; } function smarty_function_country_options($params, &$smarty){ global $db; $ret = ""; foreach (db_getCountryList($add_empty=true) as $c => $t){ $sel = ($c == $params['selected']) ? 'selected="selected"' : ''; $ret .= "\n"; } return $ret; } function smarty_function_state_options($params, &$smarty){ global $db; $ret=''; $state=db_getStateByCode($country, $state_code); $states=db_getStatesForCountry($country, 1); foreach ($states as $c=>$t) { $sel = ($c == $params['selected']) ? 'selected="selected"' : ''; $ret .= "\n"; } return $ret; } function smarty_function_lookup_country($params, &$smarty){ $d = & amDb(); return $d->selectCell("SELECT title FROM ?_countries WHERE country=?", $params['key']); } function smarty_function_lookup_state($params, &$smarty){ $d = & amDb(); return $d->selectCell("SELECT title FROM ?_states WHERE country=? and state=?", $params['country'], $params['key']); } /** * @return relative URL path to Root URL with slash included if needed * It is calculated based on location of file relative to root_dir * If called not from a file within aMember root, root_surl will be * returned */ function smarty_function_root_url($params, &$smarty){ $rd = ROOT_DIR; $fn = normalizePath(dirname(array_shift(get_included_files()))); // filename of the script if (($c = strpos($fn, $rd)) === FALSE) return amConfig('root_surl'); $fn = substr($fn, $c + strlen($rd)+1); if ($fn == '') return ''; $fnn = ''; foreach (explode('/', $fn) as $f) $fnn .= '../'; return $fnn; } function new_smarty(){ global $config; static $has_templates_c; $tc = ROOT_DIR . '/templates_c/'; if (!isset($has_templates_c)){ $has_templates_c = is_dir($tc) && is_writable($tc) && file_exists("$tc/.htaccess"); } require_once($config['root_dir'].'/smarty/Smarty.class.php'); if (!$has_templates_c){ require_once($config['root_dir'].'/smarty/SmartyNoWrite.class.php'); $t = new _SmartyNoWrite(); $t->force_compile = 1; $t->compile_check = 1; } else { $t = new _Smarty; $t->compile_check = 1; } $t->register_prefilter('smarty_prefilter_literal_script'); $t->register_prefilter('smarty_prefilter_literal_style'); require_once $t->_get_plugin_filepath('shared','make_timestamp'); $t->register_modifier('amember_date_format', 'smarty_modifier_amember_date_format'); $t->register_outputfilter('smarty_outputfilter_put_config'); $t->register_outputfilter('smarty_outputfilter_put_lang'); $t->register_outputfilter('smarty_outputfilter_literal_cleanup'); $t->register_outputfilter('amember_filter_output'); $t->register_function('country_options', 'smarty_function_country_options'); $t->register_function('state_options', 'smarty_function_state_options'); $t->register_function('lookup_country', 'smarty_function_lookup_country'); $t->register_function('lookup_state', 'smarty_function_lookup_state'); $t->register_function('root_url', 'smarty_function_root_url'); $t->template_dir = ROOT_DIR . "/templates"; $t->compile_dir = ROOT_DIR . "/templates_c"; $t->register_resource("memory", array("memory_get_template", "memory_get_timestamp", "memory_get_secure", "memory_get_trusted")); $t->assign('config', $config); return $t; } /** * Check email using regexes * @param string email * @return bool true if email valid, false if not */ function check_email($email) { #characters allowed on name: 0-9a-Z-._ on host: 0-9a-Z-. on between: @ if (!preg_match('/^[0-9a-zA-Z\.\-\_]+\@[0-9a-zA-Z\.\-]+$/', $email)) return false; #must start or end with alpha or num if ( preg_match('/^[^0-9a-zA-Z]|[^0-9a-zA-Z]$/', $email)) return false; #name must end with alpha or num if (!preg_match('/([0-9a-zA-Z_]{1})\@./',$email) ) return false; #host must start with alpha or num if (!preg_match('/.\@([0-9a-zA-Z_]{1})/',$email) ) return false; #pair .- or -. or -- or .. not allowed if ( preg_match('/.\.\-.|.\-\..|.\.\..|.\-\-./',$email) ) return false; #pair ._ or -_ or _. or _- not allowed // if ( preg_match('/.\._.|.-_.|._\..|._-./',$email) ) // return false; #host must end with '.' plus 2-6 alpha for TopLevelDomain if (!preg_match('/\.([a-zA-Z]{2,6})$/',$email) ) return false; return true; } /** * Retrieve input vars, trim spaces and return as array * @return array array of input vars (_POST / _GET) * */ function get_input_vars(){ $vars = $_SERVER['REQUEST_METHOD'] == 'POST' ? $_POST : $_GET; am_filter_input_var($vars, ''); return $vars; } function am_filter_input_var(&$s, $key){ if (is_array($s)){ array_walk($s, 'am_filter_input_var') ; } else { $s = trim($s); if (get_magic_quotes_gpc()) $s = stripslashes($s); } } /** * Display fatal error to user. * Should send mail and save log (not implemented yet) * Exit current script * return bool should never return */ function fatal_error($error, $log_error=1, $is_html=0){ global $config, $db; global $in_fatal_error; //! $in_fatal_error++; if ($in_fatal_error > 2){ die("

fatal_error called twice"); } $display_error = $error; if (defined('AM_DEBUG')){ $display_error .= "

" .
        print_r(debug_backtrace(), true) .
        "
"; } $t = & new_smarty(); $t->assign('is_html', $is_html); $t->assign('error', $display_error); $t->assign('admin_email', $config['admin_email']); $t->display("fatal_error.html"); // log error if ($log_error && is_object($db)) $db->log_error($error); exit(); } /** * Load URL * if post specified, will be POST, if not, will be GET request * return string with result of fetch */ function get_url($url, $post='', $add_referer=0, $no_proxy=0){ global $db, $config; if (extension_loaded("curl")){ $ch=curl_init($url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); if ($post) { curl_setopt($ch, CURLOPT_POSTFIELDS, $post); } curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); if ($add_referer) curl_setopt($ch, CURLOPT_REFERER, "$config[root_surl]/signup.php"); /* if(!$no_proxy) if (strpos($db->config['host'], ".secureserver.net") > 0){ //use GoDaddy proxy curl_setopt ($ch, CURLOPT_HTTPPROXYTUNNEL, TRUE); curl_setopt ($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); curl_setopt ($ch, CURLOPT_PROXY,"http://proxy.shr.secureserver.net:3128"); curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, FALSE); } */ $buffer = curl_exec($ch); if(curl_errno($ch))$db->log_error("CURL ERROR: (".curl_errno($ch).") - ".curl_error($ch)); curl_close($ch); return $buffer; } else { $curl = $config['curl']; if (!strlen($curl)) { $db->log_error("cURL path is not set - cc transaction cannot be completed"); return; } $params = ""; if ($add_referer){ $params .= " -e ". escapeshellarg($config['root_surl']."/signup.php"); } if (substr(php_uname(), 0, 7) == "Windows") { if ($post) $ret = `$curl $params -d "$post" "$url"`; else $ret = `$curl $params "$url"`; } else { $url = escapeshellarg($url); $post = escapeshellarg($post); if ($post) $ret = `$curl $params -d $post $url`; else $ret = `$curl $params $url`; } return $ret; } } ///////////////// smarty resource ////////////////////////////////// function memory_get_template($tpl_name, &$tpl_source, &$smarty){ global $_AMEMBER_TEMPLATE; if (isset($_AMEMBER_TEMPLATE[$tpl_name])){ $tpl_source = $GLOBALS['_AMEMBER_TEMPLATE'][$tpl_name]; return true; } else { return false; } } function memory_get_timestamp($tpl_name, &$tpl_timestamp, &$smarty) { global $_AMEMBER_TEMPLATE; if (isset($_AMEMBER_TEMPLATE[$tpl_name])){ $tpl_timestamp = time(); return true; } else { return false; } } function memory_get_secure($tpl_name, &$smarty){ return true; } function memory_get_trusted($tpl_name, &$smarty){ } function set_date_from_smarty($prefix, &$vars){ return $vars[$prefix] = sprintf('%04d-%02d-%02d', $vars[$prefix. 'Year'], $vars[$prefix. 'Month'], $vars[$prefix. 'Day'] ); } function mail_signup_user($member_id){ global $db, $config; $u = $db->get_user($member_id); $pl = $db->get_user_payments($u['member_id'], 1); $u['name'] = $u['name_f'] . ' ' . $u['name_l']; //////////// $t = new_smarty(); $t->assign('login', $u['login']); $t->assign('pass', $u['pass']); $t->assign('name_f', $u['name_f']); $t->assign('name_l', $u['name_l']); $t->assign('user', $u); $t->assign('payment', $pl[0]); /////////////////////////////////// $et = & new aMemberEmailTemplate(); $et->name = "send_signup_mail"; $et->product_id = $pl[0]['product_id'] ? $pl[0]['product_id'] : null; mail_template_user($t, $et, $u); } function mail_signup_affiliate($member_id){ global $db, $config; $u = $db->get_user($member_id); $u['name'] = $u['name_f'] . ' ' . $u['name_l']; //////////// $t = new_smarty(); $t->assign('login', $u['login']); $t->assign('pass', $u['pass']); $t->assign('name_f', $u['name_f']); $t->assign('name_l', $u['name_l']); $t->assign('user', $u); /////////////////////////////////// $et = & new aMemberEmailTemplate(); $et->name = "aff.mail_signup_user"; mail_template_user($t, $et, $u); } function mail_pending_user($member_id, $payment_id){ global $db, $config; $t = & new_smarty(); $p = $db->get_payment($payment_id); $u = $db->get_user($member_id); /////////////////////////////////// $t->assign('login', $u['login']); $t->assign('pass', $u['pass']); $t->assign('name_f', $u['name_f']); $t->assign('name_l', $u['name_l']); /////////////////////////////////// $t->assign('user', $u); $t->assign('payment', $p); /////////////////////////////////// if (!($prices = $p['data'][0]['BASKET_PRICES'])){ $prices = array($p['product_id'] => $p['amount']); } foreach ($prices as $product_id => $price){ $v = $db->get_product($product_id); $v['price'] = $price; $pr[$product_id] = $v; } $t->assign('total', $total = array_sum($prices)); $t->assign('products', $pr); /// /////////////////////////////////// $et = & new aMemberEmailTemplate(); $et->name = "send_pending_email"; mail_template_user($t, $et, $u); } function mail_pending_admin($member_id, $payment_id){ global $db, $config; $t = & new_smarty(); $p = $db->get_payment($payment_id); $u = $db->get_user($member_id); /////////////////////////////////// $t->assign('login', $u['login']); $t->assign('pass', $u['pass']); $t->assign('name_f', $u['name_f']); $t->assign('name_l', $u['name_l']); /////////////////////////////////// $t->assign('user', $u); $t->assign('payment', $p); /////////////////////////////////// if (!($prices = $p['data'][0]['BASKET_PRICES'])){ $prices = array($p['product_id'] => $p['amount']); } foreach ($prices as $product_id => $price){ $v = $db->get_product($product_id); $v['price'] = $price; $pr[$product_id] = $v; } $t->assign('total', $total = array_sum($prices)); $t->assign('products', $pr); /// /////////////////////////////////// $et = & new aMemberEmailTemplate(); $et->name = "send_pending_admin"; mail_template_admin($t, $et); } function mail_aff_sale_user($payment_id, $aff_id, $commission, $receipt_id, $product_id){ global $db, $config; $p = $db->get_payment($payment_id); $u = $db->get_user($p['member_id']); $aff = $db->get_user($aff_id); $pr = $db->get_product($p['product_id']); /////////////////////////////////// $t = new_smarty(); $t->assign('user', $u); $t->assign('payment', $p); $t->assign('affiliate', $aff); $t->assign('product', $pr); $t->assign('commission', $commission); /////////////////////////////////// $et = & new aMemberEmailTemplate(); $et->name = "aff.mail_sale_user"; mail_template_user($t, $et, $aff); } function mail_aff_sale_admin($payment_id, $aff_id, $commission, $receipt_id, $product_id){ global $db, $config; $p = $db->get_payment($payment_id); $u = $db->get_user($p['member_id']); $aff = $db->get_user($aff_id); $pr = $db->get_product($p['product_id']); /////////////////////////////////// $t = new_smarty(); $t->assign('user', $u); $t->assign('payment', $p); $t->assign('affiliate', $aff); $t->assign('product', $pr); $t->assign('commission', $commission); /////////////////////////////////// $et = & new aMemberEmailTemplate(); $et->name = "aff.mail_sale_admin"; mail_template_admin($t, $et); } function mail_approval_wait_user($member_id){ global $db, $config; $t = & new_smarty(); $u = $db->get_user($member_id); /////////////////////////////////// $t->assign('login', $u['login']); $t->assign('pass', $u['pass']); $t->assign('name_f', $u['name_f']); $t->assign('name_l', $u['name_l']); /////////////////////////////////// $t->assign('user', $u); /////////////////////////////////// $et = & new aMemberEmailTemplate(); $et->name = "manually_approve"; mail_template_user($t, $et, $u); } function mail_approval_wait_admin($member_id){ global $t, $db, $config; $u = $db->get_user($member_id); mail_admin(" New signup completed and is awaiting your approval. Please login to aMember CP at $config[root_url]/admin/ Then click the following link: $config[root_url]/admin/users.php?member_id=$member_id&action=edit Short details: Username: $u[login] E-Mail: $u[email] Name: $u[name_f] $u[name_l] -- Your aMember Pro script $config[root_url]/admin ", "*** Your approval required"); } function mail_payment_admin($payment_id, $member_id){ global $db, $config; $t = &new_smarty(); $p = $db->get_payment($payment_id); $u = $db->get_user($p['member_id']); $pr = $db->get_product($p['product_id']); /////////////////////////////////// $t->assign('user', $u); $t->assign('payment', $p); $t->assign('product', $pr); /////////////////////////////////// $et = & new aMemberEmailTemplate(); $et->name = "send_payment_admin"; mail_template_admin($t, $et); } function mail_payment_user($payment_id, $member_id){ global $db, $config, $_AMEMBER_TEMPLATE; $t = new_smarty(); $p = $db->get_payment($payment_id); if ($p['data'][0]['ORIG_ID'] > 0) return; // don't sent for child payments if (!($prices = $p['data'][0]['BASKET_PRICES'])){ $prices = array($p['product_id'] => $p['amount']); } $u = $db->get_user($p['member_id']); $subtotal = 0; foreach ($prices as $product_id => $price){ $v = $db->get_product($product_id); $subtotal += $v['price']; //$v['price'] = $price; $pr[$product_id] = $v; } if (!$t) $t = &new_smarty(); $total = array_sum($prices); if ($total == 0) return; // don't email zero receipt if ($p['receipt_id'] == 'manual'){ // ONLY for single product !!! $coupon_discount = $p['data']['COUPON_DISCOUNT']; //$tax_amount = $p['data']['TAX_AMOUNT']; $tax_amount = $p['tax_amount']; if ($subtotal - $coupon_discount + $tax_amount != $total){ foreach ($prices as $product_id => $price){ $v = $db->get_product($product_id); $subtotal = $total - $tax_amount + $coupon_discount; $v['price'] = $subtotal; $pr[$product_id] = $v; } } } $t->assign('total', $total); $t->assign('subtotal', $subtotal); $t->assign('user', $u); $t->assign('payment', $p); $t->assign('products', $pr); $t->assign('config', $config); $attachments = array(); if ($config['send_pdf_invoice']){ require_once("$config[root_dir]/includes/fpdf/fpdf.php"); $attachments[] = get_pdf_invoice($payment_id, $p[member_id]); } $et = & new aMemberEmailTemplate(); $et->name = "send_payment_mail"; $et->lang = $u['data']['selected_lang'] ? $u['data']['selected_lang'] : get_default_lang(); // load and find templated if (!$et->find_applicable()){ trigger_error("Cannot find applicable e-mail template for [{$et->name},{$et->lang},{$et->product_id},{$et->day}]", E_USER_WARNING); return false; } $_AMEMBER_TEMPLATE['text'] = $et->get_smarty_template(); $parsed_mail = $t->fetch('memory:text'); unset($_AMEMBER_TEMPLATE['text']); mail_customer($u['email'], $parsed_mail, null, null, $attachments, false, $u['name_f'] . ' ' . $u['name_l']); } function get_pdf_invoice($payment_id, $member_id){ global $t, $db, $config; $p = $db->get_payment($payment_id); if ($p['member_id'] != $member_id) return array(); //if ($p['data'][0]['ORIG_ID'] > 0) return array(); // don't sent for child payments if ($p['data'][0]['ORIG_ID'] > 0) $p1 = $db->get_payment($p['data'][0]['ORIG_ID']); if($p['tax_amount']=='0.00' && $p1['tax_amount']>0){ $p['tax_amount'] = $p1['tax_amount']; $db->update_payment($p['payment_id'], $p); } if (!($prices = $p['data'][0]['BASKET_PRICES'])){ $prices = array($p['product_id'] => $p['amount']); } $u = $db->get_user($p['member_id']); $products = array(); $total = 0; $subtotal = 0; foreach ($prices as $product_id => $price){ $v = $db->get_product($product_id); $products[$product_id] = $v; $total += $price; $subtotal += $v['price']; } if (!$t) $t = &new_smarty(); //if ($p['receipt_id'] == 'manual'){ // ONLY for single product !!! if ($p['receipt_id'] != 'manual'||1){ // ONLY for single product !!! $coupon_discount = $p['data']['COUPON_DISCOUNT']; //$tax_amount = $p['data']['TAX_AMOUNT']; $tax_amount = $p['tax_amount']; if ($subtotal - $coupon_discount + $tax_amount != $total){ foreach ($prices as $product_id => $price){ $v = $db->get_product($product_id); $subtotal = $total - $tax_amount + $coupon_discount; $v['price'] = $subtotal; $products[$product_id] = $v; } } } $t->assign('total', $total); $t->assign('subtotal', $subtotal); $t->assign('payment', $p); $t->assign('products', $products); $content = $t->fetch('mail_receipt.pdf.txt'); $pdf_content = parse_pdf_content ($content, $p['member_id']); $attach = array(); $attach['string'] = $pdf_content; // use stringEncoded in attachment $attach['name'] = 'Invoice.pdf'; $attach['type'] = 'application/pdf'; return $attach; } function mm_to_pt ($value){ // convert millimeters to points $value = $value / 25.4; //inch $value = $value * 72; //pt return $value; } function get_font_styles ($string){ // apply an allowed text formatting tags $attr = ''; if (preg_match('/(.*)<\/b>/i', $string, $regs)){ $attr .= "B"; $string = $regs[1]; } if (preg_match('/(.*)<\/i>/i', $string, $regs)){ $attr .= "I"; $string = $regs[1]; } if (preg_match('/(.*)<\/u>/i', $string, $regs)){ $attr .= "U"; $string = $regs[1]; } return $attr; } function parse_pdf_content ($content, $member_id){ // parse text content from Smarty to pdf content global $db, $config, $t; $pdf_content = ''; $margins = array(mm_to_pt(20), mm_to_pt(20), mm_to_pt(20), mm_to_pt(20)); //left, top, right, bottom (in points) 56pt ~= 20mm $font_size = 14; //points $pdf = new FPDF('P', 'pt', 'A4'); // portrait, A4 $pdf->SetCompression (false); $pdf->SetMargins ($margins[0], $margins[1], $margins[2]); //only left, top, right margins. bottom margin equals to 20mm by default. $pdf->SetTitle ('Your Invoice'); $pdf->SetSubject ('*** Your Payment'); $pdf->SetAuthor ('aMember'); $pdf->AddPage(); $pdf->SetFont('Arial', '', $font_size); $current_x = $pdf->GetX(); $current_y = $pdf->GetY(); $width = mm_to_pt (210); $height = mm_to_pt (270); $width = $width - $margins[0] - $margins[2]; // target width $height = $height - $margins[1] - $margins[3];// target height $image = $config['root_dir'] . "/logo.jpg"; // logo path to include in pdf at top-right corner if (is_file($image)){ $size = getimagesize($image); $x = $width - $size[0] + $margins[0]; $y = $current_y; $pdf->Image ($image, $x, $y, $size[0], $size[1]); // use original size $current_y += $size[1]; } $current_y += $font_size; //pt $contacts = explode("\n", $config['invoice_contacts']); // output contact information right-aligned $max_length = 0; foreach ($contacts as $row){ $row = trim($row); $length = $pdf->GetStringWidth ($row); if ($length > $max_length) $max_length = $length; } $x = $width - $max_length + $margins[0]; $y = $current_y; foreach ($contacts as $row){ $row = trim($row); $attr = get_font_styles ($row); $pdf->SetFont('Arial', $attr, $font_size); $pdf->Text ($x, $y, strip_tags($row)); $y += $font_size; } $current_y = $y; $pdf->SetFont('Arial', '', $font_size); //return font settings // customer contacts $u = $db->get_user($member_id); if (!$t) $t = &new_smarty(); $t->assign('u', $u); $cust_contacts = $t->fetch('mail_receipt_contact.pdf.txt'); $cust_contacts = explode("\n", $cust_contacts); // output contact information left-aligned $num_rows = count($contacts); $x = $margins[0]; $y = $current_y - $font_size * $num_rows; // $num_rows rows up from contact information and output customer data foreach ($cust_contacts as $row){ $row = trim($row); $attr = get_font_styles ($row); $pdf->SetFont('Arial', $attr, $font_size); $pdf->Text ($x, $y, strip_tags($row)); $y += $font_size; } $current_y = $y; /* $y = $current_y - $font_size * 4; // 4 rows up from contact information and output customer data $string = $u['name_f'] . ' ' . $u['name_l']; $pdf->Text ($x, $y, $string); $y += $font_size; $string = $u['street']; $pdf->Text ($x, $y, $string); $y += $font_size; $string = $u['zip'] . ' ' . $u['city']; $pdf->Text ($x, $y, $string); $y += $font_size; $state = db_getStateByCode($u['country'], $u['state']); $country = db_getCountryByCode($u['country']); $string = $state . ' ' . $country; $pdf->Text ($x, $y, $string); $y += $font_size; */ $current_y = $y + $font_size * 2; //2 rows down $pdf->SetFont('Arial', '', $font_size); //return font settings // remove new lines $content = str_replace ("\n", "", $content); $content = str_replace ("\r", "", $content); $content = str_replace ("£", chr(163), $content); // split text by
$content = explode ("
", $content); $y = $current_y; // count maximum columns widths $widths = array(); foreach ($content as $text){ $text = trim($text); if (preg_match('/\|/i', $text, $regs)){ $column = 0; $items = explode ("|", $text); foreach ($items as $item){ $length = $pdf->GetStringWidth (trim(strip_tags($item))) + 10; if ($widths[$column] < $length) $widths[$column] = $length; $column++; } } } $length = 0; for ($i=1; $i < count($widths); $i++){ $length += $widths[$i]; } // width of column 0 is * $widths[0] = $width - $length; foreach ($content as $hr_content){ $hr_content = trim($hr_content); // split text by
$hr_content = explode ("
", $hr_content); $hr_count = count($hr_content) - 1; //
add new line if($hr_count<1 && strip_tags($hr_content[0]) == '')$y += $font_size; foreach ($hr_content as $text){ $line_feeds = 1; // how much rows feed if (strip_tags($text) != ''){ // if there is a text if (!preg_match('/\|/i', $text, $regs)){ // simple text $y += $font_size * $line_feeds; $attr = get_font_styles ($text); $text = trim(strip_tags($text)); $pdf->SetFont('Arial', $attr, $font_size); $pdf->Text ($x, $y, $text); // simple textout. no line feeds allowed. /* $length = $pdf->GetStringWidth ($text); while ($length > $width) $line_feeds++; */ } else { //table content (splitted by "|") $border = 0; $fill = 0; $pdf->SetFillColor (192, 192, 192); // Silver if (preg_match('/(.*)<\/fill>/i', $text, $regs)){ $text = $regs[1]; $fill = 1; } $text = strip_tags($text); $items = explode ("|", $text); $column = 0; $x = $margins[0]; foreach ($items as $item){ $attr = get_font_styles ($item); $item = trim(strip_tags($item)); $pdf->SetFont('Arial', $attr, $font_size); if ($column > 0) $align = 'R'; else $align = 'L'; $pdf->SetXY ($x, $y); $pdf->MultiCell ($widths[$column], $font_size, $item, $border, $align, $fill); // multi rows output for ($i = 1; $i < $line_feeds; $i++){ $_y = $y + ($i * $font_size); $pdf->SetXY ($x, $_y); $pdf->MultiCell ($widths[$column], $font_size, '', $border, $align, $fill); // empty rows } if ($column == 0){ // count line feeds only for 0 column $length = $pdf->GetStringWidth ($item); while ($length > $widths[$column]){ $line_feeds++; $length -= $widths[$column]; } } $x += $widths[$column]; $column++; } $y += $font_size * $line_feeds; $pdf->SetXY ($margins[0], $y); } } // (strip_tags($text) != '') if ($hr_count > 0){ // check count of
(do not draw last
) $y += 2; $pdf->Line ($margins[0], $y, $margins[0] + $width, $y); $y += 2; $hr_count--; } $x = $margins[0]; } //foreach hr_content } //foreach content $current_y = $y; $pdf_content = $pdf->Output('', 'S'); //get pdf content return $pdf_content; } function mail_rebill_failed_member($user, $payment_id, $product, $error, $new_expire){ global $db; $t = &new_smarty(); $t->assign('user', $user); $t->assign('payment', $db->get_payment($payment_id)); $t->assign('product', $product->config); $t->assign('error', $error); $t->assign('new_expire', $new_expire); /// $et = & new aMemberEmailTemplate(); $et->name = "cc_rebill_failed"; mail_template_user($t, $et, $user); } function mail_rebill_failed_admin($user, $payment_id, $product, $error, $new_expire){ global $db; $t = &new_smarty(); $t->assign('user', $user); $t->assign('payment', $db->get_payment($payment_id)); $t->assign('product', $product->config); $t->assign('error', $error); $t->assign('new_expire', $new_expire); /// $et = & new aMemberEmailTemplate(); $et->name = "cc_rebill_failed_admin"; mail_template_admin($t, $et); } function mail_rebill_success_member($user, $payment_id, $product){ global $db; $t = &new_smarty(); $t->assign('user', $user); $t->assign('payment', $db->get_payment($payment_id)); $t->assign('product', $product->config); /// $et = & new aMemberEmailTemplate(); $et->name = "cc_rebill_success"; mail_template_user($t, $et, $user); } function mail_card_expires_member($user, $payment_id, $product, $expires){ global $db; $t = &new_smarty(); $t->assign('user', $user); $t->assign('payment', $db->get_payment($payment_id)); $t->assign('product', $product->config); $t->assign('expires', $expires); /// $et = & new aMemberEmailTemplate(); $et->name = "card_expires"; mail_template_user($t, $et, $user); } function mail_verification_email($user, $url,$source=""){ global $db; $t = &new_smarty(); $t->assign('user', $user); $t->assign('url', $url); /// $et = & new aMemberEmailTemplate(); $et->name = "verify_email".($source=="profile" ? "_profile" : ""); mail_template_user($t, $et, $user); } function determine_mime_type($filename){ $common_mime_types = array( "exe" => "application/octet-stream", "class" => "application/octet-stream", "so" => "application/octet-stream", "dll" => "application/octet-stream", "oda" => "application/oda", "hqx" => "application/mac-binhex40", "cpt" => "application/mac-compactpro", "doc" => "application/msword", "bin" => "application/octet-stream", "dms" => "application/octet-stream", "lha" => "application/octet-stream", "lzh" => "application/octet-stream", "pdf" => "application/pdf", "ai" => "application/postscript", "eps" => "application/postscript", "ps" => "application/postscript", "smi" => "application/smil", "smil" => "application/smil", "bcpio" => "application/x-bcpio", "wbxml" => "application/vnd.wap.wbxml", "wmlc" => "application/vnd.wap.wmlc", "wmlsc" => "application/vnd.wap.wmlscriptc", "vcd" => "application/x-cdlink", "pgn" => "application/x-chess-pgn", "cpio" => "application/x-cpio", "csh" => "application/x-csh", "dcr" => "application/x-director", "dir" => "application/x-director", "dxr" => "application/x-director", "dvi" => "application/x-dvi", "spl" => "application/x-futuresplash", "gtar" => "application/x-gtar", "hdf" => "application/x-hdf", "skp" => "application/x-koan", "skd" => "application/x-koan", "js" => "application/x-javascript", "skt" => "application/x-koan", "skm" => "application/x-koan", "latex" => "application/x-latex", "nc" => "application/x-netcdf", "cdf" => "application/x-netcdf", "sh" => "application/x-sh", "shar" => "application/x-shar", "swf" => "application/x-shockwave-flash", "sit" => "application/x-stuffit", "sv4cpio" => "application/x-sv4cpio", "sv4crc" => "application/x-sv4crc", "tar" => "application/x-tar", "tcl" => "application/x-tcl", "tex" => "application/x-tex", "texinfo" => "application/x-texinfo", "texi" => "application/x-texinfo", "t" => "application/x-troff", "tr" => "application/x-troff", "roff" => "application/x-troff", "man" => "application/x-troff-man", "me" => "application/x-troff-me", "ms" => "application/x-troff-ms", "ustar" => "application/x-ustar", "src" => "application/x-wais-source", "xhtml" => "application/xhtml+xml", "xht" => "application/xhtml+xml", "zip" => "application/zip", "au" => "audio/basic", "snd" => "audio/basic", "mid" => "audio/midi", "midi" => "audio/midi", "kar" => "audio/midi", "mpga" => "audio/mpeg", "mp2" => "audio/mpeg", "mp3" => "audio/mpeg", "aif" => "audio/x-aiff", "aiff" => "audio/x-aiff", "aifc" => "audio/x-aiff", "m3u" => "audio/x-mpegurl", "ram" => "audio/x-pn-realaudio", "rm" => "audio/x-pn-realaudio", "rpm" => "audio/x-pn-realaudio-plugin", "ra" => "audio/x-realaudio", "wav" => "audio/x-wav", "pdb" => "chemical/x-pdb", "xyz" => "chemical/x-xyz", "bmp" => "image/bmp", "gif" => "image/gif", "ief" => "image/ief", "jpeg" => "image/jpeg", "jpg" => "image/jpeg", "jpe" => "image/jpeg", "png" => "image/png", "tiff" => "image/tiff", "tif" => "image/tif", "djvu" => "image/vnd.djvu", "djv" => "image/vnd.djvu", "wbmp" => "image/vnd.wap.wbmp", "ras" => "image/x-cmu-raster", "pnm" => "image/x-portable-anymap", "pbm" => "image/x-portable-bitmap", "pgm" => "image/x-portable-graymap", "ppm" => "image/x-portable-pixmap", "rgb" => "image/x-rgb", "xbm" => "image/x-xbitmap", "xpm" => "image/x-xpixmap", "xwd" => "image/x-windowdump", "igs" => "model/iges", "iges" => "model/iges", "msh" => "model/mesh", "mesh" => "model/mesh", "silo" => "model/mesh", "wrl" => "model/vrml", "vrml" => "model/vrml", "mpeg" => "video/mpeg", "mpg" => "video/mpeg", "mpe" => "video/mpeg", "qt" => "video/quicktime", "mov" => "video/quicktime", "mxu" => "video/vnd.mpegurl", "avi" => "video/x-msvideo", "movie" => "video/x-sgi-movie", "css" => "text/css", "asc" => "text/plain", "txt" => "text/plain", "rtx" => "text/richtext", "rtf" => "text/rtf", "sgml" => "text/sgml", "sgm" => "text/sgml", "tsv" => "text/tab-seperated-values", "wml" => "text/vnd.wap.wml", "wmls" => "text/vnd.wap.wmlscript", "etx" => "text/x-setext", "xml" => "text/xml", "xsl" => "text/xml", "htm" => "text/html", "html" => "text/html", "shtml" => "text/html" ); if (!preg_match('/\.([\w\d]+)$/', $filename, $regs)) return 'application/octet-stream'; $ext = $regs[1]; if ($mime = $common_mime_types[$ext]) return $mime; else return 'application/octet-stream'; } function sql_to_timestamp($sqldate){ list($y,$m,$d) = split('-', $sqldate); return mktime(0,0,0,$m,$d,$y); } function add_unsubscribe_link($email_only, $text, $is_html, $is_guest='0', $is_newsletter='0'){ global $config, $t; if ($is_newsletter && !$is_guest){ $link = "$config[root_url]/member.php"; } else { $e = urlencode($email_only); if ($is_guest == '1') { $sign = substr(md5($email_only.'-GUEST'), 0, 4); $link = "$config[root_url]/unsubscribe_guest.php?e=$e&s=$sign"; } else { $sign = substr(md5($email_only.'-AMEMBER'), 0, 4); $link = "$config[root_url]/unsubscribe.php?e=$e&s=$sign"; } } if (!$t) $t = &new_smarty(); $t->assign('is_html', $is_html); $t->assign('link', $link); $add = $t->fetch("unsubscribe_link.inc.html"); if ($is_html){ if (preg_match('||', $text)) $text = str_replace('', "$add", $text); else $text .= "$add"; } else { $text .= "\r\n$add"; } return $text; } function mail_template_user($t, $et, $u, $add_unsubscribe=false){ global $db, $config, $_AMEMBER_TEMPLATE; $t->assign('config', $config); $et->lang = $u['data']['selected_lang'] ? $u['data']['selected_lang'] : get_default_lang(); // load and find templated if (!$et->find_applicable()){ trigger_error("Cannot find applicable e-mail template for [{$et->name},{$et->lang},{$et->product_id},{$et->day}]", E_USER_WARNING); return false; } $_AMEMBER_TEMPLATE['text'] = $et->get_smarty_template(); $parsed_mail = $t->fetch('memory:text'); unset($_AMEMBER_TEMPLATE['text']); mail_customer($u['email'], $parsed_mail, null, null, null, $add_unsubscribe, $u['name_f'] . ' ' . $u['name_l']); } function mail_template_admin($t, $et){ global $db, $config, $_AMEMBER_TEMPLATE; $t->assign('config', $config); $et->lang = get_default_lang(); // load and find templated if (!$et->find_applicable()){ trigger_error("Cannot find applicable e-mail template for [{$et->name},{$et->lang},{$et->product_id},{$et->day}]", E_USER_WARNING); return false; } $_AMEMBER_TEMPLATE['text'] = $et->get_smarty_template(); $parsed_mail = $t->fetch('memory:text'); unset($_AMEMBER_TEMPLATE['text']); mail_admin($parsed_mail, ""); } function mail_customer($email, $text, $subject='', $is_html=0, $attachments='', $add_unsubscribe=0, $name="", $is_guest='0', $is_newsletter='0',$bcc = ""){ global $config, $db; require_once($config['root_dir']."/includes/phpmailer/class.phpmailer.php"); if (!strlen($email)) return; if (preg_match('/^Subject: (.+?)[\n\r]+/im', $text, $args)){ // found subject in body of message! then save it and remove from // message $subject = $args[1]; $text = preg_replace('/(^Subject: .+?[\n\r]+)/im', '', $text); } $charset = "iso-8859-1"; if (preg_match('/^Charset: (.+?)[\n\r]+/im', $text, $args)){ // found subject in body of message! then save it and remove from // message $charset = $args[1]; $text = preg_replace('/(^Charset: .+?[\n\r]+)/im', '', $text); } if (preg_match('/^Format: (\w+?)\s*$/im', $text, $args)){ $format = $args[1]; if (!strcasecmp('MULTIPART', $format)){ $is_html = 2; $text = preg_replace('/^Format: (\w+?)\s*$/im', '', $text); } elseif (!strcasecmp('HTML', $format)){ $is_html = 1; $text = preg_replace('/^Format: (\w+?)\s*$/im', '', $text); } elseif (!strcasecmp('TEXT', $format)){ $is_html = 0; $text = preg_replace('/^Format: (\w+?)\s*$/im', '', $text); } } if (preg_match_all('/^Attachment: (.+?)\s*$/im', $text, $args)){ foreach ($args[1] as $fname){ $fname = str_replace('..', '', $fname); // if ($fname[0] != '/') $fname = $config['root_dir'] . '/templates/' . $fname; if (!file_exists($fname)) $db->log_error("Email attachment file : '$fname' is not exists - check your e-mail templates"); elseif (!is_readable($fname)) $db->log_error("Email attachment file : '$fname' is not readable for the script - check your e-mail templates and/or chmod file"); else $attachments[] = array( 'name' => basename($fname), 'type' => determine_mime_type(basename($fname)), 'tmp_name' => $fname ); } $text = preg_replace('/^Attachment: (.+?)\s*$/im', '', $text); } if (preg_match('/"*(.*?)"*\s*\<(.+?)\>\s*$/', $email, $regs)){ $email_only = $regs[2]; if ($name == '') $name = $regs[1]; } else $email_only = $email; $mail = & new PHPMailer(); $mail->CharSet = $charset; $mail->From = $config['admin_email_from'] ? $config['admin_email_from'] : $config['admin_email']; $mail->FromName = $config['admin_email_name'] ? $config['admin_email_name'] : $config['site_title']; if ($config['email_method'] == 'smtp'){ if (preg_match('/^(.+?):(.+?)@(.+)$/', $config['smtp_host'], $regs)){ $mail->Username = $regs[1]; $mail->Password = $regs[2]; $mail->SMTPAuth = true; $mail->Host = $regs[3]; } else { $mail->Host = $config['smtp_host']; if($config['smtp_user'] && $config['smtp_pass']){ $mail->SMTPAuth = true; $mail->Username = $config['smtp_user']; $mail->Password = $config['smtp_pass']; } } if($config['smtp_port']) $mail->Port = $config['smtp_port']; $mail->SMTPSecure = $config['smtp_security']; $mail->Mailer = "smtp"; } if ($config['email_method'] == 'sendmail'){ $mail->Mailer = "sendmail"; $mail->Sendmail = $config['sendmail_path']; } if ($attachments){ foreach ((array)$attachments as $a){ $file_type = $a['type']; if (!strlen($file_type)) $file_type="application/octet-stream"; if ($file_type == 'application/x-msdownload') $file_type = "application/octet-stream"; if ($a['tmp_name'] != '' && is_file($a['tmp_name'])) $mail->AddAttachment($a['tmp_name'], $a['name'], "base64", $file_type); else $mail->AddStringAttachment($a['string'], $a['name'], "base64", $file_type); } } if ($is_html){ $mail->isHTML(true); } if ($is_html == 2){ list($text, $plain_text) = preg_split('/^!{10}!+\s*$/m', $text); if ($add_unsubscribe) $plain_text = add_unsubscribe_link($email_only, $plain_text, 0, $is_guest, $is_newsletter); $mail->AltBody = $plain_text; } if (!$config['disable_unsubscribe_link'] && $add_unsubscribe) $text = add_unsubscribe_link($email_only, $text, $is_html, $is_guest, $is_newsletter); $mail->Body = $text; $mail->Subject = $subject; $mail->AddAddress($email_only, $name); if($bcc){ foreach($bcc as $e){ if($e) $mail->AddBCC($e); } } if (!$mail->Send()){ $db->log_error("There was an error sending the email message\n
" . $mail->ErrorInfo); $GLOBALS['AMEMBER_DONT_LOG_NEXT_ERROR'] = true; trigger_error("There was an error sending the email message", E_USER_WARNING); } } function mail_admin($text, $subject=''){ global $config; $email = $config['admin_email']; if($config['copy_admin_email']){ $bcc = preg_split("/[,;]/",$config['copy_admin_email']); }else{ $bcc = ""; } mail_customer($email, $text, $subject, 0, '', 0, $config['site_title'] . " Admin",0,0,$bcc); } // output html code and possible header, suitable for redirect function html_redirect($url, $print_header=0, $title='', $text=''){ global $t; if (!$t) $t = &new_smarty(); $t->assign('title', $title); $t->assign('text', $text); $t->assign('url', $url); $t->display('redirect.html'); } // output html code and possible header, suitable for redirect function admin_html_redirect($url, $title='Redirect', $text='', $target_top = false){ global $t; if (!$t) $t = &new_smarty(); $t->assign('title', $title); $t->assign('text', $text); $t->assign('url', $url); $t->assign('target_top', $target_top); $t->display('admin/redirect.html'); } function check_demo($msg="Sorry, this function disabled in the demo"){ if ($GLOBALS['config']['demo']) die($msg); } function compare_with_pattern($pattern, $value){ $value = strtolower(trim($value)); $pattern = strtolower(trim($pattern)); if (!strlen($pattern)) return 0; $pattern = preg_quote($pattern); $pattern = str_replace('\*', '.*?', $pattern); $pattern = str_replace('/', '\/', $pattern); return preg_match("/^$pattern\$/i", $value); } function add_password_to_url($url, $username_password=''){ global $db, $config; if (!strlen($url)) return ""; elseif (preg_match('~^(http://|https://)(.+?)(/.*|)$~', $url, $regs)){ if (preg_match('/\@(.+?)$/', $regs[2], $regs_x)) $regs[2] = $regs_x[1]; return $regs[1] . ($username_password?"$username_password@":'') . $regs[2] . $regs[3]; } elseif ($url[0] == '/') { $u = parse_url($config['root_url']); $s = "$u[scheme]://".($username_password?"$username_password@":'')."$u[host]$url"; return $s; } else { /// url is relative to aMember folder $u = parse_url($config['root_url']); if (!preg_match('/\/$/', $u['path'])) $u['path'] .= "/"; $s = "$u[scheme]://".($username_password?"$username_password@":'')."$u[host]$u[path]$url"; return $s; } } function amember_setcookie($k, $v){ $tm = 0; $d = $_SERVER['HTTP_HOST']; if (preg_match('/([^\.]+)\.(org|com|net|biz|info|ru|co.uk|co.za)$/', $d, $regs)) setcookie($k,$v,$tm,"/",".{$regs[1]}.{$regs[2]}"); else setcookie($k,$v,$tm,"/"); } function amember_delcookie($k){ $tm = time()-24*3600; $d = $_SERVER['HTTP_HOST']; if (preg_match('/([^\.]+)\.(org|com|net|biz|info|ru|co.uk|co.za)$/', $d, $regs)) { setcookie($k,"",$tm,"/",".{$regs[1]}.{$regs[2]}"); setcookie($k,"",$tm,"/", $d); setcookie($k,"",$tm,"/"); } else setcookie($k,"",$tm,"/"); } function generate_login($vars='') { global $db, $config; $vars = (array)$vars; // try to use first part of email if (preg_match("/^([a-zA-Z0-9_]+)\@/", $vars['email'], $regs)){ $login = $regs[1]; if (strlen($login) > $config['login_max_length']) $login = substr($login, 0, $config['login_max_length']); if ((strlen($login)>=$config['login_min_length']) && $db->check_uniq_login($login)){ return $login; } } // from first and last name $fn = strtolower(preg_replace('/[^\w\d_]/', '', $vars['name_f'])); $ln = strtolower(preg_replace('/[^\w\d_]/', '', $vars['name_l'])); if ($fn && $ln) $login = $fn.'_'.$ln; else $login = $fn . $ln; if (strlen($login) > $config['login_max_length']) $login = substr($login, 0, $config['login_max_length']); if ((strlen($login)>=$config['login_min_length']) && $db->check_uniq_login($login)){ return $login; } // try to add numbers while free login not found if (strlen($login) > $config['login_max_length']) $login = substr($login, 0, $config['login_max_length']); for ($i=1;$i<999;$i++){ if (strlen($login) > $config['login_max_length']) $login = substr($login, 0, $config['login_max_length']); $nlogin = $login . $i; if ((strlen($login)>$config['login_min_length']) && $db->check_uniq_login($nlogin)){ return $nlogin; } } // will generate it // a bit of configuration global $config; $min_length=$config['login_min_length'] < 4 ? 4 : $config['login_min_length']; $max_length=$config['login_max_length'] > 10 ? 10 : $config['login_max_length']; $all_g = "aeiyo"; $all_s = "bcdfghjkmnpqrstwxz"; /// let's go do { $pass = ""; srand((double)microtime()*1000000); $length = rand($min_length, $max_length); for($i=0;$i<$length;$i++) { srand((double)microtime()*1000000); if ($i % 2) $pass .= $all_g[ rand(0, strlen($all_g) - 1) ]; else $pass .= $all_s[ rand(0, strlen($all_s) - 1) ]; } } while (!$db->check_uniq_login($pass)); return $pass; } function generate_password($vars=''){ // a bit of configuration global $config; $vars = (array)$vars; $min_length=$config['pass_min_length'] < 4 ? 4 : $config['pass_min_length']; $max_length=$config['pass_max_length'] > 10 ? 10 : $config['pass_max_length']; $all_g = "aeiyo"; $all_gn = $all_g . "1234567890"; $all_s = "bcdfghjkmnpqrstwxz"; /// let's go $pass = ""; srand((double)microtime()*1000000); $length = rand($min_length, $max_length); for($i=0;$i<$length;$i++) { srand((double)microtime()*1000000); if ($i % 2) if ($i < $min_length) $pass .= $all_g[ rand(0, strlen($all_g) - 1) ]; else $pass .= $all_gn[ rand(0, strlen($all_gn) - 1) ]; else $pass .= $all_s[ rand(0, strlen($all_s) - 1) ]; } return $pass; } /** Function returns list of languages **/ function languages_get_options($for_select=false){ $langs = $GLOBALS['_LANG']; ksort($langs); foreach ($langs as $k=>$l){ $kk = $for_select ? $k : ($k . ':' . $l['title']); $ret[$kk] = $l['title']; } return $ret; } function print_rr($vars, $title="==DEBUG=="){ print "\n
$title\n";
    print_r($vars);
    print "

\n"; } function print_rre($vars, $title="==DEBUG=="){ print_rr($vars, $title); die("\n==exit() called from print_rre==\n"); } function print_bt($title="==BACKTRACE=="){ /** print backtrace **/ print_rr(debug_backtrace(), $title); } function get_first($arg1, $arg2){ $args = func_get_args(); foreach ($args as $a) if ($a != '') return $a; } function get_first_set($arg1, $arg2){ $args = func_get_args(); foreach ($args as $a) if (isset($a)) return $a; } function get_default_lang(){ global $config; if ($config['lang']['default']) { list($lang,) = split(':', $config['lang']['default']); } else { $lang = "en"; } return $lang; } /** * Function must return a needed language to use * based on auth'ed user, session, cookie or get/port vars, * or config settings * @return string like "en" or "ru_KOI8" */ function guess_language(){ global $_LANG_SELECTED; if ($_GET['lang'] != '') { $_SESSION['amember_lang'] = $_GET['lang']; $lang = $_GET['lang']; // user is logged-in and changed language global $db; if ($db && ($_SESSION['_amember_user']) && ($_SESSION['_amember_user']['data']['selected_lang'] != $lang)){ #print "Changing language to [$lang]
\n"; $u = $db->get_user($_SESSION['_amember_user']['member_id']); $u['data']['selected_lang'] = $lang; $db->update_user($u['member_id'], $u); $_SESSION['_amember_user']['data']['selected_lang'] = $lang; } } elseif ($_SESSION['amember_lang'] != ''){ $lang = $_SESSION['amember_lang']; } elseif ($_SESSION['_amember_user']['data']['selected_lang'] != ''){ $lang = $_SESSION['_amember_user']['data']['selected_lang']; } else { $lang = get_default_lang(); } return $_LANG_SELECTED = $lang; } function load_language_defs(){ global $config; $d = opendir($dir="$config[root_dir]/language"); if (!$d) { trigger_error("Cannot open $config[root_dir]/languages/ folder to read language definitions", E_USER_WARNING); return false; } $ret = array(); while ($f = readdir($d)){ if (preg_match('/^(.+?)\-def.php$/i', $f, $regs)){ include_once($dir."/".$f); } } closedir($d); } function load_language($folder){ global $config; static $loaded; if (isset($loaded[$folder])) return; // don't run twice $lang = guess_language(); $lang = preg_replace('/[^a-zA-Z0-9_-]/', '', $lang); if (!file_exists($config['root_dir'] . $folder."/$lang.php")){ trigger_error("Could not load language file [$folder] for language [$lang], using [en] instead", E_USER_WARNING); $lang = "en"; } // now check enlighs language file as last chance if (!file_exists($config['root_dir'] . $folder."/$lang.php")){ trigger_error("Could not load default (English) language file [$folder] for language [$lang]", E_USER_WARNING); return; } //// if (file_exists($config['root_dir'] . $folder."/$lang-custom.php")){ include_once($config['root_dir'] . $folder . "/$lang-custom.php"); } require_once($config['root_dir'] . $folder . "/$lang.php"); if ($lang != 'en') { $e = error_reporting(0); @require_once($config['root_dir'] . $folder . "/en.php"); error_reporting($e); } if (!headers_sent() || ($GLOBALS['_LANG'][$lang]['encoding'] != '')){ header("Content-type: text/html; charset=".$GLOBALS['_LANG'][$lang]['encoding']); } if ($GLOBALS['_LANG'][$lang]['locale'] != ''){ setlocale(LC_TIME, $GLOBALS['_LANG'][$lang]['locale']); } $loaded[$folder] = 1; } srand((double) microtime() * 1000000); /** * Returns array of period presentation or null if error * array(int, 'd'|'m'|'y') if ok * array(string-date, 'fixed') if yyyy-mm-dd date passed * array(string,'error') if error * 'w' unit is depricated and automatically replaced to days **/ function parse_period($days){ $days = trim(strtolower($days)); if (preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $days)) return array($days, 'fixed'); if (preg_match('/^(\d+)(d|w|m|y)$/', $days, $regs)) { $count = $regs[1]; $period = $regs[2]; if ($period == 'w'){ return array($count*7, 'd'); } return array($count, $period); } elseif (preg_match('/^\d+$/', $days)) return array($days, 'd'); else return array(null, 'error'); } function display_lang_choice(){ global $config, $in_fatal_error; if ($in_fatal_error) return ""; if (function_exists('admin_auth') && function_exists('admin_login_form')) return ""; $in_fatal_error++; $url = htmlspecialchars($_SERVER['PHP_SELF']); $ret = "
"; $ret .= _COMMON_LANGUAGE . ": \n"; foreach ($_GET as $k=>$v){ if ($k == 'lang' || is_array($k) || is_array($v)) continue; $ret .= "\n"; } $ret .= "
\n"; return $ret; } function set_session_cookie_domain(){ if (ini_get('session.cookie_domain') != '') return; // already configured $domain = $_SERVER['HTTP_HOST']; if ($domain == 'localhost') return $domain; $tlds = preg_split('/\s+/', ".com .net .org .co.uk .org.uk .ltd.uk .plc.uk .edu .mil .br.com .cn.com .eu.com .hu.com .no.com .qc.com .sa.com .se.com .se.net .us.com .uy.com .za.com .ac .co.ac .gv.ac .or.ac .ac.ac .af .am .as .at .ac.at .co.at .gv.at .or.at .asn.au .com.au .edu.au .org.au .net.au .be .ac.be .biz .br .adm.br .adv.br .am.br .arq.br .art.br .bio.br .cng.br .cnt.br .com.br .ecn.br .eng.br .esp.br .etc.br .eti.br .fm.br .fot.br .fst.br .g12.br .gov.br .ind.br .inf.br .jor.br .lel.br .med.br .mil.br .net.br .nom.br .ntr.br .odo.br .org.br .ppg.br .pro.br .psc.br .psi.br .rec.br .slg.br .tmp.br .tur.br .tv.br .vet.br .zlg.br .ca .ab.ca .bc.ca .mb.ca .nb.ca .nf.ca .ns.ca .nt.ca .on.ca .pe.ca .qc.ca .sk.ca .yk.ca .cc .ac.cn .com.cn .edu.cn .gov.cn .net.cn .org.cn .bj.cn .sh.cn .tj.cn .cq.cn .he.cn .nm.cn .ln.cn .jl.cn .hl.cn .js.cn .zj.cn .ah.cn .hb.cn .hn.cn .gd.cn .gx.cn .hi.cn .sc.cn .gz.cn .yn.cn .xz.cn .sn.cn .gs.cn .qh.cn .nx.cn .xj.cn .tw.cn .hk.cn .mo.cn .cx .cz .de .dk .fo .com.ec .org.ec .net.ec .mil.ec .fin.ec .med.ec .gov.ec .fr .tm.fr .com.fr .asso.fr .presse.fr .gf .gs .co.il .org.il .net.il .ac.il .k12.il .gov.il .muni.il .ac.in .co.in .ernet.in .gov.in .net.in .res.in .info .is .it .ac.jp .co.jp .go.jp .or.jp .ne.jp .ac.kr .co.kr .go.kr .ne.kr .nm.kr .or.kr .re.kr .li .lt .lu .asso.mc .tm.mc .com.mm .org.mm .net.mm .edu.mm .gov.mm .ms .mx .com.mx .org.mx .net.mx .edu.mx .gov.mx .name .nl .no .nu .pl .com.pl .net.pl .org.pl .pt .com.ro .org.ro .store.ro .tm.ro .firm.ro .www.ro .arts.ro .rec.ro .info.ro .nom.ro .nt.ro .ru .com.ru .net.ru .org.ru .se .si .com.sg .org.sg .net.sg .gov.sg .sk .st .tc .tf .ac.th .co.th .go.th .mi.th .net.th .or.th .tj .tm .to .bbs.tr .com.tr .edu.tr .gov.tr .k12.tr .mil.tr .net.tr .org.tr .com.tw .org.tw .net.tw .ac.uk .uk.co .uk.com .uk.net .gb.com .gb.net .vg .ac.za .alt.za .co.za .edu.za .gov.za .mil.za .net.za .ngo.za .nom.za .org.za .school.za .tm.za .web.za .sh .kz .ch .info .ua .biz .ws .nz .com.nz .co.nz .org.nz .com.pk .int"); $min = ''; foreach ($tlds as $d){ $dd = preg_quote($d); if (preg_match("/([^\.]+?$dd)\$/",$domain, $regs)){ if (strlen($regs[1]) > strlen($min)){ $min = $regs[1]; } } } if (!strlen($min)) return; @ini_set('session.cookie_domain', ".$min"); } // workaround for Windows root_dir detection if (($config['root_dir'] == dirname(__FILE__)) && (substr(php_uname(), 0, 7) == "Windows") ){ $config['root_dir'] = preg_replace('|^[A-Za-z]:|', '', $config['root_dir']); $config['root_dir'] = str_replace("\\", '/', $config['root_dir']); } // checking URL accessibility function is_url_accessible ($url=''){ if (!preg_match("/^(http:\/\/|https:\/\/|www\.)([0-9a-z\.\-\_\/\@\?\&\:]+)$/i", $url)) return false; $fp = @fopen ($url, "r"); if (!$fp) return false; $url_arr = parse_url($url); $host = $url_arr['host']; $path = ($url_arr['path']) ? $url_arr['path'] : '/'; $path .= $url_arr['query'] ? '?'.$url_arr['query'] : ''; $fp = @fsockopen($host, 80, $errnum, $errstr, 30); if (!$fp) { $error = "$errstr ($errno)
\n"; return false; } else { $out = "GET $path HTTP/1.1\r\n"; $out .= "Host: $host\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); $buffer = ''; while (!feof($fp)) { $buffer .= fgets($fp, 128); } fclose($fp); if (!preg_match("/200 OK/i", $buffer)) return false; } $buffer = get_url ($url); if (preg_match("/404 Not Found/i", $buffer)) return false; return true; } function start_amember_session(){ if (($_SERVER['REMOTE_ADDR'] == '') && ($_SERVER['REQUEST_METHOD'] == '')) @session_start(); // run from command-line else session_start(); } /** * Function returns full config or given config variable value * $item can be empty - then functions returns full config * or it can be set to some value, lets say "use_address_info", * or "payment.paypal_r.email" * @param null|string $item * @return array|string|mixed */ function amConfig($item=null){ if (is_null($item)) return $GLOBALS['config']; $c = & $GLOBALS['config']; foreach (preg_split('/\./', $item) as $s) { $c = & $c[$s]; if (is_null($c)) return $c; } return $c; } /** * Function displays nice-looking error message without * using of fatal_error function and template * @param string Message to display * @param boolean Return string or display message? */ function amDie($string, $return=false){ $out= << Fatal Error

Script Error
$string
CUT; return $return ? $out : die($out); } function getLoginRegex(){ global $config; return $config['login_disallow_spaces'] ? '/^[0-9a-zA-Z_]+$/D' : '/^[0-9a-zA-Z_][0-9a-zA-Z_ ]+[0-9a-zA-Z_]$/D'; } amember/config-dist.inc.php0000644774276600352300000000365311573171452021701 0ustar nf.mortgageoriginatorseminarswww Please edit file amember/config.inc.php and replace line
\$config['root_dir'] = dirname(__FILE__);
to \$config['root_dir'] = '/home/user/public_html/amember';
Of course, /home/user/public_html/amember must be replaced to the
actual UNIX filesystem path (not URL!) to aMember folder.
"); } if (!defined('AMEMBER_ONLY_DB_CONFIG')){ require_once("$config[root_dir]/rconfig.inc.php"); } }amember/cron.php0000644774276600352300000000434311573171453017662 0ustar nf.mortgageoriginatorseminarswwwquery_one("SELECT GET_LOCK('cron_lock', 30)"); } function release_lock_cron(){ global $db; return $db->query("DO RELEASE_LOCK('cron_lock')"); } /// if running from command-line, try to open aMember cron via HTTP if (is_running_from_commandline() && is_running_without_suexec()){ $db->log_error("Cron is running from command line, running [$config[root_url]/cron.php?ok] via curl..."); $ret = get_url("$config[root_url]/cron.php?ok"); if ($ret == "OK") $db->log_error("Cron job finished successfully with the following output: [$ret]"); else $db->log_error("Cron job finished with the following error message: [$ret]"); exit(); } $vars = get_input_vars(); if (!$config['use_cron']) fatal_error(_CRON_ERROR); if (isset($_GET['ok'])) $db->log_error("cron.php started"); get_lock_cron(); check_cron(); release_lock_cron(); if (isset($_GET['ok'])) $db->log_error("cron.php finished"); if (isset($_GET['ok'])) print "OK"; amember/db.inc.php0000644774276600352300000000231011573171453020046 0ustar nf.mortgageoriginatorseminarswwwconfig = $config; } function escape_array(&$arr){ if (!is_array($arr)) return array(); $v = array(); foreach ($arr as $k=>$vv) $v[$k] = $this->escape($vv); return $v; } function encode_data(& $data){ return serialize((array)$data); } function decode_data(& $data){ return (array)unserialize($data); } } ?> amember/go.php0000644774276600352300000000311211573171454017320 0ustar nf.mortgageoriginatorseminarswwwusers_find_by_string($login, 'login', 1); if (!count($ul)) return 0; return $ul[0]['member_id']; } if ($aff_id = $vars['r']){ if ($aff_id<=0) $aff_id = find_id_by_login($aff_id); if ($aff_id > 0){ aff_set_cookie($vars['r']); $db->log_aff_click($aff_id, $link); } } $link = preg_replace('/\s+/', ' ', $link); header("Location: $link"); ?> amember/index.php0000644774276600352300000000421611573171454020030 0ustar nf.mortgageoriginatorseminarswwwgo back and create config file as described."; exit(); } include($rd.'/config.inc.php'); if (count($config) < 10) { print "File amember/config.inc.php is exist, but something went wrong. Database configuration was empty or cannot be read. Please remove amember/config.inc.php and repeat installation."; exit(); } //all ok - redirect $url = "$config[root_url]/setup.php?step=5"; @header("Location: $url"); html_redirect($url, 0, 'Installation successfull', 'Installation finished successfully'); exit(); } #### regular config check if (!file_exists($rd.'/config.inc.php')){ print "aMember is not configured yet. Go to configuration page"; exit(); } include($rd.'/config.inc.php'); ############################################################################### ## ## M A I N ## ############################################################################### $t = & new_smarty(); $error = ''; $vars = & get_input_vars(); $t->display("index.html"); ?>amember/lite.inc.php0000644774276600352300000001000411573171454020416 0ustar nf.mortgageoriginatorseminarswwwin query:
$sql
"); } return $q; } function amember_get_user($login){ global $_amember_config; $prefix = $_amember_config['db']['mysql']['prefix']; $conn = amember_lite_connect(); $login = mysql_escape_string($login); $q = amember_query("SELECT * FROM {$prefix}members WHERE login='$login'", $conn); $m = mysql_fetch_assoc($q); $m['data'] = unserialize($m['data']); if (!$m['member_id']) $m = array(); return $m; } function amember_check_user($login, $pass, &$real_pass){ // password can be : plain, md5 or crypt $m = amember_get_user($login); if (!$m) return 0; if (($m['pass'] == $pass) || (md5($m['pass']) == $pass) || (crypt($m['pass'], $pass) == $pass) ) { $real_pass = $m['pass']; return 1; } else return 0; } function amember_get_subscriptions($login, $completed=0){ // returns list of member subscriptions // completed: 0 - any, -1 - not paid, 1 - paid $m = amember_get_user($login); if (!$m) return array(); global $_amember_config; $prefix = $_amember_config['db']['mysql']['prefix']; $conn = amember_lite_connect(); $where_add = ""; if ($completed > 0) $where_add = " AND completed > 0 "; elseif ($completed < 0) $where_add = " AND completed = 0 "; $q = amember_query("SELECT p.*, pr.title as product_title FROM {$prefix}payments p LEFT JOIN {$prefix}products pr USING (product_id) WHERE member_id = $m[member_id] $where_add ORDER BY tm_added", $conn); $res = array(); while ($a = mysql_fetch_assoc($q)){ $a['data'] = unserialize($a['data']); $res[] = $a; } return $res; } function amember_get_products($login){ // returns list of member active products $m = amember_get_user($login); if (!$m) return array(); global $_amember_config; $prefix = $_amember_config['db']['mysql']['prefix']; $conn = amember_lite_connect(); $q = amember_query("SELECT DISTINCT product_id FROM {$prefix}payments WHERE member_id = $m[member_id] AND begin_date <= NOW() AND expire_date >= NOW() AND completed > 0 ORDER BY tm_added", $conn); $res = array(); while (list($a) = mysql_fetch_row($q)) $res[] = $a; if (!$res) return array(); /////////////////////////////// $ids = join(',', $res); $res = array(); $q = amember_query("SELECT * FROM {$prefix}products WHERE product_id IN ($ids)", $conn); while ($a = mysql_fetch_assoc($q)){ foreach (unserialize($a['data']) as $k=>$v) $a[$k] = $v; $res[$a['product_id']] = $a; } return $res; } function amember_login_user($login, $pass){ if (amember_check_user($login, $pass, $real_pass)){ session_start(); global $_amember_login, $_amember_pass; if (ini_get('register_globals')){ session_register('_amember_login'); session_register('_amember_pass'); } $_amember_login = $_SESSION['_amember_login'] = $login; $_amember_pass = $_SESSION['_amember_pass'] = $real_pass; return 1; } else return 0; } ?>amember/log_access.inc.php0000644774276600352300000000264111573171454021573 0ustar nf.mortgageoriginatorseminarswwwusers_find_by_string($login, 'login', 1); if (!count($ul)) { $db->log_error("Unknown user was logged in: '$login'. Look like protection isn't setup correctly"); exit(); } $member_id = $ul[0]['member_id']; } // log access $db->log_access($member_id); if (!$_SESSION['ip_checked']){ //skip if already checked if ($db->check_multiple_ip($member_id, $config['max_ip_count'], $config['max_ip_period'], $_SERVER['REMOTE_ADDR'])){ //limit exceeded member_lock_by_ip($member_id); } $_SESSION['ip_checked'] = 1; } session_write_close(); ?> amember/login.php0000644774276600352300000000361411573171455020033 0ustar nf.mortgageoriginatorseminarswwwget_user_payments(intval($_SESSION['_amember_id']), 1); usort($payments, 'rcmp_begin_date'); $now = date('Y-m-d'); $urls = array(); foreach ($payments as $k=>$v){ if (($v['expire_date'] >= $now) && ($v['begin_date'] <= $now)) { $p = get_product($v['product_id']); $url = $p->config['url']; if (strlen($url)){ $urls[] = $url; } } } if ($_SESSION['amember_redirect_url']) { $redirect = $_SESSION['amember_redirect_url']; unset($_SESSION['amember_redirect_url']); } elseif (count(array_unique($urls)) == 1){ $redirect = add_password_to_url($urls[0]); } else { $redirect = $config['root_url'] . "/member.php"; } #print_r($urls); html_redirect("$redirect", 0, 'Redirect', _LOGIN_REDIRECT); ?> amember/logout.php0000644774276600352300000000127011573171455020230 0ustar nf.mortgageoriginatorseminarswww amember/member.inc.php0000644774276600352300000006755011573171456020754 0ustar nf.mortgageoriginatorseminarswww 'member_id', 'title' => 'Member #', 'type' => 'hidden' ), array( 'name' => 'login', 'title' => 'Login', 'type' => 'text' ), array( 'name' => 'pass', 'title' => 'Password', 'type' => 'text' ), array( 'name' => 'email', 'title' => 'EMail', 'type' => 'text' ), array( 'name' => 'name_f', 'title' => 'First Name', 'type' => 'text' ), array( 'name' => 'name_l', 'title' => 'Last Name', 'type' => 'text' ), array( 'name' => 'street', 'title' => 'Street', 'type' => 'text' ), array( 'name' => 'city', 'title' => 'City', 'type' => 'text' ), array( 'name' => 'state', 'title' => 'State', 'type' => 'text' ), array( 'name' => 'zip', 'title' => 'ZIP', 'type' => 'text' ), array( 'name' => 'country', 'title' => 'Country', 'type' => 'text' ), array( 'name' => 'is_male', 'title' => 'Gender (female:0/male:1)', 'type' => 'radio' ), array( 'name' => 'aff_id', 'title' => 'Affiliate #', 'type' => 'readonly' ) ); global $member_additional_fields; $member_additional_fields = array( ); function add_member_field($name, $title, $type, $description='', $validate_func='', $additional_fields=NULL){ settype($additional_fields, 'array'); global $member_additional_fields; foreach ($member_additional_fields as $k=>$v){ if ($v['name'] == $name) { if ($v['validate_func'] && ($v['validate_func'] != $validate_func)){ $member_additional_fields[$k]['validate_func'] = (array)$v['validate_func']; $member_additional_fields[$k]['validate_func'][] = $validate_func; } return; } } $member_additional_fields[] = array_merge( $additional_fields, array( 'name' => $name, 'title' => $title, 'type' => $type, 'description' => $description, 'validate_func' => $validate_func ) ); } function mail_expire_members(){ // send mail to members having // expiration_date = today() + $config['expire_mail_days'] global $config, $db; $t = & new_smarty(); $pl = array(); $et = & new aMemberEmailTemplate(); $et->name = "mail_expire"; $global_days = $et->find_days(); foreach ($db->get_products_list() as $k=>$pr){ if (($pr['dont_mail_expire'] != 2) && !$config['mail_expire']) continue; if ($pr['dont_mail_expire'] == 1) continue; $et = & new aMemberEmailTemplate(); $et->name = "mail_expire"; $et->product_id = $pr['product_id']; $days = $et->find_days(); if (($pr['dont_mail_expire'] == 2) && !$config['mail_expire'] && !$days) continue; $pr['mail_expire_days'] = $days ? $days : $global_days; $pr['mail_expire_days_global'] = $days ? false : true; if (!$pr['mail_expire_days']) continue; $pl[$k] = $pr; } // iterate on products $msent = array(); foreach ($pl as $pr){ //iterate on expiration days foreach ($pr['mail_expire_days'] as $days){ $dat = date('Y-m-d', time() + 3600 * 24 * $days); $plist = $db->get_expired_payments($dat, $dat, null, ($pr['dont_mail_expire'] ? true : false) , $pr['product_id']); //print_rr($plist, "$dat,$pr[product_id]"); foreach ($plist as $p){ // go through expired payments and send mail if ($msent[$p['member_id'] ]) continue; //dont send second mail ! $paysys = get_paysystem($p['paysys_id']); if ($paysys['recurring'] && $pr['is_recurring']) continue; // don't send if auto-recurring $u = $db->get_user($p['member_id']); $product = get_product($p['product_id']); /////////////////////////////////// $t->assign('login', $u['login']); $t->assign('pass', $u['pass']); $t->assign('name_f', $u['name_f']); $t->assign('name_l', $u['name_l']); /////////////////////////////////// $t->assign('user', $u); $t->assign('payment',$p); $t->assign('product',$product->config); /////////////////////////////////// $et = & new aMemberEmailTemplate(); $et->name = "mail_expire"; $et->day = $days; if (!$pr['mail_expire_days_global']) $et->product_id = $pr['product_id']; //print_rr($et, $u['email']); mail_template_user($t, $et, $u, false); $msent[$p['member_id'] ]++; } } } } function mail_not_completed_members(){ // send mail to all members having no active subscriptions // and pending payment completed before 'max_not_completed_days' days global $config, $db; $pl = array(); $et = & new aMemberEmailTemplate(); $et->name = "mail_not_completed"; $global_days = $et->find_days(); foreach ($db->get_products_list() as $k=>$pr){ if (!$config['mail_not_completed']) continue; $et = & new aMemberEmailTemplate(); $et->name = "mail_not_completed"; $et->product_id = $pr['product_id']; $days = $et->find_days(); if (!$config['mail_not_completed'] && !$days) continue; $pr['mail_not_completed_days'] = $days ? $days : $global_days; $pr['mail_not_completed_days_global'] = $days ? false : true; if (!$pr['mail_not_completed_days']) continue; $pl[$k] = $pr; } $t = & new_smarty(); $msent = array(); foreach ($pl as $pr){ //iterate on not_completed days foreach ($pr['mail_not_completed_days'] as $days){ $dat = date('Y-m-d', time() - 3600 * 24 * $days); $plist = $db->get_payments($dat, $dat, -1,0,-1,'',$pr['product_id']); foreach ($plist as $p){ // go through expired payments and send mail if ($msent[$p['member_id'] ]) continue; //dont send second mail ! // check for customers with the same email and last name $u = $db->get_user($p['member_id']); if ($u['unsubscribed']) continue; $email = $db->escape($u['email']); $name_l = $db->escape($u['name_l']); $name_f = $db->escape($u['name_f']); $q = $db->query($s = "SELECT SUM(p.completed) FROM {$db->config[prefix]}members m LEFT JOIN {$db->config[prefix]}payments p USING (member_id) WHERE (m.name_l = '$name_l' AND m.name_f = '$name_f') OR m.email = '$email' OR m.member_id = {$p[member_id]} "); list($c_count) = mysql_fetch_row($q); if ($c_count) continue; $product = get_product($p['product_id']); /////////////////////////////////// $t->assign('login', $u['login']); $t->assign('pass', $u['pass']); $t->assign('name_f', $u['name_f']); $t->assign('name_l', $u['name_l']); /////////////////////////////////// $t->assign('user', $u); $t->assign('payment',$p); $t->assign('product',$product->config); /////////////////////////////////// $et = & new aMemberEmailTemplate(); $et->name = "mail_not_completed"; $et->day = $days; if (!$pr['mail_not_completed_days_global']) $et->product_id = $pr['product_id']; mail_template_user($t, $et, $u, true); $msent[$p['member_id'] ]++; } } } } function check_expire_members(){ // check that internal hooks for subscription_delete // was called for expired members (for the last week) global $config, $db, $t; $dat1 = date('Y-m-d', time() - 3600 * 24 * 7); $dat2 = date('Y-m-d'); $plist = $db->get_expired_payments($dat1, $dat2); $msent = array(); foreach ($plist as $p){ // go through expired payments and send mail if ($msent[$p['member_id'] ]) continue; //dont send second mail ! $db->check_subscriptions($p['member_id']); $msent[$p['member_id'] ]++; } } ////////////////// ACCESS CHECKER CODE ///////////////////////////////// add_member_field( 'is_locked', 'Locked', 'select', 'auto-locking by IP', '', array('options' => array( '' => 'No', 1 => 'Yes', -1 => "Disable auto-lock for this user" )) ); global $config; if ($config['manually_approve']){ add_member_field( 'is_approved', 'Approved', 'select', 'is member manually approved?', '', array('options' => array( '' => 'No', 1 => 'Yes', )) ); } add_member_field( 'i_agree', 'Agreed With User Agreement', 'hidden', '', '', array('hidden_anywhere' => 1)); add_member_field( 'signup_email_sent', 'Signup Email Sent', 'hidden', '', '', array('hidden_anywhere' => 1)); add_member_field( 'approval_email_sent', 'Approval Email Sent', 'hidden', '', '', array('hidden_anywhere' => 1)); add_member_field( 'selected_lang', 'Selected Language', 'hidden', '', '', array('hidden_anywhere' => 1)); if($config['verify_email_profile']){ add_member_field( 'email_new', 'New Email address(not verified)', 'hidden', '', '', array('hidden_anywhere' => 1)); add_member_field( 'email_confirm_code', 'Email verification confirmation code', 'hidden', '', '', array('hidden_anywhere' => 1)); add_member_field( 'email_confirm_code_exp', 'Email verification confirmation code expiration time', 'hidden', '', '', array('hidden_anywhere' => 1)); } // running from cron function clear_access_log(){ global $db, $config; if (!$config['clear_access_log']) return; $dat = date('Y-m-d', time() - $config['clear_access_log_days'] * 3600 * 24); $db->clear_access_log($dat); } // running from cron function delete_old_newsletters(){ global $db, $config; $db->delete_old_newsletters(); } // function member_lock_by_ip($member_id){ global $db, $config; $m = $db->get_user($member_id); if ($m['data']['is_locked'] < 0) return; // auto-lock disabled if ($config['max_ip_actions'] != 1){ // email admin $t = & new_smarty(); $t->assign("user", $m); $et = & new aMemberEmailTemplate(); $et->name = "max_ip_actions"; mail_template_admin($t, $et); } if ($config['max_ip_actions'] != 2){ // disable customer $m['data']['is_locked'] = 1; $db->update_user($member_id, $m); } } function member_check_ip_ban(){ //return 1 if should be banned global $config; foreach (preg_split('/[\r\n]+/', $config['ban']['ip']) as $i) if (compare_with_pattern($i, $_SERVER['REMOTE_ADDR'])) return 1; } function member_check_email_ban($email){ //return 1 if should be banned global $config; foreach (preg_split('/[\r\n]+/', $config['ban']['email']) as $i) if (compare_with_pattern($i, $email)) return 1; } function member_check_login_ban($login){ //return 1 if should be banned global $config; foreach (preg_split('/[\r\n]+/', $config['ban']['login']) as $i) if (compare_with_pattern($i, $login)) return 1; } function member_check_ban($vars){ global $config, $db; $err = array(); if (member_check_ip_ban()) if ($config['ban']['ip_action'] == 'die'){ $db->log_error("Attempt to signup from denied IP: $_SERVER[REMOTE_ADDR]"); header("Status: 500 Internal Error"); header("Status: 500 Internal Error"); exit(); } else { $db->log_error("Attempt to signup from denied IP: $_SERVER[REMOTE_ADDR]"); $err[] = "Signup from this IP address denied"; } if ($vars['email'] && member_check_email_ban($vars['email'])) if ($config['ban']['email_action'] == 'die'){ $db->log_error("Attempt to signup from denied E-Mail: $vars[email]"); header("HTTP/1.0 500 Internal Error"); header("Status: 500 Internal Error"); exit(); } else { $db->log_error("Attempt to signup from denied E-Mail: $vars[email]"); $err[] = "Signup from this E-Mail address is not allowed"; } if ($vars['login'] && member_check_login_ban($vars['login'])) if ($config['ban']['login_action'] == 'die'){ header("HTTP/1.0 500 Internal Error"); header("Status: 500 Internal Error"); exit(); } else { $err[] = "Username is already taken. Please choose another username"; } return $err; } function member_send_autoresponders(){ global $db, $config, $t; $pl = $db->get_products_list(); // setup product responders foreach ($pl as $k => $p){ $et = & new aMemberEmailTemplate(); $et->name = "mail_autoresponder"; $et->product_id = $p['product_id']; $pl[$k]['autoresponder'] = $et->find_days(); } // set global responder if ($config['mail_autoresponder']){ $et = & new aMemberEmailTemplate(); $et->name = "mail_autoresponder"; $days = $et->find_days(); if ($days){ $pl[] = array( 'product_id' => -1, 'autoresponder' => $days, 'autoresponder_renew' => $config['autoresponder_renew'], ); } } foreach ($pl as $pr){ $t = &new_smarty(); if (!$pr['autoresponder']) continue; // if (!preg_match_all('/^\s*(\d+)\s*\-\s*(.+?)\s*$/m', $pr['autoresponder'], $regs)) //continue; if ($pr['product_id'] > 0) $product_where = "AND p.product_id=$pr[product_id]"; else $product_where = ""; foreach ($pr['autoresponder'] as $days){ $dat = date('Y-m-d', time()-$days*3600*24); $today = date('Y-m-d'); if ($pr['autoresponder_renew']) $q = $db->query($s = "SELECT m.* FROM {$db->config['prefix']}payments p LEFT JOIN {$db->config['prefix']}members m USING (member_id) WHERE p.begin_date='$dat' AND p.completed>0 $product_where GROUP BY m.member_id "); else $q = $db->query($s = "SELECT m.* FROM {$db->config['prefix']}members m LEFT JOIN {$db->config['prefix']}payments p USING (member_id) WHERE p.completed > 0 AND p.begin_date <= '$today' $product_where GROUP BY m.member_id HAVING SUM(to_days(if(p.expire_date>'$today', '$today', p.expire_date)) - to_days(p.begin_date)) = $days AND MAX(p.expire_date) >= '$today' "); $et = & new aMemberEmailTemplate(); $et->name = "mail_autoresponder"; $et->product_id = ($pr['product_id'] > 0) ? $pr['product_id'] : null; $et->day = $days; while ($u = mysql_fetch_assoc($q)){ $u['data'] = $db->decode_data($u['data']); $t->assign('user', $u); $t->assign('product', $pr); $t->assign('login', $u['login']); $t->assign('pass', $u['pass']); $t->assign('name_f', $u['name_f']); $t->assign('name_l', $u['name_l']); if ($u['unsubscribed']) continue; mail_template_user($t, $et, $u, true); } } } } function keep_only_zeroes($i){ return $i == '0'; } function member_send_zero_autoresponder($payment_id, $member_id=0){ global $db, $config; $p = $db->get_payment($payment_id); $member_id = $p['member_id']; $pr = $db->get_product($p['product_id']); $t = new_smarty(); $et = & new aMemberEmailTemplate(); $et->name = "mail_autoresponder"; $et->product_id = $pr['product_id']; $pl[0] = $pr; $pl[0]['autoresponder'] = array_filter($et->find_days(), 'keep_only_zeroes'); // set global responder if ($config['mail_autoresponder']){ $et = & new aMemberEmailTemplate(); $et->name = "mail_autoresponder"; $days = $et->find_days(); if ($days){ $pl[] = array( 'product_id' => -1, 'autoresponder' => array_filter($days, 'keep_only_zeroes'), 'autoresponder_renew' => $config['autoresponder_renew'], ); } } foreach ($pl as $pr){ $t = &new_smarty(); if (!$pr['autoresponder']) continue; // if (!preg_match_all('/^\s*(\d+)\s*\-\s*(.+?)\s*$/m', $pr['autoresponder'], $regs)) //continue; if ($pr['product_id'] > 0) $product_where = "AND p.product_id=$pr[product_id]"; else $product_where = ""; foreach ($pr['autoresponder'] as $days){ $dat = date('Y-m-d', time()-$days*3600*24); $today = date('Y-m-d'); if ($pr['autoresponder_renew']) $q = $db->query($s = "SELECT m.* FROM {$db->config['prefix']}payments p LEFT JOIN {$db->config['prefix']}members m USING (member_id) WHERE m.member_id = '$member_id' and p.begin_date='$dat' AND p.completed>0 $product_where GROUP BY m.member_id "); else $q = $db->query($s = "SELECT m.* FROM {$db->config['prefix']}members m LEFT JOIN {$db->config['prefix']}payments p USING (member_id) WHERE m.member_id = '$member_id' and p.completed > 0 AND p.begin_date <= '$today' $product_where GROUP BY m.member_id HAVING SUM(to_days(if(p.expire_date>'$today', '$today', p.expire_date)) - to_days(p.begin_date)) = $days AND MAX(p.expire_date) >= '$today' "); $et = & new aMemberEmailTemplate(); $et->name = "mail_autoresponder"; $et->product_id = ($pr['product_id'] > 0) ? $pr['product_id'] : null; $et->day = $days; while ($u = mysql_fetch_assoc($q)){ $u['data'] = $db->decode_data($u['data']); $t->assign('user', $u); $t->assign('product', $pr); $t->assign('login', $u['login']); $t->assign('pass', $u['pass']); $t->assign('name_f', $u['name_f']); $t->assign('name_l', $u['name_l']); if ($u['unsubscribed']) continue; mail_template_user($t, $et, $u, true); } } } } function is_field_can_be_changed($field_name, $is_signup) { $fields_to_change = (array)$GLOBALS['config']['profile_fields']; return ($is_signup || in_array($field_name, $fields_to_change)); } function vsf_address($vars, $is_signup = true){ $err = array(); if (is_field_can_be_changed('street', $is_signup) && $vars['street'] == '') $err[] = _SIGNUP_ENTER_STREET; if (is_field_can_be_changed('city', $is_signup) && $vars['city'] == '') $err[] = _SIGNUP_ENTER_CITY; if (is_field_can_be_changed('state', $is_signup) && ($vars['country'] == 'US' || $vars['country'] == 'CA') && ($vars['state'] == '')) $err[] = _SIGNUP_ENTER_STATE; if (is_field_can_be_changed('zip', $is_signup) && $vars['zip'] == '') $err[] = _SIGNUP_ENTER_ZIP; if (is_field_can_be_changed('country', $is_signup) && $vars['country'] == '') $err[] = _SIGNUP_ENTER_COUNTRY; return $err; } function get_additional_field_html($f, $val){ global $t, $config; $t->assign('f', $f); $t->assign('value', ""); $t->assign('value', $val); return $t->fetch('add_field.inc.html'); } function get_additional_field_html_readonly($f, $val){ global $t, $config; $t->assign('f', $f); if ($f['type'] == 'select'){ $val = @$f['options'][$val]; } elseif ($f['type'] == 'radio'){ $val = $f['options'][$val]; } elseif ($f['type'] == 'multi_select'){ $s = array(); foreach ((array)$val as $v) $s[] = $f['options'][$v]; $val = join(',', $s); } elseif ($f['type'] == 'checkbox'){ $s = array(); foreach ((array)$val as $v) $s[] = $f['options'][$v]; $val = join(',', $s); } $t->assign('value', $val); return $t->fetch('add_field_ro.inc.html'); } /* * @param mixed (null||array) $price_group * @param array $f additional filed decription * @return boolean * */ function is_additional_fields_avalable($price_group, $f){ if (is_null($price_group) || !$f['price_group']) { return true; } else { return array_intersect($price_group, $f['price_group']); } } function get_additional_fields_html($vars, $scope, $display_all=0, $price_group=null){ global $db, $config, $member_additional_fields; $ret = ""; if (!isset($vars['data'])){ // hack for signup form $tmp['data'] = $vars; $vars = $tmp; //$vars['data'] = $vars; // avoid *RECURSION* message in PHP 5 } foreach ($member_additional_fields as $f){ $val = $f['sql'] ? (isset($vars[$f['name']])?$vars[$f['name']]: $f['default']) : (isset($vars['data'][$f['name']])?$vars['data'][$f['name']]:$f['default']); //------ if (isset($f[require_value])) { $val=(array)$val; foreach ($f[require_value] as $rv) { $val[] = $rv['sql'] ? (isset($vars[$rv['name']])?$vars[$rv['name']]: $rv['default']) : (isset($vars['data'][$rv['name']])?$vars['data'][$rv['name']]:$rv['default']); } } //------ if ($f['type'] == 'hidden') continue; if (!is_additional_fields_avalable($price_group, $f)) continue; if (($f['display_'.$scope] == 1) || ($display_all == 1)){ $ret .= get_additional_field_html($f, $val); } elseif (($f['display_'.$scope] == -1) || ($display_all == -1)){ $ret .= get_additional_field_html_readonly($f, $val); } } return $ret; } function member_check_additional_fields(&$vars, $scope='signup', $price_group=null){ global $member_additional_fields; $error = array(); // Get price group from request for signup form if ($scope=='signup' && isset($vars['price_group'])) { $price_group = explode(',', $vars['price_group']); } foreach ($member_additional_fields as $f){ if (!is_additional_fields_avalable($price_group, $f)) continue; if (!$f['display_'.$scope]) continue; $v = $vars[$fn = $f['name']]; foreach ((array)$f['validate_func'] as $func){ if (!strlen($func)) continue; if ($err = $func($v, $f['title'], $f)){ $error[] = $err; } } } return $error; } function vf_integer($val, $field_title, $f){ if (!preg_match('/^\d+$/', $val)) return sprintf(_MEMBER_VF_INTEGER, $field_title); } function vf_number($val, $field_title, $f){ if (!is_numeric($val)) return sprintf(_MEMBER_VF_NUMERIC, $field_title); } function vf_require($val, $field_title, $f){ if (!strlen($val)) return sprintf(_MEMBER_VF_REQUIRE, $field_title); } function vf_email($val, $field_title, $f){ if (!check_email($val)) return sprintf(_MEMBER_VF_EMAIL, $field_title); } function vf_regex($val, $field_title, $f){ if (!preg_match($f['re'], $val)) return $f['re_msg']; } function move_guest_subscriptions ($member_id){ global $db, $config; settype($member_id, 'integer'); if ($member_id <= 0) return; $u = $db->get_user($member_id); if (count($u) < 1) return; if (!$u['unsubscribed']){ $g = $db->get_guest_by_email($u['email']); if (count($g) > 0 && $g['guest_id'] > 0){ $guest_id = $g['guest_id']; $threads = $db->get_guest_threads($guest_id); $threads = array_keys($threads); if (count($threads) > 0){ $db->add_member_threads($member_id, $threads); } } } } function remove_newsletter_guest ($payment_id) { global $db; $payment = $db->get_payment($payment_id); // $payment is now array if (count($payment) < 1) return; $member = $db->get_user($payment['member_id']); if (count($member) < 1) return; move_guest_subscriptions ($payment['member_id']); $g = $db->get_guest_by_email($member['email']); if (count($g) > 0 && $g['guest_id'] > 0) { $guest_id = $g['guest_id']; $threads = $db->get_guest_threads($guest_id); $threads = array_keys($threads); if (count($threads) > 0) { $db->delete_guest_threads($guest_id); } $db->delete_guest($guest_id); } } /** * Function returns effective tax value for customer * or if member_id is null, it checks only for global tax * enabled and returns value * You have to check if $product['use_tax'] is enabled before you add tax! * @param int Member ID * @return float Returns tax value as number in percents, like 17.5, or 20 */ function get_member_tax($member_id=null){ global $config, $db; if (!$config['use_tax']) return; if ($config['tax_type'] == 1){ // global tax return floatval($config['tax_value']); } elseif ($config['tax_type'] == 2) { //regional tax if (!$member_id) return ; $member = $db->get_user($member_id); if (!$member) return ; foreach ((array)$config['regional_taxes'] as $t){ if($t['zip']&&($t['country'] == $member['country'])){ // First get all values; $zips = split(";", $t['zip']); foreach($zips as $v){ $v = trim($v); if(preg_match("/(\d+)\-(\d+)/", $v, $regs) && ($member['zip'] >= $regs[1] && $member['zip']<=$regs[2])){ return floatval( $t['tax_value'] ); } if($member['zip'] == $v) return floatval( $t['tax_value'] ); } } if ($t['state'] && ($t['state'] == $member['state']) && ($t['country'] == $member['country'])) return floatval( $t['tax_value'] ); if (!$t['state'] && $t['country'] && ($t['country'] == $member['country'])) return floatval( $t['tax_value'] ); } } }amember/member.php0000644774276600352300000003640211573171456020174 0ustar nf.mortgageoriginatorseminarswww","
","
","", ""), 1,1); } /// redirect to make F5 key (Refresh) working if (strlen($_POST['amember_pass']) && ($_SERVER["REQUEST_METHOD"] == 'POST')){ $url = $_SERVER['REQUEST_URI']; srand(time()); $r = (!preg_match('/\?/', $url))? '?r=' : '&r='; $url .= $r. rand(10000,99999); html_redirect($url, 0, 'Redirect', _MEMBER_REDIRECTING); exit(); } //////////////////////////////////////////////////////////////////////// function rcmp_begin_date($a, $b){ return strcmp($b['begin_date'], $a['begin_date']); } function check_product_scope($product_id, $member_id){ // return '' if allowed // return error message if denied global $db; $product = $db->get_product($product_id); if (!$product['scope']) return; if ($product['scope'] == 'member'){ //check that customer paid if (count($db->get_user_payments($member_id,1))) return; else return _MEMBER_ONLY4_PAID; } if ($product['scope'] == 'signup'){ //check that customer paid if (!count($db->get_user_payments($member_id,1))) return; else return _MEMBER_ONLY4_NEW; } return _MEMBER_NOT4_ORDER; } function do_renew(){ global $_SESSION; global $_amember_id; global $config, $db, $t, $vars, $plugins, $error; $member_id = intval($_amember_id); $error = array_merge((array)$error, (array)plugin_validate_member_form($vars)); if (count($error)){ $t->assign('error', $error); return; } $vars['product_id'] = is_array($vars['product_id']) ? array_filter(array_map('intval',$vars['product_id'])) : intval($vars['product_id']); if (!$vars['product_id']) { $t->assign('error', _MEMBER_SELECT_PRODUCT); return; } if (($vars['coupon']!='') && $config['use_coupons']){ $coupon = $db->coupon_get($vars['coupon'],$_SESSION[_amember_id]); if (is_string($coupon)){ $t->assign('error', $coupon) ; return; } } $pc = & new PriceCalculator(); $pc->addProducts($vars['product_id']); if ($config['use_coupons'] && $vars['coupon'] != ''){ $coupon = $db->coupon_get($vars['coupon'],$_SESSION[_amember_id]); if ($coupon['coupon_id']) $pc->setCouponDiscount($coupon['discount'], split(',',trim($coupon['product_id']))); } $pc->setPriceFieldsByPaysys($vars['paysys_id']); $pc->setTax(get_member_tax($member_id)); $terms = & $pc->calculate(); $price = $terms->total; if (($price == 0) && !product_get_trial($vars['product_id']) && (($terms->discount > 0 && !$coupon['is_recurring']) || !$terms->discount) && in_array('free', $plugins['payment'])) $vars['paysys_id'] = 'free'; if ($config['product_paysystem']){ $pr = get_product(is_array($vars['product_id'])?$vars['product_id'][0]:$vars['product_id']); $vars['paysys_id'] = $pr->config['paysys_id']; } if (!$vars['paysys_id']) { $t->assign('error', _MEMBER_SELECT_PAYMENT); return; } //check for agreement $display_agreement = 0; foreach ((array)$vars['product_id'] as $pid){ $product = $db->get_product($pid); if ($product['need_agreement']) $display_agreement++; } $member = $db->get_user($member_id); if ($display_agreement && !$member['data']['i_agree'] && !$vars['i_agree']){ display_agreement(serialize($vars)); // defined in the product.inc.php exit(); } if ($vars['i_agree'] && !$member['data']['i_agree']){ $member['data']['i_agree']++; $db->update_user($member_id, $member); } /// do { // for easy exit using break; $paysys_id = $vars['paysys_id']; $product_id = $vars['product_id']; if (!is_array($product_id)) $product_id = array($product_id); foreach ((array)$vars['product_id'] as $pid){ $error = check_product_scope($pid, $_amember_id); if ($error) break; } if ($error = check_product_requirements($product_id, get_product_requirements_for_member($_amember_id))) break; // if ($terms->discount > 0) $vars['COUPON_CODE'] = $vars['coupon']; global $payment_additional_fields; $additional_values = array(); foreach ($payment_additional_fields as $f){ $fname = $f['name']; if (isset($vars[$fname])) $additional_values[$fname] = $vars[$fname]; } $additional_values['COUPON_DISCOUNT'] = $terms->discount; $additional_values['TAX_AMOUNT'] = $terms->tax; $taxes = $prices = array(); foreach ($terms->lines as $pid => $line){ $prices[$pid] = $line->total; if ($line->tax) $taxes[$pid] = $line->tax; } $additional_values['TAXES'] = $taxes; $product = & get_product($product_id[0]); $begin_date = $product->get_start($member_id); $expire_date = $product->get_expire($begin_date, null, $terms); //yyyy-mm-dd // add payment $payment_id = $db->add_waiting_payments($member_id, $product_id, $paysys_id, $price, $prices, $begin_date, $expire_date, $vars, $additional_values); $error = plugin_do_payment($paysys_id, $payment_id, $member_id, is_array($product_id) ? $product_id[0] : $product_id, $price, $begin_date, $expire_date, $vars); if ($error) { $db->delete_payment($payment_id); break; } exit(); } while (0); //if we here, error was occured $t->assign('error', $error); return ; } function check_renewal_allowed($product, $products_active){ global $config, $db; switch ($config['limit_renewals']){ case 0:// don't check return 1; case 1: // check if the same product return !in_array($product['product_id'], $products_active); case 2: // check if the same group foreach ($products_active as $i){ $pr = $db->get_product($i); if ($pr['renewal_group'] == $product['renewal_group']) return 0; } return 1; case 3: // check if any active return !$products_active; } return 0; } function update_subscriptions () { global $config, $_product_id, $t, $db, $vars; $_amember_id = $_SESSION['_amember_id']; $member_id = intval($_amember_id); $db->delete_member_threads($member_id); if (!$vars['unsubscribe']){ $q = $db->query($s = " UPDATE {$db->config['prefix']}members SET unsubscribed=0 WHERE member_id=$member_id "); $db->add_member_threads($member_id, $vars['threads']); } else { $q = $db->query($s = " UPDATE {$db->config['prefix']}members SET unsubscribed=1 WHERE member_id=$member_id "); } html_redirect("member.php", false, _TPL_NEWSLETTER_INFO_SAVED, _TPL_NEWSLETTER_INFO_UPDATED); exit; } ///////////////////////// MAIN ///////////////////////////////////////// unset($GLOBALS['_trial_days']); // trial handling $_amember_id = $_SESSION['_amember_id']; $vars = get_input_vars(); if ($vars['action'] == 'get_invoice' && $vars['id'] > 0){ $id = intval($vars['id']); if ($config['send_pdf_invoice']){ require_once("$config[root_dir]/includes/fpdf/fpdf.php"); $invoice = get_pdf_invoice($id, $_amember_id); header('Cache-Control: maxage=3600'); header('Pragma: public'); header("Cache-control: private"); header("Content-type: application/pdf"); header("Content-Length: ".strlen ($invoice['string'])); header("Content-Disposition: attachment; filename=amember-invoice-$id.pdf"); print $invoice['string']; exit; } } if ($vars['action'] == 'renew'){ do_renew(); } elseif ($vars['action'] == 'cancel_recurring'){ $p = $db->get_payment($vars['payment_id']); if ($p['member_id'] != $_amember_id) die(_MEMBER_ID_NOT_MATCH); $p['data']['CANCELLED']++; $db->update_payment($vars['payment_id'], $p); $t->assign('title', _MEMBER_SUBSCR_CANCELLED); $t->assign('msg', _MEMBER_RSUB_CANCELLED); $t->display("msg_close.html"); if ($config['send_cancel_admin']){ $u = $_SESSION['_amember_user']; mail_admin(sprintf(_MEMBER_MAIL_ADMIN,$u[login],$vars[payment_id]), _MEMBER_MAIL_THEME); } exit(); } elseif ($vars['do_agreement']) { if (!$vars['i_agree']){ global $error; $error[] = _MEMBER_ERROR; display_agreement($vars['data']); exit(); } $vars = unserialize($vars['data']); $vars['i_agree']++; do_renew(); } // common processing // get product list (to fill $_product_id also) $products = & $db->get_products_list(); $pp = array(); $_product_id = array(); foreach ($products as $p) { $pp[ $p['product_id'] ] = $p['title'] ; $_product_id[] = $p['product_id']; } $t->assign('products', $pp); $payments = & $db->get_user_payments(intval($_amember_id), 1); usort($payments, 'rcmp_begin_date'); $now = date('Y-m-d'); $member_active = $member_paid = 0; foreach ($payments as $k=>$v){ $payments[$k]['is_active'] = (($v['expire_date'] >= $now) && ($v['begin_date'] <= $now))? 1 : 0; if ($payments[$k]['is_active']) $member_active++; if ($v['completed']) $member_paid++; // try to display "Cancel" Link if ($payments[$k]['expire_date'] >= date('Y-m-d')){ $paysys = get_paysystem($v['paysys_id']); $product = $db->get_product($v['product_id']); if ($paysys['recurring'] && ($pay_plugin = &instantiate_plugin('payment', $v['paysys_id'])) && $product['is_recurring'] && method_exists($pay_plugin, 'get_cancel_link')){ $payments[$k]['cancel_url'] = $pay_plugin->get_cancel_link($v['payment_id']); } } } $t->assign('payments', $payments); /////////////////////////////////////////////////// $member_products = $_SESSION['_amember_products']; foreach ((array)$member_products as $k => $pr){ $member_products[$k]['url'] = add_password_to_url($pr['url']); foreach ((array)$pr['add_urls'] as $u=>$kk){ $uu=add_password_to_url($u, $member_login_pw); unset($member_products[$k]['add_urls'][$u]); $member_products[$k]['add_urls'][$uu] = $kk; } } $t->assign('member_products', $member_products); if ($member_paid) $member_scope_allowed = array('', 'member'); else // signup $member_scope_allowed = array('', 'signup'); $products_to_renew = $products; $products_active = array(); $dat = date('Y-m-d'); foreach ($db->get_user_payments(intval($_amember_id), 1) as $p) if (($p['begin_date'] <= $dat) && ($p['expire_date'] >= $dat)) $products_active[] = $p['product_id']; foreach ($products_to_renew as $k=>$v){ if (!in_array($v['scope'], $member_scope_allowed)) unset($products_to_renew[$k]); if(is_array($_GET['price_group'])){ if(!array_intersect($_GET['price_group'], split(',',$v['price_group']))) unset($products_to_renew[$k]); }elseif ($_GET['price_group']){ if (!in_array($_GET['price_group'], split(',',$v['price_group'])) ) unset($products_to_renew[$k]); } elseif ($v['price_group'] < 0){ unset($products_to_renew[$k]); } elseif (!check_renewal_allowed($v, $products_active)){ unset($products_to_renew[$k]); } if ($err = check_product_requirements(array($v['product_id']), get_product_requirements_for_member($_amember_id))){ unset($products_to_renew[$k]); } if ($products_to_renew[$k] && ($products_to_renew[$k]['terms'] == '')){ $pr = & new Product($products_to_renew[$k]); $products_to_renew[$k]['terms'] = $pr->getSubscriptionTerms(); } } $t->assign('products_to_renew', $products_to_renew); $paysystems = get_paysystems_list(); $pp = array(); foreach ($paysystems as $p) if ($p['public']) $pp[ $p['paysys_id'] ] = $p['title'] ; $t->assign('paysystems', $pp); $pp1 = $pp; //remove free paysystem from select if (count($pp1) > 1) foreach ($pp1 as $k=>$p) if ($k == 'free') unset($pp1[$k]); $t->assign('paysystems_select', $pp1); // newsletters form if ($vars['action'] == 'newsletters_update'){ update_subscriptions (); } $m = $db->get_user($_amember_id); $unsubscribed = $m['unsubscribed']; //$threads_count = $db->get_threads_list_c($_amember_id); //$threads_list = $db->get_threads_list(0, $db->get_threads_list_c(), $_amember_id); $threads_list = array(); $threads_list2 = $db->get_threads_list(0, $db->get_threads_list_c()); foreach ($threads_list2 as $k=>$v){ if ($db->is_subscription_possible($m['member_id'], $m['status'], $v['thread_id'])) $threads_list[] = $v; } $threads_count = count($threads_list); $threads = $db->get_member_threads($_amember_id); while (list($thread_id, ) = each ($threads)){ if (!$unsubscribed) $threads[$thread_id] = '1'; else $threads[$thread_id] = '0'; } $t->assign('threads_list', $threads_list); $t->assign('threads', $threads); $t->assign('unsubscribed', $unsubscribed); //newsletters archive if (isset($vars['start'])) $start = $vars['start']; //$db->delete_old_newsletters(); $all_count = $db->get_archive_list_c($vars['thread_id'], $_amember_id); $count = 5; $al = & $db->get_archive_list($start, $count, $vars['thread_id'], $_amember_id); $t->assign('al', $al); //Member Coupons $member_coupons = array(); if( $config[ 'use_coupons' ] ) { $xcc = $db->get_coupons( 'member', $_amember_id ); foreach( $xcc as $cc ) { // Coupon Get does all the checking so it is better this way.... $onecc = $db->coupon_get( $cc[ 'code' ], $_amember_id ); if( ! is_array( $onecc ) ) { continue; } if( ! strpos( $onecc[ 'discount' ], "%" ) ) { $onecc[ 'discount' ] = "$" . $onecc[ 'discount' ]; } $onecc[ 'product_id' ] = explode( ",", $onecc[ 'product_id' ] ); $member_coupons[] = $onecc; } } $t->assign( 'member_coupons', $member_coupons ); $member_links = plugin_get_member_links($_SESSION['_amember_user']); $t->assign('member_links', $member_links); $left_member_links = plugin_get_left_member_links($_SESSION['_amember_user']); $t->assign('left_member_links', $left_member_links); $t->assign('user', $_SESSION['_amember_user']); $t->display('member.html'); ?>amember/newsletter.php0000644774276600352300000002374611573171456021130 0ustar nf.mortgageoriginatorseminarswwwget_newsletter($vars['archive_id'], $member_id); $t->assign('a', $a); $t->display('newsletter_archive_more.html'); } else { //$db->delete_old_newsletters(); $all_count = $db->get_archive_list_c($vars['thread_id'], $member_id); $count = 20; $al = & $db->get_archive_list($start, $count, $vars['thread_id'], $member_id); $t->assign('al', $al); $t->display('newsletter_archive.html'); } } function show_guest_form($vars='') { global $config, $_product_id, $t, $db; settype($vars, 'array'); $threads_count = $db->get_threads_list_c(); $threads_list = $db->get_threads_list(0, $threads_count); if (count($vars['tr']) > 0) { $threads = array_flip($vars['tr']); while (list($thread_id, ) = each ($threads)) $threads[$thread_id] = '1'; } else { $threads = array(); } $guest_threads_list = array(); foreach ($threads_list as $thread_row) { if ($db->is_thread_available_to_guests ($thread_row['thread_id'])) $guest_threads_list[] = $thread_row; } if (!$guest_threads_list){ fatal_error(_NEWSLETTER_NO_GUEST_THREADS, false); exit; } $t->assign('vars', $vars); $t->assign('threads', $threads); $t->assign('threads_list', $guest_threads_list); $t->display ("newsletter_guests.html"); } function add_guest() { global $db, $config, $t; settype($vars, 'array'); $errors = array(); $vars = get_input_vars(); //check member if (!$vars['e'] && $vars['s']){ $member_code = split (":", $vars['s']); $member_code = intval($member_code[0]); $q = $db->query($s = " SELECT guest_email FROM {$db->config[prefix]}newsletter_guest WHERE guest_id='".$member_code."' "); $row = mysql_fetch_assoc($q); if ($row['guest_email']) $vars['e'] = $row['guest_email']; } $is_member = ($db->users_find_by_string($vars['e'], 'email', 1)) ? true : false;; if ($vars['e'] && $is_member){ $t->display('add_guest_failed_email.html'); exit; } else { $security_code = ''; $securitycode_expire = ''; if (!$config['dont_confirm_guests'] && $vars['s'] == '') { //generate a security code $acceptedChars = 'azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN0123456789'; $max = strlen($acceptedChars) - 1; $security_code = ""; for($i=0; $i < 16; $i++) $security_code .= $acceptedChars{mt_rand(0, $max)}; $security_code = $security_code . time(); $security_code = md5($security_code); $security_code = substr($security_code, 0, 16); $hours = 48; $securitycode_expire = date("Y-m-d H:i:s", time() + $hours * 60 * 60); } if (!$config['dont_confirm_guests'] && $vars['s'] != '') { //check security_code $security_code = $vars['s']; $member_code = split (":", $security_code); $security_code = $member_code[1]; $member_code = intval($member_code[0]); $unix_timestamp = time(); $q = $db->query($s = " SELECT guest_id, security_code, UNIX_TIMESTAMP(securitycode_expire) FROM {$db->config[prefix]}newsletter_guest WHERE guest_id='".$member_code."' "); list($guest_id, $guest_code, $guest_expire) = mysql_fetch_row($q); if (!$guest_id || ($guest_code != '' && $guest_code != $security_code) || ($guest_expire > 0 && $guest_expire - $unix_timestamp < 0)) { //if wrong security code $t->assign('guest_page', 'newsletter.php'); $t->display('add_guest_failed.html'); exit; } else { $q = $db->query(" UPDATE {$db->config[prefix]}newsletter_guest SET security_code='', securitycode_expire='' WHERE guest_id='".$guest_id."' "); } $q = $db->query(" SELECT COUNT(*) FROM {$db->config[prefix]}newsletter_guest_subscriptions WHERE guest_id='".$member_code."' AND security_code='".$db->escape($security_code)."' AND (UNIX_TIMESTAMP(securitycode_expire) - $unix_timestamp) > 0 "); $r = mysql_fetch_row($q); if ($r[0] > 0){ //delete old (confirmed) subscriptions $q = $db->query(" DELETE FROM {$db->config[prefix]}newsletter_guest_subscriptions WHERE guest_id='".$member_code."' AND (security_code='' OR security_code IS NULL) "); //activate new subscriptions $q = $db->query(" UPDATE {$db->config[prefix]}newsletter_guest_subscriptions SET security_code='', securitycode_expire='' WHERE guest_id='".$member_code."' AND security_code='".$db->escape($security_code)."' AND (UNIX_TIMESTAMP(securitycode_expire) - $unix_timestamp) > 0 "); } $t->display('add_guest_complete.html'); //html_redirect("newsletter.php", false, _TPL_NEWSLETTER_INFO_SAVED, _TPL_NEWSLETTER_INFO_UPDATED); exit; } //check guest $guest = $db->get_guest_by_email($vars['e']); if (count($guest) == 0 || !$guest['guest_id']) { //check required input vars if (count($vars['tr']) == 0){ $errors[] = _TPL_NEWSLETTER_REQUIRED_THREAD; } if (!strlen($vars['n'])){ $errors[] = _TPL_NEWSLETTER_REQUIRED_NAME; } if (!strlen($vars['e']) || !check_email($vars['e'])){ $errors[] = _TPL_NEWSLETTER_REQUIRED_EMAIL; } if ($errors){ $t->assign('error', $errors); show_guest_form($vars); return; } //add guest $q = $db->query($s = " INSERT INTO {$db->config['prefix']}newsletter_guest (guest_id,guest_name,guest_email,security_code,securitycode_expire) VALUES (null, '".$db->escape($vars['n'])."', '".$db->escape($vars['e'])."', '".$db->escape($security_code)."', '$securitycode_expire') "); $guest_id = mysql_insert_id($db->conn); } else { $guest_id = $guest['guest_id']; if($security_code) $db->query($s = " UPDATE {$db->config['prefix']}newsletter_guest set guest_name='".$db->escape($vars['n'])."',security_code='".$db->escape($security_code)."',securitycode_expire='$securitycode_expire' WHERE guest_id='$guest_id'"); } if (count($vars['tr']) > 0) { if ($config['dont_confirm_guests']) $db->delete_guest_threads($guest_id); $db->add_guest_threads($guest_id, $vars['tr'], $security_code, $securitycode_expire); } if (!$config['dont_confirm_guests'] && $vars['s'] == '') { //send a confirmation email $t->assign('name', htmlentities($vars['n'])); $t->assign('link',"$config[root_url]/newsletter.php?a=add_guest&s=".$guest_id.":".$security_code); $et = & new aMemberEmailTemplate(); $et->name = "verify_guest"; $t->assign('config', $config); $et->lang = guess_language(); // load and find templated if (!$et->find_applicable()){ trigger_error("Cannot find applicable e-mail template for [{$et->name},{$et->lang},{$et->product_id},{$et->day}]", E_USER_WARNING); exit; } global $_AMEMBER_TEMPLATE; $_AMEMBER_TEMPLATE['text'] = $et->get_smarty_template(); $parsed_mail = $t->fetch('memory:text'); unset($_AMEMBER_TEMPLATE['text']); mail_customer($vars['e'], $parsed_mail, null, null, null, false, $vars['n']); $t->display('add_guest_ok.html'); exit; } } $t->display('add_guest_complete.html'); //html_redirect("newsletter.php", false, _TPL_NEWSLETTER_INFO_SAVED, _TPL_NEWSLETTER_INFO_UPDATED); exit; } ///////////////////////// MAIN ///////////////////////////////////////// $vars = get_input_vars(); if (isset($vars['start'])) $start = $vars['start']; switch ($vars['a']) { case 'archive': show_archive(); break; case 'add_guest': add_guest(); break; default: show_guest_form(); break; } /////////////////////////////////////////////////// ?> amember/payment.inc.php0000644774276600352300000000337711573171456021157 0ustar nf.mortgageoriginatorseminarswww$v){ if ($v['name'] == $name) { if ($v['validate_func'] && ($v['validate_func'] != $validate_func)){ $payment_additional_fields[$k]['validate_func'] = (array)$v['validate_func']; $payment_additional_fields[$k]['validate_func'][] = $validate_func; } return; } } $payment_additional_fields[] = array_merge( $additional_fields, array( 'name' => $name, 'title' => $title, 'type' => $type, 'description' => $description, 'validate_func' => $validate_func ) ); } ?> amember/paysys.inc.php0000644774276600352300000004513111573171457021025 0ustar nf.mortgageoriginatorseminarswwwconfig = $config; } function do_payment($payment_id, $member_id, $product_id, $price, $begin_date, $expire_date, &$vars){ fatal_error("do_payment is not implemented"); } function validate_thanks(&$vars){ return ''; } function process_thanks(&$vars){ return ''; } } class amember_payment extends payment { var $public=1; //// var $title="Credit Card"; var $description="secure credit card payment"; var $fixed_price=0; var $recurring=0; var $built_in_trials=0; /// function amember_payment($config){ $this->payment($config); $this->init(); } function init(){ add_paysystem_to_list( array( 'paysys_id' => $this->get_plugin_name(), 'title' => ($this->config['title']=='') ? $this->title : $this->config['title'], 'description' => ($this->config['description']=='') ? $this->description : $this->config['description'], 'fixed_price' => $this->fixed_price, 'public' => $this->public, 'recurring' => $this->recurring, 'built_in_trials' => $this->built_in_trials, ) ); if ($this->recurring) { add_product_field( 'is_recurring', 'Recurring Billing', 'checkbox', 'should user be charged automatically
when subscription expires' ); } if ($this->built_in_trials){ add_product_field('trial1_days', 'Trial 1 Duration', 'period', 'trial period duration' ); add_product_field('trial1_price', 'Trial 1 Price', 'money', 'enter 0.0 to offer free trial' ); } } function get_plugin_name(){ if (preg_match('/^payment_(.+?)$/', get_class($this), $regs)) return $regs[1]; else die("Cannot determine payment plugin name: " . get_class($this)); } function do_payment($payment_id, $member_id, $product_id, $price, $begin_date, $expire_date, &$vars){ global $db, $config; $payment = $db->get_payment($payment_id); if ($payment['data'][0]['BASKET_PRODUCTS']) $product_ids = (array)$payment['data'][0]['BASKET_PRODUCTS']; else $product_ids = array($payment['product_id']); $products = array(); foreach ($product_ids as $product_id) $products[] = $db->get_product($product_id); $member = $db->get_user($member_id); $title = (count($products) == 1) ? $products[0]['title'] : $config['multi_title']; $invoice = $payment_id; return $this->do_bill($price, $title, $products, $member, $invoice); } function do_bill($amount, $title, $products, $member, $invoice){ die("do_bill is not implemented in this plugin: " . get_class($this)); } function add_config_items($notebook_page){ $plugin = $this->get_plugin_name(); add_config_field("payment.$plugin.title", "Payment system title", 'text', "to be displayed on signup.php and member.php pages", $notebook_page, '','','', array('default' => $this->title)); add_config_field("payment.$plugin.description", "Payment system description", 'text', "to be displayed on signup page", $notebook_page, '','','', array('default' => $this->description)); add_config_field("payment.$plugin.disable_postback_log", "PostBack messages Logging", 'select', "by default aMember will log payment system postback messages
you can disable this functionality by changing this configuration value.
It is recommended to keep this enabled at least for first 1-2 months.", $notebook_page, '','','', array('options' => array('' => 'Log Postback Messages (default)', 1 => 'Disable PostBack Logging'))); } function encode_and_redirect($url, $vars){ $vars1 = array(); foreach ($vars as $k=>$v) $vars1[] = urlencode($k) . '=' . urlencode($v); $x = join('&', $vars1); html_redirect("$url?$x", 0, _PLUG_PAY_CC_CORE_REDIR, _PLUG_PAY_CC_CORE_REDIR); } function get_dump($var){ $s = ""; foreach ($var as $k=>$v) $s .= "$k => $v
\n"; return $s; } function postback_error($err){ global $db; $plugin = $this->get_plugin_name(); fatal_error("$plugin ERROR: $err
\n".$this->get_dump($this->postback_vars)); } function postback_log($msg=''){ global $db; if ($this->config['disable_postback_log'] != '') return; $plugin = $this->get_plugin_name(); $db->log_error("$plugin DEBUG: $msg
\n".$this->get_dump($this->postback_vars)); } function handle_postback($vars){ $this->postback_vars = $vars; $this->postback_log(); $ret = $this->process_postback($vars); if ($ret) $this->postback_log("successfully handled"); return $ret; } } class amember_advanced_payment extends amember_payment{ function amember_advanced_payment($config){ $this->amember_payment($config); $this->init(); } function add_config_items($notebook_page) { $plugin = $this->get_plugin_name(); add_config_field('payment.'.$plugin.'.allow_create', 'Allow create new accounts', 'select', "aMember will create a member (if not exists) after purchase at ".$this->title." directly.
You should configure 'Paysystem Product ID' for each product
at aMember CP -> Manage Products -> Edit
KEEP IT DISABLED IF YOU DON'T UNDERSTAND WHAT IT MEANS", $notebook_page, '','','', array('options' => array(0 => 'No', 1 => 'Yes')) ); parent::add_config_items($notebook_page); } function create_new_payment(&$vars){ global $db; // Check if enabled; if(!$this->config['allow_create']) return; $member = array(); foreach(array('name_f', 'name_l', 'email', 'street', 'city', 'zip', 'country','state') as $v){ $member[$v] = $this->get_value_from_vars($v, $vars); } // Try to find existing user with the same email; $users = $db->users_find_by_string($member['email'], 'email', $exact=1); $u = $users['0']; if(!$u['member_id']){ $member['login'] = generate_login($member); $member['pass'] = generate_password($member); $member_id = $db->add_pending_user($member); $u = $db->get_user($member_id); } if(!($product_id = intval($this->get_value_from_vars('product_id', $vars)))) return; $product = get_product($product_id); $amount = $this->get_value_from_vars("amount", $vars); if($amount === false) $amount = $product->config['price']; $begin_date = date('Y-m-d'); $expire_date = $product->get_expire($begin_date, 'expire_days'); $payment_id = $db->add_waiting_payment($u['member_id'], $product_id, $this->get_plugin_name(), $amount, $begin_date, $expire_date, $vars); // Set receipt_id will be required by some payment plugins; $payment = $db->get_payment($payment_id); $payment['receipt_id'] = $this->get_value_from_vars('receipt_id', $vars); $db->update_payment($payment['payment_id'], $payment); return $payment_id; } function get_value_from_vars($var,&$vars){ return; } function find_product_by_field($field, $value){ global $db; foreach($db->get_products_list() as $p) if($value && $p[$field] == $value) return $p['product_id']; } } class amember_protect { function amember_protect($config){ $this->config = $config; } function init(){ } function get_plugin_name(){ if (preg_match('/^protect_(.+?)$/', get_class($this), $regs)) return $regs[1]; else die("Cannot determine protect plugin name: " . get_class($this)); } } class amember_integration_plugin extends amember_protect { var $db; var $hooks = array( 'subscription_added', 'subscription_updated', 'subscription_deleted', 'subscription_removed', 'subscription_check_uniq_login', 'subscription_rebuild', 'check_logged_in', 'after_login', 'after_logout', 'fill_in_signup_form' ); var $debug_sql = false; /** * This field contains pattern of tablename that * will be used to check database name and prefix * settings * For example if tablename is usually vb_user, * you should specify 'user' for this field * If you keep this empty, auto-detection will * be disabled for your plugin */ var $guess_table_pattern = null; /** * This field contains list of field names that must * be present in the table specified above. If any of * fields is not present, database/prefix will be * detected as not-acceptable for this plugin. */ var $guess_fields_pattern = array(); /////////////////////////////////// function subscription_added() { } function subscription_updated(){ } function subscription_deleted(){ } function subscription_removed(){ } function subscription_check_uniq_login($login, $email, $pass){ return 1; } function subscription_rebuild(){} function check_logged_in(){} function after_login(){} function after_logout(){} function fill_in_signup_form(&$vars){} //////////////////////////////////// function get_db(){ if (!$this->db) $this->init_database(); return $this->db; } function query($sql, $ignore_error=0){ if ($this->debug_sql) print "
SQL query:
$sql
"; $db = & $this->get_db(); $sql = str_replace("[db]", $this->config['db'], $sql); return $db->query($sql, $ignore_error); } function query_first($sql, $ignore_error=0){ $q = $this->query($sql, $ignore_error); return mysql_fetch_assoc($q); } function query_one($sql, $ignore_error=0){ $q = $this->query($sql, $ignore_error); $x = mysql_fetch_array($q); return $x[0]; } function escape_record($record){ $db = & $this->get_db(); settype($record, 'array'); if (isset($record['data'])) foreach ($record['data'] as $k=>$v) $d[$k] = is_array($v) ? $v : $db->escape($v); foreach ((array)$record as $k => $v) $record[$k] = $db->escape($v); if (isset($record['data'])) $record['data'] = $d; return $record; } function escape($s){ $db = & $this->get_db(); return $db->escape($s); } function set_cookie($k, $v){ if (function_exists('amember_setcookie')) return amember_setcookie($k, $v); else { $tm = 0; $d = $_SERVER['HTTP_HOST']; if (preg_match('/([^\.]+)\.(org|com|net|biz|info)/', $d, $regs)) setcookie($k,$v,$tm,"/",".{$regs[1]}.{$regs[2]}"); else setcookie($k,$v,$tm,"/"); } } function del_cookie($k){ if (function_exists('amember_delcookie')) return amember_delcookie($k); else { $tm = time()-24*3600; $d = $_SERVER['HTTP_HOST']; if (preg_match('/([^\.]+)\.(org|com|net|biz|info)/', $d, $regs)) setcookie($k,"",$tm,"/",".{$regs[1]}.{$regs[2]}"); else setcookie($k,"",$tm,"/"); } } function add_db_config_items($pn, $notebook_page){ add_config_field("protect.$pn.user", 'MySQL Database User', 'text', "usually you can leave this field empty.
If aMember's MySQL user is unable to connect to $pn database,
you can enter MySQL connection settings here.
This field is for MySQL username", $notebook_page, 'validate_plugin_database'); add_config_field("protect.$pn.pass", 'MySQL Database Password', 'text', "usually you can leave this field empty.
If aMember's MySQL user is unable to connect to $pn database,
you can enter MySQL connection settings here.
This field is for MySQL password", $notebook_page, ''); add_config_field("protect.$pn.host", 'MySQL Database Hostname', 'text', "usually you can leave this field empty.
If aMember's MySQL user is unable to connect to $pn database,
you can enter MySQL connection settings here.
This field is for MySQL hostname (often it is 'localhost')", $notebook_page, ''); } function init_database(){ if ($this->config['user'] != ''){ list($database, $dot, $prefix) = preg_split('|(\.)|', $this->config['db'], -1, PREG_SPLIT_DELIM_CAPTURE); if ($dot == '') $database = $GLOBALS['config']['db']['mysql']['db']; $c = array( 'host' => $this->config['host'], 'pass' => $this->config['pass'], 'user' => $this->config['user'], 'db' => $database ); $this->db = new db_mysql($c); } else { $this->db = $GLOBALS['db']; } } function guess_db_settings(){ if (!$this->guess_table_pattern || !$this->guess_fields_pattern) return array(); if ($this->config['user'] == '' || $this->config['host'] == '' || (isset($this->config['other_db']) && !$this->config['other_db'])) $config = amConfig('db.mysql'); else { $config = $this->config; /// lets get name of first available database just for DbSimple /// because it does not work without database name $c = @mysql_connect($config['host'], $config['user'], $config['pass']); if (!$c) return false; $q = mysql_query("SHOW DATABASES", $c); list($db) = mysql_fetch_row($q); if ($db == '') return false; $config['db'] = $db; } $c = connectMysql($config); if ($c->error) return false; $c->setErrorHandler(null); $res = array(); foreach ($dbs = $c->selectCol("SHOW DATABASES") as $dbname){ $tables = $c->selectCol("SHOW TABLES FROM $dbname LIKE '%$this->guess_table_pattern'"); if(is_array($tables)) foreach ($tables as $t){ // check fields here $info = $c->select("SHOW COLUMNS FROM $dbname.$t"); $infostr = ""; if(is_array($info)) foreach ($info as $k => $v) $infostr .= join(';', $v) . "\n"; $wrong = 0; foreach ($this->guess_fields_pattern as $pat){ if (!preg_match('|^'.$pat.'|m', $infostr)) $wrong++; } if ($wrong) continue; $res[] = $dbname . '.' . substr($t, 0, -strlen($this->guess_table_pattern)); } } return $res; } function init(){ set_protect_plugin_hooks($this); $this->init_database(); } } function validate_plugin_database($field, $vars){ global $db; foreach ($vars as $k => $v){ if (preg_match('/^\w+_(\w+)_\w+$/', $k, $regs)){ $pn = $regs[1]; break; } } if ($pn == '') die("Cannot determine plugin name at validate_plugin_database()"); $host = $vars['protect_'.$pn.'_host']; $user = $vars['protect_'.$pn.'_user']; $pass = $vars['protect_'.$pn.'_pass']; if ($host == '' && $user == '' && $pass == '') return; $err = ""; if ($user == '') $err .= "Please enter MySQL username.
"; // if ($pass == '') $err .= "Please enter MySQL password.
"; if ($host == '') $err .= "Please enter MySQL hostname.
"; if ($err != '') return $err; if (!@mysql_connect($host, $user, $pass, 1)){ return "Wrong MySQL username, password or hostname entered. " . mysql_error(); } } function set_protect_plugin_hooks(&$protect){ $pn = $protect->get_plugin_name(); foreach ($protect->hooks as $f) { eval ("function _{$pn}_$f(\$a1='',\$a2='',\$a3='',\$a4='',\$a5='',\$a6='',\$a7='',\$a8='',\$a9=''){ \$protect = & instantiate_plugin('protect', '{$pn}'); return \$protect->$f(\$a1,\$a2,\$a3,\$a4,\$a5,\$a6,\$a7,\$a8,\$a9); };"); setup_plugin_hook("$f", "_{$pn}_$f"); } } function cmp_ps_paypal($a, $b){ if ($a == 'paypal_pro') return -1; if ($b == 'paypal_pro') return 1; } function get_paysystems_list(){ global $__paysystems_list; uksort($__paysystems_list, 'cmp_ps_paypal'); return $__paysystems_list; } function add_paysystem_to_list($desc){ global $__paysystems_list; $__paysystems_list[$desc['paysys_id']] = $desc; } function get_paysystem($paysys_id){ global $__paysystems_list; return $__paysystems_list[$paysys_id]; } add_paysystem_to_list(array( 'paysys_id' => 'manual', 'title' => 'Manual Payment', 'description' => 'Payment Entered by Admin', 'public' => 0 ) ); ?> amember/plugins.inc.php0000644774276600352300000007004611573171457021161 0ustar nf.mortgageoriginatorseminarswww'; } else { $ptr = '::'; } $func_name = join($ptr, $func_name); } fatal_error(sprintf("Hook function is not defined: '%s' for $hook", $func_name)); } } /** * Instantiate Plugin * Get it from cache if it already exists * * @param string $type Plugin Type = db|payment|protect * @param string $name Plugin Name * @return mixed Plugin Object * * @global array Plugins List * @global mixed Script Config * @global mixed Plugins Config * @global mixed Plugins Cache */ function &instantiate_plugin($type, $name, $need_to_include=0){ global $plugins; global $config, $plugin_config; global $___plugins; //array of existsing plugins, indexed by [type][name] if (!strlen($type)) fatal_error("Plugin type is empty in instantiate_plugin(NULL, '$type')"); if (!strlen($name)) fatal_error("Plugin name is empty in instantiate_plugin('$type',NULL)"); if (!in_array($name, $plugins[$type])) fatal_error("Plugin '$name' is not enabled. Died"); $class = $type . "_" . $name; $exists = & $___plugins[$type][$name]; if (gettype($exists) == 'object') return $___plugins[$type][$name]; if ($need_to_include){ $file = $config['plugins_dir'][$type]."/$name/$name.inc.php"; if (!file_exists($file)) fatal_error("Plugin file ($file) for plugin ($type/$name) not exists"); $open = include($file); } if (!class_exists($class)) fatal_error("Error in plugin $type/$name: class $class not exists!"); return $___plugins[$type][$name] = new $class($plugin_config[$type][$name]); } /** * Instantiate Database Plugin * Return always first of database plugins. * Use {@link instaniate_plugin} * * @param string $name Database Plugin Name * @return mixed db Object * * @global array Plugins List */ function instantiate_db(){ global $plugins; return instantiate_plugin('db', $plugins['db'][0], 1); } ///////////////////// PAYMENT PLUGINS hooks //////////////////////////// function plugin_do_payment($paysys_id, $payment_id, $member_id, $product_id, $price, $begin_date, $expire_date, &$vars){ $pay_plugin = &instantiate_plugin('payment', $paysys_id); $ps = get_paysystem($paysys_id); global $db; if ($ps['fixed_price'] && ($product=$db->get_product($product_id)) && ($product['price'] != $price) && ($product['trial1_price'] != $price)){ return "Sorry, it is impossible to use this payment method for this order. Please select another payment method"; } return $pay_plugin->do_payment($payment_id, $member_id, $product_id, $price, $begin_date, $expire_date, $vars); } function plugin_validate_thanks($paysys_id, &$vars){ $pay_plugin = &instantiate_plugin('payment', $paysys_id); return $pay_plugin->validate_thanks($vars); } function plugin_process_thanks($paysys_id, &$vars){ $pay_plugin = &instantiate_plugin('payment', $paysys_id); return $pay_plugin->process_thanks($vars); } //////////////////// PROTECT PLUGINS hooks //////////////////////////////// function plugin_finish_waiting_payment($payment_id, $member_id=0){ //payment finished ok - call plugins to possible update databases, etc. global $__hooks; foreach ((array)$__hooks['finish_waiting_payment'] as $func_name){ call_user_func($func_name, $payment_id, $member_id); } } function check_for_signup_mail($payment_id, $member_id){ ### fix me! Signup mail #### global $config, $db; if (!$payment_id && !$member_id) return; global $db; if (!$member_id) { $payment = $db->get_payment($payment_id); $member_id = $payment['member_id']; } $member = $db->get_user($member_id); if ($member['data']['signup_email_sent']) return; if (!$config['manually_approve'] || $member['data']['is_approved']){ $payments = $db->get_user_payments($member_id, 1); foreach ($payments as $p) $exists_payments++; // send mail only if it FIRST payment for this product if ($exists_payments && $config['send_signup_mail']){ mail_signup_user($member_id); $member['data']['signup_email_sent']++; $db->update_user($member_id, $member); } } else { if ($member['data']['approval_email_sent']) return; mail_approval_wait_user($member_id); mail_approval_wait_admin($member_id); $member['data']['approval_email_sent']++; $db->update_user($member_id, $member); } } function plugin_update_users($member_id=0){ //payment finished ok - call plugins to possible update databases, etc. global $__hooks; if (!is_array($__hooks['update_users'])) return; foreach ($__hooks['update_users'] as $func_name){ call_user_func($func_name, $member_id); } } function plugin_update_payments($payment_id=0, $member_id=0){ global $__hooks; if (!is_array($__hooks['update_payments'])) return; foreach ($__hooks['update_payments'] as $func_name){ call_user_func($func_name, $payment_id, $member_id); } } function plugin_check_logged_in(){ //check if customer already logged-in in the slave application global $__hooks; foreach ((array)$__hooks['check_logged_in'] as $func_name){ list ($l, $p) = (array)call_user_func($func_name); if ($l) return array($l,$p); } return array('',''); } function plugin_after_login($user){ //called after successful payment //mutiple calls per session POSSIBLE! global $__hooks; foreach ((array)$__hooks['after_login'] as $func_name){ call_user_func($func_name, $user); } } function plugin_after_logout($user){ //called after logout global $__hooks; foreach ((array)$__hooks['after_logout'] as $func_name){ call_user_func($func_name, $user); } } function plugin_get_member_links($user){ //get array of links to display on the member.php page global $__hooks; $res = array(); foreach ((array)$__hooks['get_member_links'] as $func_name){ $res += (array)call_user_func($func_name, $user); } return $res; } function plugin_get_left_member_links($user){ //get array of links to display on the member.php page global $__hooks; $res = array(); foreach ((array)$__hooks['get_left_member_links'] as $func_name){ $res += (array)call_user_func($func_name, $user); } return $res; } function loggingObHandler($output) { // Free a piece of memory. unset($GLOBALS['_tmp_buf']); // Now we have additional 100K of memory, so - continue to work. if ($output == '' || trim($output) == '.') return; if (strstr($output, 'Fatal error') !== false){ $GLOBALS['db']->log_error("FATAL CRON ERROR:
\n$output"); return amDie("ERROR: Cron run resulted to fatal script execution error. Please look for details in the aMember CP -> Error Log (seek for FATAL CRON ERROR string)", true); } else $GLOBALS['db']->log_error("DEBUG (CRON OUTPUT):
\n$output"); } function start_special_logging(){ // Reserve 100K of memory for emergency needs. $GLOBALS['_tmp_buf'] = str_repeat('x', 1024 * 100); // Handle the output stream and set a handler function. ob_start('loggingObHandler'); } function stop_special_logging(){ unset($GLOBALS['_tmp_buf']); ob_end_clean(); } // cron hourly function plugin_hourly(){ global $__hooks; start_special_logging(); foreach ((array)$__hooks['hourly'] as $func_name){ call_user_func($func_name); } stop_special_logging(); } // cron daily function plugin_daily(){ global $__hooks; start_special_logging(); foreach ((array)$__hooks['daily'] as $func_name){ call_user_func($func_name); } stop_special_logging(); } // called if subscription added function plugin_subscription_added($member_id, $product_id, $member=0){ global $__hooks; global $__plugins_in_rebuild; if ($__plugins_in_rebuild) return; foreach ((array)$__hooks['subscription_added'] as $func_name){ call_user_func($func_name,$member_id, $product_id, $member); } } // called if member info updated function plugin_subscription_updated($member_id, $oldmember=0, $member=0){ global $__hooks; global $__plugins_in_rebuild; if ($__plugins_in_rebuild) return; foreach ((array)$__hooks['subscription_updated'] as $func_name){ call_user_func($func_name, $member_id, $oldmember, $member); } } // called if subscription expired/deleted function plugin_subscription_deleted($member_id, $product_id, $member=0){ global $__hooks; global $__plugins_in_rebuild; if ($__plugins_in_rebuild) return; foreach ((array)$__hooks['subscription_deleted'] as $func_name){ call_user_func($func_name, $member_id, $product_id, $member); } } // called if member removed function plugin_subscription_removed($member_id, $member=0){ global $__hooks; global $__plugins_in_rebuild; if ($__plugins_in_rebuild) return; foreach ((array)$__hooks['subscription_removed'] as $func_name){ call_user_func($func_name, $member_id, $member); } } // called to check if login is not exists in second databases // return 1 if not exists // return 0 if exists function plugin_subscription_check_uniq_login($login, $email, $pass){ global $__hooks; foreach ((array)$__hooks['subscription_check_uniq_login'] as $func_name){ $count += !call_user_func($func_name, $login, $email, $pass); } return !$count; } function plugin_subscription_rebuild(){ global $__hooks; global $db; global $__plugins_in_rebuild; $ul = $db->get_allowed_users(); // should return array[product_id][user_login]=password $users = array(); foreach ($ul as $product_id => $user) foreach ($user as $l => $p){ $users[$l]['pass'] = $p; $users[$l]['product_id'][] = $product_id; } $__plugins_in_rebuild++; $db->check_subscriptions_for_all(); $__plugins_in_rebuild--; foreach ((array)$__hooks['subscription_rebuild'] as $func_name){ call_user_func($func_name, $users); } } function plugin_display_signup_form(){ global $__hooks; foreach ((array)$__hooks['display_signup_form'] as $func_name) call_user_func($func_name, $vars); } function plugin_validate_signup_form(&$vars, $scope='signup'){ global $__hooks; $res = array(); foreach ((array)$__hooks['validate_signup_form'] as $func_name){ $res = array_merge((array)$res, (array)call_user_func_array($func_name, array(&$vars, $scope))); } return (array)$res; } function plugin_validate_member_form(&$vars){ global $__hooks; $res = array(); foreach ((array)$__hooks['validate_member_form'] as $func_name){ $res = array_merge((array)$res, (array)call_user_func_array($func_name, array(&$vars, $scope))); } return (array)$res; } function plugin_fill_in_signup_form(&$vars){ global $__hooks; $res = array(); foreach ((array)$__hooks['fill_in_signup_form'] as $func_name){ $res = array_merge((array)$res, (array)call_user_func_array($func_name, array(&$vars))); } return (array)$res; } /** * @param $menu AdminMenu */ function plugin_init_admin_menu(& $menu){ global $__hooks; foreach ((array)$__hooks['init_admin_menu'] as $func_name) call_user_func_array($func_name, array(& $menu)); } //////////////////////////////////////////////////////////////////////////// function check_cron(){ global $db; $last_runned = $db->load_cron_time(1); $h_diff = date('dH') - date('dH', $last_runned); $d_diff = date('d') - date('d', $last_runned); if ($h_diff || $d_diff) $db->save_cron_time(1); if ($h_diff) plugin_hourly(); if ($d_diff) plugin_daily(); } global $db; /* * Database (db) object * @global object $db **/ $db = & instantiate_db(); // set error handler set_error_handler('_amember_error_handler'); // load language load_language_defs(); load_language("/language"); /// load plugins load_plugins('protect'); load_plugins('payment'); global $config; if ($config['product_paysystem']){ $ps_list = array('' => '* Choose a paysystem *'); foreach ($l=get_paysystems_list() as $p) $ps_list[$p['paysys_id']] = $p['title']; add_product_field('paysys_id', 'Payment System', 'select', "Choose payment system to be used with this product.
This option only available if you have enabled option
\"Assign paysystem to product\" in aMember CP => Setup => Advanced ",'', array('options' => $ps_list) ); }; if (!is_lite()){ // add require another subscription field $require_options = array(); $prevent_options = array(); foreach ($db->get_products_list() as $pr){ $require_options['ACTIVE-'.$pr['product_id']] = 'Require ACTIVE subscription for "' . $pr['title'] . '"'; $require_options['EXPIRED-'.$pr['product_id']] = 'Require EXPIRED subscription for "' . $pr['title'] . '"'; $prevent_options['ACTIVE-'.$pr['product_id']] = 'Member has ACTIVE subscription for "' . $pr['title'] . '"'; $prevent_options['EXPIRED-'.$pr['product_id']] = 'Member has EXPIRED subscription for "' . $pr['title'] . '"'; } add_product_field('require_other', 'Require another subscription
to order this product', 'multi_select', "When user orders this subscription, aMember will
check that he has one from the following subscriptions
hold CTRL key to select several options ", '', array( 'insert_before' => '##13', 'size' => 4, 'options' => array( '' => "Don't require anything (default)", ) + $require_options )); add_product_field('prevent_if_other', 'Disallow subscription to this
product if the following conditions meet and user has:', 'multi_select', "When user orders this subscription, aMember will
check that he has not any from the following subscriptions
hold CTRL key to select several options ", '', array( 'insert_before' => '##13', 'size' => 4, 'options' => array( '' => "Don't prevent anything (default)", ) + $prevent_options )); } setup_plugin_hook('daily', array(&$db, 'check_subscriptions_for_all')); setup_plugin_hook('validate_signup_form', 'member_check_ban'); setup_plugin_hook('validate_signup_form', 'member_check_additional_fields'); setup_plugin_hook('validate_member_form', 'member_check_ban'); setup_plugin_hook('daily', 'mail_not_completed_members'); setup_plugin_hook('daily', 'member_send_autoresponders'); setup_plugin_hook('finish_waiting_payment', 'member_send_zero_autoresponder'); if ($config['send_payment_mail']) setup_plugin_hook('finish_waiting_payment', 'mail_payment_user'); if ($config['use_address_info'] == 1) setup_plugin_hook('validate_signup_form', 'vsf_address'); function clear_expired_guests(){ global $db; $db->delete_expired_guests(); $db->delete_expired_threads(); } setup_plugin_hook('daily', 'clear_expired_guests'); add_product_field('additional_subscriptions', 'Additional subscriptions', 'multi_select', "User will get free subscription for these
products if subscribed for current product
hold CTRL key to select several options", '', array('options' => get_products_options()) ); function add_additional_subscriptions($payment_id) { global $additional_subscriptions_added; $payment = $GLOBALS['db']->get_payment($payment_id); $product = $GLOBALS['db']->get_product($payment['product_id']); $additional_subscriptions_added[$payment['member_id']][$product['product_id']]++; foreach (array_filter((array)$product['additional_subscriptions']) as $product_id) { //to avoid recursion if(@intval($additional_subscriptions_added[$payment['member_id']][$product_id])) continue; $pr = &get_product($product_id); if (!$pr->config['product_id']) { continue; //there is not product with such id } $begin_date = $pr->get_start($payment['member_id']); $expire_date = $pr->get_expire($begin_date); $newp = array(); $newp['member_id'] = $payment['member_id']; $newp['product_id'] = $product_id; $newp['paysys_id'] = 'manual'; $newp['receipt_id'] = 'ADDITIONAL ACCESS:' . $payment['receipt_id']; $newp['begin_date'] = $begin_date; $newp['expire_date'] = $expire_date; $newp['amount'] = 0; $newp['completed'] = 1; $newp['data'][0]['MAIN_PAYMENT_ID'] = $payment_id; $additional_subscriptions_added[$payment['member_id']][$product_id]++; $GLOBALS['db']->add_payment($newp); } } setup_plugin_hook('finish_waiting_payment', 'add_additional_subscriptions'); @define('AMEMBER_BEFORE_CONTENT', "\n\n"); @define('AMEMBER_AFTER_CONTENT', "\n\n"); function amember_get_header_footer($vars){ global $config; static $__amember_header, $__amember_footer; if(empty($__amember_header) && empty($__amember_footer)) { $text = file_get_contents($config['root_dir']."/templates/layout.html"); if (empty($text)) { $__amember_header = "Unable to read templates/layout.html template, make sure that file exists and has correct permissions"; } elseif (strstr($text, '{$CONTENT}')===false) { $__amember_header = 'File templates/layout.html does not contain required phrase {$CONTENT} in the middle, please edit and add text {$CONTENT} to template'; } else { $mark = '-=--------CONTENTMARK-----------=-'; $t = new_smarty(); $t->assign($vars); $t->assign('CONTENT', $mark); $out = $t->fetch("layout.html"); list($__amember_header, $__amember_footer) = explode($mark, $out, 2); } } return array($__amember_header, $__amember_footer); } function amember_get_header_code_standard() { $root_url = htmlentities($GLOBALS['config']['root_surl']); $out = << CUT; if (file_exists(ROOT_DIR . '/templates/css/site.css')) $out .= ' '; return $out . "\n"; } function amember_get_header($vars){ global $__hooks; $ret = ""; if(!empty($__hooks['get_header'])){ foreach($__hooks['get_header'] as $func_name) call_user_func_array($func_name, array(& $ret, $vars)); } else { list($ret,) = amember_get_header_footer($vars); } $ret .= AMEMBER_BEFORE_CONTENT; return $ret; } function amember_get_footer($vars){ global $__hooks; $ret = ""; if(!empty($__hooks['get_footer'])){ foreach($__hooks['get_footer'] as $func_name) call_user_func_array($func_name, array(& $ret, $vars)); } else { list(,$ret) = amember_get_header_footer($vars); } $ret = AMEMBER_AFTER_CONTENT . $ret; return $ret; } function amember_get_header_code() { global $__hooks; $ret = amember_get_header_code_standard(); if (!empty($__hooks['get_header_code'])) { foreach($__hooks['get_header_code'] as $func_name) call_user_func_array($func_name, array(& $ret)); } return $ret; } function amember_filter_output($source, &$smarty, $resource_name='') { global $__hooks; if (!preg_match('/.html$/i', $resource_name) || !$__hooks['filter_output']) return $source; foreach ($__hooks['filter_output'] as $func_name) call_user_func_array($func_name, array(& $source, $resource_name, $smarty)); return $source; } function escape_for_js($s) { return strtr($s, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n')); } function insert_google_analytics(&$source, $resource_name, $smarty) { global $db; static $_ga_tracked, $_ga_tracked_sale; $ga = htmlentities(amConfig('google_analytics')); if (!$_ga_tracked) { $out = << CUT; $source = preg_replace('||i', $out . "\n", $source, 1, $count); if (!$count) $source .= $out; } if (amConfig('google_analytics')) setup_plugin_hook('filter_output', 'insert_google_analytics'); /** * @return bool true if customer is logged-in */ function amember_is_loggedin() { return (bool)$_SESSION['_amember_user']['member_id']; } /** * Return user record of logged-in customer * @return array user record */ function amember_get_userrecord() { if ($_SESSION['_amember_user']['member_id']) return $_SESSION['_amember_user']; else fatal_error("User is not logged-in in " . __FUNCTION__); } /** * Return Name (first and last) of logged-in customer * @return string */ function amember_get_name() { return htmlentities($_SESSION['_amember_user']['name_f'] . ' ' . $_SESSION['_amember_user']['name_l']); } /** * Return E-Mail address of logged-in customer * @return string */ function amember_get_email() { return $_SESSION['_amember_user']['email']; } /** * @return array[] of all payment records for logged-in customer * @throws error if user is not logged-in */ function amember_get_payments_all() { if ($_SESSION['_amember_user']['member_id']) return $GLOBALS['db']->get_user_payments(intval($_SESSION['_amember_user']['member_id']), 1); else fatal_error("User is not logged-in in " . __FUNCTION__); } /** * @return array[] of ACTIVE payment records for logged-in customer * @throws error if user is not logged-in */ function amember_get_payments_active() { $d = date('Y-m-d'); $ret = array(); foreach (amember_get_payments_all() as $p) if ($p['begin_date']<=$d && $p['expire_date']>=$d) $ret[] = $p; return $ret; } /** * Return all expired records, even if user now has an active record * to such product ! * @return array[] of EXIRED spayment records for logged-in customer * @throws error if user is not logged-in */ function amember_get_payments_expired() { $d = date('Y-m-d'); $ret = array(); foreach (amember_get_payments_all() as $p) if ($p['expire_date']<$d) $ret[] = $p; return $ret; } /** * Checks if user has active subscription to $product_id or to any from * array $product_id * @example amember_has_active_subscription(1,2,3) * @param array|int $product_id */ function amember_has_active_subscription($pid) { $product_id = array(); foreach (func_get_args() as $p) is_array($p) ? $product_id = array_merge($p, $product_id) : $product_id[] = $p; return (bool)array_intersect($product_id, $_SESSION['_amember_product_ids']); } /** * Checks if user has subscription expired to $product_id or to any from * array $product_id * Return FALSE if user has active subscription to any of these products * @param array|int $product_id * @example amember_has_active_subscription(1,3,2,4) * @throws error if user is not logged-in */ function amember_has_expired_subscription($pid) { $product_id = array(); foreach (func_get_args() as $p) is_array($p) ? $product_id = array_merge($p, $product_id) : $product_id[] = $p; if (amember_has_active_subscription($product_id)) return false; foreach (amember_get_payments_expired() as $p) if (in_array($p['product_id'], (array)$product_id)) return true; return false; } amember/product.inc.php0000644774276600352300000006616511573171460021161 0ustar nf.mortgageoriginatorseminarswww 'product_id', 'title' => 'Product #', 'type' => 'text' ), array( 'name' => 'title', 'title' => 'Title *', 'type' => 'text' ), array( 'name' => 'description', 'title' => 'Description *', 'type' => 'text' ), array( 'name' => 'price', 'title' => 'Price *', 'type' => 'money' ) ); global $product_additional_fields; $product_additional_fields = array( array( 'name' => 'expire_days', 'title' => 'Duration *', 'type' => 'period', 'description' => "Please enter subscription period for this product
it can also be set to lifetime, or to fixed date", 'validate_func'=> 'validate_period' ) ); function add_product_field( $name, $title, $type, $description='', $validate_func='', $additional_fields=NULL){ settype($additional_fields, 'array'); global $product_additional_fields; // make special order for some fields switch ($name){ case 'is_recurring': $additional_fields['insert_after'] = 'expire_days'; break; case 'trial1_price': $additional_fields['insert_after'] = 'expire_days'; break; case 'trial1_days': $additional_fields['insert_after'] = 'expire_days'; break; case 'trial2_price': $additional_fields['insert_after'] = 'trial1_days'; break; case 'trial2_days': $additional_fields['insert_after'] = 'trial1_days'; break; case 'trial_group': $additional_fields['insert_before'] = '##11'; break; case 'rebill_times': $additional_fields['insert_before'] = '##11'; break; case 'use_tax': $additional_fields['insert_before'] = '##11'; break; } if (preg_match('/.+_currency$/', $name)){ $additional_fields['insert_before'] = '##11'; } // foreach ($product_additional_fields as $k=>$v){ if ($v['name'] == $name) { if ($v['validate_func'] && ($v['validate_func'] != $validate_func)){ $product_additional_fields[$k]['validate_func'] = (array)$v['validate_func']; $product_additional_fields[$k]['validate_func'][] = $validate_func; } return; } } $to_add = array_merge( $additional_fields, array( 'name' => $name, 'title' => $title, 'type' => $type, 'description' => $description, 'validate_func' => $validate_func ) ); if ($to_add['insert_after'] || $to_add['insert_before']){ $found_key = -1; $search = $to_add['insert_after'] ? $to_add['insert_after'] : $to_add['insert_before']; foreach ($product_additional_fields as $k=>$v) if ($v['name'] == $search) $found_key = $k; if ($found_key<0) $found_key = count($product_additional_fields)-1; $replacement = $to_add['insert_after'] ? array($product_additional_fields[$found_key], $to_add) : array($to_add, $product_additional_fields[$found_key]); array_splice($product_additional_fields, $found_key,1, $replacement); } else $product_additional_fields[] = $to_add; } add_product_field('start_date', 'Fixed subscription start date', 'text', "By default, aMember calculates subscription start date
according to current date, but you may set it to fixed date here
Please enter date in format yyyy-mm-dd (for example 2006-02-28)
IN MOST CASES THIS FIELD SHOULD BE KEPT EMPTY ", '', array('insert_after ' => 'expire_days')); add_product_field('##11', 'Product URLs', 'header'); add_product_field('url', 'Product URL', 'text', "Please enter URL of protected area.
For example: /mydir/protected_dir1/
or http://area.yoursite.com/xxx/
or xxx/ or ../xxx/ -
last case case it is considered as relative
to configured aMember Pro root URL
PLEASE NOTE - folder will not become protected
if you just enter it here. Please read
aMember Pro manual about Protection Plugins. ", 'validate_product_url'); add_product_field('add_urls', 'Additional URLs', 'textarea', 'Enter additional URLs using this format:
/some_url/|URL title to display

These URLs will be displayed on the member.php page
in addition to the Product URL field', ''); if ($GLOBALS['config']['use_tax']) add_product_field('use_tax', 'Add Tax', 'checkbox', 'add tax value to price', ''); class product { // should contain keys: // product_id, title, description, price // expire_days, resources (list) var $config; function product($config){ $this->config = $config; } function get_price(){ return round($this->config['price'], 2); } /** * Function return expiration date for product, * calculated from given $field * In case of error it returns error message as string * @param int member_id to check existing subscriptions * @return string date in format yyyy-mm-dd */ function get_start($member_id=null){ global $db; $date = date('Y-m-d'); if (preg_match('/^\d\d\d\d-\d\d-\d\d$/', $this->config['start_date'])) return $this->config['start_date']; /// fixed start date if ($this->config['renewal_group'] < 0) return $date; if ($member_id > 0){ $payments = & $db->get_user_payments(intval($member_id), 1); foreach ($payments as $p){ $pr = $db->get_product($p['product_id']); if ((($p['product_id'] == $this->config['product_id']) || ($pr['renewal_group'] == $this->config['renewal_group'])) && ($p['expire_date'] > $date) ){ $date = $p['expire_date']; } } } list($y,$m,$d) = split('-', $date); $date = date('Y-m-d', mktime(0,0,0,$m, $d, $y)); return $date; } /** * Function return expiration date for product, * calculated from given $field * In case of error it returns error message as string * @param string begin_date yyyy-mm-dd * @param string field field name: expire_days, trial1_days or trial2_days * @return string date in format yyyy-mm-dd or error message */ function get_expire($begin_date, $field='expire_days', $terms=null){ /// get start calculation date list($y,$m,$d) = split('-', $begin_date); $tm = mktime(0,0,0, $m, $d, $y); // COUPON_NOT_USED functionality removed $koef = 1.0; /// get days value from field, and handle special if ($terms) switch ($pf = $terms->usedPriceFields[0]){ case 'trial1_price' : $field = 'trial1_days' ; break; case 'trial2_price' : $field = 'trial2_days' ; break; case 'price': $field = 'expire_days' ; break; default: fatal_error('Unknown price field used: [' . $pf . ']'); } $days = $this->config[$field]; list($count, $unit) = parse_period($days); if ($unit == 'error') return "Incorrect value for [$field] in product #".$this->config['product_id']; if ($unit == 'fixed') return $count; switch ($unit){ case 'd': $tm2 = $this->expire_date_add($tm, mktime(0,0,0, $m, $d+$count, $y), $koef); break; case 'm': $tm2 = $this->expire_date_add($tm, mktime(0,0,0, $m + $count, $d, $y), $koef); break; case 'y': $tm2 = $this->expire_date_add($tm, mktime(0,0,0, $m, $d, $y + $count), $koef); break; } if ($tm2 < $tm) // overflow, assign fixed "lifetime" date return MAX_SQL_DATE; return date('Y-m-d', $tm2); } function expire_date_add($tm1, $tm2, $koef){ $diff = $tm2 - $tm1; $new_diff = $diff * $koef; return $tm1 + $new_diff; } function _getTextPeriod($days, $skip_one_c){ list($c, $u) = parse_period($days); switch ($u){ case 'd': $uu = $c==1 ? 'day': 'days'; break; case 'm': $uu = $c==1 ? 'month' : 'months'; break; case 'y': $uu = $c==1 ? 'year' : 'years'; break; } $cc = $c; if ($c == 1) $cc = $skip_one_c ? '' : 'one'; return "$cc $uu"; } function _getTextPrice($number, $currency, $startWithUpperCase=false){ if ($number == 0.0) return $startWithUpperCase ? "Free" : "free"; return "$currency$number"; } /** * Function returns product subscription terms as text * @return string * @see price, expire_days, (is_recurring, trial1_price, trial1_days) - if enabled * start_date, (currency, rebill_times) - if enabled */ function getSubscriptionTerms(){ extract($this->config); global $config; if (!$currency) $currency = ($config['currency']) ? $config['currency'] : '$'; // @todo product currency $ret = ""; if (is_null($price) || !strlen($expire_days)) return ""; if ($config['terms_is_price']) return $this->_getTextPrice($price, $currency, $ret == ""); /// START_DATE if ($start_date){ // trials ignored $pr = $this->_getTextPrice($price, $currency, $ret == ""); if ($is_recurring && $price) $each = "each "; $sd = strftime($config['date_format'], strtotime($start_date)); $ed = strftime($config['date_format'], strtotime($this->get_expire($start_date))); $ret .= "$pr for period $sd - $ed"; } elseif (MAX_SQL_DATE == $expire_days){ $pr = $this->_getTextPrice($price, $currency, $ret == ""); if ($price == 0) $ret .= "Free lifetime subscription"; else $ret .= "$pr for lifetime subscription"; } elseif (preg_match('/^\d{4}-\d{2}-\d{2}$/', $expire_days)){ $ed = strftime($config['date_format'], strtotime($expire_days)); $pr = $this->_getTextPrice($price, $currency, $ret == ""); $ret .= "$pr for period up to $ed"; } else { if ($trial1_days){ $pr = $this->_getTextPrice($trial1_price, $currency, $ret == ""); $pp = $this->_getTextPeriod($trial1_days, 1); $ret .= "$pr for the first $pp. Then "; } $pr = $this->_getTextPrice($price, $currency, $ret == ""); if ($is_recurring && $price) $each = "each "; $ret .= "$pr for $each".$this->_getTextPeriod($expire_days, $is_recurring); if ($is_recurring && $rebill_times) { if ($trial1_days) $rebill_times--; $ret .= ", for $rebill_times installments"; } } return preg_replace('/[ ]+/', ' ', $ret); } } function get_product($product_id){ if (!$GLOBALS['db']) $GLOBALS['db'] = & instantiate_db(); global $db; $conf = $db->get_product($product_id); //return database record for product return new product($conf); } function get_products_options() { $result = array(); foreach ($GLOBALS['db']->get_products_list() as $product) { $result[$product['product_id']] = $product['title']; } return $result; } ////////////////////// validate functions ////////////////////////////// function validate_period(&$p, $field_name, $field){ if (($p->config[$field_name] == '') && ($field_name != 'expire_days')) return ""; // allow empty values for trial fields list($c,$u) = parse_period($p->config[$field_name]); if ($u == 'error') return "Wrong format of \"$field[title]\" field"; } function validate_product_url(&$p, $field){ $url = $p->config['url']; } function product_sort_cmp($a, $b){ $c = intval($a['order']) - intval($b['order']); if ($c) return $c; return strcmp($a['title'], $b['title']); } class PaymentTerms { var $lines = array(); var $subtotal; var $tax; var $discount; var $total; var $usedPriceFields; function calculate(){ $this->subtotal = $this->discount = $this->tax = $this->total = 0.0; foreach (array_keys($this->lines) as $k){ $l = & $this->lines[$k]; $l->calculate(); $this->subtotal += $l->subtotal; $this->discount += $l->discount; $this->tax += $l->tax; $this->total += $l->total; } $this->subtotal = round($this->subtotal, 2); $this->discount = round($this->discount, 2); $this->tax = round($this->tax, 2); $this->total = round($this->total, 2); } function setUsedPriceFields($fields){ $this->usedPriceFields = $fields; } } class PaymentTermsLine { var $product_id; // product id var $title; // product title var $price; // original price var $qty = 1; // quantity var $tax = 0.0; // tax amount var $discount = 0.0; // discount value var $subtotal; // price * qty var $total; // line total function PaymentTermsLine($product_id, $title, $price, $qty=1){ $this->product_id = $product_id; $this->title = $title; $this->price = $price; $this->qty = $qty; } function calculate(){ $this->subtotal = round($this->price * $this->qty, 2); $this->total = round($this->subtotal + $this->tax - $this->discount, 2); } } class PriceCalculator { /// input variables var $_items = array(); var $_tax = null; var $_couponDiscount = 0.0; var $_couponProducts = null; var $_priceField = array('price'); /** * add Product for calculation */ function addProduct($product_id, $qty=1){ $this->_items[$product_id] = $qty; } /** * add Product from array with qty = 1 * @param array */ function addProducts($product_ids){ foreach ((array)$product_ids as $pid) if (intval($pid) > 0) $this->addProduct(intval($pid), 1); } function emptyProducts(){ $this->_items = array(); } /** * Set product fields, it defines where class will seek for product price * @param array Array of field names, class will try from first to last * and use first where value is set * @example $pc->setPriceField('price'); * @example $pc->setPriceField('trial1_price', 'price'); */ function setPriceFields($field){ $this->_priceField = (array)$field; } /** * Function sets price fields according to paysystem type * @param string paysys_id */ function setPriceFieldsByPaysys($paysys_id){ $built_in_trials = false; if ($paysys_id && $paysys = get_paysystem($paysys_id)) $built_in_trials = $paysys['built_in_trials']; if ($built_in_trials){ $this->setPriceFields('price'); } else { $this->setPriceFields(array('trial1_price', 'price')); } } function setTax($tax){ $this->_tax = $tax; } function setCouponDiscount($couponDiscount, $couponProducts = null){ $this->_couponDiscount = trim($couponDiscount); $couponProducts = count($couponProducts) ? array_filter($couponProducts) : null; $this->_couponProducts = $couponProducts; } /** * Function calculates PaymentTerms according to given params * @return PaymentTerms payment terms object */ function & calculate(){ global $db; $terms = & new PaymentTerms(); $products = array(); $usedPriceFields = array(); // get product prices foreach ($this->_items as $pid=>$qty){ $p = $products[$pid] = $db->get_product($pid); $price = 0.0; foreach ($this->_priceField as $f) if ($p[$f] != '') { $price = $p[$f]; $usedPriceFields[] = $f; break; } $terms->lines[$pid] = & new PaymentTermsLine($pid, $p['title'], $price, $qty); } $terms->calculate(); // calculate discounts if (preg_match('/^(\d+(\.\d+)*)\s*%$/', $this->_couponDiscount, $regs)){ $discount = doubleval($regs[1]); if ($discount > 100.00) $discount = 100.00; foreach ($terms->lines as $pid => $line) if ($this->_couponIncludesProduct($pid)) $terms->lines[$pid]->discount = round($line->subtotal * $discount / 100, 2); } elseif ($this->_couponDiscount > 0.0){ $discount = doubleval($this->_couponDiscount); $this->_calculateAbsoluteDiscount($terms, $discount); } $terms->calculate(); // calculate taxes if ($this->_tax > 0){ foreach ($terms->lines as $pid => $line){ if ($products[$pid]['use_tax']) $terms->lines[$pid]->tax = round($terms->lines[$pid]->total * $this->_tax / 100, 2); } } $terms->calculate(); $terms->setUsedPriceFields($usedPriceFields); return $terms; } function _couponIncludesProduct($pid){ return empty($this->_couponProducts) || in_array($pid, (array)$this->_couponProducts); } function _calculateAbsoluteDiscount(& $terms, $discount){ $total_discountable = 0; $couponProducts = $this->_couponProducts; if ($couponProducts) $couponProducts = array_intersect($couponProducts, array_keys($this->_items)); else $couponProducts = array_keys($this->_items); if (!$couponProducts) return; foreach ($couponProducts as $pid) if ($this->_couponIncludesProduct($pid)) $total_discountable += $terms->lines[$pid]->total; if ($total_discountable > 0) $k = $discount / $total_discountable; else $k = 0; $last_pid = array_pop($couponProducts); $to_discount = $discount; foreach ($couponProducts as $pid){ $terms->lines[$pid]->discount = round($terms->lines[$pid]->total * $k, 2); $to_discount -= $terms->lines[$pid]->discount; } // set last discount $terms->lines[$last_pid]->discount = min(round($to_discount, 2), $terms->lines[$last_pid]->total); } } /** * Functions checks if first product from the list has trial * if yes, it returns "trial1_days" value, if not, it returns null * @param array|int Products ID array or single value * @return string|null Trial1_days value or null if empty */ function product_get_trial($product_id){ global $db; if (is_array($product_id)) $product_id = $product_id[0]; $p = $db->get_product($product_id); return $p['trial1_days']; } function display_agreement($data){ global $t, $error; $t->assign('data', $data); $t->assign('error', $error); $t->display('agreement.html'); } function get_product_requirements_for_member($member_id){ global $db; $dat = date('Y-m-d'); $res = array(); foreach ($db->get_user_payments($member_id, 1) as $p){ if (($p['begin_date'] < $dat) && ($p['expire_date'] < $dat)) $res['EXPIRED-'.$p['product_id']]++; elseif (($p['begin_date'] <= $dat) && ($p['expire_date'] >= $dat)) $res['ACTIVE-'.$p['product_id']]++; } return array_keys($res); } function check_product_requirements($product_ids, $have=''){ global $db; $error = array(); $will_have = $have ? (array)$have : array(); foreach ($product_ids as $product_id) $will_have[] = 'ACTIVE-'.$product_id; $will_have = array_unique($will_have); foreach ($product_ids as $product_id){ $pr = $db->get_product($product_id); if ($pr['require_other']){ $ro = array(); foreach ($pr['require_other'] as $s) if ($s) $ro[] = $s; // skip empty requirement if ($ro && !array_intersect($ro, $will_have)) { $titles = array(); foreach ($ro as $s){ if (preg_match('/^ACTIVE-(\d+)$/', $s, $args)){ $prt = $db->get_product($args[1]); $titles[] = '"'. $prt['title'] . '"'; } } if ($titles){ $error[] = "\"{$pr[title]}\" can be ordered ". "along with these products/subscriptons only: " . join(', ', $titles); continue; } $titles = array(); foreach ($ro as $s){ if (preg_match('/^EXPIRED-(\d+)$/', $s, $args)){ $prt = $db->get_product($args[1]); $titles[] = '"'. $prt['title'] . '"'; } } if ($titles){ $error[] = "\"{$pr[title]}\" can be ordered ". "only if you have expired subscription ". "for these products: " . join(', ', $titles); continue; } } } if ($pr['prevent_if_other']){ $ro = array(); // list of disallowances foreach ($pr['prevent_if_other'] as $s) if ($s) $ro[] = $s; // skip empty requirements if ($ro && ($problems=array_intersect((array)$ro, (array)$have))) { /// here is disallowance, lets display it $titles = array(); foreach ($problems as $s){ if (preg_match('/^ACTIVE-(\d+)$/', $s, $args)){ $prt = $db->get_product($args[1]); $titles[] = '"'. $prt['title'] . '"'; } } if ($titles){ $error[] = "\"{$pr[title]}\" cannot be ordered ". "because you already have active subscription(s) to: " . join(', ', $titles); } $titles = array(); foreach ($problems as $s){ if (preg_match('/^EXPIRED-(\d+)$/', $s, $args)){ $prt = $db->get_product($args[1]); $titles[] = '"'. $prt['title'] . '"'; } } if ($titles){ $error[] = "\"{$pr[title]}\" cannot be ordered ". "because you already have expired subscription(s) ". "for: " . join(', ', $titles); } } } } return $error; } add_product_field('##12', 'Product Availability/Visibilty', 'header'); add_product_field('scope', 'Scope', 'select', "Limits who can order this product
(Does not affect existing customers)", '', array('options'=>array( '' => 'Visible for all', 'disabled' => 'Disabled (hidden both on signup.php and member.php)', 'signup' => 'Only Signup (hide from member.php page)', 'member' => 'Only Members having completed subscriptions (hide from signup page)' ))); add_product_field('order', 'Sorting order', 'text', "This is a numeric field. Products
will be sorted according to this number, then alphabetically "); add_product_field('price_group', 'Price Group ID', 'text', "This is a numeric field. Products with a negative price_group
will not be displayed on the default Signup page. You can link to
an alternate Signup page like this 'signup.php?price_group=-1'
to display products ONLY from Price Group -1. You can enter
comma-separated ',' lists of pricegroups as well "); add_product_field('renewal_group', 'Renewal Group', 'text', "Value in this field defines how aMember will calculate
subscription start date when user renews his membership.
Please read this article to get idea of this feature.
In short - set the same values for products offering the same level of access
- set different values for products offering different level of access "); add_product_field('need_agreement', 'Display Agreement', 'checkbox', "Specify whether the user must agree to your Customer
Agreement before being allowed to proceed with payment.
Please put your agreement text into template:
templates/agreement.html" ,''); add_product_field('##13', 'Additional Options', 'header'); if (!is_lite()){ add_product_field('autoresponder_renew', 'Send Automatic Emails after Renewal', 'select', "When user renews subscription, aMember can
resend days counter and start emails again from first one
or aMember can continue old mailing cycle. ", '', array('options' => array( '' => 'Continue old mailing cycle', '1' => 'Reset days counter to zero, start new cycle' ))); add_product_field('dont_mail_expire', 'Do not send expiration e-mail for this product', 'hidden', "if you set this, expiration e-mail will not be send
for subscriptions to this product. ", '', array('options' => array( '' => 'Send expiration e-mail (default)', '1' => 'Do not send expiration e-mail', '2' => 'Always send expiration e-mail' ))); } add_product_field('terms', 'Custom Subscription Terms to Display', 'text', "this text will be displayed to customer near the
product title on signup.php and member.php pages
to explain payment terms
if you keep it empty, it will be generated automatically
if that is filled-in, you have to change it manually when
you change product price or other parameters ", '', array('insert_before' => '##11', 'size' => 60)); unset($GLOBALS['COUPON_NOT_USED']); unset($GLOBALS['COUPON_DISCOUNT']); unset($GLOBALS['TAX_AMOUNT']); unset($GLOBALS['TAXES']); unset($GLOBALS['PAYMENT_TERMS']); amember/profile.php0000644774276600352300000002362411573171460020362 0ustar nf.mortgageoriginatorseminarswwwassign('config', $config); $_product_id = array('ONLY_LOGIN'); include($config['plugins_dir']['protect'] . '/php_include/check.inc.php'); function check_new_username($login){ global $config, $db; if (!preg_match($p="/^\w{{$config[login_min_length]}}\w*$/", $login)){ return sprintf(_MEMBER_PROFILE_CORRECTLOG, $config[login_min_length]); } else if (!$member_id=$db->check_uniq_login($login)){ return sprintf(_MEMBER_PROFILE_NAMEEXISTS, $login); } } function get_active_price_groups() { $price_group = array(); foreach($_SESSION['_amember_products'] as $pr) { if ($pr['price_group']) { $price_group = array_merge($price_group, explode(',', $pr['price_group'])); } } return array_filter($price_group); } function save_profile(&$vars, &$user){ global $db, $config; global $_amember_id, $member_additional_fields, $email_confirmation_required; $email_confirmation_required =0; $fields_to_change = (array)$config['profile_fields']; $maf = array(); foreach ($member_additional_fields as $f){ $maf[$f['name']] = $f; // Set empty values for all fields that were not submited. // Need to do this to get validation functions working for radio buttons. if(!$vars[$f[name]]) $vars[$f[name]] = ''; } $error = array(); if ($config['use_address_info'] == 1) $error = vsf_address($vars, $is_signup = false); foreach ($vars as $k=>$v){ $field = $k; if (in_array($k, $fields_to_change)) $field_type = 1; elseif ( ($maf[$k]['display_profile'] || $maf[$k]['display_affiliate_profile']) && is_additional_fields_avalable(get_active_price_groups(), $maf[$k])) { $field_type = 2; } else { continue; } ///check username if (($k == 'login') && ($v != $_SESSION['_amember_login']) && $err=check_new_username($v)){ $error[] = sprintf(_MEMBER_PROFILE_ERROR1, $err); $user['login'] = $v; continue; } //// if($config['verify_email_profile'] && ($k=='email') && ($v!=$user['email'])){ $email_confirmation_required = 1; $old_email = $user['email']; $new_email = $v; } if (($k == 'email') && !check_email($v)){ $error[] = _MEMBER_PROFILE_ERROR2; $user['email'] = $v; continue; } elseif (($k == 'email') && $config['unique_email']){ $ul = $db->users_find_by_string($vars['email'], 'email', 1); if($ul && ($ul[0][member_id] != $_amember_id)){ $error[] = _MEMBER_PROFILE_ERROR3; continue; } } if (($k == 'name_f') && !strlen($v)){ $error[] = _MEMBER_PROFILE_ERROR4; $user['name_f'] = $v; continue; } if (($k == 'name_l') && !strlen($v)){ $error[] = _MEMBER_PROFILE_ERROR5; $user['name_l'] = $v; continue; } if (($k == 'name_f') && preg_match('/[<>"]/', $v)){ $error[] = _MEMBER_PROFILE_ERROR4; $user['name_f'] = $v; continue; } if (($k == 'name_l') && preg_match('/[<>"]/', $v)){ $error[] = _MEMBER_PROFILE_ERROR5; $user['name_l'] = $v; continue; } /// check password if ($k == 'pass0'){ if (strlen($v) == 0) { //don't change at all continue; } if (strlen($v) < $config['pass_min_length']) { $error[] = sprintf(_MEMBER_PROFILE_ERROR6, $config[pass_min_length]); continue; } if (strlen($v) > $config['pass_max_length']) { $error[] = sprintf(_MEMBER_PROFILE_ERROR7, $config[pass_max_length]); continue; } if ($vars['pass0'] != $vars['pass1']){ $error[] = _MEMBER_PROFILE_ERROR8; continue; } $field = 'pass'; } /// set value if ($field_type == 1){ $user[$field] = $v; } elseif ($field_type == 2) { $ff = $maf[$k]; foreach ((array)$ff['validate_func'] as $func){ if (!strlen($func)) continue; if ($ff['display_profile'] > 0 && $err = $func($v, $ff['title'], $ff)){ $error[] = $err; } } if ($ff['display_profile'] > 0){ if ($ff['sql']) $user[$k] = $v; else $user['data'][$k] = $v; } } else { fatal_error(sprintf(_MEMBER_PROFILE_ERROR9, $k, $field_type)); } } if (!$error){ if($email_confirmation_required){ // Restore old email address and send message to user; $user['email'] = $old_email; $user['data']['email_new'] = $new_email; $user['data']['email_confirm_code'] = substr(uniqid(rand(), true), 0, 12); $user['data']['email_confirm_code_exp'] = time()+3600*24; // Expire link in 24 hours. } $db->update_user($_amember_id, $user); if (in_array('login', $fields_to_change)) $_SESSION['_amember_login'] = $user['login']; $_SESSION['_amember_pass'] = $user['pass']; } return $error; } function display_saved(){ global $t, $db,$config; global $_amember_id,$email_confirmation_required; $user = $db->get_user($_amember_id); if($email_confirmation_required){ profile_send_verification_email($user); } html_redirect("member.php", false, _TPL_PROFILE_SAVED_TITLE, _TPL_PROFILE_SAVED_SUCCESS); } function profile_send_verification_email($user){ global $t,$config; $user['email'] = $user['data']['email_new']; mail_verification_email($user, $config['root_url'] . "/profile.php?cs=" . $user['member_id']. "-" . $user['data']['email_confirm_code'],"profile"); $t->assign('user', $u); $t->assign('source', 'profile'); $t->display("email_verify.html"); exit; } function profile_clean_verification_fields($user){ global $db; $user['data']['email_new'] = ""; $user['data']['email_confirm_code'] = ""; $user['data']['email_confirm_code_exp'] = ""; $db->update_user($user['member_id'], $user); } function display_form($user){ global $t, $config; global $_amember_id, $error,$db; $email_address = $user['email']; $email_confirmation_required = 0; if($config['verify_email_profile']){ if($user['data']['email_new']){ if($user['data']['email_confirm_code_exp'] > time()){ $email_address = $user['data']['email_new']; $email_confirmation_required = 1; }else{ // Link expired; Change values back and update user record; profile_clean_verification_fields($user); } } } $user['email'] = $email_address; $t->assign("email_confirmation_required", $email_confirmation_required); $t->assign('state_options', db_getStatesForCountry($user['country'], 1)); $t->assign('user', $user); if ($config['use_affiliates'] && $user['is_affiliate'] == '2') $additional_fields = get_additional_fields_html($user, 'affiliate_profile', 0, get_active_price_groups()); else $additional_fields = get_additional_fields_html($user, 'profile', 0, get_active_price_groups()); $t->assign('additional_fields_html', $additional_fields); $fields_to_change = array(); foreach ((array)$config['profile_fields'] as $f) $fields_to_change[$f]=1; $t->assign('fields_to_change', $fields_to_change); $t->assign('error', $error); $t->display('profile.html'); } $vars = get_input_vars(); $_amember_id = $_SESSION['_amember_id']; $user = $db->get_user($_amember_id); if($vars['resend_email'] && $config['verify_email_profile'] && $user['data']['email_new']){ $user['data']['email_confirm_code'] = substr(uniqid(rand(), true), 0, 12); $user['data']['email_confirm_code_exp'] = time()+3600*24; // Expire link in 24 hours. $db->update_user($user['member_id'], $user); profile_send_verification_email($user); } if($_GET['cs']&&$config['verify_email_profile']){ $error = ''; list($member_id, $ver_code) = split("-",$_GET["cs"]); $member_id = intval($member_id); if((!$member_id) || ($member_id!=$_SESSION['_amember_id']) || (!$ver_code) || ($user['data']['email_confirm_code']!=$ver_code)){ fatal_error(_SIGNUP_INCORRECT_LINK); }else if($user['data']['email_confirm_code_exp'] amember/rconfig.inc.php0000644774276600352300000002153111573171460021114 0ustar nf.mortgageoriginatorseminarswwwget_user($member_id); $v = $u['member_id'].$u['login'].$u['email']; if ($config['verify_email'] && $member_id && (md5($v) == $vars['v'])){ if ($u['email_verified'] >= 0){ fatal_error(_RESEND_ERROR, 1); } elseif ($u['email_verified'] < -3){ fatal_error(sprintf(_RESEND_ERROR2,"",""),1,1); } $u['email_verified']--; $db->update_user($u['member_id'], $u); foreach ($db->get_user_payments($member_id, 0) as $p) { $payment_id = $p['payment_id']; $code=$p['data']['email_confirm']['code']; } $md5 = md5($u['login'].$u['pass'].$member_id.$payment_id); $member_id_exists = 0; mail_verification_email($u, $config['root_url'] . "/signup.php?cs=" . $payment_id . "-" . $code); $t->assign('user', $u); $t->display("email_verify.html"); exit(); } else { fatal_error(_RESEND_ERROR3, 1); } ?>amember/sendpass.php0000644774276600352300000001566711573171461020553 0ustar nf.mortgageoriginatorseminarswwwquery("SELECT member_id, login, IF( ((UNIX_TIMESTAMP(securitycode_expire) - $unix_timestamp) > 0), '1', '0') AS valid_code FROM {$db->config[prefix]}members WHERE security_code='".$db->escape($security_code)."' AND member_id='".$member_code."' "); list($member_id, $login, $valid_code) = mysql_fetch_row($q); if ($member_id == '' || $login == '') { //if wrong security code $t->assign('message', _TPL_CHANGEPASSWORD_FAILED_USRNOTFOUND); $t->assign('login_page', $config['root_url'] . "/member.php"); $t->display('changepass_failed.html'); exit(); } if ($valid_code == '0') { // security_code expired. clear security_code and exit $q = $db->query("UPDATE {$db->config[prefix]}members SET security_code='', securitycode_expire='' WHERE member_id='$member_id' "); $t->assign('message', _TPL_CHANGEPASSWORD_FAILED_EXPIRED); $t->assign('login_page', $config['root_url'] . "/member.php"); $t->display('changepass_failed.html'); exit; } else { if (isset($_POST['do_change']) && $_POST['do_change'] == '1') { // save new password, clear security_code, register sessions and redirect to member.php $pass0 = $vars['pass0']; $pass1 = $vars['pass1']; if ($pass0 == $pass1 && strlen($pass0) >= $config['pass_min_length']) { //if user exists and passwords is right $q = $db->query("UPDATE {$db->config[prefix]}members SET security_code='', securitycode_expire='' WHERE member_id='$member_id' "); $member = $db->get_user($member_id); $member['pass'] = $pass0; $member['security_code'] = ''; $member['securitycode_expire'] = ''; $q = $db->update_user($member_id, $member); $_SESSION['_amember_login'] = $login; $_SESSION['_amember_pass'] = $pass0; $redirect = $config['root_url'] . "/member.php"; html_redirect("$redirect", 0, 'Redirect', _LOGIN_REDIRECT); exit; } else { $t->assign('message', _TPL_CHANGEPASSWORD_FAILED_WRONGPASS); $t->assign('login_page', $config['root_url'] . "/sendpass.php?s=" . $member_code.":".$security_code); $t->display('changepass_failed.html'); exit(); } } else { //show change password form $t->assign('login', $login); $t->assign('code', $member_code.":".$security_code); $t->display('changepass.html'); exit; } } //end $valid_code != '0' } //end $config['safe_send_pass'] == '1' && isset ($security_code) if (!strlen($login)) { $t->assign('title', _SENDPWD_FAILED_TITLE); $t->assign('text', _SENDPWD_FAILED_TEXT . ".
\n" . sprintf(_SENDPWD_FAILED_TEXT_1, htmlentities($login)) ); $t->display('sendpass_result.html'); exit(); }; $ul = $db->users_find_by_string($login, 'login', 1); if (!count($ul)){ $l = $db->escape($login); $q = $db->query("SELECT m.member_id, p.expire_date FROM {$db->config[prefix]}members m LEFT JOIN {$db->config[prefix]}payments p USING (member_id) WHERE m.email='$l' ORDER BY p.completed DESC, p.expire_date DESC LIMIT 1 "); list($member_id, $expire) = mysql_fetch_row($q); $ul = $member_id ? array($db->get_user($member_id)) : array(); } if ( count($ul) ){ $u = $ul[0]; $member_id = $u['member_id']; if ($config['safe_send_pass'] != '1') { //simple password remind method $t->assign('login', $u['login']); $t->assign('pass', $u['pass']); $t->assign('email', $u['email']); $t->assign('name_f', $u['name_f']); $t->assign('name_l', $u['name_l']); $t->assign('user', $u); $et = & new aMemberEmailTemplate(); $et->name = "send_pass"; mail_template_user($t, $et, $u); } else { //send a security code $acceptedChars = 'azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN0123456789'; $max = strlen($acceptedChars) - 1; $security_code = ""; for($i=0; $i < 16; $i++) $security_code .= $acceptedChars{mt_rand(0, $max)}; $security_code = $security_code . time(); $security_code = md5($security_code); $security_code = substr($security_code, 0, 16); $hours = 48; $securitycode_expire = date("Y-m-d H:i:s", time() + $hours * 60 * 60); $t->assign('login', $u['login']); $t->assign('email', $u['email']); $t->assign('name_f', $u['name_f']); $t->assign('name_l', $u['name_l']); $t->assign('user', $u); $t->assign('code', $member_id.":".$security_code); $t->assign('hours', $hours); $et = & new aMemberEmailTemplate(); $et->name = "send_security_code"; mail_template_user($t, $et, $u); $q = $db->query("UPDATE {$db->config[prefix]}members SET security_code='".$db->escape($security_code)."', securitycode_expire='$securitycode_expire' WHERE member_id='$member_id' "); } $t->assign('title', _SENDPWD_OK_TITLE); $t->assign('text', _SENDPWD_OK_TEXT . ".
\n" . _SENDPWD_OK_TEXT_1 ); $t->display('sendpass_result.html'); } else { $t->assign('title', _SENDPWD_FAILED_TITLE); $t->assign('text', _SENDPWD_FAILED_TEXT . ".
\n" . sprintf(_SENDPWD_FAILED_TEXT_1, htmlentities($login)) ); $t->display('sendpass_result.html'); } ?> amember/setup.php0000644774276600352300000007160611573171461020066 0ustar nf.mortgageoriginatorseminarswww= $minver){ return true; } else { die("PHP version ".$vercheck." or greater is required to run aMember. Your PHP-Version is : ".phpversion(). "
Please upgrade or ask your hosting to upgrade. PHP before $vercheck was buggy and vunerable."); } } version_check('4.1.0'); // if version not ok the script stopped and displays an errormsg if (!function_exists('mysql_connect')){ die("PHP on your webhosting has been compiled without MySQL support.
so aMember cannot be installed to your hosting, please contact your
hosting support to fix this problem."); } error_reporting(E_ALL ^ E_NOTICE); ini_set("magic_quotes_runtime", 0); // set_magic_quotes_runtime(0); ini_set('display_errors', 1); /*************************************************************************** * Author: Alex Scott * Email: alex@cgi-central.net * Web: http://www.cgi-central.net * Details: The installation file * FileName $RCSfile$ * Release: 3.2.3PRO ($Revision: 5392 $) * * Please direct bug reports,suggestions or feedback to the cgi-central forums. * http://www.cgi-central.net/forum/ * * aMember PRO is a commercial software. Any distribution is strictly prohibited. * Web-based setup. Steps: 0 - check for installed config.php, check if it writeable - main config.inc.php data form 1 - check config.inc.php data - display mysql connection form 2 - check mysql connection - check for tables installed - if installed, skip to step 4 - if not installed ask to install it 3 - install mysql db 4 - plugins configuration (except MySQL) 5 - save all config files */ /** * Retrieve input vars, trim spaces and return as array * @return array array of input vars (_POST or _GET) * */ function get_input_vars(){ $REQUEST_METHOD = $_SERVER['REQUEST_METHOD']; $vars = $REQUEST_METHOD == 'POST' ? $_POST : $_GET; foreach ($vars as $k=>$v){ if (is_array($v)) continue; if (get_magic_quotes_gpc()) $v = stripslashes($v); $vars[$k] = trim($v); } return $vars; } function make_password($length=16){ $vowels = 'aeiouy'; $consonants = 'bdghjlmnpqrstvwxz'; $password = ''; $alt = time() % 2; srand(time()); for ($i = 0; $i < $length; $i++) { if ($alt == 1) { $password .= $consonants[(rand() % 17)]; $alt = 0; } else { $password .= $vowels[(rand() % 6)]; $alt = 1; } } return $password; } function display_header($title){ global $header_displayed; if ($header_displayed) return; $header_displayed++; print << $title

$title

EOF; } function display_footer(){ global $footer_displayed; if ($footer_displayed) return; $footer_displayed++; print << © CGI-Central, Inc., 2002-2006
EOF; } function display_fatal($error){ display_header(); print "Fatal Error: $error"; display_footer(); exit(); } function display_errors($errs){ display_header("aMember Installation"); print "

"; foreach ((array)$errs as $e) print "

  • $e\n"; print "

  • "; } function exit_errors($errs){ if (!is_array($errs)) $errs = array($errs); display_errors($errs); print <<return and fix these errors.

    EOF; display_footer(); exit(); } function check_for_existance(){ global $root_dir; $errors = array(); $cf = "$root_dir/config.inc.php"; if (file_exists($cf) && filesize($cf)){ $errors[] = "File 'config.inc.php' in amember folder is already exists and non-empty. Please remove it or delete all content if you want to do full reconfiguration"; } if ($errors) { display_errors($errors); print <<here to refresh page.

    EOF; display_footer(); exit(); } } function check_for_writeable(){ global $root_dir; $errors = array(); $cf = "$root_dir/config.inc.php"; if (!is_writeable($d = "$root_dir/data/")){ $errors[] = "Directory '$d' is not writeable. Please fix it"; } if (!is_writeable($d = "$root_dir/data/new_rewrite/")){ $errors[] = "Directory '$d' is not writeable. Please fix it"; } if (!is_writeable($d = "$root_dir/templates_c")){ $errors[] = "Directory '$d' is not writeable. Please fix it"; } if ($errors) { display_errors($errors); print <<here to refresh page.

    EOF; display_footer(); exit(); } } function display_main_config(){ global $root_dir; $HTTP_HOST = $_SERVER['HTTP_HOST']; $SERVER_ADMIN = $_SERVER['SERVER_ADMIN']; $REQUEST_URI = $_SERVER['REQUEST_URI']; $root_url = "http://$HTTP_HOST" . str_replace('/setup.php', '', $REQUEST_URI); $admin_email = $SERVER_ADMIN; $admin_login = 'admin'; $admin_pass = ''; print <<

    Enter configuration parameters

    You may modify these values later via the aMember Control Panel EOF; if ('@TRIAL@' == '@'.'TRIAL@') print << EOF; print <<
    EOF; if ('@LITE@' == ('@' . 'LITE@')) print << EOF; print << EOF; } function check_main_config(){ $vars = get_input_vars(); $errors = array(); if (!strlen($vars['@ROOT_URL@'])) $errors[] = "Please enter root url of script"; if (!strlen($vars['@ROOT_SURL@'])) $errors[] = "Please enter secure root url of script (or keep DEFAULT VALUE - set it equal to Not-secure root URL - it will work anyway)"; if (!strlen($vars['@ADMIN_EMAIL@'])) $errors[] = "Please enter admin email"; if (!strlen($vars['@ADMIN_LOGIN@'])) $errors[] = "Please enter admin login"; if (!strlen($vars['@ADMIN_PASS@'])) $errors[] = "Please enter admin password"; if ('@TRIAL@' == '@'.'TRIAL@'){ if (!strlen($vars['@LICENSE@'])) $errors[] = "Please enter license code"; if (!preg_match('/===== .+?===== EN(F|D) OF LICENSE =====/s', $vars['@LICENSE@'])) $errors[] = "Please enter full license code (it should start and end with ======)"; if (preg_match('/===== .+? \((.+?), (.+?), valid thru (.+?)\) =====/', $vars['@LICENSE@'], $regs)){ $d = preg_quote($regs[1]); $sd = preg_quote($regs[2]); $exp = $regs[3]; $u1 = parse_url($url=$vars['@ROOT_URL@']); $u2 = parse_url($surl=$vars['@ROOT_SURL@']); if (!preg_match($x = "/($d|$sd)\$/", $u1['host'])) $errors[] = "Root URL '$url' doesn't match license domain"; if (!preg_match("/($d|$sd)\$/", $u2['host'])) $errors[] = "Secure Root URL '$surl' doesn't match license domain"; } } if ($errors) { display_errors($errors); print <<return and fix these errors.

    EOF; display_footer(); exit(); } } function get_hidden_vars(){ $res = ''; foreach ($_POST as $k=>$v){ if ($k[0] == '@') if (is_array($v)) // array foreach ($v as $kk=>$vv) $res .= sprintf(''."\n", htmlspecialchars($k), htmlspecialchars($vv)); else $res .= sprintf(''."\n", htmlspecialchars($k), htmlspecialchars($v)); } return $res; } function display_mysql_form(){ $hidden = get_hidden_vars(); print <<

    Enter MySQL configuration parameters

    You may edit config.inc.php if you need to make changes after Setup
    Root URL of script
    Do not place a trailing slash ( / ) at the end!
    Please note that url must match your license.
    Secure (HTTPS) Root URL of script
    Please keep default (not-secure) value if you are unsure.
    No trailing slash ( / ) please!
    Please note that url must match your license.
    Admin Email
    The address that alerts and other email should be sent to
    Admin Login
    Username for login to the Admin interface
    Admin Password
    Password for login to the Admin interface
    License
    Enter the Full license key, including dashed lines ( == ) above and below!
    MySQL Host
    Very often 'localhost'
    MySQL Database
    Note: Setup does not create the database for you.
    Use the default database created by your host or
    create a new database, for example 'amember'
    MySQL Username
    MySQL Username
    MySQL Password
    MySQL Password
    MySQL Tables Prefix
    If unsure, use the default value 'amember_'

    $hidden EOF; } function check_mysql_form(&$db_installed){ $db_installed = 0; $vars = $_POST; $errors = array(); if (!strlen($vars['@DB_MYSQL_DB@'])) $errors[] = "Please enter mysql database name"; if (!strlen($vars['@DB_MYSQL_USER@'])) $errors[] = "Please enter mysql username"; # if (!strlen($vars['@DB_MYSQL_PASS@'])) $errors[] = "Please enter mysql password"; if (!strlen($vars['@DB_MYSQL_HOST@'])) $errors[] = "Please enter mysql hostname"; if ($errors) { display_errors($errors); print <<return and fix these errors.

    EOF; display_footer(); exit(); } /// really connect $conn = @mysql_connect( $vars['@DB_MYSQL_HOST@'], $vars['@DB_MYSQL_USER@'], $vars['@DB_MYSQL_PASS@'] ); if (!$conn) $errors = "Cannot connect to mysql (".mysql_error().")"; if ($errors) { display_errors($errors); print <<return and fix these errors.

    EOF; display_footer(); exit(); } $dbc = @mysql_select_db($vars['@DB_MYSQL_DB@']); if (!$dbc) $errors = "Cannot select database '" . $vars["@DB_MYSQL_DB@"] . "' (" . mysql_error() . ")"; if ($errors) { display_errors($errors); print <<return and fix these errors.

    EOF; display_footer(); exit(); } /* $q = mysql_query("SELECT COUNT(*) FROM ".$vars['@DB_MYSQL_PREFIX@']."error_log", $conn); if (mysql_errno()) return; $q = mysql_query("SELECT COUNT(*) FROM ".$vars['@DB_MYSQL_PREFIX@']."members", $conn); if (mysql_errno()) return; $q = mysql_query("SELECT COUNT(*) FROM ".$vars['@DB_MYSQL_PREFIX@']."payments", $conn); if (mysql_errno()) return; $q = mysql_query("SELECT COUNT(*) FROM ".$vars['@DB_MYSQL_PREFIX@']."access_log", $conn); if (mysql_errno()) return; $q = mysql_query("SELECT COUNT(*) FROM ".$vars['@DB_MYSQL_PREFIX@']."cron_run", $conn); if (mysql_errno()) return; $q = mysql_query("SELECT COUNT(*) FROM ".$vars['@DB_MYSQL_PREFIX@']."products", $conn); if (mysql_errno()) return; */ // always install db $db_installed = 0; } function display_db_install_query(){ $hidden = get_hidden_vars(); print <<

    Continue installation?

    aMember Setup Wizard is now ready to finish installation and create database tables. If database tables are already created, aMember will intelligently modify its structure to match latest aMember version. Your existing configuration and database records will not be removed.

    $hidden EOF; } function create_mysql_tables(){ $vars = $_POST; $conn = @mysql_connect( $vars['@DB_MYSQL_HOST@'], $vars['@DB_MYSQL_USER@'], $vars['@DB_MYSQL_PASS@'] ); if (!$conn) exit_errors("Cannot connect to mysql (".mysql_error().")"); $dbc = @mysql_select_db($vars['@DB_MYSQL_DB@']); if (!$dbc) exit_errors("Cannot select database '" . $vars["@DB_MYSQL_DB@"] . "' (" . mysql_error() . ")"); if (!is_readable("amember.sql")) exit_errors("File [amember.sql] not found, make sure you've uploaded all files"); $file = join('', file("amember.sql")); $file = str_replace('@DB_MYSQL_PREFIX@', $vars['@DB_MYSQL_PREFIX@'], $file); $file = preg_replace('/^\s+\#(.*)$/m', '', $file); preg_match_all('/(CREATE TABLE\s+(.+?)\s+.+?|.+?);\s*$/ms', $file, $out); $vars['@CURL_PATH@'] = guess_curl(); $prefix = $vars['@DB_MYSQL_PREFIX@']; $email_templates_created = email_templates_created($prefix); foreach ($out[0] as $sql){ foreach ($vars as $k=>$v){ if ($k == '@ADMIN_PASS@') { srand(time()); $v = crypt($v); } if ($k == '@PAYMENT_PLUGINS@') $v = serialize($v); if ($k == '@PROTECT_PLUGINS@') $v = serialize($v); $k = mysql_escape_string($k); $v = mysql_escape_string($v); $sql = str_replace($k, $v, $sql); } if (preg_match('/CREATE TABLE\s+(\w+)/', $sql, $regs)) { $tname = $regs[1]; if (mysql_query("SELECT * FROM $tname LIMIT 1") && !mysql_errno()){ continue; // SKIP TABLE CREATION } } elseif (preg_match("/INSERT INTO {$prefix}email_templates/", $sql) && $email_templates_created) { continue; } elseif (preg_match('/MODIFY\s+(\w+)\s+(.+);/', $sql, $regs)){ $tname = $regs[1]; $mreq = $regs[2]; if (preg_match('/FIELD\s+(\w+)\s+(.+)/', $mreq, $regs)){ $field = $regs[1]; $q = mysql_query("SHOW FIELDS FROM $tname"); $sql = ''; while (list($f,$t,$null,$index,$add) = mysql_fetch_row($q)){ if ($f == $field) { $sql = "ALTER TABLE $tname CHANGE $field $field $regs[2];"; break; } } if (!$sql) $sql = "ALTER TABLE $tname ADD $field $regs[2];"; } elseif (preg_match('/DROP_FIELD\s+(\w+)/', $sql, $regs)){ $field = $regs[1]; $q = mysql_query("SHOW FIELDS FROM $tname"); $sql = ''; while (list($f,$t,$null,$index,$add) = mysql_fetch_row($q)){ if ($f == $field) { $sql = "ALTER TABLE $tname DROP $field"; break; } } } elseif (preg_match('/(UNIQUE INDEX|INDEX)\s+(\w+)\s+.+/', $mreq, $regs)){ $index = $regs[2]; $q = mysql_query("SHOW INDEX FROM $tname"); while (list($t,$t,$index1) = mysql_fetch_row($q)){ if ($index1 != $index) continue; mysql_query("ALTER TABLE $tname DROP INDEX $index"); } $sql = "ALTER TABLE $tname ADD $regs[0]"; } else { // unknown modify request print "unknown modify request"; continue; } } $sql = preg_replace('/;\s*$/s', '', $sql); mysql_query($sql); if ($err = mysql_error()) exit_errors($err . "
    SQL:
    $sql
    "); } // insert countries foreach (array('countries', 'states') as $ff){ $fn = "sql-$ff.sql"; $q = mysql_query($s = "SELECT COUNT(*) FROM {$prefix}$ff"); if ($e = mysql_error()) print "SQL Error: $e
    \n"; $c = mysql_fetch_row($q); $c = $c[0]; if ($c) continue; if (!is_readable($fn)) exit_errors("File [$fn] not found, make sure you've uploaded all files"); $sql = join('', file("$fn")); $sql = str_replace('@DB_MYSQL_PREFIX@', $vars['@DB_MYSQL_PREFIX@'], $sql); mysql_query($sql); if ($err = mysql_error()) exit_errors($err . " in [$fn]"); } } function guess_curl(){ // try to guess location of "curl" executable if (extension_loaded("curl")) return; // don't try $try = array( '/usr/bin/curl', '/usr/local/bin/curl', '/usr/local/curl/bin/curl', '/win/curl.exe', ); foreach ($try as $p){ if (!@file_exists($p)) continue; $ret = @`$p -m 3 -k https://www.paypal.com/`; if (($ret != '') && preg_match('|$v) $vars[$varname][$k] = "'" . $v . "'"; $vars['@DB_PLUGINS@'] = join(',', (array)$vars['@DB_PLUGINS@']); $vars['@PAYMENT_PLUGINS@'] = join(',', (array)$vars['@PAYMENT_PLUGINS@']); $vars['@PROTECT_PLUGINS@'] = join(',', (array)$vars['@PROTECT_PLUGINS@']); srand(time()); $vars['@ADMIN_PASS@'] = crypt($vars['@ADMIN_PASS@']); $f = file($fn = "$root_dir/config-dist.inc.php"); if (!$f) display_errors(array("Cannot open $fn . Please upload this file")); $f1 = array(); foreach ($f as $k1=>$v1) { foreach ($vars as $k=>$v) $v1 = str_replace($k, $v, $v1); $f1[] = $v1; } $f2 = array(); return array(join('', $f1), join('', $f2)); } function email_templates_created($prefix){ $q = mysql_query($s = "SELECT COUNT(email_template_id) FROM {$prefix}email_templates"); if (mysql_errno()) return false; $r = mysql_fetch_row($q); return $r[0] > 0; } function display_send_files_form($error_filename){ display_header("Could not save config file"); $hidden = get_hidden_vars(); global $root_dir; $files = get_config_files(); $conf = htmlentities($files[0]); print <<Installation script is unable to save file $error_filename.
    For complete setup you may download new config files to your computer and upload it back to your server.

    File config.inc.php. Upload it to your FTP:
    $root_dir/config.inc.php

    $hidden

    Internet Expolorer sometimes rename
    files when save it. For example, it may rename config.inc.php
    to config[1].inc.php. Don't forget to fix it before uploading!

    Or, alternatively, you may copy&paste this text to amember/config.inc.php file.

    Copy to clipboard


    When the file is copied or created, click this link to continue.





    CUT; display_footer(); } function send_config_file(){ global $_POST; $file = $_POST['file']; $files = get_config_files(); $filename = 'config.inc.php'; header("Content-Disposition: attachment; filename=\"$filename\""); header("Content-Type: application/php"); print $files[$file]; exit(); } function commit_changes(){ global $root_dir; $vars = $_POST; create_mysql_tables(); list($f1, $f2) = get_config_files(); /// $fp = @fopen($fn = "$root_dir/config.inc.php", 'wb'); if (!$fp){ display_send_files_form($fn); return; } fwrite($fp, $f1); fclose($fp); $HTTP_HOST = $_SERVER['HTTP_HOST']; $REQUEST_URI = $_SERVER['REQUEST_URI']; header(sprintf("Location: http://%s%s?step=5", $HTTP_HOST, $REQUEST_URI)); exit(); } function display_thanks(){ print "

    Thank you for choosing aMember Pro. You can find the aMember Pro User's Guide here.
    Feel free to contact CGI-Central any time if you have any issues with the script.

    Please review the following:
    (You may want to bookmark this page)

  • Admin page (aMember Control Panel)
  • Signup page
  • Registered Member page
  • Login page (redirect to protected area)


  • Before aMember is ready to use you will also need to do the following:

  • Go to the Admin page and Login. From the Main Menu on the left select Utilities>Setup/Configuration These settings may be used to tune your installation. Enable any additional payment plugins that you need, then visit the plugins configuration section and enter your settings.

  • Go to the Admin page and add your products or subscription types.

    You may prefer to refer to them as 'Products' or 'Subscription Types' depending upon the type of business you are in. For example, you might choose to refer to a newsletter as a 'Subscription,' while you might call computer software or hardware a 'Product.' It's up to you what you choose to call these aMember database records.

    Remember, a 'Product' or 'Subscription Type' is just a different way to refer to the same thing, which is an aMember database record.

    You may specify the Subscription Type (free or paid signup, etc.) as you enter each product.

    It is important to set up at least one product!


  • Determine whether or not your payment system(s) require any special configuration. If so then you can refer to the Installation Manual for more information, or contact CGI-Central for script customization services.

  • Setup your protection for protected areas. You can use .htaccess or PHP included files. To use the Cookie-Based login capability all of your protected files must be PHP!

  • Check your installation by testing your
    Signup Page.

  • Once you have everything set up and working correctly then you may wish to customize some of the HTML templates. You should at least consider customizing the following templates:

    header.html
    footer.html
    thanks.html
    sendpass.txt
    signup_mail.txt

    You can read more about templates customization here. Tip: 90% of aMember's look and feel can be customized by editing the CSS stylesheet in the file amember/templates/css/site.css.

  • Feel free to contact CGI-Central Support if you need any customization of the script.

    You can also find a lot of useful info in the aMember Forum.

    "; } //////////////////////// main ////////////////////////////////////////////// $root_dir = dirname(__FILE__); $step = intval($_POST['step']); if (!$step) $step = intval($_GET['step']); if ($step != 5) check_for_existance(); while (1){ switch ($step){ case 0: case '0': display_header("aMember Setup: Step ".($step+1)." of 4"); check_for_writeable(); display_main_config(); break; case 1: case '1': display_header("aMember Setup: Step ".($step+1)." of 4"); check_main_config(); display_mysql_form(); break; case 2: case '2': display_header("aMember Setup: Step ".($step+1)." of 4"); check_mysql_form($db_installed); if ($db_installed) { $step = 3; display_plugins_form(); break;} display_db_install_query(); break; case 3: case '3': commit_changes(); break; case 5: case '5': display_header("aMember Setup: Step ".($step-1)." of 4"); display_thanks(); break; case 9: case '9': send_config_file(); break; } break; } display_footer(); amember/signup.php0000644774276600352300000003722011573171462020226 0ustar nf.mortgageoriginatorseminarswww"]/', $vars['name_f'])){ $error[] = _SIGNUP_PLEASE_ENTER_FNAME; } if (!strlen($vars['name_l'])){ $error[] = _SIGNUP_PLEASE_ENTER_LNAME; } if (preg_match('/[<>"]/', $vars['name_l'])){ $error[] = _SIGNUP_PLEASE_ENTER_LNAME; } $preg = getLoginRegex(); if (!preg_match($preg, $vars['login'])){ $error[] = $config['login_disallow_spaces'] ? _SIGNUP_INVALID_USERNAME_W_SPACES : _SIGNUP_INVALID_USERNAME; } elseif (strlen($vars['login']) < $config['login_min_length']){ $error[] = sprintf(_SIGNUP_INVALID_USERNAME_2,$config['login_min_length']); } elseif (!$member_id=$db->check_uniq_login($vars['login'], $vars['email'], $vars['pass0'], 1)){ $error[] = sprintf(_SIGNUP_INVALID_USERNAME_3,$vars[login]); } if (!check_email($vars['email'])){ $error[] = _SIGNUP_PLEASE_ENTER_EMAIL; } elseif (($config['unique_email'] && $member_id <= 0) && $db->users_find_by_string($vars['email'], 'email', 1)){ $error[] = _SIGNUP_INVALID_EMAIL_1.'
    '.sprintf(_SIGNUP_INVALID_EMAIL_2,'','','
    '); } if (!strlen($vars['pass0'])){ $error[] = _SIGNUP_PLEASE_ENTER_PSWD; } elseif (strlen($vars['pass0']) < $config['pass_min_length']){ $ll = $config[pass_min_length]; $error[] = sprintf(_SIGNUP_INVALID_PASS_1,$ll); } if ($vars['pass0'] != $vars['pass1']){ $error[] = _SIGNUP_INVALID_PASS_2; } if (($vars['coupon']!='') && $config['use_coupons']){ $coupon = $db->coupon_get($vars['coupon']); if (is_string($coupon)) $error[] = $coupon; } $error = array_merge($error, plugin_validate_signup_form($vars)); return !count($error); } ############################################################################### # SHOW_PAYMENT_FORM # # get vars from database and plugins # display $GLOBAL[error] if it set # substitute previous entered parameters using Smarty # function show_payment_form(){ global $t; global $error; global $db, $config, $vars; global $signup_scope_allowed; $t->assign('error', $error); $products = $db->get_products_list(); if (!count($products)){ fatal_error(_SIGNUP_SCRIPT_ERROR); } foreach ($products as $k=>$v){ if (!in_array($v['scope'], $signup_scope_allowed)) unset($products[$k]); if(is_array($vars['price_group'])){ if(!array_intersect($vars['price_group'], split(',',$v['price_group']))) unset($products[$k]); }elseif ($vars['price_group']){ if (!in_array($vars['price_group'], split(',',$v['price_group'])) ) unset($products[$k]); } elseif ($v['price_group'] < 0){ unset($products[$k]); } if ($products[$k] && ($products[$k]['terms'] == '')){ $pr = & new Product($products[$k]); $products[$k]['terms'] = $pr->getSubscriptionTerms(); } } $paysystems = get_paysystems_list(); //remove paysystems such as manual foreach ($paysystems as $k=>$p) if (!$p['public']) unset($paysystems[$k]); //remove free paysystem from select if (count($paysystems) > 1) foreach ($paysystems as $k=>$p) if ($p['paysys_id'] == 'free') unset($paysystems[$k]); plugin_fill_in_signup_form($_REQUEST); plugin_fill_in_signup_form($vars); // Fill additional fields $t->assign('products', $products); $t->assign('paysystems', $paysystems); $price_group = $vars['price_group'] ? explode(',', $vars['price_group']) : array(); $t->assign('additional_fields_html', get_additional_fields_html($vars, 'signup', 0, $price_group)); if ($vars['country']) $t->assign('state_options', db_getStatesForCountry($vars['country'], 1)); $is_affiliate = '0'; $newsletter_threads = $db->get_signup_threads_c($is_affiliate); $t->assign('newsletter_threads', $newsletter_threads); $t->display($config['amember_signup_template'] ? $config['amember_signup_template'] : 'signup.html'); } function proceed_to_payment($payment_id, $member_id_exists){ global $config, $db; $payment = $db->get_payment($payment_id); if (!$payment['payment_id']) fatal_error(sprintf(_SIGNUP_PAYMENT_NOT_FOUND,$payment_id), 1); if ($payment['completed']) fatal_error(sprintf(_SIGNUP_PAYMENT_COMPLETED,$payment_id).""._SIGNUP_PAYMENT_COMPLETED_1."", 1,1); extract($payment, EXTR_OVERWRITE); if ($pr = $payment['data'][0]['BASKET_PRODUCTS']) $product_id = $pr; global $error; $error = plugin_do_payment($paysys_id, $payment_id, $member_id, is_array($product_id) ? $product_id[0] : $product_id, $amount, $begin_date, $expire_date, $vars); if ($error) { $db->delete_payment($payment_id); if (!$member_id_exists) $db->delete_user($member_id); show_payment_form(); } } ############################################################################### ## ## M A I N ## ############################################################################### unset($GLOBALS['_trial_days']); // trial handling $t = & new_smarty(); $error = ''; $vars = & get_input_vars(); plugin_display_signup_form($vars); $error = array(); unset($member_id); $coupon = null; if (!empty($vars['product_id'])) $vars['product_id'] = is_array($vars['product_id']) ? array_filter(array_map('intval',$vars['product_id'])) : intval($vars['product_id']); if ($vars['cs']){ list ($payment_id, $code) = explode ("-", $vars['cs']); $payment = $db->get_payment($payment_id); if (!$payment['payment_id']) fatal_error(_SIGNUP_INCORRECT_LINK, 1); $member_id = $payment['member_id']; $email_confirm_code = $payment['data']['email_confirm']['code']; $email_confirm_time = $payment['data']['email_confirm']['time']; $member_id_exists = $payment['data']['email_confirm']['member_id_exists']; // extract all variables from payment to signup $vars['member_id'] = $member_id; $vars['payment_id'] = $payment_id; $vars['member_id_exists'] = $member_id_exists; $u = $db->get_user($member_id); if (time() - $email_confirm_time > 10 * 24 * 60 * 60) // check that 'time' saved in record is not older than 10 days (to avoid code guessing) fatal_error(_SIGNUP_INCORRECT_LINK, 1); if (!$u['member_id']) fatal_error(_SIGNUP_INCORRECT_LINK, 1); if ($email_confirm_code != $code) fatal_error(_SIGNUP_INCORRECT_LINK, 1); $u['email_verified'] = 1; $db->update_user($member_id, $u); if ($config['auto_login_after_signup']){ $_SESSION['_amember_login'] = $u['login']; $_SESSION['_amember_pass'] = $u['pass']; } proceed_to_payment($payment_id, $member_id_exists); exit(); } // verificate CAPTCHA if (($vars['do_payment'] || $vars['do_agreement']) && $config['use_captcha_signup'] && !$_SESSION['amember_captcha_verified']){ if (($vars['captcha'] != '') && (strtolower($vars['captcha']) == $_SESSION['amember_captcha'])){ $_SESSION['amember_captcha_verified'] = true; } else { $error[] = _SIGNUP_CAPTCHA_ERROR; } } if ($vars['do_agreement']){ if (!$vars['i_agree']){ $error[] = _SIGNUP_USER_AGREEMENT; display_agreement($vars['data']); exit(); } $vars = unserialize($vars['data']); $vars['i_agree']++; foreach ($vars as $k=>$v) $t->_smarty_vars['request'][$k] = $v; } ///// if ($vars['do_payment']){ $vars['aff_id'] = $_COOKIE['amember_aff_id']; if (!$config['login_dont_lowercase']) $vars['login'] = strtolower($vars['login']); if ($config['generate_login']) $vars['login'] = generate_login($vars); if ($config['generate_pass']) $vars['pass'] = $vars['pass0'] = $vars['pass1'] = generate_password($vars); if ($vars['product_id']){ $pc = & new PriceCalculator(); $pc->addProducts($vars['product_id']); if ($config['use_coupons'] && $vars['coupon'] != ''){ $coupon = $db->coupon_get($vars['coupon']); if ($coupon['coupon_id']) $pc->setCouponDiscount($coupon['discount'], split(',',trim($coupon['product_id']))); } $pc->setPriceFieldsByPaysys($vars['paysys_id']); $pc->setTax(get_member_tax(null)); $terms = & $pc->calculate(); $price = $terms->total; if ($config['product_paysystem']){ $pr = get_product(is_array($vars['product_id'])?$vars['product_id'][0]:$vars['product_id']); $vars['paysys_id'] = $pr->config['paysys_id']; } if (!$price && !product_get_trial($vars['product_id']) && (($terms->discount > 0 && !$coupon['is_recurring']) || !$terms->discount) && in_array('free', $plugins['payment'])) $vars['paysys_id'] = 'free'; } } if (($vars['do_payment'] && check_payment_form())){ //check for agreement $display_agreement = 0; foreach ((array)$vars['product_id'] as $pid){ $product = $db->get_product($pid); if ($product['need_agreement']) $display_agreement++; } if ($display_agreement && !$vars['i_agree']){ display_agreement(serialize($vars)); // defined in the product.inc.php exit(); } // do payment ! $product_id = $vars['product_id']; if (!is_array($product_id)) $product_id = array($product_id); $login = $vars['login']; $paysys_id = $vars['paysys_id']; do { // to easy exit using break() foreach ((array)$vars['product_id'] as $pid){ $product = $db->get_product($pid); if (!in_array($product['scope'], $signup_scope_allowed)){ $error = _SIGNUP_INCORRECT_PRODID; break; } ////////////// check products scope } if ($error = check_product_requirements((array)$vars['product_id'])) break; $member_id = $db->check_uniq_login($vars['login'], $vars['email'], $vars['pass0'], 1); $member_id_exists = 0; if ($config['verify_email']) $vars['email_verified'] = -1; if ($GLOBALS['_LANG_SELECTED'] != get_default_lang()){ $vars['selected_lang'] = $GLOBALS['_LANG_SELECTED']; } if ($member_id < 0) { $member_id = $db->add_pending_user($vars); $is_affiliate = '0'; //only member if ($db->get_signup_threads_c($is_affiliate) && $vars['to_subscribe']) $db->subscribe_member ($member_id, $is_affiliate); } elseif (!$member_id) die(_SIGNUP_LOGIN_EXISTS); else { $member_id_exists++; //we found existing user with the same params // then will clean CC parameters if any if ($db->get_user_payments($member_id,1)) { $error[] = sprintf(_SIGNUP_INVALID_USERNAME_3,$vars[login]); } else { $member = $db->get_user($member_id); $member['data']['cc-hidden']=''; $member['data']['cc-expire']=''; $member['data']['cc']=''; $member['data']['cc_street']=''; $member['data']['cc_city']=''; $member['data']['cc_state']=''; $member['data']['cc_zip']=''; $member['data']['cc_country']=''; foreach ($vars as $k=>$v) $member[$k] = $v; $db->update_user($member_id, $member); } } if ($error) { break; } $pc = & new PriceCalculator(); $pc->addProducts($vars['product_id']); if ($config['use_coupons'] && $vars['coupon'] != ''){ $coupon = $db->coupon_get($vars['coupon']); if ($coupon['coupon_id']) $pc->setCouponDiscount($coupon['discount'], split(',',trim($coupon['product_id']))); } $pc->setPriceFieldsByPaysys($vars['paysys_id']); $pc->setTax(get_member_tax($member_id)); $terms = & $pc->calculate(); $price = $terms->total; // if ($terms->discount > 0) $vars['COUPON_CODE'] = $vars['coupon']; $additional_values = array(); foreach ($payment_additional_fields as $f){ $fname = $f['name']; if (isset($vars[$fname])) $additional_values[$fname] = $vars[$fname]; } $additional_values['COUPON_DISCOUNT'] = $terms->discount; $additional_values['TAX_AMOUNT'] = $terms->tax; $taxes = $prices = array(); foreach ($terms->lines as $pid => $line){ $prices[$pid] = $line->total; if ($line->tax) $taxes[$pid] = $line->tax; } $additional_values['TAXES'] = $taxes; $product = & get_product($product_id[0]); $begin_date = $product->get_start(); $expire_date = $product->get_expire($begin_date, null, $terms); //yyyy-mm-dd // add payment $payment_id = $db->add_waiting_payments($member_id, $product_id, $paysys_id, $price, $prices, $begin_date, $expire_date, $vars, $additional_values); if ($error) { $db->delete_user($member_id); break; } $u = $db->get_user($member_id); if ($config['verify_email']){ global $db; $code = substr(uniqid(rand(), true), 0, 12); $payment = $db->get_payment($payment_id); $payment['data']['email_confirm'] = array('code' => $code, 'member_id_exists' => $member_id_exists, 'time' => time()); $db->update_payment($payment_id, $payment); mail_verification_email($u, $config['root_url'] . "/signup.php?cs=" . $payment_id . "-" . $code); $t->assign('user', $u); $t->assign('payment', $payment); $t->display("email_verify.html"); exit(); } if ($config['auto_login_after_signup']){ $_SESSION['_amember_login'] = $u['login']; $_SESSION['_amember_pass'] = $u['pass']; } unset($_SESSION['amember_captcha_verified']) ; proceed_to_payment($payment_id, $member_id_exists); exit(); } while (0); } show_payment_form(); ?> amember/site-dist.inc.php0000644774276600352300000000065511573171462021400 0ustar nf.mortgageoriginatorseminarswwwamember/sql-countries.sql0000644774276600352300000001562211573171462021543 0ustar nf.mortgageoriginatorseminarswwwINSERT INTO @DB_MYSQL_PREFIX@countries (country_id, country, title, tag) VALUES (1, 'US', 'United States', 10), (2, 'CA', 'Canada', 5), (3, 'AF', 'Afghanistan', 0), (4, 'AL', 'Albania', 0), (5, 'DZ', 'Algeria', 0), (6, 'AS', 'American Samoa', 0), (7, 'AD', 'Andorra', 0), (8, 'AO', 'Angola', 0), (9, 'AI', 'Anguilla', 0), (10, 'AQ', 'Antarctica', 0), (11, 'AG', 'Antigua and Barbuda', 0), (12, 'AR', 'Argentina', 0), (13, 'AM', 'Armenia', 0), (14, 'AW', 'Aruba', 0), (15, 'AU', 'Australia', 0), (16, 'AT', 'Austria', 0), (17, 'AZ', 'Azerbaijan', 0), (18, 'BS', 'Bahamas', 0), (19, 'BH', 'Bahrain', 0), (20, 'BD', 'Bangladesh', 0), (21, 'BB', 'Barbados', 0), (22, 'BY', 'Belarus', 0), (23, 'BE', 'Belgium', 0), (24, 'BZ', 'Belize', 0), (25, 'BJ', 'Benin', 0), (26, 'BM', 'Bermuda', 0), (27, 'BT', 'Bhutan', 0), (28, 'BO', 'Bolivia', 0), (29, 'BA', 'Bosnia and Herzegovina', 0), (30, 'BW', 'Botswana', 0), (31, 'BV', 'Bouvet Island', 0), (32, 'BR', 'Brazil', 0), (33, 'IO', 'British Indian Ocean Territory', 0), (34, 'BN', 'Brunei', 0), (35, 'BG', 'Bulgaria', 0), (36, 'BF', 'Burkina Faso', 0), (37, 'BI', 'Burundi', 0), (38, 'KH', 'Cambodia', 0), (39, 'CM', 'Cameroon', 0), (40, 'CV', 'Cape Verde', 0), (41, 'KY', 'Cayman Islands', 0), (42, 'CF', 'Central African Republic', 0), (43, 'TD', 'Chad', 0), (44, 'CL', 'Chile', 0), (45, 'CN', 'China', 0), (46, 'CX', 'Christmas Island', 0), (47, 'CC', 'Cocos (Keeling) Islands', 0), (48, 'CO', 'Colombia', 0), (49, 'KM', 'Comoros', 0), (50, 'CG', 'Congo', 0), (51, 'CK', 'Cook Islands', 0), (52, 'CR', 'Costa Rica', 0), (53, 'CI', 'Cote d''Ivoire', 0), (54, 'HR', 'Croatia (Hrvatska)', 0), (55, 'CU', 'Cuba', 0), (56, 'CY', 'Cyprus', 0), (57, 'CZ', 'Czech Republic', 0), (58, 'CD', 'Congo (DRC)', 0), (59, 'DK', 'Denmark', 0), (60, 'DJ', 'Djibouti', 0), (61, 'DM', 'Dominica', 0), (62, 'DO', 'Dominican Republic', 0), (63, 'TP', 'East Timor', 0), (64, 'EC', 'Ecuador', 0), (65, 'EG', 'Egypt', 0), (66, 'SV', 'El Salvador', 0), (67, 'GQ', 'Equatorial Guinea', 0), (68, 'ER', 'Eritrea', 0), (69, 'EE', 'Estonia', 0), (70, 'ET', 'Ethiopia', 0), (71, 'FK', 'Falkland Islands (Islas Malvinas)', 0), (72, 'FO', 'Faroe Islands', 0), (73, 'FJ', 'Fiji Islands', 0), (74, 'FI', 'Finland', 0), (75, 'FR', 'France', 0), (76, 'GF', 'French Guiana', 0), (77, 'PF', 'French Polynesia', 0), (78, 'TF', 'French Southern and Antarctic Lands', 0), (79, 'GA', 'Gabon', 0), (80, 'GM', 'Gambia', 0), (81, 'GE', 'Georgia', 0), (82, 'DE', 'Germany', 0), (83, 'GH', 'Ghana', 0), (84, 'GI', 'Gibraltar', 0), (85, 'GR', 'Greece', 0), (86, 'GL', 'Greenland', 0), (87, 'GD', 'Grenada', 0), (88, 'GP', 'Guadeloupe', 0), (89, 'GU', 'Guam', 0), (90, 'GT', 'Guatemala', 0), (91, 'GN', 'Guinea', 0), (92, 'GW', 'Guinea-Bissau', 0), (93, 'GY', 'Guyana', 0), (94, 'HT', 'Haiti', 0), (95, 'HM', 'Heard Island and McDonald Islands', 0), (96, 'HN', 'Honduras', 0), (97, 'HK', 'Hong Kong SAR', 0), (98, 'HU', 'Hungary', 0), (99, 'IS', 'Iceland', 0), (100, 'IN', 'India', 0), (101, 'ID', 'Indonesia', 0), (102, 'IR', 'Iran', 0), (103, 'IQ', 'Iraq', 0), (104, 'IE', 'Ireland', 0), (105, 'IL', 'Israel', 0), (106, 'IT', 'Italy', 0), (107, 'JM', 'Jamaica', 0), (108, 'JP', 'Japan', 0), (109, 'JO', 'Jordan', 0), (110, 'KZ', 'Kazakhstan', 0), (111, 'KE', 'Kenya', 0), (112, 'KI', 'Kiribati', 0), (113, 'KR', 'Korea', 0), (114, 'KW', 'Kuwait', 0), (115, 'KG', 'Kyrgyzstan', 0), (116, 'LA', 'Laos', 0), (117, 'LV', 'Latvia', 0), (118, 'LB', 'Lebanon', 0), (119, 'LS', 'Lesotho', 0), (120, 'LR', 'Liberia', 0), (121, 'LY', 'Libya', 0), (122, 'LI', 'Liechtenstein', 0), (123, 'LT', 'Lithuania', 0), (124, 'LU', 'Luxembourg', 0), (125, 'MO', 'Macao SAR', 0), (126, 'MK', 'Macedonia', 0), (127, 'MG', 'Madagascar', 0), (128, 'MW', 'Malawi', 0), (129, 'MY', 'Malaysia', 0), (130, 'MV', 'Maldives', 0), (131, 'ML', 'Mali', 0), (132, 'MT', 'Malta', 0), (133, 'MH', 'Marshall Islands', 0), (134, 'MQ', 'Martinique', 0), (135, 'MR', 'Mauritania', 0), (136, 'MU', 'Mauritius', 0), (137, 'YT', 'Mayotte', 0), (138, 'MX', 'Mexico', 0), (139, 'FM', 'Micronesia', 0), (140, 'MD', 'Moldova', 0), (141, 'MC', 'Monaco', 0), (142, 'MN', 'Mongolia', 0), (143, 'MS', 'Montserrat', 0), (144, 'MA', 'Morocco', 0), (145, 'MZ', 'Mozambique', 0), (146, 'MM', 'Myanmar', 0), (147, 'NA', 'Namibia', 0), (148, 'NR', 'Nauru', 0), (149, 'NP', 'Nepal', 0), (150, 'NL', 'Netherlands', 0), (151, 'AN', 'Netherlands Antilles', 0), (152, 'NC', 'New Caledonia', 0), (153, 'NZ', 'New Zealand', 0), (154, 'NI', 'Nicaragua', 0), (155, 'NE', 'Niger', 0), (156, 'NG', 'Nigeria', 0), (157, 'NU', 'Niue', 0), (158, 'NF', 'Norfolk Island', 0), (159, 'KP', 'North Korea', 0), (160, 'MP', 'Northern Mariana Islands', 0), (161, 'NO', 'Norway', 0), (162, 'OM', 'Oman', 0), (163, 'PK', 'Pakistan', 0), (164, 'PW', 'Palau', 0), (165, 'PA', 'Panama', 0), (166, 'PG', 'Papua New Guinea', 0), (167, 'PY', 'Paraguay', 0), (168, 'PE', 'Peru', 0), (169, 'PH', 'Philippines', 0), (170, 'PN', 'Pitcairn Islands', 0), (171, 'PL', 'Poland', 0), (172, 'PT', 'Portugal', 0), (173, 'PR', 'Puerto Rico', 0), (174, 'QA', 'Qatar', 0), (175, 'RE', 'Reunion', 0), (176, 'RO', 'Romania', 0), (177, 'RU', 'Russia', 0), (178, 'RW', 'Rwanda', 0), (179, 'WS', 'Samoa', 0), (180, 'SM', 'San Marino', 0), (181, 'ST', 'Sao Tome and Principe', 0), (182, 'SA', 'Saudi Arabia', 0), (183, 'SN', 'Senegal', 0), (184, 'YU', 'Serbia and Montenegro', 0), (185, 'SC', 'Seychelles', 0), (186, 'SL', 'Sierra Leone', 0), (187, 'SG', 'Singapore', 0), (188, 'SK', 'Slovakia', 0), (189, 'SI', 'Slovenia', 0), (190, 'SB', 'Solomon Islands', 0), (191, 'SO', 'Somalia', 0), (192, 'ZA', 'South Africa', 0), (193, 'GS', 'South Georgia and the South Sandwich Islands', 0), (194, 'ES', 'Spain', 0), (195, 'LK', 'Sri Lanka', 0), (196, 'SH', 'St. Helena', 0), (197, 'KN', 'St. Kitts and Nevis', 0), (198, 'LC', 'St. Lucia', 0), (199, 'PM', 'St. Pierre and Miquelon', 0), (200, 'VC', 'St. Vincent and the Grenadines', 0), (201, 'SD', 'Sudan', 0), (202, 'SR', 'Suriname', 0), (203, 'SJ', 'Svalbard and Jan Mayen', 0), (204, 'SZ', 'Swaziland', 0), (205, 'SE', 'Sweden', 0), (206, 'CH', 'Switzerland', 0), (207, 'SY', 'Syria', 0), (208, 'TW', 'Taiwan', 0), (209, 'TJ', 'Tajikistan', 0), (210, 'TZ', 'Tanzania', 0), (211, 'TH', 'Thailand', 0), (212, 'TG', 'Togo', 0), (213, 'TK', 'Tokelau', 0), (214, 'TO', 'Tonga', 0), (215, 'TT', 'Trinidad and Tobago', 0), (216, 'TN', 'Tunisia', 0), (217, 'TR', 'Turkey', 0), (218, 'TM', 'Turkmenistan', 0), (219, 'TC', 'Turks and Caicos Islands', 0), (220, 'TV', 'Tuvalu', 0), (221, 'UG', 'Uganda', 0), (222, 'UA', 'Ukraine', 0), (223, 'AE', 'United Arab Emirates', 0), (224, 'GB', 'United Kingdom', 0), (225, 'UM', 'United States Minor Outlying Islands', 0), (226, 'UY', 'Uruguay', 0), (227, 'UZ', 'Uzbekistan', 0), (228, 'VU', 'Vanuatu', 0), (229, 'VA', 'Vatican City', 0), (230, 'VE', 'Venezuela', 0), (231, 'VN', 'Viet Nam', 0), (232, 'VG', 'Virgin Islands (British)', 0), (233, 'VI', 'Virgin Islands', 0), (234, 'WF', 'Wallis and Futuna', 0), (235, 'YE', 'Yemen', 0), (236, 'ZM', 'Zambia', 0), (237, 'ZW', 'Zimbabwe', 0); amember/sql-states.sql0000644774276600352300000036202611573171464021040 0ustar nf.mortgageoriginatorseminarswwwINSERT INTO @DB_MYSQL_PREFIX@states (state, country, title) VALUES ('AD-ALV', 'AD', 'Andorra la Vella'), ('AD-CAN', 'AD', 'Canillo'), ('AD-ENC', 'AD', 'Encamp'), ('AD-ESE', 'AD', 'Escaldes-Engordany'), ('AD-LMA', 'AD', 'La Massana'), ('AD-ORD', 'AD', 'Ordino'), ('AD-SJL', 'AD', 'Sant Julia de LOA'), ('AE-AJ', 'AE', '''Ajman'), ('AE-AZ', 'AE', 'Abu Zaby'), ('AE-DU', 'AE', 'Dubayy'), ('AE-FU', 'AE', 'Al Fujayrah'), ('AE-RK', 'AE', 'R''as al Khaymah'), ('AE-SH', 'AE', 'Ash Shariqah'), ('AE-UQ', 'AE', 'Umm al Qaywayn'), ('AF-BAL', 'AF', 'Balkh province'), ('AF-BAM', 'AF', 'Bamian province'), ('AF-BDG', 'AF', 'Badghis province'), ('AF-BDS', 'AF', 'Badakhshan province'), ('AF-BGL', 'AF', 'Baghlan province'), ('AF-FRA', 'AF', 'Farah province'), ('AF-FYB', 'AF', 'Faryab province'), ('AF-GHA', 'AF', 'Ghazni province'), ('AF-GHO', 'AF', 'Ghowr province'), ('AF-HEL', 'AF', 'Helmand province'), ('AF-HER', 'AF', 'Herat province'), ('AF-JOW', 'AF', 'Jowzjan province'), ('AF-KAB', 'AF', 'Kabul province'), ('AF-KAN', 'AF', 'Kandahar province'), ('AF-KAP', 'AF', 'Kapisa province'), ('AF-KDZ', 'AF', 'Kondoz province'), ('AF-KHO', 'AF', 'Khost province'), ('AF-KNR', 'AF', 'Konar province'), ('AF-LAG', 'AF', 'Laghman province'), ('AF-LOW', 'AF', 'Lowgar province'), ('AF-NAN', 'AF', 'Nangrahar province'), ('AF-NIM', 'AF', 'Nimruz province'), ('AF-NUR', 'AF', 'Nurestan province'), ('AF-ORU', 'AF', 'Oruzgan province'), ('AF-PAR', 'AF', 'Parwan province'), ('AF-PIA', 'AF', 'Paktia province'), ('AF-PKA', 'AF', 'Paktika province'), ('AF-SAM', 'AF', 'Samangan province'), ('AF-SAR', 'AF', 'Sar-e Pol province'), ('AF-TAK', 'AF', 'Takhar province'), ('AF-WAR', 'AF', 'Wardak province'), ('AF-ZAB', 'AF', 'Zabol province'), ('AG-ASG', 'AG', 'Saint George'), ('AG-ASH', 'AG', 'Saint Philip'), ('AG-ASJ', 'AG', 'Saint John'), ('AG-ASL', 'AG', 'Saint Paul'), ('AG-ASM', 'AG', 'Saint Mary'), ('AG-ASR', 'AG', 'Saint Peter'), ('AG-BAR', 'AG', 'Barbuda'), ('AG-RED', 'AG', 'Redonda'), ('AL-BR', 'AL', 'Berat'), ('AL-BU', 'AL', 'Bulqize'), ('AL-DI', 'AL', 'Diber'), ('AL-DL', 'AL', 'Delvine'), ('AL-DR', 'AL', 'Durres'), ('AL-DV', 'AL', 'Devoll'), ('AL-EL', 'AL', 'Elbasan'), ('AL-ER', 'AL', 'Kolonje'), ('AL-FR', 'AL', 'Fier'), ('AL-GJ', 'AL', 'Gjirokaster'), ('AL-GR', 'AL', 'Gramsh'), ('AL-HA', 'AL', 'Has'), ('AL-KA', 'AL', 'Kavaje'), ('AL-KB', 'AL', 'Kurbin'), ('AL-KC', 'AL', 'Kucove'), ('AL-KO', 'AL', 'Korce'), ('AL-KR', 'AL', 'Kruje'), ('AL-KU', 'AL', 'Kukes'), ('AL-LB', 'AL', 'Librazhd'), ('AL-LE', 'AL', 'Lezhe'), ('AL-LU', 'AL', 'Lushnje'), ('AL-MK', 'AL', 'Mallakaster'), ('AL-MM', 'AL', 'Malesi e Madhe'), ('AL-MR', 'AL', 'Mirdite'), ('AL-MT', 'AL', 'Mat'), ('AL-PG', 'AL', 'Pogradec'), ('AL-PQ', 'AL', 'Peqin'), ('AL-PR', 'AL', 'Permet'), ('AL-PU', 'AL', 'Puke'), ('AL-SH', 'AL', 'Shkoder'), ('AL-SK', 'AL', 'Skrapar'), ('AL-SR', 'AL', 'Sarande'), ('AL-TE', 'AL', 'Tepelene'), ('AL-TP', 'AL', 'Tropoje'), ('AL-TR', 'AL', 'Tirane'), ('AL-VL', 'AL', 'Vlore'), ('AM-AGT', 'AM', 'Aragatsotn'), ('AM-ARM', 'AM', 'Armavir'), ('AM-ARR', 'AM', 'Ararat'), ('AM-GEG', 'AM', 'Geghark''unik'''), ('AM-KOT', 'AM', 'Kotayk'''), ('AM-LOR', 'AM', 'Lorri'), ('AM-SHI', 'AM', 'Shirak'), ('AM-SYU', 'AM', 'Syunik'''), ('AM-TAV', 'AM', 'Tavush'), ('AM-VAY', 'AM', 'Vayots'' Dzor'), ('AM-YER', 'AM', 'Yerevan'), ('AO-BGO', 'AO', 'Bengo'), ('AO-BGU', 'AO', 'Benguela province'), ('AO-BIE', 'AO', 'Bie'), ('AO-CAB', 'AO', 'Cabinda'), ('AO-CCU', 'AO', 'Cuando-Cubango'), ('AO-CNN', 'AO', 'Cunene'), ('AO-CNO', 'AO', 'Cuanza Norte'), ('AO-CUS', 'AO', 'Cuanza Sul'), ('AO-HUA', 'AO', 'Huambo province'), ('AO-HUI', 'AO', 'Huila province'), ('AO-LNO', 'AO', 'Lunda Norte'), ('AO-LSU', 'AO', 'Lunda Sul'), ('AO-LUA', 'AO', 'Luanda'), ('AO-MAL', 'AO', 'Malange'), ('AO-MOX', 'AO', 'Moxico'), ('AO-NAM', 'AO', 'Namibe'), ('AO-UIG', 'AO', 'Uige'), ('AO-ZAI', 'AO', 'Zaire'), ('AR-A', 'AR', 'Salta'), ('AR-B', 'AR', 'Buenos Aires Province'), ('AR-C', 'AR', 'Distrito Federal'), ('AR-D', 'AR', 'San Luis'), ('AR-E', 'AR', 'Entre Rios'), ('AR-F', 'AR', 'La Rioja'), ('AR-G', 'AR', 'Santiago del Estero'), ('AR-H', 'AR', 'Chaco'), ('AR-J', 'AR', 'San Juan'), ('AR-K', 'AR', 'Catamarca'), ('AR-L', 'AR', 'La Pampa'), ('AR-M', 'AR', 'Mendoza'), ('AR-N', 'AR', 'Misiones'), ('AR-P', 'AR', 'Formosa'), ('AR-Q', 'AR', 'Neuquen'), ('AR-R', 'AR', 'Rio Negro'), ('AR-S', 'AR', 'Santa Fe'), ('AR-T', 'AR', 'Tucuman'), ('AR-U', 'AR', 'Chubut'), ('AR-V', 'AR', 'Tierra del Fuego'), ('AR-W', 'AR', 'Corrientes'), ('AR-X', 'AR', 'Cordoba'), ('AR-Y', 'AR', 'Jujuy'), ('AR-Z', 'AR', 'Santa Cruz'), ('AS-E', 'AS', 'Eastern'), ('AS-M', 'AS', 'Manu''a'), ('AS-R', 'AS', 'Rose Island'), ('AS-S', 'AS', 'Swains Island'), ('AS-W', 'AS', 'Western'), ('AT-BUR', 'AT', 'Burgenland'), ('AT-KAR', 'AT', 'Karnten'), ('AT-NOS', 'AT', 'Niederosterreich'), ('AT-OOS', 'AT', 'Oberosterreich'), ('AT-SAL', 'AT', 'Salzburg'), ('AT-STE', 'AT', 'Steiermark'), ('AT-TIR', 'AT', 'Tirol'), ('AT-VOR', 'AT', 'Vorarlberg'), ('AT-WIE', 'AT', 'Wien'), ('AU-ACT', 'AU', 'Australian Capital Territory'), ('AU-NSW', 'AU', 'New South Wales'), ('AU-NT', 'AU', 'Northern Territory'), ('AU-QLD', 'AU', 'Queensland'), ('AU-SA', 'AU', 'South Australia'), ('AU-TAS', 'AU', 'Tasmania'), ('AU-VIC', 'AU', 'Victoria'), ('AU-WA', 'AU', 'Western Australia'), ('AZ-AB', 'AZ', 'Ali Bayramli'), ('AZ-ABS', 'AZ', 'Abseron'), ('AZ-AGA', 'AZ', 'Agstafa'), ('AZ-AGC', 'AZ', 'AgcabAdi'), ('AZ-AGM', 'AZ', 'Agdam'), ('AZ-AGS', 'AZ', 'Agdas'), ('AZ-AGU', 'AZ', 'Agsu'), ('AZ-AST', 'AZ', 'Astara'), ('AZ-BA', 'AZ', 'Baki'), ('AZ-BAB', 'AZ', 'Babak'), ('AZ-BAL', 'AZ', 'Balakan'), ('AZ-BAR', 'AZ', 'Barda'), ('AZ-BEY', 'AZ', 'Beylaqan'), ('AZ-BIL', 'AZ', 'Bilasuvar'), ('AZ-CAB', 'AZ', 'Cabrayil'), ('AZ-CAL', 'AZ', 'Calilabab'), ('AZ-CUL', 'AZ', 'Culfa'), ('AZ-DAS', 'AZ', 'Daskasan'), ('AZ-DAV', 'AZ', 'Davaci'), ('AZ-FUZ', 'AZ', 'Fuzuli'), ('AZ-GA', 'AZ', 'Ganca'), ('AZ-GAD', 'AZ', 'Gadabay'), ('AZ-GOR', 'AZ', 'Goranboy'), ('AZ-GOY', 'AZ', 'Goycay'), ('AZ-HAC', 'AZ', 'Haciqabul'), ('AZ-IMI', 'AZ', 'Imisli'), ('AZ-ISM', 'AZ', 'Ismayilli'), ('AZ-KAL', 'AZ', 'Kalbacar'), ('AZ-KUR', 'AZ', 'Kurdamir'), ('AZ-LAC', 'AZ', 'Lacin'), ('AZ-LAN', 'AZ', 'Lankaran'), ('AZ-LER', 'AZ', 'Lerik'), ('AZ-MAS', 'AZ', 'Masalli'), ('AZ-MI', 'AZ', 'Mingacevir'), ('AZ-NA', 'AZ', 'Naftalan'), ('AZ-NEF', 'AZ', 'Neftcala'), ('AZ-NX', 'AZ', 'Naxcivan'), ('AZ-OGU', 'AZ', 'Oguz'), ('AZ-ORD', 'AZ', 'Ordubad'), ('AZ-QAB', 'AZ', 'Qabala'), ('AZ-QAX', 'AZ', 'Qax'), ('AZ-QAZ', 'AZ', 'Qazax'), ('AZ-QBA', 'AZ', 'Quba'), ('AZ-QBI', 'AZ', 'Qubadli'), ('AZ-QOB', 'AZ', 'Qobustan'), ('AZ-QUS', 'AZ', 'Qusar'), ('AZ-SA', 'AZ', 'Saki'), ('AZ-SAB', 'AZ', 'Sabirabad'), ('AZ-SAD', 'AZ', 'Sadarak'), ('AZ-SAH', 'AZ', 'Sahbuz'), ('AZ-SAK', 'AZ', 'Saki'), ('AZ-SAL', 'AZ', 'Salyan'), ('AZ-SAR', 'AZ', 'Sarur'), ('AZ-SAT', 'AZ', 'Saatli'), ('AZ-SIY', 'AZ', 'Siyazan'), ('AZ-SKR', 'AZ', 'Samkir'), ('AZ-SM', 'AZ', 'Sumqayit'), ('AZ-SMI', 'AZ', 'Samaxi'), ('AZ-SMX', 'AZ', 'Samux'), ('AZ-SS', 'AZ', 'Susa'), ('AZ-SUS', 'AZ', 'Susa'), ('AZ-TAR', 'AZ', 'Tartar'), ('AZ-TOV', 'AZ', 'Tovuz'), ('AZ-UCA', 'AZ', 'Ucar'), ('AZ-XA', 'AZ', 'Xankandi'), ('AZ-XAC', 'AZ', 'Xacmaz'), ('AZ-XAN', 'AZ', 'Xanlar'), ('AZ-XCI', 'AZ', 'Xocali'), ('AZ-XIZ', 'AZ', 'Xizi'), ('AZ-XVD', 'AZ', 'Xocavand'), ('AZ-YAR', 'AZ', 'Yardimli'), ('AZ-YEV', 'AZ', 'Yevlax'), ('AZ-ZAN', 'AZ', 'Zangilan'), ('AZ-ZAQ', 'AZ', 'Zaqatala'), ('AZ-ZAR', 'AZ', 'Zardab'), ('BA-BRO', 'BA', 'Brcko district'), ('BA-FBP', 'BA', 'Bosanskopodrinjski Kanton'), ('BA-FHN', 'BA', 'Hercegovacko-neretvanski Kanton'), ('BA-FPO', 'BA', 'Posavski Kanton'), ('BA-FSA', 'BA', 'Kanton Sarajevo'), ('BA-FSB', 'BA', 'Srednjebosanski Kanton'), ('BA-FTU', 'BA', 'Tuzlanski Kanton'), ('BA-FUS', 'BA', 'Unsko-Sanski Kanton'), ('BA-FZA', 'BA', 'Zapadnobosanska'), ('BA-FZE', 'BA', 'Zenicko-Dobojski Kanton'), ('BA-FZH', 'BA', 'Zapadnohercegovacka Zupanija'), ('BA-SBI', 'BA', 'Bijeljina'), ('BA-SBL', 'BA', 'Banja Luka'), ('BA-SDO', 'BA', 'Doboj'), ('BA-SFO', 'BA', 'Foca'), ('BA-SSR', 'BA', 'Sarajevo-Romanija or Sokolac'), ('BA-STR', 'BA', 'Trebinje'), ('BA-SVL', 'BA', 'Vlasenica'), ('BB-AND', 'BB', 'Saint Andrew'), ('BB-CC', 'BB', 'Christ Church'), ('BB-GEO', 'BB', 'Saint George'), ('BB-JAM', 'BB', 'Saint James'), ('BB-JOH', 'BB', 'Saint John'), ('BB-JOS', 'BB', 'Saint Joseph'), ('BB-LUC', 'BB', 'Saint Lucy'), ('BB-MIC', 'BB', 'Saint Michael'), ('BB-PET', 'BB', 'Saint Peter'), ('BB-PHI', 'BB', 'Saint Philip'), ('BB-THO', 'BB', 'Saint Thomas'), ('BD-BAR', 'BD', 'Barisal'), ('BD-CHI', 'BD', 'Chittagong'), ('BD-DHA', 'BD', 'Dhaka'), ('BD-KHU', 'BD', 'Khulna'), ('BD-RAJ', 'BD', 'Rajshahi'), ('BD-SYL', 'BD', 'Sylhet'), ('BE-VAN', 'BE', 'Antwerpen'), ('BE-VBR', 'BE', 'Vlaams Brabant'), ('BE-VLI', 'BE', 'Limburg'), ('BE-VOV', 'BE', 'Oost-Vlaanderen'), ('BE-VWV', 'BE', 'West-Vlaanderen'), ('BE-WBR', 'BE', 'Brabant Wallon'), ('BE-WHT', 'BE', 'Hainaut'), ('BE-WLG', 'BE', 'Liege'), ('BE-WLX', 'BE', 'Luxembourg'), ('BE-WNA', 'BE', 'Namur'), ('BF-BAL', 'BF', 'Bale'), ('BF-BAM', 'BF', 'Bam'), ('BF-BAN', 'BF', 'Banwa'), ('BF-BAZ', 'BF', 'Bazega'), ('BF-BLG', 'BF', 'Boulgou'), ('BF-BOK', 'BF', 'Boulkiemde'), ('BF-BOR', 'BF', 'Bougouriba'), ('BF-COM', 'BF', 'Comoe'), ('BF-GAN', 'BF', 'Ganzourgou'), ('BF-GNA', 'BF', 'Gnagna'), ('BF-GOU', 'BF', 'Gourma'), ('BF-HOU', 'BF', 'Houet'), ('BF-IOA', 'BF', 'Ioba'), ('BF-KAD', 'BF', 'Kadiogo'), ('BF-KEN', 'BF', 'Kenedougou'), ('BF-KOD', 'BF', 'Komondjari'), ('BF-KOL', 'BF', 'Koulpelogo'), ('BF-KOP', 'BF', 'Kompienga'), ('BF-KOS', 'BF', 'Kossi'), ('BF-KOT', 'BF', 'Kouritenga'), ('BF-KOW', 'BF', 'Kourweogo'), ('BF-LER', 'BF', 'Leraba'), ('BF-LOR', 'BF', 'Loroum'), ('BF-MOU', 'BF', 'Mouhoun'), ('BF-NAH', 'BF', 'Nahouri'), ('BF-NAM', 'BF', 'Namentenga'), ('BF-NAY', 'BF', 'Nayala'), ('BF-NOU', 'BF', 'Noumbiel'), ('BF-OUB', 'BF', 'Oubritenga'), ('BF-OUD', 'BF', 'Oudalan'), ('BF-PAS', 'BF', 'Passore'), ('BF-PON', 'BF', 'Poni'), ('BF-SAG', 'BF', 'Sanguie'), ('BF-SAM', 'BF', 'Sanmatenga'), ('BF-SEN', 'BF', 'Seno'), ('BF-SIS', 'BF', 'Sissili'), ('BF-SOM', 'BF', 'Soum'), ('BF-SOR', 'BF', 'Sourou'), ('BF-TAP', 'BF', 'Tapoa'), ('BF-TUY', 'BF', 'Tuy'), ('BF-YAG', 'BF', 'Yagha'), ('BF-YAT', 'BF', 'Yatenga'), ('BF-ZIR', 'BF', 'Ziro'), ('BF-ZOD', 'BF', 'Zondoma'), ('BF-ZOW', 'BF', 'Zoundweogo'), ('BG-01', 'BG', 'Blagoevgrad'), ('BG-02', 'BG', 'Burgas'), ('BG-03', 'BG', 'Varna'), ('BG-04', 'BG', 'Veliko Turnovo'), ('BG-05', 'BG', 'Vidin'), ('BG-06', 'BG', 'Vratsa'), ('BG-07', 'BG', 'Gabrovo'), ('BG-08', 'BG', 'Dobrich'), ('BG-09', 'BG', 'Kurdzhali'), ('BG-10', 'BG', 'Kyustendil'), ('BG-11', 'BG', 'Lovech'), ('BG-12', 'BG', 'Montana'), ('BG-13', 'BG', 'Pazardzhik'), ('BG-14', 'BG', 'Pernik'), ('BG-15', 'BG', 'Pleven'), ('BG-16', 'BG', 'Plovdiv'), ('BG-17', 'BG', 'Razgrad'), ('BG-18', 'BG', 'Ruse'), ('BG-19', 'BG', 'Silistra'), ('BG-20', 'BG', 'Sliven'), ('BG-21', 'BG', 'Smolyan'), ('BG-22', 'BG', 'Sofia Region'), ('BG-23', 'BG', 'Sofia'), ('BG-24', 'BG', 'Stara Zagora'), ('BG-25', 'BG', 'Turgovishte'), ('BG-26', 'BG', 'Khaskovo'), ('BG-27', 'BG', 'Shumen'), ('BG-28', 'BG', 'Yambol'), ('BH-CAP', 'BH', 'Capital'), ('BH-CEN', 'BH', 'Central'), ('BH-MUH', 'BH', 'Muharraq'), ('BH-NOR', 'BH', 'Northern'), ('BH-SOU', 'BH', 'Southern'), ('BI-BB', 'BI', 'Bubanza'), ('BI-BJ', 'BI', 'Bujumbura'), ('BI-BR', 'BI', 'Bururi'), ('BI-CA', 'BI', 'Cankuzo'), ('BI-CI', 'BI', 'Cibitoke'), ('BI-GI', 'BI', 'Gitega'), ('BI-KI', 'BI', 'Kirundo'), ('BI-KR', 'BI', 'Karuzi'), ('BI-KY', 'BI', 'Kayanza'), ('BI-MA', 'BI', 'Makamba'), ('BI-MU', 'BI', 'Muramvya'), ('BI-MW', 'BI', 'Mwaro'), ('BI-MY', 'BI', 'Muyinga'), ('BI-NG', 'BI', 'Ngozi'), ('BI-RT', 'BI', 'Rutana'), ('BI-RY', 'BI', 'Ruyigi'), ('BJ-AK', 'BJ', 'Atakora'), ('BJ-AL', 'BJ', 'Alibori'), ('BJ-AQ', 'BJ', 'Atlantique'), ('BJ-BO', 'BJ', 'Borgou'), ('BJ-CO', 'BJ', 'Collines'), ('BJ-DO', 'BJ', 'Donga'), ('BJ-KO', 'BJ', 'Kouffo'), ('BJ-LI', 'BJ', 'Littoral'), ('BJ-MO', 'BJ', 'Mono'), ('BJ-OU', 'BJ', 'Oueme'), ('BJ-PL', 'BJ', 'Plateau'), ('BJ-ZO', 'BJ', 'Zou'), ('BM-DS', 'BM', 'Devonshire'), ('BM-GC', 'BM', 'Saint George City'), ('BM-HA', 'BM', 'Hamilton'), ('BM-HC', 'BM', 'Hamilton City'), ('BM-PB', 'BM', 'Pembroke'), ('BM-PG', 'BM', 'Paget'), ('BM-SA', 'BM', 'Sandys'), ('BM-SG', 'BM', 'Saint George''s'), ('BM-SH', 'BM', 'Southampton'), ('BM-SM', 'BM', 'Smith''s'), ('BM-WA', 'BM', 'Warwick'), ('BN-BEL', 'BN', 'Belait'), ('BN-BRM', 'BN', 'Brunei and Muara'), ('BN-TEM', 'BN', 'Temburong'), ('BN-TUT', 'BN', 'Tutong'), ('BO-BEN', 'BO', 'Departmento Beni'), ('BO-CHU', 'BO', 'Departmento Chuquisaca'), ('BO-COC', 'BO', 'Departmento Cochabamba'), ('BO-LPZ', 'BO', 'Departmento La Paz'), ('BO-ORU', 'BO', 'Departmento Oruro'), ('BO-PAN', 'BO', 'Departmento Pando'), ('BO-POT', 'BO', 'Departmento Potosi'), ('BO-SCZ', 'BO', 'Departmento Santa Cruz'), ('BO-TAR', 'BO', 'Departmento Tarija'), ('BR-AC', 'BR', 'Acre'), ('BR-AL', 'BR', 'Alagoas'), ('BR-AM', 'BR', 'Amazonas'), ('BR-AP', 'BR', 'Amapa'), ('BR-BA', 'BR', 'Bahia'), ('BR-CE', 'BR', 'Ceara'), ('BR-DF', 'BR', 'Distrito Federal'), ('BR-ES', 'BR', 'Espirito Santo'), ('BR-GO', 'BR', 'Goias'), ('BR-MA', 'BR', 'Maranhao'), ('BR-MG', 'BR', 'Minas Gerais'), ('BR-MS', 'BR', 'Mato Grosso do Sul'), ('BR-MT', 'BR', 'Mato Grosso'), ('BR-PA', 'BR', 'Para'), ('BR-PB', 'BR', 'Paraiba'), ('BR-PE', 'BR', 'Pernambuco'), ('BR-PI', 'BR', 'Piaui'), ('BR-PR', 'BR', 'Parana'), ('BR-RJ', 'BR', 'Rio de Janeiro'), ('BR-RN', 'BR', 'Rio Grande do Norte'), ('BR-RO', 'BR', 'Rondonia'), ('BR-RR', 'BR', 'Roraima'), ('BR-RS', 'BR', 'Rio Grande do Sul'), ('BR-SC', 'BR', 'Santa Catarina'), ('BR-SE', 'BR', 'Sergipe'), ('BR-SP', 'BR', 'Sao Paulo'), ('BR-TO', 'BR', 'Tocantins'), ('BS-ACK', 'BS', 'Acklins'), ('BS-BER', 'BS', 'Berry Islands'), ('BS-BIM', 'BS', 'Bimini'), ('BS-BLK', 'BS', 'Black Point'), ('BS-CAB', 'BS', 'Central Abaco'), ('BS-CAN', 'BS', 'Central Andros'), ('BS-CAT', 'BS', 'Cat Island'), ('BS-CEL', 'BS', 'Central Eleuthera'), ('BS-CRO', 'BS', 'Crooked Island'), ('BS-EGB', 'BS', 'East Grand Bahama'), ('BS-EXU', 'BS', 'Exuma'), ('BS-FRE', 'BS', 'City of Freeport'), ('BS-GRD', 'BS', 'Grand Cay'), ('BS-HAR', 'BS', 'Harbour Island'), ('BS-HOP', 'BS', 'Hope Town'), ('BS-INA', 'BS', 'Inagua'), ('BS-LNG', 'BS', 'Long Island'), ('BS-MAN', 'BS', 'Mangrove Cay'), ('BS-MAY', 'BS', 'Mayaguana'), ('BS-MOO', 'BS', 'Moore''s Island'), ('BS-NAB', 'BS', 'North Abaco'), ('BS-NAN', 'BS', 'North Andros'), ('BS-NEL', 'BS', 'North Eleuthera'), ('BS-RAG', 'BS', 'Ragged Island'), ('BS-RUM', 'BS', 'Rum Cay'), ('BS-SAB', 'BS', 'South Abaco'), ('BS-SAL', 'BS', 'San Salvador'), ('BS-SAN', 'BS', 'South Andros'), ('BS-SEL', 'BS', 'South Eleuthera'), ('BS-SWE', 'BS', 'Spanish Wells'), ('BS-WGB', 'BS', 'West Grand Bahama'), ('BT-BUM', 'BT', 'Bumthang'), ('BT-CHU', 'BT', 'Chukha'), ('BT-DAG', 'BT', 'Dagana'), ('BT-GAS', 'BT', 'Gasa'), ('BT-HAA', 'BT', 'Haa'), ('BT-LHU', 'BT', 'Lhuntse'), ('BT-MON', 'BT', 'Mongar'), ('BT-PAR', 'BT', 'Paro'), ('BT-PEM', 'BT', 'Pemagatshel'), ('BT-PUN', 'BT', 'Punakha'), ('BT-SAR', 'BT', 'Sarpang'), ('BT-SAT', 'BT', 'Samtse'), ('BT-SJO', 'BT', 'Samdrup Jongkhar'), ('BT-THI', 'BT', 'Thimphu'), ('BT-TRG', 'BT', 'Trashigang'), ('BT-TRO', 'BT', 'Trongsa'), ('BT-TRY', 'BT', 'Trashiyangste'), ('BT-TSI', 'BT', 'Tsirang'), ('BT-WPH', 'BT', 'Wangdue Phodrang'), ('BT-ZHE', 'BT', 'Zhemgang'), ('BW-CE', 'BW', 'Central'), ('BW-GH', 'BW', 'Ghanzi'), ('BW-KD', 'BW', 'Kgalagadi'), ('BW-KT', 'BW', 'Kgatleng'), ('BW-KW', 'BW', 'Kweneng'), ('BW-NE', 'BW', 'North East'), ('BW-NG', 'BW', 'Ngamiland'), ('BW-NW', 'BW', 'North West'), ('BW-SE', 'BW', 'South East'), ('BW-SO', 'BW', 'Southern'), ('BY-BR', 'BY', 'Brest voblast'), ('BY-HO', 'BY', 'Homyel voblast'), ('BY-HR', 'BY', 'Hrodna voblast'), ('BY-MA', 'BY', 'Mahilyow voblast'), ('BY-MI', 'BY', 'Minsk voblast'), ('BY-VI', 'BY', 'Vitsebsk voblast'), ('BZ-BZ', 'BZ', 'Belize District'), ('BZ-CR', 'BZ', 'Corozal District'), ('BZ-CY', 'BZ', 'Cayo District'), ('BZ-OW', 'BZ', 'Orange Walk District'), ('BZ-SC', 'BZ', 'Stann Creek District'), ('BZ-TO', 'BZ', 'Toledo District'), ('AB', 'CA', 'Alberta'), ('BC', 'CA', 'British Columbia'), ('MB', 'CA', 'Manitoba'), ('NB', 'CA', 'New Brunswick'), ('NL', 'CA', 'Newfoundland and Labrador'), ('NS', 'CA', 'Nova Scotia'), ('NT', 'CA', 'Northwest Territories'), ('NU', 'CA', 'Nunavut'), ('ON', 'CA', 'Ontario'), ('PE', 'CA', 'Prince Edward Island'), ('QC', 'CA', 'Quebec'), ('SK', 'CA', 'Saskatchewan'), ('YT', 'CA', 'Yukon Territory'), ('CC-D', 'CC', 'Direction Island'), ('CC-H', 'CC', 'Home Island'), ('CC-O', 'CC', 'Horsburgh Island'), ('CC-S', 'CC', 'South Island'), ('CC-W', 'CC', 'West Island'), ('CD-BC', 'CD', 'Bas-Congo'), ('CD-BN', 'CD', 'Bandundu'), ('CD-EQ', 'CD', 'Equateur'), ('CD-KA', 'CD', 'Katanga'), ('CD-KE', 'CD', 'Kasai-Oriental'), ('CD-KN', 'CD', 'Kinshasa'), ('CD-KW', 'CD', 'Kasai-Occidental'), ('CD-MA', 'CD', 'Maniema'), ('CD-NK', 'CD', 'Nord-Kivu'), ('CD-OR', 'CD', 'Orientale'), ('CD-SK', 'CD', 'Sud-Kivu'), ('CF-BAN', 'CF', 'Bangui'), ('CF-BBA', 'CF', 'Bamingui-Bangoran'), ('CF-BKO', 'CF', 'Basse-Kotto'), ('CF-HKO', 'CF', 'Haute-Kotto'), ('CF-HMB', 'CF', 'Haut-Mbomou'), ('CF-KEM', 'CF', 'Kemo'), ('CF-LOB', 'CF', 'Lobaye'), ('CF-MBO', 'CF', 'Mbomou'), ('CF-MKD', 'CF', 'Mambere-KadeO? C'), ('CF-NGR', 'CF', 'Nana-Grebizi'), ('CF-NMM', 'CF', 'Nana-Mambere'), ('CF-OMP', 'CF', 'Ombella-M''Poko'), ('CF-OPE', 'CF', 'Ouham-Pende'), ('CF-OUH', 'CF', 'Ouham'), ('CF-OUK', 'CF', 'Ouaka'), ('CF-SMB', 'CF', 'Sangha-Mbaere'), ('CF-VAK', 'CF', 'Vakaga'), ('CG-BO', 'CG', 'Bouenza'), ('CG-BR', 'CG', 'Brazzaville'), ('CG-CO', 'CG', 'Cuvette-Ouest'), ('CG-CU', 'CG', 'Cuvette'), ('CG-KO', 'CG', 'Kouilou'), ('CG-LE', 'CG', 'Lekoumou'), ('CG-LI', 'CG', 'Likouala'), ('CG-NI', 'CG', 'Niari'), ('CG-PL', 'CG', 'Plateaux'), ('CG-PO', 'CG', 'Pool'), ('CG-SA', 'CG', 'Sangha'), ('CH-AG', 'CH', 'Aargau'), ('CH-AI', 'CH', 'Appenzell Innerhoden'), ('CH-AR', 'CH', 'Appenzell Ausserrhoden'), ('CH-BE', 'CH', 'Bern'), ('CH-BL', 'CH', 'Basel-Landschaft'), ('CH-BS', 'CH', 'Basel-Stadt'), ('CH-FR', 'CH', 'Fribourg'), ('CH-GE', 'CH', 'Geneva'), ('CH-GL', 'CH', 'Glarus'), ('CH-GR', 'CH', 'Graubunden'), ('CH-JU', 'CH', 'Jura'), ('CH-LU', 'CH', 'Lucerne'), ('CH-NE', 'CH', 'NeuchO?l S'), ('CH-NW', 'CH', 'Nidwalden'), ('CH-OW', 'CH', 'Obwalden'), ('CH-SG', 'CH', 'St. Gallen'), ('CH-SH', 'CH', 'Schaffhausen'), ('CH-SO', 'CH', 'Solothurn'), ('CH-SZ', 'CH', 'Schwyz'), ('CH-TG', 'CH', 'Thurgau'), ('CH-TI', 'CH', 'Ticino'), ('CH-UR', 'CH', 'Uri'), ('CH-VD', 'CH', 'Vaud'), ('CH-VS', 'CH', 'Valais'), ('CH-ZG', 'CH', 'Zug'), ('CH-ZH', 'CH', 'Zurich'), ('CI-ABE', 'CI', 'Abengourou'), ('CI-ABI', 'CI', 'Abidjan'), ('CI-ABO', 'CI', 'Aboisso'), ('CI-ADI', 'CI', 'Adiake'), ('CI-ADZ', 'CI', 'Adzope'), ('CI-AGB', 'CI', 'Agboville'), ('CI-AGN', 'CI', 'Agnibilekrou'), ('CI-ALE', 'CI', 'Alepe'), ('CI-BAN', 'CI', 'Bangolo'), ('CI-BDK', 'CI', 'Bondoukou'), ('CI-BDL', 'CI', 'Boundiali'), ('CI-BEO', 'CI', 'Beoumi'), ('CI-BFL', 'CI', 'Bouafle'), ('CI-BGN', 'CI', 'Bongouanou'), ('CI-BIA', 'CI', 'Biankouma'), ('CI-BKE', 'CI', 'Bouake'), ('CI-BNA', 'CI', 'Bouna'), ('CI-BOC', 'CI', 'Bocanda'), ('CI-DAL', 'CI', 'Daloa'), ('CI-DAN', 'CI', 'Danane'), ('CI-DAO', 'CI', 'Daoukro'), ('CI-DBU', 'CI', 'Dabou'), ('CI-DIM', 'CI', 'Dimbokro'), ('CI-DIV', 'CI', 'Divo'), ('CI-DKL', 'CI', 'Dabakala'), ('CI-DUE', 'CI', 'Duekoue'), ('CI-FER', 'CI', 'Ferkessedougou'), ('CI-GAG', 'CI', 'Gagnoa'), ('CI-GBA', 'CI', 'Grand-Bassam'), ('CI-GLA', 'CI', 'Grand-Lahou'), ('CI-GUI', 'CI', 'Guiglo'), ('CI-ISS', 'CI', 'Issia'), ('CI-JAC', 'CI', 'Jacqueville'), ('CI-KAT', 'CI', 'Katiola'), ('CI-KOR', 'CI', 'Korhogo'), ('CI-LAK', 'CI', 'Lakota'), ('CI-MAN', 'CI', 'Man'), ('CI-MBA', 'CI', 'Mbahiakro'), ('CI-MKN', 'CI', 'Mankono'), ('CI-ODI', 'CI', 'Odienne'), ('CI-OUM', 'CI', 'Oume'), ('CI-SAK', 'CI', 'Sakassou'), ('CI-SAS', 'CI', 'Sassandra'), ('CI-SEG', 'CI', 'Seguela'), ('CI-SIN', 'CI', 'Sinfra'), ('CI-SOU', 'CI', 'Soubre'), ('CI-SPE', 'CI', 'San-Pedro'), ('CI-TAB', 'CI', 'Tabou'), ('CI-TAN', 'CI', 'Tanda'), ('CI-TBA', 'CI', 'Touba'), ('CI-TIA', 'CI', 'Tiassale'), ('CI-TIE', 'CI', 'Tiebissou'), ('CI-TIN', 'CI', 'Tingrela'), ('CI-TLP', 'CI', 'Toulepleu'), ('CI-TMD', 'CI', 'Toumodi'), ('CI-VAV', 'CI', 'Vavoua'), ('CI-YAM', 'CI', 'Yamoussoukro'), ('CI-ZUE', 'CI', 'Zuenoula'), ('CK-AI', 'CK', 'Aitutaki'), ('CK-AT', 'CK', 'Atiu'), ('CK-MA', 'CK', 'Manuae'), ('CK-MG', 'CK', 'Mangaia'), ('CK-MK', 'CK', 'Manihiki'), ('CK-MT', 'CK', 'Mitiaro'), ('CK-MU', 'CK', 'Mauke'), ('CK-NI', 'CK', 'Nassau Island'), ('CK-PA', 'CK', 'Palmerston'), ('CK-PE', 'CK', 'Penrhyn'), ('CK-PU', 'CK', 'Pukapuka'), ('CK-RK', 'CK', 'Rakahanga'), ('CK-RR', 'CK', 'Rarotonga'), ('CK-SU', 'CK', 'Surwarrow'), ('CK-TA', 'CK', 'Takutea'), ('CL-AI', 'CL', 'Aisen del General Carlos Ibanez del Campo (XI)'), ('CL-AN', 'CL', 'Antofagasta (II)'), ('CL-AR', 'CL', 'Araucania (IX)'), ('CL-AT', 'CL', 'Atacama (III)'), ('CL-BI', 'CL', 'Bio-Bio (VIII)'), ('CL-CO', 'CL', 'Coquimbo (IV)'), ('CL-LI', 'CL', 'Libertador General Bernardo O''Higgins (VI)'), ('CL-LL', 'CL', 'Los Lagos (X)'), ('CL-MA', 'CL', 'Magallanes (XII)'), ('CL-ML', 'CL', 'Maule (VII)'), ('CL-RM', 'CL', 'Region Metropolitana (RM)'), ('CL-TA', 'CL', 'Tarapaca (I)'), ('CL-VS', 'CL', 'Valparaiso (V)'), ('CM-ADA', 'CM', 'Adamawa Province (Adamaoua)'), ('CM-CEN', 'CM', 'Centre Province'), ('CM-EST', 'CM', 'East Province (Est)'), ('CM-EXN', 'CM', 'Extreme North Province (ExtrO?-Nord) C'), ('CM-LIT', 'CM', 'Littoral Province'), ('CM-NOR', 'CM', 'North Province (Nord)'), ('CM-NOT', 'CM', 'Northwest Province (Nord-Ouest)'), ('CM-OUE', 'CM', 'West Province (Ouest)'), ('CM-SOU', 'CM', 'Southwest Province (Sud-Ouest).'), ('CM-SUD', 'CM', 'South Province (Sud)'), ('CN-11', 'CN', 'Beijing'), ('CN-12', 'CN', 'Tianjin'), ('CN-13', 'CN', 'Hebei'), ('CN-14', 'CN', 'Shanxi'), ('CN-15', 'CN', 'Nei Mongol'), ('CN-21', 'CN', 'Liaoning'), ('CN-22', 'CN', 'Jilin'), ('CN-23', 'CN', 'Heilongjiang'), ('CN-31', 'CN', 'Shanghai'), ('CN-32', 'CN', 'Jiangsu'), ('CN-33', 'CN', 'Zhejiang'), ('CN-34', 'CN', 'Anhui'), ('CN-35', 'CN', 'Fujian'), ('CN-36', 'CN', 'Jiangxi'), ('CN-37', 'CN', 'Shandong'), ('CN-41', 'CN', 'Henan'), ('CN-42', 'CN', 'Hubei'), ('CN-43', 'CN', 'Hunan'), ('CN-44', 'CN', 'Guangdong'), ('CN-45', 'CN', 'Guangxi'), ('CN-46', 'CN', 'Hainan'), ('CN-51', 'CN', 'Sichuan'), ('CN-52', 'CN', 'Guizhou'), ('CN-53', 'CN', 'Yunnan'), ('CN-54', 'CN', 'Xizang ZO?O? (Tibet) CH'), ('CN-61', 'CN', 'Shaanxi'), ('CN-62', 'CN', 'Gansu'), ('CN-63', 'CN', 'Qinghai'), ('CN-64', 'CN', 'Ningxia'), ('CN-65', 'CN', 'Xinjiang'), ('CN-71', 'CN', 'Taiwan'), ('CN-91', 'CN', 'Xianggang'), ('CN-92', 'CN', 'Aomen'), ('CN-97', 'CN', 'ChongqO? C'), ('CN-98', 'CN', 'Gaoxiong'), ('CN-99', 'CN', 'Taibei'), ('CO-AMZ', 'CO', 'Amazonas'), ('CO-ANT', 'CO', 'Antioquia'), ('CO-ARA', 'CO', 'Arauca'), ('CO-ATL', 'CO', 'Atlantico'), ('CO-BDC', 'CO', 'Bogota D.C.'), ('CO-BOL', 'CO', 'Bolivar'), ('CO-BOY', 'CO', 'Boyaca'), ('CO-CAL', 'CO', 'Caldas'), ('CO-CAM', 'CO', 'Cundinamarca'), ('CO-CAQ', 'CO', 'Caqueta'), ('CO-CAS', 'CO', 'Casanare'), ('CO-CAU', 'CO', 'Cauca'), ('CO-CES', 'CO', 'Cesar'), ('CO-CHO', 'CO', 'Choco'), ('CO-COR', 'CO', 'Cordoba'), ('CO-GJR', 'CO', 'Guajira'), ('CO-GNA', 'CO', 'Guainia'), ('CO-GVR', 'CO', 'Guaviare'), ('CO-HUI', 'CO', 'Huila'), ('CO-MAG', 'CO', 'Magdalena'), ('CO-MET', 'CO', 'Meta'), ('CO-NAR', 'CO', 'Narino'), ('CO-NDS', 'CO', 'Norte de Santander'), ('CO-PUT', 'CO', 'Putumayo'), ('CO-QUI', 'CO', 'Quindio'), ('CO-RIS', 'CO', 'Risaralda'), ('CO-SAN', 'CO', 'Santander'), ('CO-SAP', 'CO', 'San Andres y Providencia'), ('CO-SUC', 'CO', 'Sucre'), ('CO-TOL', 'CO', 'Tolima'), ('CO-VAU', 'CO', 'Vaupes'), ('CO-VDC', 'CO', 'Valle del Cauca'), ('CO-VIC', 'CO', 'Vichada'), ('CR-AL', 'CR', 'Alajuela'), ('CR-CA', 'CR', 'Cartago'), ('CR-GU', 'CR', 'Guanacaste'), ('CR-HE', 'CR', 'Heredia'), ('CR-LI', 'CR', 'Limon'), ('CR-PU', 'CR', 'Puntarenas'), ('CR-SJ', 'CR', 'San Jose'), ('CS-KOS', 'CS', 'Kosovo'), ('CS-MON', 'CS', 'Montenegro'), ('CS-SER', 'CS', 'Serbia'), ('CS-VOJ', 'CS', 'Vojvodina'), ('CU-CAM', 'CU', 'Camaguey'), ('CU-CAV', 'CU', 'Ciego de Avila'), ('CU-CFU', 'CU', 'Cienfuegos'), ('CU-CLH', 'CU', 'Ciudad de La Habana'), ('CU-GRA', 'CU', 'Granma'), ('CU-GUA', 'CU', 'Guantanamo'), ('CU-HOL', 'CU', 'Holguin'), ('CU-IJU', 'CU', 'Isla de la Juventud'), ('CU-LHA', 'CU', 'La Habana'), ('CU-LTU', 'CU', 'Las Tunas'), ('CU-MAT', 'CU', 'Matanzas'), ('CU-PRI', 'CU', 'Pinar del Rio'), ('CU-SCU', 'CU', 'Santiago de Cuba'), ('CU-SSP', 'CU', 'Sancti Spiritus'), ('CU-VCL', 'CU', 'Villa Clara'), ('CV-BR', 'CV', 'Brava'), ('CV-BV', 'CV', 'Boa Vista'), ('CV-CA', 'CV', 'Santa Catarina'), ('CV-CR', 'CV', 'Santa Cruz'), ('CV-CS', 'CV', 'Calheta de Sao Miguel'), ('CV-MA', 'CV', 'Maio'), ('CV-MO', 'CV', 'Mosteiros'), ('CV-PA', 'CV', 'Paul'), ('CV-PN', 'CV', 'Porto Novo'), ('CV-PR', 'CV', 'Praia'), ('CV-RG', 'CV', 'Ribeira Grande'), ('CV-SD', 'CV', 'Sao Domingos'), ('CV-SF', 'CV', 'Sao Filipe'), ('CV-SL', 'CV', 'Sal'), ('CV-SN', 'CV', 'Sao Nicolau'), ('CV-SV', 'CV', 'Sao Vicente'), ('CV-TA', 'CV', 'Tarrafal'), ('CY-A', 'CY', 'Larnaca'), ('CY-F', 'CY', 'Famagusta'), ('CY-I', 'CY', 'Limassol'), ('CY-K', 'CY', 'Kyrenia'), ('CY-N', 'CY', 'Nicosia'), ('CY-P', 'CY', 'Paphos'), ('CZ-JC', 'CZ', 'South Bohemian Region (Jihocesky kraj)'), ('CZ-JM', 'CZ', 'South Moravian Region (Jihomoravsky kraj)'), ('CZ-KA', 'CZ', 'Carlsbad Region (Karlovarsky kraj)'), ('CZ-KR', 'CZ', 'Hradec Kralove Region (Kralovehradecky kraj)'), ('CZ-LI', 'CZ', 'Liberec Region (Liberecky kraj)'), ('CZ-MO', 'CZ', 'Moravian-Silesian Region (Moravskoslezsky kraj)'), ('CZ-OL', 'CZ', 'Olomouc Region (Olomoucky kraj)'), ('CZ-PA', 'CZ', 'Pardubice Region (Pardubicky kraj)'), ('CZ-PL', 'CZ', 'Plzen( Region Plzensky kraj)'), ('CZ-PR', 'CZ', 'Prague - the Capital (Praha - hlavni mesto)'), ('CZ-ST', 'CZ', 'Central Bohemian Region (Stredocesky kraj)'), ('CZ-US', 'CZ', 'Usti nad Labem Region (Ustecky kraj)'), ('CZ-VY', 'CZ', 'Vysoc(ina Region (kraj Vysoc(ina)'), ('CZ-ZL', 'CZ', 'Zlin Region (Zlinsky kraj)'), ('DE-BE', 'DE', 'Berlin'), ('DE-BR', 'DE', 'Brandenburg'), ('DE-BW', 'DE', 'Baden-Wurttemberg'), ('DE-BY', 'DE', 'Bayern'), ('DE-HB', 'DE', 'Bremen'), ('DE-HE', 'DE', 'Hessen'), ('DE-HH', 'DE', 'Hamburg'), ('DE-MV', 'DE', 'Mecklenburg-Vorpommern'), ('DE-NI', 'DE', 'Niedersachsen'), ('DE-NW', 'DE', 'Nordrhein-Westfalen'), ('DE-RP', 'DE', 'Rheinland-Pfalz'), ('DE-SH', 'DE', 'Schleswig-Holstein'), ('DE-SL', 'DE', 'Saarland'), ('DE-SN', 'DE', 'Sachsen'), ('DE-ST', 'DE', 'Sachsen-Anhalt'), ('DE-TH', 'DE', 'Thuringen'), ('DJ-J', 'DJ', 'Djibouti'), ('DJ-K', 'DJ', 'Dikhil'), ('DJ-O', 'DJ', 'Obock'), ('DJ-S', 'DJ', '''Ali Sabih'), ('DJ-T', 'DJ', 'Tadjoura'), ('DK-AR', 'DK', 'Arhus'), ('DK-BH', 'DK', 'Bornholm'), ('DK-CC', 'DK', 'Copenhagen (municipality)'), ('DK-CO', 'DK', 'Copenhagen'), ('DK-FC', 'DK', 'Frederiksberg (municipality)'), ('DK-FO', 'DK', 'Faroe Islands'), ('DK-FR', 'DK', 'Frederiksborg'), ('DK-FU', 'DK', 'Funen'), ('DK-GL', 'DK', 'Greenland'), ('DK-NJ', 'DK', 'North Jutland'), ('DK-RB', 'DK', 'Ribe'), ('DK-RK', 'DK', 'Ringkjobing'), ('DK-RO', 'DK', 'Roskilde'), ('DK-SJ', 'DK', 'South Jutland'), ('DK-ST', 'DK', 'Storstrom'), ('DK-VB', 'DK', 'Viborg'), ('DK-VK', 'DK', 'Vejle'), ('DK-WZ', 'DK', 'West Zealand'), ('DM-AND', 'DM', 'Saint Andrew Parish'), ('DM-DAV', 'DM', 'Saint David Parish'), ('DM-GEO', 'DM', 'Saint George Parish'), ('DM-JOH', 'DM', 'Saint John Parish'), ('DM-JOS', 'DM', 'Saint Joseph Parish'), ('DM-LUK', 'DM', 'Saint Luke Parish'), ('DM-MAR', 'DM', 'Saint Mark Parish'), ('DM-PAT', 'DM', 'Saint Patrick Parish'), ('DM-PAU', 'DM', 'Saint Paul Parish'), ('DM-PET', 'DM', 'Saint Peter Parish'), ('DO-AL', 'DO', 'La Altagracia'), ('DO-AZ', 'DO', 'Azua'), ('DO-BC', 'DO', 'Baoruco'), ('DO-BH', 'DO', 'Barahona'), ('DO-DJ', 'DO', 'Dajabon'), ('DO-DN', 'DO', 'Distrito Nacional'), ('DO-DU', 'DO', 'Duarte'), ('DO-EL', 'DO', 'Elias Pina'), ('DO-ET', 'DO', 'Espaillat'), ('DO-HM', 'DO', 'Hato Mayor'), ('DO-IN', 'DO', 'Independencia'), ('DO-JO', 'DO', 'San Jose de Ocoa'), ('DO-MC', 'DO', 'Monte Cristi'), ('DO-MN', 'DO', 'Monsenor Nouel'), ('DO-MP', 'DO', 'Monte Plata'), ('DO-MT', 'DO', 'Maria Trinidad Sanchez'), ('DO-PD', 'DO', 'Pedernales'), ('DO-PM', 'DO', 'San Pedro de Macoris'), ('DO-PP', 'DO', 'Puerto Plata'), ('DO-PR', 'DO', 'Peravia (Bani)'), ('DO-RO', 'DO', 'La Romana'), ('DO-SA', 'DO', 'Santiago'), ('DO-SC', 'DO', 'San Cristobal'), ('DO-SD', 'DO', 'Santo Domingo'), ('DO-SH', 'DO', 'Sanchez Ramirez'), ('DO-SJ', 'DO', 'San Juan'), ('DO-SL', 'DO', 'Salcedo'), ('DO-SM', 'DO', 'Samana'), ('DO-ST', 'DO', 'Santiago Rodriguez'), ('DO-SY', 'DO', 'El Seybo'), ('DO-VA', 'DO', 'Valverde'), ('DO-VE', 'DO', 'La Vega'), ('DZ-ADE', 'DZ', 'Ain Defla'), ('DZ-ADR', 'DZ', 'Adrar'), ('DZ-ALG', 'DZ', 'Alger'), ('DZ-ANN', 'DZ', 'Annaba'), ('DZ-ATE', 'DZ', 'Ain Temouchent'), ('DZ-BAT', 'DZ', 'Batna'), ('DZ-BBA', 'DZ', 'Bordj Bou Arreridj'), ('DZ-BEC', 'DZ', 'Bechar'), ('DZ-BEJ', 'DZ', 'Bejaia'), ('DZ-BIS', 'DZ', 'Biskra'), ('DZ-BLI', 'DZ', 'Blida'), ('DZ-BMD', 'DZ', 'Boumerdes'), ('DZ-BOA', 'DZ', 'Bouira'), ('DZ-CHL', 'DZ', 'Chlef'), ('DZ-CON', 'DZ', 'Constantine'), ('DZ-DJE', 'DZ', 'Djelfa'), ('DZ-EBA', 'DZ', 'El Bayadh'), ('DZ-EOU', 'DZ', 'El Oued'), ('DZ-ETA', 'DZ', 'El Tarf'), ('DZ-GHA', 'DZ', 'Ghardaia'), ('DZ-GUE', 'DZ', 'Guelma'), ('DZ-ILL', 'DZ', 'Illizi'), ('DZ-JIJ', 'DZ', 'Jijel'), ('DZ-KHE', 'DZ', 'Khenchela'), ('DZ-LAG', 'DZ', 'Laghouat'), ('DZ-MED', 'DZ', 'Medea'), ('DZ-MIL', 'DZ', 'Mila'), ('DZ-MOS', 'DZ', 'Mostaganem'), ('DZ-MSI', 'DZ', 'M''Sila'), ('DZ-MUA', 'DZ', 'Muaskar'), ('DZ-NAA', 'DZ', 'Naama'), ('DZ-OEB', 'DZ', 'Oum el-Bouaghi'), ('DZ-ORA', 'DZ', 'Oran'), ('DZ-OUA', 'DZ', 'Ouargla'), ('DZ-REL', 'DZ', 'Relizane'), ('DZ-SAH', 'DZ', 'Souk Ahras'), ('DZ-SAI', 'DZ', 'Saida'), ('DZ-SBA', 'DZ', 'Sidi Bel Abbes'), ('DZ-SET', 'DZ', 'Setif'), ('DZ-SKI', 'DZ', 'Skikda'), ('DZ-TAM', 'DZ', 'Tamanghasset'), ('DZ-TEB', 'DZ', 'Tebessa'), ('DZ-TIA', 'DZ', 'Tiaret'), ('DZ-TIN', 'DZ', 'Tindouf'), ('DZ-TIP', 'DZ', 'Tipaza'), ('DZ-TIS', 'DZ', 'Tissemsilt'), ('DZ-TLE', 'DZ', 'Tlemcen'), ('DZ-TOU', 'DZ', 'Tizi Ouzou'), ('EC-A', 'EC', 'Azuay'), ('EC-B', 'EC', 'Bolivar'), ('EC-C', 'EC', 'Carchi'), ('EC-D', 'EC', 'Orellana'), ('EC-E', 'EC', 'Esmeraldas'), ('EC-F', 'EC', 'Canar'), ('EC-G', 'EC', 'Guayas'), ('EC-H', 'EC', 'Chimborazo'), ('EC-I', 'EC', 'Imbabura'), ('EC-L', 'EC', 'Loja'), ('EC-M', 'EC', 'Manabi'), ('EC-N', 'EC', 'Napo'), ('EC-O', 'EC', 'El Oro'), ('EC-P', 'EC', 'Pichincha'), ('EC-R', 'EC', 'Los Rios'), ('EC-S', 'EC', 'Morona-Santiago'), ('EC-T', 'EC', 'Tungurahua'), ('EC-U', 'EC', 'Sucumbios'), ('EC-W', 'EC', 'Galapagos'), ('EC-X', 'EC', 'Cotopaxi'), ('EC-Y', 'EC', 'Pastaza'), ('EC-Z', 'EC', 'Zamora-Chinchipe'), ('EE-37', 'EE', 'Harju County'), ('EE-39', 'EE', 'Hiiu County'), ('EE-44', 'EE', 'Ida-Viru County'), ('EE-49', 'EE', 'JOAa County'), ('EE-51', 'EE', 'JArva County'), ('EE-57', 'EE', 'LAAne County'), ('EE-59', 'EE', 'LAAne-Viru County'), ('EE-65', 'EE', 'POA County'), ('EE-67', 'EE', 'PArnu County'), ('EE-70', 'EE', 'Rapla County'), ('EE-74', 'EE', 'Saare County'), ('EE-78', 'EE', 'Tartu County'), ('EE-82', 'EE', 'Valga County'), ('EE-84', 'EE', 'Viljandi County'), ('EE-86', 'EE', 'VOACounty'), ('EG-ASW', 'EG', 'Aswan'), ('EG-ASY', 'EG', 'Asyut'), ('EG-BAM', 'EG', 'Al Bahr al Ahmar'), ('EG-BHY', 'EG', 'Al Buhayrah'), ('EG-BSD', 'EG', 'Bur Sa''id'), ('EG-BSW', 'EG', 'Bani Suwayf'), ('EG-DHY', 'EG', 'Ad Daqahliyah'), ('EG-DMY', 'EG', 'Dumyat'), ('EG-FYM', 'EG', 'Al Fayyum'), ('EG-GBY', 'EG', 'Al Gharbiyah'), ('EG-IDR', 'EG', 'Al Iskandariyah'), ('EG-IML', 'EG', 'Al Isma''iliyah'), ('EG-JNS', 'EG', 'Janub Sina'''), ('EG-JZH', 'EG', 'Al Jizah'), ('EG-KSH', 'EG', 'Kafr ash Shaykh'), ('EG-MAT', 'EG', 'Matruh'), ('EG-MFY', 'EG', 'Al Minufiyah'), ('EG-MNY', 'EG', 'Al Minya'), ('EG-QHR', 'EG', 'Al Qahirah'), ('EG-QIN', 'EG', 'Qina'), ('EG-QLY', 'EG', 'Al Qalyubiyah'), ('EG-SHQ', 'EG', 'Ash Sharqiyah'), ('EG-SHS', 'EG', 'Shamal Sina'''), ('EG-SUH', 'EG', 'Suhaj'), ('EG-SWY', 'EG', 'As Suways'), ('EG-WJD', 'EG', 'Al Wadi al Jadid'), ('ER-BR', 'ER', 'Gash-Barka (Barentu)'), ('ER-DE', 'ER', 'Southern (Debub)'), ('ER-DK', 'ER', 'Southern Red Sea (Debub-Keih-Bahri)'), ('ER-KE', 'ER', 'Anseba (Keren)'), ('ER-MA', 'ER', 'Central (Maekel)'), ('ER-SK', 'ER', 'Northern Red Sea (Semien-Keih-Bahri)'), ('ES-AB', 'ES', 'Albacete'), ('ES-AC', 'ES', 'Alicante'), ('ES-AL', 'ES', 'Alava'), ('ES-AM', 'ES', 'Almeria'), ('ES-AS', 'ES', 'Asturias'), ('ES-AV', 'ES', 'Avila'), ('ES-BA', 'ES', 'Barcelona'), ('ES-BJ', 'ES', 'Badajoz'), ('ES-BU', 'ES', 'Burgos'), ('ES-CA', 'ES', 'A Coruna'), ('ES-CC', 'ES', 'Caceres'), ('ES-CD', 'ES', 'Cordoba'), ('ES-CL', 'ES', 'Castellon'), ('ES-CR', 'ES', 'Ciudad Real'), ('ES-CT', 'ES', 'Cantabria'), ('ES-CU', 'ES', 'Cuenca'), ('ES-CZ', 'ES', 'Cadiz'), ('ES-GD', 'ES', 'Granada'), ('ES-GI', 'ES', 'Girona'), ('ES-GJ', 'ES', 'Guadalajara'), ('ES-GP', 'ES', 'Guipuzcoa'), ('ES-HL', 'ES', 'Huelva'), ('ES-HS', 'ES', 'Huesca'), ('ES-IB', 'ES', 'Illes Balears'), ('ES-JN', 'ES', 'Jaen'), ('ES-LE', 'ES', 'Leon'), ('ES-LG', 'ES', 'Lugo'), ('ES-LL', 'ES', 'Lleida'), ('ES-MD', 'ES', 'Madrid'), ('ES-ML', 'ES', 'Malaga'), ('ES-MU', 'ES', 'Murcia'), ('ES-NV', 'ES', 'Navarra'), ('ES-OU', 'ES', 'Ourense'), ('ES-PL', 'ES', 'Palencia'), ('ES-PM', 'ES', 'Las Palmas'), ('ES-PO', 'ES', 'Pontevedra'), ('ES-RJ', 'ES', 'La Rioja'), ('ES-SC', 'ES', 'Santa Cruz de Tererife'), ('ES-SG', 'ES', 'Segovia'), ('ES-SL', 'ES', 'Salamanca'), ('ES-SO', 'ES', 'Soria'), ('ES-SV', 'ES', 'Sevilla'), ('ES-TA', 'ES', 'Tarragona'), ('ES-TE', 'ES', 'Teruel'), ('ES-TO', 'ES', 'Toledo'), ('ES-VC', 'ES', 'Valencia'), ('ES-VD', 'ES', 'Valladolid'), ('ES-VZ', 'ES', 'Vizcaya'), ('ES-ZM', 'ES', 'Zamora'), ('ES-ZR', 'ES', 'Zaragoza'), ('ET-AA', 'ET', 'Addis Ababa'), ('ET-AF', 'ET', 'Afar'), ('ET-AH', 'ET', 'Amhara'), ('ET-BG', 'ET', 'Benishangul-Gumaz'), ('ET-DD', 'ET', 'Dire Dawa'), ('ET-GB', 'ET', 'Gambela'), ('ET-HR', 'ET', 'Hariai'), ('ET-OR', 'ET', 'Oromia'), ('ET-SM', 'ET', 'Somali'), ('ET-SN', 'ET', 'Southern Nations - Nationalities and Peoples Region'), ('ET-TG', 'ET', 'Tigray'), ('FI-AH', 'FI', 'Ahvenanmaan laani'), ('FI-ES', 'FI', 'Etela-Suomen laani'), ('FI-IS', 'FI', 'Ita-Suomen laani'), ('FI-LL', 'FI', 'Lapin laani'), ('FI-LS', 'FI', 'Lansi-Suomen laani'), ('FI-OU', 'FI', 'Oulun laani'), ('FJ-C', 'FJ', 'Central Division'), ('FJ-E', 'FJ', 'Eastern Division'), ('FJ-N', 'FJ', 'Northern Division'), ('FJ-R', 'FJ', 'Rotuma'), ('FJ-W', 'FJ', 'Western Division'), ('FM-C', 'FM', 'Chuuk'), ('FM-K', 'FM', 'Kosrae'), ('FM-P', 'FM', 'Pohnpei'), ('FM-Y', 'FM', 'Yap'), ('FR-A67', 'FR', 'Bas-Rhin - Alsace'), ('FR-A68', 'FR', 'Haut-Rhin - Alsace'), ('FR-B24', 'FR', 'Dordogne - Aquitaine'), ('FR-B33', 'FR', 'Gironde - Aquitaine'), ('FR-B40', 'FR', 'Landes - Aquitaine'), ('FR-B47', 'FR', 'Lot-et-Garonne - Aquitaine'), ('FR-B64', 'FR', 'Pyrenees-Atlantiques - Aquitaine'), ('FR-B79', 'FR', 'Deux-Sevres - Aquitaine'), ('FR-C03', 'FR', 'Allier - Auvergne'), ('FR-C15', 'FR', 'Cantal - Auvergne'), ('FR-C43', 'FR', 'Haute-Loire - Auvergne'), ('FR-C63', 'FR', 'Pu-de-Dme - Auvergne'), ('FR-D21', 'FR', 'Cote-d''Or - Bourgogne'), ('FR-D58', 'FR', 'Nievre - Bourgogne'), ('FR-D71', 'FR', 'Saone-et-Loire - Bourgogne'), ('FR-D89', 'FR', 'Yonne - Bourgogne'), ('FR-E22', 'FR', 'Cotes-d''Armor - Bretagne'), ('FR-E29', 'FR', 'Finistere - Bretagne'), ('FR-E35', 'FR', 'Ille-et-Vilaine - Bretagne'), ('FR-E56', 'FR', 'Morbihan - Bretagne'), ('FR-F18', 'FR', 'Cher - Centre'), ('FR-F28', 'FR', 'Eure-et-Loir - Centre'), ('FR-F36', 'FR', 'Indre - Centre'), ('FR-F37', 'FR', 'Indre-et-Loire - Centre'), ('FR-F41', 'FR', 'Loir-et-Cher - Centre'), ('FR-F45', 'FR', 'Loiret - Centre'), ('FR-G08', 'FR', 'Ardennes - Champagne-Ardenne'), ('FR-G10', 'FR', 'Aube - Champagne-Ardenne'), ('FR-G51', 'FR', 'Marne - Champagne-Ardenne'), ('FR-G52', 'FR', 'Haute-Marne - Champagne-Ardenne'), ('FR-H2A', 'FR', 'Corse-du-Sud - Corse'), ('FR-H2B', 'FR', 'Haute-Corse - Corse'), ('FR-I25', 'FR', 'Doubs - Franche-Comte'), ('FR-I39', 'FR', 'Jura - Franche-Comte'), ('FR-I70', 'FR', 'Haute-Saone - Franche-Comte'), ('FR-I90', 'FR', 'Haute-Saone - Territoire de Belfort'), ('FR-J75', 'FR', 'Paris - Ile-de-France'), ('FR-J77', 'FR', 'Seine-et-Marne - Ile-de-France'), ('FR-J78', 'FR', 'Yvelines - Ile-de-France'), ('FR-J91', 'FR', 'Essonne - Ile-de-France'), ('FR-J92', 'FR', 'Hauts-de-Seine - Ile-de-France'), ('FR-J93', 'FR', 'Seine-Saint-Denis - Ile-de-France'), ('FR-J94', 'FR', 'Val-de-Marne - Ile-de-France'), ('FR-J95', 'FR', 'Val-d''Oise - Ile-de-France'), ('FR-U04', 'FR', 'Alpes-de-Haute-Provence'), ('FR-U05', 'FR', 'Hautes-Alpes'), ('FR-U06', 'FR', 'Alpes-Maritimes'), ('FR-U13', 'FR', 'Bouches-du-Rhne'), ('FR-U83', 'FR', 'Var'), ('FR-U84', 'FR', 'Vaucluse'), ('GA-ES', 'GA', 'Estuaire'), ('GA-HO', 'GA', 'Haut-Ogooue'), ('GA-MO', 'GA', 'Moyen-Ogooue'), ('GA-NG', 'GA', 'Ngounie'), ('GA-NY', 'GA', 'Nyanga'), ('GA-OI', 'GA', 'Ogooue-Ivindo'), ('GA-OL', 'GA', 'Ogooue-Lolo'), ('GA-OM', 'GA', 'Ogooue-Maritime'), ('GA-WN', 'GA', 'Woleu-Ntem'), ('GB-ABD', 'GB', 'Aberdeenshire'), ('GB-ABE', 'GB', 'Aberdeen'), ('GB-AGB', 'GB', 'Argyll and Bute'), ('GB-AGY', 'GB', 'Isle of Anglesey'), ('GB-ANS', 'GB', 'Angus'), ('GB-ANT', 'GB', 'Antrim'), ('GB-ARD', 'GB', 'Ards'), ('GB-ARM', 'GB', 'Armagh'), ('GB-BAS', 'GB', 'Bath and North East Somerset'), ('GB-BBD', 'GB', 'Blackburn with Darwen'), ('GB-BDF', 'GB', 'Bedfordshire'), ('GB-BDG', 'GB', 'Barking and Dagenham'), ('GB-BEN', 'GB', 'Brent'), ('GB-BEX', 'GB', 'Bexley'), ('GB-BFS', 'GB', 'Belfast'), ('GB-BGE', 'GB', 'Bridgend'), ('GB-BGW', 'GB', 'Blaenau Gwent'), ('GB-BIR', 'GB', 'Birmingham'), ('GB-BKM', 'GB', 'Buckinghamshire'), ('GB-BLA', 'GB', 'Ballymena'), ('GB-BLY', 'GB', 'Ballymoney'), ('GB-BMH', 'GB', 'Bournemouth'), ('GB-BNB', 'GB', 'Banbridge'), ('GB-BNE', 'GB', 'Barnet'), ('GB-BNH', 'GB', 'Brighton and Hove'), ('GB-BNS', 'GB', 'Barnsley'), ('GB-BOL', 'GB', 'Bolton'), ('GB-BPL', 'GB', 'Blackpool'), ('GB-BRC', 'GB', 'Bracknell Forest'), ('GB-BRD', 'GB', 'Bradford'), ('GB-BRY', 'GB', 'Bromley'), ('GB-BST', 'GB', 'Bristol City of'), ('GB-BUR', 'GB', 'Bury'), ('GB-CAM', 'GB', 'Cambridgeshire'), ('GB-CAY', 'GB', 'Caerphilly'), ('GB-CGN', 'GB', 'Ceredigion'), ('GB-CGV', 'GB', 'Craigavon'), ('GB-CHS', 'GB', 'Cheshire'), ('GB-CKF', 'GB', 'Carrickfergus'), ('GB-CKT', 'GB', 'Cookstown'), ('GB-CLD', 'GB', 'Calderdale'), ('GB-CLK', 'GB', 'Clackmannanshire'), ('GB-CLR', 'GB', 'Coleraine'), ('GB-CMA', 'GB', 'Cumbria'), ('GB-CMD', 'GB', 'Camden'), ('GB-CMN', 'GB', 'Carmarthenshire'), ('GB-CON', 'GB', 'Cornwall'), ('GB-COV', 'GB', 'Coventry (West Midlands district)'), ('GB-CRF', 'GB', 'Cardiff'), ('GB-CRY', 'GB', 'Croydon'), ('GB-CSR', 'GB', 'Castlereagh'), ('GB-CWY', 'GB', 'Conwy'), ('GB-DAL', 'GB', 'Darlington'), ('GB-DBY', 'GB', 'Derbyshire'), ('GB-DEN', 'GB', 'Denbighshire'), ('GB-DER', 'GB', 'Derby'), ('GB-DEV', 'GB', 'Devon'), ('GB-DGN', 'GB', 'Dungannon and South Tyrone'), ('GB-DGY', 'GB', 'Dumfries and Galloway'), ('GB-DNC', 'GB', 'Doncaster'), ('GB-DND', 'GB', 'Dundee'), ('GB-DOR', 'GB', 'Dorset'), ('GB-DOW', 'GB', 'Down'), ('GB-DRY', 'GB', 'Derry'), ('GB-DUD', 'GB', 'Dudley (West Midlands district)'), ('GB-DUR', 'GB', 'Durham'), ('GB-EAL', 'GB', 'Ealing'), ('GB-EAY', 'GB', 'East Ayrshire'), ('GB-EDH', 'GB', 'Edinburgh'), ('GB-EDU', 'GB', 'East Dunbartonshire'), ('GB-ELN', 'GB', 'East Lothian'), ('GB-ELS', 'GB', 'Eilean Siar'), ('GB-ENF', 'GB', 'Enfield'), ('GB-ERW', 'GB', 'East Renfrewshire'), ('GB-ERY', 'GB', 'East Riding of Yorkshire'), ('GB-ESS', 'GB', 'Essex'), ('GB-ESX', 'GB', 'East Sussex'), ('GB-FAL', 'GB', 'Falkirk'), ('GB-FER', 'GB', 'Fermanagh'), ('GB-FIF', 'GB', 'Fife'), ('GB-FLN', 'GB', 'Flintshire'), ('GB-GAT', 'GB', 'Gateshead (Tyne & Wear district)'), ('GB-GLG', 'GB', 'Glasgow'), ('GB-GLS', 'GB', 'Gloucestershire'), ('GB-GRE', 'GB', 'Greenwich'), ('GB-GSY', 'GB', 'Guernsey'), ('GB-GWN', 'GB', 'Gwynedd'), ('GB-HAL', 'GB', 'Halton'), ('GB-HAM', 'GB', 'Hampshire'), ('GB-HAV', 'GB', 'Havering'), ('GB-HCK', 'GB', 'Hackney'), ('GB-HEF', 'GB', 'Herefordshire County of'), ('GB-HIL', 'GB', 'Hillingdon'), ('GB-HLD', 'GB', 'Highland'), ('GB-HMF', 'GB', 'Hammersmith and Fulham'), ('GB-HNS', 'GB', 'Hounslow'), ('GB-HPL', 'GB', 'Hartlepool'), ('GB-HRT', 'GB', 'Hertfordshire'), ('GB-HRW', 'GB', 'Harrow'), ('GB-HRY', 'GB', 'Haringey'), ('GB-IOS', 'GB', 'Isles of Scilly'), ('GB-IOW', 'GB', 'Isle of Wight'), ('GB-ISL', 'GB', 'Islington'), ('GB-IVC', 'GB', 'Inverclyde'), ('GB-JSY', 'GB', 'Jersey'), ('GB-KEC', 'GB', 'Kensington and Chelsea'), ('GB-KEN', 'GB', 'Kent'), ('GB-KHL', 'GB', 'Kingston upon Hull City of'), ('GB-KIR', 'GB', 'Kirklees'), ('GB-KTT', 'GB', 'Kingston upon Thames'), ('GB-KWL', 'GB', 'Knowsley'), ('GB-LAN', 'GB', 'Lancashire'), ('GB-LBH', 'GB', 'Lambeth'), ('GB-LCE', 'GB', 'Leicester'), ('GB-LDS', 'GB', 'Leeds'), ('GB-LEC', 'GB', 'Leicestershire'), ('GB-LEW', 'GB', 'Lewisham'), ('GB-LIN', 'GB', 'Lincolnshire'), ('GB-LIV', 'GB', 'Liverpool'), ('GB-LMV', 'GB', 'Limavady'), ('GB-LND', 'GB', 'London City of'), ('GB-LRN', 'GB', 'Larne'), ('GB-LSB', 'GB', 'Lisburn'), ('GB-LUT', 'GB', 'Luton'), ('GB-MAN', 'GB', 'Manchester'), ('GB-MDB', 'GB', 'Middlesbrough'), ('GB-MDW', 'GB', 'Medway'), ('GB-MFT', 'GB', 'Magherafelt'), ('GB-MIK', 'GB', 'Milton Keynes'), ('GB-MLN', 'GB', 'Midlothian'), ('GB-MON', 'GB', 'Monmouthshire'), ('GB-MRT', 'GB', 'Merton'), ('GB-MRY', 'GB', 'Moray'), ('GB-MTY', 'GB', 'Merthyr Tydfil'), ('GB-MYL', 'GB', 'Moyle'), ('GB-NAY', 'GB', 'North Ayrshire'), ('GB-NBL', 'GB', 'Northumberland'), ('GB-NDN', 'GB', 'North Down'), ('GB-NEL', 'GB', 'North East Lincolnshire'), ('GB-NET', 'GB', 'Newcastle upon Tyne'), ('GB-NFK', 'GB', 'Norfolk'), ('GB-NGM', 'GB', 'Nottingham'), ('GB-NLK', 'GB', 'North Lanarkshire'), ('GB-NLN', 'GB', 'North Lincolnshire'), ('GB-NSM', 'GB', 'North Somerset'), ('GB-NTA', 'GB', 'Newtownabbey'), ('GB-NTH', 'GB', 'Northamptonshire'), ('GB-NTL', 'GB', 'Neath Port Talbot'), ('GB-NTT', 'GB', 'Nottinghamshire'), ('GB-NTY', 'GB', 'North Tyneside'), ('GB-NWM', 'GB', 'Newham'), ('GB-NWP', 'GB', 'Newport'), ('GB-NYK', 'GB', 'North Yorkshire'), ('GB-NYM', 'GB', 'Newry and Mourne'), ('GB-OLD', 'GB', 'Oldham'), ('GB-OMH', 'GB', 'Omagh'), ('GB-ORK', 'GB', 'Orkney Islands'), ('GB-OXF', 'GB', 'Oxfordshire'), ('GB-PEM', 'GB', 'Pembrokeshire'), ('GB-PKN', 'GB', 'Perth and Kinross'), ('GB-PLY', 'GB', 'Plymouth'), ('GB-POL', 'GB', 'Poole'), ('GB-POR', 'GB', 'Portsmouth'), ('GB-POW', 'GB', 'Powys'), ('GB-PTE', 'GB', 'Peterborough'), ('GB-RCC', 'GB', 'Redcar and Cleveland'), ('GB-RCH', 'GB', 'Rochdale'), ('GB-RCT', 'GB', 'Rhondda Cynon Taf'), ('GB-RDB', 'GB', 'Redbridge'), ('GB-RDG', 'GB', 'Reading'), ('GB-RFW', 'GB', 'Renfrewshire'), ('GB-RIC', 'GB', 'Richmond upon Thames'), ('GB-ROT', 'GB', 'Rotherham'), ('GB-RUT', 'GB', 'Rutland'), ('GB-SAW', 'GB', 'Sandwell'), ('GB-SAY', 'GB', 'South Ayrshire'), ('GB-SCB', 'GB', 'Scottish Borders The'), ('GB-SFK', 'GB', 'Suffolk'), ('GB-SFT', 'GB', 'Sefton'), ('GB-SGC', 'GB', 'South Gloucestershire'), ('GB-SHF', 'GB', 'Sheffield'), ('GB-SHN', 'GB', 'St Helens'), ('GB-SHR', 'GB', 'Shropshire'), ('GB-SKP', 'GB', 'Stockport'), ('GB-SLF', 'GB', 'Salford'), ('GB-SLG', 'GB', 'Slough'), ('GB-SLK', 'GB', 'South Lanarkshire'), ('GB-SND', 'GB', 'Sunderland'), ('GB-SOL', 'GB', 'Solihull'), ('GB-SOM', 'GB', 'Somerset'), ('GB-SOS', 'GB', 'Southend-on-Sea'), ('GB-SRY', 'GB', 'Surrey'), ('GB-STB', 'GB', 'Strabane'), ('GB-STE', 'GB', 'Stoke-on-Trent'), ('GB-STG', 'GB', 'Stirling'), ('GB-STH', 'GB', 'Southampton'), ('GB-STN', 'GB', 'Sutton'), ('GB-STS', 'GB', 'Staffordshire'), ('GB-STT', 'GB', 'Stockton-on-Tees'), ('GB-STY', 'GB', 'South Tyneside'), ('GB-SWA', 'GB', 'Swansea'), ('GB-SWD', 'GB', 'Swindon'), ('GB-SWK', 'GB', 'Southwark'), ('GB-TAM', 'GB', 'Tameside'), ('GB-TFW', 'GB', 'Telford and Wrekin'), ('GB-THR', 'GB', 'Thurrock'), ('GB-TOB', 'GB', 'Torbay'), ('GB-TOF', 'GB', 'Torfaen'), ('GB-TRF', 'GB', 'Trafford'), ('GB-TWH', 'GB', 'Tower Hamlets'), ('GB-VGL', 'GB', 'Vale of Glamorgan'), ('GB-WAR', 'GB', 'Warwickshire'), ('GB-WBK', 'GB', 'West Berkshire'), ('GB-WDU', 'GB', 'West Dunbartonshire'), ('GB-WFT', 'GB', 'Waltham Forest'), ('GB-WGN', 'GB', 'Wigan'), ('GB-WIL', 'GB', 'Wiltshire'), ('GB-WKF', 'GB', 'Wakefield'), ('GB-WLL', 'GB', 'Walsall'), ('GB-WLN', 'GB', 'West Lothian'), ('GB-WLV', 'GB', 'Wolverhampton'), ('GB-WND', 'GB', 'Wandsworth'), ('GB-WNM', 'GB', 'Windsor and Maidenhead'), ('GB-WOK', 'GB', 'Wokingham'), ('GB-WOR', 'GB', 'Worcestershire'), ('GB-WRL', 'GB', 'Wirral'), ('GB-WRT', 'GB', 'Warrington'), ('GB-WRX', 'GB', 'Wrexham'), ('GB-WSM', 'GB', 'Westminster'), ('GB-WSX', 'GB', 'West Sussex'), ('GB-YOR', 'GB', 'York'), ('GB-ZET', 'GB', 'Shetland Islands'), ('GD-A', 'GD', 'Saint Andrew'), ('GD-C', 'GD', 'Carriacou'), ('GD-D', 'GD', 'Saint David'), ('GD-G', 'GD', 'Saint George'), ('GD-J', 'GD', 'Saint John'), ('GD-M', 'GD', 'Saint Mark'), ('GD-P', 'GD', 'Saint Patrick'), ('GD-Q', 'GD', 'Petit Martinique'), ('GE-AB', 'GE', 'Abkhazia'), ('GE-AJ', 'GE', 'Ajaria'), ('GE-GU', 'GE', 'Guria'), ('GE-IM', 'GE', 'Imereti'), ('GE-KA', 'GE', 'Kakheti'), ('GE-KK', 'GE', 'Kvemo Kartli'), ('GE-MM', 'GE', 'Mtskheta-Mtianeti'), ('GE-RL', 'GE', 'Racha Lechkhumi and Kvemo Svaneti'), ('GE-SJ', 'GE', 'Samtskhe-Javakheti'), ('GE-SK', 'GE', 'Shida Kartli'), ('GE-SZ', 'GE', 'Samegrelo-Zemo Svaneti'), ('GE-TB', 'GE', 'Tbilisi'), ('GH-AS', 'GH', 'Ashanti Region'), ('GH-BA', 'GH', 'Brong-Ahafo Region'), ('GH-CE', 'GH', 'Central Region'), ('GH-EA', 'GH', 'Eastern Region'), ('GH-GA', 'GH', 'Greater Accra Region'), ('GH-NO', 'GH', 'Northern Region'), ('GH-UE', 'GH', 'Upper East Region'), ('GH-UW', 'GH', 'Upper West Region'), ('GH-VO', 'GH', 'Volta Region'), ('GH-WE', 'GH', 'Western Region'), ('GL-A', 'GL', 'Avannaa'), ('GL-K', 'GL', 'Kitaa'), ('GL-T', 'GL', 'Tunu'), ('GM-BJ', 'GM', 'Banjul'), ('GM-BR', 'GM', 'Brikama'), ('GM-BS', 'GM', 'Basse'), ('GM-CR', 'GM', 'Central River'), ('GM-JA', 'GM', 'Janjangbure'), ('GM-KA', 'GM', 'Kanifeng'), ('GM-KE', 'GM', 'Kerewan'), ('GM-KU', 'GM', 'Kuntaur'), ('GM-LR', 'GM', 'Lower River'), ('GM-MA', 'GM', 'Mansakonko'), ('GM-NB', 'GM', 'North Bank'), ('GM-UR', 'GM', 'Upper River'), ('GM-WE', 'GM', 'Western'), ('GN-BFA', 'GN', 'Boffa'), ('GN-BOK', 'GN', 'Boke'), ('GN-BYL', 'GN', 'Beyla'), ('GN-CNK', 'GN', 'Conakry'), ('GN-COY', 'GN', 'Coyah'), ('GN-DBL', 'GN', 'Dabola'), ('GN-DBR', 'GN', 'Dubreka'), ('GN-DGR', 'GN', 'Dinguiraye'), ('GN-DLB', 'GN', 'Dalaba'), ('GN-FRC', 'GN', 'Forecariah'), ('GN-FRI', 'GN', 'Fria'), ('GN-FRN', 'GN', 'Faranah'), ('GN-GAO', 'GN', 'Gaoual'), ('GN-GCD', 'GN', 'Gueckedou'), ('GN-KBA', 'GN', 'Koubia'), ('GN-KDA', 'GN', 'Koundara'), ('GN-KND', 'GN', 'Kindia'), ('GN-KNK', 'GN', 'Kankan'), ('GN-KRA', 'GN', 'Kouroussa'), ('GN-KRN', 'GN', 'Kerouane'), ('GN-KSD', 'GN', 'Kissidougou'), ('GN-LAB', 'GN', 'Labe'), ('GN-LLM', 'GN', 'Lelouma'), ('GN-LOL', 'GN', 'Lola'), ('GN-MAL', 'GN', 'Mali'), ('GN-MAM', 'GN', 'Mamou'), ('GN-MAN', 'GN', 'Mandiana'), ('GN-MCT', 'GN', 'Macenta'), ('GN-NZR', 'GN', 'Nzerekore'), ('GN-PIT', 'GN', 'Pita'), ('GN-SIG', 'GN', 'Siguiri'), ('GN-TLM', 'GN', 'Telimele'), ('GN-TOG', 'GN', 'Tougue'), ('GN-YOM', 'GN', 'Yomou'), ('GQ-AN', 'GQ', 'Provincia Annobon'), ('GQ-BN', 'GQ', 'Provincia Bioko Norte'), ('GQ-BS', 'GQ', 'Provincia Bioko Sur'), ('GQ-CS', 'GQ', 'Provincia Centro Sur'), ('GQ-KN', 'GQ', 'Provincia Kie-Ntem'), ('GQ-LI', 'GQ', 'Provincia Litoral'), ('GQ-WN', 'GQ', 'Provincia Wele-Nzas'), ('GR-AT', 'GR', 'Attica'), ('GR-CM', 'GR', 'Central Macedonia'), ('GR-CN', 'GR', 'Central Greece'), ('GR-CR', 'GR', 'Crete'), ('GR-EM', 'GR', 'East Macedonia and Thrace'), ('GR-EP', 'GR', 'Epirus'), ('GR-II', 'GR', 'Ionian Islands'), ('GR-NA', 'GR', 'North Aegean'), ('GR-PP', 'GR', 'Peloponnesos'), ('GR-SA', 'GR', 'South Aegean'), ('GR-TH', 'GR', 'Thessaly'), ('GR-WG', 'GR', 'West Greece'), ('GR-WM', 'GR', 'West Macedonia'), ('GT-AV', 'GT', 'Alta Verapaz'), ('GT-BV', 'GT', 'Baja Verapaz'), ('GT-CM', 'GT', 'Chimaltenango'), ('GT-CQ', 'GT', 'Chiquimula'), ('GT-ES', 'GT', 'Escuintla'), ('GT-GU', 'GT', 'Guatemala'), ('GT-HU', 'GT', 'Huehuetenango'), ('GT-IZ', 'GT', 'Izabal'), ('GT-JA', 'GT', 'Jalapa'), ('GT-JU', 'GT', 'Jutiapa'), ('GT-PE', 'GT', 'El Peten'), ('GT-PR', 'GT', 'El Progreso'), ('GT-QC', 'GT', 'El Quiche'), ('GT-QZ', 'GT', 'Quetzaltenango'), ('GT-RE', 'GT', 'Retalhuleu'), ('GT-SM', 'GT', 'San Marcos'), ('GT-SO', 'GT', 'Solola'), ('GT-SR', 'GT', 'Santa Rosa'), ('GT-ST', 'GT', 'Sacatepequez'), ('GT-SU', 'GT', 'Suchitepequez'), ('GT-TO', 'GT', 'Totonicapan'), ('GT-ZA', 'GT', 'Zacapa'), ('GW-BB', 'GW', 'Biombo Region'), ('GW-BF', 'GW', 'Bafata Region'), ('GW-BL', 'GW', 'Bolama Region'), ('GW-BS', 'GW', 'Bissau Region'), ('GW-CA', 'GW', 'Cacheu Region'), ('GW-GA', 'GW', 'Gabu Region'), ('GW-OI', 'GW', 'Oio Region'), ('GW-QU', 'GW', 'Quinara Region'), ('GW-TO', 'GW', 'Tombali Region'), ('GY-BW', 'GY', 'Barima-Waini'), ('GY-CM', 'GY', 'Cuyuni-Mazaruni'), ('GY-DM', 'GY', 'Demerara-Mahaica'), ('GY-EC', 'GY', 'East Berbice-Corentyne'), ('GY-EW', 'GY', 'Essequibo Islands-West Demerara'), ('GY-MB', 'GY', 'Mahaica-Berbice'), ('GY-PI', 'GY', 'Potaro-Siparuni'), ('GY-PM', 'GY', 'Pomeroon-Supenaam'), ('GY-UD', 'GY', 'Upper Demerara-Berbice'), ('GY-UT', 'GY', 'Upper Takutu-Upper Essequibo'), ('HK-HCW', 'HK', 'Central and Western Hong Kong Island'), ('HK-HEA', 'HK', 'Eastern Hong Kong Island'), ('HK-HSO', 'HK', 'Southern Hong Kong Island'), ('HK-HWC', 'HK', 'Wan Chai Hong Kong Island'), ('HK-KKC', 'HK', 'Kowloon City Kowloon'), ('HK-KKT', 'HK', 'Kwun Tong Kowloon'), ('HK-KSS', 'HK', 'Sham Shui Po Kowloon'), ('HK-KWT', 'HK', 'Wong Tai Sin Kowloon'), ('HK-KYT', 'HK', 'Yau Tsim Mong Kowloon'), ('HK-NIS', 'HK', 'Islands New Territories'), ('HK-NKT', 'HK', 'Kwai Tsing New Territories'), ('HK-NNO', 'HK', 'North New Territories'), ('HK-NSK', 'HK', 'Sai Kung New Territories'), ('HK-NST', 'HK', 'Sha Tin New Territories'), ('HK-NTM', 'HK', 'Tuen Mun New Territories'), ('HK-NTP', 'HK', 'Tai Po New Territories'), ('HK-NTW', 'HK', 'Tsuen Wan New Territories'), ('HK-NYL', 'HK', 'Yuen Long New Territories'), ('HM-F', 'HM', 'Flat Island'), ('HM-H', 'HM', 'Heard Island'), ('HM-M', 'HM', 'McDonald Island'), ('HM-S', 'HM', 'Shag Island'), ('HN-AT', 'HN', 'Atlantida'), ('HN-CH', 'HN', 'Choluteca'), ('HN-CL', 'HN', 'Colon'), ('HN-CM', 'HN', 'Comayagua'), ('HN-CP', 'HN', 'Copan'), ('HN-CR', 'HN', 'Cortes'), ('HN-FM', 'HN', 'Francisco Morazan'), ('HN-GD', 'HN', 'Gracias a Dios'), ('HN-IB', 'HN', 'Islas de la Bahia (Bay Islands)'), ('HN-IN', 'HN', 'Intibuca'), ('HN-LE', 'HN', 'Lempira'), ('HN-OC', 'HN', 'Ocotepeque'), ('HN-OL', 'HN', 'Olancho'), ('HN-PA', 'HN', 'El Paraiso'), ('HN-PZ', 'HN', 'La Paz'), ('HN-SB', 'HN', 'Santa Barbara'), ('HN-VA', 'HN', 'Valle'), ('HN-YO', 'HN', 'Yoro'), ('HR-01', 'HR', 'Zagreb county'), ('HR-02', 'HR', 'Krapina-Zagorje county'), ('HR-03', 'HR', 'Sisak-Moslavina county'), ('HR-04', 'HR', 'Karlovac county'), ('HR-05', 'HR', 'Varazdin county'), ('HR-06', 'HR', 'Koprivnica-Krizevci county'), ('HR-07', 'HR', 'Bjelovar-Bilogora county'), ('HR-08', 'HR', 'Primorje-Gorski Kotar county'), ('HR-09', 'HR', 'Lika-Senj county'), ('HR-10', 'HR', 'Virovitica-Podravina county'), ('HR-11', 'HR', 'Pozega-Slavonia county'), ('HR-12', 'HR', 'Brod-Posavina county'), ('HR-13', 'HR', 'Zadar county'), ('HR-14', 'HR', 'Osijek-Baranja county'), ('HR-15', 'HR', 'Sibenik-Knin county'), ('HR-16', 'HR', 'Vukovar-Srijem county'), ('HR-17', 'HR', 'Split-Dalmatia county'), ('HR-18', 'HR', 'Istria county'), ('HR-19', 'HR', 'Dubrovnik-Neretva county'), ('HR-20', 'HR', 'Medjimurje county'), ('HR-21', 'HR', 'Zagreb (city)'), ('HT-AR', 'HT', 'Artibonite'), ('HT-CE', 'HT', 'Centre'), ('HT-GA', 'HT', 'Grand''Anse'), ('HT-ND', 'HT', 'Nord'), ('HT-NE', 'HT', 'Nord-Est'), ('HT-NO', 'HT', 'Nord-Ouest'), ('HT-OU', 'HT', 'Ouest'), ('HT-SD', 'HT', 'Sud'), ('HT-SE', 'HT', 'Sud-Est'), ('HU-BA', 'HU', 'Borsod-Abauj-Zemplen'), ('HU-BC', 'HU', 'Bekescsaba'), ('HU-BK', 'HU', 'Bacs-Kiskun'), ('HU-BR', 'HU', 'Baranya'), ('HU-BS', 'HU', 'Bekes'), ('HU-BU', 'HU', 'Budapest'), ('HU-CG', 'HU', 'Csongrad'), ('HU-DB', 'HU', 'Debrecen'), ('HU-DJ', 'HU', 'Dunaujvaros'), ('HU-EG', 'HU', 'Eger'), ('HU-FJ', 'HU', 'Fejer'), ('HU-GM', 'HU', 'Gyor-Moson-Sopron'), ('HU-GY', 'HU', 'Gyor'), ('HU-HB', 'HU', 'Hajdu-Bihar'), ('HU-HM', 'HU', 'Hodmezovasarhely'), ('HU-HV', 'HU', 'Heves'), ('HU-JN', 'HU', 'Jasz-Nagykun-Szolnok'), ('HU-KC', 'HU', 'Kecskemet'), ('HU-KE', 'HU', 'Komarom-Esztergom'), ('HU-KP', 'HU', 'Kaposvar'), ('HU-MK', 'HU', 'Miskolc'), ('HU-NG', 'HU', 'Nograd'), ('HU-NK', 'HU', 'Nagykanizsa'), ('HU-NY', 'HU', 'Nyiregyhaza'), ('HU-PC', 'HU', 'Pecs'), ('HU-PE', 'HU', 'Pest'), ('HU-SB', 'HU', 'Szombathely'), ('HU-SG', 'HU', 'Szeged'), ('HU-SK', 'HU', 'Szekesfehervar'), ('HU-SL', 'HU', 'Szolnok'), ('HU-SM', 'HU', 'Somogy'), ('HU-SO', 'HU', 'Sopron'), ('HU-SS', 'HU', 'Szabolcs-Szatmar-Bereg'), ('HU-TB', 'HU', 'Tatabanya'), ('HU-TO', 'HU', 'Tolna'), ('HU-VA', 'HU', 'Vas'), ('HU-VZ', 'HU', 'Veszprem'), ('HU-ZA', 'HU', 'Zala'), ('HU-ZG', 'HU', 'Zalaegerszeg'), ('ID-AC', 'ID', 'Aceh'), ('ID-BA', 'ID', 'Bali'), ('ID-BB', 'ID', 'Bangka-Belitung'), ('ID-BE', 'ID', 'Bengkulu'), ('ID-BT', 'ID', 'Banten'), ('ID-GO', 'ID', 'Gorontalo'), ('ID-IJ', 'ID', 'Papua'), ('ID-JA', 'ID', 'Jambi'), ('ID-JI', 'ID', 'Jawa Timur'), ('ID-JK', 'ID', 'Jakarta Raya'), ('ID-JR', 'ID', 'Jawa Barat'), ('ID-JT', 'ID', 'Jawa Tengah'), ('ID-KB', 'ID', 'Kalimantan Barat'), ('ID-KI', 'ID', 'Kalimantan Timur'), ('ID-KS', 'ID', 'Kalimantan Selatan'), ('ID-KT', 'ID', 'Kalimantan Tengah'), ('ID-LA', 'ID', 'Lampung'), ('ID-MA', 'ID', 'Maluku'), ('ID-MU', 'ID', 'Maluku Utara'), ('ID-NB', 'ID', 'Nusa Tenggara Barat'), ('ID-NT', 'ID', 'Nusa Tenggara Timur'), ('ID-RI', 'ID', 'Riau'), ('ID-SB', 'ID', 'Sumatera Barat'), ('ID-SG', 'ID', 'Sulawesi Tenggara'), ('ID-SL', 'ID', 'Sumatera Selatan'), ('ID-SN', 'ID', 'Sulawesi Selatan'), ('ID-ST', 'ID', 'Sulawesi Tengah'), ('ID-SU', 'ID', 'Sumatera Utara'), ('ID-SW', 'ID', 'Sulawesi Utara'), ('ID-YO', 'ID', 'Yogyakarta'), ('IE-CK', 'IE', 'Cork'), ('IE-CL', 'IE', 'Clare'), ('IE-CV', 'IE', 'Cavan'), ('IE-CW', 'IE', 'Carlow'), ('IE-DB', 'IE', 'Dublin'), ('IE-DG', 'IE', 'Donegal'), ('IE-GW', 'IE', 'Galway'), ('IE-KD', 'IE', 'Kildare'), ('IE-KK', 'IE', 'Kilkenny'), ('IE-KR', 'IE', 'Kerry'), ('IE-LA', 'IE', 'Laois'), ('IE-LF', 'IE', 'Longford'), ('IE-LM', 'IE', 'Limerick'), ('IE-LR', 'IE', 'Leitrim'), ('IE-LT', 'IE', 'Louth'), ('IE-MG', 'IE', 'Monaghan'), ('IE-MT', 'IE', 'Meath'), ('IE-MY', 'IE', 'Mayo'), ('IE-OF', 'IE', 'Offaly'), ('IE-RC', 'IE', 'Roscommon'), ('IE-SL', 'IE', 'Sligo'), ('IE-TP', 'IE', 'Tipperary'), ('IE-WF', 'IE', 'Waterford'), ('IE-WK', 'IE', 'Wicklow'), ('IE-WM', 'IE', 'Westmeath'), ('IE-WX', 'IE', 'Wexford'), ('IL-C', 'IL', 'Central'), ('IL-H', 'IL', 'Haifa'), ('IL-J', 'IL', 'Jerusalem'), ('IL-N', 'IL', 'Northern'), ('IL-S', 'IL', 'Southern'), ('IL-T', 'IL', 'Tel Aviv'), ('IN-AN', 'IN', 'Andaman and Nicobar Islands'), ('IN-AP', 'IN', 'Andhra Pradesh'), ('IN-AR', 'IN', 'Arunachal Pradesh'), ('IN-AS', 'IN', 'Assam'), ('IN-BR', 'IN', 'Bihar'), ('IN-CH', 'IN', 'Chandigarh'), ('IN-CT', 'IN', 'Chhattisgarh'), ('IN-DD', 'IN', 'Daman and Diu'), ('IN-DL', 'IN', 'Delhi'), ('IN-DN', 'IN', 'Dadra and Nagar Haveli'), ('IN-GA', 'IN', 'Goa'), ('IN-GJ', 'IN', 'Gujarat'), ('IN-HP', 'IN', 'Himachal Pradesh'), ('IN-HR', 'IN', 'Haryana'), ('IN-JH', 'IN', 'Jharkhand'), ('IN-JK', 'IN', 'Jammu and Kashmir'), ('IN-KA', 'IN', 'Karnataka'), ('IN-KL', 'IN', 'Kerala'), ('IN-LD', 'IN', 'Lakshadweep'), ('IN-ML', 'IN', 'Meghalaya'), ('IN-MM', 'IN', 'Maharashtra'), ('IN-MN', 'IN', 'Manipur'), ('IN-MP', 'IN', 'Madhya Pradesh'), ('IN-MZ', 'IN', 'Mizoram'), ('IN-NL', 'IN', 'Nagaland'), ('IN-OR', 'IN', 'Orissa'), ('IN-PB', 'IN', 'Punjab'), ('IN-PY', 'IN', 'Pondicherry'), ('IN-RJ', 'IN', 'Rajasthan'), ('IN-SK', 'IN', 'Sikkim'), ('IN-TN', 'IN', 'Tamil Nadu'), ('IN-TR', 'IN', 'Tripura'), ('IN-UL', 'IN', 'Uttaranchal'), ('IN-UP', 'IN', 'Uttar Pradesh'), ('IN-WB', 'IN', 'West Bengal'), ('IO-DG', 'IO', 'Diego Garcia'), ('IO-DI', 'IO', 'Danger Island'), ('IO-EA', 'IO', 'Eagle Islands'), ('IO-EG', 'IO', 'Egmont Islands'), ('IO-NI', 'IO', 'Nelsons Island'), ('IO-PB', 'IO', 'Peros Banhos'), ('IO-SI', 'IO', 'Salomon Islands'), ('IO-TB', 'IO', 'Three Brothers'), ('IQ-AB', 'IQ', 'Al Anbar'), ('IQ-AL', 'IQ', 'Arbil'), ('IQ-BA', 'IQ', 'Al Basrah'), ('IQ-BB', 'IQ', 'Babil'), ('IQ-BD', 'IQ', 'Baghdad'), ('IQ-DH', 'IQ', 'Dahuk'), ('IQ-DQ', 'IQ', 'Dhi Qar'), ('IQ-DY', 'IQ', 'Diyala'), ('IQ-KB', 'IQ', 'Al Karbala'), ('IQ-MU', 'IQ', 'Al Muthanna'), ('IQ-MY', 'IQ', 'Maysan'), ('IQ-NJ', 'IQ', 'An Najaf'), ('IQ-NN', 'IQ', 'Ninawa'), ('IQ-QA', 'IQ', 'Al Qadisyah'), ('IQ-SD', 'IQ', 'Salah ad Din'), ('IQ-SL', 'IQ', 'As Sulaymaniyah'), ('IQ-TM', 'IQ', 'At Ta''mim'), ('IQ-WS', 'IQ', 'Wasit'), ('IR-ARD', 'IR', 'Ardabil'), ('IR-BSH', 'IR', 'Bushehr'), ('IR-CMB', 'IR', 'Chahar Mahaal and Bakhtiari'), ('IR-EAZ', 'IR', 'East Azarbaijan'), ('IR-EFH', 'IR', 'Esfahan'), ('IR-FAR', 'IR', 'Fars'), ('IR-GIL', 'IR', 'Gilan'), ('IR-GLS', 'IR', 'Golestan'), ('IR-HMD', 'IR', 'Hamadan'), ('IR-HRM', 'IR', 'Hormozgan'), ('IR-ILM', 'IR', 'Ilam'), ('IR-KBA', 'IR', 'Kohkiluyeh and Buyer Ahmad'), ('IR-KRB', 'IR', 'Kerman'), ('IR-KRD', 'IR', 'Kurdistan'), ('IR-KRM', 'IR', 'Kermanshah'), ('IR-KZT', 'IR', 'Khuzestan'), ('IR-LRS', 'IR', 'Lorestan'), ('IR-MKZ', 'IR', 'Markazi'), ('IR-MZD', 'IR', 'Mazandaran'), ('IR-NKH', 'IR', 'North Khorasan'), ('IR-QAZ', 'IR', 'Qazvin'), ('IR-QOM', 'IR', 'Qom'), ('IR-RKH', 'IR', 'Razavi Khorasan'), ('IR-SBL', 'IR', 'Sistan and Baluchistan'), ('IR-SKH', 'IR', 'South Khorasan'), ('IR-SMN', 'IR', 'Semnan'), ('IR-TEH', 'IR', 'Tehran'), ('IR-WEZ', 'IR', 'West Azarbaijan'), ('IR-YZD', 'IR', 'Yazd'), ('IR-ZAN', 'IR', 'Zanjan'), ('IS-AL', 'IS', 'Austurland'), ('IS-HF', 'IS', 'Hofuoborgarsvaeoi'), ('IS-NE', 'IS', 'Norourland eystra'), ('IS-NV', 'IS', 'Norourland vestra'), ('IS-SL', 'IS', 'Suourland'), ('IS-SN', 'IS', 'Suournes'), ('IS-VF', 'IS', 'Vestfiroir'), ('IS-VL', 'IS', 'Vesturland'), ('IT-AG', 'IT', 'Agrigento'), ('IT-AL', 'IT', 'Alessandria'), ('IT-AN', 'IT', 'Ancona'), ('IT-AO', 'IT', 'Aosta'), ('IT-AP', 'IT', 'Ascoli Piceno'), ('IT-AQ', 'IT', 'L''Aquila'), ('IT-AR', 'IT', 'Arezzo'), ('IT-AT', 'IT', 'Asti'), ('IT-AV', 'IT', 'Avellino'), ('IT-BA', 'IT', 'Bari'), ('IT-BG', 'IT', 'Bergamo'), ('IT-BI', 'IT', 'Biella'), ('IT-BL', 'IT', 'Belluno'), ('IT-BN', 'IT', 'Benevento'), ('IT-BO', 'IT', 'Bologna'), ('IT-BR', 'IT', 'Brindisi'), ('IT-BS', 'IT', 'Brescia'), ('IT-BZ', 'IT', 'Bolzano'), ('IT-CA', 'IT', 'Cagliari'), ('IT-CB', 'IT', 'Campobasso'), ('IT-CE', 'IT', 'Caserta'), ('IT-CH', 'IT', 'Chieti'), ('IT-CL', 'IT', 'Caltanissetta'), ('IT-CN', 'IT', 'Cuneo'), ('IT-CO', 'IT', 'Como'), ('IT-CR', 'IT', 'Cremona'), ('IT-CS', 'IT', 'Cosenza'), ('IT-CT', 'IT', 'Catania'), ('IT-CZ', 'IT', 'Catanzaro'), ('IT-EN', 'IT', 'Enna'), ('IT-FE', 'IT', 'Ferrara'), ('IT-FG', 'IT', 'Foggia'), ('IT-FI', 'IT', 'Firenze'), ('IT-FO', 'IT', 'ForlO?esena'), ('IT-FR', 'IT', 'Frosinone'), ('IT-GE', 'IT', 'Genova'), ('IT-GO', 'IT', 'Gorizia'), ('IT-GR', 'IT', 'Grosseto'), ('IT-IM', 'IT', 'Imperia'), ('IT-IS', 'IT', 'Isernia'), ('IT-KR', 'IT', 'Crotone'), ('IT-LC', 'IT', 'Lecco'), ('IT-LE', 'IT', 'Lecce'), ('IT-LI', 'IT', 'Livorno'), ('IT-LO', 'IT', 'Lodi'), ('IT-LT', 'IT', 'Latina'), ('IT-LU', 'IT', 'Lucca'), ('IT-MC', 'IT', 'Macerata'), ('IT-ME', 'IT', 'Messina'), ('IT-MI', 'IT', 'Milano'), ('IT-MN', 'IT', 'Mantova'), ('IT-MO', 'IT', 'Modena'), ('IT-MS', 'IT', 'Massa-Carrara'), ('IT-MT', 'IT', 'Matera'), ('IT-NA', 'IT', 'Naploli'), ('IT-NO', 'IT', 'Novara'), ('IT-NU', 'IT', 'Nuoro'), ('IT-OR', 'IT', 'Oristano'), ('IT-PA', 'IT', 'Palermo'), ('IT-PC', 'IT', 'Piacenza'), ('IT-PD', 'IT', 'Padova'), ('IT-PE', 'IT', 'Pescara'), ('IT-PG', 'IT', 'Perugia'), ('IT-PI', 'IT', 'Pisa'), ('IT-PN', 'IT', 'Pordenone'), ('IT-PO', 'IT', 'Prato'), ('IT-PR', 'IT', 'Parma'), ('IT-PS', 'IT', 'Pesaro e Urbino'), ('IT-PT', 'IT', 'Pistoia'), ('IT-PV', 'IT', 'Pavia'), ('IT-PZ', 'IT', 'Potenza'), ('IT-RA', 'IT', 'Ravenna'), ('IT-RC', 'IT', 'Reggio Calabria'), ('IT-RE', 'IT', 'Reggio Emilia'), ('IT-RG', 'IT', 'Ragusa'), ('IT-RI', 'IT', 'Rieti'), ('IT-RM', 'IT', 'Roma'), ('IT-RN', 'IT', 'Rimini'), ('IT-RO', 'IT', 'Rovigo'), ('IT-SA', 'IT', 'Salerno'), ('IT-SI', 'IT', 'Siena'), ('IT-SO', 'IT', 'Sondrio'), ('IT-SP', 'IT', 'La Spezia'), ('IT-SR', 'IT', 'Siracusa'), ('IT-SS', 'IT', 'Sassari'), ('IT-SV', 'IT', 'Savona'), ('IT-TA', 'IT', 'Taranto'), ('IT-TE', 'IT', 'Teramo'), ('IT-TN', 'IT', 'Trento'), ('IT-TO', 'IT', 'Torino'), ('IT-TP', 'IT', 'Trapani'), ('IT-TR', 'IT', 'Terni'), ('IT-TS', 'IT', 'Trieste'), ('IT-TV', 'IT', 'Treviso'), ('IT-UD', 'IT', 'Udine'), ('IT-VA', 'IT', 'Varese'), ('IT-VB', 'IT', 'Verbano-Cusio-Ossola'), ('IT-VC', 'IT', 'Vercelli'), ('IT-VE', 'IT', 'Venezia'), ('IT-VI', 'IT', 'Vicenza'), ('IT-VR', 'IT', 'Verona'), ('IT-VT', 'IT', 'Viterbo'), ('IT-VV', 'IT', 'Vibo Valentia'), ('JM-AND', 'JM', 'Saint Andrew Parish'), ('JM-ANN', 'JM', 'Saint Ann Parish'), ('JM-CAT', 'JM', 'Saint Catherine Parish'), ('JM-CLA', 'JM', 'Clarendon Parish'), ('JM-ELI', 'JM', 'Saint Elizabeth Parish'), ('JM-HAN', 'JM', 'Hanover Parish'), ('JM-JAM', 'JM', 'Saint James Parish'), ('JM-KIN', 'JM', 'Kingston Parish'), ('JM-MAN', 'JM', 'Manchester Parish'), ('JM-MAR', 'JM', 'Saint Mary Parish'), ('JM-POR', 'JM', 'Portland Parish'), ('JM-THO', 'JM', 'Saint Thomas Parish'), ('JM-TRL', 'JM', 'Trelawny Parish'), ('JM-WML', 'JM', 'Westmoreland Parish'), ('JO-AJ', 'JO', 'Ajlun'), ('JO-AM', 'JO', '''Amman'), ('JO-AQ', 'JO', 'Al ''Aqabah'), ('JO-BA', 'JO', 'Al Balqa'''), ('JO-IR', 'JO', 'Irbid'), ('JO-JA', 'JO', 'Jarash'), ('JO-KA', 'JO', 'Al Karak'), ('JO-MD', 'JO', 'Madaba'), ('JO-MF', 'JO', 'Al Mafraq'), ('JO-MN', 'JO', 'Ma''an'), ('JO-TA', 'JO', 'At Tafilah'), ('JO-ZA', 'JO', 'Az Zarqa'''), ('JP-01', 'JP', 'Hokkaido'), ('JP-02', 'JP', 'Aomori'), ('JP-03', 'JP', 'Iwate'), ('JP-04', 'JP', 'Miyagi'), ('JP-05', 'JP', 'Akita'), ('JP-06', 'JP', 'Yamagata'), ('JP-07', 'JP', 'Hukusima (Fukushima)'), ('JP-08', 'JP', 'Ibaraki'), ('JP-09', 'JP', 'Totigi (Tochigi)'), ('JP-10', 'JP', 'Gunma'), ('JP-11', 'JP', 'Saitama'), ('JP-12', 'JP', 'Tiba (Chiba)'), ('JP-13', 'JP', 'Tokyo'), ('JP-14', 'JP', 'Kanagawa'), ('JP-15', 'JP', 'Niigata'), ('JP-16', 'JP', 'Toyama'), ('JP-17', 'JP', 'Isikawa (Ishikawa)'), ('JP-18', 'JP', 'Hukui (Fukui)'), ('JP-19', 'JP', 'Yamanasi (Yamanashi)'), ('JP-20', 'JP', 'Nagano'), ('JP-21', 'JP', 'Gihu (Gifu)'), ('JP-22', 'JP', 'Sizuoka (Shizuoka)'), ('JP-23', 'JP', 'Aiti (Aichi)'), ('JP-24', 'JP', 'Mie'), ('JP-25', 'JP', 'Siga (Shiga)'), ('JP-26', 'JP', 'Kyoto'), ('JP-27', 'JP', 'Osaka'), ('JP-28', 'JP', 'Hyogo'), ('JP-29', 'JP', 'Nara'), ('JP-30', 'JP', 'Wakayama'), ('JP-31', 'JP', 'Tottori'), ('JP-32', 'JP', 'Simane (Shimane)'), ('JP-33', 'JP', 'Okayama'), ('JP-34', 'JP', 'Hirosima (Hiroshima)'), ('JP-35', 'JP', 'Yamaguti (Yamaguchi)'), ('JP-36', 'JP', 'Tokusima (Tokushima)'), ('JP-37', 'JP', 'Kagawa'), ('JP-38', 'JP', 'Ehime'), ('JP-39', 'JP', 'Koti (Kochi)'), ('JP-40', 'JP', 'Hukuoka (Fukuoka)'), ('JP-41', 'JP', 'Saga'), ('JP-42', 'JP', 'Nagasaki'), ('JP-43', 'JP', 'Kumamoto'), ('JP-44', 'JP', 'Oita'), ('JP-45', 'JP', 'Miyazaki'), ('JP-46', 'JP', 'Kagosima (Kagoshima)'), ('JP-47', 'JP', 'Okinawa'), ('KE-CE', 'KE', 'Central'), ('KE-CO', 'KE', 'Coast'), ('KE-EA', 'KE', 'Eastern'), ('KE-NA', 'KE', 'Nairobi Area'), ('KE-NE', 'KE', 'North Eastern'), ('KE-NY', 'KE', 'Nyanza'), ('KE-RV', 'KE', 'Rift Valley'), ('KE-WE', 'KE', 'Western'), ('KG-B', 'KG', 'Batken'), ('KG-C', 'KG', 'Chu'), ('KG-GB', 'KG', 'Bishkek'), ('KG-J', 'KG', 'Jalal-Abad'), ('KG-N', 'KG', 'Naryn'), ('KG-O', 'KG', 'Osh'), ('KG-T', 'KG', 'Talas'), ('KG-Y', 'KG', 'Ysyk-Kol'), ('KH-BA', 'KH', 'Battambang'), ('KH-BM', 'KH', 'Banteay Meanchey'), ('KH-KB', 'KH', 'Keb'), ('KH-KK', 'KH', 'Kaoh Kong'), ('KH-KL', 'KH', 'Kandal'), ('KH-KM', 'KH', 'Kampong Cham'), ('KH-KN', 'KH', 'Kampong Chhnang'), ('KH-KO', 'KH', 'Kampong Som'), ('KH-KP', 'KH', 'Kampot'), ('KH-KR', 'KH', 'Kratie'), ('KH-KT', 'KH', 'Kampong Thom'), ('KH-KU', 'KH', 'Kampong Speu'), ('KH-MK', 'KH', 'Mondul Kiri'), ('KH-OM', 'KH', 'Oddar Meancheay'), ('KH-PA', 'KH', 'Pailin'), ('KH-PG', 'KH', 'Prey Veng'), ('KH-PP', 'KH', 'Phnom Penh'), ('KH-PR', 'KH', 'Preah Vihear'), ('KH-PS', 'KH', 'Preah Seihanu (Kompong Som or Sihanoukville)'), ('KH-PU', 'KH', 'Pursat'), ('KH-RK', 'KH', 'Ratanak Kiri'), ('KH-SI', 'KH', 'Siemreap'), ('KH-SR', 'KH', 'Svay Rieng'), ('KH-ST', 'KH', 'Stung Treng'), ('KH-TK', 'KH', 'Takeo'), ('KI-AG', 'KI', 'Abaiang'), ('KI-AK', 'KI', 'Aranuka'), ('KI-AM', 'KI', 'Abemama'), ('KI-AO', 'KI', 'Arorae'), ('KI-BA', 'KI', 'Banaba'), ('KI-BE', 'KI', 'Beru'), ('KI-KA', 'KI', 'Kanton'), ('KI-KR', 'KI', 'Kiritimati'), ('KI-KU', 'KI', 'Kuria'), ('KI-ME', 'KI', 'Marakei'), ('KI-MI', 'KI', 'Maiana'), ('KI-MN', 'KI', 'Makin'), ('KI-NI', 'KI', 'Nikunau'), ('KI-NO', 'KI', 'Nonouti'), ('KI-ON', 'KI', 'Onotoa'), ('KI-TE', 'KI', 'Teraina'), ('KI-TM', 'KI', 'Tamana'), ('KI-TR', 'KI', 'Tabuaeran'), ('KI-TT', 'KI', 'Tabiteuea'), ('KI-TW', 'KI', 'Tarawa'), ('KI-bT', 'KI', 'Butaritari'), ('KM-A', 'KM', 'Anjouan'), ('KM-G', 'KM', 'Grande Comore'), ('KM-M', 'KM', 'Moheli'), ('KN-CAP', 'KN', 'Saint Paul Capesterre'), ('KN-CCN', 'KN', 'Christ Church Nichola Town'), ('KN-CHA', 'KN', 'Saint Paul Charlestown'), ('KN-SAS', 'KN', 'Saint Anne Sandy Point'), ('KN-SGB', 'KN', 'Saint George Basseterre'), ('KN-SGG', 'KN', 'Saint George Gingerland'), ('KN-SJC', 'KN', 'Saint John Capesterre'), ('KN-SJF', 'KN', 'Saint John Figtree'), ('KN-SJW', 'KN', 'Saint James Windward'), ('KN-SMC', 'KN', 'Saint Mary Cayon'), ('KN-SPB', 'KN', 'Saint Peter Basseterre'), ('KN-STL', 'KN', 'Saint Thomas Lowland'), ('KN-STM', 'KN', 'Saint Thomas Middle Island'), ('KN-TPP', 'KN', 'Trinity Palmetto Point'), ('KP-CHA', 'KP', 'Chagang-do'), ('KP-HAB', 'KP', 'Hamgyong-bukto'), ('KP-HAN', 'KP', 'Hamgyong-namdo'), ('KP-HWB', 'KP', 'Hwanghae-bukto'), ('KP-HWN', 'KP', 'Hwanghae-namdo'), ('KP-KAN', 'KP', 'Kangwon-do'), ('KP-NAJ', 'KP', 'Rason Directly Governed City'), ('KP-PYB', 'KP', 'P''yongan-bukto'), ('KP-PYN', 'KP', 'P''yongan-namdo'), ('KP-PYO', 'KP', 'P''yongyang Special City'), ('KP-YAN', 'KP', 'Ryanggang-do (Yanggang-do)'), ('KR-11', 'KR', 'Seoul Special City'), ('KR-26', 'KR', 'Busan Metropolitan City'), ('KR-27', 'KR', 'Daegu Metropolitan City'), ('KR-28', 'KR', 'Incheon Metropolitan City'), ('KR-29', 'KR', 'Gwangju Metropolitan City'), ('KR-30', 'KR', 'Daejeon Metropolitan City'), ('KR-31', 'KR', 'Ulsan Metropolitan City'), ('KR-41', 'KR', 'Gyeonggi-do'), ('KR-42', 'KR', 'Gangwon-do'), ('KR-43', 'KR', 'Chungcheongbuk-do'), ('KR-44', 'KR', 'Chungcheongnam-do'), ('KR-45', 'KR', 'Jeollabuk-do'), ('KR-46', 'KR', 'Jeollanam-do'), ('KR-47', 'KR', 'Gyeongsangbuk-do'), ('KR-48', 'KR', 'Gyeongsangnam-do'), ('KR-49', 'KR', 'Jeju-do'), ('KW-D', 'KW', 'Al Ahmadi'), ('KW-F', 'KW', 'Al Farwaniyah'), ('KW-H', 'KW', 'Hawalli'), ('KW-J', 'KW', 'Al Jahra'), ('KW-S', 'KW', 'Al Asimah'), ('KY-CR', 'KY', 'Creek'), ('KY-EA', 'KY', 'Eastern'), ('KY-ML', 'KY', 'Midland'), ('KY-SK', 'KY', 'Stake Bay'), ('KY-SP', 'KY', 'Spot Bay'), ('KY-ST', 'KY', 'South Town'), ('KY-WD', 'KY', 'West End'), ('KY-WN', 'KY', 'Western'), ('KZ-AKM', 'KZ', 'Aqmola'), ('KZ-AKT', 'KZ', 'Aqtobe'), ('KZ-ALA', 'KZ', 'Almaty'), ('KZ-ALM', 'KZ', 'Almaty'), ('KZ-AST', 'KZ', 'Astana'), ('KZ-ATY', 'KZ', 'Atyrau'), ('KZ-KAR', 'KZ', 'Qaraghandy'), ('KZ-KUS', 'KZ', 'Qustanay'), ('KZ-KZY', 'KZ', 'Qyzylorda'), ('KZ-MAN', 'KZ', 'Mangghystau'), ('KZ-PAV', 'KZ', 'Paylodar'), ('KZ-SEV', 'KZ', 'Soltustik Qazaqstan'), ('KZ-VOS', 'KZ', 'Shyghys Qazaqstan'), ('KZ-YUZ', 'KZ', 'Ongtustik Qazaqstan'), ('KZ-ZAP', 'KZ', 'Baty Qazaqstan'), ('KZ-ZHA', 'KZ', 'Zhambyl'), ('LA-AT', 'LA', 'Attapu'), ('LA-BK', 'LA', 'Bokeo'), ('LA-BL', 'LA', 'Bolikhamxai'), ('LA-CH', 'LA', 'Champasak'), ('LA-HO', 'LA', 'Houaphan'), ('LA-KH', 'LA', 'Khammouan'), ('LA-LM', 'LA', 'Louang Namtha'), ('LA-LP', 'LA', 'Louangphabang'), ('LA-OU', 'LA', 'Oudomxai'), ('LA-PH', 'LA', 'Phongsali'), ('LA-SL', 'LA', 'Salavan'), ('LA-SV', 'LA', 'Savannakhet'), ('LA-VI', 'LA', 'Vientiane'), ('LA-VT', 'LA', 'Vientiane'), ('LA-XA', 'LA', 'Xaignabouli'), ('LA-XE', 'LA', 'Xekong'), ('LA-XI', 'LA', 'Xiangkhoang'), ('LA-XN', 'LA', 'Xaisomboun'), ('LC-AR', 'LC', 'Anse-la-Raye'), ('LC-CA', 'LC', 'Castries'), ('LC-CH', 'LC', 'Choiseul'), ('LC-DA', 'LC', 'Dauphin'), ('LC-DE', 'LC', 'Dennery'), ('LC-GI', 'LC', 'Gros-Islet'), ('LC-LA', 'LC', 'Laborie'), ('LC-MI', 'LC', 'Micoud'), ('LC-PR', 'LC', 'Praslin'), ('LC-SO', 'LC', 'Soufriere'), ('LC-VF', 'LC', 'Vieux-Fort'), ('LI-A', 'LI', 'Schaan'), ('LI-B', 'LI', 'Balzers'), ('LI-E', 'LI', 'Eschen'), ('LI-G', 'LI', 'Gamprin'), ('LI-M', 'LI', 'Mauren'), ('LI-N', 'LI', 'Triesen'), ('LI-P', 'LI', 'Planken'), ('LI-R', 'LI', 'Ruggell'), ('LI-T', 'LI', 'Triesenberg'), ('LI-V', 'LI', 'Vaduz'), ('Li-L', 'LI', 'Schellenberg'), ('LK-CE', 'LK', 'Central'), ('LK-EA', 'LK', 'Eastern'), ('LK-NC', 'LK', 'North Central'), ('LK-NO', 'LK', 'Northern'), ('LK-NW', 'LK', 'North Western'), ('LK-SA', 'LK', 'Sabaragamuwa'), ('LK-SO', 'LK', 'Southern'), ('LK-UV', 'LK', 'Uva'), ('LK-WE', 'LK', 'Western'), ('LR-BG', 'LR', 'Bong'), ('LR-BI', 'LR', 'Bomi'), ('LR-CM', 'LR', 'Grand Cape Mount'), ('LR-GB', 'LR', 'Grand Bassa'), ('LR-GG', 'LR', 'Grand Gedeh'), ('LR-GK', 'LR', 'Grand Kru'), ('LR-LO', 'LR', 'Lofa'), ('LR-MG', 'LR', 'Margibi'), ('LR-ML', 'LR', 'Maryland'), ('LR-MS', 'LR', 'Montserrado'), ('LR-NB', 'LR', 'Nimba'), ('LR-RC', 'LR', 'River Cess'), ('LR-SN', 'LR', 'Sinoe'), ('LS-BB', 'LS', 'Butha-Buthe'), ('LS-BE', 'LS', 'Berea'), ('LS-LE', 'LS', 'Leribe'), ('LS-MF', 'LS', 'Mafeteng'), ('LS-MH', 'LS', 'Mohale''s Hoek'), ('LS-MK', 'LS', 'Mokhotlong'), ('LS-MS', 'LS', 'Maseru'), ('LS-QN', 'LS', 'Qacha''s Nek'), ('LS-QT', 'LS', 'Quthing'), ('LS-TT', 'LS', 'Thaba-Tseka'), ('LT-AL', 'LT', 'Alytus'), ('LT-KA', 'LT', 'Kaunas'), ('LT-KL', 'LT', 'Klaipeda'), ('LT-MA', 'LT', 'Marijampole'), ('LT-PA', 'LT', 'Panevezys'), ('LT-SI', 'LT', 'Siauliai'), ('LT-TA', 'LT', 'Taurage'), ('LT-TE', 'LT', 'Telsiai'), ('LT-UT', 'LT', 'Utena'), ('LT-VI', 'LT', 'Vilnius'), ('LU-DC', 'LU', 'Clervaux'), ('LU-DD', 'LU', 'Diekirch'), ('LU-DR', 'LU', 'Redange'), ('LU-DV', 'LU', 'Vianden'), ('LU-DW', 'LU', 'Wiltz'), ('LU-GE', 'LU', 'Echternach'), ('LU-GG', 'LU', 'Grevenmacher'), ('LU-GR', 'LU', 'Remich'), ('LU-LC', 'LU', 'Capellen'), ('LU-LE', 'LU', 'Esch-sur-Alzette'), ('LU-LL', 'LU', 'Luxembourg'), ('LU-LM', 'LU', 'Mersch'), ('LV-AIZ', 'LV', 'Aizkraukles Rajons'), ('LV-ALU', 'LV', 'Aluksnes Rajons'), ('LV-BAL', 'LV', 'Balvu Rajons'), ('LV-BAU', 'LV', 'Bauskas Rajons'), ('LV-CES', 'LV', 'Cesu Rajons'), ('LV-DGR', 'LV', 'Daugavpils Rajons'), ('LV-DGV', 'LV', 'Daugavpils'), ('LV-DOB', 'LV', 'Dobeles Rajons'), ('LV-GUL', 'LV', 'Gulbenes Rajons'), ('LV-JEK', 'LV', 'Jekabpils Rajons'), ('LV-JGR', 'LV', 'Jelgavas Rajons'), ('LV-JGV', 'LV', 'Jelgava'), ('LV-JUR', 'LV', 'Jurmala'), ('LV-KRA', 'LV', 'Kraslavas Rajons'), ('LV-KUL', 'LV', 'Kuldigas Rajons'), ('LV-LIM', 'LV', 'Limbazu Rajons'), ('LV-LPK', 'LV', 'Liepaja'), ('LV-LPR', 'LV', 'Liepajas Rajons'), ('LV-LUD', 'LV', 'Ludzas Rajons'), ('LV-MAD', 'LV', 'Madonas Rajons'), ('LV-OGR', 'LV', 'Ogres Rajons'), ('LV-PRE', 'LV', 'Preilu Rajons'), ('LV-RGA', 'LV', 'Riga'), ('LV-RGR', 'LV', 'Rigas Rajons'), ('LV-RZK', 'LV', 'Rezekne'), ('LV-RZR', 'LV', 'Rezeknes Rajons'), ('LV-SAL', 'LV', 'Saldus Rajons'), ('LV-TAL', 'LV', 'Talsu Rajons'), ('LV-TUK', 'LV', 'Tukuma Rajons'), ('LV-VLK', 'LV', 'Valkas Rajons'), ('LV-VLM', 'LV', 'Valmieras Rajons'), ('LV-VSL', 'LV', 'Ventspils'), ('LV-VSR', 'LV', 'Ventspils Rajons'), ('LY-AJ', 'LY', 'Ajdabiya'), ('LY-AS', 'LY', 'Ash Shati'''), ('LY-AW', 'LY', 'Awbari'), ('LY-AZ', 'LY', 'Al ''Aziziyah'), ('LY-BA', 'LY', 'Banghazi'), ('LY-DA', 'LY', 'Darnah'), ('LY-FA', 'LY', 'Al Fatih'), ('LY-GD', 'LY', 'Ghadamis'), ('LY-GY', 'LY', 'Gharyan'), ('LY-JA', 'LY', 'Al Jabal al Akhdar'), ('LY-JU', 'LY', 'Al Jufrah'), ('LY-KH', 'LY', 'Al Khums'), ('LY-KU', 'LY', 'Al Kufrah'), ('LY-MI', 'LY', 'Misratah'), ('LY-MZ', 'LY', 'Murzuq'), ('LY-NK', 'LY', 'An Nuqat al Khams'), ('LY-SB', 'LY', 'Sabha'), ('LY-SU', 'LY', 'Surt'), ('LY-SW', 'LY', 'Sawfajjin'), ('LY-TH', 'LY', 'Tarhunah'), ('LY-TL', 'LY', 'Tarabulus (Tripoli)'), ('LY-TU', 'LY', 'Tubruq'), ('LY-YA', 'LY', 'Yafran'), ('LY-ZA', 'LY', 'Az Zawiyah'), ('LY-ZL', 'LY', 'Zlitan'), ('MA-ADK', 'MA', 'Ad Dakhla'), ('MA-AGD', 'MA', 'Agadir'), ('MA-AZI', 'MA', 'Azilal'), ('MA-BJD', 'MA', 'Boujdour'), ('MA-BLM', 'MA', 'Boulemane'), ('MA-BME', 'MA', 'Beni Mellal'), ('MA-BSL', 'MA', 'Ben Slimane'), ('MA-CBL', 'MA', 'Casablanca'), ('MA-CHA', 'MA', 'Chaouen'), ('MA-EJA', 'MA', 'El Jadida'), ('MA-EKS', 'MA', 'El Kelaa des Sraghna'), ('MA-ERA', 'MA', 'Er Rachidia'), ('MA-ESM', 'MA', 'Es Smara'), ('MA-ESS', 'MA', 'Essaouira'), ('MA-FES', 'MA', 'Fes'), ('MA-FIG', 'MA', 'Figuig'), ('MA-GLM', 'MA', 'Guelmim'), ('MA-HOC', 'MA', 'Al Hoceima'), ('MA-IFR', 'MA', 'Ifrane'), ('MA-KEN', 'MA', 'Kenitra'), ('MA-KHM', 'MA', 'Khemisset'), ('MA-KHN', 'MA', 'Khenifra'), ('MA-KHO', 'MA', 'Khouribga'), ('MA-LAR', 'MA', 'Larache'), ('MA-LYN', 'MA', 'Laayoune'), ('MA-MKN', 'MA', 'Meknes'), ('MA-MRK', 'MA', 'Marrakech'), ('MA-NAD', 'MA', 'Nador'), ('MA-ORZ', 'MA', 'Ouarzazate'), ('MA-OUJ', 'MA', 'Oujda'), ('MA-RSA', 'MA', 'Rabat-Sale'), ('MA-SAF', 'MA', 'Safi'), ('MA-SET', 'MA', 'Settat'), ('MA-SKA', 'MA', 'Sidi Kacem'), ('MA-TAN', 'MA', 'Tan-Tan'), ('MA-TAO', 'MA', 'Taounate'), ('MA-TAT', 'MA', 'Tata'), ('MA-TAZ', 'MA', 'Taza'), ('MA-TET', 'MA', 'Tetouan'), ('MA-TGR', 'MA', 'Tangier'), ('MA-TIZ', 'MA', 'Tiznit'), ('MA-TRD', 'MA', 'Taroudannt'), ('MC-FV', 'MC', 'Fontvieille'), ('MC-LC', 'MC', 'La Condamine'), ('MC-MC', 'MC', 'Monte-Carlo'), ('MC-MV', 'MC', 'Monaco-Ville'), ('MD-BA', 'MD', 'Balti'), ('MD-CA', 'MD', 'Cahul'), ('MD-CU', 'MD', 'Chisinau'), ('MD-ED', 'MD', 'Edinet'), ('MD-GA', 'MD', 'Gagauzia'), ('MD-LA', 'MD', 'Lapusna'), ('MD-OR', 'MD', 'Orhei'), ('MD-SN', 'MD', 'StO?a Nistrului'), ('MD-SO', 'MD', 'Soroca'), ('MD-TI', 'MD', 'Tighina'), ('MD-UN', 'MD', 'Ungheni'), ('MG-AN', 'MG', 'Antananarivo province'), ('MG-AS', 'MG', 'Antsiranana province'), ('MG-FN', 'MG', 'Fianarantsoa province'), ('MG-MJ', 'MG', 'Mahajanga province'), ('MG-TL', 'MG', 'Toliara province'), ('MG-TM', 'MG', 'Toamasina province'), ('MH-ALG', 'MH', 'Ailinginae'), ('MH-ALK', 'MH', 'Ailuk'), ('MH-ALL', 'MH', 'Ailinglaplap'), ('MH-ARN', 'MH', 'Arno'), ('MH-AUR', 'MH', 'Aur'), ('MH-BKK', 'MH', 'Bokak'), ('MH-BKN', 'MH', 'Bikini'), ('MH-BKR', 'MH', 'Bikar'), ('MH-EBN', 'MH', 'Ebon'), ('MH-EKB', 'MH', 'Erikub'), ('MH-ENT', 'MH', 'Enewetak'), ('MH-JBT', 'MH', 'Jabat'), ('MH-JEM', 'MH', 'Jemo'), ('MH-JLT', 'MH', 'Jaluit'), ('MH-KIL', 'MH', 'Kili'), ('MH-KWJ', 'MH', 'Kwajalein'), ('MH-LAE', 'MH', 'Lae'), ('MH-LIB', 'MH', 'Lib'), ('MH-LKP', 'MH', 'Likiep'), ('MH-MIL', 'MH', 'Mili'), ('MH-MJR', 'MH', 'Majuro'), ('MH-MJT', 'MH', 'Mejit'), ('MH-MLP', 'MH', 'Maloelap'), ('MH-NAM', 'MH', 'Namu'), ('MH-NMK', 'MH', 'Namorik'), ('MH-RGK', 'MH', 'Rongrik'), ('MH-RGL', 'MH', 'Rongelap'), ('MH-TOK', 'MH', 'Toke'), ('MH-UJA', 'MH', 'Ujae'), ('MH-UJL', 'MH', 'Ujelang'), ('MH-UTK', 'MH', 'Utirik'), ('MH-WTH', 'MH', 'Wotho'), ('MH-WTJ', 'MH', 'Wotje'), ('ML-CD', 'ML', 'Bamako Capital District'), ('ML-GA', 'ML', 'Gao'), ('ML-KD', 'ML', 'Kidal'), ('ML-KL', 'ML', 'Koulikoro'), ('ML-KY', 'ML', 'Kayes'), ('ML-MP', 'ML', 'Mopti'), ('ML-SG', 'ML', 'Segou'), ('ML-SK', 'ML', 'Sikasso'), ('ML-TB', 'ML', 'Tombouctou'), ('MM-AY', 'MM', 'Ayeyarwady'), ('MM-BG', 'MM', 'Bago'), ('MM-CH', 'MM', 'Chin State'), ('MM-KC', 'MM', 'Kachin State'), ('MM-KH', 'MM', 'Kayah State'), ('MM-KN', 'MM', 'Kayin State'), ('MM-MD', 'MM', 'Mandalay'), ('MM-MG', 'MM', 'Magway'), ('MM-MN', 'MM', 'Mon State'), ('MM-RK', 'MM', 'Rakhine State'), ('MM-SG', 'MM', 'Sagaing'), ('MM-SH', 'MM', 'Shan State'), ('MM-TN', 'MM', 'Tanintharyi'), ('MM-YG', 'MM', 'Yangon'), ('MN-035', 'MN', 'Orhon'), ('MN-037', 'MN', 'Darhan uul'), ('MN-039', 'MN', 'Hentiy'), ('MN-041', 'MN', 'Hovsgol'), ('MN-043', 'MN', 'Hovd'), ('MN-046', 'MN', 'Uvs'), ('MN-047', 'MN', 'Tov'), ('MN-049', 'MN', 'Selenge'), ('MN-051', 'MN', 'Suhbaatar'), ('MN-053', 'MN', 'Omnogovi'), ('MN-055', 'MN', 'Ovorhangay'), ('MN-057', 'MN', 'Dzavhan'), ('MN-059', 'MN', 'DundgovL'), ('MN-061', 'MN', 'Dornod'), ('MN-063', 'MN', 'Dornogov'), ('MN-064', 'MN', 'Govi-Sumber'), ('MN-065', 'MN', 'Govi-Altay'), ('MN-067', 'MN', 'Bulgan'), ('MN-069', 'MN', 'Bayanhongor'), ('MN-071', 'MN', 'Bayan-Olgiy'), ('MN-073', 'MN', 'Arhangay'), ('MN-1', 'MN', 'Ulanbaatar'), ('MO-ANT', 'MO', 'St. Anthony Parish'), ('MO-CAT', 'MO', 'Cathedral Parish'), ('MO-LAW', 'MO', 'St. Lawrence Parish'), ('MO-LAZ', 'MO', 'St. Lazarus Parish'), ('MO-OLF', 'MO', 'Our Lady Fatima Parish'), ('MP-N', 'MP', 'Northern Islands'), ('MP-R', 'MP', 'Rota'), ('MP-S', 'MP', 'Saipan'), ('MP-T', 'MP', 'Tinian'), ('MR-AD', 'MR', 'Adrar'), ('MR-AS', 'MR', 'Assaba'), ('MR-BR', 'MR', 'Brakna'), ('MR-DN', 'MR', 'Dakhlet Nouadhibou'), ('MR-GM', 'MR', 'Guidimaka'), ('MR-GO', 'MR', 'Gorgol'), ('MR-HC', 'MR', 'Hodh Ech Chargui'), ('MR-HG', 'MR', 'Hodh El Gharbi'), ('MR-IN', 'MR', 'Inchiri'), ('MR-NO', 'MR', 'Nouakchott'), ('MR-TA', 'MR', 'Tagant'), ('MR-TR', 'MR', 'Trarza'), ('MR-TZ', 'MR', 'Tiris Zemmour'), ('MS-A', 'MS', 'Saint Anthony'), ('MS-G', 'MS', 'Saint Georges'), ('MS-P', 'MS', 'Saint Peter'), ('MT-ATT', 'MT', 'Attard'), ('MT-BAL', 'MT', 'Balzan'), ('MT-BGU', 'MT', 'Birgu'), ('MT-BKK', 'MT', 'Birkirkara'), ('MT-BOR', 'MT', 'Bormla'), ('MT-BRZ', 'MT', 'Birzebbuga'), ('MT-DIN', 'MT', 'Dingli'), ('MT-FGU', 'MT', 'Fgura'), ('MT-FLO', 'MT', 'Floriana'), ('MT-FNT', 'MT', 'Fontana'), ('MT-GDJ', 'MT', 'Gudja'), ('MT-GHJ', 'MT', 'Ghajnsielem'), ('MT-GHR', 'MT', 'Gharb'), ('MT-GHS', 'MT', 'Ghasri'), ('MT-GRG', 'MT', 'Gargur'), ('MT-GXQ', 'MT', 'Gaxaq'), ('MT-GZR', 'MT', 'Gzira'), ('MT-HMR', 'MT', 'Hamrun'), ('MT-IKL', 'MT', 'Iklin'), ('MT-ISL', 'MT', 'Isla'), ('MT-KLK', 'MT', 'Kalkara'), ('MT-KRC', 'MT', 'Kercem'), ('MT-KRK', 'MT', 'Kirkop'), ('MT-LIJ', 'MT', 'Lija'), ('MT-LUQ', 'MT', 'Luqa'), ('MT-MDN', 'MT', 'Mdina'), ('MT-MEL', 'MT', 'Melliea'), ('MT-MGR', 'MT', 'Mgarr'), ('MT-MKL', 'MT', 'Marsaskala'), ('MT-MQA', 'MT', 'Mqabba'), ('MT-MRS', 'MT', 'Marsa'), ('MT-MSI', 'MT', 'Msida'), ('MT-MST', 'MT', 'Mosta'), ('MT-MTF', 'MT', 'Mtarfa'), ('MT-MUN', 'MT', 'Munxar'), ('MT-MXL', 'MT', 'Marsaxlokk'), ('MT-NAD', 'MT', 'Nadur'), ('MT-NAX', 'MT', 'Naxxar'), ('MT-PAO', 'MT', 'Paola'), ('MT-PEM', 'MT', 'Pembroke'), ('MT-PIE', 'MT', 'Pieta'), ('MT-QAL', 'MT', 'Qala'), ('MT-QOR', 'MT', 'Qormi'), ('MT-QRE', 'MT', 'Qrendi'), ('MT-RAB', 'MT', 'Rabat'), ('MT-SAF', 'MT', 'Safi'), ('MT-SGI', 'MT', 'San Giljan'), ('MT-SGW', 'MT', 'San Gwann'), ('MT-SIG', 'MT', 'Siggiewi'), ('MT-SLA', 'MT', 'San Lawrenz'), ('MT-SLM', 'MT', 'Sliema'), ('MT-SLU', 'MT', 'Santa Lucija'), ('MT-SNT', 'MT', 'Sannat'), ('MT-SPB', 'MT', 'San Pawl il-Bahar'), ('MT-SVE', 'MT', 'Santa Venera'), ('MT-SWQ', 'MT', 'Swieqi'), ('MT-TRX', 'MT', 'Tarxien'), ('MT-TXB', 'MT', 'Ta Xbiex'), ('MT-VIC', 'MT', 'Victoria'), ('MT-VLT', 'MT', 'Valletta'), ('MT-XEW', 'MT', 'Xewkija'), ('MT-XGJ', 'MT', 'Xgajra'), ('MT-ZAG', 'MT', 'Xagra'), ('MT-ZBG', 'MT', 'Zebbug'), ('MT-ZBR', 'MT', 'Zabbar'), ('MT-ZEB', 'MT', 'Zebbug'), ('MT-ZJT', 'MT', 'Zejtun'), ('MT-ZRQ', 'MT', 'Zurrieq'), ('MU-AG', 'MU', 'Agalega Islands'), ('MU-BL', 'MU', 'Black River'), ('MU-BR', 'MU', 'Beau Bassin-Rose Hill'), ('MU-CC', 'MU', 'Cargados Carajos Shoals (Saint Brandon Islands)'), ('MU-CU', 'MU', 'Curepipe'), ('MU-FL', 'MU', 'Flacq'), ('MU-GP', 'MU', 'Grand Port'), ('MU-MO', 'MU', 'Moka'), ('MU-PA', 'MU', 'Pamplemousses'), ('MU-PL', 'MU', 'Port Louis'), ('MU-PU', 'MU', 'Port Louis'), ('MU-PW', 'MU', 'Plaines Wilhems'), ('MU-QB', 'MU', 'Quatre Bornes'), ('MU-RO', 'MU', 'Rodrigues'), ('MU-RR', 'MU', 'Riviere du Rempart'), ('MU-SA', 'MU', 'Savanne'), ('MU-VP', 'MU', 'Vacoas-Phoenix'), ('MV-AAD', 'MV', 'Ari Atoll Dheknu'), ('MV-AAU', 'MV', 'Ari Atoll Uthuru'), ('MV-ADD', 'MV', 'Addu'), ('MV-FAA', 'MV', 'Faadhippolhu'), ('MV-FEA', 'MV', 'Felidhe Atoll'), ('MV-FMU', 'MV', 'Fua Mulaku'), ('MV-HAD', 'MV', 'Huvadhu Atoll Dhekunu'), ('MV-HAU', 'MV', 'Huvadhu Atoll Uthuru'), ('MV-HDH', 'MV', 'Hadhdhunmathi'), ('MV-KLH', 'MV', 'Kolhumadulu'), ('MV-MAA', 'MV', 'Male Atoll'), ('MV-MAD', 'MV', 'Maalhosmadulu Dhekunu'), ('MV-MAU', 'MV', 'Maalhosmadulu Uthuru'), ('MV-MLD', 'MV', 'Miladhunmadulu Dhekunu'), ('MV-MLU', 'MV', 'Miladhunmadulu Uthuru'), ('MV-MUA', 'MV', 'Mulaku Atoll'), ('MV-NAD', 'MV', 'Nilandhe Atoll Dhekunu'), ('MV-NAU', 'MV', 'Nilandhe Atoll Uthuru'), ('MV-THD', 'MV', 'Thiladhunmathi Dhekunu'), ('MV-THU', 'MV', 'Thiladhunmathi Uthuru'), ('MW-BLK', 'MW', 'Balaka'), ('MW-BLT', 'MW', 'Blantyre'), ('MW-CKW', 'MW', 'Chikwawa'), ('MW-CRD', 'MW', 'Chiradzulu'), ('MW-CTP', 'MW', 'Chitipa'), ('MW-DDZ', 'MW', 'Dedza'), ('MW-DWA', 'MW', 'Dowa'), ('MW-KRG', 'MW', 'Karonga'), ('MW-KSG', 'MW', 'Kasungu'), ('MW-LKM', 'MW', 'Likoma'), ('MW-LLG', 'MW', 'Lilongwe'), ('MW-MCG', 'MW', 'Machinga'), ('MW-MCH', 'MW', 'Mchinji'), ('MW-MGC', 'MW', 'Mangochi'), ('MW-MLJ', 'MW', 'Mulanje'), ('MW-MWZ', 'MW', 'Mwanza'), ('MW-MZM', 'MW', 'Mzimba'), ('MW-NKB', 'MW', 'Nkhata Bay'), ('MW-NKH', 'MW', 'Nkhotakota'), ('MW-NSJ', 'MW', 'Nsanje'), ('MW-NTI', 'MW', 'Ntchisi'), ('MW-NTU', 'MW', 'Ntcheu'), ('MW-PHL', 'MW', 'Phalombe'), ('MW-RMP', 'MW', 'Rumphi'), ('MW-SLM', 'MW', 'Salima'), ('MW-THY', 'MW', 'Thyolo'), ('MW-ZBA', 'MW', 'Zomba'), ('MX-AGU', 'MX', 'Aguascalientes'), ('MX-BCN', 'MX', 'Baja California'), ('MX-BCS', 'MX', 'Baja California Sur'), ('MX-CAM', 'MX', 'Campeche'), ('MX-CHH', 'MX', 'Chihuahua'), ('MX-CHP', 'MX', 'Chiapas'), ('MX-COA', 'MX', 'Coahuila'), ('MX-COL', 'MX', 'Colima'), ('MX-DIF', 'MX', 'Distrito Federal'), ('MX-DUR', 'MX', 'Durango'), ('MX-GRO', 'MX', 'Guerrero'), ('MX-GUA', 'MX', 'Guanajuato'), ('MX-HID', 'MX', 'Hidalgo'), ('MX-JAL', 'MX', 'Jalisco'), ('MX-MEX', 'MX', 'Mexico'), ('MX-MIC', 'MX', 'Michoacan'), ('MX-MOR', 'MX', 'Morelos'), ('MX-NAY', 'MX', 'Nayarit'), ('MX-NLE', 'MX', 'Nuevo Leon'), ('MX-OAX', 'MX', 'Oaxaca'), ('MX-PUE', 'MX', 'Puebla'), ('MX-QUE', 'MX', 'Queretaro'), ('MX-ROO', 'MX', 'Quintana Roo'), ('MX-SIN', 'MX', 'Sinaloa'), ('MX-SLP', 'MX', 'San Luis Potosi'), ('MX-SON', 'MX', 'Sonora'), ('MX-TAB', 'MX', 'Tabasco'), ('MX-TAM', 'MX', 'Tamaulipas'), ('MX-TLA', 'MX', 'Tlaxcala'), ('MX-VER', 'MX', 'Veracruz'), ('MX-YUC', 'MX', 'Yucatan'), ('MX-ZAC', 'MX', 'Zacatecas'), ('MY-JH', 'MY', 'Johor'), ('MY-KD', 'MY', 'Kedah'), ('MY-KL', 'MY', 'Kuala Lumpur'), ('MY-KN', 'MY', 'Kelantan'), ('MY-LB', 'MY', 'Labuan'), ('MY-ML', 'MY', 'Malacca'), ('MY-NS', 'MY', 'Negeri Sembilan'), ('MY-PG', 'MY', 'Penang'), ('MY-PH', 'MY', 'Pahang'), ('MY-PK', 'MY', 'Perak'), ('MY-PS', 'MY', 'Perlis'), ('MY-SB', 'MY', 'Sabah'), ('MY-SL', 'MY', 'Selangor'), ('MY-SR', 'MY', 'Sarawak'), ('MY-TR', 'MY', 'Terengganu'), ('MY-WP', 'MY', 'Wilayah Persekutuan'), ('MZ-CD', 'MZ', 'Cabo Delgado'), ('MZ-GZ', 'MZ', 'Gaza'), ('MZ-IN', 'MZ', 'Inhambane'), ('MZ-MC', 'MZ', 'Maputo (city)'), ('MZ-MN', 'MZ', 'Manica'), ('MZ-MP', 'MZ', 'Maputo'), ('MZ-NA', 'MZ', 'Nampula'), ('MZ-NI', 'MZ', 'Niassa'), ('MZ-SO', 'MZ', 'Sofala'), ('MZ-TE', 'MZ', 'Tete'), ('MZ-ZA', 'MZ', 'Zambezia'), ('NA-CA', 'NA', 'Caprivi'), ('NA-ER', 'NA', 'Erongo'), ('NA-HA', 'NA', 'Hardap'), ('NA-KH', 'NA', 'Khomas'), ('NA-KR', 'NA', 'Karas'), ('NA-KU', 'NA', 'Kunene'), ('NA-KV', 'NA', 'Kavango'), ('NA-OJ', 'NA', 'Otjozondjupa'), ('NA-OK', 'NA', 'Omaheke'), ('NA-ON', 'NA', 'Oshana'), ('NA-OO', 'NA', 'Oshikoto'), ('NA-OT', 'NA', 'Omusati'), ('NA-OW', 'NA', 'Ohangwena'), ('NC-L', 'NC', 'Iles Loyaute'), ('NC-N', 'NC', 'Nord'), ('NC-S', 'NC', 'Sud'), ('NG-AB', 'NG', 'Abia'), ('NG-AD', 'NG', 'Adamawa'), ('NG-AG', 'NG', 'Agadez'), ('NG-AK', 'NG', 'Akwa Ibom'), ('NG-AN', 'NG', 'Anambra'), ('NG-BC', 'NG', 'Bauchi'), ('NG-BN', 'NG', 'Benue'), ('NG-BO', 'NG', 'Borno'), ('NG-BY', 'NG', 'Bayelsa'), ('NG-CR', 'NG', 'Cross River'), ('NG-CT', 'NG', 'Federal Capital Territory'), ('NG-DE', 'NG', 'Delta'), ('NG-DF', 'NG', 'Diffa'), ('NG-DS', 'NG', 'Dosso'), ('NG-EB', 'NG', 'Ebonyi'), ('NG-ED', 'NG', 'Edo'), ('NG-EK', 'NG', 'Ekiti'), ('NG-EN', 'NG', 'Enugu'), ('NG-GO', 'NG', 'Gombe'), ('NG-IM', 'NG', 'Imo'), ('NG-JI', 'NG', 'Jigawa'), ('NG-KD', 'NG', 'Kaduna'), ('NG-KE', 'NG', 'Kebbi'), ('NG-KN', 'NG', 'Kano'), ('NG-KO', 'NG', 'Kogi'), ('NG-KT', 'NG', 'Katsina'), ('NG-KW', 'NG', 'Kwara'), ('NG-LA', 'NG', 'Lagos'), ('NG-MA', 'NG', 'Maradi'), ('NG-NA', 'NG', 'Nassarawa'), ('NG-NI', 'NG', 'Niger'), ('NG-NM', 'NG', 'Niamey'), ('NG-OG', 'NG', 'Ogun'), ('NG-ONG', 'NG', 'Ondo'), ('NG-OS', 'NG', 'Osun'), ('NG-OY', 'NG', 'Oyo'), ('NG-PL', 'NG', 'Plateau'), ('NG-RI', 'NG', 'Rivers'), ('NG-SO', 'NG', 'Sokoto'), ('NG-TA', 'NG', 'Taraba'), ('NG-TH', 'NG', 'Tahoua'), ('NG-TL', 'NG', 'Tillaberi'), ('NG-YO', 'NG', 'Yobe'), ('NG-ZA', 'NG', 'Zamfara'), ('NG-ZD', 'NG', 'Zinder'), ('NI-AN', 'NI', 'Region Autonoma del Atlantico Norte'), ('NI-AS', 'NI', 'Region Autonoma del Atlantico Sur'), ('NI-BO', 'NI', 'Boaco'), ('NI-CA', 'NI', 'Carazo'), ('NI-CD', 'NI', 'Chinandega'), ('NI-CT', 'NI', 'Chontales'), ('NI-ES', 'NI', 'Esteli'), ('NI-GR', 'NI', 'Granada'), ('NI-JI', 'NI', 'Jinotega'), ('NI-LE', 'NI', 'Leon'), ('NI-MD', 'NI', 'Madriz'), ('NI-MN', 'NI', 'Managua'), ('NI-MS', 'NI', 'Masaya'), ('NI-MT', 'NI', 'Matagalpa'), ('NI-NS', 'NI', 'Nueva Segovia'), ('NI-RV', 'NI', 'Rivas'), ('NI-SJ', 'NI', 'Rio San Juan'), ('NL-DR', 'NL', 'Drenthe'), ('NL-FL', 'NL', 'Flevoland'), ('NL-FR', 'NL', 'Friesland'), ('NL-GE', 'NL', 'Gelderland'), ('NL-GR', 'NL', 'Groningen'), ('NL-LI', 'NL', 'Limburg'), ('NL-NB', 'NL', 'Noord Brabant'), ('NL-NH', 'NL', 'Noord Holland'), ('NL-OV', 'NL', 'Overijssel'), ('NL-UT', 'NL', 'Utrecht'), ('NL-ZE', 'NL', 'Zeeland'), ('NL-ZH', 'NL', 'Zuid Holland'), ('NO-AA', 'NO', 'Aust-Agder'), ('NO-AK', 'NO', 'Akershus'), ('NO-BU', 'NO', 'Buskerud'), ('NO-FM', 'NO', 'Finnmark'), ('NO-HL', 'NO', 'Hordaland'), ('NO-HM', 'NO', 'Hedmark'), ('NO-MR', 'NO', 'More og Romdal'), ('NO-NL', 'NO', 'Nordland'), ('NO-NT', 'NO', 'Nord-Trondelag'), ('NO-OF', 'NO', 'Ostfold'), ('NO-OL', 'NO', 'Oslo'), ('NO-OP', 'NO', 'Oppland'), ('NO-RL', 'NO', 'Rogaland'), ('NO-SJ', 'NO', 'Sogn og Fjordane'), ('NO-ST', 'NO', 'Sor-Trondelag'), ('NO-TM', 'NO', 'Telemark'), ('NO-TR', 'NO', 'Troms'), ('NO-VA', 'NO', 'Vest-Agder'), ('NO-VF', 'NO', 'Vestfold'), ('NP-BA', 'NP', 'Bagmati'), ('NP-BH', 'NP', 'Bheri'), ('NP-DH', 'NP', 'Dhawalagiri'), ('NP-GA', 'NP', 'Gandaki'), ('NP-JA', 'NP', 'Janakpur'), ('NP-KA', 'NP', 'Karnali'), ('NP-KO', 'NP', 'Kosi'), ('NP-LU', 'NP', 'Lumbini'), ('NP-MA', 'NP', 'Mahakali'), ('NP-ME', 'NP', 'Mechi'), ('NP-NA', 'NP', 'Narayani'), ('NP-RA', 'NP', 'Rapti'), ('NP-SA', 'NP', 'Sagarmatha'), ('NP-SE', 'NP', 'Seti'), ('NR-AA', 'NR', 'Anabar'), ('NR-AI', 'NR', 'Anibare'), ('NR-AO', 'NR', 'Aiwo'), ('NR-AT', 'NR', 'Anetan'), ('NR-BA', 'NR', 'Baiti'), ('NR-BO', 'NR', 'Boe'), ('NR-BU', 'NR', 'Buada'), ('NR-DE', 'NR', 'Denigomodu'), ('NR-EW', 'NR', 'Ewa'), ('NR-IJ', 'NR', 'Ijuw'), ('NR-ME', 'NR', 'Meneng'), ('NR-NI', 'NR', 'Nibok'), ('NR-UA', 'NR', 'Uaboe'), ('NR-YA', 'NR', 'Yaren'), ('NZ-AUK', 'NZ', 'Auckland'), ('NZ-BOP', 'NZ', 'Bay of Plenty'), ('NZ-CAN', 'NZ', 'Canterbury'), ('NZ-GIS', 'NZ', 'Gisborne'), ('NZ-HKB', 'NZ', 'Hawke''s Bay'), ('NZ-MBH', 'NZ', 'Marlborough'), ('NZ-MWT', 'NZ', 'Manawatu-Wanganui'), ('NZ-NSN', 'NZ', 'Nelson'), ('NZ-NTL', 'NZ', 'Northland'), ('NZ-OTA', 'NZ', 'Otago'), ('NZ-STL', 'NZ', 'Southland'), ('NZ-TAS', 'NZ', 'Tasman'), ('NZ-TKI', 'NZ', 'Taranaki'), ('NZ-WGN', 'NZ', 'Wellington'), ('NZ-WKO', 'NZ', 'Waikato'), ('NZ-WTC', 'NZ', 'West Coast'), ('OM-BA', 'OM', 'Al Batinah'), ('OM-DA', 'OM', 'Ad Dakhiliyah'), ('OM-MA', 'OM', 'Masqat'), ('OM-MU', 'OM', 'Musandam'), ('OM-SH', 'OM', 'Ash Sharqiyah'), ('OM-WU', 'OM', 'Al Wusta'), ('OM-ZA', 'OM', 'Az Zahirah'), ('OM-ZU', 'OM', 'Zufar'), ('PA-BT', 'PA', 'Bocas del Toro'), ('PA-CC', 'PA', 'Cocle'), ('PA-CH', 'PA', 'Chiriqui'), ('PA-CL', 'PA', 'Colon'), ('PA-DA', 'PA', 'Darien'), ('PA-HE', 'PA', 'Herrera'), ('PA-LS', 'PA', 'Los Santos'), ('PA-PA', 'PA', 'Panama'), ('PA-SB', 'PA', 'San Blas'), ('PA-VG', 'PA', 'Veraguas'), ('PE-AM', 'PE', 'Amazonas'), ('PE-AN', 'PE', 'Ancash'), ('PE-AP', 'PE', 'Apurimac'), ('PE-AR', 'PE', 'Arequipa'), ('PE-AY', 'PE', 'Ayacucho'), ('PE-CJ', 'PE', 'Cajamarca'), ('PE-CL', 'PE', 'Callao'), ('PE-CU', 'PE', 'Cusco'), ('PE-HO', 'PE', 'Huanuco'), ('PE-HV', 'PE', 'Huancavelica'), ('PE-IC', 'PE', 'Ica'), ('PE-JU', 'PE', 'Junin'), ('PE-LD', 'PE', 'La Libertad'), ('PE-LI', 'PE', 'Lima'), ('PE-LO', 'PE', 'Loreto'), ('PE-LY', 'PE', 'Lambayeque'), ('PE-MD', 'PE', 'Madre de Dios'), ('PE-MO', 'PE', 'Moquegua'), ('PE-PA', 'PE', 'Pasco'), ('PE-PI', 'PE', 'Piura'), ('PE-PU', 'PE', 'Puno'), ('PE-SM', 'PE', 'San Martin'), ('PE-TA', 'PE', 'Tacna'), ('PE-TU', 'PE', 'Tumbes'), ('PE-UC', 'PE', 'Ucayali'), ('PF-I', 'PF', 'Archipel des Tubuai'), ('PF-M', 'PF', 'Archipel des Marquises'), ('PF-S', 'PF', 'Iles Sous-le-Vent'), ('PF-T', 'PF', 'Archipel des Tuamotu'), ('PF-V', 'PF', 'Iles du Vent'), ('PG-BV', 'PG', 'Bougainville'), ('PG-CE', 'PG', 'Central'), ('PG-CH', 'PG', 'Chimbu'), ('PG-EB', 'PG', 'East New Britain'), ('PG-EH', 'PG', 'Eastern Highlands'), ('PG-EN', 'PG', 'Enga'), ('PG-ES', 'PG', 'East Sepik'), ('PG-GU', 'PG', 'Gulf'), ('PG-MB', 'PG', 'Milne Bay'), ('PG-MD', 'PG', 'Madang'), ('PG-MN', 'PG', 'Manus'), ('PG-MR', 'PG', 'Morobe'), ('PG-NC', 'PG', 'National Capital'), ('PG-NI', 'PG', 'New Ireland'), ('PG-NO', 'PG', 'Northern'), ('PG-SA', 'PG', 'Sandaun'), ('PG-SH', 'PG', 'Southern Highlands'), ('PG-WB', 'PG', 'West New Britain'), ('PG-WE', 'PG', 'Western'), ('PG-WH', 'PG', 'Western Highlands'), ('PH-ABR', 'PH', 'Abra'), ('PH-AKL', 'PH', 'Aklan'), ('PH-ALB', 'PH', 'Albay'), ('PH-ANO', 'PH', 'Agusan del Norte'), ('PH-ANT', 'PH', 'Antique'), ('PH-APY', 'PH', 'Apayao'), ('PH-ASU', 'PH', 'Agusan del Sur'), ('PH-AUR', 'PH', 'Aurora'), ('PH-BAS', 'PH', 'Basilan'), ('PH-BEN', 'PH', 'Benguet'), ('PH-BLR', 'PH', 'Biliran'), ('PH-BOL', 'PH', 'Bohol'), ('PH-BTA', 'PH', 'Bataan'), ('PH-BTE', 'PH', 'Batanes'), ('PH-BTG', 'PH', 'Batangas'), ('PH-BUK', 'PH', 'Bukidnon'), ('PH-BUL', 'PH', 'Bulacan'), ('PH-CAG', 'PH', 'Cagayan'), ('PH-CAM', 'PH', 'Camiguin'), ('PH-CAP', 'PH', 'Capiz'), ('PH-CAT', 'PH', 'Catanduanes'), ('PH-CAV', 'PH', 'Cavite'), ('PH-CEB', 'PH', 'Cebu'), ('PH-CMP', 'PH', 'Compostela'), ('PH-CNO', 'PH', 'Camarines Norte'), ('PH-CSU', 'PH', 'Camarines Sur'), ('PH-DNO', 'PH', 'Davao del Norte'), ('PH-DOR', 'PH', 'Davao Oriental'), ('PH-DSU', 'PH', 'Davao del Sur'), ('PH-ESA', 'PH', 'Eastern Samar'), ('PH-GUI', 'PH', 'Guimaras'), ('PH-IFU', 'PH', 'Ifugao'), ('PH-ILO', 'PH', 'Iloilo'), ('PH-INO', 'PH', 'Ilocos Norte'), ('PH-ISA', 'PH', 'Isabela'), ('PH-ISU', 'PH', 'Ilocos Sur'), ('PH-KAL', 'PH', 'Kalinga'), ('PH-LAG', 'PH', 'Laguna'), ('PH-LEY', 'PH', 'Leyte'), ('PH-LNO', 'PH', 'Lanao del Norte'), ('PH-LSU', 'PH', 'Lanao del Sur'), ('PH-MAG', 'PH', 'Maguindanao'), ('PH-MIC', 'PH', 'Mindoro Occidental'), ('PH-MIR', 'PH', 'Mindoro Oriental'), ('PH-MOP', 'PH', 'Mountain Province'), ('PH-MOR', 'PH', 'Misamis Oriental'), ('PH-MRN', 'PH', 'Marinduque'), ('PH-MSB', 'PH', 'Masbate'), ('PH-MSC', 'PH', 'Misamis Occidental'), ('PH-NCT', 'PH', 'North Cotabato'), ('PH-NEC', 'PH', 'Nueva Ecija'), ('PH-NOC', 'PH', 'Negros Occidental'), ('PH-NOR', 'PH', 'Negros Oriental'), ('PH-NSM', 'PH', 'Northern Samar'), ('PH-NVZ', 'PH', 'Nueva Vizcaya'), ('PH-PLW', 'PH', 'Palawan'), ('PH-PMP', 'PH', 'Pampanga'), ('PH-PNG', 'PH', 'Pangasinan'), ('PH-QRN', 'PH', 'Quirino'), ('PH-QZN', 'PH', 'Quezon'), ('PH-RIZ', 'PH', 'Rizal'), ('PH-ROM', 'PH', 'Romblon'), ('PH-SCO', 'PH', 'South Cotabato'), ('PH-SKU', 'PH', 'Sultan Kudarat'), ('PH-SLE', 'PH', 'Southern Leyte'), ('PH-SLU', 'PH', 'Sulu'), ('PH-SMR', 'PH', 'Samar'), ('PH-SNO', 'PH', 'Surigao del Norte'), ('PH-SQJ', 'PH', 'Siquijor'), ('PH-SRG', 'PH', 'Sarangani'), ('PH-SRS', 'PH', 'Sorsogon'), ('PH-SSU', 'PH', 'Surigao del Sur'), ('PH-TAR', 'PH', 'Tarlac'), ('PH-TAW', 'PH', 'Tawi-Tawi'), ('PH-UNI', 'PH', 'La Union'), ('PH-ZBL', 'PH', 'Zambales'), ('PH-ZNO', 'PH', 'Zamboanga del Norte'), ('PH-ZSI', 'PH', 'Zamboanga Sibugay'), ('PH-ZSU', 'PH', 'Zamboanga del Sur'), ('PK-B', 'PK', 'Balochistan'), ('PK-I', 'PK', 'Islamabad Capital Territory'), ('PK-N', 'PK', 'North-West Frontier Province'), ('PK-P', 'PK', 'Punjab'), ('PK-S', 'PK', 'Sindh'), ('PK-T', 'PK', 'Federally Administered Tribal Areas'), ('PL-DO', 'PL', 'Dolnoslaskie'), ('PL-KP', 'PL', 'Kujawsko-Pomorskie'), ('PL-LL', 'PL', 'Lubelskie'), ('PL-LO', 'PL', 'Lodzkie'), ('PL-LU', 'PL', 'Lubuskie'), ('PL-ML', 'PL', 'Malopolskie'), ('PL-MZ', 'PL', 'Mazowieckie'), ('PL-OP', 'PL', 'Opolskie'), ('PL-PL', 'PL', 'Podlaskie'), ('PL-PM', 'PL', 'Pomorskie'), ('PL-PP', 'PL', 'Podkarpackie'), ('PL-SL', 'PL', 'Slaskie'), ('PL-SW', 'PL', 'Swietokrzyskie'), ('PL-WM', 'PL', 'Warminsko-Mazurskie'), ('PL-WP', 'PL', 'Wielkopolskie'), ('PL-ZA', 'PL', 'Zachodniopomorskie'), ('PM-M', 'PM', 'Miquelon'), ('PM-P', 'PM', 'Saint Pierre'), ('PT-AR', 'PT', 'Acores (Azores)'), ('PT-AV', 'PT', 'Aveiro'), ('PT-BA', 'PT', 'Braga'), ('PT-BJ', 'PT', 'Beja'), ('PT-BN', 'PT', 'Braganca'), ('PT-CB', 'PT', 'Castelo Branco'), ('PT-CO', 'PT', 'Coimbra'), ('PT-EV', 'PT', 'Evora'), ('PT-FA', 'PT', 'Faro'), ('PT-GU', 'PT', 'Guarda'), ('PT-LE', 'PT', 'Leiria'), ('PT-LI', 'PT', 'Lisboa'), ('PT-MA', 'PT', 'Madeira'), ('PT-PG', 'PT', 'Portalegre'), ('PT-PO', 'PT', 'Porto'), ('PT-SA', 'PT', 'Santarem'), ('PT-SE', 'PT', 'Setubal'), ('PT-VC', 'PT', 'Viana do Castelo'), ('PT-VR', 'PT', 'Vila Real'), ('PT-VS', 'PT', 'Viseu'), ('PW-AM', 'PW', 'Aimeliik'), ('PW-AN', 'PW', 'Angaur'), ('PW-AR', 'PW', 'Airai'), ('PW-HA', 'PW', 'Hatohobei'), ('PW-KA', 'PW', 'Kayangel'), ('PW-KO', 'PW', 'Koror'), ('PW-ME', 'PW', 'Melekeok'), ('PW-NA', 'PW', 'Ngaraard'), ('PW-NC', 'PW', 'Ngchesar'), ('PW-ND', 'PW', 'Ngardmau'), ('PW-NG', 'PW', 'Ngarchelong'), ('PW-NR', 'PW', 'Ngeremlengui'), ('PW-NT', 'PW', 'Ngatpang'), ('PW-NW', 'PW', 'Ngiwal'), ('PW-PE', 'PW', 'Peleliu'), ('PW-SO', 'PW', 'Sonsorol'), ('PY-AG', 'PY', 'Alto Paraguay'), ('PY-AM', 'PY', 'Amambay'), ('PY-AN', 'PY', 'Alto Parana'), ('PY-AS', 'PY', 'Asuncion'), ('PY-BO', 'PY', 'Boqueron'), ('PY-CC', 'PY', 'Concepcion'), ('PY-CD', 'PY', 'Cordillera'), ('PY-CE', 'PY', 'Central'), ('PY-CG', 'PY', 'Caaguazu'), ('PY-CN', 'PY', 'Canindeyu'), ('PY-CZ', 'PY', 'Caazapa'), ('PY-GU', 'PY', 'Guaira'), ('PY-IT', 'PY', 'Itapua'), ('PY-MI', 'PY', 'Misiones'), ('PY-NE', 'PY', 'Neembucu'), ('PY-PA', 'PY', 'Paraguari'), ('PY-PH', 'PY', 'Presidente Hayes'), ('PY-SP', 'PY', 'San Pedro'), ('QA-DW', 'QA', 'Ad Dawhah'), ('QA-GW', 'QA', 'Al Ghuwayriyah'), ('QA-JB', 'QA', 'Jarayan al Batinah'), ('QA-JM', 'QA', 'Al Jumayliyah'), ('QA-KR', 'QA', 'Al Khawr'), ('QA-MS', 'QA', 'Madinat ash Shamal'), ('QA-RN', 'QA', 'Ar Rayyan'), ('QA-UD', 'QA', 'Umm Sa''id'), ('QA-UL', 'QA', 'Umm Salal'), ('QA-WK', 'QA', 'Al Wakrah'), ('RO-AD', 'RO', 'Arad'), ('RO-AG', 'RO', 'Arges'), ('RO-AL', 'RO', 'Alba'), ('RO-BA', 'RO', 'Bacau'), ('RO-BC', 'RO', 'Bucuresti'), ('RO-BH', 'RO', 'Bihor'), ('RO-BL', 'RO', 'Braila'), ('RO-BN', 'RO', 'Bistrita-Nasaud'), ('RO-BO', 'RO', 'Botosani'), ('RO-BS', 'RO', 'Brasov'), ('RO-BZ', 'RO', 'Buzau'), ('RO-CJ', 'RO', 'Cluj'), ('RO-CR', 'RO', 'Calarasi'), ('RO-CS', 'RO', 'Caras-Severin'), ('RO-CT', 'RO', 'Constanta'), ('RO-CV', 'RO', 'Covasna'), ('RO-DI', 'RO', 'Dimbovita'), ('RO-DO', 'RO', 'Dolj'), ('RO-GG', 'RO', 'Giurgiu'), ('RO-GJ', 'RO', 'Gorj'), ('RO-GL', 'RO', 'Galati'), ('RO-HA', 'RO', 'Harghita'), ('RO-HU', 'RO', 'Hunedoara'), ('RO-IF', 'RO', 'Ilfov'), ('RO-IM', 'RO', 'Ialomita'), ('RO-IS', 'RO', 'Iasi'), ('RO-MA', 'RO', 'Maramures'), ('RO-ME', 'RO', 'Mehedinti'), ('RO-MU', 'RO', 'Mures'), ('RO-NE', 'RO', 'Neamt'), ('RO-OL', 'RO', 'Olt'), ('RO-PR', 'RO', 'Prahova'), ('RO-SI', 'RO', 'Timis'), ('RO-SJ', 'RO', 'Salaj'), ('RO-SM', 'RO', 'Satu Mare'), ('RO-SO', 'RO', 'Sibiu'), ('RO-SU', 'RO', 'Suceava'), ('RO-TE', 'RO', 'Teleorman'), ('RO-TU', 'RO', 'Tulcea'), ('RO-VA', 'RO', 'Vaslui'), ('RO-VI', 'RO', 'Vilcea'), ('RO-VR', 'RO', 'Vrancea'), ('RU-AD', 'RU', 'Adygeya'), ('RU-AGB', 'RU', 'Aga Buryatia'), ('RU-AL', 'RU', 'Altai Republic'), ('RU-ALT', 'RU', 'Altai Krai'), ('RU-AMU', 'RU', 'Amur'), ('RU-ARK', 'RU', 'Arkhangelsk'), ('RU-AST', 'RU', 'Astrakhan'), ('RU-BA', 'RU', 'Bashkortostan'), ('RU-BEL', 'RU', 'Belgorod'), ('RU-BRY', 'RU', 'Bryansk'), ('RU-BU', 'RU', 'Buryatia'), ('RU-CE', 'RU', 'Chechnya'), ('RU-CHE', 'RU', 'Chelyabinsk'), ('RU-CHI', 'RU', 'Chita'), ('RU-CHU', 'RU', 'Chukotka'), ('RU-CU', 'RU', 'Chuvashia'), ('RU-DA', 'RU', 'Dagestan'), ('RU-EVE', 'RU', 'Evenkia'), ('RU-IN', 'RU', 'Ingushetia'), ('RU-IRK', 'RU', 'Irkutsk'), ('RU-IVA', 'RU', 'Ivanovo'), ('RU-KAM', 'RU', 'Kamchatka'), ('RU-KB', 'RU', 'Kabardino-Balkaria'), ('RU-KC', 'RU', 'Karachay-Cherkessia'), ('RU-KDA', 'RU', 'Krasnodar'), ('RU-KEM', 'RU', 'Kemerovo'), ('RU-KGD', 'RU', 'Kaliningrad'), ('RU-KGN', 'RU', 'Kurgan'), ('RU-KHA', 'RU', 'Khabarovsk'), ('RU-KHM', 'RU', 'Khantia-Mansia'), ('RU-KIR', 'RU', 'Kirov'), ('RU-KK', 'RU', 'Khakassia'), ('RU-KL', 'RU', 'Kalmykia'), ('RU-KLU', 'RU', 'Kaluga'), ('RU-KO', 'RU', 'Komi'), ('RU-KOP', 'RU', 'Permyakia'), ('RU-KOR', 'RU', 'Koryakia'), ('RU-KOS', 'RU', 'Kostroma'), ('RU-KR', 'RU', 'Karelia'), ('RU-KRS', 'RU', 'Kursk'), ('RU-KYA', 'RU', 'Krasnoyarsk'), ('RU-LEN', 'RU', 'Leningrad'), ('RU-LIP', 'RU', 'Lipetsk'), ('RU-MAG', 'RU', 'Magadan'), ('RU-ME', 'RU', 'Mari El'), ('RU-MO', 'RU', 'Mordovia'), ('RU-MOS', 'RU', 'Moscow (Province)'), ('RU-MOW', 'RU', 'Moscow (City)'), ('RU-MUR', 'RU', 'Murmansk'), ('RU-NEN', 'RU', 'Nenetsia'), ('RU-NGR', 'RU', 'Novgorod'), ('RU-NIZ', 'RU', 'Nizhny Novgorod'), ('RU-NVS', 'RU', 'Novosibirsk'), ('RU-OMS', 'RU', 'Omsk'), ('RU-ORE', 'RU', 'Orenburg'), ('RU-ORL', 'RU', 'Oryol'), ('RU-PER', 'RU', 'Perm'), ('RU-PNZ', 'RU', 'Penza'), ('RU-PRI', 'RU', 'Primorsky'), ('RU-PSK', 'RU', 'Pskov'), ('RU-ROS', 'RU', 'Rostov'), ('RU-RYA', 'RU', 'Ryazan'), ('RU-SA', 'RU', 'Sakha'), ('RU-SAK', 'RU', 'Sakhalin'), ('RU-SAM', 'RU', 'Samara'), ('RU-SAR', 'RU', 'Saratov'), ('RU-SE', 'RU', 'North Ossetia'), ('RU-SMO', 'RU', 'Smolensk'), ('RU-SPE', 'RU', 'St. Petersburg'), ('RU-STA', 'RU', 'Stavropol'), ('RU-SVE', 'RU', 'Sverdlovsk'), ('RU-TA', 'RU', 'Tatarstan'), ('RU-TAM', 'RU', 'Tambov'), ('RU-TAY', 'RU', 'Taymyria'), ('RU-TOM', 'RU', 'Tomsk'), ('RU-TUL', 'RU', 'Tula'), ('RU-TVE', 'RU', 'Tver'), ('RU-TY', 'RU', 'Tuva'), ('RU-TYU', 'RU', 'Tyumen'), ('RU-UD', 'RU', 'Udmurtia'), ('RU-ULY', 'RU', 'Ulynovsk'), ('RU-UOB', 'RU', 'Ust-Orda Buryatia'), ('RU-VGG', 'RU', 'Volgograd'), ('RU-VLA', 'RU', 'Vladimir'), ('RU-VLG', 'RU', 'Vologda'), ('RU-VOR', 'RU', 'Voronezh'), ('RU-YAN', 'RU', 'Yamalia'), ('RU-YAR', 'RU', 'Yaroslavl'), ('RU-YEV', 'RU', 'Jewish Oblast'), ('RW-BU', 'RW', 'Butare'), ('RW-BY', 'RW', 'Byumba'), ('RW-CY', 'RW', 'Cyangugu'), ('RW-GK', 'RW', 'Gikongoro'), ('RW-GS', 'RW', 'Gisenyi'), ('RW-GT', 'RW', 'Gitarama'), ('RW-KG', 'RW', 'Kibungo'), ('RW-KR', 'RW', 'Kigali Rurale'), ('RW-KV', 'RW', 'Kigali-ville'), ('RW-KY', 'RW', 'Kibuye'), ('RW-RU', 'RW', 'Ruhengeri'), ('RW-UM', 'RW', 'Umutara'), ('SA-AQ', 'SA', 'Ash Sharqiyah (Eastern Province)'), ('SA-AS', 'SA', '''Asir'), ('SA-BH', 'SA', 'Al Bahah'), ('SA-HL', 'SA', 'Ha''il'), ('SA-HS', 'SA', 'Al Hudud ash Shamaliyah'), ('SA-JF', 'SA', 'Al Jawf'), ('SA-JZ', 'SA', 'Jizan'), ('SA-MD', 'SA', 'Al Madinah'), ('SA-ML', 'SA', 'Makkah'), ('SA-NR', 'SA', 'Najran'), ('SA-QS', 'SA', 'Al Qasim'), ('SA-RD', 'SA', 'Ar Riyad'), ('SA-TB', 'SA', 'Tabuk'), ('SB-CE', 'SB', 'Central'), ('SB-CH', 'SB', 'Choiseul'), ('SB-GC', 'SB', 'Guadalcanal'), ('SB-HO', 'SB', 'Honiara'), ('SB-IS', 'SB', 'Isabel'), ('SB-MK', 'SB', 'Makira'), ('SB-ML', 'SB', 'Malaita'), ('SB-RB', 'SB', 'Rennell and Bellona'), ('SB-TM', 'SB', 'Temotu'), ('SB-WE', 'SB', 'Western'), ('SC-AB', 'SC', 'Anse Boileau'), ('SC-AE', 'SC', 'Anse Etoile'), ('SC-AL', 'SC', 'Anse Louis'), ('SC-AP', 'SC', 'Anse aux Pins'), ('SC-AR', 'SC', 'Anse Royale'), ('SC-BA', 'SC', 'Bel Air'), ('SC-BL', 'SC', 'Baie Lazare'), ('SC-BO', 'SC', 'Bel Ombre'), ('SC-BS', 'SC', 'Baie Sainte Anne'), ('SC-BV', 'SC', 'Beau Vallon'), ('SC-CA', 'SC', 'Cascade'), ('SC-DG', 'SC', 'La Digue'), ('SC-GL', 'SC', 'Glacis'), ('SC-GM', 'SC', 'Grand'' Anse (on Mahe)'), ('SC-GP', 'SC', 'Grand'' Anse (on Praslin)'), ('SC-MB', 'SC', 'Mont Buxton'), ('SC-MF', 'SC', 'Mont Fleuri'), ('SC-PG', 'SC', 'Port Glaud'), ('SC-PL', 'SC', 'Plaisance'), ('SC-PR', 'SC', 'Pointe La Rue'), ('SC-RA', 'SC', 'La Riviere Anglaise'), ('SC-SL', 'SC', 'Saint Louis'), ('SC-TA', 'SC', 'Takamaka'), ('SD-ANB', 'SD', 'An Nil al Abyad'), ('SD-ANL', 'SD', 'A''ali an Nil'), ('SD-ANZ', 'SD', 'An Nil al Azraq'), ('SD-ASH', 'SD', 'Ash Shamaliyah'), ('SD-BAM', 'SD', 'Al Bahr al Ahmar'), ('SD-BJA', 'SD', 'Bahr al Jabal'), ('SD-BRT', 'SD', 'Al Buhayrat'), ('SD-GBG', 'SD', 'Gharb Bahr al Ghazal'), ('SD-GDA', 'SD', 'Gharb Darfur'), ('SD-GIS', 'SD', 'Gharb al Istiwa''iyah'), ('SD-GKU', 'SD', 'Gharb Kurdufan'), ('SD-JDA', 'SD', 'Janub Darfur'), ('SD-JKU', 'SD', 'Janub Kurdufan'), ('SD-JQL', 'SD', 'Junqali'), ('SD-JZR', 'SD', 'Al Jazirah'), ('SD-KRT', 'SD', 'Al Khartum'), ('SD-KSL', 'SD', 'Kassala'), ('SD-NNL', 'SD', 'Nahr an Nil'), ('SD-QDR', 'SD', 'Al Qadarif'), ('SD-SBG', 'SD', 'Shamal Bahr al Ghazal'), ('SD-SDA', 'SD', 'Shamal Darfur'), ('SD-SIS', 'SD', 'Sharq al Istiwa''iyah'), ('SD-SKU', 'SD', 'Shamal Kurdufan'), ('SD-SNR', 'SD', 'Sinnar'), ('SD-WDH', 'SD', 'Al Wahdah'), ('SD-WRB', 'SD', 'Warab'), ('SH-A', 'SH', 'Ascension'), ('SH-S', 'SH', 'Saint Helena'), ('SH-T', 'SH', 'Tristan da Cunha'), ('SK-BA', 'SK', 'Banskobystricky'), ('SK-BR', 'SK', 'Bratislavsky'), ('SK-KO', 'SK', 'Kosicky'), ('SK-NI', 'SK', 'Nitriansky'), ('SK-PR', 'SK', 'Presovsky'), ('SK-TC', 'SK', 'Trenciansky'), ('SK-TV', 'SK', 'Trnavsky'), ('SK-ZI', 'SK', 'Zilinsky'), ('SL-E', 'SL', 'Eastern'), ('SL-N', 'SL', 'Northern'), ('SL-S', 'SL', 'Southern'), ('SL-W', 'SL', 'Western'), ('SM-AC', 'SM', 'Acquaviva'), ('SM-BM', 'SM', 'Borgo Maggiore'), ('SM-CH', 'SM', 'Chiesanuova'), ('SM-DO', 'SM', 'Domagnano'), ('SM-FA', 'SM', 'Faetano'), ('SM-FI', 'SM', 'Fiorentino'), ('SM-MO', 'SM', 'Montegiardino'), ('SM-SE', 'SM', 'Serravalle'), ('SM-SM', 'SM', 'Citta di San Marino'), ('SN-DA', 'SN', 'Dakar'), ('SN-DI', 'SN', 'Diourbel'), ('SN-FA', 'SN', 'Fatick'), ('SN-KA', 'SN', 'Kaolack'), ('SN-KO', 'SN', 'Kolda'), ('SN-LO', 'SN', 'Louga'), ('SN-MA', 'SN', 'Matam'), ('SN-SL', 'SN', 'Saint-Louis'), ('SN-TA', 'SN', 'Tambacounda'), ('SN-TH', 'SN', 'Thies'), ('SN-ZI', 'SN', 'Ziguinchor'), ('SO-AW', 'SO', 'Awdal'), ('SO-BK', 'SO', 'Bakool'), ('SO-BN', 'SO', 'Banaadir'), ('SO-BR', 'SO', 'Bari'), ('SO-BY', 'SO', 'Bay'), ('SO-GA', 'SO', 'Galguduud'), ('SO-GE', 'SO', 'Gedo'), ('SO-HI', 'SO', 'Hiiraan'), ('SO-JD', 'SO', 'Jubbada Dhexe'), ('SO-JH', 'SO', 'Jubbada Hoose'), ('SO-MU', 'SO', 'Mudug'), ('SO-NU', 'SO', 'Nugaal'), ('SO-SA', 'SO', 'Sanaag'), ('SO-SD', 'SO', 'Shabeellaha Dhexe'), ('SO-SH', 'SO', 'Shabeellaha Hoose'), ('SO-SL', 'SO', 'Sool'), ('SO-TO', 'SO', 'Togdheer'), ('SO-WG', 'SO', 'Woqooyi Galbeed'), ('SR-BR', 'SR', 'Brokopondo'), ('SR-CM', 'SR', 'Commewijne'), ('SR-CR', 'SR', 'Coronie'), ('SR-MA', 'SR', 'Marowijne'), ('SR-NI', 'SR', 'Nickerie'), ('SR-PA', 'SR', 'Para'), ('SR-PM', 'SR', 'Paramaribo'), ('SR-SA', 'SR', 'Saramacca'), ('SR-SI', 'SR', 'Sipaliwini'), ('SR-WA', 'SR', 'Wanica'), ('ST-P', 'ST', 'Principe'), ('ST-S', 'ST', 'Sao Tome'), ('SV-AH', 'SV', 'Ahuachapan'), ('SV-CA', 'SV', 'Cabanas'), ('SV-CH', 'SV', 'Chalatenango'), ('SV-CU', 'SV', 'Cuscatlan'), ('SV-LB', 'SV', 'La Libertad'), ('SV-MO', 'SV', 'Morazan'), ('SV-PZ', 'SV', 'La Paz'), ('SV-SA', 'SV', 'Santa Ana'), ('SV-SM', 'SV', 'San Miguel'), ('SV-SO', 'SV', 'Sonsonate'), ('SV-SS', 'SV', 'San Salvador'), ('SV-SV', 'SV', 'San Vicente'), ('SV-UN', 'SV', 'La Union'), ('SV-US', 'SV', 'Usulutan'), ('SW-BL', 'SW', 'Blekinge'), ('SW-DA', 'SW', 'Dalama'), ('SW-GA', 'SW', 'Gavleborg'), ('SW-GO', 'SW', 'Gotland'), ('SW-HA', 'SW', 'Halland'), ('SW-JA', 'SW', 'Jamtland'), ('SW-JO', 'SW', 'Jonkping'), ('SW-KA', 'SW', 'Kalmar'), ('SW-KR', 'SW', 'Kronoberg'), ('SW-NO', 'SW', 'Norrbotten'), ('SW-OG', 'SW', 'Ostergotland'), ('SW-OR', 'SW', 'Orebro'), ('SW-SK', 'SW', 'Skane'), ('SW-SO', 'SW', 'Sodermanland'), ('SW-ST', 'SW', 'Stockholm'), ('SW-UP', 'SW', 'Uppdala'), ('SW-VB', 'SW', 'Vasterbotten'), ('SW-VG', 'SW', 'Vastra Gotaland'), ('SW-VL', 'SW', 'Varmland'), ('SW-VM', 'SW', 'Vastmanland'), ('SW-VN', 'SW', 'Vasternorrland'), ('SY-DA', 'SY', 'Dara'), ('SY-DI', 'SY', 'Dimashq'), ('SY-DZ', 'SY', 'Dayr az Zawr'), ('SY-HA', 'SY', 'Al Hasakah'), ('SY-HI', 'SY', 'Hims'), ('SY-HL', 'SY', 'Halab'), ('SY-HM', 'SY', 'Hamah'), ('SY-ID', 'SY', 'Idlib'), ('SY-LA', 'SY', 'Al Ladhiqiyah'), ('SY-QU', 'SY', 'Al Qunaytirah'), ('SY-RD', 'SY', 'Rif Dimashq'), ('SY-RQ', 'SY', 'Ar Raqqah'), ('SY-SU', 'SY', 'As Suwayda'), ('SY-TA', 'SY', 'Tartus'), ('SZ-H', 'SZ', 'Hhohho'), ('SZ-L', 'SZ', 'Lubombo'), ('SZ-M', 'SZ', 'Manzini'), ('SZ-S', 'SZ', 'Shishelweni'), ('TC-AC', 'TC', 'Ambergris Cays'), ('TC-DC', 'TC', 'Dellis Cay'), ('TC-EC', 'TC', 'East Caicos'), ('TC-FC', 'TC', 'French Cay'), ('TC-GT', 'TC', 'Grand Turk'), ('TC-LW', 'TC', 'Little Water Cay'), ('TC-MC', 'TC', 'Middle Caicos'), ('TC-NC', 'TC', 'North Caicos'), ('TC-PN', 'TC', 'Pine Cay'), ('TC-PR', 'TC', 'Providenciales'), ('TC-RC', 'TC', 'Parrot Cay'), ('TC-SC', 'TC', 'South Caicos'), ('TC-SL', 'TC', 'Salt Cay'), ('TC-WC', 'TC', 'West Caicos'), ('TD-BA', 'TD', 'Batha'), ('TD-BE', 'TD', 'Borkou-Ennedi-Tibesti'), ('TD-BI', 'TD', 'Biltine'), ('TD-CB', 'TD', 'Chari-Baguirmi'), ('TD-GU', 'TD', 'Guera'), ('TD-KA', 'TD', 'Kanem'), ('TD-LA', 'TD', 'Lac'), ('TD-LC', 'TD', 'Logone Occidental'), ('TD-LR', 'TD', 'Logone Oriental'), ('TD-MC', 'TD', 'Moyen-Chari'), ('TD-MK', 'TD', 'Mayo-Kebbi'), ('TD-OU', 'TD', 'Ouaddai'), ('TD-SA', 'TD', 'Salamat'), ('TD-TA', 'TD', 'Tandjile'), ('TF-A', 'TF', 'Ile Amsterdam'), ('TF-C', 'TF', 'Iles Crozet'), ('TF-D', 'TF', 'Adelie Land'), ('TF-K', 'TF', 'Iles Kerguelen'), ('TF-P', 'TF', 'Ile Saint-Paul'), ('TG-C', 'TG', 'Centrale'), ('TG-K', 'TG', 'Kara'), ('TG-M', 'TG', 'Maritime'), ('TG-P', 'TG', 'Plateaux'), ('TG-S', 'TG', 'Savanes'), ('TH-10', 'TH', 'Bangkok'), ('TH-11', 'TH', 'Samut Prakan'), ('TH-12', 'TH', 'Nonthaburi'), ('TH-13', 'TH', 'Pathum Thani'), ('TH-14', 'TH', 'Phra Nakhon Si Ayutthaya'), ('TH-15', 'TH', 'Ang Thong'), ('TH-16', 'TH', 'Lop Buri'), ('TH-17', 'TH', 'Sing Buri'), ('TH-18', 'TH', 'Chai Nat'), ('TH-19', 'TH', 'Saraburi'), ('TH-20', 'TH', 'Chon Buri'), ('TH-21', 'TH', 'Rayong'), ('TH-22', 'TH', 'Chanthaburi'), ('TH-23', 'TH', 'Trat'), ('TH-24', 'TH', 'Chachoengsao'), ('TH-25', 'TH', 'Prachin Buri'), ('TH-26', 'TH', 'Nakhon Nayok'), ('TH-27', 'TH', 'Sa Kaeo'), ('TH-30', 'TH', 'Nakhon Ratchasima'), ('TH-31', 'TH', 'Buri Ram'), ('TH-32', 'TH', 'Surin'), ('TH-33', 'TH', 'Si Sa Ket'), ('TH-34', 'TH', 'Ubon Ratchathani'), ('TH-35', 'TH', 'Yasothon'), ('TH-36', 'TH', 'Chaiyaphum'), ('TH-37', 'TH', 'Amnat Charoen'), ('TH-39', 'TH', 'Nong Bua Lam Phu'), ('TH-40', 'TH', 'Khon Kaen'), ('TH-41', 'TH', 'Udon Thani'), ('TH-42', 'TH', 'Loei'), ('TH-43', 'TH', 'Nong Khai'), ('TH-44', 'TH', 'Maha Sarakham'), ('TH-45', 'TH', 'Roi Et'), ('TH-46', 'TH', 'Kalasin'), ('TH-47', 'TH', 'Sakon Nakhon'), ('TH-48', 'TH', 'Nakhon Phanom'), ('TH-49', 'TH', 'Mukdahan'), ('TH-50', 'TH', 'Chiang Mai'), ('TH-51', 'TH', 'Lamphun'), ('TH-52', 'TH', 'Lampang'), ('TH-53', 'TH', 'Uttaradit'), ('TH-54', 'TH', 'Phrae'), ('TH-55', 'TH', 'Nan'), ('TH-56', 'TH', 'Phayao'), ('TH-57', 'TH', 'Chiang Rai'), ('TH-58', 'TH', 'Mae Hong Son'), ('TH-60', 'TH', 'Nakhon Sawan'), ('TH-61', 'TH', 'Uthai Thani'), ('TH-62', 'TH', 'Kamphaeng Phet'), ('TH-63', 'TH', 'Tak'), ('TH-64', 'TH', 'Sukhothai'), ('TH-65', 'TH', 'Phitsanulok'), ('TH-66', 'TH', 'Phichit'), ('TH-70', 'TH', 'Ratchaburi'), ('TH-71', 'TH', 'Kanchanaburi'), ('TH-72', 'TH', 'Suphanburi'), ('TH-73', 'TH', 'Nakhon Pathom'), ('TH-74', 'TH', 'Samut Sakhon'), ('TH-75', 'TH', 'Samut Songkhram'), ('TH-76', 'TH', 'Phetchabun'), ('TH-77', 'TH', 'Prachuap Khiri Khan'), ('TH-78', 'TH', 'Phetchaburi'), ('TH-80', 'TH', 'Nakhon Si Thammarat'), ('TH-81', 'TH', 'Krabi'), ('TH-82', 'TH', 'Phang Nga'), ('TH-83', 'TH', 'Phuket'), ('TH-84', 'TH', 'Surat Thani'), ('TH-85', 'TH', 'Ranong'), ('TH-86', 'TH', 'Chumpon'), ('TH-90', 'TH', 'Songkhla'), ('TH-91', 'TH', 'Satun'), ('TH-92', 'TH', 'Trang'), ('TH-93', 'TH', 'Phattalung'), ('TH-94', 'TH', 'Pattani'), ('TH-95', 'TH', 'Yala'), ('TH-96', 'TH', 'Narathiwat'), ('TH-S', 'TH', 'Pattaya'), ('TJ-GB', 'TJ', 'Gorno-Badakhstan'), ('TJ-KT', 'TJ', 'Khatlon'), ('TJ-SU', 'TJ', 'Sughd'), ('TK-A', 'TK', 'Atafu'), ('TK-F', 'TK', 'Fakaofo'), ('TK-N', 'TK', 'Nukunonu'), ('TL-AL', 'TL', 'Aileu'), ('TL-AN', 'TL', 'Ainaro'), ('TL-BA', 'TL', 'Baucau'), ('TL-BO', 'TL', 'Bobonaro'), ('TL-CO', 'TL', 'Cova Lima'), ('TL-DI', 'TL', 'Dili'), ('TL-ER', 'TL', 'Ermera'), ('TL-LA', 'TL', 'Lautem'), ('TL-LI', 'TL', 'Liquica'), ('TL-MF', 'TL', 'Manufahi'), ('TL-MT', 'TL', 'Manatuto'), ('TL-OE', 'TL', 'Oecussi'), ('TL-VI', 'TL', 'Viqueque'), ('TM-A', 'TM', 'Ahal Welayaty'), ('TM-B', 'TM', 'Balkan Welayaty'), ('TM-D', 'TM', 'Dashhowuz Welayaty'), ('TM-L', 'TM', 'Lebap Welayaty'), ('TM-M', 'TM', 'Mary Welayaty'), ('TN-AR', 'TN', 'Ariana'), ('TN-BA', 'TN', 'Ben Arous'), ('TN-BI', 'TN', 'Bizerte'), ('TN-BJ', 'TN', 'Beja'), ('TN-GB', 'TN', 'Gabes'), ('TN-GF', 'TN', 'Gafsa'), ('TN-JE', 'TN', 'Jendouba'), ('TN-KB', 'TN', 'Kebili'), ('TN-KF', 'TN', 'Kef'), ('TN-KR', 'TN', 'Kairouan'), ('TN-KS', 'TN', 'Kasserine'), ('TN-ME', 'TN', 'Medenine'), ('TN-MH', 'TN', 'Mahdia'), ('TN-MN', 'TN', 'Manouba'), ('TN-MO', 'TN', 'Monastir'), ('TN-NA', 'TN', 'Nabeul'), ('TN-SD', 'TN', 'Sidi'), ('TN-SF', 'TN', 'Sfax'), ('TN-SL', 'TN', 'Siliana'), ('TN-SO', 'TN', 'Sousse'), ('TN-TA', 'TN', 'Tataouine'), ('TN-TO', 'TN', 'Tozeur'), ('TN-TU', 'TN', 'Tunis'), ('TN-ZA', 'TN', 'Zaghouan'), ('TO-H', 'TO', 'Ha''apai'), ('TO-T', 'TO', 'Tongatapu'), ('TO-V', 'TO', 'Vava''u'), ('TR-ADA', 'TR', 'Adana'), ('TR-ADI', 'TR', 'Adiyaman'), ('TR-AFY', 'TR', 'Afyonkarahisar'), ('TR-AGR', 'TR', 'Agri'), ('TR-AKS', 'TR', 'Aksaray'), ('TR-AMA', 'TR', 'Amasya'), ('TR-ANK', 'TR', 'Ankara'), ('TR-ANT', 'TR', 'Antalya'), ('TR-ARD', 'TR', 'Ardahan'), ('TR-ART', 'TR', 'Artvin'), ('TR-AYI', 'TR', 'Aydin'), ('TR-BAL', 'TR', 'Balikesir'), ('TR-BAR', 'TR', 'Bartin'), ('TR-BAT', 'TR', 'Batman'), ('TR-BAY', 'TR', 'Bayburt'), ('TR-BIL', 'TR', 'Bilecik'), ('TR-BIN', 'TR', 'Bingol'), ('TR-BIT', 'TR', 'Bitlis'), ('TR-BOL', 'TR', 'Bolu'), ('TR-BRD', 'TR', 'Burdur'), ('TR-BRS', 'TR', 'Bursa'), ('TR-CKL', 'TR', 'Canakkale'), ('TR-CKR', 'TR', 'Cankiri'), ('TR-COR', 'TR', 'Corum'), ('TR-DEN', 'TR', 'Denizli'), ('TR-DIY', 'TR', 'Diyarbakir'), ('TR-DUZ', 'TR', 'Duzce'), ('TR-EDI', 'TR', 'Edirne'), ('TR-ELA', 'TR', 'Elazig'), ('TR-ESK', 'TR', 'Eskisehir'), ('TR-EZC', 'TR', 'Erzincan'), ('TR-EZR', 'TR', 'Erzurum'), ('TR-GAZ', 'TR', 'Gaziantep'), ('TR-GIR', 'TR', 'Giresun'), ('TR-GMS', 'TR', 'Gumushane'), ('TR-HKR', 'TR', 'Hakkari'), ('TR-HTY', 'TR', 'Hatay'), ('TR-IGD', 'TR', 'Igdir'), ('TR-ISP', 'TR', 'Isparta'), ('TR-IST', 'TR', 'Istanbul'), ('TR-IZM', 'TR', 'Izmir'), ('TR-KAH', 'TR', 'Kahramanmaras'), ('TR-KAS', 'TR', 'Kastamonu'), ('TR-KAY', 'TR', 'Kayseri'), ('TR-KLR', 'TR', 'Kirklareli'), ('TR-KLS', 'TR', 'Kilis'), ('TR-KOC', 'TR', 'Kocaeli'), ('TR-KON', 'TR', 'Konya'), ('TR-KRB', 'TR', 'Karabuk'), ('TR-KRH', 'TR', 'Kirsehir'), ('TR-KRK', 'TR', 'Kirikkale'), ('TR-KRM', 'TR', 'Karaman'), ('TR-KRS', 'TR', 'Kars'), ('TR-KUT', 'TR', 'Kutahya'), ('TR-MAL', 'TR', 'Malatya'), ('TR-MAN', 'TR', 'Manisa'), ('TR-MAR', 'TR', 'Mardin'), ('TR-MER', 'TR', 'Mersin'), ('TR-MUG', 'TR', 'Mugla'), ('TR-MUS', 'TR', 'Mus'), ('TR-NEV', 'TR', 'Nevsehir'), ('TR-NIG', 'TR', 'Nigde'), ('TR-ORD', 'TR', 'Ordu'), ('TR-OSM', 'TR', 'Osmaniye'), ('TR-RIZ', 'TR', 'Rize'), ('TR-SAK', 'TR', 'Sakarya'), ('TR-SAM', 'TR', 'Samsun'), ('TR-SAN', 'TR', 'Sanliurfa'), ('TR-SII', 'TR', 'Siirt'), ('TR-SIN', 'TR', 'Sinop'), ('TR-SIR', 'TR', 'Sirnak'), ('TR-SIV', 'TR', 'Sivas'), ('TR-TEL', 'TR', 'Tekirdag'), ('TR-TOK', 'TR', 'Tokat'), ('TR-TRA', 'TR', 'Trabzon'), ('TR-TUN', 'TR', 'Tunceli'), ('TR-USK', 'TR', 'Usak'), ('TR-VAN', 'TR', 'Van'), ('TR-YAL', 'TR', 'Yalova'), ('TR-YOZ', 'TR', 'Yozgat'), ('TR-ZON', 'TR', 'Zonguldak'), ('TT-AR', 'TT', 'Arima'), ('TT-CH', 'TT', 'Chaguanas'), ('TT-CT', 'TT', 'Couva/Tabaquite/Talparo'), ('TT-DM', 'TT', 'Diego Martin'), ('TT-MR', 'TT', 'Mayaro/Rio Claro'), ('TT-PD', 'TT', 'Penal/Debe'), ('TT-PF', 'TT', 'Point Fortin'), ('TT-PS', 'TT', 'Port of Spain'), ('TT-PT', 'TT', 'Princes Town'), ('TT-SF', 'TT', 'San Fernando'), ('TT-SG', 'TT', 'Sangre Grande'), ('TT-SI', 'TT', 'Siparia'), ('TT-SL', 'TT', 'San Juan/Laventille'), ('TT-TO', 'TT', 'Tobago'), ('TT-TP', 'TT', 'Tunapuna/Piarco'), ('TV-FUN', 'TV', 'Funafuti'), ('TV-NFT', 'TV', 'Nukufetau'), ('TV-NLK', 'TV', 'Niulakita'), ('TV-NLL', 'TV', 'Nukulaelae'), ('TV-NME', 'TV', 'Nanumea'), ('TV-NMG', 'TV', 'Nanumanga'), ('TV-NTO', 'TV', 'Niutao'), ('TV-NUI', 'TV', 'Nui'), ('TV-VAI', 'TV', 'Vaitupu'), ('TW-CC', 'TW', 'Chia-i city'), ('TW-CH', 'TW', 'Chang-hua'), ('TW-CI', 'TW', 'Chia-i'), ('TW-CL', 'TW', 'Chi-lung'), ('TW-HC', 'TW', 'Hsin-chu'), ('TW-HL', 'TW', 'Hua-lien'), ('TW-HS', 'TW', 'Hsin-chu'), ('TW-IL', 'TW', 'I-lan'), ('TW-KC', 'TW', 'Kao-hsiung city'), ('TW-KH', 'TW', 'Kao-hsiung county'), ('TW-KM', 'TW', 'Kin-men'), ('TW-LC', 'TW', 'Lien-chiang'), ('TW-ML', 'TW', 'Miao-li'), ('TW-NT', 'TW', 'Nan-t''ou'), ('TW-PH', 'TW', 'P''eng-hu'), ('TW-PT', 'TW', 'P''ing-tung'), ('TW-TA', 'TW', 'T''ai-nan'), ('TW-TC', 'TW', 'T''ai-pei city'), ('TW-TG', 'TW', 'T''ai-chung'), ('TW-TH', 'TW', 'T''ai-chung'), ('TW-TN', 'TW', 'T''ai-nan'), ('TW-TP', 'TW', 'T''ai-pei county'), ('TW-TT', 'TW', 'T''ai-tung'), ('TW-TY', 'TW', 'T''ao-yuan'), ('TW-YL', 'TW', 'Yun-lin'), ('TZ-AR', 'TZ', 'Arusha'), ('TZ-DO', 'TZ', 'Dodoma'), ('TZ-DS', 'TZ', 'Dar es Salaam'), ('TZ-IR', 'TZ', 'Iringa'), ('TZ-KA', 'TZ', 'Kagera'), ('TZ-KI', 'TZ', 'Kigoma'), ('TZ-KJ', 'TZ', 'Kilimanjaro'), ('TZ-LN', 'TZ', 'Lindi'), ('TZ-MB', 'TZ', 'Mbeya'), ('TZ-MO', 'TZ', 'Morogoro'), ('TZ-MR', 'TZ', 'Mara'), ('TZ-MT', 'TZ', 'Mtwara'), ('TZ-MW', 'TZ', 'Mwanza'), ('TZ-MY', 'TZ', 'Manyara'), ('TZ-PN', 'TZ', 'Pemba North'), ('TZ-PS', 'TZ', 'Pemba South'), ('TZ-PW', 'TZ', 'Pwani'), ('TZ-RK', 'TZ', 'Rukwa'), ('TZ-RV', 'TZ', 'Ruvuma'), ('TZ-SH', 'TZ', 'Shinyanga'), ('TZ-SI', 'TZ', 'Singida'), ('TZ-TB', 'TZ', 'Tabora'), ('TZ-TN', 'TZ', 'Tanga'), ('TZ-ZC', 'TZ', 'Zanzibar Central/South'), ('TZ-ZN', 'TZ', 'Zanzibar North'), ('TZ-ZU', 'TZ', 'Zanzibar Urban/West'), ('UA-CH', 'UA', 'Chernihiv'), ('UA-CK', 'UA', 'Cherkasy'), ('UA-CR', 'UA', 'Crimea'), ('UA-CV', 'UA', 'Chernivtsi'), ('UA-DN', 'UA', 'Dnipropetrovs''k'), ('UA-DO', 'UA', 'Donets''k'), ('UA-IV', 'UA', 'Ivano-Frankivs''k'), ('UA-KL', 'UA', 'Kharkiv Kherson'), ('UA-KM', 'UA', 'Khmel''nyts''kyy'), ('UA-KR', 'UA', 'Kirovohrad'), ('UA-KV', 'UA', 'Kiev'), ('UA-KY', 'UA', 'Kyyiv'), ('UA-LU', 'UA', 'Luhans''k'), ('UA-LV', 'UA', 'L''viv'), ('UA-MY', 'UA', 'Mykolayiv'), ('UA-OD', 'UA', 'Odesa'), ('UA-PO', 'UA', 'Poltava'), ('UA-RI', 'UA', 'Rivne'), ('UA-SE', 'UA', 'Sevastopol'), ('UA-SU', 'UA', 'Sumy'), ('UA-TE', 'UA', 'Ternopil'''), ('UA-VI', 'UA', 'Vinnytsya'), ('UA-VO', 'UA', 'Volyn'''), ('UA-ZA', 'UA', 'Zaporizhzhya'), ('UA-ZH', 'UA', 'Zhytomyr'), ('UA-ZK', 'UA', 'Zakarpattya'), ('UG-ADJ', 'UG', 'Adjumani'), ('UG-APC', 'UG', 'Apac'), ('UG-ARU', 'UG', 'Arua'), ('UG-BSH', 'UG', 'Bushenyi'), ('UG-BUG', 'UG', 'Bugiri'), ('UG-BUN', 'UG', 'Bundibugyo'), ('UG-BUS', 'UG', 'Busia'), ('UG-GUL', 'UG', 'Gulu'), ('UG-HOI', 'UG', 'Hoima'), ('UG-IGA', 'UG', 'Iganga'), ('UG-JIN', 'UG', 'Jinja'), ('UG-KAB', 'UG', 'Kaberamaido'), ('UG-KAL', 'UG', 'Kalangala'), ('UG-KAM', 'UG', 'Kamwenge'), ('UG-KAN', 'UG', 'Kanungu'), ('UG-KAR', 'UG', 'Kabarole'), ('UG-KAS', 'UG', 'Kasese'), ('UG-KAY', 'UG', 'Kayunga'), ('UG-KBA', 'UG', 'Kibaale'), ('UG-KBL', 'UG', 'Kabale'), ('UG-KIB', 'UG', 'Kiboga'), ('UG-KIS', 'UG', 'Kisoro'), ('UG-KIT', 'UG', 'Kitgum'), ('UG-KML', 'UG', 'Kamuli'), ('UG-KMP', 'UG', 'Kampala'), ('UG-KOT', 'UG', 'Kotido'), ('UG-KPC', 'UG', 'Kapchorwa'), ('UG-KTK', 'UG', 'Katakwi'), ('UG-KUM', 'UG', 'Kumi'), ('UG-KYE', 'UG', 'Kyenjojo'), ('UG-LIR', 'UG', 'Lira'), ('UG-LUW', 'UG', 'Luwero'), ('UG-MAS', 'UG', 'Masaka'), ('UG-MAY', 'UG', 'Mayuge'), ('UG-MBA', 'UG', 'Mbale'), ('UG-MBR', 'UG', 'Mbarara'), ('UG-MOY', 'UG', 'Moyo'), ('UG-MPI', 'UG', 'Mpigi'), ('UG-MRT', 'UG', 'Moroto'), ('UG-MSN', 'UG', 'Masindi'), ('UG-MUB', 'UG', 'Mubende'), ('UG-MUK', 'UG', 'Mukono'), ('UG-NAK', 'UG', 'Nakapiripirit'), ('UG-NEB', 'UG', 'Nebbi'), ('UG-NKS', 'UG', 'Nakasongola'), ('UG-NTU', 'UG', 'Ntungamo'), ('UG-PAD', 'UG', 'Pader'), ('UG-PAL', 'UG', 'Pallisa'), ('UG-RAK', 'UG', 'Rakai'), ('UG-RUK', 'UG', 'Rukungiri'), ('UG-SEM', 'UG', 'Sembabule'), ('UG-SIR', 'UG', 'Sironko'), ('UG-SOR', 'UG', 'Soroti'), ('UG-TOR', 'UG', 'Tororo'), ('UG-WAK', 'UG', 'Wakiso'), ('UG-YUM', 'UG', 'Yumbe'), ('UM-BI', 'UM', 'Baker Island'), ('UM-HI', 'UM', 'Howland Island'), ('UM-JA', 'UM', 'Johnston Atoll'), ('UM-JI', 'UM', 'Jarvis Island'), ('UM-KR', 'UM', 'Kingman Reef'), ('UM-MA', 'UM', 'Midway Atoll'), ('UM-NI', 'UM', 'Navassa Island'), ('UM-PA', 'UM', 'Palmyra Atoll'), ('UM-WI', 'UM', 'Wake Island'), ('AK', 'US', 'Alaska'), ('AL', 'US', 'Alabama'), ('AR', 'US', 'Arkansas'), ('AS', 'US', 'American Samoa'), ('AZ', 'US', 'Arizona'), ('CA', 'US', 'California'), ('CO', 'US', 'Colorado'), ('CT', 'US', 'Connecticut'), ('DC', 'US', 'District of Columbia'), ('DE', 'US', 'Delaware'), ('FL', 'US', 'Florida'), ('GA', 'US', 'Georgia'), ('GU', 'US', 'Guam'), ('HI', 'US', 'Hawaii'), ('IA', 'US', 'Iowa'), ('ID', 'US', 'Idaho'), ('IL', 'US', 'Illinois'), ('IN', 'US', 'Indiana'), ('KS', 'US', 'Kansas'), ('KY', 'US', 'Kentucky'), ('LA', 'US', 'Louisiana'), ('MA', 'US', 'Massachusetts'), ('MD', 'US', 'Maryland'), ('ME', 'US', 'Maine'), ('MI', 'US', 'Michigan'), ('MN', 'US', 'Minnesota'), ('MO', 'US', 'Missouri'), ('MP', 'US', 'Northern Mariana Islands'), ('MS', 'US', 'Mississippi'), ('MT', 'US', 'Montana'), ('NC', 'US', 'North Carolina'), ('ND', 'US', 'North Dakota'), ('NE', 'US', 'Nebraska'), ('NH', 'US', 'New Hampshire'), ('NJ', 'US', 'New Jersey'), ('NM', 'US', 'New Mexico'), ('NV', 'US', 'Nevada'), ('NY', 'US', 'New York'), ('OH', 'US', 'Ohio'), ('OK', 'US', 'Oklahoma'), ('OR', 'US', 'Oregon'), ('PA', 'US', 'Pennsylvania'), ('PR', 'US', 'Puerto Rico'), ('RI', 'US', 'Rhode Island'), ('SC', 'US', 'South Carolina'), ('SD', 'US', 'South Dakota'), ('TN', 'US', 'Tennessee'), ('TX', 'US', 'Texas'), ('UM', 'US', 'U.S. Minor Outlying Islands'), ('UT', 'US', 'Utah'), ('VA', 'US', 'Virginia'), ('VI', 'US', 'Virgin Islands of the U.S.'), ('VT', 'US', 'Vermont'), ('WA', 'US', 'Washington'), ('WI', 'US', 'Wisconsin'), ('WV', 'US', 'West Virginia')