From f4f5381f66f460525ec7571f193967335a378602 Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Mon, 3 Aug 2015 17:46:24 +0200 Subject: [PATCH 01/54] Release 2.0.1 --- README.md | 59 +-- ctrynams.js | 268 +++++------ ctrynams_short.js | 551 +++++++++++++++++++++++ mapcode.js | 993 +++++++++++++++++++---------------------- mapcode_library_js.doc | Bin 77824 -> 93184 bytes ndata.js | 7 +- sample.html | 10 +- 7 files changed, 1184 insertions(+), 704 deletions(-) create mode 100644 ctrynams_short.js diff --git a/README.md b/README.md index 192be86..8d3faad 100644 --- a/README.md +++ b/README.md @@ -7,16 +7,15 @@ Copyright (C) 2014 Stichting Mapcode Foundation (http://www.mapcode.com) **Online documentation can be found at: http://mapcode-foundation.github.io/mapcode-js/** If you plan to use mapcodes in HTML/Javascript extensively, you may be interested in -looking at running an instance of a Mapcode REST API server in your applications -landscape. +looking at running an instance of a Mapcode REST API server in your applications +landscape. -This reduces the payload the HTML/Javascript tremendously, as the mapcode tables will +This reduces the payload the HTML/Javascript tremendously, as the mapcode tables will not need to be transported to the client. You can find the Mapcode REST API sources, ready to be deployed on any JVM server, like Tomcat or Jetty, on: **https://github.com/mapcode-foundation/mapcode-rest-service** - ## License Licensed under the Apache License, Version 2.0 (the "License"); @@ -46,6 +45,10 @@ of the Mapcode library by Rijn Buve and Matthew Lowden. * July 2015 + * 2.0.1 + + Prettyfied source and minor fixes. + * 2.0.0 Fixes to the data rectangles (primarily intended for ISO proposal), see Word document for details. @@ -59,15 +62,15 @@ of the Mapcode library by Rijn Buve and Matthew Lowden. * May 2015 * 1.50.3 - + Redesign of the API to conform to Javascript standards and match the Java implementation of the mapcode system * 1.50.1 - + Bugfix for mapcodes in IN-DD (in India). - * 1.50 - + * 1.50 + Major release. This version is not backwards compatible with mapcode 1.4x: is has dropped support for Antartica AT0-8 codes and has a changed (improved) way of dealing with the Greek alphabet. @@ -79,49 +82,49 @@ of the Mapcode library by Rijn Buve and Matthew Lowden. * January 2015 - * 1.41 - + * 1.41 + Added the India state Telangana (IN-TG), until 2014 a region in Adhra Pradesh. * August 2014 - * 1.33 - + * 1.33 + Normalise results when longitude below -180 degrees. - * 1.32 - + * 1.32 + Prevent FIJI failing to decode at exactly 180 degrees; prevent invalid filtering near the territory bounding rectangle. * April 2014 - * 1.31 - + * 1.31 + Make iso2ccode() even more forgiving by allowing a state alias to be recognized in context. - * 1.3 - + * 1.3 + Disable 7-char state codes for large states in India, and instead generate country mapcodes for states. - * 1.28 - + * 1.28 + Fix for starpipe "zoning" error, causing the last 2 mapcode characters to be ignored in certain areas. - * 1.27 - + * 1.27 + Support undefined ranges in data array (useful for partial JavaScript builds). * May 2013 - * 1.26 - + * 1.26 + Added alias OD for India, and 2.3 code for Daman and Diu. - * 1.25 - + * 1.25 + Ccode2iso(c,2) support added. - * 1.24 - + * 1.24 + Public domain release. diff --git a/ctrynams.js b/ctrynams.js index b2a1862..229fdbb 100644 --- a/ctrynams.js +++ b/ctrynams.js @@ -15,138 +15,138 @@ */ var isofullname = [ - 'Vatican City (Holy See)', 'Monaco', 'Gibraltar', 'Tokelau', - 'Cocos Islands (Keeling Islands)', 'Saint-Barthelemy', 'Nauru', 'Tuvalu', - 'Macau (Aomen)', 'Sint Maarten', 'Saint-Martin', 'Norfolk and Philip Island (Philip Island)', - 'Pitcairn Islands', 'Bouvet Island', 'Bermuda', 'British Indian Ocean Territory', - 'San Marino', 'Guernsey', 'Anguilla', 'Montserrat', - 'Jersey', 'Christmas Island', 'Wallis and Futuna (Futuna)', 'British Virgin Islands (Virgin Islands, British)', - 'Liechtenstein', 'Aruba', 'Marshall Islands', 'American Samoa (Samoa, American)', - 'Cook Islands', 'Saint Pierre and Miquelon (Miquelon)', 'Niue', 'Saint Kitts and Nevis (Nevis)', - 'Cayman islands', 'Bonaire, St Eustasuis and Saba (Saba) (St Eustasius)', 'Maldives', 'Saint Helena, Ascension and Tristan da Cunha (Ascension) (Tristan da Cunha)', - 'Malta', 'Grenada', 'US Virgin Islands (Virgin Islands, US)', 'Mayotte', - 'Svalbard and Jan Mayen (Jan Mayen) (Spitsbergen)', 'Saint Vincent and the Grenadines (Grenadines)', 'Heard Island and McDonald Islands (McDonald Islands)', 'Barbados', - 'Antigua and Barbuda (Barbuda)', 'Curacao', 'Seychelles', 'Palau', - 'Northern Mariana Islands', 'Andorra', 'Guam', 'Isle of Man', - 'Saint Lucia', 'Micronesia (Federated States of Micronesia)', 'Singapore', 'Tonga', - 'Dominica', 'Bahrain', 'Kiribati', 'Turks and Caicos Islands (Caicos Islands)', - 'Sao Tome and Principe (Principe)', 'Hong Kong (Xianggang)', 'Martinique', 'Faroe Islands', - 'Guadeloupe', 'Comoros', 'Mauritius', 'Reunion', - 'Luxembourg', 'Samoa', 'South Georgia and the South Sandwich Islands (South Sandwich Islands)', 'French Polynesia', - 'Cape Verde', 'Trinidad and Tobago (Tobago)', 'Brunei', 'French Southern and Antarctic Lands', - 'Puerto Rico', 'Cyprus', 'Lebanon', 'Jamaica', - 'Gambia (The Gambia)', 'Qatar', 'Falkland Islands', 'Vanuatu', - 'Montenegro', 'Bahamas', 'East Timor', 'Swaziland', - 'Kuwait', 'Fiji', 'New Caledonia', 'Slovenia', - 'Israel', 'Palestinian territories', 'El Salvador', 'Belize', - 'Djibouti', 'Macedonia', 'Rwanda', 'Haiti', - 'Burundi', 'Equatorial Guinea', 'Albania', 'Solomon Islands', - 'Armenia', 'Lesotho', 'Belgium', 'Moldova', - 'Guinea-Bissau', 'Taiwan', 'Bhutan', 'Switzerland', - 'Netherlands', 'Denmark', 'Estonia', 'Dominican Republic', - 'Slovakia', 'Costa Rica', 'Bosnia and Herzegovina', 'Croatia', - 'Togo', 'Latvia', 'Lithuania', 'Sri Lanka', - 'Georgia', 'Ireland', 'Sierra Leone', 'Panama', - 'Czech Republic', 'French Guiana', 'United Arab Emirates', 'Austria', - 'Azerbaijan', 'Serbia', 'Jordan', 'Portugal', - 'Hungary', 'South Korea', 'Iceland', 'Guatemala', - 'Cuba', 'Bulgaria', 'Liberia', 'Honduras', - 'Benin', 'Eritrea', 'Malawi', 'North Korea', - 'Nicaragua', 'Greece', 'Tajikistan', 'Bangladesh', - 'Nepal', 'Tunisia', 'Suriname', 'Uruguay', - 'Cambodia', 'Syria', 'Senegal', 'Kyrgyzstan', - 'Belarus', 'Guyana', 'Laos', 'Romania', - 'Ghana', 'Uganda', 'United Kingdom (Scotland) (Great Britain) (Northern Ireland) (Ireland, Northern)', 'Guinea', - 'Ecuador', 'Western Sahara (Sahrawi)', 'Gabon', 'New Zealand', - 'Burkina Faso', 'Philippines', 'Italy', 'Oman', - 'Poland', 'Ivory Coast', 'Norway', 'Malaysia', - 'Vietnam', 'Finland', 'Congo-Brazzaville', 'Germany', - 'Japan', 'Zimbabwe', 'Paraguay', 'Iraq', - 'Morocco', 'Uzbekistan', 'Sweden', 'Papua New Guinea', - 'Cameroon', 'Turkmenistan', 'Spain', 'Thailand', - 'Yemen', 'France', 'Aaland Islands', 'Kenya', - 'Botswana', 'Madagascar', 'Ukraine', 'South Sudan', - 'Central African Republic', 'Somalia', 'Afghanistan', 'Myanmar (Burma)', - 'Zambia', 'Chile', 'Turkey', 'Pakistan', - 'Mozambique', 'Namibia', 'Venezuela', 'Nigeria', - 'Tanzania', 'Egypt', 'Mauritania', 'Bolivia', - 'Ethiopia', 'Colombia', 'South Africa', 'Mali', - 'Angola', 'Niger', 'Chad', 'Peru', - 'Mongolia', 'Iran', 'Libya', 'Sudan', - 'Indonesia', 'Federal District', 'Tlaxcala', 'Morelos', - 'Aguascalientes', 'Colima', 'Queretaro', 'Hidalgo', - 'Mexico State', 'Tabasco', 'Nayarit', 'Guanajuato', - 'Puebla', 'Yucatan', 'Quintana Roo', 'Sinaloa', - 'Campeche', 'Michoacan', 'San Luis Potosi', 'Guerrero', - 'Nuevo Leon', 'Baja California', 'Veracruz', 'Chiapas', - 'Baja California Sur', 'Zacatecas', 'Jalisco', 'Tamaulipas', - 'Oaxaca', 'Durango', 'Coahuila', 'Sonora', - 'Chihuahua', 'Greenland', 'Saudi Arabia', 'Congo-Kinshasa', - 'Algeria', 'Kazakhstan', 'Argentina', 'Daman and Diu', - 'Dadra and Nagar Haveli', 'Chandigarh', 'Andaman and Nicobar', 'Lakshadweep', - 'Delhi', 'Meghalaya', 'Nagaland', 'Manipur', - 'Tripura', 'Mizoram', 'Sikkim', 'Punjab', - 'Haryana', 'Arunachal Pradesh', 'Assam', 'Bihar', - 'Uttarakhand', 'Goa', 'Kerala', 'Tamil Nadu', - 'Himachal Pradesh', 'Jammu and Kashmir', 'Chhattisgarh', 'Jharkhand', - 'Karnataka', 'Rajasthan', 'Odisha (Orissa)', 'Gujarat', - 'West Bengal', 'Madhya Pradesh', 'Telangana', 'Andhra Pradesh', - 'Maharashtra', 'Uttar Pradesh', 'Puducherry', 'New South Wales', - 'Australian Capital Territory', 'Jervis Bay Territory', 'Northern Territory', 'South Australia', - 'Tasmania', 'Victoria', 'Western Australia', 'Queensland', - 'Distrito Federal', 'Sergipe', 'Alagoas', 'Rio de Janeiro', - 'Espirito Santo', 'Rio Grande do Norte', 'Paraiba', 'Santa Catarina', - 'Pernambuco', 'Amapa', 'Ceara', 'Acre', - 'Parana', 'Roraima', 'Rondonia', 'Sao Paulo', - 'Piaui', 'Tocantins', 'Rio Grande do Sul', 'Maranhao', - 'Goias', 'Mato Grosso do Sul', 'Bahia', 'Minas Gerais', - 'Mato Grosso', 'Para', 'Amazonas', 'District of Columbia', - 'Rhode Island', 'Delaware', 'Connecticut', 'New Jersey', - 'New Hampshire', 'Vermont', 'Massachusetts', 'Hawaii', - 'Maryland', 'West Virginia', 'South Carolina', 'Maine', - 'Indiana', 'Kentucky', 'Tennessee', 'Virginia', - 'Ohio', 'Pennsylvania', 'Mississippi', 'Louisiana', - 'Alabama', 'Arkansas', 'North Carolina', 'New York', - 'Iowa', 'Illinois', 'Georgia', 'Wisconsin', - 'Florida', 'Missouri', 'Oklahoma', 'North Dakota', - 'Washington', 'South Dakota', 'Nebraska', 'Kansas', - 'Idaho', 'Utah', 'Minnesota', 'Michigan', - 'Wyoming', 'Oregon', 'Colorado', 'Nevada', - 'Arizona', 'New Mexico', 'Montana', 'California', - 'Texas', 'Alaska', 'British Columbia', 'Alberta', - 'Ontario', 'Quebec', 'Saskatchewan', 'Manitoba', - 'Newfoundland and Labrador (Labrador)', 'New Brunswick', 'Nova Scotia', 'Prince Edward Island', - 'Yukon', 'Northwest Territories', 'Nunavut', 'India', - 'Australia', 'Brazil', 'USA (United States of America) (America)', 'Mexico', - 'Moscow', 'Saint Petersburg', 'Kaliningrad Oblast', 'Ingushetia Republic', - 'Adygea Republic', 'North Ossetia-Alania Republic', 'Kabardino-Balkar Republic', 'Karachay-Cherkess Republic', - 'Chechen Republic', 'Chuvash Republic', 'Ivanovo Oblast', 'Lipetsk Oblast', - 'Oryol Oblast', 'Tula Oblast', 'Belgorod Oblast', 'Vladimir Oblast', - 'Kursk Oblast', 'Kaluga Oblast', 'Tambov Oblast', 'Bryansk Oblast', - 'Yaroslavl Oblast', 'Ryazan Oblast', 'Astrakhan Oblast', 'Moscow Oblast', - 'Smolensk Oblast', 'Dagestan Republic', 'Voronezh Oblast', 'Novgorod Oblast', - 'Pskov Oblast', 'Kostroma Oblast', 'Stavropol Krai', 'Krasnodar Krai', - 'Kalmykia Republic', 'Tver Oblast', 'Leningrad Oblast', 'Rostov Oblast', - 'Volgograd Oblast', 'Vologda Oblast', 'Murmansk Oblast', 'Karelia Republic', - 'Nenets Autonomous Okrug', 'Komi Republic', 'Arkhangelsk Oblast', 'Mordovia Republic', - 'Nizhny Novgorod Oblast', 'Penza Oblast', 'Kirov Oblast', 'Mari El Republic', - 'Orenburg Oblast', 'Ulyanovsk Oblast', 'Perm Krai', 'Bashkortostan Republic', - 'Udmurt Republic', 'Tatarstan Republic', 'Samara Oblast', 'Saratov Oblast', - 'Yamalo-Nenets', 'Khanty-Mansi', 'Sverdlovsk Oblast', 'Tyumen Oblast', - 'Kurgan Oblast', 'Chelyabinsk Oblast', 'Buryatia Republic', 'Zabaykalsky Krai', - 'Irkutsk Oblast', 'Novosibirsk Oblast', 'Tomsk Oblast', 'Omsk Oblast', - 'Khakassia Republic', 'Kemerovo Oblast', 'Altai Republic', 'Altai Krai', - 'Tuva Republic', 'Krasnoyarsk Krai', 'Magadan Oblast', 'Chukotka Okrug', - 'Kamchatka Krai', 'Sakhalin Oblast', 'Primorsky Krai', 'Jewish Autonomous Oblast', - 'Khabarovsk Krai', 'Amur Oblast', 'Sakha Republic (Yakutia Republic)', 'Canada', - 'Russia', 'Shanghai', 'Tianjin', 'Beijing', - 'Hainan', 'Ningxia Hui', 'Chongqing', 'Zhejiang', - 'Jiangsu', 'Fujian', 'Anhui', 'Liaoning', - 'Shandong', 'Shanxi', 'Jiangxi', 'Henan', - 'Guizhou', 'Guangdong', 'Hubei', 'Jilin', - 'Hebei', 'Shaanxi', 'Nei Mongol (Inner Mongolia)', 'Heilongjiang', - 'Hunan', 'Guangxi Zhuang', 'Sichuan', 'Yunnan', - 'Xizang (Tibet)', 'Gansu', 'Qinghai', 'Xinjiang Uyghur', - 'China', 'United States Minor Outlying Islands', 'Clipperton Island', 'Antarctica', - 'International (Worldwide) (Earth)', '?']; + "Vatican City State (Holy See)", "Monaco (Principality of _)", "Gibraltar", "Tokelau", + "Cocos Islands (Keeling Islands)", "Saint-Barthelemy (Collectivity of _)", "Nauru (Republic of _)", "Tuvalu", + "Macau (Aomen)", "Sint Maarten", "Saint Martin (Collectivity of _)", "Norfolk and Philip Island (Philip Island)", + "Pitcairn Group of Islands", "Bouvet Island", "Bermuda (Somers Isles)", "British Indian Ocean Territory", + "San Marino (Republic of _)", "Guernsey (Bailiwick of _)", "Anguilla", "Montserrat", + "Jersey (Bailiwick of _)", "Christmas Island", "Wallis and Futuna (Futuna) (Collectivity of the _ Islands)", "British Virgin Islands (Virgin Islands, British)", + "Liechtenstein (Principality of _)", "Aruba", "Marshall Islands (Republic of the _)", "American Samoa (Samoa, American)", + "Cook Islands", "Saint Pierre and Miquelon (Miquelon) (Collectivity of _)", "Niue", "Saint Kitts and Nevis (Nevis) (Federation of _)", + "Cayman islands", "Bonaire, St Eustasuis and Saba (Saba) (St Eustasius)", "Maldives (Republic of _)", "Saint Helena, Ascension and Tristan da Cunha (Ascension) (Tristan da Cunha)", + "Malta (Republic of _)", "Grenada", "Virgin Islands of the United States (US Virgin Islands) (American Virgin Islands)", "Mayotte (Maore)", + "Svalbard and Jan Mayen (Jan Mayen) (Spitsbergen)", "Saint Vincent and the Grenadines (Grenadines)", "Heard Island and McDonald Islands (McDonald Islands)", "Barbados", + "Antigua and Barbuda (Barbuda)", "Curacao", "Seychelles (Republic of _)", "Palau (Republic of _)", + "Northern Mariana Islands (Commonwealth of the _)", "Andorra (Principality of _) (Principality of the Valleys of _)", "Guam", "Isle of Mann (Mann)", + "Saint Lucia", "Micronesia (Federated States of Micronesia)", "Singapore (Republic of _)", "Tonga (Kingdom of _)", + "Dominica (Commonwealth of _)", "Bahrain (Kingdom of _)", "Kiribati (Republic of _)", "Turks and Caicos Islands (Caicos Islands)", + "Sao Tome and Principe (Principe) (Democratic Republic of _)", "Hong Kong (Xianggang)", "Martinique", "Faroe Islands", + "Guadeloupe", "Comoros (Union of the _)", "Mauritius (Republic of _)", "Reunion", + "Luxembourg (Grand Duchy of _)", "Samoa (Independent State of _)", "South Georgia and the South Sandwich Islands (South Sandwich Islands)", "French Polynesia (Collectivity of _)", + "Cape Verde (Cabo Verde) (Republic of Cabo Verde)", "Trinidad and Tobago (Republic of _) (Tobago)", "Brunei (Nation of _, the Abode of Peace)", "French Southern and Antarctic Lands", + "Puerto Rico (Commonwealth of _)", "Cyprus (Republic of _)", "Lebanon (Lebanese Republic)", "Jamaica", + "Gambia (The Gambia) (Republic of the _)", "Qatar (State of _)", "Falkland Islands", "Vanuatu (Republic of _)", + "Montenegro", "Bahamas (Commonwealth of the _)", "Timor-Leste (Democratic Republic of _) (East Timor)", "Swaziland (Kingdom of _)", + "Kuwait (State of _)", "Fiji (Republic of _)", "New Caledonia", "Slovenia (Republic of _)", + "Israel (State of _)", "Palestinian territories (State of Palestine)", "El Salvador (Republic of _)", "Belize", + "Djibouti (Republic of _)", "Macedonia (Republic of _) (FYROM) (Former Yugoslav Republic of Macedonia)", "Rwanda (Republic of _)", "Haiti (Republic of _)", + "Burundi (Republic of _)", "Equatorial Guinea (Republic of _)", "Albania (Republic of _)", "Solomon Islands", + "Armenia (Republic of _)", "Lesotho (Kingdom of _)", "Belgium (Kingdom of _)", "Moldova (Republic of _)", + "Guinea-Bissau (Republic of _)", "Taiwan (Republic of China)", "Bhutan (Kingdom of _)", "Switzerland (Swiss Confederation)", + "Netherlands (The Netherlands) (Kingdom of the _)", "Denmark (Kingdom of _)", "Estonia (Republic of _)", "Dominican Republic", + "Slovakia (Slovak Republic)", "Costa Rica (Republic of _)", "Bosnia and Herzegovina", "Croatia (Republic of _)", + "Togo (Togolese Republic)", "Latvia (Republic of _)", "Lithuania (Republic of _)", "Sri Lanka (Democratic Socialist Republic of _)", + "Georgia", "Ireland (Republic of _)", "Sierra Leone (Republic of _)", "Panama (Republic of _)", + "Czech Republic", "French Guiana (Guiana)", "United Arab Emirates (Emirates)", "Austria (Republic of _)", + "Azerbaijan (Republic of _)", "Serbia (Republic of _)", "Jordan (Hashemite Kingdom of _) (Kingdom of _)", "Portugal (Portuguese Republic)", + "Hungary (Republic of _)", "South Korea (Republic of Korea)", "Iceland", "Guatemala (Republic of _)", + "Cuba (Republic of _)", "Bulgaria (Republic of _)", "Liberia (Republic of _)", "Honduras (Republic of _)", + "Benin (Republic of _)", "Eritrea (State of _)", "Malawi (Republic of _)", "North Korea (Democratic People's Republic of Korea)", + "Nicaragua (Republic of _)", "Greece (Hellenic Republic)", "Tajikistan (Republic of _)", "Bangladesh (People's Republic of _)", + "Nepal (Federal Democratic Republic of _)", "Tunisia (Tunisian Republic) (Republic of _)", "Suriname (Republic of _)", "Uruguay (Eastern Republic of _)", + "Cambodia (Kingdom of _)", "Syria (Syrian Arab Republic)", "Senegal (Republic of _)", "Kyrgyzstan (Kyrgyz Republic)", + "Belarus (Republic of _)", "Guyana (Co-operative Republic of _)", "Laos (Lao People's Democratic Republic)", "Romania", + "Ghana (Republic of _)", "Uganda (Republic of _)", "United Kingdom (Scotland) (Great Britain) (Northern Ireland) (Ireland, Northern) (Britain) (United Kingdom of Great Britain and Northern Ireland)", "Guinea (Republic of _) (Guinea-Conakry)", + "Ecuador (Republic of _)", "Western Sahara (Sahrawi Arab Democratic Republic)", "Gabon (Gabonese Republic)", "New Zealand", + "Burkina Faso", "Philippines (Republic of the _)", "Italy (Italian Republic)", "Oman (Sultanate of _)", + "Poland (Republic of _)", "Ivory Coast (Cote d'Ivoire) (Republic of Cote d'Ivoire)", "Norway (Kingdom of _)", "Malaysia", + "Vietnam (Socialist Republic of _)", "Finland (Republic of _)", "Congo-Brazzaville (West Congo) (Republic of the Congo)", "Germany (Federal Republic of _)", + "Japan", "Zimbabwe (Republic of _)", "Paraguay (Republic of _)", "Iraq (Republic of _)", + "Morocco (Kingdom of _)", "Uzbekistan (Republic of _)", "Sweden (Kingdom of _)", "Papua New Guinea (Independent State of _)", + "Cameroon (Republic of _)", "Turkmenistan", "Spain (Kingdom of _)", "Thailand (Kingdom of _)", + "Yemen (Republic of _)", "France (French Republic)", "Aaland Islands", "Kenya (Republic of _)", + "Botswana (Republic of _)", "Madagascar (Republic of _)", "Ukraine", "South Sudan (Republic of _)", + "Central African Republic", "Somalia (Federal Republic of _)", "Afghanistan (Islamic Republic of _)", "Myanmar (Republic of the Union of _) (Burma)", + "Zambia (Republic of _)", "Chile (Republic of _)", "Turkey (Republic of _)", "Pakistan (Islamic Republic of _)", + "Mozambique (Republic of _)", "Namibia (Republic of _)", "Venezuela (Bolivarian Republic of _)", "Nigeria (Federal Republic of _)", + "Tanzania (United Republic of _)", "Egypt (Arab Republic of _)", "Mauritania (Islamic Republic of _)", "Bolivia (Plurinational State of _)", + "Ethiopia (Federal Democratic Republic of _)", "Colombia (Republic of _)", "South Africa (Republic of _)", "Mali (Republic of _)", + "Angola (Republic of _)", "Niger (Republic of _)", "Chad (Republic of _)", "Peru (Republic of _)", + "Mongolia", "Iran (Persia) (Islamic Republic of _)", "Libya", "Sudan (Republic of the _)", + "Indonesia (Republic of _)", "Federal District", "Tlaxcala", "Morelos", + "Aguascalientes", "Colima", "Queretaro", "Hidalgo", + "Mexico State", "Tabasco", "Nayarit", "Guanajuato", + "Puebla", "Yucatan", "Quintana Roo", "Sinaloa", + "Campeche", "Michoacan", "San Luis Potosi", "Guerrero", + "Nuevo Leon (New Leon)", "Baja California", "Veracruz", "Chiapas", + "Baja California Sur", "Zacatecas", "Jalisco", "Tamaulipas", + "Oaxaca", "Durango", "Coahuila", "Sonora", + "Chihuahua", "Greenland", "Saudi Arabia (Kingdom of _)", "Congo-Kinshasa (Democratic Republic of the Congo) (East Congo)", + "Algeria (People's Democratic Republic of _)", "Kazakhstan (Republic of _)", "Argentina (Argentine Republic)", "Daman and Diu", + "Dadra and Nagar Haveli", "Chandigarh", "Andaman and Nicobar", "Lakshadweep", + "Delhi (National Capital Territory of _)", "Meghalaya", "Nagaland", "Manipur", + "Tripura", "Mizoram", "Sikkim", "Punjab", + "Haryana", "Arunachal Pradesh", "Assam", "Bihar", + "Uttarakhand", "Goa", "Kerala", "Tamil Nadu", + "Himachal Pradesh", "Jammu and Kashmir", "Chhattisgarh", "Jharkhand", + "Karnataka", "Rajasthan", "Odisha (Orissa)", "Gujarat", + "West Bengal", "Madhya Pradesh", "Telangana", "Andhra Pradesh", + "Maharashtra", "Uttar Pradesh", "Puducherry", "New South Wales", + "Australian Capital Territory", "Jervis Bay Territory", "Northern Territory", "South Australia", + "Tasmania", "Victoria", "Western Australia", "Queensland", + "Distrito Federal", "Sergipe", "Alagoas", "Rio de Janeiro", + "Espirito Santo", "Rio Grande do Norte", "Paraiba", "Santa Catarina", + "Pernambuco", "Amapa", "Ceara", "Acre", + "Parana", "Roraima", "Rondonia", "Sao Paulo", + "Piaui", "Tocantins", "Rio Grande do Sul", "Maranhao", + "Goias", "Mato Grosso do Sul", "Bahia", "Minas Gerais", + "Mato Grosso", "Para", "Amazonas", "District of Columbia (Washington, D.C.)", + "Rhode Island", "Delaware", "Connecticut", "New Jersey", + "New Hampshire", "Vermont", "Massachusetts (Commonwealth of _)", "Hawaii", + "Maryland", "West Virginia", "South Carolina", "Maine", + "Indiana", "Kentucky (Commonwealth of _)", "Tennessee", "Virginia (Commonwealth of _)", + "Ohio", "Pennsylvania (Commonwealth of _)", "Mississippi", "Louisiana", + "Alabama", "Arkansas", "North Carolina", "New York", + "Iowa", "Illinois", "Georgia", "Wisconsin", + "Florida", "Missouri", "Oklahoma", "North Dakota", + "Washington", "South Dakota", "Nebraska", "Kansas", + "Idaho", "Utah", "Minnesota", "Michigan", + "Wyoming", "Oregon", "Colorado", "Nevada", + "Arizona", "New Mexico", "Montana", "California", + "Texas", "Alaska", "British Columbia", "Alberta", + "Ontario", "Quebec", "Saskatchewan", "Manitoba", + "Newfoundland and Labrador (Labrador)", "New Brunswick", "Nova Scotia", "Prince Edward Island", + "Yukon", "Northwest Territories", "Nunavut", "India (Republic of _)", + "Australia (Commonwealth of _)", "Brazil (Federative Republic of _)", "USA (United States of America) (America)", "Mexico (United Mexican States)", + "Moscow", "Saint Petersburg", "Kaliningrad Oblast", "Ingushetia", + "Adygea Republic", "North Ossetia-Alania Republic", "Kabardino-Balkar Republic", "Karachay-Cherkess Republic", + "Chechen Republic (Chechnya) (Ichkeria)", "Chuvash Republic", "Ivanovo Oblast", "Lipetsk Oblast", + "Oryol Oblast", "Tula Oblast", "Belgorod Oblast", "Vladimir Oblast", + "Kursk Oblast", "Kaluga Oblast", "Tambov Oblast", "Bryansk Oblast", + "Yaroslavl Oblast", "Ryazan Oblast", "Astrakhan Oblast", "Moscow Oblast", + "Smolensk Oblast", "Dagestan Republic", "Voronezh Oblast", "Novgorod Oblast", + "Pskov Oblast", "Kostroma Oblast", "Stavropol Krai", "Krasnodar Krai", + "Kalmykia Republic", "Tver Oblast", "Leningrad Oblast", "Rostov Oblast", + "Volgograd Oblast", "Vologda Oblast", "Murmansk Oblast", "Karelia Republic", + "Nenets Autonomous Okrug", "Komi Republic", "Arkhangelsk Oblast", "Mordovia Republic", + "Nizhny Novgorod Oblast", "Penza Oblast", "Kirov Oblast", "Mari El Republic", + "Orenburg Oblast", "Ulyanovsk Oblast", "Perm Krai", "Bashkortostan Republic", + "Udmurt Republic", "Tatarstan Republic", "Samara Oblast", "Saratov Oblast", + "Yamalo-Nenets", "Khanty-Mansi", "Sverdlovsk Oblast", "Tyumen Oblast", + "Kurgan Oblast", "Chelyabinsk Oblast", "Buryatia Republic", "Zabaykalsky Krai", + "Irkutsk Oblast", "Novosibirsk Oblast", "Tomsk Oblast", "Omsk Oblast", + "Khakassia Republic", "Kemerovo Oblast", "Altai Republic", "Altai Krai", + "Tuva Republic", "Krasnoyarsk Krai", "Magadan Oblast", "Chukotka Okrug", + "Kamchatka Krai", "Sakhalin Oblast", "Primorsky Krai", "Jewish Autonomous Oblast", + "Khabarovsk Krai", "Amur Oblast", "Sakha Republic (Yakutia Republic)", "Canada", + "Russia (Russian Federation)", "Shanghai Municipality", "Tianjin Municipality", "Beijing Municipality", + "Hainan Province", "Ningxia Hui Autonomous Region", "Chongqing Municipality", "Zhejiang Province", + "Jiangsu Province", "Fujian Province", "Anhui Province", "Liaoning Province", + "Shandong Province", "Shanxi Province", "Jiangxi Province", "Henan Province", + "Guizhou Province", "Guangdong Province", "Hubei Province", "Jilin Province", + "Hebei Province (Yanzhao Province)", "Shaanxi Province", "Nei Mongol Autonomous Region (Inner Mongolia)", "Heilongjiang Province", + "Hunan Province", "Guangxi Zhuang Autonomous Region", "Sichuan Province", "Yunnan Province", + "Xizang Autonomous Region (Tibet)", "Gansu Province", "Qinghai Province (Tsinghai Province)", "Xinjiang Uyghur Autonomous Region", + "China (People's Republic of _)", "United States Minor Outlying Islands", "Clipperton Island", "Antarctica", + "International (Worldwide) (Earth)", "?"]; diff --git a/ctrynams_short.js b/ctrynams_short.js new file mode 100644 index 0000000..e92a7fd --- /dev/null +++ b/ctrynams_short.js @@ -0,0 +1,551 @@ +/* + * Copyright (C) 2014-2015 Stichting Mapcode Foundation (http://www.mapcode.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var isofullname = [ + "Vatican City State (Holy See)", + "Monaco", + "Gibraltar", + "Tokelau", + "Cocos Islands (Keeling Islands)", + "Saint-Barthelemy", + "Nauru", + "Tuvalu", + "Macau (Aomen)", + "Sint Maarten", + "Saint Martin", + "Norfolk and Philip Island (Philip Island)", + "Pitcairn Group of Islands", + "Bouvet Island", + "Bermuda (Somers Isles)", + "British Indian Ocean Territory", + "San Marino", + "Guernsey", + "Anguilla", + "Montserrat", + "Jersey", + "Christmas Island", + "Wallis and Futuna (Futuna)", + "British Virgin Islands (Virgin Islands, British)", + "Liechtenstein", + "Aruba", + "Marshall Islands", + "American Samoa (Samoa, American)", + "Cook Islands", + "Saint Pierre and Miquelon (Miquelon)", + "Niue", + "Saint Kitts and Nevis (Nevis)", + "Cayman islands", + "Bonaire, St Eustasuis and Saba (Saba) (St Eustasius)", + "Maldives", + "Saint Helena, Ascension and Tristan da Cunha (Ascension) (Tristan da Cunha)", + "Malta", + "Grenada", + "Virgin Islands of the United States (US Virgin Islands) (American Virgin Islands)", + "Mayotte (Maore)", + "Svalbard and Jan Mayen (Jan Mayen) (Spitsbergen)", + "Saint Vincent and the Grenadines (Grenadines)", + "Heard Island and McDonald Islands (McDonald Islands)", + "Barbados", + "Antigua and Barbuda (Barbuda)", + "Curacao", + "Seychelles", + "Palau", + "Northern Mariana Islands", + "Andorra", + "Guam", + "Isle of Mann (Mann)", + "Saint Lucia", + "Micronesia (Federated States of Micronesia)", + "Singapore", + "Tonga", + "Dominica", + "Bahrain", + "Kiribati", + "Turks and Caicos Islands (Caicos Islands)", + "Sao Tome and Principe (Principe)", + "Hong Kong (Xianggang)", + "Martinique", + "Faroe Islands", + "Guadeloupe", + "Comoros", + "Mauritius", + "Reunion", + "Luxembourg", + "Samoa", + "South Georgia and the South Sandwich Islands (South Sandwich Islands)", + "French Polynesia", + "Cape Verde (Cabo Verde) (Republic of Cabo Verde)", + "Trinidad and Tobago (Tobago)", + "Brunei", + "French Southern and Antarctic Lands", + "Puerto Rico", + "Cyprus", + "Lebanon (Lebanese Republic)", + "Jamaica", + "Gambia (The Gambia)", + "Qatar", + "Falkland Islands", + "Vanuatu", + "Montenegro", + "Bahamas", + "Timor-Leste (East Timor)", + "Swaziland", + "Kuwait", + "Fiji", + "New Caledonia", + "Slovenia", + "Israel", + "Palestinian territories (State of Palestine)", + "El Salvador", + "Belize", + "Djibouti", + "Macedonia (FYROM) (Former Yugoslav Republic of Macedonia)", + "Rwanda", + "Haiti", + "Burundi", + "Equatorial Guinea", + "Albania", + "Solomon Islands", + "Armenia", + "Lesotho", + "Belgium", + "Moldova", + "Guinea-Bissau", + "Taiwan (Republic of China)", + "Bhutan", + "Switzerland (Swiss Confederation)", + "Netherlands (The Netherlands)", + "Denmark", + "Estonia", + "Dominican Republic", + "Slovakia (Slovak Republic)", + "Costa Rica", + "Bosnia and Herzegovina", + "Croatia", + "Togo (Togolese Republic)", + "Latvia", + "Lithuania", + "Sri Lanka", + "Georgia", + "Ireland", + "Sierra Leone", + "Panama", + "Czech Republic", + "French Guiana (Guiana)", + "United Arab Emirates (Emirates)", + "Austria", + "Azerbaijan", + "Serbia", + "Jordan", + "Portugal (Portuguese Republic)", + "Hungary", + "South Korea (Republic of Korea)", + "Iceland", + "Guatemala", + "Cuba", + "Bulgaria", + "Liberia", + "Honduras", + "Benin", + "Eritrea", + "Malawi", + "North Korea (Democratic People's Republic of Korea)", + "Nicaragua", + "Greece (Hellenic Republic)", + "Tajikistan", + "Bangladesh", + "Nepal", + "Tunisia (Tunisian Republic)", + "Suriname", + "Uruguay", + "Cambodia", + "Syria (Syrian Arab Republic)", + "Senegal", + "Kyrgyzstan (Kyrgyz Republic)", + "Belarus", + "Guyana", + "Laos (Lao People's Democratic Republic)", + "Romania", + "Ghana", + "Uganda", + "United Kingdom (Scotland) (Great Britain) (Northern Ireland) (Ireland, Northern) (Britain) (United Kingdom of Great Britain and Northern Ireland)", + "Guinea (Guinea-Conakry)", + "Ecuador", + "Western Sahara (Sahrawi Arab Democratic Republic)", + "Gabon (Gabonese Republic)", + "New Zealand", + "Burkina Faso", + "Philippines", + "Italy (Italian Republic)", + "Oman", + "Poland", + "Ivory Coast (Cote d'Ivoire) (Republic of Cote d'Ivoire)", + "Norway", + "Malaysia", + "Vietnam", + "Finland", + "Congo-Brazzaville (West Congo) (Republic of the Congo)", + "Germany", + "Japan", + "Zimbabwe", + "Paraguay", + "Iraq", + "Morocco", + "Uzbekistan", + "Sweden", + "Papua New Guinea", + "Cameroon", + "Turkmenistan", + "Spain", + "Thailand", + "Yemen", + "France (French Republic)", + "Aaland Islands", + "Kenya", + "Botswana", + "Madagascar", + "Ukraine", + "South Sudan", + "Central African Republic", + "Somalia", + "Afghanistan", + "Myanmar (Burma)", + "Zambia", + "Chile", + "Turkey", + "Pakistan", + "Mozambique", + "Namibia", + "Venezuela", + "Nigeria", + "Tanzania", + "Egypt", + "Mauritania", + "Bolivia", + "Ethiopia", + "Colombia", + "South Africa", + "Mali", + "Angola", + "Niger", + "Chad", + "Peru", + "Mongolia", + "Iran (Persia)", + "Libya", + "Sudan", + "Indonesia", + "Federal District", + "Tlaxcala", + "Morelos", + "Aguascalientes", + "Colima", + "Queretaro", + "Hidalgo", + "Mexico State", + "Tabasco", + "Nayarit", + "Guanajuato", + "Puebla", + "Yucatan", + "Quintana Roo", + "Sinaloa", + "Campeche", + "Michoacan", + "San Luis Potosi", + "Guerrero", + "Nuevo Leon (New Leon)", + "Baja California", + "Veracruz", + "Chiapas", + "Baja California Sur", + "Zacatecas", + "Jalisco", + "Tamaulipas", + "Oaxaca", + "Durango", + "Coahuila", + "Sonora", + "Chihuahua", + "Greenland", + "Saudi Arabia", + "Congo-Kinshasa (Democratic Republic of the Congo) (East Congo)", + "Algeria", + "Kazakhstan", + "Argentina (Argentine Republic)", + "Daman and Diu", + "Dadra and Nagar Haveli", + "Chandigarh", + "Andaman and Nicobar", + "Lakshadweep", + "Delhi", + "Meghalaya", + "Nagaland", + "Manipur", + "Tripura", + "Mizoram", + "Sikkim", + "Punjab", + "Haryana", + "Arunachal Pradesh", + "Assam", + "Bihar", + "Uttarakhand", + "Goa", + "Kerala", + "Tamil Nadu", + "Himachal Pradesh", + "Jammu and Kashmir", + "Chhattisgarh", + "Jharkhand", + "Karnataka", + "Rajasthan", + "Odisha (Orissa)", + "Gujarat", + "West Bengal", + "Madhya Pradesh", + "Telangana", + "Andhra Pradesh", + "Maharashtra", + "Uttar Pradesh", + "Puducherry", + "New South Wales", + "Australian Capital Territory", + "Jervis Bay Territory", + "Northern Territory", + "South Australia", + "Tasmania", + "Victoria", + "Western Australia", + "Queensland", + "Distrito Federal", + "Sergipe", + "Alagoas", + "Rio de Janeiro", + "Espirito Santo", + "Rio Grande do Norte", + "Paraiba", + "Santa Catarina", + "Pernambuco", + "Amapa", + "Ceara", + "Acre", + "Parana", + "Roraima", + "Rondonia", + "Sao Paulo", + "Piaui", + "Tocantins", + "Rio Grande do Sul", + "Maranhao", + "Goias", + "Mato Grosso do Sul", + "Bahia", + "Minas Gerais", + "Mato Grosso", + "Para", + "Amazonas", + "District of Columbia (Washington, D.C.)", + "Rhode Island", + "Delaware", + "Connecticut", + "New Jersey", + "New Hampshire", + "Vermont", + "Massachusetts", + "Hawaii", + "Maryland", + "West Virginia", + "South Carolina", + "Maine", + "Indiana", + "Kentucky", + "Tennessee", + "Virginia", + "Ohio", + "Pennsylvania", + "Mississippi", + "Louisiana", + "Alabama", + "Arkansas", + "North Carolina", + "New York", + "Iowa", + "Illinois", + "Georgia", + "Wisconsin", + "Florida", + "Missouri", + "Oklahoma", + "North Dakota", + "Washington", + "South Dakota", + "Nebraska", + "Kansas", + "Idaho", + "Utah", + "Minnesota", + "Michigan", + "Wyoming", + "Oregon", + "Colorado", + "Nevada", + "Arizona", + "New Mexico", + "Montana", + "California", + "Texas", + "Alaska", + "British Columbia", + "Alberta", + "Ontario", + "Quebec", + "Saskatchewan", + "Manitoba", + "Newfoundland and Labrador (Labrador)", + "New Brunswick", + "Nova Scotia", + "Prince Edward Island", + "Yukon", + "Northwest Territories", + "Nunavut", + "India", + "Australia", + "Brazil", + "USA (United States of America) (America)", + "Mexico (United Mexican States)", + "Moscow", + "Saint Petersburg", + "Kaliningrad Oblast", + "Ingushetia", + "Adygea Republic", + "North Ossetia-Alania Republic", + "Kabardino-Balkar Republic", + "Karachay-Cherkess Republic", + "Chechen Republic (Chechnya) (Ichkeria)", + "Chuvash Republic", + "Ivanovo Oblast", + "Lipetsk Oblast", + "Oryol Oblast", + "Tula Oblast", + "Belgorod Oblast", + "Vladimir Oblast", + "Kursk Oblast", + "Kaluga Oblast", + "Tambov Oblast", + "Bryansk Oblast", + "Yaroslavl Oblast", + "Ryazan Oblast", + "Astrakhan Oblast", + "Moscow Oblast", + "Smolensk Oblast", + "Dagestan Republic", + "Voronezh Oblast", + "Novgorod Oblast", + "Pskov Oblast", + "Kostroma Oblast", + "Stavropol Krai", + "Krasnodar Krai", + "Kalmykia Republic", + "Tver Oblast", + "Leningrad Oblast", + "Rostov Oblast", + "Volgograd Oblast", + "Vologda Oblast", + "Murmansk Oblast", + "Karelia Republic", + "Nenets Autonomous Okrug", + "Komi Republic", + "Arkhangelsk Oblast", + "Mordovia Republic", + "Nizhny Novgorod Oblast", + "Penza Oblast", + "Kirov Oblast", + "Mari El Republic", + "Orenburg Oblast", + "Ulyanovsk Oblast", + "Perm Krai", + "Bashkortostan Republic", + "Udmurt Republic", + "Tatarstan Republic", + "Samara Oblast", + "Saratov Oblast", + "Yamalo-Nenets", + "Khanty-Mansi", + "Sverdlovsk Oblast", + "Tyumen Oblast", + "Kurgan Oblast", + "Chelyabinsk Oblast", + "Buryatia Republic", + "Zabaykalsky Krai", + "Irkutsk Oblast", + "Novosibirsk Oblast", + "Tomsk Oblast", + "Omsk Oblast", + "Khakassia Republic", + "Kemerovo Oblast", + "Altai Republic", + "Altai Krai", + "Tuva Republic", + "Krasnoyarsk Krai", + "Magadan Oblast", + "Chukotka Okrug", + "Kamchatka Krai", + "Sakhalin Oblast", + "Primorsky Krai", + "Jewish Autonomous Oblast", + "Khabarovsk Krai", + "Amur Oblast", + "Sakha Republic (Yakutia Republic)", + "Canada", + "Russia (Russian Federation)", + "Shanghai", + "Tianjin", + "Beijing", + "Hainan", + "Ningxia Hui", + "Chongqing", + "Zhejiang", + "Jiangsu", + "Fujian", + "Anhui", + "Liaoning", + "Shandong", + "Shanxi", + "Jiangxi", + "Henan", + "Guizhou", + "Guangdong", + "Hubei", + "Jilin", + "Hebei (Yanzhao)", + "Shaanxi", + "Nei Mongol (Inner Mongolia)", + "Heilongjiang", + "Hunan", + "Guangxi Zhuang", + "Sichuan", + "Yunnan", + "Xizang (Tibet)", + "Gansu", + "Qinghai (Tsinghai)", + "Xinjiang Uyghur", + "China", + "United States Minor Outlying Islands", + "Clipperton Island", + "Antarctica", + "International (Worldwide) (Earth)", + "?"]; + diff --git a/mapcode.js b/mapcode.js index 769ed7c..1917ae2 100644 --- a/mapcode.js +++ b/mapcode.js @@ -14,7 +14,6 @@ * limitations under the License. */ - var entity_iso = [ 'VAT', 'MCO', 'GIB', 'TKL', 'CCK', 'BLM', 'NRU', 'TUV', 'MAC', 'SXM', 'MAF', 'NFK', 'PCN', 'BVT', 'BMU', 'IOT', 'SMR', 'GGY', 'AIA', 'MSR', @@ -71,27 +70,20 @@ var entity_iso = [ '8HN', '8GX', '8SC', '8YN', '8XZ', '8GS', '8QH', '8XJ', 'CHN', 'UMI', 'CPT', 'ATA', 'AAA', '?']; - var aliases = "2UK=2UT,2CG=2CT,1GU=GUM,1UM=UMI,1VI=VIR,1PR=PRI,1AS=ASM,1MP=MNP,4CX=CXR,4CC=CCK,4NF=NFK,4HM=HMD,COL=5CL,5ME=5MX,MEX=5MX,5TM=TAM,5AG=AGU,5BC=BCN,5BS=BCS,5CM=CAM,5CS=CHP,5CH=CHH,5CO=COA,5DF=DIF,5DG=DUR,5GT=GUA,5GR=GRO,5HG=HID,5JA=JAL,5MI=MIC,5MO=MOR,5NA=NAY,5NL=NLE,5OA=OAX,5PB=PUE,5QE=QUE,5QR=ROO,5SL=SLP,5SI=SIN,5SO=SON,5TB=TAB,5TL=TLA,5VE=VER,5YU=YUC,5ZA=ZAC,811=8BJ,812=8TJ,813=8HE,814=8SX,815=8NM,821=8LN,822=8JL,823=8HL,831=8SH,832=8JS,833=8ZJ,834=8AH,835=8FJ,836=8JX,837=8SD,841=8HA,842=8HB,843=8HN,844=8GD,845=8GX,846=8HI,850=8CQ,851=8SC,852=8GZ,853=8YN,854=8XZ,861=8SN,862=8GS,863=8QH,864=8NX,865=8XJ,871=TWN,891=HKG,892=MAC,8TW=TWN,8HK=HKG,8MC=MAC,BEL=7BE,KIR=7KI,PRI=7PO,CHE=7CH,KHM=7KM,PER=7PM,TAM=7TT,0US=USA,0AU=AUS,0RU=RUS,0CN=CHN,TAA=SHN,ASC=SHN,DGA=IOT,WAK=MHL,JTN=UMI,MID=1HI,2OD=2OR,"; var dependency = [ 27, 410, 50, 410, 26, 410, 53, 410, 48, 410, 47, 410, 76, 410, 529, 410, 38, 410, 21, 408, 4, 408, 42, 408, 11, 408, + 18, 166, 14, 166, 15, 166, 23, 166, 32, 166, 82, 166, 2, 166, 17, 166, 51, 166, 20, 166, 19, 166, 12, 166, 35, 166, 70, 166, 59, 166, 61, 528, 8, 528, 109, 528, 63, 113, 265, 113, 198, 181, - 530, 197, 129, 197, 71, 197, 75, 197, 64, 197, 62, 197, 90, 197, 67, 197, 29, 197, 5, 197, 10, 197, 22, 197, - 18, 166, 14, 166, 15, 166, 23, 166, 32, 166, 82, 166, 2, 166, 17, 166, 51, 166, 20, 166, 19, 166, 12, 166, 35, 166, 70, 166, 59, 166, - 18, 166, 14, 166, 15, 166, 23, 166, 32, 166, 82, 166, 2, 166, 17, 166, 51, 166, 20, 166, 19, 166, 12, 166, 35, 166, 70, 166, 59, 166, + 530, 197, 129, 197, 71, 197, 75, 197, 64, 197, 62, 197, 90, 197, 67, 197, 10, 197, 29, 197, 5, 197, 22, 197, + 13, 178, 40, 178, 25, 112, 33, 112, 45, 112, 9, 112, 28, 171, 30, 171, 3, 171, - 18, 166, 14, 166, 15, 166, 23, 166, 32, 166, 82, 166, 2, 166, 17, 166, 51, 166, 20, 166, 19, 166, 12, 166, 35, 166, 70, 166, 59, 166, - 13, 178, 40, 178, - 18, 166, 14, 166, 15, 166, 23, 166, 32, 166, 82, 166, 2, 166, 17, 166, 51, 166, 20, 166, 19, 166, 12, 166, 35, 166, 70, 166, 59, 166, 77, 210, - 18, 166, 14, 166, 15, 166, 23, 166, 32, 166, 82, 166, 2, 166, 17, 166, 51, 166, 20, 166, 19, 166, 12, 166, 35, 166, 70, 166, 59, 166, - 27, 410, 50, 410, 26, 410, 53, 410, 48, 410, 47, 410, 76, 410, 529, 410, 38, 410, - 27, 410, 50, 410, 26, 410, 53, 410, 48, 410, 47, 410, 76, 410, 529, 410, 38, 410, -1]; var usa_from = 343; @@ -118,19 +110,18 @@ var ccode_chn = 528; var rus_from = 412; var rus_upto = 494; var ccode_rus = 496; -var ccode_ata = 531; var ccode_earth = 532; var parents3 = "USA,IND,CAN,AUS,MEX,BRA,RUS,CHN,"; var parents2 = "US,IN,CA,AU,MX,BR,RU,CN,"; - var ccode_start = 112; // NLD -var mapcode_cversion = "2.0.0"; +var mapcode_cversion = "2.0.2"; +var mapcode_dataversion = "2.0"; // *************************** mapcode_org ********************* -var mapcode_javaversion = '2.0.0/C' + mapcode_cversion; +var mapcode_javaversion = '2.0.1/Data2.0'; /// PRIVATE returns string without leading spaces and plus-signs, and trailing spaces function trim(str) { @@ -187,7 +178,7 @@ function alias2iso(territoryAlphaCode) { /// PRIVATE given ISO code, return territoryNumber (or negative if error) function iso2ccode(territoryAlphaCode) { - if (territoryAlphaCode == "" || typeof territoryAlphaCode == "undefined") { + if (typeof territoryAlphaCode == "undefined") { return undefined; } if (!isNaN(territoryAlphaCode)) { @@ -323,8 +314,7 @@ function isSubdivision(territory) { /// PUBLIC returns true iff territoryNumber is a country that has states function hasSubdivision(territory) { - var territoryNumber = getTerritoryNumber(territory); - return (territoryNumber == ccode_usa || territoryNumber == ccode_ind || territoryNumber == ccode_can || territoryNumber == ccode_aus || territoryNumber == ccode_mex || territoryNumber == ccode_bra || territoryNumber == ccode_chn || territoryNumber == ccode_rus); + return (parents3.indexOf(getTerritoryAlphaCode(getTerritoryNumber(territory), 0)) >= 0); } /// PRIVATE returns true iff x in range (all values in millionths) @@ -336,7 +326,7 @@ function isInRangeX(x, minx, maxx) { x += 360000000; } else { x -= 360000000; - } // 1.32 fix FIJI edge case + } if (minx <= x && x < maxx) { return true; } @@ -344,76 +334,76 @@ function isInRangeX(x, minx, maxx) { } /// PRIVATE returns true iff coordinate inside rectangle (all values in millionths) -function fitsInside(y, x, minx, maxx, miny, maxy) { - return ( miny <= y && y < maxy && isInRangeX(x, minx, maxx) ); +function fitsInside(coord, mm) { + return ( mm.miny <= coord.y && coord.y < mm.maxy && isInRangeX(coord.x, mm.minx, mm.maxx) ); } /// PRIVATE returns true iff coordinate inside rectangle with some room to spare (all values in millionths) -function fitsInsideWithRoom(coord, minx, maxx, miny, maxy) { - if ((( miny - 45) > coord.y) || (coord.y >= (maxy + 45))) { +function fitsInsideWithRoom(coord, mm) { + if ((( mm.miny - 45) > coord.y) || (coord.y >= (mm.maxy + 45))) { return false; } - var xroom = xDivider4(miny, maxy) / 4; - return isInRangeX(coord.x, minx - xroom, maxx + xroom); + var xroom = xDivider4(mm.miny, mm.maxy) / 4; + return isInRangeX(coord.x, mm.minx - xroom, mm.maxx + xroom); } - /// PUBLIC return the AlphaCode (usually an ISO 3166 code) of a territory /// format: 0=local (often ambiguous), 1=international (full and unambiguous, DEFAULT), 2=shortest (shortest non-ambiguous abbreviation) -function getTerritoryAlphaCode(territoryNumber, format) { +function getTerritoryAlphaCode(territory, format) { if (format == undefined) { format = 1; } - if (territoryNumber >= 0 && territoryNumber <= ccode_earth) { - var n = entity_iso[territoryNumber]; - if (/^[0-9]/.test(n)) { - n = n.substring(1); - } - if (format) { - var parent = getParentOf(territoryNumber); - if (parent >= 0) { - if (format == 2) { - // see if n occurs multiple times, if not, don't bother with parent - var count = 0; - var i = aliases.indexOf(n + '='); - if (i >= 0) { - count = 2; - } else if (n.length == 2) { - for (i = 0; i < entity_iso.length; i++) { - if (entity_iso[i].substr(1) == n) { - if (entity_iso[i].charAt(0) >= '0') { - if (entity_iso[i].charAt(0) <= '9') { - count++; - if (count > 1) { - break; - } + var territoryNumber = getTerritoryNumber(territory); + if (territoryNumber < 0 || territoryNumber > ccode_earth) { + return -1; + } + var n = entity_iso[territoryNumber]; + if (/^[0-9]/.test(n)) { + n = n.substring(1); + } + if (format) { + var parent = getParentOf(territoryNumber); + if (parent >= 0) { + if (format == 2) { + // see if n occurs multiple times, if not, don't bother with parent + var count = 0; + var i = aliases.indexOf(n + '='); + if (i >= 0) { + count = 2; + } else if (n.length == 2) { + for (i = 0; i < entity_iso.length; i++) { + if (entity_iso[i].substr(1) == n) { + if (entity_iso[i].charAt(0) >= '0') { + if (entity_iso[i].charAt(0) <= '9') { + count++; + if (count > 1) { + break; } } } } - } else { - for (i = 0; i < entity_iso.length; i++) { - if (entity_iso[i] == n) { - count++; - if (count > 1) { - break; - } + } + } else { + for (i = 0; i < entity_iso.length; i++) { + if (entity_iso[i] == n) { + count++; + if (count > 1) { + break; } } } - if (count == 1) { - return n; - } } - return parentname2(parentletter(entity_iso[parent])) + '-' + n; + if (count == 1) { + return n; + } } + return parentname2(parentletter(entity_iso[parent])) + '-' + n; } - return n; } + return n; } /// PRIVATE low-level routines for data access -var minx, miny, maxx, maxy; // GLOBAL function dataFirstRecord(territoryNumber) { return data_start[territoryNumber]; } @@ -421,38 +411,17 @@ function dataLastRecord(territoryNumber) { return data_start[++territoryNumber] - 1; } function minmaxSetup(i) { - miny = data_miny[i]; var d = data_maxy[i]; if (d < 10) { var shortmaxy = [0, 122309, 27539, 27449, 149759, 2681190, 60119, 62099, 491040, 86489]; d = shortmaxy[d]; } - maxy = miny + d; - minx = data_minx[i]; - maxx = minx + data_maxx[i]; -} - -/// DEPRECATED return a territoryNumber which could PROBABLY encode coordinate (y,x) in degrees; optional preferredTerritoryNumber is returned if possible; returns "international" if all else fails; -function find_bestiso(y, x, preferredTerritoryNumber) { - var ox = Math.round(x * 1000000); - var oy = Math.round(y * 1000000); - // see if inside preferredTerritoryNumber? - if (preferredTerritoryNumber && preferredTerritoryNumber >= 0 && preferredTerritoryNumber <= ccode_earth) { - minmaxSetup(dataLastRecord(preferredTerritoryNumber)); // get encompassing rectangle - if (fitsInside(oy, ox, minx, maxx, miny, maxy)) { - return preferredTerritoryNumber; - } - } - // find first fit - var i; - for (i = 0; i < ccode_earth; i++) { - minmaxSetup(dataLastRecord(i)); // get encompassing rectangle - if (fitsInside(oy, ox, minx, maxx, miny, maxy)) { - return i; - } - } - // assume earth - return ccode_earth; + return { + minx: data_minx[i], + miny: data_miny[i], + maxx: data_minx[i] + data_maxx[i], + maxy: data_miny[i] + d + }; } /// low-level tables for mapcode encoding and decoding @@ -534,11 +503,10 @@ function decodeBase31(str) { return value; } - -function decodeTriple(result) { +function decodeTriple(input) { var triplex, tripley; - var c1 = decodeChar[result.charCodeAt(0)]; - var x = decodeBase31(result.substr(1)); + var c1 = decodeChar[input.charCodeAt(0)]; + var x = decodeBase31(input.substr(1)); if (c1 < 24) { triplex = (c1 % 6) * 28 + Math.floor(x / 34); tripley = Math.floor(c1 / 6) * 34 + Math.floor(x % 34); @@ -579,6 +547,7 @@ var getDebugInfo; // caller must set this to 1 to get debug info about first var mcInfo; /* type: 1=topdown nameless, 2=sixwide nameless, 3=regulargrid 4=irregular grid 5=rounded groups 6=unrounded groups + record: rectangle record used to encode rectangles: rectEncompassing : encompassing rectangle of country or subdivision rectArea : area of the encoding record @@ -602,19 +571,17 @@ function asDegreeRect(minx, miny, dx, dy) { function maxMapcodePrecision() { return 8; } -var use_high_precision = 0; // nr of letters of high-precision postfix (if any) // GLOBAL -var extrapostfix = ''; // GLOBAL -var fraclat = 0, fraclon = 0; -function encodeExtension(result, extrax4, extray, dividerx4, dividery, extraDigits, ydirection) { + +function encodeExtension(result, enc, extrax4, extray, dividerx4, dividery, extraDigits, ydirection) { if (!extraDigits) { return result; } if (extraDigits > maxMapcodePrecision()) { extraDigits = maxMapcodePrecision(); } - var encx = (extrax4 + 4 * fraclon) / (dividerx4); - var ency = (extray + fraclat * ydirection) / (dividery ); - extrapostfix = ''; + var encx = (extrax4 + 4 * enc.fraclon) / (dividerx4); + var ency = (extray + enc.fraclat * ydirection) / (dividery ); + result += '-'; while (extraDigits-- > 0) { encx *= 30; var gx = Math.floor(encx); @@ -635,40 +602,39 @@ function encodeExtension(result, extrax4, extray, dividerx4, dividery, extraDigi var row1 = Math.floor(gy / 5); var row2 = (gy % 5); // add postfix: - extrapostfix += encodeChar[row1 * 5 + column1]; + result += encodeChar[row1 * 5 + column1]; if (extraDigits-- > 0) { - extrapostfix += encodeChar[row2 * 6 + column2]; + result += encodeChar[row2 * 6 + column2]; } encx -= gx; ency -= gy; - } // while - return result + '-' + extrapostfix; + } + return result; } -function decodeExtension(y, x, dividerx4, dividery, ydirection, orginput) { +function decodeExtension(extensionchars, y, x, dividerx4, dividery, ydirection) { var extrax, extray; var dividerx = dividerx4 / 4; var processor = 1.0; extrax = 0; extray = 0; var idx = 0; - while (idx < extrapostfix.length) { + if (extensionchars.length > 8) { + return false; + } + while (idx < extensionchars.length) { var column1, row1, column2, row2; var halfcolumn = 0; - var c1 = decodeChar[extrapostfix.charCodeAt(idx++)]; - if (c1 < 0) { - c1 = 0; - } else if (c1 > 29) { - c1 = 29; + var c1 = decodeChar[extensionchars.charCodeAt(idx++)]; + if (c1 < 0 || c1 == 30) { + return false; } row1 = Math.floor(c1 / 5); column1 = (c1 % 5); - if (idx < extrapostfix.length) { - var c2 = decodeChar[extrapostfix.charCodeAt(idx++)]; - if (c2 < 0) { - c2 = 0; - } else if (c2 > 29) { - c2 = 29; + if (idx < extensionchars.length) { + var c2 = decodeChar[extensionchars.charCodeAt(idx++)]; + if (c2 < 0 || c2 == 30) { + return false; } row2 = Math.floor(c2 / 6); column2 = (c2 % 6); @@ -690,16 +656,15 @@ function decodeExtension(y, x, dividerx4, dividery, ydirection, orginput) { return {y: extray, x: extrax} } -function decodeGrid(result, minx, miny, maxx, maxy, headerletter, territoryNumber, m) // for a well-formed result, and integer variables // returns millionths +function decodeGrid(input, extensionchars, headerletter, m) // for a well-formed input, and integer variables // returns millionths { var relx, rely; - var orgresult = result; - var prefixlength = result.indexOf('.'); - var postfixlength = result.length - 1 - prefixlength; + var prefixlength = input.indexOf('.'); + var postfixlength = input.length - 1 - prefixlength; if (prefixlength == 1 && postfixlength == 4) { prefixlength++; postfixlength--; - result = result.charAt(0) + result.charAt(2) + '.' + result.substring(3); + input = input.charAt(0) + input.charAt(2) + '.' + input.substring(3); } divy = smartdiv(m); @@ -710,16 +675,15 @@ function decodeGrid(result, minx, miny, maxx, maxy, headerletter, territoryNumbe divx = Math.floor(nc[prefixlength] / divy); } - if (prefixlength == 4 && divx == xside[4] && divy == yside[4]) { - result = result.charAt(0) + result.charAt(2) + result.charAt(1) + result.substr(3); + if (prefixlength == 4 && divx == 961 && divy == 961) { + input = input.charAt(0) + input.charAt(2) + input.charAt(1) + input.substr(3); } - var d; - var v = decodeBase31(result); + var v = decodeBase31(input); if (divx != divy && prefixlength > 2) // D==6 { - d = decodeSixWide(v, divx, divy); + var d = decodeSixWide(v, divx, divy); relx = d.x; rely = d.y; } @@ -729,22 +693,25 @@ function decodeGrid(result, minx, miny, maxx, maxy, headerletter, territoryNumbe rely = divy - 1 - rely; } - var ygridsize = Math.floor((maxy - miny + divy - 1) / divy); - var xgridsize = Math.floor((maxx - minx + divx - 1) / divx); + var mm = minmaxSetup(m); + var ygridsize = Math.floor((mm.maxy - mm.miny + divy - 1) / divy); + var xgridsize = Math.floor((mm.maxx - mm.minx + divx - 1) / divx); - rely = miny + (rely * ygridsize); - relx = minx + (relx * xgridsize); + rely = mm.miny + (rely * ygridsize); + relx = mm.minx + (relx * xgridsize); - var dividery = Math.floor(( (((ygridsize)) + yside[postfixlength] - 1) / yside[postfixlength] )); - var dividerx = Math.floor(( (((xgridsize)) + xside[postfixlength] - 1) / xside[postfixlength] )); + var xp = xside[postfixlength]; + var dividerx = Math.floor((xgridsize + xp - 1) / xp); + var yp = yside[postfixlength]; + var dividery = Math.floor((ygridsize + yp - 1) / yp); - var rest = result.substr(prefixlength + 1); + var rest = input.substr(prefixlength + 1); // decoderelative (postfix vs rely,relx) var difx; var dify; if (postfixlength == 3) { - d = decodeTriple(rest); + var d = decodeTriple(rest); difx = d.x; dify = d.y; } @@ -753,18 +720,17 @@ function decodeGrid(result, minx, miny, maxx, maxy, headerletter, territoryNumbe rest = rest.charAt(0) + rest.charAt(2) + rest.charAt(1) + rest.charAt(3); } v = decodeBase31(rest); - difx = Math.floor(v / yside[postfixlength]); - dify = Math.floor(v % yside[postfixlength]); + difx = Math.floor(v / yp); + dify = Math.floor(v % yp); } - dify = yside[postfixlength] - 1 - dify; + dify = yp - 1 - dify; var cornery = rely + (dify * dividery); var cornerx = relx + (difx * dividerx); - return decodeExtension(cornery, cornerx, dividerx << 2, dividery, 1, headerletter + result) + return decodeExtension(extensionchars, cornery, cornerx, dividerx << 2, dividery, 1) } - function encodeBase31(value, nrchars) { var result = ''; while (nrchars-- > 0) { @@ -795,12 +761,16 @@ function encodeTriple(difx, dify, dividerx, dividery) { } } - -function encodeGrid(m, y, x, codex, minx, miny, maxx, maxy, headerletter, territoryNumber) { - var orgcodex = codex; +function encodeGrid(enc, m, mm, headerletter, extraDigits) { + var orgcodex = Codex(m); + var codex = orgcodex; + if (codex == 21) { + codex = 22; + } if (codex == 14) { codex = 23; } + var prefixlength = Math.floor(codex / 10); var postfixlength = (codex % 10); @@ -809,7 +779,7 @@ function encodeGrid(m, y, x, codex, minx, miny, maxx, maxy, headerletter, territ divx = xside[prefixlength]; divy = yside[prefixlength]; if (getDebugInfo) { - mcInfo = {type: 3, regular: true, form: (prefixlength == 2 ? 'rr' : 'rrrr')}; + mcInfo = {type: 3, record: m, regular: true, form: (prefixlength == 2 ? 'rr' : 'rrrr')}; } } else { @@ -817,6 +787,7 @@ function encodeGrid(m, y, x, codex, minx, miny, maxx, maxy, headerletter, territ if (getDebugInfo) { mcInfo = { type: 4, + record: m, regular: false, form: (prefixlength == 2 ? 'ss' : prefixlength == 3 ? 'sss' : 'ssss') }; @@ -834,12 +805,13 @@ function encodeGrid(m, y, x, codex, minx, miny, maxx, maxy, headerletter, territ mcInfo.prefixDivy = divy; } - var ygridsize = Math.floor((maxy - miny + divy - 1) / divy); - var rely = y - miny; + var ygridsize = Math.floor((mm.maxy - mm.miny + divy - 1) / divy); + var rely = enc.coord32.y - mm.miny; rely = Math.floor(rely / ygridsize); - var xgridsize = Math.floor((maxx - minx + divx - 1) / divx); + var xgridsize = Math.floor((mm.maxx - mm.minx + divx - 1) / divx); - var relx = x - minx; + var x = enc.coord32.x; + var relx = x - mm.minx; if (relx < 0) { x += 360000000; relx += 360000000; @@ -856,7 +828,7 @@ function encodeGrid(m, y, x, codex, minx, miny, maxx, maxy, headerletter, territ } var v; - if (divx != divy && codex > 24) // D==6 + if (divx != divy && prefixlength > 2) // D==6 { v = encodeSixWide(relx, rely, divx, divy); } @@ -865,17 +837,16 @@ function encodeGrid(m, y, x, codex, minx, miny, maxx, maxy, headerletter, territ } result = encodeBase31(v, prefixlength); - if (prefixlength == 4 && divx == 961 && divy == 961) { result = result.charAt(0) + result.charAt(2) + result.charAt(1) + result.charAt(3); } if (getDebugInfo && prefixlength == 4 && divx == 961 && divy == 961) { - mcInfo.rectZone = asDegreeRect(minx + 31 * xgridsize * Math.floor(relx / 31), miny + 31 * ygridsize * Math.floor(rely / 31), xgridsize * 31, ygridsize * 31); + mcInfo.rectZone = asDegreeRect(mm.minx + 31 * xgridsize * Math.floor(relx / 31), mm.miny + 31 * ygridsize * Math.floor(rely / 31), xgridsize * 31, ygridsize * 31); } - rely = miny + (rely * ygridsize); - relx = minx + (relx * xgridsize); + rely = mm.miny + (rely * ygridsize); + relx = mm.minx + (relx * xgridsize); var dividery = Math.floor((((ygridsize)) + yside[postfixlength] - 1) / yside[postfixlength]); var dividerx = Math.floor((((xgridsize)) + xside[postfixlength] - 1) / xside[postfixlength]); @@ -885,7 +856,7 @@ function encodeGrid(m, y, x, codex, minx, miny, maxx, maxy, headerletter, territ // encoderelative var difx = x - relx; - var dify = y - rely; + var dify = enc.coord32.y - rely; var extrax = difx % dividerx; var extray = dify % dividery; difx = Math.floor(difx / dividerx); @@ -921,10 +892,9 @@ function encodeGrid(m, y, x, codex, minx, miny, maxx, maxy, headerletter, territ } } - return encodeExtension(headerletter + result, extrax << 2, extray, dividerx << 2, dividery, use_high_precision, 1); // grid + return encodeExtension(headerletter + result, enc, extrax << 2, extray, dividerx << 2, dividery, extraDigits, 1); // grid } - /// alphabet support var MAXLANS = 14; @@ -933,16 +903,16 @@ var asc2lan = [ [913, 914, 926, 916, 63, 917, 915, 919, 921, 928, 922, 923, 924, 925, 927, 929, 920, 936, 931, 932, 63, 934, 937, 935, 933, 918, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Greek [1040, 1042, 1057, 1044, 1045, 1046, 1043, 1053, 1048, 1055, 1050, 1051, 1052, 1047, 1054, 1056, 1060, 1071, 1062, 1058, 1069, 1063, 1064, 1061, 1059, 1041, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Cyrillic [1488, 1489, 1490, 1491, 1507, 1492, 1494, 1495, 1493, 1496, 1497, 1498, 1499, 1500, 1505, 1501, 1502, 1504, 1506, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Hebrew - [2309, 2325, 2327, 2328, 2319, 2330, 2332, 2335, 63, 2336, 2339, 2340, 2342, 2343, 63, 2344, 2346, 2349, 2350, 2352, 2347, 2354, 2357, 2360, 2361, 2337, 2406, 2407, 2408, 2409, 2410, 2411, 2412, 2413, 2414, 2415], // Hindi + [2309, 2325, 2327, 2328, 2319, 2330, 2332, 2335, 73, 2336, 2339, 2340, 2342, 2343, 79, 2344, 2346, 2349, 2350, 2352, 2347, 2354, 2357, 2360, 2361, 2337, 2406, 2407, 2408, 2409, 2410, 2411, 2412, 2413, 2414, 2415], // Hindi [3346, 3349, 3350, 3351, 3339, 3354, 3356, 3359, 3335, 3361, 3364, 3365, 3366, 3367, 3360, 3368, 3374, 3376, 3377, 3378, 3337, 3380, 3381, 3382, 3384, 3385, 3430, 3431, 3432, 3433, 3434, 3435, 3436, 3437, 3438, 3439], // Malay [4256, 4257, 4259, 4262, 4260, 4265, 4267, 4268, 4275, 4270, 4272, 4273, 4274, 4276, 4269, 4277, 4278, 4279, 4280, 4281, 4264, 4282, 4283, 4285, 4286, 4287, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Georgian [12450, 12459, 12461, 12463, 12458, 12465, 12467, 12469, 12452, 12473, 12481, 12488, 12490, 12492, 12454, 12498, 12501, 12504, 12507, 12513, 12456, 12514, 12520, 12521, 12525, 12530, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Katakana [3632, 3585, 3586, 3588, 3634, 3591, 3592, 3593, 3633, 3594, 3601, 3604, 3606, 3607, 3597, 3608, 3610, 3612, 3617, 3619, 3628, 3621, 3623, 3629, 3630, 3631, 3664, 3665, 3666, 3667, 3668, 3669, 3670, 3671, 3672, 3673], // Thai [3760, 3713, 3714, 3716, 3779, 3719, 3720, 3722, 3780, 3725, 3732, 3735, 3737, 3738, 3782, 3740, 3742, 3745, 3746, 3747, 3773, 3751, 3754, 3755, 3757, 3759, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Lao [1366, 1330, 1331, 1332, 1333, 1336, 1337, 1338, 1339, 1341, 1343, 1344, 1345, 1347, 1365, 1351, 1352, 1354, 1357, 1358, 1349, 1359, 1360, 1361, 1362, 1363, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Armenian - [2437, 2444, 2453, 2454, 2447, 2455, 2457, 2458, 63, 2461, 2464, 2465, 2466, 2467, 63, 2468, 2469, 2470, 2472, 2474, 2451, 2476, 2477, 2479, 2482, 2489, 2534, 2535, 2536, 2537, 2538, 2539, 2540, 2541, 2542, 2543], // Bengali - [2565, 2581, 2583, 2584, 2575, 2586, 2588, 2591, 63, 2592, 2595, 2596, 2598, 2599, 63, 2600, 2602, 2605, 2606, 2608, 2603, 2610, 2613, 2616, 2617, 2593, 2662, 2663, 2664, 2665, 2666, 2667, 2668, 2669, 2670, 2671], // Gurmukhi - [3928, 3904, 3905, 3906, 3940, 3908, 3909, 3910, 63, 3911, 3914, 3916, 3918, 3919, 63, 3921, 3923, 3924, 3926, 3934, 3941, 3935, 3937, 3938, 3939, 3942, 3872, 3873, 3874, 3875, 3876, 3877, 3878, 3879, 3880, 3881] // Tibetan + [2437, 2444, 2453, 2454, 2447, 2455, 2457, 2458, 73, 2461, 2464, 2465, 2466, 2467, 79, 2468, 2469, 2470, 2472, 2474, 2451, 2476, 2477, 2479, 2482, 2489, 2534, 2535, 2536, 2537, 2538, 2539, 2540, 2541, 2542, 2543], // Bengali + [2565, 2581, 2583, 2584, 2575, 2586, 2588, 2591, 73, 2592, 2595, 2596, 2598, 2599, 79, 2600, 2602, 2605, 2606, 2608, 2603, 2610, 2613, 2616, 2617, 2593, 2662, 2663, 2664, 2665, 2666, 2667, 2668, 2669, 2670, 2671], // Gurmukhi + [3928, 3904, 3905, 3906, 3940, 3908, 3909, 3910, 73, 3911, 3914, 3916, 3918, 3919, 79, 3921, 3923, 3924, 3926, 3934, 3941, 3935, 3937, 3938, 3939, 3942, 3872, 3873, 3874, 3875, 3876, 3877, 3878, 3879, 3880, 3881] // Tibetan ]; // *UI* @@ -981,20 +951,26 @@ var lanlannam = [ ["དབུ་ཅན་"] ]; - /// PRIVATE substitute characters in str with characters form the specified language (pass asHTML=1 to explicitly HTML-encode characters) function showinlan(str, lan, asHTML) { + str = to_ascii(str); if (!lan) { return str; } var result = ''; + // skip leading territory + var i = str.indexOf(' '); + if (i > 0) { + result = str.substr(0, ++i); + str = str.substr(i); + } + // unpack for languages that do not support E and U - if (asc2lan[lan][4] == 63) { // is there no equivalent for the letter E in this language? + if (asc2lan[lan][4] == 63) { if (str.indexOf('E') >= 0 || str.indexOf('U') >= 0) { str = aeu_pack(aeu_unpack(str), true); - /* v1.50 repack! */ } } @@ -1024,24 +1000,22 @@ function to_ascii(str) { var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; var result = ''; str = trim(str).toUpperCase(); + var len = str.length; - var i; - var trans = 0; for (i = 0; i < len; i++) { var c = str.charCodeAt(i); if (c > 0 && c < 127) { result += str.charAt(i); } else { + var found = 0; var lan; for (lan = 0; lan < MAXLANS; lan++) { var nrc = asc2lan[lan].length; - var found = 0; var j; for (j = 0; j < nrc; j++) { if (c == asc2lan[lan][j]) { result += letters.charAt(j); found = 1; - trans = 1; break; } } @@ -1061,31 +1035,7 @@ function to_ascii(str) { return result; } - /// PRIVATE lowest-level data access - -var flags, codex, codexlo, codexhi, codexlen; // GLOBAL -var isnameless, isrestricted, recType, isSpecialShape22; // GLOBAL - -function dataSetup(i) { - flags = data_flags[i]; - codexhi = Math.floor((flags & 31) / 5); - codexlo = ((flags & 31) % 5) + 1; - codexlen = codexlo + codexhi; - codex = 10 * codexhi + codexlo; - // iscountry = (flags & 32); - isnameless = (flags & 64); - isrestricted = (flags & 512); - isSpecialShape22 = (flags & 1024); - recType = ((flags >> 7) & 3); // 1=pipe 2=plus 3=star - if (codex == 21 && isnameless == 0) { - codex++; - codexlo++; - codexlen++; - } - minmaxSetup(i); -} - function headerLetter(i) { var flags = data_flags[i]; if (((flags >> 7) & 3) == 1) { @@ -1106,164 +1056,165 @@ function isAutoHeader(i) { return data_flags[i] & (8 << 5); } function CodexLen(i) { - flags = data_flags[i]; - codexhi = Math.floor((flags & 31) / 5); - return codexhi + ((flags & 31) % 5) + 1; + var flags = data_flags[i] & 31; + return Math.floor(flags / 5) + (flags % 5) + 1; } function Codex(i) { - flags = data_flags[i]; - codexhi = Math.floor((flags & 31) / 5); - return 10 * codexhi + ((flags & 31) % 5) + 1; + var flags = data_flags[i] & 31; + return 10 * Math.floor(flags / 5) + (flags % 5) + 1; } function isSpecialShape(i) { return data_flags[i] & 1024; } +function recType(i) { + return ((data_flags[i] >> 7) & 3); // 1=pipe 2=plus 3=star +} -function firstNamelessRecord(samecodex, index, firstcode) { +function firstNamelessRecord(index, firstcode) { var i = index; - while (i >= firstcode && Codex(i) == samecodex && isNameless(i)) { + var codex = Codex(i); + while (i >= firstcode && Codex(i) == codex && isNameless(i)) { i--; } i++; return i; } -function countNamelessRecords(samecodex, index, firstcode) { - var i = firstNamelessRecord(samecodex, index, firstcode); +function countNamelessRecords(index, firstcode) { + var i = firstNamelessRecord(index, firstcode); var e = index; - while (Codex(e) == samecodex) { + var codex = Codex(e); + while (Codex(e) == codex) { e++; } return (e - i); } - // mid-level encode/decode -function encodeNameless(x, y, index, firstcode) { - var A = countNamelessRecords(codex, index, firstcode); +function encodeNameless(enc, m, firstcode, extraDigits) { + var A = countNamelessRecords(m, firstcode); + if (A < 1) { + return ''; + } var p = Math.floor(31 / A); var r = (31 % A); - var X = index - firstNamelessRecord(codex, index, firstcode); + var codex = Codex(m); + var codexlen = CodexLen(m); + var X = m - firstNamelessRecord(m, firstcode); - if (A > 1) { - var storage_offset = 0; + var storage_offset; - if (codex != 21 && A <= 31) { - storage_offset = (X * p + (X < r ? X : r)) * (961 * 961); - } - else if (codex != 21 && A < 62) { - if (X < (62 - A)) { - storage_offset = X * (961 * 961); - } - else { - storage_offset = (62 - A + Math.floor((X - 62 + A) / 2) ) * (961 * 961); - if ((X + A) & 1) { - storage_offset += (16 * 961 * 31); - } - } + if (codex != 21 && A <= 31) { + storage_offset = (X * p + (X < r ? X : r)) * (961 * 961); + } + else if (codex != 21 && A < 62) { + if (X < (62 - A)) { + storage_offset = X * (961 * 961); } else { - var BASEPOWER = (codex == 21) ? 961 * 961 : 961 * 961 * 31; - var BASEPOWERA = Math.floor(BASEPOWER / A); - if (A == 62) { - BASEPOWERA++; - } else { - BASEPOWERA = (961) * Math.floor(BASEPOWERA / 961); + storage_offset = (62 - A + Math.floor((X - 62 + A) / 2) ) * (961 * 961); + if ((X + A) & 1) { + storage_offset += (16 * 961 * 31); } - - storage_offset = X * BASEPOWERA; } - - var SIDE = smartdiv(index); - var orgSIDE = SIDE; - var xSIDE = SIDE; - if (isSpecialShape22) { - xSIDE *= SIDE; - SIDE = 1 + Math.floor((maxy - miny) / 90); - xSIDE = Math.floor(xSIDE / SIDE); + } + else { + var BASEPOWER = (codex == 21) ? 961 * 961 : 961 * 961 * 31; + var BASEPOWERA = Math.floor(BASEPOWER / A); + if (A == 62) { + BASEPOWERA++; + } else { + BASEPOWERA = (961) * Math.floor(BASEPOWERA / 961); } - var dividerx4 = xDivider4(miny, maxy); // note that xDivider4 is 4 times too large - var xFracture = Math.floor(4 * fraclon); - var dx = Math.floor((4 * (x - minx) + xFracture) / dividerx4); // dx is in millionths - var extrax4 = (x - minx) * 4 - dx * dividerx4; // extrax4 is in quarter-millionths + storage_offset = X * BASEPOWERA; + } - var dividery = 90; - var dy = Math.floor((maxy - y) / dividery); - var extray = (maxy - y) % dividery; + var mm = minmaxSetup(m); + var SIDE = smartdiv(m); + var orgSIDE = SIDE; + var xSIDE = SIDE; + if (isSpecialShape(m)) { + xSIDE *= SIDE; + SIDE = 1 + Math.floor((mm.maxy - mm.miny) / 90); + xSIDE = Math.floor(xSIDE / SIDE); + } - if (extray == 0 && fraclat > 0) { - dy--; - extray += dividery; - } + var dividerx4 = xDivider4(mm.miny, mm.maxy); // note that xDivider4 is 4 times too large + var xFracture = Math.floor(4 * enc.fraclon); + var dx = Math.floor((4 * (enc.coord32.x - mm.minx) + xFracture) / dividerx4); // dx is in millionths + var extrax4 = (enc.coord32.x - mm.minx) * 4 - dx * dividerx4; // extrax4 is in quarter-millionths - var v = storage_offset; - if (isSpecialShape22) { - v += encodeSixWide(dx, SIDE - 1 - dy, xSIDE, SIDE); - } - else { - v += (dx * SIDE + dy); - } + var dividery = 90; + var dy = Math.floor((mm.maxy - enc.coord32.y) / dividery); + var extray = (mm.maxy - enc.coord32.y) % dividery; - if (getDebugInfo) { - mcInfo = {type: (isSpecialShape22 ? 2 : 1), regular: false}; - mcInfo.rectCell = asDegreeRect(minx + dx * (dividerx4 / 4), maxy - (dy + 1) * dividery, dividerx4 / 4, dividery); - mcInfo.prefixDivx = xSIDE; - mcInfo.prefixDivy = SIDE; - mcInfo.dotPosition = (codex == 22 ? 3 : 2); - mcInfo.form = (codexlen == 3 ? 'nnnn' : 'nnnnn'); - mcInfo.postfixType = 0; - } + if (extray == 0 && enc.fraclat > 0) { + dy--; + extray += dividery; + } - var result = encodeBase31(v, codexlen + 1); + var v = storage_offset; + if (isSpecialShape(m)) { + v += encodeSixWide(dx, SIDE - 1 - dy, xSIDE, SIDE); + } + else { + v += (dx * SIDE + dy); + } - if (codexlen == 3) { - result = result.substr(0, 2) + '.' + result.substr(2); - } - else if (codexlen == 4) { - if (codex == 22 && orgSIDE == 961 && !isSpecialShape22) { - if (getDebugInfo) { - mcInfo.form = 'hrrpp'; - mcInfo.headerletter = encodeChar[storage_offset / (961 * 961)]; - mcInfo.postfixType = 2; - mcInfo.regular = true; - mcInfo.rectRegion = asDegreeRect((minx + (31 * Math.floor(dx / 31) * dividerx4 / 4)), maxy - (31 * dividery) * (1 + Math.floor(dy / 31)), 31 * dividerx4 / 4, 31 * dividery); - } - result = result.charAt(0) + result.charAt(1) + result.charAt(3) + result.charAt(2) + result.charAt(4); - } - if (codex == 13) { - result = result.substr(0, 2) + '.' + result.substr(2); - } else { - result = result.substr(0, 3) + '.' + result.substr(3); + if (getDebugInfo) { + mcInfo = {type: (isSpecialShape(m) ? 2 : 1), regular: false, record: m}; + mcInfo.rectCell = asDegreeRect(mm.minx + dx * (dividerx4 / 4), mm.maxy - (dy + 1) * dividery, dividerx4 / 4, dividery); + mcInfo.prefixDivx = xSIDE; + mcInfo.prefixDivy = SIDE; + mcInfo.dotPosition = (codex == 22 ? 3 : 2); + mcInfo.form = (codexlen == 3 ? 'nnnn' : 'nnnnn'); + mcInfo.postfixType = 0; + } + + var result = encodeBase31(v, codexlen + 1); + + if (codexlen == 3) { + result = result.substr(0, 2) + '.' + result.substr(2); + } + else if (codexlen == 4) { + if (codex == 22 && orgSIDE == 961 && !isSpecialShape(m)) { + if (getDebugInfo) { + mcInfo.form = 'hrrpp'; + mcInfo.headerletter = encodeChar[storage_offset / (961 * 961)]; + mcInfo.postfixType = 2; + mcInfo.regular = true; + mcInfo.rectRegion = asDegreeRect((mm.minx + (31 * Math.floor(dx / 31) * dividerx4 / 4)), mm.maxy - (31 * dividery) * (1 + Math.floor(dy / 31)), 31 * dividerx4 / 4, 31 * dividery); } + result = result.charAt(0) + result.charAt(1) + result.charAt(3) + '.' + result.charAt(2) + result.charAt(4); + } else if (codex == 13) { + result = result.substr(0, 2) + '.' + result.substr(2); + } else { + result = result.substr(0, 3) + '.' + result.substr(3); } - - return encodeExtension(result, extrax4, extray, dividerx4, dividery, use_high_precision, -1); // nameless } -} + return encodeExtension(result, enc, extrax4, extray, dividerx4, dividery, extraDigits, -1); // nameless +} -function decodeNameless(result, firstrec) // returns millionths -{ +function decodeNameless(input, extensionchars, m, firstindex) { + var codex = Codex(m); if (codex == 22) { - result = result.substr(0, 3) + result.substr(4); + input = input.substr(0, 3) + input.substr(4); } else { - result = result.substr(0, 2) + result.substr(3); + input = input.substr(0, 2) + input.substr(3); } - var A = countNamelessRecords(codex, firstrec, firstrec); - if (A < 2) { - A = 1; - } // paranoia - + var A = countNamelessRecords(m, firstindex); + var F = firstNamelessRecord(m, firstindex); var p = Math.floor(31 / A); var r = (31 % A); - var v; - var X = -1; + var v = 0; + var X; var swapletters = 0; if (codex != 21 && A <= 31) { - var offset = decodeChar[result.charCodeAt(0)]; + var offset = decodeChar[input.charCodeAt(0)]; if (offset < r * (p + 1)) { X = Math.floor(offset / (p + 1)); @@ -1274,12 +1225,11 @@ function decodeNameless(result, firstrec) // returns millionths } } else if (codex != 21 && A < 62) { - X = decodeChar[result.charCodeAt(0)]; + X = decodeChar[input.charCodeAt(0)]; if (X < (62 - A)) { swapletters = (codex == 22); - } - else { - X = X + (X - (62 - A)); + } else { + X += (X - (62 - A)); } } else // codex==21 || A>=62 @@ -1292,26 +1242,29 @@ function decodeNameless(result, firstrec) // returns millionths BASEPOWERA = 961 * Math.floor(BASEPOWERA / 961); } - // decode and determine x - v = decodeBase31(result); + // decode + v = decodeBase31(input); + X = Math.floor(v / BASEPOWERA); v %= BASEPOWERA; } if (swapletters) { - if (!isSpecialShape(firstrec + X)) { - result = result.charAt(0) + result.charAt(1) + result.charAt(3) + result.charAt(2) + result.charAt(4); + if (!isSpecialShape(m + X)) { + input = input.charAt(0) + input.charAt(1) + input.charAt(3) + input.charAt(2) + input.charAt(4); } } if (codex != 21 && A <= 31) { - v = decodeBase31(result); + v = decodeBase31(input); + if (X > 0) { v -= ( (X * p + (X < r ? X : r)) * (961 * 961) ); } } else if (codex != 21 && A < 62) { - v = decodeBase31(result.substr(1)); + v = decodeBase31(input.substr(1)); + if (X >= (62 - A)) { if (v >= (16 * 961 * 31)) { v -= (16 * 961 * 31); @@ -1323,19 +1276,20 @@ function decodeNameless(result, firstrec) // returns millionths if (X > A) { return false; } // past end! - dataSetup(firstrec + X); + m = F + X; + var mm = minmaxSetup(m); - SIDE = smartdiv(firstrec + X); + SIDE = smartdiv(m); var xSIDE = SIDE; - if (isSpecialShape22) { + if (isSpecialShape(m)) { xSIDE *= SIDE; - SIDE = 1 + Math.floor((maxy - miny) / 90); + SIDE = 1 + Math.floor((mm.maxy - mm.miny) / 90); xSIDE = Math.floor(xSIDE / SIDE); } var dx, dy; - if (isSpecialShape22) { + if (isSpecialShape(m)) { var d = decodeSixWide(v, xSIDE, SIDE); dx = d.x; dy = SIDE - 1 - d.y; @@ -1345,154 +1299,146 @@ function decodeNameless(result, firstrec) // returns millionths dx = Math.floor(v / SIDE); } - if (dx >= xSIDE) // else out-of-range! - { + if (dx >= xSIDE) { // else out-of-range! return false; } - var dividerx4 = xDivider4(miny, maxy); // 4 times too large! + var dividerx4 = xDivider4(mm.miny, mm.maxy); // 4 times too large! var dividery = 90; - var cornerx = minx + Math.floor((dx * dividerx4) / 4); // FIRST multiply, THEN divide! - var cornery = maxy - (dy * dividery); - var ret = decodeExtension(cornery, cornerx, dividerx4, dividery, -1, result); - ret.x += ((dx * dividerx4) % 4) / 4.0; + var cornerx = mm.minx + Math.floor((dx * dividerx4) / 4); // FIRST multiply, THEN divide! + var cornery = mm.maxy - (dy * dividery); + var ret = decodeExtension(extensionchars, cornery, cornerx, dividerx4, dividery, -1); + if (ret) { + ret.x += ((dx * dividerx4) % 4) / 4.0; + } return ret; } - -function encodeAutoHeader(y, x, thiscodexlen, thisindex, territoryNumber) { +function encodeAutoHeader(enc, m, extraDigits) { var STORAGE_START = 0; // search back to first of the group - var firstindex = thisindex; - while (isAutoHeader(firstindex - 1) && CodexLen(firstindex - 1) == thiscodexlen) { + var codex = Codex(m); + var codexlen = CodexLen(m); + var firstindex = m; + while (isAutoHeader(firstindex - 1) && Codex(firstindex - 1) == codex) { firstindex--; } var i; - for (i = firstindex; CodexLen(i) == thiscodexlen; i++) { - dataSetup(i); - var H = Math.floor((maxy - miny + 89) / 90); - var xdiv = xDivider4(miny, maxy); - var W = Math.floor(( (maxx - minx) * 4 + (xdiv - 1) ) / xdiv); + for (i = firstindex; Codex(i) == codex; i++) { + var mm = minmaxSetup(i); + var H = Math.floor((mm.maxy - mm.miny + 89) / 90); + var xdiv = xDivider4(mm.miny, mm.maxy); + var W = Math.floor(( (mm.maxx - mm.minx) * 4 + (xdiv - 1) ) / xdiv); H = 176 * Math.floor((H + 176 - 1) / 176); W = 168 * Math.floor((W + 168 - 1) / 168); var product = Math.floor(W / 168) * Math.floor(H / 176) * 961 * 31; - if (recType == 2) { // *+ + if (recType(i) == 2) { // *+ var GOODROUNDER = codex >= 23 ? (961 * 961 * 31) : (961 * 961); product = Math.floor((STORAGE_START + product + GOODROUNDER - 1) / GOODROUNDER) * GOODROUNDER - STORAGE_START; } - if (i == thisindex) { - if (fitsInside(y, x, minx, maxx, miny, maxy)) { - var dividerx = Math.floor((maxx - minx + W - 1) / W); - var vx = Math.floor((x - minx) / dividerx); - var extrax = ((x - minx) % dividerx); + if (i == m && fitsInside(enc.coord32, mm)) { + var dividerx = Math.floor((mm.maxx - mm.minx + W - 1) / W); + var vx = Math.floor((enc.coord32.x - mm.minx) / dividerx); + var extrax = ((enc.coord32.x - mm.minx) % dividerx); - var dividery = Math.floor((maxy - miny + H - 1) / H); - var vy = Math.floor((maxy - y) / dividery); - var extray = ((maxy - y) % dividery); + var dividery = Math.floor((mm.maxy - mm.miny + H - 1) / H); + var vy = Math.floor((mm.maxy - enc.coord32.y) / dividery); + var extray = ((mm.maxy - enc.coord32.y) % dividery); - var spx = vx % 168; - var spy = vy % 176; + var spx = vx % 168; + var spy = vy % 176; - vx = Math.floor(vx / 168); - var value = vx * Math.floor(H / 176); + vx = Math.floor(vx / 168); + var value = vx * Math.floor(H / 176); - if (extray == 0 && fraclat > 0) { - if (vy == 0) { - STORAGE_START += product; - continue; - } - vy--; - extray += dividery; + if (extray == 0 && enc.fraclat > 0) { + if (vy == 0) { + STORAGE_START += product; + continue; } + vy--; + extray += dividery; + } - vy = Math.floor(vy / 176); - value += vy; - + vy = Math.floor(vy / 176); + value += vy; - if (getDebugInfo) { - mcInfo = {type: (recType == 2 ? 6 : 5), regular: false}; // 5=unrounded groups / 6=rounded groups - mcInfo.form = (codexlen == 4 ? 'ggppp' : 'gggppp'); - mcInfo.postfixType = 3; - mcInfo.dotPosition = codexlen - 2; - mcInfo.prefixDivx = Math.floor(W / 168); - mcInfo.prefixDivy = Math.floor(H / 176); - mcInfo.rectSubarea = asDegreeRect(minx + (vx * 168 ) * dividerx, maxy - ((vy + 1) * 176 ) * dividery, 168 * dividerx, 176 * dividery); - mcInfo.rectCell = asDegreeRect(minx + (vx * 168 + spx) * dividerx, maxy - ((vy ) * 176 + spy + 1) * dividery, dividerx, dividery); - } + if (getDebugInfo) { + mcInfo = {type: (recType(i) == 2 ? 6 : 5), regular: false, record: i}; // 5=unrounded groups / 6=rounded groups + mcInfo.form = (codexlen == 4 ? 'ggppp' : 'gggppp'); + mcInfo.postfixType = 3; + mcInfo.dotPosition = codexlen - 2; + mcInfo.prefixDivx = Math.floor(W / 168); + mcInfo.prefixDivy = Math.floor(H / 176); + mcInfo.rectSubarea = asDegreeRect(mm.minx + (vx * 168 ) * dividerx, mm.maxy - ((vy + 1) * 176 ) * dividery, 168 * dividerx, 176 * dividery); + mcInfo.rectCell = asDegreeRect(mm.minx + (vx * 168 + spx) * dividerx, mm.maxy - ((vy ) * 176 + spy + 1) * dividery, dividerx, dividery); + } - var mapc = encodeBase31(Math.floor(STORAGE_START / (961 * 31)) + value, codexlen - 2) + '.' + encodeTriple(spx, spy, dividerx, dividery); + var mapc = encodeBase31(Math.floor(STORAGE_START / (961 * 31)) + value, codexlen - 2) + '.' + encodeTriple(spx, spy, dividerx, dividery); - return encodeExtension(mapc, extrax << 2, extray, dividerx << 2, dividery, use_high_precision, -1); // autoheader - } + return encodeExtension(mapc, enc, extrax << 2, extray, dividerx << 2, dividery, extraDigits, -1); // autoheader } STORAGE_START += product; } return ''; // fail } -function decodeAutoHeader(input, firstindex, territoryNumber) { +function decodeAutoHeader(input, extensionchars, m) { var STORAGE_START = 0; - var thiscodexlen = codexlen; + var codex = Codex(m); + + var value = decodeBase31(input); // decode (before dot) - var value = decodeBase31(input); // decode top (before dot) value *= (961 * 31); var triple = decodeTriple(input.substr(input.length - 3)); // decode bottom 3 chars - var i; - for (i = firstindex; ; i++) { - if (CodexLen(i) != thiscodexlen) { - return false; - } - if (i > firstindex) { - dataSetup(i); - } + for (; Codex(m) == codex && recType(m) > 1; m++) { + var mm = minmaxSetup(m); - var H = Math.floor((maxy - miny + 89) / 90); - var xdiv = xDivider4(miny, maxy); - var W = Math.floor(( (maxx - minx) * 4 + (xdiv - 1) ) / xdiv); + var H = Math.floor((mm.maxy - mm.miny + 89) / 90); + var xdiv = xDivider4(mm.miny, mm.maxy); + var W = Math.floor(( (mm.maxx - mm.minx) * 4 + (xdiv - 1) ) / xdiv); H = 176 * Math.floor((H + 176 - 1) / 176); W = 168 * Math.floor((W + 168 - 1) / 168); var product = Math.floor(W / 168) * Math.floor(H / 176) * 961 * 31; - if (recType == 2) { // *+ + if (recType(m) == 2) { var GOODROUNDER = codex >= 23 ? (961 * 961 * 31) : (961 * 961); product = Math.floor((STORAGE_START + product + GOODROUNDER - 1) / GOODROUNDER) * GOODROUNDER - STORAGE_START; } if (value >= STORAGE_START && value < STORAGE_START + product) // code belongs here? { - var dividerx = Math.floor((maxx - minx + W - 1) / W); - var dividery = Math.floor((maxy - miny + H - 1) / H); + var dividerx = Math.floor((mm.maxx - mm.minx + W - 1) / W); + var dividery = Math.floor((mm.maxy - mm.miny + H - 1) / H); value -= STORAGE_START; value = Math.floor(value / (961 * 31)); - var vx = Math.floor(value / Math.floor(H / 176)) * 168 + triple.x; - var vy = (value % Math.floor(H / 176)) * 176 + triple.y; - - var cornery = maxy - vy * dividery; - var cornerx = minx + vx * dividerx; + var vx = triple.x + 168 * Math.floor(value / Math.floor(H / 176)); + var vy = triple.y + 176 * (value % Math.floor(H / 176)); - var retval = decodeExtension(cornery, cornerx, dividerx << 2, dividery, -1, input); - if (retval.x < minx || retval.x >= maxx || retval.y < miny || retval.y > maxy) { + var cornery = mm.maxy - vy * dividery; + var cornerx = mm.minx + vx * dividerx; + if (cornerx < mm.minx || cornerx >= mm.maxx || cornery < mm.miny || cornery > mm.maxy) { return false; } - return retval; + return decodeExtension(extensionchars, cornery, cornerx, dividerx << 2, dividery, -1); } STORAGE_START += product; } + return false; } - /// PRIVATE add vowels to prevent a mapcode r from being all-digit function aeu_pack(r, short) /* v1.50 */ { var dotpos = -9; @@ -1502,9 +1448,8 @@ function aeu_pack(r, short) /* v1.50 */ { for (d = 0; d < rlen; d++) { if (r.charAt(d) < '0' || r.charAt(d) > '9') // not digit? { - if (r.charAt(d) == '.' && dotpos < 0) // first dot? - { - dotpos = d; + if (r.charAt(d) == '.' && dotpos < 0) { + dotpos = d; // first dot? } else if (r.charAt(d) == '-') { rest = r.substring(d); r = r.substring(0, d); @@ -1514,7 +1459,7 @@ function aeu_pack(r, short) /* v1.50 */ { return r; } } - } // not alldigit (or multiple dots) + } var v; if (rlen - 2 > dotpos) { // does r have a dot, AND at least 2 chars after the dot? @@ -1533,72 +1478,66 @@ function aeu_pack(r, short) /* v1.50 */ { // PRIVATE (defaults for last 4 are false,false,false,-1) var debugStopRecord = -1; // GLOBAL /// returns result, or empty if error -var results; // GLOBAL -function mapcoderEngine(orgy, orgx, tn, getshortest, isrecursive, state_override) { - // round to millionths and normalise - if (isNaN(orgx)) { - orgx = 0; - } - if (isNaN(orgy)) { - orgy = 0; - } - orgy = Number(orgy); - orgx = Number(orgx); - if (orgy > 90) { - orgy = 90; - } else if (orgy < -90) { - orgy = -90; - } // cut within [-90..+90] - if (orgx >= 180) { - orgx -= 360; - } else if (orgx < -180) { - orgx += 360; - } // move within [-180..+180> - - { // seperate out the fraction - var y = orgy + 90; - var x = orgx + 180; - y *= 1000000; - x *= 1000000; - var lat32 = Math.floor(y); - var lon32 = Math.floor(x); - fraclat = y - lat32; // get fraction - fraclon = x - lon32; // get fraction - - // for 8-digit precision, cells are divided into 810,000 by 810,000 minicells. So take care of math errors - fraclat *= 810000; - if (fraclat < 1) { - fraclat = 0; - } else { - if (fraclat > 809999) { - fraclat = 0; - lat32++; - } else { - fraclat /= 810000; - } - } - fraclon *= 810000; - if (fraclon < 1) { - fraclon = 0; - } else { - if (fraclon > 809999) { - fraclon = 0; - lon32++; - } else { - fraclon /= 810000; - } - } +function getEncodeRec(lat, lon) { + + if (isNaN(lat)) { + lat = 0; + } + lat = Number(lat); + if (lat > 90) { + lat = 90; + } else if (lat < -90) { + lat = -90; + } + // seperate out the fraction + var y = lat + 90; + y *= 1000000; + var lat32 = Math.floor(y); + fraclat = y - lat32; // get fraction + // solve math errors for 810,000 minicells (30^4) + fraclat *= 810000; + if (fraclat < 1) { + fraclat = 0; + } else if (fraclat > 809999) { + fraclat = 0; + lat32++; + } else { + fraclat /= 810000; + } + + if (isNaN(lon)) { + lon = 0; + } + lon = Number(lon); + if (lon >= 180) { + lon -= 360; + } else if (lon < -180) { + lon += 360; + } + // seperate out the fraction + var x = lon + 180; + x *= 1000000; + var lon32 = Math.floor(x); + fraclon = x - lon32; // get fraction + // solve math errors for 810,000 minicells (30^4) + fraclon *= 810000; + if (fraclon < 1) { + fraclon = 0; + } else if (fraclon > 809999) { + fraclon = 0; + lon32++; + } else { + fraclon /= 810000; + } - y = lat32 - 90000000; - x = lon32 - 180000000; - } // + return {coord32: {y: lat32 - 90000000, x: lon32 - 180000000}, fraclat: fraclat, fraclon: fraclon}; +} - mcInfo = {type: 0}; +function mapcoderEngine(enc, tn, getshortest, isrecursive, state_override, extraDigits) { + var results = []; - if (!isrecursive) { - results = []; - } + mcInfo = {type: 0}; var fromTerritory = 0; var uptoTerritory = ccode_earth; @@ -1622,37 +1561,40 @@ function mapcoderEngine(orgy, orgx, tn, getshortest, isrecursive, state_override // make sure it fits the country if (territoryNumber != ccode_earth) { - minmaxSetup(upto); // find encompassing rect - if (!(fitsInside(y, x, minx, maxx, miny, maxy))) { // does not fit? + if (!(fitsInside(enc.coord32, minmaxSetup(upto)))) { // does not fit encompassing rect? if (isrecursive) { return; } - from = upto + 1; // empty the range + continue; } } for (var i = from; i <= upto; i++) { - dataSetup(i); - if (codex < 54) // exlude 54 and 55 + + if (Codex(i) < 54) // exlude 54 and 55 { - if (fitsInside(y, x, minx, maxx, miny, maxy)) { + var mm = minmaxSetup(i); + if (fitsInside(enc.coord32, mm)) { var r; - if (isnameless) { - r = encodeNameless(x, y, i, from); + if (isNameless(i)) { + r = encodeNameless(enc, i, from, extraDigits); } - else if (recType > 1) { - r = encodeAutoHeader(y, x, codexlen, i, territoryNumber); + else if (recType(i) > 1) { + r = encodeAutoHeader(enc, i, extraDigits); } - else if (isrestricted && i == upto && getParentOf(territoryNumber) >= 0) { - mapcoderEngine(orgy, orgx, getParentOf(territoryNumber), getshortest, true/*recursive*/, territoryNumber); + else if (isRestricted(i) && i == upto && getParentOf(territoryNumber) >= 0) { + moreresults = mapcoderEngine(enc, getParentOf(territoryNumber), getshortest, true/*recursive*/, territoryNumber, extraDigits); + if (moreresults && moreresults.length > 0) { + results = results.concat(moreresults); + } continue; } else { - if (isrestricted && results.length == original_length) { + if (isRestricted(i) && results.length == original_length) { r = ''; // restricted, and no shorter mapcodes exist: do not generate mapcodes } else { - r = encodeGrid(i, y, x, codex, minx, miny, maxx, maxy, headerLetter(i), territoryNumber); + r = encodeGrid(enc, i, mm, headerLetter(i), extraDigits); } } @@ -1669,14 +1611,13 @@ function mapcoderEngine(orgy, orgx, tn, getshortest, isrecursive, state_override results.length = 0; // clear all other results } - if (getDebugInfo) { mcInfo.mapcode = r; mcInfo.record = i; - mcInfo.rectArea = asDegreeRect(minx, miny, maxx - minx, maxy - miny); + mcInfo.rectArea = asDegreeRect(mm.minx, mm.miny, mm.maxx - mm.minx, mm.maxy - mm.miny); mcInfo.form = mcInfo.form.substr(0, mcInfo.dotPosition) + '.' + mcInfo.form.substr(mcInfo.dotPosition); - dataSetup(upto); - mcInfo.rectEncompassing = asDegreeRect(minx, miny, maxx - minx, maxy - miny); + var mm = minmaxSetup(upto); + mcInfo.rectEncompassing = asDegreeRect(mm.minx, mm.miny, mm.maxx - mm.minx, mm.maxy - mm.miny); } else { mcInfo = {mapcode: r}; @@ -1702,7 +1643,6 @@ function mapcoderEngine(orgy, orgx, tn, getshortest, isrecursive, state_override return results; } - /// PRIVATE remove vowels from mapcode str into an all-digit mapcode (assumes str is already uppercase!) function aeu_unpack(str) { var voweled = 0; @@ -1781,7 +1721,6 @@ function aeu_unpack(str) { } } // nonodigit! - return str; } @@ -1789,13 +1728,11 @@ function aeu_unpack(str) { function master_decode(mapcode, territoryNumber) // returns object with y and x fields, or false { mapcode = to_ascii(mapcode); - + var extensionchars = ''; var minpos = mapcode.indexOf('-'); if (minpos > 0) { - extrapostfix = trim(mapcode.substring(minpos + 1)); + extensionchars = trim(mapcode.substring(minpos + 1)); mapcode = trim(mapcode.substring(0, minpos)); - } else { - extrapostfix = ''; } mapcode = aeu_unpack(mapcode); @@ -1803,7 +1740,6 @@ function master_decode(mapcode, territoryNumber) // returns object with y and x return false; } // failed to decode! - var mclen = mapcode.length; if (mclen >= 10) { @@ -1825,24 +1761,23 @@ function master_decode(mapcode, territoryNumber) // returns object with y and x var prefixlength = mapcode.indexOf('.'); var postfixlength = mclen - 1 - prefixlength; + var incodex = prefixlength * 10 + postfixlength; var result; - var i; - for (i = from; i <= upto; i++) { - dataSetup(i); - if (recType == 0 && isnameless == 0 && codexhi == prefixlength && codexlo == postfixlength) { - result = decodeGrid(mapcode, minx, miny, maxx, maxy, '', territoryNumber, i); - if (isrestricted && result) { + var m; + for (m = from; m <= upto; m++) { + var codex = Codex(m); + if (recType(m) == 0 && isNameless(m) == 0 && (incodex == codex || (incodex == 22 && codex == 21))) { + result = decodeGrid(mapcode, extensionchars, '', m); + if (result && isRestricted(m)) { var fitssomewhere = 0; var j; for (j = upto - 1; j >= from; j--) { // look in previous rects - dataSetup(j); - if (isrestricted) { - continue; - } - if (fitsInsideWithRoom(result, minx, maxx, miny, maxy)) { - fitssomewhere = 1; - break; + if (!isRestricted(j)) { + if (fitsInsideWithRoom(result, minmaxSetup(j))) { + fitssomewhere = 1; + break; + } } } if (!fitssomewhere) { @@ -1851,16 +1786,16 @@ function master_decode(mapcode, territoryNumber) // returns object with y and x } break; } - else if (recType == 1 && codexlo == postfixlength && codexhi + 1 == prefixlength && headerLetter(i) == mapcode.charAt(0)) { - result = decodeGrid(mapcode.substr(1), minx, miny, maxx, maxy, mapcode.substr(0, 1), territoryNumber, i); + else if (recType(m) == 1 && codex + 10 == incodex && headerLetter(m) == mapcode.charAt(0)) { + result = decodeGrid(mapcode.substr(1), extensionchars, mapcode.substr(0, 1), m); break; } - else if (isnameless && ((codex == 21 && prefixlength == 2 && postfixlength == 2 ) || (codex == 22 && prefixlength == 3 && postfixlength == 2) || (codex == 13 && prefixlength == 2 && postfixlength == 3))) { - result = decodeNameless(mapcode, i); + else if (isNameless(m) && ((codex == 21 && incodex == 22 ) || (codex == 22 && incodex == 32) || (codex == 13 && incodex == 23))) { + result = decodeNameless(mapcode, extensionchars, m, from); break; } - else if (recType > 1 && postfixlength == 3 && codexlo + codexhi == prefixlength + 2) { - result = decodeAutoHeader(mapcode, i, territoryNumber); + else if (recType(m) > 1 && postfixlength == 3 && CodexLen(m) == prefixlength + 2) { + result = decodeAutoHeader(mapcode, extensionchars, m); break; } } @@ -1870,20 +1805,17 @@ function master_decode(mapcode, territoryNumber) // returns object with y and x result.x -= 360000000; } else if (result.x < -180000000) { result.x += 360000000; - } // 1.33 normalize <-180 + } // make sure result is in the country if (territoryNumber != ccode_earth) { - minmaxSetup(upto); // find encompassing rect - if (!(fitsInsideWithRoom(result, minx, maxx, miny, maxy))) { // does not fit? + if (!(fitsInsideWithRoom(result, minmaxSetup(upto)))) { return false; } } - } - if (result) { - result.x = result.x / 1000000.0; - result.y = result.y / 1000000.0; + result.x /= 1000000.0; + result.y /= 1000000.0; if (result.y > 90) { result.y = 90; } @@ -1912,9 +1844,10 @@ function fullname(territoryNumber, keepindex) { return getTerritoryFullname(territoryNumber); } function master_encode(orgy, orgx, tn, isrecursive, stop_with_one_result, allowworld, state_override) { - mapcoderEngine(orgy, orgx, tn, stop_with_one_result, isrecursive, state_override); + var enc = getEncodeRec(lat, lon); + mapcoderEngine(enc, tn, stop_with_one_result, isrecursive, state_override, 0); if (allowworld && !isrecursive && tn != ccode_earth && (results.length == 0 || results[results.length - 1].territoryNumber != ccode_earth)) { - mapcoderEngine(orgy, orgx, ccode_earth, stop_with_one_result, true/*recursive*/, -1); + mapcoderEngine(enc, ccode_earth, stop_with_one_result, true/*recursive*/, -1, 0); } var strArray = []; for (var i = 0; i < results.length; i++) { @@ -1928,34 +1861,38 @@ function master_encode(orgy, orgx, tn, isrecursive, stop_with_one_result, alloww /// PUBLIC returns {distance,width,height}, the distance between two coordinates, and the longitudinal distance ("width") and latitudinal distance ("height") - all expressed in meters /// Warning: accurate only for coordinates within a few hundred meters of each other function distanceInMeters(latDeg1, lonDeg1, latDeg2, lonDeg2) { + var worstParallel = 0; // assume equator if (latDeg1 > latDeg2) { - var t = latDeg1; - latDeg1 = latDeg2; - latDeg2 = t; + if (latDeg1 < 0) { + worstParallel = latDeg2; + } else if (latDeg2 > 0) { + worstParallel = latDeg1; + } } - var worstParallel = 0; // assume equator - if (latDeg2 < 0) { - worstParallel = latDeg1; - } else if (latDeg1 > 0) { - worstParallel = latDeg2; + else { + if (latDeg2 < 0) { + worstParallel = latDeg1; + } else if (latDeg1 > 0) { + worstParallel = latDeg2; + } } var dy = (latDeg2 - latDeg1) * 1000000 / 9; var dx = (lonDeg2 - lonDeg1) * Math.cos(Math.PI * worstParallel / 180) * 1000000 / 9; return {distance: Math.sqrt(dx * dx + dy * dy), width: (dx < 0 ? -dx : dx), height: (dy < 0 ? -dy : dy)}; } -/// PUBLIC convert a mapcode (without territory abbreviation) into a particular alphabet +/// PUBLIC convert a mapcode (skipping the territory abbreviation) into a particular alphabet /// targetAlphabet: 0=roman, 1=greek etc. /// returns: string function convertToAlphabet(mapcode, targetAlphabet) { - return showinlan(to_ascii(mapcode), targetAlphabet, false) + return showinlan(mapcode, targetAlphabet, false); } -/// PUBLIC convert a mapcode (without territory abbreviation) into a particular alphabet +/// PUBLIC convert a mapcode (skipping the territory abbreviation) into a particular alphabet /// targetAlphabet: 0=roman, 1=greek etc. /// returns: HTML-encoded string function convertToAlphabetAsHTML(mapcode, targetAlphabet) { - return showinlan(to_ascii(mapcode), targetAlphabet, true) + return showinlan(mapcode, targetAlphabet, true); } /// PUBLIC decode a string (which may contain a full mapcode, including a territory) @@ -1995,12 +1932,11 @@ function decode(mapcodeString, territory) { /// the WithPrecision variants produce mapcodes extended with high-precision letters (the parameter specifies how many letters: 0, 1, or 2). function encodeWithPrecision(latitudeDegrees, longitudeDegrees, precision, territory) { - use_high_precision = precision; - return mapcoderEngine(latitudeDegrees, longitudeDegrees, getTerritoryNumber(territory), false/*getshortest*/, false/*recursive*/, -1/*override*/); + return mapcoderEngine(getEncodeRec(latitudeDegrees, longitudeDegrees), getTerritoryNumber(territory), false/*getshortest*/, false/*recursive*/, -1/*override*/, precision); } function encode(latitudeDegrees, longitudeDegrees, territory) { - return encodeWithPrecision(latitudeDegrees, longitudeDegrees, 0, getTerritoryNumber(territory)) + return encodeWithPrecision(latitudeDegrees, longitudeDegrees, 0, territory) } function encodeInternational(latitudeDegrees, longitudeDegrees) { @@ -2012,10 +1948,9 @@ function encodeInternationalWithPrecision(latitudeDegrees, longitudeDegrees, pre } function encodeShortestWithPrecision(latitudeDegrees, longitudeDegrees, precision, territory) { - use_high_precision = precision; - return mapcoderEngine(latitudeDegrees, longitudeDegrees, getTerritoryNumber(territory), true/*getshortest*/, false/*recursive*/, -1/*override*/); + return mapcoderEngine(getEncodeRec(latitudeDegrees, longitudeDegrees), getTerritoryNumber(territory), true/*getshortest*/, false/*recursive*/, -1/*override*/, precision); } function encodeShortest(latitudeDegrees, longitudeDegrees, territory) { - return encodeShortestWithPrecision(latitudeDegrees, longitudeDegrees, 0, getTerritoryNumber(territory)); + return encodeShortestWithPrecision(latitudeDegrees, longitudeDegrees, 0, territory); } diff --git a/mapcode_library_js.doc b/mapcode_library_js.doc index ba8ab903289d4e8a14d4832f8b2d56b7d5cc66df..7652b4ecabe4590ec17d0092ac53dc48f432a283 100644 GIT binary patch literal 93184 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 z z^@h|W84Op^m)Aj~XOd)cg1pD39%UA*`6p>3GiCVBhdKf((+LwVI>429yFp0V7u7GV zN7hvXDhVzPmh*g<|5l-dJu}Hq)=Xc$wD)?x6!8mHI$HUg3-YXTU9iZ~|4w$SUO+wk z)H3XtN`=@uzH%BD2fii2u%~!3x3CnSe$?#fXKgB=EgIz07rJG~rD8T65S>u&9C{#n zq4+u)Pk+0ViY{B~^_0vnLM`|L4Zd25#7eG|n9k5bou7p|KTbs#pyjYdLM%v}9jIj; zbTy``D6ztjFHmW#Y0t#s5;JRJI1l+o@g-j$x*15dgBI~59|5r6{WrYqBOF68JK9N>T?m)=rnLdlgV%6_brdRxl^S4Of zmK&(Lb>&ZlcLJk<@?dT#;M73Tq8VmZ5wik|{H$N#g$}2hV@x7l-!rV}^K)mqa-e!w zM8YvPoRHDwQC6=nofO}^iFq?S?3p$jA)CfL8#0!wWlYU-nDgx0&3E0-YATYO8C0_p zG9|4%Qk@m9V#3Qdqom#nLcW^7(x5)&DVR}!;!_!QHx4JkwgRWu;F~I9*V^6ejL#Ub zgltp5GjqaZY3Aj=N~WWIp=hbO8iyqU`MI_TIB`kZ8<^wdiIo|aRF?W`mxf&mwV7=m z-$u)VOc$eh8&GYbuxC*L!f(k&L4~}}kT5+nt;V`gDo?CWm-xv*)aiPaz|Ur6%ACo> za{1zo-N>xxl8%J9@;XYzU66<0C|B%m#aSRh|2D~=Nb$2|Dd1|dE@_yj({4*b^Rzp?+xK7e#dAfG z(m~6j+^EKJC4Zqx{?J@2`3wKOB!`j5R8;mVz}q+Is1$rdjZxnZfHYOij&btcr+vjH)D><^UHut=9)q`%$4tVUJYLrbN7 za@A*Am@8oYT28bFb*jL&?Cl7=p4n5V{n>nrqdHJmCnNEM+CwWYOBZ3wYJ--(Ml4&) z<+2Tm`Rih}ukcJ@$swk6tz;+R?H0u~cvsYum`#!y5zH&Py6`3P zZ5!sZ==;rKdDPrs%t9Y~fsZ5^=~q3k zz1YY8>PNIaiZH0TIj19$)P?+&^xYT(j?h@o``mAnSYsbCHQY;qnEIcjpMONB`P>&+ zi$fgo){~0iYI!wBp0qNr&T4mMCCQtJDtQd>SoTF&BvnaX!| z@pS9z3A(!G=FXnQBg1FSkhekHjSDRx_!=PlTt=x8UJ(4Vr z=82v>Uf#yFKC{WJahk`IZg0EKE|@&gG<$MdANCk24v*&>f9|t+0KW6xiLW(Jgh?a8-525!=tbj(lQOB9khph7y`!}Kzy(VQakeHVE75#1~0-E_yT(K z$>hUfBz*S4XIoxezva;f9(~}hTh?54%U!E)S#|EJQ&%Ee<>RI*Ag1_kNNqOfx_$sL43HS& z&hTM#>ff&Sxzwf9xn0kH=2+^qgR5SDM}4jns5_}kslyS}T{WBy=fG3&H0*$J$moUe zxx4DVL&t9SeRjAVAMUSXTk9g&+PcePl7oOne=$BW4!MRp>3Zgd)Dxky{DMPprl%T} zwkX1^`~BN{m&!UUl6%~(jA=QqZU8=f9(MBkpd!s-&^dM~okoiE1~RxVNKGtD{yH`QG8E29Mr{kVmAS9t}xy@QmKAXD`)PpusI4D-j1L3}yKp(X(pk z5hLScES$z$UtnF6tS6%ne0t~r9d>}|=7(K%vWfEF46nee@EYuZozR&--!Ta);1YNY zzJRabYZ%|fFbZKh%z%a9hYI)u{N3HMoEnsq-4WEA36{Th4%b zRKGvs{9-5vsq1TC4cq}z=Xb)R@ECl#d*=tcKiK`|?$>rdxBG*;)?8SB;qKbqmAmIn zb!VM+G=K4HQQ3~RBQs9w@rf0AvG4kw^pOs0#Oj88x1X|>x*4;kr5VQqZSe$lzG>Zz znkhzlE!1bE9Nn`jbHpwkTOoe-YiR#>KJM4d%4`8ETSoJ-(Bod zRlV4-qe}0MmKHgYQiz6}%K22I}W|DCkN(!#tP|=fJtJ7H)z& z;bGVSufl7vwi|x%7(5QWx*NtpFa%DAGhj8uwEvy%I*;+$7svK}h%F{eD;=#&+q?Ua zoR}ux%KPZsC~I$G$`>)VpwsSSEXHX2S4VxNT|N#^!PD?8*s}0G$De@6!!#%Xw@myT z_w{fC{043WTTcGKvB=7O@DMx>w!BP4My5as%!M1lmZ7IPejY@A4uQ|Mf42RNmtR=_ z!ejjV(+hXWzsGLB>AK6WyZmg8$R`71+k9oztah9}@DcpBEj&aFFNe|qPGJ753f>wmoc z<~6s!e&Orq$iF|H{`yaxf8zK0?XO3Wj<~XREI+BeWc7poZ&-MUuAjZAYT~!9Rm~8W z?0c!L+&dbNxLoy|*!F9UB-=8vH|w$`JJQIN`h5wcjz0vcU%Ni-x>I!`bwjyJ-CPe+ zFLqsg#PP?loIeZJ2>yex`QUUo1KxzKVDygb16rx&c55}KcC8Gv!yP8Z(aH#7F58y~ z_9aY=-58UCRyyolyXFL(en44*Rxcs*1WNxOENy8sybmA1hp-*&I{lJk`EzgWpc8b1 zK48K?7z`ue2QUeWU@n{hWzYb>hMV9JWS~FT@*y(uF6@TC!#_Y|q@fS810@HeCm;wB zsE0;a0blKwe;>d9)z+AQFMqXxe@}jO*NsUJQoUK0?dVZAnjh-{2$>F zu-pD?9KQ+MK=i<2OiK)ck?`g2k9Tj|{qeSqkKc96HLK5G!N1*M{#EnOzq?r1I(oCR zUADHw+~Z)^XkGMM*DWqMwdFWfDJ=muU7c`Rra#_q?BDY;*R}{`N@U zIeSRYs!s}E*Qw%c&6MuxR^5j=qHfpb4A#D+iwiJM9odNY6T!eg`HUYW5)Bg_|2sVt zfe(}VFsX-ZT_@w&k2svVft7GN+ytATOMk+Qo# zI)bQfkGX1W&LHil`hplgt9Nj0!rsybM?nEd-5+Hd#satn?uQ59QLtsc77_yXTl9&xA}D(-vjQpe*o>g zBMgTTaOVJI2VQ{JU<>>MzJkt2qD$bjZT#E({4lq;WMYLbFeRtRw~dKMZMpSn488->c;rQINoySG{z^n z<8^nKO>Rd_81YCK+kNef%kUc2(KR~yofUDp)@GRIe@H)rug2=)L@YNR|fAKE={`$r9kKcXs zuWr8dyqhn*d1YP2LfUow&(W2VK})+^s$HIml+Ac5+Alc96>}3+a8p8Ww7b`@ zW3G-hs12um>Bqu}`l3V@A-%y5kG~)$X2)7{QZL0GlX^mR&CX98ie5)s>F!~>tiaUFyp z3@5{Ba2>3H-@{$-AUp(rg}31y*aq*z2XF)?N-@lX6JRl%2s__?lEAwhc#4jUz-iOI=Fcx$Eg&-0y+ZSAXh7>TB`Q)Dc_& z_rY_}F9*8;CO|dR!gg4aiyKacb0KC75Ht7leNElOOq|3dC%GeenB+dmW7`*>n4Te4 zNoKfLf?0OG^bL8(<5FT;zZk#(^y(B^+0QEi268?)>PhcQ!tC|5Nv?&AO}kx9W^#6$|Hl zHRmgp<5){7rd`CeImY#tru6rls#_kC?wI_t-lt_BVzZiMG)zpKE%{4vI{wiHMrzwH z?xi(VOq-AKiOC1;ThAOt`?hb;k40CmDp5cyt_>p+33cXS(q1owb#NbaqOE%2Sdca> z?Y9X|hqFQ2@+FYt#ny*w;a2zx{t1TQ-?nU! z|LgBvcki|9)?c~)m+LQDf96F$xoCYuVDbFL^J67mo~-_&rURuZTS}82F6yQXDR-l9 z+&R}YiP+Sthv?F?YF+gSx>oY0bvBHisTnKNmdNeeXQWtTthpH}ovl-joACcP_SX2a z>}&bUjb=?tXF*B2aRSK1jKMnKXisHZ9tO1;d$w6P?xY&16L<5~Clbp!{d06K+`|@o z%pzC(vva2wt~gBUb2a<|_!zly0Cb1LAPc09N5ENdHe3XkgVg(P;U0Jxo`jd+E%+Gz z22$@U;3kMM`FFajHMt`uOe-D9V~g>5&z*vQi6bUCF^<2w(-t#x<@S(c^_0(=2@-v; zj_4KQ*Md2-{mpxfK2kR~!$Y)3X`|9UJLWS#57IuH;6~U6U5C&=z#LcwFT-I&dA1MJ z;3T*Z?uGl{L&zA$Tp-MZR`!1})|^0GJFrJmf;%Gkc$%VJl9tNQO` z)xWF}m-T?wI&o2w*2pn>q^|C3*YPE~p4YO!7v6=B!LIWGy55V~`$6je29Wwc3Tzoz z%(2Kp2v)*H@C&eI;(3lmF1EuzAQQRh;*yc$Ii3$szc-OV9SEY!B@}`SrB;`1!drelOO~u;5@hh?uLiqd3XU*#*iuK4n3eJ z425AZ4hmo?R6`B?6n+M4;Cgrf9)y=+6KsZ8U^{#c#xb-5=nRL!m%CZ5{Qg^8`1k%> z8+X37QysjIL;kJ*^8@qIYT`<}KO z^`$NAwHsWAPkM>#-7eyZy17z68IX9yvX90hHgeQOOtvLy>l&`EJoz75$4r#E7zt7z z?z)gVxC^8nr2P4VHL4Dz-0kv~a&Ckhz%I`ZIW{T3!(lF52p7REa4Y=X-ERIf9a62% z?>o#w%za`U+nw8U5R-zaM|1|Dxz!h)5k6RC-L5Y$$5LlLsDz(^)ZbdT8SFZIfa8Z? z7kma+9gB?*smCFUU_yTw4!6SXumN6z!^h$W55r$zH+%`5e?Ys2UXTwHp#+vdEj$Pt z;e9a1p+n$s`0SHypS{8VPhS0GBtta)q9P#xtKm%;FoAg@*aRm`xENw2bT?Jt{E|Cj zL_FrQ7@s$ts5to7JDzhVXTKdp)&)s_yq%G9b-VVR&%C-_*E93}c>?nj&<~?FL`-{3*h&cz z>AG5nh--!T<@Y!~v0r>Uj9u{*TCB#x}Y3_uoj+!1JDJ1;74#aY=OVSxLM38LN!F-68IJT z0XD*cv(Zg3A5Mf7a4tLruR+G~=zaKn`&%!*_4)SC|NQwMZ{Gf^?Vm&Zzl%8g`Sz8H zmD^WJ3!{9#ICyvBx@@WJ@OyBIy}~oDCSt-h_xsJs6-nzfLHG{U{ReKHyxHw|=0C*|lWKROIqoEu9eO`AUhj9=n@yNR z|0n804w81W08WMbK+t z>jNWK+NhNI6(D8)E08k38l=px11a-c;kWQRxCicq`#`=M^C$S&Exqr%9q+mw->%QA z?x_FbcEsGYm6yeYiOG*U=6}U;MmOWYGpka543*_-%CBQLqxYF#?CEo6igEB!Cmt~% zt+M>O*$>g=NM5>(?$lL#*A!i)E!_;afYhe{>?t;7Fk05pKuJ6C^`1|%9f8Vi{ z-Rm#?E6U`5@Sd@H$<|)z4O^$V-iEgsj_;K+4o=XD!WdqbyH8&dxV3;n-5%QDK9sgwQsZFus7#xL)Aw(Cz%H*PYf zuk9#uauA?@_`~(`&ui4EKS*E3AD=Jh&(VANT>3>u;8A+pnzz+Df3U1lmfVtpwUipsfVjN}#O- z+Df3U1lmfVtpwUifD$-6wWraIX~V0G&N6YRf9diF!QnuTlVOMWuJ&@@@AD`5{wBX~ zdcDMLm+d#X&wu;1<9IBzb5E)<&gj&`&TD(4h)JT5nmVfHq)aRI=8q@zHWp7wN%yg@ znUcv0x6JeiEHYBYrEtw66@&Z%1fDJ#QG3696YK=<6H1avy1$l2jAf@}79Y&8e z#~R~~G7gnj_hga$^eOTVS1RvtrCJ{aPF1gQEizJFamxop6U9A5#hn@(cgi7F-2L3~ zvY_w;?jV2GA?`Q9C>Zz2o@(tKn>V?a1RFIE)qne2^)0oY12rAXKjtMi?4^jR84l%JGskn1Jo zJbguDdLGX(Qt$3scSMRvGc}fq_H5y ztIErYp`)tjN?l*|w1ZNe0&dCgPdt-l$tKwuW9;E4=UA#^Oa>mc8a!S#&VsYy&(J=F zvV?pX0>2~a>jdifHuwTYP+Qe-Hk<=b!PBq<#!>GV!o%<>?1D}0d0q^!z^m{Y?0}un zxdZ8e3b+IwgD>DK_!`Ee2n%64%z%a9hYI)u+zA`tc__%_dYA|E;T$*@*1}D2Cp-)r z;8l1H)*gT#JO+z^Zf%TfmQGj?1n?pekCB^$$c3%0bR6_ z23z0_*bPVYVx1GnH#XP7ZSWX84j+KY{ChSGg7Gk-59|D4CCIlmZ-PzGr7!EgU^e^) zZiM^be)t$V9gMs~AD991t-#;I2XGMDs|ZeoKfs;vCwKrh!h7%)bUB3eUeFDWGFe{) z(_tz63Z8=v@ID-TICTv3Ap~pSZFmQ^!MpGt$hW5Y_op0S@e!;Gf(zh2cn%I6z#28^ z463C3p)yhQC4S zQLIyfo8V@6Xdu_ZX6Tqj8->%L32uaK&^4Pff;q4XUWUU4vEBlv!AWo-+za=?hmdhJ z^#U`YLk`bsVMH!62IoUJFL{C?FceOPQ{YN?4mQB2um=hU^DGD|;aa#3?uWm@4)Ekr zjxY-Ra1w;z0=NtAh8I9O*%asr6>&F~6*2qvB8;V>62gp1%7xD^f`PW{2E z5w!P_w0D>?n(}~O!^_ZT4C{^{0IT6m7;p?S0h{22V>yNs!3U+V3ND6E;N9cUp}c>v z4&H?+C{$So{}N=4qrBh&=vY7q0ZrDu-7j>IhA}(qui&{#%G|X;pCYd7xCx}Ho-BoSXTv?AJ00OIjpOK%is#Q z5`G2$2Uo*2a2>3HTj96xJGck#h5O(ExQuEtq^{)Gq>*F9=)c`BgG{EhD(});I={Gb z`Ooz0O?Fb9ytkAGu>zc5T;ALKbjj>vxiqy9t|hK zeLv;Wk_>(q_0ZD&z6-x^I}feb$ugR8esMbF-_~DK$!48RQ zWB(YU?y~Ces;f-$j|Oq68WWBktU2&FI7nB*RF+d?OX8c(1M@T zFu#QN%WT04Teo5M&@=MbGlwXqe zr~Hz%KjoLC{VBgB?N9k7X@ANuS^JZ6Ng~%OToSofeo5q7`6ZES<(EXRlgdQAP3zW? z;+L7E-fh1`^=|tms(0HjQN7!KiR#_RtSjwcD2bj1HHLbBE)&39Mg-CoV=4XkDOdN_)-tj|$h#(Pt#T39QVhJT&vO za+uOWxhTJ8;dB8>xMqGJ!Z)Y-qrYFKl~13eR_ZLdnE5~WU(fGkoET( z63*JZLN18802>(EOSBvS@o3tHj{oVNa*{qGH4awiAlD|_U zf2-nFZYJNXmhYCzw+kh0(gtK8#U%!>2pC*uu(V&^jWWgqm#g=prm&v|Gl1X*+2buR zexyOZV<^@56=l=^DB=TozpDF!9(#J8DJ3t7lTs&fh6z&Q-4Fjc^w{(Brp~+~A>~12 zJII2OicpH2NSn10_c-Iwon)2wwb<~!oBZ*Bk#zfIk738%Uk89PLvRUo9Wvyrw# z62|MfJE$|xXYP;)Br^H^nrnFX>$Ftk02R)_-H!8e{do4>^!XId%Uis~M#mkJg$KAn z7vpKUjj@MqhLN5og7$;76m{>e^2V1s+Oy|ej@lbb|2UwtygIqj+so75sK(V5*J|ae z(SAJ!i(jqwD^aeX_FJu7b=q&Ea-F1IJ@O=6NMBi^Tw(3ETDc;2IOVF>u9B`2ZkZ0Z zTDcnRE0t@xcJ=5cS2pS^OO$Jc_FJu7Ke59p*U5Ic?h@`4JDhTzYKK#<)3o14l{0ra-FNM?9ofYou~aulpFequ-{0yHQFztT-R&AJCy4N zJDhU;#twI*gu79@BFeQ^UwMae-DHPTuAA*}YbD$*b~xp_)efgzztw)blrU<0qpw_fmv)sX*WLQc)ynlp z?YB|6?$Lfd4wi8D+ToPzKJ8kqT=(lMH!9bk>~Q@g+ymNGqFfJZ*J|Z@2$#}X%Jr}v z?hpz0h#gM39<{?M*JE}#<$7GZdK@a@{%nU+t|#np%JrmnZB(wOw5!Kq67FeSl9m$X zT5pF_u4lC0M&)|e4rfZZ=j?FGwZRUjT+eIQM&<@(4Dr(7T7lA7+ZM#BBg4yRl@>~PApQ@f7+xIZ=h zi4J!%E_s<*NX23n7SneNJ7AAy9F|5S+@g7a{now~@3H?WFWd?T(cvGi>4Fg`%!Os} zOU+L99Zic@Ff@cSF~EesXr4HlKjZ)#;Wc;{{sy1J9?i*Eg!0GNgeT!SkUtKlz)IW< zZ@`kV7Ms`$c|YKVN6kw16UMPf^%$x`pYWhv#W9YCLmT2UKP2t(87C*y+6sAtMH~?$1hvr%K!WLMG zwJR(rvRKUiWca=2UiPnR#$y!=Q{Ybc6FdeR;5B$#vk{9m7o)TmWMC=3ROC#yVh^UO zVMD5zfE z$1>rWYRJ@PsxpjI#dgQHkJ|QC=MPp}#vYtU5V;aDWQ(w|HP!ZTwe7FAN2u)pwLOw; zigA?M4piGLwM7^?KS*s6I*xPLrW%YC*m~8O!RlD-=2SIoNl^oY6g7NFRRe`oHH1l3 zgPBw{Y)DlDnp8D>NL2%yR5i3oRfCBXHM~hx1D#Ygw2+UL$lVLnT@X+1gPrfpFt*qFDyWa zSHk`9sAe0&{E=ogVk{hnAP>;=L7as}@DsR7vx|Kf)8ZY3SGXwKVk3LuX+-!h@Cv*G zAHi<;C!{0T!r5c^<5`+#*~=fXd_%M4IKpYpAInSs@TO+O4|v%h&e8m69OFgJA_P{L zg~$r)G$Rn+pTO<#nkENPUJZYTQUqFf1CB(jb6^z6ACD3Wp%~;300~(L{R!X)`J+C< zS(=xo@}fOlLSqn)pKc+4Q05@bYwWjb&Zdb7ClnE%<_z}tz{8rY?1f1*p(4$F>>q(= z;U#zjKG4V?yBLBlT?V#JO+i{xAq~=@9khoIkO7&1_@F&g)FhdQhBJvnwL2e{q3Vy#qH2`pqR5@e9g0-xt77(|t3*@H=N_V^7Jz7|MIhQqbkmRF1Xv6wf)7fe49dX| z6;KIP5P&7H6sn&WUb01x|(2pb1vO z>2L;|31`9Ca1MwZNLfi<1~t`(YR81js{A#+aBfYYEEEg}D z7m7rDmEp{$+10)>e@SDV-)NEuL~-v!1Vz3YB9K}X-S|x+NN*|(L>i4Isr_@mVc2#} zb&`6cNyI{m;hWs}z^1ZbeQhMvm>cp}27`l32SO+}E`1>%P*8UnJiWUpuzu_idhw=GQcj*?q=+><(+4Z=PoN8TZ|j zg|)7?eBIZ(?`s{q&$wet7RoI-?(3~%cRJlMyU#Zd<&M*xs^-V;ux?-LywsfZT(_rT z;lRi6Ipm}>tq&t%DwM)fkWYVYhBx7_P|%K%8QcW7!rQ3Bk3l}w^(Z_I&%!ji$P)ND ztbt#0)2rdoj`U`55nKXq!26I*qaFp9)0JKao8dj!+L_Oc!9U<@7(8E%6+Kt89n5nh4UK|ZaOL05brbOrg$)>xPTlVLhtbO~&OPvJ92>qR=@D)=Kj z0uLWV9^r5B1)SH1Px8QJa3kCdcf)3QAJ);$-viT4dN~2!0{6fZ@GNYAEih;RJv@wpNiZ2sfI0|41DpkC!>{0Xa2xyy9)Vs* zQWnr320{)D1Nl_dGa#R*x&$tT>tQY23-Xz&0dORYgwZeyiop-^`KlY>X1E_d2hSkn z0v3ZjdI~}aR>C!~2IR9=&%<9}D{O~4m;ULI{qoDwb;KvY#bKyL=4CIqnH^VJ(FFXma!xs1mx0^d{S!~ zOo#cf5X!(0OW`N*Q}_j}fg9lgcoJR)`TW+qAfMjy!eA%{A5=mW{1p7dkw>@+gX22* z;b`g(8sJp84eo^ZVJF-$hEGnxC-6CpIEF`Y@WHY8LoY0!Lm>jEK+0I!B`k!+kitkM z14^L^PJ(4{6Rd+9u|L+q-^C6o#L@-%v%`LIS`Q(@V*{_y9{bhgVs~=;Q z|7Ozv%k%eb)m=MXPWJxWiuYd`kJNoS<8*5;#};Z}pgwr|EK0(*biPc(ksh^hY|CaR z=XSwG?Py`}2s{P0MI#o>^&lS(73)Pl9y$W#H8ER-LBdU-|$vgy{b`<#lu{@rISKzPEDT|&Drob!^ zi$tsu+Y)(~L9C5k@HOlKu{h*Inqpse+&brB6D!fG2a`}f$>IsRW4W+pfEIs4VrdGS7bc&=G~+OM9Z}O7ICj9;WDOrj9hLud2T=MWFZ$iI$ zKcD>8J>ygqC_27- zWVOqIPGnsUB(g3C?q^ot?BYcDW)~uSv&(*DbzOHSvUS~wY+d*L$ZAtBC$gqqMAp=6 zKeIZ!j}zhSK14XX&)&28tqO30$l3(BO@L8FmY&<2TG|Hzww|(St*LiuEofjAWtx5f zCMq&rDazR32ehDbqgq=QO?Xx4)YG-*cSU2xA!>HU9@PmrYIepRcO0_VK!t8f7Dr<3 z>W(8#$B~{ij>JmU9Y^|J^CEgw=f%;Zv3Y5?*SsWFpYC+D-)mkHYfX0?9rl_Rku#ka zM^VP+B}2#Y?RM~O`mr+|y35Cp_RIQu~3snmRQBMJnl#knU&SVx^@<0j+VzA2_m$z zx(@=JsE4*X_{5_knv~4mS>0;#E-~>4$lZyTjg!`l;GYuY_@sNU@^OFY*j)Mc4H_t zd6?jK%fk$}TOLHX-NSgm;C9R3+1&e2Qr`TxXOEnhzqXv2o(An8*>P*HDqV0HPkuAg z4~EW==(x3UB}(bQkyCTYJa4%U9HXJ8_MqWYZx7-U0cIfV359#xH6* z7#AFpVSL@QqjCJm?nZuoZ=+(|VaD@S{f&;JvW>AhgNzPyh8g)aV+?=4sYaSP!`S9u zV4N5Fk#XAWCB}jigGSTBlZ<;$3>)kH^+rG6a`iV}hc=#RT+`(&tbW=jLVFXL$5MEpMHb!;^?);Ba7D>Yr{}^i}8PBZ#6DF`a$E^ zh6j!7WEWO8$6qbC1e0^}OXb12_2bFB zyk;PuJlK)OnuT#{&vS3J|B<-&$Y%n0hB=q@_Ddnin)+IGRtnwzSy#!`GP|okbKp8| z&xMnFts<(_)b?rZ(%Yq`rSBPIyjif^c+hS(>PB2w!b<-dR{w_$llP+h+|T5_f*|L7 z+?f@3#KU`T?NU-xIIZkhvMt;*$Q`1zsByHA@ z;!wYtDrc4YuE(@j`O|*Ru37%(lTP{b*7l#d4s&ULnnQlZxxI}Y8yHesvqwKH>E2;r z$5DTln2J*VL~$3RTqm;b&3d0M-AL>5bNph@${G3HmTssoPuOX-&bDn^R{|Lwu5NdS zafh*TWw&9mA>?gNVSj#V)yw=AM}oOSy#kv^Hdn?y)WynuTJQ;PCSh2M4@!z{jg5N z*$Lg)iE@vzS7Iaj_j7%XYHqLohIwq-QgFU`)~`SLa#mHBn=j5Vjvn~?%~A~a;n9`7 z_^$#HyvraBc7c*XJlk>Hg}tcze(XgzXR(*A;#l^g>SwSQ;aR}`0QSq-OW~c#o)vV4 zsN4hDU&X#N`!(!E_uaytRdU81?B)Ikk&(Dn zzVxx=VRpbD@rRoGxv!JF6a_;yzG`oIFk)SsDD2Ro!_++(`WrLtm&nXn>IE`$elS$d z`Eg+EDy#Ytc~-|Oe*A~)4tX|39gn$t(xmkpQlt*>R&^mNT->7EW#9H|D}lBWXe)uX z5@;)dwi0M7fwmH8D}lBWXe)uX68PUPfn?)<8CR#i_{@t}c@OS#=`R`o=Y09w37l&e zckW~coTEU-x-#~x0vW5^9`Tw_bZmmrOQ5;X&reGBX5g!C?-h5l}L5Mzx+Ep98AXKgP!DwS@t4UMK zYE@9{{eB0pc)wqfegZ#&AH@e>mHz&-yCG(!>`FkyneyA&%oH~Wd90*d`c}(oXAJjT*j|0E=g_)ucv7gmftVL#W6OqK1zq66YFGnnp&Rl*=u4ulZhsO*(@ULg zupRoKeydwuFHp7hG0Tl2r)2Q-5w+# zgF|o_j)1ngl`rNf9E0O94kzFwoPyJE2F}7cI1d-#B3y#Ya0RZyHMkBp;3nJx`E=xq zxea&VF5H9r@BrlNc?gd{I(S0<6rRCzcmXfr73lgK^0)8~-opp@2%kXLe*{bfpH(Jo zimw5MQ&#Z^WqI?5$w$o_gF<7bxv5M#l-5d}_GvAq<`=)dhEgqkoBy>>aVqldjR&PJ zBfvAGpmtlLla5qNO}_dOr}9?aq{)l4n5ZEIo|VnW^UIPPXCgmMg?5N5e+Tz&(ZD11 zqWw`uzDr(Y^eWs{&mnG_hkR)~199c6ZAXKOlp#1)QWZj{XP-yrW2(Z8WFvt`zNIwB)sl0{LlXegzbduz7jEnQ5c%rbKTdUT{WZ(pw4uAYK&fT578^4W5%(~U$fl6uE jGyfWH=uwO!MP^Lt+zGEcxzzWi6U}_r!}r$a&C$Rllh;W+ delta 15421 zcmc)R30zHE<2UfN>oh9OQ5jAdO42M%XdscH%u|#)&65UYJTw@JN*f1VRFVpzP{wPz zrlgEFQwViS2qn3f-rqW>b9KA-`9J^9^S+fHbau*w zY(d$mEVN@_1Lu3hgH;<5>WKqzfAdO6oOyR`8 z{HSp>iE%z5u^&XPv6Cd+_@%;mLgYlV(y&fb6#t(>^)72h0);93+PPfU&>HiZ_afvN z!a9VB2*uNb9SJGqBacD738BlbMyQ7{2O;gchby&24LQDKS&gc7Z-=(oQS51a`qSl zgHQxC=i=qMhjcs2a>U}#IuWm^`-*81bnW^NVi_r`Vd8ZDeX?j~y1nm+UK~kC8GAv- zjsI?R*VParu3X|d`S!NsRkTG4JMs8UsIUwa;j&SLbXJ>i`UwX@Xd|&h4owl#%BEcg z=9`bT9Cr~7i*rneF<%cNP5^RnL1w0+IHPp*HJU;_ah|$|;yU=^fGQg-f#nhW%bF9X zr~6vE4~tUyqa4Kf7Ki_4I{(iC6ff}qDijxB_XPiSSb>lqBiIX4qpW@mijpoKrhC2v zW#boH46lS^{Ed+$A*4jYba_wnh{$l?7$3TsQ11vjTNF1oFgk!66TyuR z=UQ`lanZc6sKD?rZU`?rnim;m#I6`+gw+&|QtU5drlCkXx_2|OB@zpEFp?UxQrX=L zedwUqcc$2PzO;&k8X*ag2wUMRdwZi6>mYDspRQJ9O@j3iT9%ju-*3b+nFg?m9^Nje!h-TqepxI~wngwx^Ml5F4fm$^)91n@|Do z;5{tGv2Gdo;Y{EU3G|ErFQ69a5#+0QkD?))6{OD|@>672Mxf-qPy_yoY}#5&VLWZE zXdDfz)@lpqtz2xzr`azD@zx(9-Ux4?3EqM@MPCtTkRoYN1U1kGT`&Ms7y%A24yM3N zSO~rl2U&0c`XL7cdf^l-&K}LuZ|s^#3zPQNcdhlbfBv}j?qB-rtryXsZY|ikam_}= zgduID?CNk$b|mHTQt_ba^DJ`lcqM#8FJEt!Z4VmObOK_IzpxBofutrO`s?9GS zTsx7!Ge0>$E@*zxMEi+BSedp$KMh)?SZFNsg^l2;%XE%lD`K@|bVL)`HQ^f4qBxty z)8fztSdXZ_tYvID>%-$Rs;ui02bL3O-T!S()h|_LRh_}HL&x%t?LL;bd*iBb-#HUe zZAbY!tkcqb_H$TIna*^x<*_z4OTw1~c+Olh(|Hh^oubW7;rp;R`4+57f(E-Y zNt@ldVgQU9JN3X7x z9?D{q*yZf2M`6B?Ud`<~NL1N18#LK@Nycnxk_ua!)Q8<3pCe4VZ9*URdy=uE-B3d8 z!5_9m1@tx|WE40+00hBr;5Q7z5C@5n4qw@9KP~nh_O`UO^Vo>A$s#!BC1bDK#gSnT zvubR0Oi#9Moff0b&QG-DpEM-o5{S1w3EP|uJn#dWmQ}!qZ6E-ewjGcKx8MoTbQ*vm zd~SI0Yi0S>^PPR=;eFfpZ5RHeEJq)_;78%JnH)Lk-ojmhHQHdvT5Z_Eo=7xCOI@=; zO6wH8b=RB?n z%i&k3h8M8X3{?Q>kO%wWB)o_LlM>e3|U55Bj8BL zg3e*n2};DQ0EPE63X2vXEj&3C%vcZ?9xb?6T?&g96fL0podqN=99l3NL0A?Vh|q$N zMh3;1ml}>1&<7`JQLPJ4*4rkt_Gvg-r={VftjL~AbK=u7xd~Np8}7hesD_8|5?;X@ zXad>cs6=oDHxNK6oPvv>ZiQA1BVaVlf>2lo7eQ$RT0EG-@)3kjb|6v)C!ri}!Y%j! zAK?!m*0>q~2~Y5A33mB7~+JuYHJ7|XBz(%zl+-mhL(*8 z6c3?^Yzvk7v-RM>@S`1Jny_VIi68CEL8`N8Ejx>EJwj!ahPe355MKr;Mqw#d3`ay< zbl(tnL^04}qQ#R1;v#yBI4vexJi~3+)n0v=_bjtVi&fl%-5)MxG_qN&r6l1Hwt_VX z*BXvFX+d@^#0?le4z&Dk!*}QaHCr6TVKf9oEabwkPz?>x&kjdnm-AE5zq6S+jFyqtBorg-Go28qS#VS=m73k*8z#PQM2t+&xXmXMv1#)07 zoP~36A0B`>nT?3I!gr8DvJ|1O9U81S?M4_u)4vdSkODL>`=J2D`8kXD&+rjipu!%B z!+pIyxWiQ7L0fZM^P9FeZO!$~wW6RN(fa0^w&t39_^Y{guld?NmFAkuHD`+pi+2@o zE#A6*D_Y*L9YfiG9W&XRJ9@KTTh;$O7@>W2-aepxNz1Mjwmll+$c2`6SueBmz(ka~ z4q+-8P80MLYJuRXOu+?c`O$LAgk4Y!=ioX#f#=Wyt?&ifK^M=*EWi?` z0Ut_$J_dRL^)6_Sa^rB$0yD4%N0VXAVgALdM z-BdJegw2ovEYQtggG#suG%4~(h7NFnCTk>k0Zra=xC0}QJX?r{&Ls26Q4E}hdT0hG zq@R9%x>+z#e!A9bk+6jE9YI0(v5Eh7cjlBMv+WTbe}G)AhII-qm}kt&>d$ zcD1Cn^l!pX_rA*x#M&e=b~v3V011cO2y*9M(ZP z6haw%1qBZjFu1^aD1s)CnTo~@DqsaRa0xs*dy7B?E7rxg%WchGs zwyis}+m5gdxuQ9tDQ|;=NT~%vOxN9L?ENc(*ljpCfC!Z!&1JtM-ZR zz;z+NN@=~SX7 zz6qjJ=os7xVZOXs+BgG?r_mvdCz>>aH-Kia0%!)SfM)P6&V zzIILY7dAUc3y;&f{@z}#MQ?C1wlmiA%U>5cm#@WE$ZW<5Lzm4hu+2HBs;DQeK~(Vy zZv~#W%a$mfTQ0%3l14lKH_S1;H&%W{5*L(E2cJQjgM&8=1}kuZncxRYU@dHef3+Oe z%O?gBxQNEH|KH$0UD1EO98P8bNy`884R+fe|9@Fj|89fUD81S61!Pg8yQWiFUU;KKLNaD*DoY&QvN*D)*NRX+*c^my5 zFt-$OBjF^1eS6*p(Y%zocV(UD_ zh9S;FYNGKQiQlCp0x{an#5|umN)Y~7ThD)38_mfgEEB>?UevcXCc)g6jtj(?CcU$h zC*v@khb?l2TMi;o*b;piuOOVmip=n0=U-g!VL)biee6(S42XgGY(|usV7d|3?2?AX1oGYFV}}_t0h?3p zoLA}Z^CEH6v2-v^C>wrBi*HJXAT^GRDYk(v(>qqI!5t~_7Zx9_z!(yWo)#VL+}$KO z>PVw3;<_aBw}>f!AcnUEL=E9Q=kPGRdW>E;eQ5+Q%F{S5H00ps@}Ntm%46G-z9&?j zsE#~ku&?@7PMT-`lom<8^wN-&>H)fwoIbYowKLwLDv=b%xpVVu+s*v>{jWH_H5*)C zaOc38D*5YQuXxOAsH|{Xa(Kp~ENST}vl|8sK3jD7@Qn&HucTkdFw^J)FYA%sHP@iDG$8}86{g?cL@Z>_v zL{sY?Mp=G^J4;TjcRs~^GVN1}@w{u19=GZWVs)Py$-OV$`J49i{>tr&E-y@toNFsT zX}G$iwDamLZl4R?^~;sVPYvE&^MCnE(-d-`W5f4bmY<$Ipto8b9g^LOYu|(Y_2)6g z3P(Yl!U=z2Brhb&#F+jjrd6Vx6xO{@I-78NrN^C1y$3BZ*_ZBYvUeqUVZaa2(|N4( z=JAxP((WgU-!My(*-9728~P^H|w{% zZ9{6uz8N~0FE3&J&&kgp(K4kRmlY|vg3|n_{+|-8GjtT ztP}F^)`^FcoSJf9Ee=ULbUoG5#iC}D+?ot~P5FI+4bGA)-#7>AxMrC&9DZoU-#1B@ zpB?LR!rmwCbmpL>eZGn*mbPuTb}T=9tM7Qh;U{VNQHg4kXFrKZ5y%%Mywug%9Cs%o zyzTVKoo^!6)T-ndT~UlpJ-M9Mc1g*2Z(o&KSv#-(pZea5aMsPUYq#%z(X>`jt$sBk z^k#;vob{x^?H=)|7sAJU+UJy=k*2)CldtchQg+s?AFF$7yx`hXPuutI+jTYP_f!bH z!xkO&&OWmDQqGuW8>N8SKDv)0ymzbEy?gol#TbKH31iDA@n54pofdow@b@0`i{`wF zq66PGm-I-u?LEF?$3*Fexx4F^Z}qEN$mCaFjw#$VVSh&ZG-BE3;)H3&r>6WoBmDR` zshN`eed{!zy$w1&-?DjU$4BY!{u#+L|5&*q`8y-q$-F!zhDlt29Yg3`HjtruozX%{zUOxrle=*0cG ziSLf)_8@Y(uIbe(pN90?t2=%1Y6Go-mmli0%JSj-*RJMul?ODE@t?(Ou^`LOWU8=EN!WMb=yQgt^XeTuQoBhv)^XN z<;*+#{d>yKdsa36(fY^fU#FZaet9yr zI(^MJ3rESmHTo+2x?3?Tnw~6DF`Afk-Zxd|`r|n*&SRoe{On&CxI}8Ebfn5EwzS&h zT#FC(wup~aP4BJK+}O0+v8>l%3rC}Vhm$rl_FfxL%wDwV;&2;*X5DwA-PQV2{A}N8 zI*mJVQc_)~{q4=XtV5UU%w>-{ei}UXsDoM`pBLAHo0NUZ8{ere;$LoEt)O=0;cV;J z4R@U`YiEqo>V5y1`J(|UuXtetWZSJ4MMYcWNcKd6WGUZAu?LarHVo_s-!pXR7b6a;V?DVIs%o zSo@Q48yl`!*(o@wPYSK>x52qD|96$qiK=67O&T21Ea_LH`?1f*)wPEj&N(01{O<1k z=T-&>CI`;oe!O9H^wmd0KbLQx>!LRv$nryPD7YMBzgsLaz!r+RtADwC)0Iu@KNeOmc`!I4?o ze8rE$N|PIAdWJsPd+7JiX4%K|>(t*z9gnH6+Tr5ad&`o>9UA_Xi|;D;e7#FSt#{e@ z_$`}Q(+_eg-X>$FRX^+H+2DJzSCRgc9p*hBuNofGI_yKVX5S+oU(4ni-57Uwy1ljP zfe-O}HeK4g*7f$*#zqyRsKeEh@9q7VvHI9b9o0v^{J|TFlg7l@7$oHOyQv$XsT#z4 zpE&mE#hk%UO{N{cAd%0Tv*r*hsZ+G}&2ldZm*z1^2K}zv?<-i~H*3%*PrqgJOgG7| zUU|7#V&;w_x1xCh{aJ!-kF?A~)2nV&49wQsyR5g;ZCR7TX{o!Dt~{0g_+k};EEmj(2G3M@CyR}zWS#Qj9x0@ffRAtxs z(%8EJJs#eFreCN%;i}56wE?$1qRpnfm~g|ww$UhM&5{$d zEjZJAT+dPIIk@;jqvP;Xfe(gH?K$uCy9O8Y$ejU2%kr`fi-RA{xVhc?q4a}AOV15H ze01*G-jWS}^u@du@4&_OmZvRfj!0;i+A0Pq2SIf0X)4yNjNI~j_uV1(y&dPeU&p?6-nWibY1U#_PP#?Fc+A*mYga$GpZYpio=ZwqfhyofksOno=F6 zYEItp(9ZXWSA1&th_@R4o81g14IVhvz}ReiWKaDG>`zt6)7w`US?^7o`ATnZp5wLC zRjzF@E3-aiGAn)=cy^KU^7}+) zoE!5_ox1!CSrc8zFcQP?$>zVh$i-}3x_`Ljb$9#g3c6qR{kb%s3`3E2xd`mOWcRD6 zKbIt$xZ>_|H6^;T>QV#U*VO%jMz|(=cZp{{|FkOM^-cGcbZ-d4#f3k21Q#m^i?a0|sTU9(9bs!?66J%7PVXq= z@CaTQrul_OhI&V1Fw)<|H_|&cFpTdX8e(E@YHDQ?>Kz!S$6e%aHc~Gn+Dwld9fz22 zFk*}R&FMIEIu0@4V8pzAd~lP4IXWZaF_lYs4DjFe<>6zf|ARaH`si+1%MWJ!}Wi7j<&4!P=v=O)g z{k10{zub1TTk)E!Y9;`bB~7gorbY1-zsnc)E`penRkI zo?v~r+r)cGptqE%ig=HMgwjtf=_9>HB(P)vUfCdF^eZ0vEeCx`Pv4Hy_jh`D_COyQ zixY*(#0)IJ3as%BBf;BWG8!BK8KKWBh%1a|KYUSB{5psb?qK8v-m!h#?HLX`x7|kp zI|c6EMcC`@a|Q2}n8cBKxNRE%gCQMQcn*zVh?2H}oybHkJc0(ORYGY~f?Q?h4gUfP z{1VtBUz2FwfCv7t3f99mxCrHN3!Z?%Ks>AmD;NV~VLpUG1jIlBBtj+}g2QkIE`T~R z+Gh}+XmSx51cqP^=W$FghgE0+>9860!hSdj$|!t27y!dz1WW=C@PSmwg#tJYt_H?4PC+G9!82%tc2FORcUdq3ZOjppfPRye2lRWalTZ$~pa!17 zdyqi&tAhsU!w?t^6JZ`KhP8bBtb=Wk4YWxW!b!LakKqZtfp^djUqQ|kEfNO6K(GKS zaDwsR4G|Cvaj*`y!CuIP5;y^T@wZ5o7^s0Jcng0(2gslS%Yq7U!3;)&D~yL3FbllF z2LfR!B*PZS0s2kTS-1-Kp&IB%Vg1cf|3=tlhXMT>Y$5Q#50YUkcCKu=i9P2oq+mx& zhy73lFQ5*zu#4*g{eGhc^su|@gCB%|HjWy)-~y8&7Y>2hDAd0-_S_AS24>hZtsw)p zLpJ2WBX|zgID9+@Luc%w;0^TagRQU&euf(`a10?vFbpigb}Xs}c0w*3ffHawUl-d$ z1S|#mR(J+@LjV-QQD}0-dopN+?=WgSb~z}9ldyOK>KTT)VS~^FpWw(uyg&u($=FT7 z55gb{Rse53ep2BLw1CAF94x^B#=}m?fooGmZXhi0RDtjoRKaby3-{m&Jc9;kg7<R#Bx!J&>;YsDh#UM+G-f+Eh(>(6ON0Ki!J-Y)_9<>}4bIq0=@&0M(I)8IeqXeOU>Jb5 zUS}?+vvDK8p@VK7o7%d?o zEh)v3l91$d7z)k}l5!FfQW6|G z+QyDCQ4-EADr>qLL988iv7UlGc8o3GQM4+K6gDd@iB(CE=N$uylX!c3Xj;)Z<9T~1 zUNA)BnY%aP;>ySyPxu2cMGuu|CcC~jX{Im50)+F=o31AFUT4I9;gZZxayY{);Hf?0YDUd+Y zirpE#9<-9^Ovs4fnLCpq!3z;Yc`#!&lyQ`F#Aw<~Xz|mTW(z7j7|&80d&ZP0X)elB zIN`;(GjjAFXJ=yaEJ2t&(~Cm~1smiUd%+QJ#(fSQjK|ajNQ5L<3+rG#(CNttQ(z-( zf>cO@bfD9}b=uN7OvimMRS97BGuwQb5IL`LQ-uFBxlIt`%kY^Qf>s35o|yZ!i(nZK zqw)n`dCW3qjUdJkLmLFGeoO)rN&n5U^s+xQTcQsaGyf=kTIO7v5yNovW;x8abVLwy Gjrl(aFZ%od diff --git a/ndata.js b/ndata.js index 5329c70..eaee32d 100644 --- a/ndata.js +++ b/ndata.js @@ -15,6 +15,7 @@ */ var data_start = [ + 0, 3, 6, 10, 14, 17, 19, 20, 31, 32, 34, 36, 38, 43, 45, 48, 52, 59, 63, 65, 67, 71, 73, 81, 87, 95, 97, 132, 139, 149, @@ -70,7 +71,6 @@ var data_start = [ 16094, 16114, 16135, 16153, 16171, 16190, 16206, 16222, 16276, 16302, 16309, 16311, 16312, 16344]; - var data_flags = [ 11, 534, 540, 11, 534, 540, 11, 34956, 12945, 540, 10, 75, 75, 17, 1098, 1098, 12, 11, 12, 11, @@ -892,7 +892,6 @@ var data_flags = [ 16535, 18583, 20631, 22679, 24727, 26775, 28823, 30871, 32919, 34967, 37015, 39063, 41111, 43159, 45207, 47255, 49303, 51351, 53399, 55447, 57495, 59543, 61591, 29, -1]; - var data_minx = [ 12433114, 5850000, 12444000, 7404110, -5200000, 7404110, -5384925, -5734540, -6703000, -5384925, @@ -2531,7 +2530,6 @@ var data_minx = [ -180000000, -180000000, -180000000, -180000000, -180000000, -180000000, -180000000, -180000000, -180000000, -180000000, -180000000, -180000000, -180000000, -180000000, -1]; - var data_miny = [ 41851944, 35450000, 41899000, 43723932, 41310000, 43723932, 36107682, 35987080, 35867000, 36107682, @@ -4170,7 +4168,6 @@ var data_miny = [ 10145275, 14243171, 18420638, 22677675, 27054069, 31589604, 36324066, 41337026, 46668269, 52556508, 59200669, 66998607, 77183669, -90000000, -1]; - var data_maxx = [ 115320, 12710000, 16000, 40362, 14800000, 40362, 63426, 572880, 3277000, 63426, @@ -5809,7 +5806,6 @@ var data_maxx = [ 360000000, 360000000, 360000000, 360000000, 360000000, 360000000, 360000000, 360000000, 360000000, 360000000, 360000000, 360000000, 360000000, 360000000, -1]; - var data_maxy = [ 86490, 19630000, 9000, 28830, 12247000, 28830, 51894, 8, 2608972, 51894, @@ -7448,7 +7444,6 @@ var data_maxy = [ 4097896, 4177467, 4257037, 4376394, 4535535, 4734462, 5012960, 5331243, 5888239, 6644161, 7797938, 10185062, 12816332, 180000000, -1]; - var data_special1 = [ 1, 1290, 3, 1, 1, 3, 1, 1, 166, 3, 1, 3844, 3721, 167, 679, 679, 1, 1, 1, 1, diff --git a/sample.html b/sample.html index 7cc5b88..3fbac89 100644 --- a/sample.html +++ b/sample.html @@ -65,9 +65,7 @@

Sample mapcode HTML

- -
Enter a territory and enter a mapcode:
- +
Enter a territory and enter a mapcode


@@ -116,13 +114,11 @@

Sample mapcode HTML

Longitude: - Restrict to territory:: + Restrict to territory: - -
Enter a latitude, a longitude, and a default territory context:
- +
Enter a latitude, a longitude, and a default territory context
From 6aae9b27c6d0f5d0e392e640f196343258faef31 Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Tue, 4 Aug 2015 17:13:59 +0200 Subject: [PATCH 02/54] Release 2.0.1 --- README.md | 56 ++++++++++++++++++++--------------------------------- mapcode.js | 4 ++-- sample.html | 12 ++++++++---- 3 files changed, 31 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 8d3faad..12ef2ce 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Mapcode Library for JavaScript -Copyright (C) 2014 Stichting Mapcode Foundation (http://www.mapcode.com) +Copyright (C) 2014-2015 Stichting Mapcode Foundation (http://www.mapcode.com) ---- @@ -16,7 +16,7 @@ not need to be transported to the client. You can find the Mapcode REST API sources, ready to be deployed on any JVM server, like Tomcat or Jetty, on: **https://github.com/mapcode-foundation/mapcode-rest-service** -## License +# License Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -33,7 +33,7 @@ limitations under the License. Original C library created by Pieter Geelen. Work on Java version of the Mapcode library by Rijn Buve and Matthew Lowden. -## Javascript Files for Mapcode Support +# Javascript Files for Mapcode Support mapcode.js - Key routines for mapcode support ndata.js - Data table for mapcode support @@ -41,35 +41,29 @@ of the Mapcode library by Rijn Buve and Matthew Lowden. sample.html - Sample code to interpret / generate mapcodes ctrynams.js - Optional js array with the names of territories (in English) -## Version History +# Version History -* July 2015 +* 2.0.1 - August 2015 - * 2.0.1 + Minor fixes. - Prettyfied source and minor fixes. - - * 2.0.0 +* 2.0.0 - July 2015 Fixes to the data rectangles (primarily intended for ISO proposal), see Word document for details. -* June 2015 - - * 1.54 +* 1.54 - June 2015 Removed unneeded mminfo flags (no effect on functionality). -* May 2015 - - * 1.50.3 +* 1.50.3 - May 2015 Redesign of the API to conform to Javascript standards and match the Java implementation of the mapcode system - * 1.50.1 +* 1.50.1 - May 2015 Bugfix for mapcodes in IN-DD (in India). - * 1.50 +* 1.50 - May 2015 Major release. This version is not backwards compatible with mapcode 1.4x: is has dropped support for Antartica AT0-8 codes and has a changed (improved) way of dealing with the Greek alphabet. @@ -80,51 +74,43 @@ of the Mapcode library by Rijn Buve and Matthew Lowden. Retired legacy Antarctica claims AT0 through AT8. -* January 2015 - - * 1.41 +* 1.41 - January 2015 Added the India state Telangana (IN-TG), until 2014 a region in Adhra Pradesh. -* August 2014 - - * 1.33 +* 1.33 - August 2014 Normalise results when longitude below -180 degrees. - * 1.32 +* 1.32 - August 2014 Prevent FIJI failing to decode at exactly 180 degrees; prevent invalid filtering near the territory bounding rectangle. -* April 2014 - - * 1.31 +* 1.31 - April 2014 Make iso2ccode() even more forgiving by allowing a state alias to be recognized in context. - * 1.3 +* 1.3 - April 2014 Disable 7-char state codes for large states in India, and instead generate country mapcodes for states. - * 1.28 +* 1.28 - April 2014 Fix for starpipe "zoning" error, causing the last 2 mapcode characters to be ignored in certain areas. - * 1.27 +* 1.27 - April 2014 Support undefined ranges in data array (useful for partial JavaScript builds). -* May 2013 - - * 1.26 +* 1.26 - May 2013 Added alias OD for India, and 2.3 code for Daman and Diu. - * 1.25 +* 1.25 - May 2013 Ccode2iso(c,2) support added. - * 1.24 +* 1.24 - May 2013 Public domain release. diff --git a/mapcode.js b/mapcode.js index 1917ae2..2157c49 100644 --- a/mapcode.js +++ b/mapcode.js @@ -70,7 +70,7 @@ var entity_iso = [ '8HN', '8GX', '8SC', '8YN', '8XZ', '8GS', '8QH', '8XJ', 'CHN', 'UMI', 'CPT', 'ATA', 'AAA', '?']; -var aliases = "2UK=2UT,2CG=2CT,1GU=GUM,1UM=UMI,1VI=VIR,1PR=PRI,1AS=ASM,1MP=MNP,4CX=CXR,4CC=CCK,4NF=NFK,4HM=HMD,COL=5CL,5ME=5MX,MEX=5MX,5TM=TAM,5AG=AGU,5BC=BCN,5BS=BCS,5CM=CAM,5CS=CHP,5CH=CHH,5CO=COA,5DF=DIF,5DG=DUR,5GT=GUA,5GR=GRO,5HG=HID,5JA=JAL,5MI=MIC,5MO=MOR,5NA=NAY,5NL=NLE,5OA=OAX,5PB=PUE,5QE=QUE,5QR=ROO,5SL=SLP,5SI=SIN,5SO=SON,5TB=TAB,5TL=TLA,5VE=VER,5YU=YUC,5ZA=ZAC,811=8BJ,812=8TJ,813=8HE,814=8SX,815=8NM,821=8LN,822=8JL,823=8HL,831=8SH,832=8JS,833=8ZJ,834=8AH,835=8FJ,836=8JX,837=8SD,841=8HA,842=8HB,843=8HN,844=8GD,845=8GX,846=8HI,850=8CQ,851=8SC,852=8GZ,853=8YN,854=8XZ,861=8SN,862=8GS,863=8QH,864=8NX,865=8XJ,871=TWN,891=HKG,892=MAC,8TW=TWN,8HK=HKG,8MC=MAC,BEL=7BE,KIR=7KI,PRI=7PO,CHE=7CH,KHM=7KM,PER=7PM,TAM=7TT,0US=USA,0AU=AUS,0RU=RUS,0CN=CHN,TAA=SHN,ASC=SHN,DGA=IOT,WAK=MHL,JTN=UMI,MID=1HI,2OD=2OR,"; +var aliases = "2UK=2UT,2CG=2CT,1GU=GUM,1UM=UMI,1VI=VIR,1AS=ASM,1MP=MNP,4CX=CXR,4CC=CCK,4NF=NFK,4HM=HMD,COL=5CL,5ME=5MX,MEX=5MX,5AG=AGU,5BC=BCN,5BS=BCS,5CM=CAM,5CS=CHP,5CH=CHH,5CO=COA,5DF=DIF,5DG=DUR,5GT=GUA,5GR=GRO,5HG=HID,5JA=JAL,5MI=MIC,5MO=MOR,5NA=NAY,5NL=NLE,5OA=OAX,5PB=PUE,5QE=QUE,5QR=ROO,5SL=SLP,5SI=SIN,5SO=SON,5TB=TAB,5TL=TLA,5VE=VER,5YU=YUC,5ZA=ZAC,811=8BJ,812=8TJ,813=8HE,814=8SX,815=8NM,821=8LN,822=8JL,823=8HL,831=8SH,832=8JS,833=8ZJ,834=8AH,835=8FJ,836=8JX,837=8SD,841=8HA,842=8HB,843=8HN,844=8GD,845=8GX,846=8HI,850=8CQ,851=8SC,852=8GZ,853=8YN,854=8XZ,861=8SN,862=8GS,863=8QH,864=8NX,865=8XJ,871=TWN,891=HKG,892=MAC,8TW=TWN,8HK=HKG,8MC=MAC,BEL=7BE,KIR=7KI,PRI=7PO,CHE=7CH,KHM=7KM,PER=7PM,TAM=7TT,0US=USA,0AU=AUS,0RU=RUS,0CN=CHN,TAA=SHN,ASC=SHN,DGA=IOT,WAK=MHL,JTN=UMI,MID=1HI,1PR=PRI,5TM=TAM,TAM=TAM,2OD=2OR,"; var dependency = [ 27, 410, 50, 410, 26, 410, 53, 410, 48, 410, 47, 410, 76, 410, 529, 410, 38, 410, @@ -181,7 +181,7 @@ function iso2ccode(territoryAlphaCode) { if (typeof territoryAlphaCode == "undefined") { return undefined; } - if (!isNaN(territoryAlphaCode)) { + if (!isNaN(territoryAlphaCode) && territoryAlphaCode < 800) { return territoryAlphaCode; } territoryAlphaCode = trim(String(territoryAlphaCode)).toUpperCase(); diff --git a/sample.html b/sample.html index 3fbac89..3f78b92 100644 --- a/sample.html +++ b/sample.html @@ -1,5 +1,5 @@ Mapcode Javascript Unit Test @@ -9,13 +24,15 @@ -Mapcode Javascript Unit Test 2.2.1
+

Mapcode Javascript Unit Tests

@@ -44,7 +61,7 @@ out('convertToAlphabet(convertToAlphabet("' + str + '",' + i + '))= "' + dec + '", expected "' + expect + '"'); } - // see if E/U voweled mapcodes (re)convert as expected + // see if E/U vowelled mapcodes (re)convert as expected str = "OMN 112.3AU"; expect = str; nrTests++; @@ -59,8 +76,9 @@ function printGeneratedMapcodes(r, name) { var n = r.length; var t = '   ' + n + ' results generated (' + name + '):'; - for (var i = 0; i < n; i++) + for (var i = 0; i < n; i++) { t += ' (' + r[i].fullmapcode + ')'; + } out(t); } @@ -98,8 +116,9 @@ // test that expected solution is there var foundlocal = 0; for (var i = 0; i < r.length; i++) { - if (r[i].fullmapcode.indexOf(str) == 0) + if (r[i].fullmapcode.indexOf(str) == 0) { foundlocal = 1; + } } if (!foundlocal) { nrErrors++; @@ -121,7 +140,7 @@ } } - // check that all global solutions are within 9 milimeters of coordinate + // check that all global solutions are within 9 millimeters of coordinate for (precision = 0; precision <= 8; precision++) { r = encodeWithPrecision(y, x, precision); for (i = 0; i < r.length; i++) { @@ -233,10 +252,10 @@ "NLD 123.U45", // U in invalid position "NLD 123.1UE", // UE illegal vowel-encode "NLD 123.1UU", // UU illegal - "NLD x23.1A0", // A0 with nondigit - "NLD 1x3.1A0", // A0 with nondigit - "NLD 12x.1A0", // A0 with nondigit - "NLD 123.xA0", // A0 with nondigit + "NLD x23.1A0", // A0 with non-digit + "NLD 1x3.1A0", // A0 with non-digit + "NLD 12x.1A0", // A0 with non-digit + "NLD 123.xA0", // A0 with non-digit "NLD 123.1U#", // U# "NLD ZZ.ZZ", // nameless out of range @@ -249,8 +268,9 @@ var i; for (i = 0; ; i++) { var str = badcodes[i]; - if (str == 'end') + if (str == 'end') { break; + } nrTests++; var p = decode(str); @@ -261,12 +281,12 @@ } } - // test encode/decodes from testdata array; returns nonzero if more tests are needed + // test encode/decodes from test data array; returns nonzero if more tests are needed var next_encode_to_test = 0; function test_encodes_decodes() { var tests_per_timeslot = 50; for (var i = next_encode_to_test; testdata[i] != -1; i += 5) { - if (nrErrors > 20) { + if (nrErrors > 0) { out('Too many errors!'); return 0; } @@ -307,11 +327,13 @@ return 0; } - // perform tests on alphacodes (used from test_territories.js) + // perform tests on alpha codes (used from test_territories.js) function test_territory(alphacode, tc, isAlias, needsParent, tcParent) { var ccode = tc - 1; var ccodeParent = tcParent - 1; - if (nrErrors > 30) return; + if (nrErrors > 30) { + return; + } nrTests++; var tn = getTerritoryNumber(alphacode, needsParent ? ccodeParent : 0); @@ -343,8 +365,8 @@ "ATA", -90, 0, 1, // in data version 2.2, ATA -90,0 has ZZ.ZZ and multiple borders "ATA", -70, 0, 0, - "USA", 31, -70, 0, // interational waters (not in state) - "MEX", 19, -115, 0, // interational waters (not in state) + "USA", 31, -70, 0, // international waters (not in state) + "MEX", 19, -115, 0, // international waters (not in state) "MEX", 18.358525, -114.722672, 0, // Isla Clarion, not in a state "MX-ROO", 20, -87, 0, // just in ROO "MX-ROO", 20, -87.3, 0, // in ROO because in MEX @@ -428,72 +450,73 @@ function territory_code_tests() { var testdata = [ // expected answer, context, string - "BR-AL", "BRA", "AL", - "VAT", , "", - "", , "R", - "", , "RX", - "", , "RXX", - "RUS", , "RUS", - "", , "RUSSIA", - "USA", , "US", - "USA", , "USA", - "USA", , "usa", - "USA", , " usa ", - "", , "999", - "", , "-44 33", - "", , "666", - "USA", , "410", - "USA", , " 410 ", - "USA", , "410 MORE TEXT", - "USA", , "US CA", - "", , "US-TEST", - "USA", , "US OTHER TEXT", - "USA", , " US OTHER TEXT ", - "US-CA", , "US-CA", - "US-CA", , "US-CA OTHER TEXT", - "US-CA", , "USA-CA", - "RU-TT", , "RUS-TAM", - "", , "RUS-TAMX", - "RU-TT", , "RUS-TAM X OTHER TEXT", - "RU-AL", "rus", "AL", - "RU-AL", "RUS", "AL", - "RU-AL", "ru-tam", "AL", - "RU-AL", "RU-TAM", "AL", - "US-AL", "US", "AL", - "US-AL", "US-CA", "AL", - -9]; - - for (var i = 0; testdata[i] != -9; i += 3 ) { - var tc = getTerritoryAlphaCode(getTerritoryNumber(testdata[i + 2], testdata[i + 1])); - nrTests++; - if (tc != testdata[i]) - { - nrErrors++; - out('*** ERROR *** getTerritoryNumber("' + testdata[i + 2] + '", ' + - testdata[i + 1] + ')=' + tc + ', expected ' + testdata[i]); + "BR-AL", "BRA", "AL", + "VAT", , "", + "", , "R", + "", , "RX", + "", , "RXX", + "RUS", , "RUS", + "", , "RUSSIA", + "USA", , "US", + "USA", , "USA", + "USA", , "usa", + "USA", , " usa ", + "", , "999", + "", , "-44 33", + "", , "666", + "USA", , "410", + "USA", , " 410 ", + "USA", , "410 MORE TEXT", + "USA", , "US CA", + "", , "US-TEST", + "USA", , "US OTHER TEXT", + "USA", , " US OTHER TEXT ", + "US-CA", , "US-CA", + "US-CA", , "US-CA OTHER TEXT", + "US-CA", , "USA-CA", + "RU-TT", , "RUS-TAM", + "", , "RUS-TAMX", + "RU-TT", , "RUS-TAM X OTHER TEXT", + "RU-AL", "rus", "AL", + "RU-AL", "RUS", "AL", + "RU-AL", "ru-tam", "AL", + "RU-AL", "RU-TAM", "AL", + "US-AL", "US", "AL", + "US-AL", "US-CA", "AL", + -9]; + + for (var i = 0; testdata[i] != -9; i += 3) { + var tc = getTerritoryAlphaCode(getTerritoryNumber(testdata[i + 2], testdata[i + 1])); + nrTests++; + if (tc != testdata[i]) { + nrErrors++; + out('*** ERROR *** getTerritoryNumber("' + testdata[i + 2] + '", ' + + testdata[i + 1] + ')=' + tc + ', expected ' + testdata[i]); } } } - var myVar = setInterval(function () { stepper() }, 20); + var myVar = setInterval(function () { + stepper() + }, 20); var dostep = 0; function stepper() { - switch (dostep++) { + switch (dostep) { case 0: - out('JavaScript version ' + mapcode_javaversion); + out('Mapcode Javascript version ' + mapcode_javaversion); break; case 1: - out('
Alphabet tests'); + out('
Alphabet tests'); break; case 2: alphabet_tests(); break; case 3: - out('
Distance tests'); + out('
Distance tests'); distance_tests(); - out('
Territory tests'); + out('
Territory tests'); out((ccode_earth + 1) + ' territories'); test_territory_insides(); break; @@ -502,31 +525,42 @@ test_territories(); break; case 5: - out('
Failing decode tests'); + out('
Incorrect format tests'); break; case 6: test_failing_decodes(); break; case 7: - out('
Encode/Decode tests'); + out('
Encode/decode tests'); break; case 8: - if (test_encodes_decodes()) dostep--; + if (test_encodes_decodes()) { + dostep--; + } break; case 9: - out('
Edge-case Encode/Decode tests'); + out('
Edge-case encode/decode tests'); break; case 10: - if (test_corner_encodes()) dostep--; + if (test_corner_encodes()) { + dostep--; + } break; case 11: - out('
Done.'); + out('
Done
'); out('Executed ' + nrTests + ' tests, found ' + nrErrors + ' errors'); + if ((nrWarnings > 0) || (nrErrors > 0)) { + out("UNIT TEST FAILED!"); + } + else { + out("Unit tests passed"); + } break; default: clearInterval(myVar); break; } + dostep++; } From 50d23196ebcb5b5b17d837d8c9ba4aa4019c997b Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Mon, 12 Oct 2015 12:04:10 +0200 Subject: [PATCH 26/54] Fixed unit test HTML --- unittest/unittest.html | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/unittest/unittest.html b/unittest/unittest.html index 3a4a002..27e5f61 100644 --- a/unittest/unittest.html +++ b/unittest/unittest.html @@ -16,7 +16,7 @@ --> - Mapcode Javascript Unit Test + Mapcode Javascript Unit Tests @@ -494,7 +494,6 @@

Mapcode Javascript Unit Tests

testdata[i + 1] + ')=' + tc + ', expected ' + testdata[i]); } } - } @@ -548,9 +547,9 @@

Mapcode Javascript Unit Tests

break; case 11: out('
Done
'); - out('Executed ' + nrTests + ' tests, found ' + nrErrors + ' errors'); + out('Executed ' + nrTests + ' tests, found ' + nrErrors + ' errors (and ' + nrWarnings + ') warnings'); if ((nrWarnings > 0) || (nrErrors > 0)) { - out("UNIT TEST FAILED!"); + out("UNIT TESTS FAILED!"); } else { out("Unit tests passed"); From 8198ec6f09072cd0533057558bf08be0eb505540 Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Thu, 29 Sep 2016 20:13:24 +0200 Subject: [PATCH 27/54] Added arabic --- README.md | 12 ++ mapcode.js | 363 ++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 299 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index fd8eaec..4758bf9 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,18 @@ To run the Javascript unit tests, simply open the file `unittest/unittest/html`. # Version History +* 2.3.0 + + Arabic script added. + + Greek script extended to be AEU-capable. + + Tibetan script changed so all characters can be typed on a computer keyboard without using the SHIFT key. + + Greek, Hebrew and Arab, the languages that have (implied) vowels in mapcode sequences, have been extended with ABJAD conversion, + to prevent more than two consecutive non-digits from occurring. + NOTE: as a result, mapcodes in Greek, Arab and Hebrew scripts are now often one character longer than in the roman script. + * 2.2.0 Solved 1-microdegree gap in a few spots on Earth, noticable now extreme precision is possible; diff --git a/mapcode.js b/mapcode.js index 1c3c9f1..70d0112 100644 --- a/mapcode.js +++ b/mapcode.js @@ -14,60 +14,60 @@ * limitations under the License. */ var entity_iso = [ - 'VAT','MCO','GIB','TKL','CCK','BLM','NRU','TUV','MAC','SXM', - 'MAF','NFK','PCN','BVT','BMU','IOT','SMR','GGY','AIA','MSR', - 'JEY','CXR','WLF','VGB','LIE','ABW','MHL','ASM','COK','SPM', - 'NIU','KNA','CYM','BES','MDV','SHN','MLT','GRD','VIR','MYT', - 'SJM','VCT','HMD','BRB','ATG','CUW','SYC','PLW','MNP','AND', - 'GUM','IMN','LCA','FSM','SGP','TON','DMA','BHR','KIR','TCA', - 'STP','HKG','MTQ','FRO','GLP','COM','MUS','REU','LUX','WSM', - 'SGS','PYF','CPV','TTO','BRN','ATF','PRI','CYP','LBN','JAM', - 'GMB','QAT','FLK','VUT','MNE','BHS','TLS','SWZ','KWT','FJI', - 'NCL','SVN','ISR','PSE','SLV','BLZ','DJI','MKD','RWA','HTI', - 'BDI','GNQ','ALB','SLB','ARM','LSO','BEL','MDA','GNB','TWN', - 'BTN','CHE','NLD','DNK','EST','DOM','SVK','CRI','BIH','HRV', - 'TGO','LVA','LTU','LKA','GEO','IRL','SLE','PAN','CZE','GUF', - 'ARE','AUT','AZE','SRB','JOR','PRT','HUN','KOR','ISL','GTM', - 'CUB','BGR','LBR','HND','BEN','ERI','MWI','PRK','NIC','GRC', - 'TJK','BGD','NPL','TUN','SUR','URY','KHM','SYR','SEN','KGZ', - 'BLR','GUY','LAO','ROU','GHA','UGA','GBR','GIN','ECU','ESH', - 'GAB','NZL','BFA','PHL','ITA','OMN','POL','CIV','NOR','MYS', - 'VNM','FIN','COG','DEU','JPN','ZWE','PRY','IRQ','MAR','UZB', - 'SWE','PNG','CMR','TKM','ESP','THA','YEM','FRA','ALA','KEN', - 'BWA','MDG','UKR','SSD','CAF','SOM','AFG','MMR','ZMB','CHL', - 'TUR','PAK','MOZ','NAM','VEN','NGA','TZA','EGY','MRT','BOL', - 'ETH','COL','ZAF','MLI','AGO','NER','TCD','PER','MNG','IRN', - 'LBY','SDN','IDN','DIF','TLA','MOR','AGU','5CL','QUE','HID', - '5MX','TAB','NAY','GUA','PUE','YUC','ROO','SIN','CAM','MIC', - 'SLP','GRO','NLE','BCN','VER','CHP','BCS','ZAC','JAL','TAM', - 'OAX','DUR','COA','SON','CHH','GRL','SAU','COD','DZA','KAZ', - 'ARG','2DD','2DN','2CH','2AN','2LD','2DL','2ML','2NL','2MN', - '2TR','2MZ','2SK','2PB','2HR','2AR','2AS','2BR','2UT','2GA', - '2KL','2TN','2HP','2JK','2CT','2JH','2KA','2RJ','2OR','2GJ', - '2WB','2MP','2TG','2AP','2MH','2UP','2PY','NSW','ACT','JBT', - '4NT','4SA','TAS','VIC','4WA','QLD','6DF','6SE','6AL','6RJ', - '6ES','6RN','6PB','6SC','6PE','6AP','6CE','6AC','6PR','6RR', - '6RO','6SP','6PI','6TO','6RS','6MA','6GO','6MS','6BA','6MG', - '6MT','6PA','6AM','1DC','1RI','1DE','1CT','1NJ','1NH','1VT', - '1MA','1HI','1MD','1WV','1SC','1ME','1IN','1KY','1TN','1VA', - '1OH','1PA','1MS','1LA','1AL','1AR','1NC','1NY','1IA','1IL', - '1GA','1WI','1FL','1MO','1OK','1ND','1WA','1SD','1NE','1KS', - '1ID','1UT','1MN','1MI','1WY','1OR','1CO','1NV','1AZ','1NM', - '1MT','1CA','1TX','1AK','3BC','3AB','3ON','3QC','3SK','3MB', - '3NL','3NB','3NS','3PE','3YT','3NT','3NU','IND','AUS','BRA', - 'USA','MEX','MOW','SPE','KGD','7IN','7AD','7SE','7KB','7KC', - '7CE','7CU','IVA','LIP','ORL','TUL','7BE','VLA','KRS','KLU', - '7TT','BRY','YAR','RYA','AST','MOS','SMO','7DA','VOR','NGR', - 'PSK','KOS','STA','KDA','7KL','TVE','LEN','ROS','VGG','VLG', - 'MUR','7KR','NEN','7KO','ARK','7MO','NIZ','PNZ','7KI','7ME', - 'ORE','ULY','7PM','7BA','7UD','7TA','SAM','SAR','YAN','7KM', - 'SVE','TYU','KGN','7CH','7BU','ZAB','IRK','NVS','TOM','OMS', - '7KK','KEM','7AL','ALT','7TY','KYA','MAG','CHU','KAM','SAK', - '7PO','YEV','KHA','AMU','7SA','CAN','RUS','8SH','8TJ','8BJ', - '8HI','8NX','8CQ','8ZJ','8JS','8FJ','8AH','8LN','8SD','8SX', - '8JX','8HA','8GZ','8GD','8HB','8JL','8HE','8SN','8NM','8HL', - '8HN','8GX','8SC','8YN','8XZ','8GS','8QH','8XJ','CHN','UMI', - 'CPT','ATA','AAA', '?']; + 'VAT', 'MCO', 'GIB', 'TKL', 'CCK', 'BLM', 'NRU', 'TUV', 'MAC', 'SXM', + 'MAF', 'NFK', 'PCN', 'BVT', 'BMU', 'IOT', 'SMR', 'GGY', 'AIA', 'MSR', + 'JEY', 'CXR', 'WLF', 'VGB', 'LIE', 'ABW', 'MHL', 'ASM', 'COK', 'SPM', + 'NIU', 'KNA', 'CYM', 'BES', 'MDV', 'SHN', 'MLT', 'GRD', 'VIR', 'MYT', + 'SJM', 'VCT', 'HMD', 'BRB', 'ATG', 'CUW', 'SYC', 'PLW', 'MNP', 'AND', + 'GUM', 'IMN', 'LCA', 'FSM', 'SGP', 'TON', 'DMA', 'BHR', 'KIR', 'TCA', + 'STP', 'HKG', 'MTQ', 'FRO', 'GLP', 'COM', 'MUS', 'REU', 'LUX', 'WSM', + 'SGS', 'PYF', 'CPV', 'TTO', 'BRN', 'ATF', 'PRI', 'CYP', 'LBN', 'JAM', + 'GMB', 'QAT', 'FLK', 'VUT', 'MNE', 'BHS', 'TLS', 'SWZ', 'KWT', 'FJI', + 'NCL', 'SVN', 'ISR', 'PSE', 'SLV', 'BLZ', 'DJI', 'MKD', 'RWA', 'HTI', + 'BDI', 'GNQ', 'ALB', 'SLB', 'ARM', 'LSO', 'BEL', 'MDA', 'GNB', 'TWN', + 'BTN', 'CHE', 'NLD', 'DNK', 'EST', 'DOM', 'SVK', 'CRI', 'BIH', 'HRV', + 'TGO', 'LVA', 'LTU', 'LKA', 'GEO', 'IRL', 'SLE', 'PAN', 'CZE', 'GUF', + 'ARE', 'AUT', 'AZE', 'SRB', 'JOR', 'PRT', 'HUN', 'KOR', 'ISL', 'GTM', + 'CUB', 'BGR', 'LBR', 'HND', 'BEN', 'ERI', 'MWI', 'PRK', 'NIC', 'GRC', + 'TJK', 'BGD', 'NPL', 'TUN', 'SUR', 'URY', 'KHM', 'SYR', 'SEN', 'KGZ', + 'BLR', 'GUY', 'LAO', 'ROU', 'GHA', 'UGA', 'GBR', 'GIN', 'ECU', 'ESH', + 'GAB', 'NZL', 'BFA', 'PHL', 'ITA', 'OMN', 'POL', 'CIV', 'NOR', 'MYS', + 'VNM', 'FIN', 'COG', 'DEU', 'JPN', 'ZWE', 'PRY', 'IRQ', 'MAR', 'UZB', + 'SWE', 'PNG', 'CMR', 'TKM', 'ESP', 'THA', 'YEM', 'FRA', 'ALA', 'KEN', + 'BWA', 'MDG', 'UKR', 'SSD', 'CAF', 'SOM', 'AFG', 'MMR', 'ZMB', 'CHL', + 'TUR', 'PAK', 'MOZ', 'NAM', 'VEN', 'NGA', 'TZA', 'EGY', 'MRT', 'BOL', + 'ETH', 'COL', 'ZAF', 'MLI', 'AGO', 'NER', 'TCD', 'PER', 'MNG', 'IRN', + 'LBY', 'SDN', 'IDN', 'DIF', 'TLA', 'MOR', 'AGU', '5CL', 'QUE', 'HID', + '5MX', 'TAB', 'NAY', 'GUA', 'PUE', 'YUC', 'ROO', 'SIN', 'CAM', 'MIC', + 'SLP', 'GRO', 'NLE', 'BCN', 'VER', 'CHP', 'BCS', 'ZAC', 'JAL', 'TAM', + 'OAX', 'DUR', 'COA', 'SON', 'CHH', 'GRL', 'SAU', 'COD', 'DZA', 'KAZ', + 'ARG', '2DD', '2DN', '2CH', '2AN', '2LD', '2DL', '2ML', '2NL', '2MN', + '2TR', '2MZ', '2SK', '2PB', '2HR', '2AR', '2AS', '2BR', '2UT', '2GA', + '2KL', '2TN', '2HP', '2JK', '2CT', '2JH', '2KA', '2RJ', '2OR', '2GJ', + '2WB', '2MP', '2TG', '2AP', '2MH', '2UP', '2PY', 'NSW', 'ACT', 'JBT', + '4NT', '4SA', 'TAS', 'VIC', '4WA', 'QLD', '6DF', '6SE', '6AL', '6RJ', + '6ES', '6RN', '6PB', '6SC', '6PE', '6AP', '6CE', '6AC', '6PR', '6RR', + '6RO', '6SP', '6PI', '6TO', '6RS', '6MA', '6GO', '6MS', '6BA', '6MG', + '6MT', '6PA', '6AM', '1DC', '1RI', '1DE', '1CT', '1NJ', '1NH', '1VT', + '1MA', '1HI', '1MD', '1WV', '1SC', '1ME', '1IN', '1KY', '1TN', '1VA', + '1OH', '1PA', '1MS', '1LA', '1AL', '1AR', '1NC', '1NY', '1IA', '1IL', + '1GA', '1WI', '1FL', '1MO', '1OK', '1ND', '1WA', '1SD', '1NE', '1KS', + '1ID', '1UT', '1MN', '1MI', '1WY', '1OR', '1CO', '1NV', '1AZ', '1NM', + '1MT', '1CA', '1TX', '1AK', '3BC', '3AB', '3ON', '3QC', '3SK', '3MB', + '3NL', '3NB', '3NS', '3PE', '3YT', '3NT', '3NU', 'IND', 'AUS', 'BRA', + 'USA', 'MEX', 'MOW', 'SPE', 'KGD', '7IN', '7AD', '7SE', '7KB', '7KC', + '7CE', '7CU', 'IVA', 'LIP', 'ORL', 'TUL', '7BE', 'VLA', 'KRS', 'KLU', + '7TT', 'BRY', 'YAR', 'RYA', 'AST', 'MOS', 'SMO', '7DA', 'VOR', 'NGR', + 'PSK', 'KOS', 'STA', 'KDA', '7KL', 'TVE', 'LEN', 'ROS', 'VGG', 'VLG', + 'MUR', '7KR', 'NEN', '7KO', 'ARK', '7MO', 'NIZ', 'PNZ', '7KI', '7ME', + 'ORE', 'ULY', '7PM', '7BA', '7UD', '7TA', 'SAM', 'SAR', 'YAN', '7KM', + 'SVE', 'TYU', 'KGN', '7CH', '7BU', 'ZAB', 'IRK', 'NVS', 'TOM', 'OMS', + '7KK', 'KEM', '7AL', 'ALT', '7TY', 'KYA', 'MAG', 'CHU', 'KAM', 'SAK', + '7PO', 'YEV', 'KHA', 'AMU', '7SA', 'CAN', 'RUS', '8SH', '8TJ', '8BJ', + '8HI', '8NX', '8CQ', '8ZJ', '8JS', '8FJ', '8AH', '8LN', '8SD', '8SX', + '8JX', '8HA', '8GZ', '8GD', '8HB', '8JL', '8HE', '8SN', '8NM', '8HL', + '8HN', '8GX', '8SC', '8YN', '8XZ', '8GS', '8QH', '8XJ', 'CHN', 'UMI', + 'CPT', 'ATA', 'AAA', '?']; var aliases = "2UK=2UT,2CG=2CT,1GU=GUM,1UM=UMI,1VI=VIR,1AS=ASM,1MP=MNP,4CX=CXR,4CC=CCK,4NF=NFK,4HM=HMD,COL=5CL,5ME=5MX,MEX=5MX,5AG=AGU,5BC=BCN,5BS=BCS,5CM=CAM,5CS=CHP,5CH=CHH,5CO=COA,5DF=DIF,5DG=DUR,5GT=GUA,5GR=GRO,5HG=HID,5JA=JAL,5MI=MIC,5MO=MOR,5NA=NAY,5NL=NLE,5OA=OAX,5PB=PUE,5QE=QUE,5QR=ROO,5SL=SLP,5SI=SIN,5SO=SON,5TB=TAB,5TL=TLA,5VE=VER,5YU=YUC,5ZA=ZAC,811=8BJ,812=8TJ,813=8HE,814=8SX,815=8NM,821=8LN,822=8JL,823=8HL,831=8SH,832=8JS,833=8ZJ,834=8AH,835=8FJ,836=8JX,837=8SD,841=8HA,842=8HB,843=8HN,844=8GD,845=8GX,846=8HI,850=8CQ,851=8SC,852=8GZ,853=8YN,854=8XZ,861=8SN,862=8GS,863=8QH,864=8NX,865=8XJ,871=TWN,891=HKG,892=MAC,8TW=TWN,8HK=HKG,8MC=MAC,BEL=7BE,KIR=7KI,PRI=7PO,CHE=7CH,KHM=7KM,PER=7PM,TAM=7TT,0US=USA,0AU=AUS,0RU=RUS,0CN=CHN,TAA=SHN,ASC=SHN,DGA=IOT,WAK=MHL,JTN=UMI,MID=1HI,1PR=PRI,5TM=TAM,TAM=TAM,2OD=2OR,"; @@ -120,7 +120,7 @@ var mapcode_dataversion = "2.2.0"; // *************************** mapcode_org ********************* -var mapcode_javaversion = '2.2.2/Data' + mapcode_dataversion; +var mapcode_javaversion = '2.3.0/Data' + mapcode_dataversion; /// PRIVATE returns string without leading spaces and plus-signs, and trailing spaces function trim(str) { @@ -182,7 +182,9 @@ function iso2ccode(territoryAlphaCode) { } territoryAlphaCode = trim(String(territoryAlphaCode)).toUpperCase(); var sp = territoryAlphaCode.indexOf(" "); - if (sp > 0) territoryAlphaCode = territoryAlphaCode.substr(0, sp); + if (sp > 0) { + territoryAlphaCode = territoryAlphaCode.substr(0, sp); + } if (!isNaN(territoryAlphaCode)) { var n = Number(territoryAlphaCode); if ((n >= 0) && (n <= ccode_earth)) { @@ -696,10 +698,12 @@ function convertFractionsToCoord32(p) { } function wrap(p) { - if (p.x >= (180 * 3240000 * 1000000)) + if (p.x >= (180 * 3240000 * 1000000)) { p.x -= (360 * 3240000 * 1000000); - if (p.x < (-180 * 3240000 * 1000000)) + } + if (p.x < (-180 * 3240000 * 1000000)) { p.x += (360 * 3240000 * 1000000); + } return p; } @@ -782,7 +786,7 @@ function decodeExtension(extensionchars, coord32, dividerx4, dividery, lon_offse } var lon4 = (coord32.x * 3240000.0) + (lon32 * dividerx4) + (lon_offset4 * 810000.0); - var lat1 = (coord32.y * 810000.0) + (lat32 * dividery ); + var lat1 = (coord32.y * 810000.0) + (lat32 * dividery ); // determine the range of coordinates that are encode to this mapcode var mapcodeZone; @@ -905,10 +909,10 @@ function encodeBase31(value, nrchars) { function encodeTriple(difx, dify, dividerx, dividery) { var rx, ry, cx, cy; if (dify < 4 * 34) { - rx = Math.floor(difx / 28); - ry = Math.floor(dify / 34); - cx = (difx % 28); - cy = (dify % 34); + rx = Math.floor(difx / 28); + ry = Math.floor(dify / 34); + cx = (difx % 28); + cy = (dify % 34); if (getDebugInfo) { mcInfo.rectRegion = asDegreeRect((1000000 * mcInfo.rectSubarea.minx) + ((28 * rx * dividerx)), (1000000 * (mcInfo.rectSubarea.maxy)) - (((34 * ry) + 34) * dividery), 28 * dividerx, 34 * dividery); } @@ -1061,10 +1065,10 @@ function encodeGrid(enc, m, mm, headerletter, extraDigits) { /// alphabet support -var MAXLANS = 14; +var MAXLANS = 15; var asc2lan = [ [65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Roman - [913, 914, 926, 916, 63, 917, 915, 919, 921, 928, 922, 923, 924, 925, 927, 929, 920, 936, 931, 932, 63, 934, 937, 935, 933, 918, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Greek + [913, 914, 926, 916, 904/*e*/, 917, 915, 919, 921, 928, 922, 923, 924, 925, 927, 929, 920, 936, 931, 932, 905/*u*/, 934, 937, 935, 933, 918, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Greek [1040, 1042, 1057, 1044, 1045, 1046, 1043, 1053, 1048, 1055, 1050, 1051, 1052, 1047, 1054, 1056, 1060, 1071, 1062, 1058, 1069, 1063, 1064, 1061, 1059, 1041, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Cyrillic [1488, 1489, 1490, 1491, 1507, 1492, 1494, 1495, 1493, 1496, 1497, 1498, 1499, 1500, 1505, 1501, 1502, 1504, 1506, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Hebrew [2309, 2325, 2327, 2328, 2319, 2330, 2332, 2335, 73, 2336, 2339, 2340, 2342, 2343, 79, 2344, 2346, 2349, 2350, 2352, 2347, 2354, 2357, 2360, 2361, 2337, 2406, 2407, 2408, 2409, 2410, 2411, 2412, 2413, 2414, 2415], // Hindi @@ -1076,7 +1080,8 @@ var asc2lan = [ [1366, 1330, 1331, 1332, 1333, 1336, 1337, 1338, 1339, 1341, 1343, 1344, 1345, 1347, 1365, 1351, 1352, 1354, 1357, 1358, 1349, 1359, 1360, 1361, 1362, 1363, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Armenian [2437, 2444, 2453, 2454, 2447, 2455, 2457, 2458, 73, 2461, 2464, 2465, 2466, 2467, 79, 2468, 2469, 2470, 2472, 2474, 2451, 2476, 2477, 2479, 2482, 2489, 2534, 2535, 2536, 2537, 2538, 2539, 2540, 2541, 2542, 2543], // Bengali [2565, 2581, 2583, 2584, 2575, 2586, 2588, 2591, 73, 2592, 2595, 2596, 2598, 2599, 79, 2600, 2602, 2605, 2606, 2608, 2603, 2610, 2613, 2616, 2617, 2593, 2662, 2663, 2664, 2665, 2666, 2667, 2668, 2669, 2670, 2671], // Gurmukhi - [3928, 3904, 3905, 3906, 3940, 3908, 3909, 3910, 73, 3911, 3914, 3916, 3918, 3919, 79, 3921, 3923, 3924, 3926, 3934, 3941, 3935, 3937, 3938, 3939, 3942, 3872, 3873, 3874, 3875, 3876, 3877, 3878, 3879, 3880, 3881] // Tibetan + [3928, 3904, 3905, 3906, 3940, 3908, 3909, 3910, 73, 3911, 0xF49, 0xF55, 0xF50, /*KLM=3914, 3916, 3918,*/ 3919, 79, 3921, 3923, 3924, 3926, 3934, 0xF60/*u=3941*/, 3935, 3937, 3938, 3939, 3942, 3872, 3873, 3874, 3875, 3876, 3877, 3878, 3879, 3880, 3881], // Tibetan + [1576, 1578, 1581, 1582, 1609/*e*/, 1583, 1584, 1585, 73/*i*/, 1586, 1587, 1588, 1589, 1590, 79/*o*/, 1591, 1592, 1593, 1594, 1601, 1602/*u*/, 1603, 1604, 1605, 1606, 1608, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57] // Arabic ]; // *UI* @@ -1094,7 +1099,8 @@ var lannam = [ ["Armenian"], ["Bengali"], ["Gurmukhi"], - ["Tibetan"] + ["Tibetan"], + ["Arabic"] ]; // *UI* @@ -1112,7 +1118,8 @@ var lanlannam = [ ["հայերեն"], ["বাংলা"], ["ਗੁਰਮੁਖੀ"], - ["དབུ་ཅན་"] + ["དབུ་ཅན་"], + ["العَرَبِيَّة"] ]; /// PRIVATE substitute characters in str with characters form the specified language (pass asHTML=1 to explicitly HTML-encode characters) @@ -1131,6 +1138,10 @@ function showinlan(str, lan, asHTML) { str = str.substr(sp); } + if (lan == 1 || lan == 3 || lan == 14) { + str = convertToAbjad(str); + } + // unpack for languages that do not support E and U if (asc2lan[lan][4] == 63) { if (str.indexOf('E') >= 0 || str.indexOf('U') >= 0) { @@ -1193,11 +1204,20 @@ function to_ascii(str) { } } var p = result.lastIndexOf(' '); - if (p < 0) p = 0; else p++; + if (p < 0) { + p = 0; + } else { + p++; + } if (result.charAt(p) == 'A') { result = result.substr(0, p) + aeu_pack(aeu_unpack(result.substr(p)), false); /* v1.50 repack A-voweled to AEU-voweled */ } + + if (isAbjadScript(str)) { + result = convertFromAbjad(result); + } + return result; } @@ -1641,8 +1661,16 @@ var debugStopRecord = -1; // GLOBAL function getEncodeRec(lat, lon) { - if (isNaN(lat)) lat = 0; else lat = Number(lat); - if (lat < -90) lat = -90; else if (lat > 90) lat = 90; + if (isNaN(lat)) { + lat = 0; + } else { + lat = Number(lat); + } + if (lat < -90) { + lat = -90; + } else if (lat > 90) { + lat = 90; + } lat += 90; // lat now [0..180] lat *= 810000000000; var fraclat = Math.floor(lat + 0.1); @@ -1651,14 +1679,20 @@ function getEncodeRec(lat, lon) { fraclat -= (lat32 * 810000); lat32 -= 90000000; - if (isNaN(lon)) lon = 0; else lon = Number(lon); + if (isNaN(lon)) { + lon = 0; + } else { + lon = Number(lon); + } lon -= (360 * Math.floor(lon / 360)); // lon now in [0..360> lon *= 3240000000000; var fraclon = Math.floor(lon + 0.1); d = fraclon / 3240000; var lon32 = Math.floor(d); fraclon -= (lon32 * 3240000); - if (lon32 >= 180000000) lon32 -= 360000000; + if (lon32 >= 180000000) { + lon32 -= 360000000; + } return {coord32: {y: lat32, x: lon32}, fraclat: fraclat, fraclon: fraclon}; } @@ -1775,7 +1809,7 @@ function aeu_unpack(str) { var lastpos = str.length - 1; var dotpos = str.indexOf('.'); if (dotpos < 2 || lastpos < dotpos + 2) { - return ''; + return str; } // Error: no dot, or less than 2 letters before dot, or less than 2 letters after dot if (str.charAt(0) == 'A') /* V1.50 */ @@ -1847,8 +1881,12 @@ function aeu_unpack(str) { } } } - if (voweled && hasletters) return ''; - if (!voweled && !hasletters) return ''; + if (voweled && hasletters) { + return ''; + } + if (!voweled && !hasletters) { + return ''; + } return str; } @@ -2121,3 +2159,176 @@ function multipleBordersNearby(latitudeDegrees, longitudeDegrees, territory) { function maxErrorInMeters(extraDigits) { return maxErrorInMetersForDigits[extraDigits]; } + +/// PRIVATE convert a mapcode to an ABJAD-format (never more than 2 non-digits in a row) +function convertToAbjad(str) { + var rest = '', h = str.indexOf('-'); + if (h > 0) { + rest = str.substring(h); + str = str.substring(0, h); + } + str = aeu_unpack(str); + var len = str.length; + var dot = str.indexOf('.'); + var form = 10 * dot + (len - dot - 1); + + // see if >2 non-digits in a row + var inarow = 0; + for (var i = 0; i < len; i++) { + var c = str.charCodeAt(i); + if (c != 46) { + inarow++; + if (decodeChar[c] <= 9) { + inarow = 0; + } else if (inarow > 2) { + break; + } + } + } + if (inarow < 3 && (form == 22 || form == 32 || form == 33 || form == 42 || form == 43 || form == 44 || form == 54)) { + // no need to do anything + } + else { + var c = decodeChar[str.charCodeAt(2)]; + if (c < 0) { + c = decodeChar[str.charCodeAt(3)]; + } + var c1, c2, c3 = 0; + if (form >= 44) { + c = (c * 31) + (decodeChar[str.charCodeAt(len - 1)] + 39); + c1 = Math.floor(c / 100) + c2 = Math.floor((c % 100) / 10); + c3 = (c % 10); + } + else if (len == 7) { + if (form == 24) { + c += 7; + } else if (form == 33) { + c += 38; + } else if (form == 42) { + c += 69; + } + c1 = Math.floor(c / 10); + c2 = (c % 10); + } + else { + c1 = 2 + Math.floor(c / 8); + c2 = 2 + (c % 8); + } + + if (form == 22) { + str = str.charAt(0) + str.charAt(1) + '.' + c1 + c2 + str.charAt(4); + } + else if (form == 23) { + str = str.charAt(0) + str.charAt(1) + '.' + c1 + c2 + str.charAt(4) + str.charAt(5); + } + else if (form == 32) { + str = str.charAt(0) + str.charAt(1) + '.' + (c1 + 4) + c2 + str.charAt(4) + str.charAt(5); + } + else if (form == 24) { + str = str.charAt(0) + str.charAt(1) + c1 + '.' + str.charAt(4) + c2 + str.charAt(5) + str.charAt(6); + } + else if (form == 33) { + str = str.charAt(0) + str.charAt(1) + c1 + '.' + str.charAt(4) + c2 + str.charAt(5) + str.charAt(6); + } + else if (form == 42) { + str = str.charAt(0) + str.charAt(1) + c1 + '.' + str.charAt(3) + c2 + str.charAt(5) + str.charAt(6); + } + else if (form == 43) { + str = str.charAt(0) + str.charAt(1) + (c1 + 4) + '.' + str.charAt(3) + str.charAt(5) + c2 + str.charAt(6) + str.charAt(7); + } + else if (form == 34) { + str = str.charAt(0) + str.charAt(1) + c1 + '.' + str.charAt(4) + str.charAt(5) + c2 + str.charAt(6) + str.charAt(7); + } + else if (form == 44) { + str = str.charAt(0) + str.charAt(1) + c1 + str.charAt(3) + '.' + c2 + str.charAt(5) + str.charAt(6) + c3 + str.charAt(7); + } + else if (form == 54) { + str = str.charAt(0) + str.charAt(1) + c1 + str.charAt(3) + str.charAt(4) + '.' + c2 + str.charAt(6) + str.charAt(7) + c3 + str.charAt(8); + } + } + return aeu_pack(str + rest, false); +} + +/// PRIVATE returns true if str contains characters from an abjad-script +function isAbjadScript(str) { + for (var i = 0; i < str.length; i++) { + var c = str.charCodeAt(i); + if (c >= 1576 && c <= 1609) { + return true; + } // arabic + if (c >= 1488 && c <= 1514) { + return true; + } // hebrew + if (c >= 904 && c <= 969) { + return true; + } // greek 0x388-0x3C9 + } + return false; +} + +/// PRIVATE convert a mapcode in ABJAD-format to normal format +function convertFromAbjad(result) { + // split into prefix, s, postfix + var p = result.lastIndexOf(' '); + if (p < 0) { + p = 0; + } else { + p++; + } + var prefix = result.substr(0, p); + var s = result.substr(p); + var postfix = ''; + var h = s.indexOf('-'); + if (h > 0) { + postfix = s.substring(h); + s = s.substring(0, h); + } + + s = aeu_unpack(s); + var len = s.length; + var dot = s.indexOf('.'); + var form = dot * 10 + (len - dot - 1); + var c; + + if (form == 23) { + c = (s.charAt(3) * 8) + (s.charAt(4) - 18); + s = s.charAt(0) + s.charAt(1) + '.' + encodeChar[c] + s.charAt(5); + } + else if (form == 24) { + c = (s.charAt(3) * 8) + (s.charAt(4) - 18); + if (c >= 32) { + s = s.charAt(0) + s.charAt(1) + encodeChar[c - 32] + '.' + s.charAt(5) + s.charAt(6); + } else { + s = s.charAt(0) + s.charAt(1) + '.' + encodeChar[c] + s.charAt(5) + s.charAt(6); + } + } + else if (form == 34) { + c = (s.charAt(2) * 10) + (s.charAt(5) - 7); + if (c < 31) { + s = s.charAt(0) + s.charAt(1) + '.' + encodeChar[c] + s.charAt(4) + s.charAt(6) + s.charAt(7); + } else if (c < 62) { + s = s.charAt(0) + s.charAt(1) + encodeChar[c - 31] + '.' + s.charAt(4) + s.charAt(6) + s.charAt(7); + } else { + s = s.charAt(0) + s.charAt(1) + encodeChar[c - 62] + s.charAt(4) + '.' + s.charAt(6) + s.charAt(7); + } + } + else if (form == 35) { + c = (s.charAt(2) * 8) + (s.charAt(6) - 18); + if (c >= 32) { + s = s.charAt(0) + s.charAt(1) + encodeChar[c - 32] + s.charAt(4) + '.' + s.charAt(5) + s.charAt(7) + s.charAt(8); + } else { + s = s.charAt(0) + s.charAt(1) + encodeChar[c] + '.' + s.charAt(4) + s.charAt(5) + s.charAt(7) + s.charAt(8); + } + } + else if (form == 45) { + c = (s.charAt(2) * 100) + (s.charAt(5) * 10) + (s.charAt(8) - 39); + s = s.charAt(0) + s.charAt(1) + encodeChar[Math.floor(c / 31)] + s.charAt(3) + '.' + s.charAt(6) + s.charAt(7) + s.charAt(9) + encodeChar[c % 31]; + } + else if (form == 55) { + c = (s.charAt(2) * 100) + (s.charAt(6) * 10) + (s.charAt(9) - 39); + s = s.charAt(0) + s.charAt(1) + encodeChar[Math.floor(c / 31)] + s.charAt(3) + s.charAt(4) + '.' + s.charAt(7) + s.charAt(8) + s.charAt(10) + encodeChar[c % 31]; + } + return prefix + aeu_pack(s, false) + postfix; +} + From 11acd6afb8ac7f9a0a6312d251f9b1a42cc01e40 Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Fri, 30 Sep 2016 19:17:32 +0200 Subject: [PATCH 28/54] Fixed unit test --- mapcode.js | 45 +++++++++++++---- unittest/unittest.html | 112 +++++++++++++++++++++++++++++++---------- 2 files changed, 120 insertions(+), 37 deletions(-) diff --git a/mapcode.js b/mapcode.js index 70d0112..8f6c9e4 100644 --- a/mapcode.js +++ b/mapcode.js @@ -1068,7 +1068,7 @@ function encodeGrid(enc, m, mm, headerletter, extraDigits) { var MAXLANS = 15; var asc2lan = [ [65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Roman - [913, 914, 926, 916, 904/*e*/, 917, 915, 919, 921, 928, 922, 923, 924, 925, 927, 929, 920, 936, 931, 932, 905/*u*/, 934, 937, 935, 933, 918, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Greek + [913, 914, 926, 916, 904/*e*/, 917, 915, 919, 921, 928, 922, 923, 924, 925, 927/*o*/, 929, 920, 936, 931, 932, 905/*u*/, 934, 937, 935, 933, 918, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Greek [1040, 1042, 1057, 1044, 1045, 1046, 1043, 1053, 1048, 1055, 1050, 1051, 1052, 1047, 1054, 1056, 1060, 1071, 1062, 1058, 1069, 1063, 1064, 1061, 1059, 1041, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Cyrillic [1488, 1489, 1490, 1491, 1507, 1492, 1494, 1495, 1493, 1496, 1497, 1498, 1499, 1500, 1505, 1501, 1502, 1504, 1506, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Hebrew [2309, 2325, 2327, 2328, 2319, 2330, 2332, 2335, 73, 2336, 2339, 2340, 2342, 2343, 79, 2344, 2346, 2349, 2350, 2352, 2347, 2354, 2357, 2360, 2361, 2337, 2406, 2407, 2408, 2409, 2410, 2411, 2412, 2413, 2414, 2415], // Hindi @@ -1642,7 +1642,7 @@ function aeu_pack(r, short) /* v1.50 */ { } var v; - if (rlen - 2 > dotpos) { // does r have a dot, AND at least 2 chars after the dot? + if (dotpos >= 2 && rlen - 2 > dotpos) { // does r have a dot, AND at least 2 chars after the dot? if (short) { /* v1.50 new way: use only A */ v = (r.charCodeAt(0) - 48) * 100 + (r.charCodeAt(rlen - 2) - 48) * 10 + (r.charCodeAt(rlen - 1) - 48); r = 'A' + r.substring(1, rlen - 2) + encodeChar[Math.floor(v / 32)] + encodeChar[v % 32]; // 1.50 @@ -2161,15 +2161,23 @@ function maxErrorInMeters(extraDigits) { } /// PRIVATE convert a mapcode to an ABJAD-format (never more than 2 non-digits in a row) -function convertToAbjad(str) { - var rest = '', h = str.indexOf('-'); - if (h > 0) { - rest = str.substring(h); - str = str.substring(0, h); +function convertToAbjad(mapcode) { + var str, rest; + var h = mapcode.indexOf('-'); + if (h >= 0) { + rest = mapcode.substring(h); + str = aeu_unpack(mapcode.substring(0, h)); + } + else { + rest = ''; + str = aeu_unpack(mapcode); } - str = aeu_unpack(str); + var len = str.length; var dot = str.indexOf('.'); + if (dot < 2 || dot > 5) { + return mapcode; + } var form = 10 * dot + (len - dot - 1); // see if >2 non-digits in a row @@ -2187,15 +2195,22 @@ function convertToAbjad(str) { } if (inarow < 3 && (form == 22 || form == 32 || form == 33 || form == 42 || form == 43 || form == 44 || form == 54)) { // no need to do anything + return mapcode; } else { var c = decodeChar[str.charCodeAt(2)]; if (c < 0) { c = decodeChar[str.charCodeAt(3)]; + if (c < 0) { + return mapcode; + } } var c1, c2, c3 = 0; if (form >= 44) { c = (c * 31) + (decodeChar[str.charCodeAt(len - 1)] + 39); + if (c < 39 || c > 999) { + return mapcode; + } c1 = Math.floor(c / 100) c2 = Math.floor((c % 100) / 10); c3 = (c % 10); @@ -2246,8 +2261,12 @@ function convertToAbjad(str) { else if (form == 54) { str = str.charAt(0) + str.charAt(1) + c1 + str.charAt(3) + str.charAt(4) + '.' + c2 + str.charAt(6) + str.charAt(7) + c3 + str.charAt(8); } + else { + return mapcode; + } } - return aeu_pack(str + rest, false); + //alert(str+' ['+rest+'] = '+aeu_pack(str, false)); + return aeu_pack(str, false) + rest; } /// PRIVATE returns true if str contains characters from an abjad-script @@ -2288,7 +2307,10 @@ function convertFromAbjad(result) { s = aeu_unpack(s); var len = s.length; var dot = s.indexOf('.'); - var form = dot * 10 + (len - dot - 1); + if (dot < 2 || dot > 5) { + return result; + } + var form = 10 * dot + (len - dot - 1); var c; if (form == 23) { @@ -2329,6 +2351,9 @@ function convertFromAbjad(result) { c = (s.charAt(2) * 100) + (s.charAt(6) * 10) + (s.charAt(9) - 39); s = s.charAt(0) + s.charAt(1) + encodeChar[Math.floor(c / 31)] + s.charAt(3) + s.charAt(4) + '.' + s.charAt(7) + s.charAt(8) + s.charAt(10) + encodeChar[c % 31]; } + else { + return result; + } return prefix + aeu_pack(s, false) + postfix; } diff --git a/unittest/unittest.html b/unittest/unittest.html index 27e5f61..a04eb8d 100644 --- a/unittest/unittest.html +++ b/unittest/unittest.html @@ -45,30 +45,81 @@

Mapcode Javascript Unit Tests

var nrWarnings = 0; // test the alphabet conversion routines - function alphabet_tests() { - out(MAXLANS + ' alphabets'); - for (var i = 0; i < MAXLANS; i++) { + var testpairs = [ +// "OIoi#%?-.abcdfghjklmnpqrstvwxyz0123456789ABCDFGHJKLMNPQRSTVWXYZ","OIOI#%?-.ABCDFGHJKLMNPQRSTVWXYZ0123456789ABCDFGHJKLMNPQRSTVWXYZ", +// "OEUoi OIoi#%?-.abcdfghjklmnpqrstvwxyz0123456789ABCDFGHJKLMNPQRSTVWXYZ","OEUOI OIOI#%?-.ABCDFGHJKLMNPQRSTVWXYZ0123456789ABCDFGHJKLMNPQRSTVWXYZ", +// "OEUoi OIoi#%?-.abcdfghjklmnpqrstvwxyz0123456789euEUABCDFGHJKLMNPQRSTVWXYZ" , "OEUOI OIOI#%?-.ABCDFGHJKLMNPQRSTVWXYZ0123456789EUEUABCDFGHJKLMNPQRSTVWXYZ", + "OEUoi OIoi#%?abcdfghjklmnpqrstvwxyz0123456789euEUABCDFGHJKLMNPQRSTVWXYZ", "OEUOI OIOI#%?ABCDFGHJKLMNPQRSTVWXYZ0123456789EUEUABCDFGHJKLMNPQRSTVWXYZ", + ".", ".", + "-", "-", + "-abc", "-ABC", + "12.34", "12.34", + " Oio 12.AU ", "OIO 12.AU", + "OMN 112.3AU", "OMN 112.3AU", + "OMN 112.3EU", "OMN 112.3EU", + "OMN 100.3EU", "OMN 100.3EU", + "OMN 1Oo.3EU", "OMN 1OO.3EU", + "49.4V", "49.4V", + "NLD 49.4V-xx123", "NLD 49.4V-XX123", + "xx.xx", "XX.XX", + "xx.xxx", "XX.XXX", + "xxx.xx", "XXX.XX", + "xx.xxxx", "XX.XXXX", + "xxx.xxx", "XXX.XXX", + "xxxx.xx", "XXXX.XX", + "xxx.xxxx", "XXX.XXXX", + "xxxx.xxx", "XXXX.XXX", + "xxxx.xxxx", "XXXX.XXXX", + "xxxxx.xxxx", "XXXXX.XXXX", + "pq.rs", "PQ.RS", + "bc.123", "BC.123", + "123.xy", "123.XY", + " nld 12.34E0", "NLD 12.34E0", + "VVX.xxx", "VVX.XXX", + "x123.xx", "X123.XX", + "xxx.xxxx", "XXX.XXXX", + "12xx.xxx", "12XX.XXX", + "xxxx.xx12", "XXXX.XX12", + "99zxx.xxxx", "99ZXX.XXXX", + "xx.xx-P", "XX.XX-P", + "xx.xxx-pq", "XX.XXX-PQ", + "xxx.xx-123", "XXX.XX-123", + "xx.xxxx-pqRS", "XX.XXXX-PQRS", + "xxx.xxx-PQRSTUVW", "XXX.XXX-PQRSTUVW", + "xxxx.xx-pqrstuvw", "XXXX.XX-PQRSTUVW", + "xxx.xxxx-PQrsTU", "XXX.XXXX-PQRSTU", + "xxxx.xxx-09876543", "XXXX.XXX-09876543", + "xxxx.xxxx-PQRSTUVW", "XXXX.XXXX-PQRSTUVW", + "xxxxx.xxxx-PQRSTUVW", "XXXXX.XXXX-PQRSTUVW", + "pq.rs-PQRSTUVW", "PQ.RS-PQRSTUVW", + "bc.123-PQRSTUVW", "BC.123-PQRSTUVW", + "123.xy-PQRSTUVW", "123.XY-PQRSTUVW", + "12.34E0-PQRSTUVW", "12.34E0-PQRSTUVW", + "VVX.xxx-PQRSTUVW", "VVX.XXX-PQRSTUVW", + "x123.xx-PQRSTUVW", "X123.XX-PQRSTUVW", + "xxx.xxxx-PQRSTUVW", "XXX.XXXX-PQRSTUVW", + "12xx.xxx-PQRSTUVW", "12XX.XXX-PQRSTUVW", + "xxxx.xx12-PQRSTUVW", "XXXX.XX12-PQRSTUVW", + "99zxx.xxxx-PQRSTUVW", "99ZXX.XXXX-PQRSTUVW", + "", "" + ]; - // see if alphabets (re)convert as expected - var str = "OEUoi OIoi#%?-.abcdfghjklmnpqrstvwxyz0123456789ABCDFGHJKLMNPQRSTVWXYZ"; - var expect = "OEUOI OIOI#%?-.ABCDFGHJKLMNPQRSTVWXYZ0123456789ABCDFGHJKLMNPQRSTVWXYZ"; - nrTests++; - var enc = convertToAlphabet(str, i); - var dec = convertToAlphabet(enc, 0); - if (dec != expect) { - nrErrors++; - out('convertToAlphabet(convertToAlphabet("' + str + '",' + i + '))= "' + dec + '", expected "' + expect + '"'); - } + function alphabet_tests() { + out(MAXLANS + ' alphabets'); - // see if E/U vowelled mapcodes (re)convert as expected - str = "OMN 112.3AU"; - expect = str; - nrTests++; - dec = convertToAlphabet(convertToAlphabet(str, i), 0); - if (dec != expect) { - nrErrors++; - out('convertToAlphabet(convertToAlphabet("' + str + '",' + i + '))= "' + dec + '", expected "' + expect + '"'); + for (var t = 0; t < testpairs.length; t += 2) { + for (var i = 0; i < MAXLANS; i++) { + // see if alphabets (re)convert as expected + var str = testpairs[t]; + var expect = testpairs[t + 1]; + nrTests++; + var enc = convertToAlphabet(str, i); + var dec = convertToAlphabet(enc, 0); + if (dec != expect) { + nrErrors++; + out('convertToAlphabet(convertToAlphabet("' + str + '",' + i + '))= "' + dec + '", expected "' + expect + '"'); + } } } } @@ -145,6 +196,13 @@

Mapcode Javascript Unit Tests

r = encodeWithPrecision(y, x, precision); for (i = 0; i < r.length; i++) { str = r[i].fullmapcode; + + dec = convertToAlphabet(convertToAlphabet(str, 14), 0); + if (dec != str) { + nrError++; + out('*** lanencode ' + str); + } + nrTests++; var p = decode(str); if (p) { @@ -504,18 +562,18 @@

Mapcode Javascript Unit Tests

function stepper() { switch (dostep) { case 0: - out('Mapcode Javascript version ' + mapcode_javaversion); + out('Mapcode JavaScript version ' + mapcode_javaversion); break; case 1: - out('
Alphabet tests'); + out('
Alphabet tests'); break; case 2: alphabet_tests(); break; case 3: - out('
Distance tests'); + out('
Distance tests'); distance_tests(); - out('
Territory tests'); + out('
Territory tests'); out((ccode_earth + 1) + ' territories'); test_territory_insides(); break; @@ -530,7 +588,7 @@

Mapcode Javascript Unit Tests

test_failing_decodes(); break; case 7: - out('
Encode/decode tests'); + out('
Encode/Decode tests'); break; case 8: if (test_encodes_decodes()) { @@ -538,7 +596,7 @@

Mapcode Javascript Unit Tests

} break; case 9: - out('
Edge-case encode/decode tests'); + out('
Edge-case Encode/Decode tests'); break; case 10: if (test_corner_encodes()) { From c28b6237ef9811695b673932f375ccf5c5c5ee81 Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Sun, 2 Oct 2016 13:28:32 +0200 Subject: [PATCH 29/54] Fixed arabic --- mapcode.js | 18 ++++++- unittest/unittest.html | 116 +++++++++++++++++++++++++++++++++-------- 2 files changed, 109 insertions(+), 25 deletions(-) diff --git a/mapcode.js b/mapcode.js index 8f6c9e4..f28a4aa 100644 --- a/mapcode.js +++ b/mapcode.js @@ -1143,10 +1143,17 @@ function showinlan(str, lan, asHTML) { } // unpack for languages that do not support E and U - if (asc2lan[lan][4] == 63) { + if (lan == 1) { // greek + var rest = ''; + var h = str.indexOf('-'); + if (h >= 0) { + rest = str.substring(h); + str = str.substring(0, h); + } if (str.indexOf('E') >= 0 || str.indexOf('U') >= 0) { str = aeu_pack(aeu_unpack(str), true); } + str += rest; } // substitute @@ -1210,7 +1217,14 @@ function to_ascii(str) { p++; } if (result.charAt(p) == 'A') { - result = result.substr(0, p) + aeu_pack(aeu_unpack(result.substr(p)), false); + var mc = result.substr(p); + var rest = ''; + var h = mc.indexOf('-'); + if (h >= 0) { + rest = mc.substring(h); + mc = mc.substring(0, h); + } + result = result.substr(0, p) + aeu_pack(aeu_unpack(mc), false) + rest; /* v1.50 repack A-voweled to AEU-voweled */ } diff --git a/unittest/unittest.html b/unittest/unittest.html index a04eb8d..86b6b4f 100644 --- a/unittest/unittest.html +++ b/unittest/unittest.html @@ -45,11 +45,11 @@

Mapcode Javascript Unit Tests

var nrWarnings = 0; // test the alphabet conversion routines - var testpairs = [ -// "OIoi#%?-.abcdfghjklmnpqrstvwxyz0123456789ABCDFGHJKLMNPQRSTVWXYZ","OIOI#%?-.ABCDFGHJKLMNPQRSTVWXYZ0123456789ABCDFGHJKLMNPQRSTVWXYZ", -// "OEUoi OIoi#%?-.abcdfghjklmnpqrstvwxyz0123456789ABCDFGHJKLMNPQRSTVWXYZ","OEUOI OIOI#%?-.ABCDFGHJKLMNPQRSTVWXYZ0123456789ABCDFGHJKLMNPQRSTVWXYZ", -// "OEUoi OIoi#%?-.abcdfghjklmnpqrstvwxyz0123456789euEUABCDFGHJKLMNPQRSTVWXYZ" , "OEUOI OIOI#%?-.ABCDFGHJKLMNPQRSTVWXYZ0123456789EUEUABCDFGHJKLMNPQRSTVWXYZ", + "12.34E0-PQRSTZVW", "12.34E0-PQRSTZVW", + "OIoi#%?-.abcdfghjklmnpqrstvwxyz0123456789ABCDFGHJKLMNPQRSTVWXYZ", "OIOI#%?-.ABCDFGHJKLMNPQRSTVWXYZ0123456789ABCDFGHJKLMNPQRSTVWXYZ", + "OEUoi OIoi#%?-.abcdfghjklmnpqrstvwxyz0123456789ABCDFGHJKLMNPQRSTVWXYZ", "OEUOI OIOI#%?-.ABCDFGHJKLMNPQRSTVWXYZ0123456789ABCDFGHJKLMNPQRSTVWXYZ", + "OEUoi OIoi#%?-.abcdfghjklmnpqrstvwxyz0123456789euEUABCDFGHJKLMNPQRSTVWXYZ", "OEUOI OIOI#%?-.ABCDFGHJKLMNPQRSTVWXYZ0123456789EUEUABCDFGHJKLMNPQRSTVWXYZ", "OEUoi OIoi#%?abcdfghjklmnpqrstvwxyz0123456789euEUABCDFGHJKLMNPQRSTVWXYZ", "OEUOI OIOI#%?ABCDFGHJKLMNPQRSTVWXYZ0123456789EUEUABCDFGHJKLMNPQRSTVWXYZ", ".", ".", "-", "-", @@ -59,7 +59,7 @@

Mapcode Javascript Unit Tests

"OMN 112.3AU", "OMN 112.3AU", "OMN 112.3EU", "OMN 112.3EU", "OMN 100.3EU", "OMN 100.3EU", - "OMN 1Oo.3EU", "OMN 1OO.3EU", + "OMN 1Oo.3Oo", "OMN 1OO.3OO", "49.4V", "49.4V", "NLD 49.4V-xx123", "NLD 49.4V-XX123", "xx.xx", "XX.XX", @@ -86,25 +86,74 @@

Mapcode Javascript Unit Tests

"xx.xxx-pq", "XX.XXX-PQ", "xxx.xx-123", "XXX.XX-123", "xx.xxxx-pqRS", "XX.XXXX-PQRS", - "xxx.xxx-PQRSTUVW", "XXX.XXX-PQRSTUVW", - "xxxx.xx-pqrstuvw", "XXXX.XX-PQRSTUVW", - "xxx.xxxx-PQrsTU", "XXX.XXXX-PQRSTU", + "xxx.xxx-PQRSTZVW", "XXX.XXX-PQRSTZVW", + "xxxx.xx-pqrstZvw", "XXXX.XX-PQRSTZVW", + "xxx.xxxx-PQrsTZ", "XXX.XXXX-PQRSTZ", "xxxx.xxx-09876543", "XXXX.XXX-09876543", - "xxxx.xxxx-PQRSTUVW", "XXXX.XXXX-PQRSTUVW", - "xxxxx.xxxx-PQRSTUVW", "XXXXX.XXXX-PQRSTUVW", - "pq.rs-PQRSTUVW", "PQ.RS-PQRSTUVW", - "bc.123-PQRSTUVW", "BC.123-PQRSTUVW", - "123.xy-PQRSTUVW", "123.XY-PQRSTUVW", - "12.34E0-PQRSTUVW", "12.34E0-PQRSTUVW", - "VVX.xxx-PQRSTUVW", "VVX.XXX-PQRSTUVW", - "x123.xx-PQRSTUVW", "X123.XX-PQRSTUVW", - "xxx.xxxx-PQRSTUVW", "XXX.XXXX-PQRSTUVW", - "12xx.xxx-PQRSTUVW", "12XX.XXX-PQRSTUVW", - "xxxx.xx12-PQRSTUVW", "XXXX.XX12-PQRSTUVW", - "99zxx.xxxx-PQRSTUVW", "99ZXX.XXXX-PQRSTUVW", + "xxxx.xxxx-PQRSTZVW", "XXXX.XXXX-PQRSTZVW", + "xxxxx.xxxx-PQRSTZVW", "XXXXX.XXXX-PQRSTZVW", + "pq.rs-PQRSTZVW", "PQ.RS-PQRSTZVW", + "bc.123-PQRSTZVW", "BC.123-PQRSTZVW", + "123.xy-PQRSTZVW", "123.XY-PQRSTZVW", + "VVX.xxx-PQRSTZVW", "VVX.XXX-PQRSTZVW", + "x123.xx-PQRSTZVW", "X123.XX-PQRSTZVW", + "xxx.xxxx-PQRSTZVW", "XXX.XXXX-PQRSTZVW", + "12xx.xxx-PQRSTZVW", "12XX.XXX-PQRSTZVW", + "xxxx.xx12-PQRSTZVW", "XXXX.XX12-PQRSTZVW", + "99zxx.xxxx-PQRSTZVW", "99ZXX.XXXX-PQRSTZVW", + "", "" + ]; + + var greek_versions = [ + "26.53UK", "\u039161.328\u03A5", + "FR.B016", "\u0395\u03A81.0716", + "000.EU", "\u0391\u0030\u0030.23", + "PQ.YZ", "\u03a1\u0398.57\u0396", + "PQ.XYZ", "\u03a1\u0398.56\u03a5\u0396", + "PQR.YZ", "\u03a1\u0398.89\u03a5\u0396", + "PQ.RXYZ", "\u03a1\u03983.\u03a70\u03a5\u0396", + "PQR.XYZ", "\u03a1\u03986.\u03a71\u03a5\u0396", + "PQRX.YZ", "\u03a1\u03989.\u03a72\u03a5\u0396", + "PQR.SXYZ", "\u03a1\u03984.\u03a3\u03a79\u03a5\u0396", + "PQRS.XYZ", "\u03a1\u03988.\u03a3\u03a79\u03a5\u0396", + "PQRS.WXYZ", "\u03a1\u03987\u03a3.8\u03a9\u03a72\u03a5", + "PQRST.WXYZ", "\u03a1\u03987\u03a3\u03a4.8\u03a9\u03a72\u03a5", + "P4.YZ", "\u03a14.\u03a5\u0396", + "PQ.4Z", "\u03a1\u0398.4\u0396", + "PQ.4YZ", "\u03a1\u0398.26\u03a5\u0396", + "PQ4.YZ", "\u03a1\u03984.\u03a5\u0396", + "PQ.46YZ", "\u03a1\u03981.61\u03a5\u0396", + "PQ4.6YZ", "\u03a1\u03984.6\u03a5\u0396", + "PQ46.YZ", "\u03a1\u039846.\u03a5\u0396", + "PQ4.S6YZ", "\u03a1\u03982.\u03a366\u03a5\u0396", + "PQ4S.6YZ", "\u03a1\u03984\u03a3.6\u03a5\u0396", + "PQ4S.W6YZ", "\u03a1\u03984\u03a3.\u03a96\u03a5\u0396", + "PQ4PQ.6YZ9", "\u03a1\u03984\u03a1\u0398.6\u03a5\u03969", + "PQ.YZ-BCD", "\u03a1\u0398.57\u0396-\u0392\u039e\u0394", + "PQ.XYZ-BCD", "\u03a1\u0398.56\u03a5\u0396-\u0392\u039e\u0394", + "PQR.YZ-BCD", "\u03a1\u0398.89\u03a5\u0396-\u0392\u039e\u0394", + "PQ.RXYZ-BCD", "\u03a1\u03983.\u03a70\u03a5\u0396-\u0392\u039e\u0394", + "PQR.XYZ-BCD", "\u03a1\u03986.\u03a71\u03a5\u0396-\u0392\u039e\u0394", + "PQRX.YZ-BCD", "\u03a1\u03989.\u03a72\u03a5\u0396-\u0392\u039e\u0394", + "PQR.SXYZ-BCD", "\u03a1\u03984.\u03a3\u03a79\u03a5\u0396-\u0392\u039e\u0394", + "PQRS.XYZ-BCD", "\u03a1\u03988.\u03a3\u03a79\u03a5\u0396-\u0392\u039e\u0394", + "PQRS.WXYZ-BCD", "\u03a1\u03987\u03a3.8\u03a9\u03a72\u03a5-\u0392\u039e\u0394", + "PQRST.WXYZ-BCD", "\u03a1\u03987\u03a3\u03a4.8\u03a9\u03a72\u03a5-\u0392\u039e\u0394", + "P4.YZ-BCD", "\u03a14.\u03a5\u0396-\u0392\u039e\u0394", + "PQ.4Z-BCD", "\u03a1\u0398.4\u0396-\u0392\u039e\u0394", + "PQ.4YZ-BCD", "\u03a1\u0398.26\u03a5\u0396-\u0392\u039e\u0394", + "PQ4.YZ-BCD", "\u03a1\u03984.\u03a5\u0396-\u0392\u039e\u0394", + "PQ.46YZ-BCD", "\u03a1\u03981.61\u03a5\u0396-\u0392\u039e\u0394", + "PQ4.6YZ-BCD", "\u03a1\u03984.6\u03a5\u0396-\u0392\u039e\u0394", + "PQ46.YZ-BCD", "\u03a1\u039846.\u03a5\u0396-\u0392\u039e\u0394", + "PQ4.S6YZ-BCD", "\u03a1\u03982.\u03a366\u03a5\u0396-\u0392\u039e\u0394", + "PQ4S.6YZ-BCD", "\u03a1\u03984\u03a3.6\u03a5\u0396-\u0392\u039e\u0394", + "PQ4S.W6YZ-BCD", "\u03a1\u03984\u03a3.\u03a96\u03a5\u0396-\u0392\u039e\u0394", + "PQ4PQ.6YZ9-BCD", "\u03a1\u03984\u03a1\u0398.6\u03a5\u03969-\u0392\u039e\u0394", "", "" ]; + function alphabet_tests() { out(MAXLANS + ' alphabets'); @@ -118,10 +167,29 @@

Mapcode Javascript Unit Tests

var dec = convertToAlphabet(enc, 0); if (dec != expect) { nrErrors++; - out('convertToAlphabet(convertToAlphabet("' + str + '",' + i + '))= "' + dec + '", expected "' + expect + '"'); + out('*** ERROR ** convertToAlphabet(convertToAlphabet("' + str + '",' + i + '))= "' + dec + '", expected "' + expect + '"'); } } } + + for (var t = 0; t < greek_versions.length; t += 2) { + // see if alphabets (re)convert as expected + var str = greek_versions[t]; + var expect = greek_versions[t + 1]; + nrTests++; + var enc = convertToAlphabet(str, 1); // to greek + if (enc != expect) { + nrErrors++; + out('*** ERROR *** convertToAlphabet("' + str + '",GREEK))= "' + enc + '", expected "' + expect + '"'); + } + var dec = convertToAlphabet(enc, 0); + if (dec != str) { + nrErrors++; + out('*** ERROR *** convertToAlphabet(convertToAlphabet("' + str + '",' + i + '))= "' + dec + '", expected "' + str + '"'); + } + } + + } function printGeneratedMapcodes(r, name) { @@ -197,10 +265,12 @@

Mapcode Javascript Unit Tests

for (i = 0; i < r.length; i++) { str = r[i].fullmapcode; - dec = convertToAlphabet(convertToAlphabet(str, 14), 0); + // check conversion back and forth via Arabic script + nrTests++; + var dec = convertToAlphabet(convertToAlphabet(str, 14), 0); if (dec != str) { nrError++; - out('*** lanencode ' + str); + out('*** ERROR *** convert back and forth failed: ' + str); } nrTests++; From 498485207abf12c5fb0078514484f9e9db71b22e Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Mon, 3 Oct 2016 11:15:18 +0200 Subject: [PATCH 30/54] Fixed data --- README.md | 12 ++++++++---- mapcode.js | 2 +- ndata.js | 4 ++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 4758bf9..70aaa5c 100644 --- a/README.md +++ b/README.md @@ -47,16 +47,20 @@ To run the Javascript unit tests, simply open the file `unittest/unittest/html`. # Version History +* 2.3.1 + + Minor fixes to prevent some compiler warnings, or multiple inclusion of `.h` files. + + Minor data fix (`ndata.js`) for Gansu Province, China (where mountain range extending further west). + * 2.3.0 Arabic script added. - Greek script extended to be AEU-capable. - Tibetan script changed so all characters can be typed on a computer keyboard without using the SHIFT key. - Greek, Hebrew and Arab, the languages that have (implied) vowels in mapcode sequences, have been extended with ABJAD conversion, - to prevent more than two consecutive non-digits from occurring. + Greek, Hebrew and Arabic, the scripts that have (implied) vowels in mapcode sequences, have been extended with + ABJAD conversion, to prevent more than two consecutive non-digits from occurring. NOTE: as a result, mapcodes in Greek, Arab and Hebrew scripts are now often one character longer than in the roman script. * 2.2.0 diff --git a/mapcode.js b/mapcode.js index f28a4aa..1946d45 100644 --- a/mapcode.js +++ b/mapcode.js @@ -116,7 +116,7 @@ var parents2 = "US,IN,CA,AU,MX,BR,RU,CN,"; var ccode_start = 112; // NLD var mapcode_cversion = "2.0.2"; -var mapcode_dataversion = "2.2.0"; +var mapcode_dataversion = "2.3.0"; // *************************** mapcode_org ********************* diff --git a/ndata.js b/ndata.js index 21c4134..67626f4 100644 --- a/ndata.js +++ b/ndata.js @@ -2515,7 +2515,7 @@ var data_minx = [ 97500000,91031470,90910000,88697155,91684812,97058740,91953340,94237896,92216363,90862942, 80018608,91632196,98499896,94439842,84029573,90022228,87013337,93031119,78380000,78380000, 103784752,103307533,100351605,103104190,104072649,105613000,102128428,98193980,106570000,102521160, -98387000,102321286,99663928,96267754,89350000,92750000,101693766,101463360,102040000,101569028, +98387000,102321286,99663928,96267754,89350000,92290000,101693766,101463360,102040000,101569028, 95239887,94763300,101505500,100481032,100043584,102695000,100195620,99797354,98644443,92904342, 89350000,89350000,87550718,87323072,85938073,87189832,80179592,75903280,81242332,86087260, 84806664,84804393,88030717,93418501,79860627,85008964,77170628,82894560,84353849,80689556, @@ -5791,7 +5791,7 @@ var data_maxx = [ 8720000,159302,520998,382331,170975,174719,174719,171807,323927,262422, 176383,171807,171807,140315,144053,3008891,3008891,3008891,20788000,20788000, 146599,665282,221990,211419,214302,395740,190943,193439,266859,189279, -193439,3247219,3366383,3396174,19390000,15990000,122416,578088,298819,215743, +193439,3247219,3366383,3396174,19390000,16450000,122416,578088,298819,215743, 218626,308742,258543,185535,228824,299934,180959,3277010,3157846,3277010, 19390000,13790000,119164,476655,466054,206335,198015,193439,206335,199679, 173271,170213,181765,165797,152546,173271,155944,163079,3664293,3664293, From e2c4bcbf0d6991645aee3bd82408e79d93a5d31b Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Mon, 3 Oct 2016 11:40:25 +0200 Subject: [PATCH 31/54] Updated 2.3.1 --- mapcode.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapcode.js b/mapcode.js index 1946d45..b15f04f 100644 --- a/mapcode.js +++ b/mapcode.js @@ -120,7 +120,7 @@ var mapcode_dataversion = "2.3.0"; // *************************** mapcode_org ********************* -var mapcode_javaversion = '2.3.0/Data' + mapcode_dataversion; +var mapcode_javaversion = '2.3.1/Data' + mapcode_dataversion; /// PRIVATE returns string without leading spaces and plus-signs, and trailing spaces function trim(str) { From b3a5bc493567e194f21008656cc5426d95fbb3ee Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Thu, 20 Oct 2016 15:39:38 +0200 Subject: [PATCH 32/54] Added alphabets --- README.md | 18 ++ ctrynams.js | 52 +++--- ctrynams_short.js | 52 +++--- mapcode.js | 375 +++++++++++++++++++++++++---------------- unittest/unittest.html | 8 +- 5 files changed, 308 insertions(+), 197 deletions(-) diff --git a/README.md b/README.md index 70aaa5c..77e43cd 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,24 @@ To run the Javascript unit tests, simply open the file `unittest/unittest/html`. # Version History + +* 2.4.0 + + Added scripts for Korean (Choson'gul / Hangul), Burmese, Khmer, Sinhalese, Thaana (Maldivan), + Chinese (Zhuyin, Bopomofo), Tifinagh (Berber), Tamil, Amharic, Telugu, Odia, Kannada, Gujarati. + + Renamed language strings to more correct terms (Malay to Malayalam; Hindi to Devanagari). + + Added var `alphabetsForTerritory[t]`, returning the most commonly used alphabets for territory `t`. + + Improved some characters for Arabic and Devanagari. + + Fixed Bengali to also support Assamese. + + For some alphabets, removed recognition of letters `I` and/or `O` unless looking like digits `1` and/or `0`. + + Replaced internal encoded `entity_iso[]` array by non-encoded `iso3166alpha[]`. + * 2.3.1 Minor fixes to prevent some compiler warnings, or multiple inclusion of `.h` files. diff --git a/ctrynams.js b/ctrynams.js index 5f7637d..7769eea 100644 --- a/ctrynams.js +++ b/ctrynams.js @@ -14,10 +14,10 @@ * limitations under the License. */ -// *** GENERATED FILE, DO NOT CHANGE OR PRETTIFY *** +// *** GENERATED FILE (coords.cpp), DO NOT CHANGE OR PRETTIFY *** var isofullname = [ -"Vatican City State (Holy See)", +"Vatican (Holy See) (_ City State)", "Monaco (Principality of _)", "Gibraltar", "Tokelau", @@ -28,8 +28,8 @@ var isofullname = [ "Macau (Aomen)", "Sint Maarten", "Saint Martin (Collectivity of _)", -"Norfolk and Philip Island (Philip Island)", -"Pitcairn Group of Islands", +"Norfolk and Philip Island (Philip Island) (Norfolk Island)", +"Pitcairn Islands (Pitcairn, Henderson, Ducie and Oeno Islands)", "Bouvet Island", "Bermuda (Somers Isles)", "British Indian Ocean Territory", @@ -39,29 +39,29 @@ var isofullname = [ "Montserrat", "Jersey (Bailiwick of _)", "Christmas Island", -"Wallis and Futuna (Futuna) (Collectivity of the _ Islands)", +"Wallis and Futuna (Futuna) (Wallis) (Collectivity of the _ Islands)", "British Virgin Islands (Virgin Islands, British)", "Liechtenstein (Principality of _)", "Aruba", "Marshall Islands (Republic of the _)", "American Samoa (Samoa, American)", "Cook Islands", -"Saint Pierre and Miquelon (Miquelon) (Collectivity of _)", +"Saint Pierre and Miquelon (Miquelon) (Saint Pierre) (Collectivity of _)", "Niue", -"Saint Kitts and Nevis (Nevis) (Federation of _)", +"Saint Kitts and Nevis (Nevis) (Saint Kitts) (Federation of _)", "Cayman islands", -"Bonaire, St Eustasuis and Saba (Saba) (St Eustasius)", +"Bonaire, St Eustasuis and Saba (Bonaire) (Saba) (St Eustasius)", "Maldives (Republic of _)", -"Saint Helena, Ascension and Tristan da Cunha (Ascension) (Tristan da Cunha)", +"Saint Helena, Ascension and Tristan da Cunha (Saint Helena) (Ascension) (Tristan da Cunha)", "Malta (Republic of _)", "Grenada", "Virgin Islands of the United States (US Virgin Islands) (American Virgin Islands)", "Mayotte (Maore)", -"Svalbard and Jan Mayen (Jan Mayen) (Spitsbergen)", -"Saint Vincent and the Grenadines (Grenadines)", -"Heard Island and McDonald Islands (McDonald Islands)", +"Svalbard and Jan Mayen (Svalbard) (Jan Mayen) (Spitsbergen)", +"Saint Vincent and the Grenadines (Saint Vincent) (Grenadines)", +"Heard Island and McDonald Islands (Heard Island) (McDonald Islands)", "Barbados", -"Antigua and Barbuda (Barbuda)", +"Antigua and Barbuda (Antigua) (Barbuda)", "Curacao", "Seychelles (Republic of _)", "Palau (Republic of _)", @@ -76,8 +76,8 @@ var isofullname = [ "Dominica (Commonwealth of _)", "Bahrain (Kingdom of _)", "Kiribati (Republic of _)", -"Turks and Caicos Islands (Caicos Islands)", -"Sao Tome and Principe (Principe) (Democratic Republic of _)", +"Turks and Caicos Islands (Turks Islands) (Caicos Islands)", +"Sao Tome and Principe (Sao Tome) (Principe) (Democratic Republic of _)", "Hong Kong (Xianggang)", "Martinique", "Faroe Islands", @@ -87,10 +87,10 @@ var isofullname = [ "Reunion", "Luxembourg (Grand Duchy of _)", "Samoa (Independent State of _)", -"South Georgia and the South Sandwich Islands (South Sandwich Islands)", +"South Georgia and the South Sandwich Islands (South Georgia) (South Sandwich Islands)", "French Polynesia (Collectivity of _)", "Cape Verde (Cabo Verde) (Republic of Cabo Verde)", -"Trinidad and Tobago (Republic of _) (Tobago)", +"Trinidad and Tobago (Republic of _) (Trinidad) (Tobago)", "Brunei (Nation of _, the Abode of Peace)", "French Southern and Antarctic Lands", "Puerto Rico (Commonwealth of _)", @@ -99,7 +99,7 @@ var isofullname = [ "Jamaica", "Gambia (The Gambia) (Republic of the _)", "Qatar (State of _)", -"Falkland Islands", +"Falkland Islands (The Falklands)", "Vanuatu (Republic of _)", "Montenegro", "Bahamas (Commonwealth of the _)", @@ -154,7 +154,7 @@ var isofullname = [ "Jordan (Hashemite Kingdom of _) (Kingdom of _)", "Portugal (Portuguese Republic)", "Hungary (Republic of _)", -"South Korea (Republic of Korea)", +"South Korea (Republic of Korea) (Korea, South)", "Iceland", "Guatemala (Republic of _)", "Cuba (Republic of _)", @@ -164,9 +164,9 @@ var isofullname = [ "Benin (Republic of _)", "Eritrea (State of _)", "Malawi (Republic of _)", -"North Korea (Democratic People's Republic of Korea)", +"North Korea (Democratic People's Republic of Korea) (Korea, North)", "Nicaragua (Republic of _)", -"Greece (Hellenic Republic)", +"Greece (Hellenic Republic) (Hellas)", "Tajikistan (Republic of _)", "Bangladesh (People's Republic of _)", "Nepal (Federal Democratic Republic of _)", @@ -183,7 +183,7 @@ var isofullname = [ "Romania", "Ghana (Republic of _)", "Uganda (Republic of _)", -"United Kingdom (Scotland) (Great Britain) (Northern Ireland) (Ireland, Northern) (Britain) (United Kingdom of Great Britain and Northern Ireland)", +"United Kingdom (Scotland) (Great Britain) (England) (Northern Ireland) (Ireland, Northern) (Britain) (United Kingdom of Great Britain and Northern Ireland)", "Guinea (Republic of _) (Guinea-Conakry)", "Ecuador (Republic of _)", "Western Sahara (Sahrawi Arab Democratic Republic)", @@ -289,9 +289,9 @@ var isofullname = [ "Kazakhstan (Republic of _)", "Argentina (Argentine Republic)", "Daman and Diu", -"Dadra and Nagar Haveli", +"Dadra and Nagar Haveli (Dadra) (Nagar Haveli)", "Chandigarh", -"Andaman and Nicobar", +"Andaman and Nicobar (Andaman) (Nicobar)", "Lakshadweep", "Delhi (National Capital Territory of _)", "Meghalaya", @@ -310,7 +310,7 @@ var isofullname = [ "Kerala", "Tamil Nadu", "Himachal Pradesh", -"Jammu and Kashmir", +"Jammu and Kashmir (Jammu) (Kashmir)", "Chhattisgarh", "Jharkhand", "Karnataka", @@ -417,7 +417,7 @@ var isofullname = [ "Quebec", "Saskatchewan", "Manitoba", -"Newfoundland and Labrador (Labrador)", +"Newfoundland and Labrador (Newfoundland) (Labrador)", "New Brunswick", "Nova Scotia", "Prince Edward Island", diff --git a/ctrynams_short.js b/ctrynams_short.js index f7d5710..8dbd9f3 100644 --- a/ctrynams_short.js +++ b/ctrynams_short.js @@ -14,10 +14,10 @@ * limitations under the License. */ -// *** GENERATED FILE, DO NOT CHANGE OR PRETTIFY *** +// *** GENERATED FILE (coords.cpp), DO NOT CHANGE OR PRETTIFY *** var isofullname = [ -"Vatican City State (Holy See)", +"Vatican (Holy See)", "Monaco", "Gibraltar", "Tokelau", @@ -28,8 +28,8 @@ var isofullname = [ "Macau (Aomen)", "Sint Maarten", "Saint Martin", -"Norfolk and Philip Island (Philip Island)", -"Pitcairn Group of Islands", +"Norfolk and Philip Island (Philip Island) (Norfolk Island)", +"Pitcairn Islands (Pitcairn, Henderson, Ducie and Oeno Islands)", "Bouvet Island", "Bermuda (Somers Isles)", "British Indian Ocean Territory", @@ -39,29 +39,29 @@ var isofullname = [ "Montserrat", "Jersey", "Christmas Island", -"Wallis and Futuna (Futuna)", +"Wallis and Futuna (Futuna) (Wallis)", "British Virgin Islands (Virgin Islands, British)", "Liechtenstein", "Aruba", "Marshall Islands", "American Samoa (Samoa, American)", "Cook Islands", -"Saint Pierre and Miquelon (Miquelon)", +"Saint Pierre and Miquelon (Miquelon) (Saint Pierre)", "Niue", -"Saint Kitts and Nevis (Nevis)", +"Saint Kitts and Nevis (Nevis) (Saint Kitts)", "Cayman islands", -"Bonaire, St Eustasuis and Saba (Saba) (St Eustasius)", +"Bonaire, St Eustasuis and Saba (Bonaire) (Saba) (St Eustasius)", "Maldives", -"Saint Helena, Ascension and Tristan da Cunha (Ascension) (Tristan da Cunha)", +"Saint Helena, Ascension and Tristan da Cunha (Saint Helena) (Ascension) (Tristan da Cunha)", "Malta", "Grenada", "Virgin Islands of the United States (US Virgin Islands) (American Virgin Islands)", "Mayotte (Maore)", -"Svalbard and Jan Mayen (Jan Mayen) (Spitsbergen)", -"Saint Vincent and the Grenadines (Grenadines)", -"Heard Island and McDonald Islands (McDonald Islands)", +"Svalbard and Jan Mayen (Svalbard) (Jan Mayen) (Spitsbergen)", +"Saint Vincent and the Grenadines (Saint Vincent) (Grenadines)", +"Heard Island and McDonald Islands (Heard Island) (McDonald Islands)", "Barbados", -"Antigua and Barbuda (Barbuda)", +"Antigua and Barbuda (Antigua) (Barbuda)", "Curacao", "Seychelles", "Palau", @@ -76,8 +76,8 @@ var isofullname = [ "Dominica", "Bahrain", "Kiribati", -"Turks and Caicos Islands (Caicos Islands)", -"Sao Tome and Principe (Principe)", +"Turks and Caicos Islands (Turks Islands) (Caicos Islands)", +"Sao Tome and Principe (Sao Tome) (Principe)", "Hong Kong (Xianggang)", "Martinique", "Faroe Islands", @@ -87,10 +87,10 @@ var isofullname = [ "Reunion", "Luxembourg", "Samoa", -"South Georgia and the South Sandwich Islands (South Sandwich Islands)", +"South Georgia and the South Sandwich Islands (South Georgia) (South Sandwich Islands)", "French Polynesia", "Cape Verde (Cabo Verde) (Republic of Cabo Verde)", -"Trinidad and Tobago (Tobago)", +"Trinidad and Tobago (Trinidad) (Tobago)", "Brunei", "French Southern and Antarctic Lands", "Puerto Rico", @@ -99,7 +99,7 @@ var isofullname = [ "Jamaica", "Gambia (The Gambia)", "Qatar", -"Falkland Islands", +"Falkland Islands (The Falklands)", "Vanuatu", "Montenegro", "Bahamas", @@ -154,7 +154,7 @@ var isofullname = [ "Jordan", "Portugal (Portuguese Republic)", "Hungary", -"South Korea (Republic of Korea)", +"South Korea (Republic of Korea) (Korea, South)", "Iceland", "Guatemala", "Cuba", @@ -164,9 +164,9 @@ var isofullname = [ "Benin", "Eritrea", "Malawi", -"North Korea (Democratic People's Republic of Korea)", +"North Korea (Democratic People's Republic of Korea) (Korea, North)", "Nicaragua", -"Greece (Hellenic Republic)", +"Greece (Hellenic Republic) (Hellas)", "Tajikistan", "Bangladesh", "Nepal", @@ -183,7 +183,7 @@ var isofullname = [ "Romania", "Ghana", "Uganda", -"United Kingdom (Scotland) (Great Britain) (Northern Ireland) (Ireland, Northern) (Britain) (United Kingdom of Great Britain and Northern Ireland)", +"United Kingdom (Scotland) (Great Britain) (England) (Northern Ireland) (Ireland, Northern) (Britain) (United Kingdom of Great Britain and Northern Ireland)", "Guinea (Guinea-Conakry)", "Ecuador", "Western Sahara (Sahrawi Arab Democratic Republic)", @@ -289,9 +289,9 @@ var isofullname = [ "Kazakhstan", "Argentina (Argentine Republic)", "Daman and Diu", -"Dadra and Nagar Haveli", +"Dadra and Nagar Haveli (Dadra) (Nagar Haveli)", "Chandigarh", -"Andaman and Nicobar", +"Andaman and Nicobar (Andaman) (Nicobar)", "Lakshadweep", "Delhi", "Meghalaya", @@ -310,7 +310,7 @@ var isofullname = [ "Kerala", "Tamil Nadu", "Himachal Pradesh", -"Jammu and Kashmir", +"Jammu and Kashmir (Jammu) (Kashmir)", "Chhattisgarh", "Jharkhand", "Karnataka", @@ -417,7 +417,7 @@ var isofullname = [ "Quebec", "Saskatchewan", "Manitoba", -"Newfoundland and Labrador (Labrador)", +"Newfoundland and Labrador (Newfoundland) (Labrador)", "New Brunswick", "Nova Scotia", "Prince Edward Island", diff --git a/mapcode.js b/mapcode.js index b15f04f..6e1e82a 100644 --- a/mapcode.js +++ b/mapcode.js @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -var entity_iso = [ +var iso3166alpha = [ + 'VAT', 'MCO', 'GIB', 'TKL', 'CCK', 'BLM', 'NRU', 'TUV', 'MAC', 'SXM', 'MAF', 'NFK', 'PCN', 'BVT', 'BMU', 'IOT', 'SMR', 'GGY', 'AIA', 'MSR', 'JEY', 'CXR', 'WLF', 'VGB', 'LIE', 'ABW', 'MHL', 'ASM', 'COK', 'SPM', @@ -37,37 +38,69 @@ var entity_iso = [ 'BWA', 'MDG', 'UKR', 'SSD', 'CAF', 'SOM', 'AFG', 'MMR', 'ZMB', 'CHL', 'TUR', 'PAK', 'MOZ', 'NAM', 'VEN', 'NGA', 'TZA', 'EGY', 'MRT', 'BOL', 'ETH', 'COL', 'ZAF', 'MLI', 'AGO', 'NER', 'TCD', 'PER', 'MNG', 'IRN', - 'LBY', 'SDN', 'IDN', 'DIF', 'TLA', 'MOR', 'AGU', '5CL', 'QUE', 'HID', - '5MX', 'TAB', 'NAY', 'GUA', 'PUE', 'YUC', 'ROO', 'SIN', 'CAM', 'MIC', - 'SLP', 'GRO', 'NLE', 'BCN', 'VER', 'CHP', 'BCS', 'ZAC', 'JAL', 'TAM', - 'OAX', 'DUR', 'COA', 'SON', 'CHH', 'GRL', 'SAU', 'COD', 'DZA', 'KAZ', - 'ARG', '2DD', '2DN', '2CH', '2AN', '2LD', '2DL', '2ML', '2NL', '2MN', - '2TR', '2MZ', '2SK', '2PB', '2HR', '2AR', '2AS', '2BR', '2UT', '2GA', - '2KL', '2TN', '2HP', '2JK', '2CT', '2JH', '2KA', '2RJ', '2OR', '2GJ', - '2WB', '2MP', '2TG', '2AP', '2MH', '2UP', '2PY', 'NSW', 'ACT', 'JBT', - '4NT', '4SA', 'TAS', 'VIC', '4WA', 'QLD', '6DF', '6SE', '6AL', '6RJ', - '6ES', '6RN', '6PB', '6SC', '6PE', '6AP', '6CE', '6AC', '6PR', '6RR', - '6RO', '6SP', '6PI', '6TO', '6RS', '6MA', '6GO', '6MS', '6BA', '6MG', - '6MT', '6PA', '6AM', '1DC', '1RI', '1DE', '1CT', '1NJ', '1NH', '1VT', - '1MA', '1HI', '1MD', '1WV', '1SC', '1ME', '1IN', '1KY', '1TN', '1VA', - '1OH', '1PA', '1MS', '1LA', '1AL', '1AR', '1NC', '1NY', '1IA', '1IL', - '1GA', '1WI', '1FL', '1MO', '1OK', '1ND', '1WA', '1SD', '1NE', '1KS', - '1ID', '1UT', '1MN', '1MI', '1WY', '1OR', '1CO', '1NV', '1AZ', '1NM', - '1MT', '1CA', '1TX', '1AK', '3BC', '3AB', '3ON', '3QC', '3SK', '3MB', - '3NL', '3NB', '3NS', '3PE', '3YT', '3NT', '3NU', 'IND', 'AUS', 'BRA', - 'USA', 'MEX', 'MOW', 'SPE', 'KGD', '7IN', '7AD', '7SE', '7KB', '7KC', - '7CE', '7CU', 'IVA', 'LIP', 'ORL', 'TUL', '7BE', 'VLA', 'KRS', 'KLU', - '7TT', 'BRY', 'YAR', 'RYA', 'AST', 'MOS', 'SMO', '7DA', 'VOR', 'NGR', - 'PSK', 'KOS', 'STA', 'KDA', '7KL', 'TVE', 'LEN', 'ROS', 'VGG', 'VLG', - 'MUR', '7KR', 'NEN', '7KO', 'ARK', '7MO', 'NIZ', 'PNZ', '7KI', '7ME', - 'ORE', 'ULY', '7PM', '7BA', '7UD', '7TA', 'SAM', 'SAR', 'YAN', '7KM', - 'SVE', 'TYU', 'KGN', '7CH', '7BU', 'ZAB', 'IRK', 'NVS', 'TOM', 'OMS', - '7KK', 'KEM', '7AL', 'ALT', '7TY', 'KYA', 'MAG', 'CHU', 'KAM', 'SAK', - '7PO', 'YEV', 'KHA', 'AMU', '7SA', 'CAN', 'RUS', '8SH', '8TJ', '8BJ', - '8HI', '8NX', '8CQ', '8ZJ', '8JS', '8FJ', '8AH', '8LN', '8SD', '8SX', - '8JX', '8HA', '8GZ', '8GD', '8HB', '8JL', '8HE', '8SN', '8NM', '8HL', - '8HN', '8GX', '8SC', '8YN', '8XZ', '8GS', '8QH', '8XJ', 'CHN', 'UMI', - 'CPT', 'ATA', 'AAA', '?']; + 'LBY', 'SDN', 'IDN', 'MX-DIF', 'MX-TLA', + 'MX-MOR', 'MX-AGU', 'MX-CL', 'MX-QUE', 'MX-HID', + 'MX-MX', 'MX-TAB', 'MX-NAY', 'MX-GUA', 'MX-PUE', + 'MX-YUC', 'MX-ROO', 'MX-SIN', 'MX-CAM', 'MX-MIC', + 'MX-SLP', 'MX-GRO', 'MX-NLE', 'MX-BCN', 'MX-VER', + 'MX-CHP', 'MX-BCS', 'MX-ZAC', 'MX-JAL', 'MX-TAM', + 'MX-OAX', 'MX-DUR', 'MX-COA', 'MX-SON', 'MX-CHH', + 'GRL', 'SAU', 'COD', 'DZA', 'KAZ', + 'ARG', 'IN-DD', 'IN-DN', 'IN-CH', 'IN-AN', + 'IN-LD', 'IN-DL', 'IN-ML', 'IN-NL', 'IN-MN', + 'IN-TR', 'IN-MZ', 'IN-SK', 'IN-PB', 'IN-HR', + 'IN-AR', 'IN-AS', 'IN-BR', 'IN-UT', 'IN-GA', + 'IN-KL', 'IN-TN', 'IN-HP', 'IN-JK', 'IN-CT', + 'IN-JH', 'IN-KA', 'IN-RJ', 'IN-OR', 'IN-GJ', + 'IN-WB', 'IN-MP', 'IN-TG', 'IN-AP', 'IN-MH', + 'IN-UP', 'IN-PY', 'AU-NSW', 'AU-ACT', 'AU-JBT', + 'AU-NT', 'AU-SA', 'AU-TAS', 'AU-VIC', 'AU-WA', + 'AU-QLD', 'BR-DF', 'BR-SE', 'BR-AL', 'BR-RJ', + 'BR-ES', 'BR-RN', 'BR-PB', 'BR-SC', 'BR-PE', + 'BR-AP', 'BR-CE', 'BR-AC', 'BR-PR', 'BR-RR', + 'BR-RO', 'BR-SP', 'BR-PI', 'BR-TO', 'BR-RS', + 'BR-MA', 'BR-GO', 'BR-MS', 'BR-BA', 'BR-MG', + 'BR-MT', 'BR-PA', 'BR-AM', 'US-DC', 'US-RI', + 'US-DE', 'US-CT', 'US-NJ', 'US-NH', 'US-VT', + 'US-MA', 'US-HI', 'US-MD', 'US-WV', 'US-SC', + 'US-ME', 'US-IN', 'US-KY', 'US-TN', 'US-VA', + 'US-OH', 'US-PA', 'US-MS', 'US-LA', 'US-AL', + 'US-AR', 'US-NC', 'US-NY', 'US-IA', 'US-IL', + 'US-GA', 'US-WI', 'US-FL', 'US-MO', 'US-OK', + 'US-ND', 'US-WA', 'US-SD', 'US-NE', 'US-KS', + 'US-ID', 'US-UT', 'US-MN', 'US-MI', 'US-WY', + 'US-OR', 'US-CO', 'US-NV', 'US-AZ', 'US-NM', + 'US-MT', 'US-CA', 'US-TX', 'US-AK', 'CA-BC', + 'CA-AB', 'CA-ON', 'CA-QC', 'CA-SK', 'CA-MB', + 'CA-NL', 'CA-NB', 'CA-NS', 'CA-PE', 'CA-YT', + 'CA-NT', 'CA-NU', 'IND', 'AUS', 'BRA', + 'USA', 'MEX', 'RU-MOW', 'RU-SPE', 'RU-KGD', + 'RU-IN', 'RU-AD', 'RU-SE', 'RU-KB', 'RU-KC', + 'RU-CE', 'RU-CU', 'RU-IVA', 'RU-LIP', 'RU-ORL', + 'RU-TUL', 'RU-BE', 'RU-VLA', 'RU-KRS', 'RU-KLU', + 'RU-TT', 'RU-BRY', 'RU-YAR', 'RU-RYA', 'RU-AST', + 'RU-MOS', 'RU-SMO', 'RU-DA', 'RU-VOR', 'RU-NGR', + 'RU-PSK', 'RU-KOS', 'RU-STA', 'RU-KDA', 'RU-KL', + 'RU-TVE', 'RU-LEN', 'RU-ROS', 'RU-VGG', 'RU-VLG', + 'RU-MUR', 'RU-KR', 'RU-NEN', 'RU-KO', 'RU-ARK', + 'RU-MO', 'RU-NIZ', 'RU-PNZ', 'RU-KI', 'RU-ME', + 'RU-ORE', 'RU-ULY', 'RU-PM', 'RU-BA', 'RU-UD', + 'RU-TA', 'RU-SAM', 'RU-SAR', 'RU-YAN', 'RU-KM', + 'RU-SVE', 'RU-TYU', 'RU-KGN', 'RU-CH', 'RU-BU', + 'RU-ZAB', 'RU-IRK', 'RU-NVS', 'RU-TOM', 'RU-OMS', + 'RU-KK', 'RU-KEM', 'RU-AL', 'RU-ALT', 'RU-TY', + 'RU-KYA', 'RU-MAG', 'RU-CHU', 'RU-KAM', 'RU-SAK', + 'RU-PO', 'RU-YEV', 'RU-KHA', 'RU-AMU', 'RU-SA', + 'CAN', 'RUS', 'CN-SH', 'CN-TJ', 'CN-BJ', + 'CN-HI', 'CN-NX', 'CN-CQ', 'CN-ZJ', 'CN-JS', + 'CN-FJ', 'CN-AH', 'CN-LN', 'CN-SD', 'CN-SX', + 'CN-JX', 'CN-HA', 'CN-GZ', 'CN-GD', 'CN-HB', + 'CN-JL', 'CN-HE', 'CN-SN', 'CN-NM', 'CN-HL', + 'CN-HN', 'CN-GX', 'CN-SC', 'CN-YN', 'CN-XZ', + 'CN-GS', 'CN-QH', 'CN-XJ', 'CHN', 'UMI', + 'CPT', 'ATA', 'AAA' +]; + var aliases = "2UK=2UT,2CG=2CT,1GU=GUM,1UM=UMI,1VI=VIR,1AS=ASM,1MP=MNP,4CX=CXR,4CC=CCK,4NF=NFK,4HM=HMD,COL=5CL,5ME=5MX,MEX=5MX,5AG=AGU,5BC=BCN,5BS=BCS,5CM=CAM,5CS=CHP,5CH=CHH,5CO=COA,5DF=DIF,5DG=DUR,5GT=GUA,5GR=GRO,5HG=HID,5JA=JAL,5MI=MIC,5MO=MOR,5NA=NAY,5NL=NLE,5OA=OAX,5PB=PUE,5QE=QUE,5QR=ROO,5SL=SLP,5SI=SIN,5SO=SON,5TB=TAB,5TL=TLA,5VE=VER,5YU=YUC,5ZA=ZAC,811=8BJ,812=8TJ,813=8HE,814=8SX,815=8NM,821=8LN,822=8JL,823=8HL,831=8SH,832=8JS,833=8ZJ,834=8AH,835=8FJ,836=8JX,837=8SD,841=8HA,842=8HB,843=8HN,844=8GD,845=8GX,846=8HI,850=8CQ,851=8SC,852=8GZ,853=8YN,854=8XZ,861=8SN,862=8GS,863=8QH,864=8NX,865=8XJ,871=TWN,891=HKG,892=MAC,8TW=TWN,8HK=HKG,8MC=MAC,BEL=7BE,KIR=7KI,PRI=7PO,CHE=7CH,KHM=7KM,PER=7PM,TAM=7TT,0US=USA,0AU=AUS,0RU=RUS,0CN=CHN,TAA=SHN,ASC=SHN,DGA=IOT,WAK=MHL,JTN=UMI,MID=1HI,1PR=PRI,5TM=TAM,TAM=TAM,2OD=2OR,"; @@ -120,7 +153,7 @@ var mapcode_dataversion = "2.3.0"; // *************************** mapcode_org ********************* -var mapcode_javaversion = '2.3.1/Data' + mapcode_dataversion; +var mapcode_javaversion = '2.4.0/Data' + mapcode_dataversion; /// PRIVATE returns string without leading spaces and plus-signs, and trailing spaces function trim(str) { @@ -175,6 +208,16 @@ function alias2iso(territoryAlphaCode) { return ''; } +/// PRIVATE given ISO code, return territoryNumber (or negative if error) +function findISO(territoryAlphaCode) { + for (var i = 0; i < iso3166alpha.length; i++) { + if (territoryAlphaCode == iso3166alpha[i]) { + return i; + } + } + return -1; +} + /// PRIVATE given ISO code, return territoryNumber (or negative if error) function iso2ccode(territoryAlphaCode) { if (typeof territoryAlphaCode == "undefined") { @@ -192,69 +235,91 @@ function iso2ccode(territoryAlphaCode) { } } + var i, isoa; var sep = territoryAlphaCode.lastIndexOf('-'); - if (sep >= 0) { - + if (sep >= 0) { // territory! var prefix = territoryAlphaCode.substring(0, sep); - territoryAlphaCode = trim(territoryAlphaCode.substring(sep + 1)); - - if (territoryAlphaCode.length != 2 && territoryAlphaCode.length != 3) { + var properMapcode = territoryAlphaCode.substring(sep + 1); + if (set_disambiguate(prefix) || properMapcode.length < 2) { return -1; } - if (set_disambiguate(prefix)) { - return -1; + i = findISO(parentname2(disambiguate) + '-' + properMapcode); + if (i >= 0) { + return i; } - - // FIRST see if the territoryAlphaCode is in this disambiguation - if (territoryAlphaCode.length == 2) { - return iso2ccode(disambiguate + '' + territoryAlphaCode); + // recognise alias + if (properMapcode.length == 3) { + isoa = alias2iso(properMapcode); + } else { + isoa = alias2iso(disambiguate + '' + properMapcode); } - else if (territoryAlphaCode.length == 3) { - var isoa = alias2iso(territoryAlphaCode); - if (isoa) { - if (isoa.charAt(0) == disambiguate) { - territoryAlphaCode = isoa; + if (isoa) { + if (isoa.charAt(0) == disambiguate) { + properMapcode = isoa.substring(1); + } else { + properMapcode = isoa; + i = findISO(properMapcode); + if (i >= 0) { + return i; } } } + return findISO(parentname2(disambiguate) + '-' + properMapcode); } - if (territoryAlphaCode.length != 2 && territoryAlphaCode.length != 3) { - return -1; - } - - { - var testiso = (territoryAlphaCode.length == 2 ? disambiguate + '' + territoryAlphaCode : territoryAlphaCode); - var i; - for (i = 0; i < entity_iso.length; i++) { - if (testiso == entity_iso[i]) { - return i; + // first rewrite alias in context + if (territoryAlphaCode.length == 2) { + isoa = alias2iso(disambiguate + '' + territoryAlphaCode); + if (isoa) { + if (isoa.charAt(0) == disambiguate) { + territoryAlphaCode = isoa.substring(1); + } else { + territoryAlphaCode = isoa; } } + } - // 1.31 improvement: recognise alias in current context - if (territoryAlphaCode.length == 2 && testiso.length == 3) { - var aliasiso = alias2iso(testiso); - if (aliasiso) { - return iso2ccode(aliasiso); - } + // no prefix. check if a normal territory + if (territoryAlphaCode.length == 3) { + i = findISO(territoryAlphaCode); + if (i >= 0) { + return i; } + } + + // no prefix, check in context + i = findISO(parentname2(disambiguate) + '-' + territoryAlphaCode); + if (i >= 0) { + return i; + } + - // look for any iso2 match - if (territoryAlphaCode.length == 2) { - for (i = 0; i < entity_iso.length; i++) { - if (entity_iso[i].charCodeAt(0) <= 57 && territoryAlphaCode == entity_iso[i].substring(1, 3)) { + if (territoryAlphaCode.length >= 2) { + i = findISO(parentname2(disambiguate) + '-' + territoryAlphaCode); + if (i >= 0) { + return i; + } + // find in ANY context + var hyphenated = '-' + territoryAlphaCode; + for (i = 0; i < iso3166alpha.length; i++) { + if (iso3166alpha[i].indexOf(hyphenated) > 0) { + if (iso3166alpha[i].substring(iso3166alpha[i].indexOf(hyphenated)) == hyphenated) { return i; } } } + } - territoryAlphaCode = alias2iso(territoryAlphaCode); - if (territoryAlphaCode) { - return iso2ccode(territoryAlphaCode); + // all else failed, try non-disambiguated alphacode + isoa = alias2iso(territoryAlphaCode); // or try ANY alias + if (isoa) { + if (isoa.charCodeAt(0) <= 57) { // starts with digit + territoryAlphaCode = parentname2(isoa.charCodeAt(0) - 48) + '-' + isoa.substring(1); + } else { + territoryAlphaCode = isoa; } + return iso2ccode(territoryAlphaCode); } - return -1; } @@ -263,7 +328,7 @@ function iso2ccode(territoryAlphaCode) { function getTerritoryNumber(territoryAlphaCode, contextTerritory) { if (contextTerritory) { var contextTerritoryNumber = getTerritoryNumber(contextTerritory); - set_disambiguate(entity_iso[contextTerritoryNumber]); + set_disambiguate(iso3166alpha[contextTerritoryNumber]); } return iso2ccode(territoryAlphaCode); } @@ -372,50 +437,30 @@ function getTerritoryAlphaCode(territory, format) { if (territoryNumber < 0 || territoryNumber > ccode_earth) { return ''; } - var n = entity_iso[territoryNumber]; - if (/^[0-9]/.test(n)) { - n = n.substring(1); - } - if (format) { - var parent = getParentOf(territoryNumber); - if (parent >= 0) { - if (format == 2) { - // see if n occurs multiple times, if not, don't bother with parent - var count = 0; - var i = aliases.indexOf(n + '='); - if (i >= 0) { - count = 2; - } else if (n.length == 2) { - for (i = 0; i < entity_iso.length; i++) { - if (entity_iso[i].substr(1) == n) { - if (entity_iso[i].charAt(0) >= '0') { - if (entity_iso[i].charAt(0) <= '9') { - count++; - if (count > 1) { - break; - } - } - } - } - } - } else { - for (i = 0; i < entity_iso.length; i++) { - if (entity_iso[i] == n) { - count++; - if (count > 1) { - break; - } - } - } - } - if (count == 1) { - return n; - } + var full = iso3166alpha[territoryNumber]; + var hyphen = full.indexOf("-"); + if (format == 1 || hyphen <= 0) { + return full; + } + var short = full.substr(hyphen + 1); + if (format == 0) { + return short; + } + // shortest POSSIBLE + var parent = getParentOf(territoryNumber); + // see if n occurs multiple times, if not, don't bother with parent + var count = 0; + var i = aliases.indexOf(n + '='); + if (i >= 0) { + count = 2; + } else { + for (i = 0; i < iso3166alpha.length; i++) { + if (iso3166alpha[i].indexOf("-" + short) > 0) { + count++; } - return parentname2(parentletter(entity_iso[parent])) + '-' + n; } } - return n; + return (count == 1) ? short : full; } /// PRIVATE low-level routines for data access @@ -1065,24 +1110,39 @@ function encodeGrid(enc, m, mm, headerletter, extraDigits) { /// alphabet support -var MAXLANS = 15; +var MAXLANS = 28; var asc2lan = [ - [65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Roman - [913, 914, 926, 916, 904/*e*/, 917, 915, 919, 921, 928, 922, 923, 924, 925, 927/*o*/, 929, 920, 936, 931, 932, 905/*u*/, 934, 937, 935, 933, 918, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Greek - [1040, 1042, 1057, 1044, 1045, 1046, 1043, 1053, 1048, 1055, 1050, 1051, 1052, 1047, 1054, 1056, 1060, 1071, 1062, 1058, 1069, 1063, 1064, 1061, 1059, 1041, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Cyrillic - [1488, 1489, 1490, 1491, 1507, 1492, 1494, 1495, 1493, 1496, 1497, 1498, 1499, 1500, 1505, 1501, 1502, 1504, 1506, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Hebrew - [2309, 2325, 2327, 2328, 2319, 2330, 2332, 2335, 73, 2336, 2339, 2340, 2342, 2343, 79, 2344, 2346, 2349, 2350, 2352, 2347, 2354, 2357, 2360, 2361, 2337, 2406, 2407, 2408, 2409, 2410, 2411, 2412, 2413, 2414, 2415], // Hindi - [3346, 3349, 3350, 3351, 3339, 3354, 3356, 3359, 3335, 3361, 3364, 3365, 3366, 3367, 3360, 3368, 3374, 3376, 3377, 3378, 3337, 3380, 3381, 3382, 3384, 3385, 3430, 3431, 3432, 3433, 3434, 3435, 3436, 3437, 3438, 3439], // Malay - [4256, 4257, 4259, 4262, 4260, 4265, 4267, 4268, 4275, 4270, 4272, 4273, 4274, 4276, 4269, 4277, 4278, 4279, 4280, 4281, 4264, 4282, 4283, 4285, 4286, 4287, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Georgian - [12450, 12459, 12461, 12463, 12458, 12465, 12467, 12469, 12452, 12473, 12481, 12488, 12490, 12492, 12454, 12498, 12501, 12504, 12507, 12513, 12456, 12514, 12520, 12521, 12525, 12530, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Katakana - [3632, 3585, 3586, 3588, 3634, 3591, 3592, 3593, 3633, 3594, 3601, 3604, 3606, 3607, 3597, 3608, 3610, 3612, 3617, 3619, 3628, 3621, 3623, 3629, 3630, 3631, 3664, 3665, 3666, 3667, 3668, 3669, 3670, 3671, 3672, 3673], // Thai - [3760, 3713, 3714, 3716, 3779, 3719, 3720, 3722, 3780, 3725, 3732, 3735, 3737, 3738, 3782, 3740, 3742, 3745, 3746, 3747, 3773, 3751, 3754, 3755, 3757, 3759, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Lao - [1366, 1330, 1331, 1332, 1333, 1336, 1337, 1338, 1339, 1341, 1343, 1344, 1345, 1347, 1365, 1351, 1352, 1354, 1357, 1358, 1349, 1359, 1360, 1361, 1362, 1363, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], // Armenian - [2437, 2444, 2453, 2454, 2447, 2455, 2457, 2458, 73, 2461, 2464, 2465, 2466, 2467, 79, 2468, 2469, 2470, 2472, 2474, 2451, 2476, 2477, 2479, 2482, 2489, 2534, 2535, 2536, 2537, 2538, 2539, 2540, 2541, 2542, 2543], // Bengali - [2565, 2581, 2583, 2584, 2575, 2586, 2588, 2591, 73, 2592, 2595, 2596, 2598, 2599, 79, 2600, 2602, 2605, 2606, 2608, 2603, 2610, 2613, 2616, 2617, 2593, 2662, 2663, 2664, 2665, 2666, 2667, 2668, 2669, 2670, 2671], // Gurmukhi - [3928, 3904, 3905, 3906, 3940, 3908, 3909, 3910, 73, 3911, 0xF49, 0xF55, 0xF50, /*KLM=3914, 3916, 3918,*/ 3919, 79, 3921, 3923, 3924, 3926, 3934, 0xF60/*u=3941*/, 3935, 3937, 3938, 3939, 3942, 3872, 3873, 3874, 3875, 3876, 3877, 3878, 3879, 3880, 3881], // Tibetan - [1576, 1578, 1581, 1582, 1609/*e*/, 1583, 1584, 1585, 73/*i*/, 1586, 1587, 1588, 1589, 1590, 79/*o*/, 1591, 1592, 1593, 1594, 1601, 1602/*u*/, 1603, 1604, 1605, 1606, 1608, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57] // Arabic -]; + // A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 + [0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // roman + [0x0391, 0x0392, 0x039e, 0x0394, 0x0388, 0x0395, 0x0393, 0x0397, 0x0399, 0x03a0, 0x039a, 0x039b, 0x039c, 0x039d, 0x039f, 0x03a1, 0x0398, 0x03a8, 0x03a3, 0x03a4, 0x0389, 0x03a6, 0x03a9, 0x03a7, 0x03a5, 0x0396, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // greek + [0x0410, 0x0412, 0x0421, 0x0414, 0x0415, 0x0416, 0x0413, 0x041d, 0x0049, 0x041f, 0x041a, 0x041b, 0x041c, 0x0417, 0x041e, 0x0420, 0x0424, 0x042f, 0x0426, 0x0422, 0x042d, 0x0427, 0x0428, 0x0425, 0x0423, 0x0411, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // cyrillic + [0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05e3, 0x05d4, 0x05d6, 0x05d7, 0x05d5, 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05e1, 0x05dd, 0x05de, 0x05e0, 0x05e2, 0x05e4, 0x05e5, 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // hebrew + [0x0905, 0x0915, 0x0917, 0x0918, 0x090f, 0x091a, 0x091c, 0x091f, 0x0049, 0x0920, 0x0923, 0x0924, 0x0926, 0x0927, 0x004f, 0x0928, 0x092a, 0x092d, 0x092e, 0x0930, 0x092b, 0x0932, 0x0935, 0x0938, 0x0939, 0x092c, 0x0966, 0x0967, 0x0968, 0x0969, 0x096a, 0x096b, 0x096c, 0x096d, 0x096e, 0x096f], // Devanagari + [0x0d12, 0x0d15, 0x0d16, 0x0d17, 0x0d0b, 0x0d1a, 0x0d1c, 0x0d1f, 0x0049, 0x0d21, 0x0d24, 0x0d25, 0x0d26, 0x0d27, 0x0d20, 0x0d28, 0x0d2e, 0x0d30, 0x0d31, 0x0d32, 0x0d09, 0x0d34, 0x0d35, 0x0d36, 0x0d38, 0x0d39, 0x0d66, 0x0d67, 0x0d68, 0x0d69, 0x0d6a, 0x0d6b, 0x0d6c, 0x0d6d, 0x0d6e, 0x0d6f], // Malayalam + [0x10a0, 0x10a1, 0x10a3, 0x10a6, 0x10a4, 0x10a9, 0x10ab, 0x10ac, 0x0049, 0x10ae, 0x10b0, 0x10b1, 0x10b2, 0x10b4, 0x10ad, 0x10b5, 0x10b6, 0x10b7, 0x10b8, 0x10b9, 0x10a8, 0x10ba, 0x10bb, 0x10bd, 0x10be, 0x10bf, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Georgian + [0x30a2, 0x30ab, 0x30ad, 0x30af, 0x30aa, 0x30b1, 0x30b3, 0x30b5, 0x0049, 0x30b9, 0x30c1, 0x30c8, 0x30ca, 0x30cc, 0x004f, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30e1, 0x30a8, 0x30e2, 0x30e8, 0x30e9, 0x30ed, 0x30f2, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Katakana + [0x0e30, 0x0e01, 0x0e02, 0x0e04, 0x0e32, 0x0e07, 0x0e08, 0x0e09, 0x0049, 0x0e0a, 0x0e11, 0x0e14, 0x0e16, 0x0e17, 0x004f, 0x0e18, 0x0e1a, 0x0e1c, 0x0e21, 0x0e23, 0x0e2c, 0x0e25, 0x0e27, 0x0e2d, 0x0e2e, 0x0e2f, 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, 0x0e58, 0x0e59], // Thai + [0x0eb0, 0x0e81, 0x0e82, 0x0e84, 0x0ec3, 0x0e87, 0x0e88, 0x0e8a, 0x0ec4, 0x0e8d, 0x0e94, 0x0e97, 0x0e99, 0x0e9a, 0x004f, 0x0e9c, 0x0e9e, 0x0ea1, 0x0ea2, 0x0ea3, 0x0ebd, 0x0ea7, 0x0eaa, 0x0eab, 0x0ead, 0x0eaf, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Laos + [0x0556, 0x0532, 0x0533, 0x0534, 0x0535, 0x0538, 0x0539, 0x053a, 0x053b, 0x053d, 0x053f, 0x0540, 0x0541, 0x0543, 0x0555, 0x0547, 0x0548, 0x054a, 0x054d, 0x054e, 0x0545, 0x054f, 0x0550, 0x0551, 0x0552, 0x0553, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // armenian + [0x099c, 0x0998, 0x0995, 0x0996, 0x09ae, 0x0997, 0x0999, 0x099a, 0x0049, 0x099d, 0x09a0, 0x09a1, 0x09a2, 0x09a3, 0x004f, 0x09a4, 0x09a5, 0x09a6, 0x09a8, 0x09aa, 0x099f, 0x09ac, 0x09ad, 0x09af, 0x09b2, 0x09b9, 0x09e6, 0x09e7, 0x09e8, 0x09e9, 0x09ea, 0x09eb, 0x09ec, 0x09ed, 0x09ee, 0x09ef], // Bengali/Assamese + [0x0a05, 0x0a15, 0x0a17, 0x0a18, 0x0a0f, 0x0a1a, 0x0a1c, 0x0a1f, 0x0049, 0x0a20, 0x0a23, 0x0a24, 0x0a26, 0x0a27, 0x004f, 0x0a28, 0x0a2a, 0x0a2d, 0x0a2e, 0x0a30, 0x0a2b, 0x0a32, 0x0a35, 0x0a38, 0x0a39, 0x0a21, 0x0a66, 0x0a67, 0x0a68, 0x0a69, 0x0a6a, 0x0a6b, 0x0a6c, 0x0a6d, 0x0a6e, 0x0a6f], // Gurmukhi + [0x0f58, 0x0f40, 0x0f41, 0x0f42, 0x0f64, 0x0f44, 0x0f45, 0x0f46, 0x0049, 0x0f47, 0x0f49, 0x0f55, 0x0f50, 0x0f4f, 0x004f, 0x0f51, 0x0f53, 0x0f54, 0x0f56, 0x0f5e, 0x0f60, 0x0f5f, 0x0f61, 0x0f62, 0x0f63, 0x0f66, 0x0f20, 0x0f21, 0x0f22, 0x0f23, 0x0f24, 0x0f25, 0x0f26, 0x0f27, 0x0f28, 0x0f29], // Tibetan + [0x0628, 0x062a, 0x062d, 0x062e, 0x062B, 0x062f, 0x0630, 0x0631, 0x0627, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0647, 0x0637, 0x0638, 0x0639, 0x063a, 0x0641, 0x0642, 0x062C, 0x0644, 0x0645, 0x0646, 0x0648, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Arabic + [0x1112, 0x1100, 0x1102, 0x1103, 0x1166, 0x1105, 0x1107, 0x1109, 0x1175, 0x1110, 0x1111, 0x1161, 0x1162, 0x1163, 0x110b, 0x1164, 0x1165, 0x1167, 0x1169, 0x1172, 0x1174, 0x110c, 0x110e, 0x110f, 0x116d, 0x116e, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Korean // 0xc601, 0xc77c, 0xc774, 0xc0bc, 0xc0ac, 0xc624, 0xc721, 0xce60, 0xd314, 0xad6c (vocal digits) + [0x1005, 0x1000, 0x1001, 0x1002, 0x1013, 0x1003, 0x1004, 0x101a, 0x0049, 0x1007, 0x100c, 0x100d, 0x100e, 0x1010, 0x101d, 0x1011, 0x1012, 0x101e, 0x1014, 0x1015, 0x1016, 0x101f, 0x1017, 0x1018, 0x100f, 0x101c, 0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047, 0x1048, 0x1049], // Burmese + [0x1789, 0x1780, 0x1781, 0x1782, 0x1785, 0x1783, 0x1784, 0x1787, 0x179a, 0x1788, 0x178a, 0x178c, 0x178d, 0x178e, 0x004f, 0x1791, 0x1792, 0x1793, 0x1794, 0x1795, 0x179f, 0x1796, 0x1798, 0x179b, 0x17a0, 0x17a2, 0x17e0, 0x17e1, 0x17e2, 0x17e3, 0x17e4, 0x17e5, 0x17e6, 0x17e7, 0x17e8, 0x17e9], // Khmer + [0x0d85, 0x0d9a, 0x0d9c, 0x0d9f, 0x0d89, 0x0da2, 0x0da7, 0x0da9, 0x0049, 0x0dac, 0x0dad, 0x0daf, 0x0db1, 0x0db3, 0x004f, 0x0db4, 0x0db6, 0x0db8, 0x0db9, 0x0dba, 0x0d8b, 0x0dbb, 0x0dbd, 0x0dc0, 0x0dc3, 0x0dc4, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Sinhalese + [0x0794, 0x0780, 0x0781, 0x0782, 0x0797, 0x0783, 0x0784, 0x0785, 0x0049, 0x0786, 0x0787, 0x0788, 0x0789, 0x078a, 0x004f, 0x078b, 0x078c, 0x078d, 0x078e, 0x078f, 0x079c, 0x0790, 0x0791, 0x0792, 0x0793, 0x07b1, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Thaana + [0x3123, 0x3105, 0x3108, 0x3106, 0x3114, 0x3107, 0x3109, 0x310a, 0x0049, 0x310b, 0x310c, 0x310d, 0x310e, 0x310f, 0x004f, 0x3115, 0x3116, 0x3110, 0x3111, 0x3112, 0x3113, 0x3129, 0x3117, 0x3128, 0x3118, 0x3119, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Chinese + [0x2D49, 0x2D31, 0x2D33, 0x2D37, 0x2D53, 0x2D3C, 0x2D3D, 0x2D40, 0x2D4F, 0x2D43, 0x2D44, 0x2D45, 0x2D47, 0x2D4D, 0x2D54, 0x2D4E, 0x2D55, 0x2D56, 0x2D59, 0x2D5A, 0x2D62, 0x2D5B, 0x2D5C, 0x2D5F, 0x2D61, 0x2D63, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Tifinagh (BERBER) + [0x0b99, 0x0b95, 0x0b9a, 0x0b9f, 0x0b86, 0x0ba4, 0x0ba8, 0x0baa, 0x0049, 0x0bae, 0x0baf, 0x0bb0, 0x0bb2, 0x0bb5, 0x004f, 0x0bb4, 0x0bb3, 0x0bb1, 0x0b85, 0x0b88, 0x0b93, 0x0b89, 0x0b8e, 0x0b8f, 0x0b90, 0x0b92, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Tamil (digits 0xBE6-0xBEF) + [0x121B, 0x1260, 0x1264, 0x12F0, 0x121E, 0x134A, 0x1308, 0x1200, 0x0049, 0x12E8, 0x12AC, 0x1208, 0x1293, 0x1350, 0x12D0, 0x1354, 0x1240, 0x1244, 0x122C, 0x1220, 0x12C8, 0x1226, 0x1270, 0x1276, 0x1338, 0x12DC, 0x1372, 0x1369, 0x136a, 0x136b, 0x136c, 0x136d, 0x136e, 0x136f, 0x1370, 0x1371], // Amharic (digits 1372|1369-1371) + [0x0C1E, 0x0C15, 0x0C17, 0x0C19, 0x0C2B, 0x0C1A, 0x0C1C, 0x0C1F, 0x0049, 0x0C20, 0x0C21, 0x0C23, 0x0C24, 0x0C25, 0x004f, 0x0C26, 0x0C27, 0x0C28, 0x0C2A, 0x0C2C, 0x0C2D, 0x0C2E, 0x0C30, 0x0C32, 0x0C33, 0x0C35, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Telugu + [0x0B1D, 0x0B15, 0x0B16, 0x0B17, 0x0B23, 0x0B18, 0x0B1A, 0x0B1C, 0x0049, 0x0B1F, 0x0B21, 0x0B22, 0x0B24, 0x0B25, 0x0B20, 0x0B26, 0x0B27, 0x0B28, 0x0B2A, 0x0B2C, 0x0B39, 0x0B2E, 0x0B2F, 0x0B30, 0x0B33, 0x0B38, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Odia + [0x0C92, 0x0C95, 0x0C96, 0x0C97, 0x0C8E, 0x0C99, 0x0C9A, 0x0C9B, 0x0049, 0x0C9C, 0x0CA0, 0x0CA1, 0x0CA3, 0x0CA4, 0x004f, 0x0CA6, 0x0CA7, 0x0CA8, 0x0CAA, 0x0CAB, 0x0C87, 0x0CAC, 0x0CAD, 0x0CB0, 0x0CB2, 0x0CB5, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Kannada + [0x0AB3, 0x0A97, 0x0A9C, 0x0AA1, 0x0A87, 0x0AA6, 0x0AAC, 0x0A95, 0x0049, 0x0A9A, 0x0A9F, 0x0AA4, 0x0AAA, 0x0AA0, 0x004f, 0x0AB0, 0x0AB5, 0x0A9E, 0x0AAE, 0x0AAB, 0x0A89, 0x0AB7, 0x0AA8, 0x0A9D, 0x0AA2, 0x0AAD, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Gujarati +] + // *UI* var lannam = [ @@ -1090,8 +1150,8 @@ var lannam = [ ["Greek"], ["Cyrillic"], ["Hebrew"], - ["Hindi"], - ["Malay"], + ["Devanagari"], + ["Malayalam"], ["Georgian"], ["Katakana"], ["Thai"], @@ -1100,7 +1160,20 @@ var lannam = [ ["Bengali"], ["Gurmukhi"], ["Tibetan"], - ["Arabic"] + ["Arabic"], + ["Korean"], + ["Burmese"], + ["Khmer"], + ["Sinhalese"], + ["Thaana"], + ["Chinese"], + ["Tifinagh"], + ["Tamil"], + ["Amharic"], + ["Telugu"], + ["Odia"], + ["Kannada"], + ["Gujarati"] ]; // *UI* @@ -1109,8 +1182,8 @@ var lanlannam = [ ["ελληνικά"], ["кириллица"], ["עִבְרִית"], - ["हिंदी"], - ["Melayu"], + ["देवनागरी"], // Devanagari + ["മലയാളം"], // Malayalam ["ქართული"], ["カタカナ"], ["ภาษาไทย"], @@ -1119,7 +1192,20 @@ var lanlannam = [ ["বাংলা"], ["ਗੁਰਮੁਖੀ"], ["དབུ་ཅན་"], - ["العَرَبِيَّة"] + ["العَرَبِيَّة"], + ["조선글/한글"], // Korean (Choson'gul / Hangul ) + ["မြန်မာအက္ခရာ"], // Burmese + ["អក្សរខ្មែរ"], // Khmer script + ['සිංහල අක්ෂර මාලාව'], // Sinhalese + ["ތާނަ"], // Thaana (Maldivan) + ["ㄅㄆㄇㄈ"], // Chinese (bopomofo) // 注音符號, + ["ⵜⵉⴼⵉⵏⴰⵖ"], // Tifinagh (Berber) + ["தமிழ்"], // Tamil + ["ኣማርኛ"], // Amharic + ["తెలుగు"], // Telugu + ["ଓଡ଼ିଆ"], // Odia + ["ಕನ್ನಡ"], // Kannada + ["ગુજરાતી"] // Gujarati ]; /// PRIVATE substitute characters in str with characters form the specified language (pass asHTML=1 to explicitly HTML-encode characters) @@ -1138,7 +1224,7 @@ function showinlan(str, lan, asHTML) { str = str.substr(sp); } - if (lan == 1 || lan == 3 || lan == 14) { + if (lan == 1 || lan == 3 || lan == 14 || lan == 15) { // greek hebrew arabic korean str = convertToAbjad(str); } @@ -2287,15 +2373,18 @@ function convertToAbjad(mapcode) { function isAbjadScript(str) { for (var i = 0; i < str.length; i++) { var c = str.charCodeAt(i); - if (c >= 1576 && c <= 1609) { + if (c >= 0x0628 && c <= 0x0649) { return true; } // arabic - if (c >= 1488 && c <= 1514) { + if (c >= 0x05d0 && c <= 0x05ea) { return true; } // hebrew - if (c >= 904 && c <= 969) { + if (c >= 0x0388 && c <= 0x03c9) { + return true; + } // greek uppercase and lowecase + if ((c >= 0x1100 && c <= 0x1175) || (c >= 0xad6c && c <= 0xd314)) { return true; - } // greek 0x388-0x3C9 + } // korean } return false; } diff --git a/unittest/unittest.html b/unittest/unittest.html index 86b6b4f..b4e8ac0 100644 --- a/unittest/unittest.html +++ b/unittest/unittest.html @@ -468,7 +468,7 @@

Mapcode Javascript Unit Tests

if (tn != ccode) { nrErrors++; - out('*** ERROR *** getTerritoryNumber(' + alphacode + (needsParent ? ',' + getTerritoryAlphaCode(ccodeParent) : "") + ')=' + tn + ' but expected ' + ccode); + out('*** ERROR *** getTerritoryNumber(' + alphacode + (needsParent ? ',' + getTerritoryAlphaCode(ccodeParent) : "") + ')=' + tn + '=' + getTerritoryAlphaCode(tn) + ' but expected ' + ccode + '=' + getTerritoryAlphaCode(ccode)); } if (needsParent == 0 && isAlias == 0 && (alphacode.length <= 3 || alphacode.charAt(3) != '-')) { @@ -577,6 +577,10 @@

Mapcode Javascript Unit Tests

function territory_code_tests() { var testdata = [ + "ASM", "USA", "AS", + "MX-AGU", , "AG", + "MX-TAM", , "MEX-TAM", + "CXR", , "AUS-CX", // expected answer, context, string "BR-AL", "BRA", "AL", "VAT", , "", @@ -619,7 +623,7 @@

Mapcode Javascript Unit Tests

if (tc != testdata[i]) { nrErrors++; out('*** ERROR *** getTerritoryNumber("' + testdata[i + 2] + '", ' + - testdata[i + 1] + ')=' + tc + ', expected ' + testdata[i]); + testdata[i + 1] + ')=' + tc + ', expected \"' + testdata[i] + '\"'); } } } From c3d82e3d0c2e759ebb750bdc52879abfd6508c3a Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Tue, 25 Oct 2016 15:38:36 +0200 Subject: [PATCH 33/54] Release 2.4.0 --- README.md | 10 ++++------ mapcode.js | 55 +++++++++++++++++++++++++++--------------------------- 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 77e43cd..5dbf094 100644 --- a/README.md +++ b/README.md @@ -55,15 +55,13 @@ To run the Javascript unit tests, simply open the file `unittest/unittest/html`. Renamed language strings to more correct terms (Malay to Malayalam; Hindi to Devanagari). - Added var `alphabetsForTerritory[t]`, returning the most commonly used alphabets for territory `t`. + Added var alphabetsForTerritory[t], returning the most commonly used alphabets for territory t. - Improved some characters for Arabic and Devanagari. - - Fixed Bengali to also support Assamese. + Improved some characters for Arabic and Devanagari; Fixed Bengali to also support Assamese. - For some alphabets, removed recognition of letters `I` and/or `O` unless looking like digits `1` and/or `0`. + For some alphabets, removed recognition of letters I and/or O unless looking like digits 1 and/or 0. - Replaced internal encoded `entity_iso[]` array by non-encoded `iso3166alpha[]`. + replaced internal encoded entity_iso[] array by non-encoded iso3166alpha[]. * 2.3.1 diff --git a/mapcode.js b/mapcode.js index 6e1e82a..7c02531 100644 --- a/mapcode.js +++ b/mapcode.js @@ -12,9 +12,9 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - */ + */ var iso3166alpha = [ - + 'VAT', 'MCO', 'GIB', 'TKL', 'CCK', 'BLM', 'NRU', 'TUV', 'MAC', 'SXM', 'MAF', 'NFK', 'PCN', 'BVT', 'BMU', 'IOT', 'SMR', 'GGY', 'AIA', 'MSR', 'JEY', 'CXR', 'WLF', 'VGB', 'LIE', 'ABW', 'MHL', 'ASM', 'COK', 'SPM', @@ -235,31 +235,30 @@ function iso2ccode(territoryAlphaCode) { } } - var i, isoa; + var i,isoa; var sep = territoryAlphaCode.lastIndexOf('-'); if (sep >= 0) { // territory! var prefix = territoryAlphaCode.substring(0, sep); var properMapcode = territoryAlphaCode.substring(sep + 1); - if (set_disambiguate(prefix) || properMapcode.length < 2) { + if (set_disambiguate(prefix) || properMapcode.length<2) { return -1; } i = findISO(parentname2(disambiguate) + '-' + properMapcode); - if (i >= 0) { + if (i>=0) { return i; } // recognise alias - if (properMapcode.length == 3) { + if (properMapcode.length==3) isoa = alias2iso(properMapcode); - } else { + else isoa = alias2iso(disambiguate + '' + properMapcode); - } if (isoa) { if (isoa.charAt(0) == disambiguate) { properMapcode = isoa.substring(1); } else { properMapcode = isoa; i = findISO(properMapcode); - if (i >= 0) { + if (i>=0) { return i; } } @@ -268,7 +267,7 @@ function iso2ccode(territoryAlphaCode) { } // first rewrite alias in context - if (territoryAlphaCode.length == 2) { + if (territoryAlphaCode.length==2) { isoa = alias2iso(disambiguate + '' + territoryAlphaCode); if (isoa) { if (isoa.charAt(0) == disambiguate) { @@ -280,41 +279,41 @@ function iso2ccode(territoryAlphaCode) { } // no prefix. check if a normal territory - if (territoryAlphaCode.length == 3) { + if (territoryAlphaCode.length==3) { i = findISO(territoryAlphaCode); - if (i >= 0) { + if (i>=0) { return i; } } // no prefix, check in context i = findISO(parentname2(disambiguate) + '-' + territoryAlphaCode); - if (i >= 0) { + if (i>=0) { return i; } - if (territoryAlphaCode.length >= 2) { + if (territoryAlphaCode.length>=2) { i = findISO(parentname2(disambiguate) + '-' + territoryAlphaCode); - if (i >= 0) { - return i; + if (i>=0) { + return i; } // find in ANY context var hyphenated = '-' + territoryAlphaCode; for (i = 0; i < iso3166alpha.length; i++) { - if (iso3166alpha[i].indexOf(hyphenated) > 0) { - if (iso3166alpha[i].substring(iso3166alpha[i].indexOf(hyphenated)) == hyphenated) { + if (iso3166alpha[i].indexOf(hyphenated)>0) { + if (iso3166alpha[i].substring(iso3166alpha[i].indexOf(hyphenated))==hyphenated) { return i; } } } } - + // all else failed, try non-disambiguated alphacode isoa = alias2iso(territoryAlphaCode); // or try ANY alias if (isoa) { if (isoa.charCodeAt(0) <= 57) { // starts with digit - territoryAlphaCode = parentname2(isoa.charCodeAt(0) - 48) + '-' + isoa.substring(1); + territoryAlphaCode = parentname2(isoa.charCodeAt(0)-48) + '-' + isoa.substring(1); } else { territoryAlphaCode = isoa; } @@ -439,11 +438,11 @@ function getTerritoryAlphaCode(territory, format) { } var full = iso3166alpha[territoryNumber]; var hyphen = full.indexOf("-"); - if (format == 1 || hyphen <= 0) { + if (format==1 || hyphen<=0) { return full; } - var short = full.substr(hyphen + 1); - if (format == 0) { + var short = full.substr(hyphen+1); + if (format==0) { return short; } // shortest POSSIBLE @@ -455,7 +454,7 @@ function getTerritoryAlphaCode(territory, format) { count = 2; } else { for (i = 0; i < iso3166alpha.length; i++) { - if (iso3166alpha[i].indexOf("-" + short) > 0) { + if (iso3166alpha[i].indexOf("-"+short)>0) { count++; } } @@ -1140,7 +1139,7 @@ var asc2lan = [ [0x0C1E, 0x0C15, 0x0C17, 0x0C19, 0x0C2B, 0x0C1A, 0x0C1C, 0x0C1F, 0x0049, 0x0C20, 0x0C21, 0x0C23, 0x0C24, 0x0C25, 0x004f, 0x0C26, 0x0C27, 0x0C28, 0x0C2A, 0x0C2C, 0x0C2D, 0x0C2E, 0x0C30, 0x0C32, 0x0C33, 0x0C35, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Telugu [0x0B1D, 0x0B15, 0x0B16, 0x0B17, 0x0B23, 0x0B18, 0x0B1A, 0x0B1C, 0x0049, 0x0B1F, 0x0B21, 0x0B22, 0x0B24, 0x0B25, 0x0B20, 0x0B26, 0x0B27, 0x0B28, 0x0B2A, 0x0B2C, 0x0B39, 0x0B2E, 0x0B2F, 0x0B30, 0x0B33, 0x0B38, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Odia [0x0C92, 0x0C95, 0x0C96, 0x0C97, 0x0C8E, 0x0C99, 0x0C9A, 0x0C9B, 0x0049, 0x0C9C, 0x0CA0, 0x0CA1, 0x0CA3, 0x0CA4, 0x004f, 0x0CA6, 0x0CA7, 0x0CA8, 0x0CAA, 0x0CAB, 0x0C87, 0x0CAC, 0x0CAD, 0x0CB0, 0x0CB2, 0x0CB5, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Kannada - [0x0AB3, 0x0A97, 0x0A9C, 0x0AA1, 0x0A87, 0x0AA6, 0x0AAC, 0x0A95, 0x0049, 0x0A9A, 0x0A9F, 0x0AA4, 0x0AAA, 0x0AA0, 0x004f, 0x0AB0, 0x0AB5, 0x0A9E, 0x0AAE, 0x0AAB, 0x0A89, 0x0AB7, 0x0AA8, 0x0A9D, 0x0AA2, 0x0AAD, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Gujarati + [0x0AB3, 0x0A97, 0x0A9C, 0x0AA1, 0x0A87, 0x0AA6, 0x0AAC, 0x0A95, 0x0049, 0x0A9A, 0x0A9F, 0x0AA4, 0x0AAA, 0x0AA0, 0x004f, 0x0AB0, 0x0AB5, 0x0A9E, 0x0AAE, 0x0AAB, 0x0A89, 0x0AB7, 0x0AA8, 0x0A9D, 0x0AA2, 0x0AAD, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Gujarati ] @@ -1183,7 +1182,7 @@ var lanlannam = [ ["кириллица"], ["עִבְרִית"], ["देवनागरी"], // Devanagari - ["മലയാളം"], // Malayalam + ["മലയാളം"], // Malayalam ["ქართული"], ["カタカナ"], ["ภาษาไทย"], @@ -1195,8 +1194,8 @@ var lanlannam = [ ["العَرَبِيَّة"], ["조선글/한글"], // Korean (Choson'gul / Hangul ) ["မြန်မာအက္ခရာ"], // Burmese - ["អក្សរខ្មែរ"], // Khmer script - ['සිංහල අක්ෂර මාලාව'], // Sinhalese + ["អក្សរខ្មែរ"], // Khmer script + ['සිංහල අක්ෂර මාලාව'], // Sinhalese ["ތާނަ"], // Thaana (Maldivan) ["ㄅㄆㄇㄈ"], // Chinese (bopomofo) // 注音符號, ["ⵜⵉⴼⵉⵏⴰⵖ"], // Tifinagh (Berber) From 1bcd44819a35b01bef145647de4045ada31374eb Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Tue, 25 Oct 2016 15:40:45 +0200 Subject: [PATCH 34/54] Revert "Release 2.4.0" This reverts commit c3d82e3d0c2e759ebb750bdc52879abfd6508c3a. --- README.md | 10 ++++++---- mapcode.js | 55 +++++++++++++++++++++++++++--------------------------- 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 5dbf094..77e43cd 100644 --- a/README.md +++ b/README.md @@ -55,13 +55,15 @@ To run the Javascript unit tests, simply open the file `unittest/unittest/html`. Renamed language strings to more correct terms (Malay to Malayalam; Hindi to Devanagari). - Added var alphabetsForTerritory[t], returning the most commonly used alphabets for territory t. + Added var `alphabetsForTerritory[t]`, returning the most commonly used alphabets for territory `t`. - Improved some characters for Arabic and Devanagari; Fixed Bengali to also support Assamese. + Improved some characters for Arabic and Devanagari. + + Fixed Bengali to also support Assamese. - For some alphabets, removed recognition of letters I and/or O unless looking like digits 1 and/or 0. + For some alphabets, removed recognition of letters `I` and/or `O` unless looking like digits `1` and/or `0`. - replaced internal encoded entity_iso[] array by non-encoded iso3166alpha[]. + Replaced internal encoded `entity_iso[]` array by non-encoded `iso3166alpha[]`. * 2.3.1 diff --git a/mapcode.js b/mapcode.js index 7c02531..6e1e82a 100644 --- a/mapcode.js +++ b/mapcode.js @@ -12,9 +12,9 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - */ + */ var iso3166alpha = [ - + 'VAT', 'MCO', 'GIB', 'TKL', 'CCK', 'BLM', 'NRU', 'TUV', 'MAC', 'SXM', 'MAF', 'NFK', 'PCN', 'BVT', 'BMU', 'IOT', 'SMR', 'GGY', 'AIA', 'MSR', 'JEY', 'CXR', 'WLF', 'VGB', 'LIE', 'ABW', 'MHL', 'ASM', 'COK', 'SPM', @@ -235,30 +235,31 @@ function iso2ccode(territoryAlphaCode) { } } - var i,isoa; + var i, isoa; var sep = territoryAlphaCode.lastIndexOf('-'); if (sep >= 0) { // territory! var prefix = territoryAlphaCode.substring(0, sep); var properMapcode = territoryAlphaCode.substring(sep + 1); - if (set_disambiguate(prefix) || properMapcode.length<2) { + if (set_disambiguate(prefix) || properMapcode.length < 2) { return -1; } i = findISO(parentname2(disambiguate) + '-' + properMapcode); - if (i>=0) { + if (i >= 0) { return i; } // recognise alias - if (properMapcode.length==3) + if (properMapcode.length == 3) { isoa = alias2iso(properMapcode); - else + } else { isoa = alias2iso(disambiguate + '' + properMapcode); + } if (isoa) { if (isoa.charAt(0) == disambiguate) { properMapcode = isoa.substring(1); } else { properMapcode = isoa; i = findISO(properMapcode); - if (i>=0) { + if (i >= 0) { return i; } } @@ -267,7 +268,7 @@ function iso2ccode(territoryAlphaCode) { } // first rewrite alias in context - if (territoryAlphaCode.length==2) { + if (territoryAlphaCode.length == 2) { isoa = alias2iso(disambiguate + '' + territoryAlphaCode); if (isoa) { if (isoa.charAt(0) == disambiguate) { @@ -279,41 +280,41 @@ function iso2ccode(territoryAlphaCode) { } // no prefix. check if a normal territory - if (territoryAlphaCode.length==3) { + if (territoryAlphaCode.length == 3) { i = findISO(territoryAlphaCode); - if (i>=0) { + if (i >= 0) { return i; } } // no prefix, check in context i = findISO(parentname2(disambiguate) + '-' + territoryAlphaCode); - if (i>=0) { + if (i >= 0) { return i; } - if (territoryAlphaCode.length>=2) { + if (territoryAlphaCode.length >= 2) { i = findISO(parentname2(disambiguate) + '-' + territoryAlphaCode); - if (i>=0) { - return i; + if (i >= 0) { + return i; } // find in ANY context var hyphenated = '-' + territoryAlphaCode; for (i = 0; i < iso3166alpha.length; i++) { - if (iso3166alpha[i].indexOf(hyphenated)>0) { - if (iso3166alpha[i].substring(iso3166alpha[i].indexOf(hyphenated))==hyphenated) { + if (iso3166alpha[i].indexOf(hyphenated) > 0) { + if (iso3166alpha[i].substring(iso3166alpha[i].indexOf(hyphenated)) == hyphenated) { return i; } } } } - + // all else failed, try non-disambiguated alphacode isoa = alias2iso(territoryAlphaCode); // or try ANY alias if (isoa) { if (isoa.charCodeAt(0) <= 57) { // starts with digit - territoryAlphaCode = parentname2(isoa.charCodeAt(0)-48) + '-' + isoa.substring(1); + territoryAlphaCode = parentname2(isoa.charCodeAt(0) - 48) + '-' + isoa.substring(1); } else { territoryAlphaCode = isoa; } @@ -438,11 +439,11 @@ function getTerritoryAlphaCode(territory, format) { } var full = iso3166alpha[territoryNumber]; var hyphen = full.indexOf("-"); - if (format==1 || hyphen<=0) { + if (format == 1 || hyphen <= 0) { return full; } - var short = full.substr(hyphen+1); - if (format==0) { + var short = full.substr(hyphen + 1); + if (format == 0) { return short; } // shortest POSSIBLE @@ -454,7 +455,7 @@ function getTerritoryAlphaCode(territory, format) { count = 2; } else { for (i = 0; i < iso3166alpha.length; i++) { - if (iso3166alpha[i].indexOf("-"+short)>0) { + if (iso3166alpha[i].indexOf("-" + short) > 0) { count++; } } @@ -1139,7 +1140,7 @@ var asc2lan = [ [0x0C1E, 0x0C15, 0x0C17, 0x0C19, 0x0C2B, 0x0C1A, 0x0C1C, 0x0C1F, 0x0049, 0x0C20, 0x0C21, 0x0C23, 0x0C24, 0x0C25, 0x004f, 0x0C26, 0x0C27, 0x0C28, 0x0C2A, 0x0C2C, 0x0C2D, 0x0C2E, 0x0C30, 0x0C32, 0x0C33, 0x0C35, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Telugu [0x0B1D, 0x0B15, 0x0B16, 0x0B17, 0x0B23, 0x0B18, 0x0B1A, 0x0B1C, 0x0049, 0x0B1F, 0x0B21, 0x0B22, 0x0B24, 0x0B25, 0x0B20, 0x0B26, 0x0B27, 0x0B28, 0x0B2A, 0x0B2C, 0x0B39, 0x0B2E, 0x0B2F, 0x0B30, 0x0B33, 0x0B38, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Odia [0x0C92, 0x0C95, 0x0C96, 0x0C97, 0x0C8E, 0x0C99, 0x0C9A, 0x0C9B, 0x0049, 0x0C9C, 0x0CA0, 0x0CA1, 0x0CA3, 0x0CA4, 0x004f, 0x0CA6, 0x0CA7, 0x0CA8, 0x0CAA, 0x0CAB, 0x0C87, 0x0CAC, 0x0CAD, 0x0CB0, 0x0CB2, 0x0CB5, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Kannada - [0x0AB3, 0x0A97, 0x0A9C, 0x0AA1, 0x0A87, 0x0AA6, 0x0AAC, 0x0A95, 0x0049, 0x0A9A, 0x0A9F, 0x0AA4, 0x0AAA, 0x0AA0, 0x004f, 0x0AB0, 0x0AB5, 0x0A9E, 0x0AAE, 0x0AAB, 0x0A89, 0x0AB7, 0x0AA8, 0x0A9D, 0x0AA2, 0x0AAD, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Gujarati + [0x0AB3, 0x0A97, 0x0A9C, 0x0AA1, 0x0A87, 0x0AA6, 0x0AAC, 0x0A95, 0x0049, 0x0A9A, 0x0A9F, 0x0AA4, 0x0AAA, 0x0AA0, 0x004f, 0x0AB0, 0x0AB5, 0x0A9E, 0x0AAE, 0x0AAB, 0x0A89, 0x0AB7, 0x0AA8, 0x0A9D, 0x0AA2, 0x0AAD, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039], // Gujarati ] @@ -1182,7 +1183,7 @@ var lanlannam = [ ["кириллица"], ["עִבְרִית"], ["देवनागरी"], // Devanagari - ["മലയാളം"], // Malayalam + ["മലയാളം"], // Malayalam ["ქართული"], ["カタカナ"], ["ภาษาไทย"], @@ -1194,8 +1195,8 @@ var lanlannam = [ ["العَرَبِيَّة"], ["조선글/한글"], // Korean (Choson'gul / Hangul ) ["မြန်မာအက္ခရာ"], // Burmese - ["អក្សរខ្មែរ"], // Khmer script - ['සිංහල අක්ෂර මාලාව'], // Sinhalese + ["អក្សរខ្មែរ"], // Khmer script + ['සිංහල අක්ෂර මාලාව'], // Sinhalese ["ތާނަ"], // Thaana (Maldivan) ["ㄅㄆㄇㄈ"], // Chinese (bopomofo) // 注音符號, ["ⵜⵉⴼⵉⵏⴰⵖ"], // Tifinagh (Berber) From b2d8708430f31892f01f68447f2265500ebd66a8 Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Mon, 16 Jan 2017 10:28:25 +0100 Subject: [PATCH 35/54] Improved README.md --- README.md | 139 +++++++++++++++++++++++++++--------------------------- 1 file changed, 70 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index 77e43cd..940e52a 100644 --- a/README.md +++ b/README.md @@ -47,135 +47,136 @@ To run the Javascript unit tests, simply open the file `unittest/unittest/html`. # Version History +### 2.4.0 -* 2.4.0 +* Added scripts for Korean (Choson'gul / Hangul), Burmese, Khmer, Sinhalese, Thaana (Maldivan), + Chinese (Zhuyin, Bopomofo), Tifinagh (Berber), Tamil, Amharic, Telugu, Odia, Kannada, Gujarati. - Added scripts for Korean (Choson'gul / Hangul), Burmese, Khmer, Sinhalese, Thaana (Maldivan), - Chinese (Zhuyin, Bopomofo), Tifinagh (Berber), Tamil, Amharic, Telugu, Odia, Kannada, Gujarati. +* Renamed language strings to more correct terms (Malay to Malayalam; Hindi to Devanagari). - Renamed language strings to more correct terms (Malay to Malayalam; Hindi to Devanagari). +* Added var `alphabetsForTerritory[t]`, returning the most commonly used alphabets for territory `t`. - Added var `alphabetsForTerritory[t]`, returning the most commonly used alphabets for territory `t`. - - Improved some characters for Arabic and Devanagari. - +* Improved some characters for Arabic and Devanagari. +* Fixed Bengali to also support Assamese. - For some alphabets, removed recognition of letters `I` and/or `O` unless looking like digits `1` and/or `0`. +* For some alphabets, removed recognition of letters `I` and/or `O` unless looking like digits `1` and/or `0`. - Replaced internal encoded `entity_iso[]` array by non-encoded `iso3166alpha[]`. +* Replaced internal encoded `entity_iso[]` array by non-encoded `iso3166alpha[]`. -* 2.3.1 +### 2.3.1 - Minor fixes to prevent some compiler warnings, or multiple inclusion of `.h` files. +* Minor fixes to prevent some compiler warnings, or multiple inclusion of `.h` files. - Minor data fix (`ndata.js`) for Gansu Province, China (where mountain range extending further west). +* Minor data fix (`ndata.js`) for Gansu Province, China (where mountain range extending further west). -* 2.3.0 +### 2.3.0 - Arabic script added. - - Tibetan script changed so all characters can be typed on a computer keyboard without using the SHIFT key. +* Arabic script added. +* Tibetan script changed so all characters can be typed on a computer keyboard without using the SHIFT key. - Greek, Hebrew and Arabic, the scripts that have (implied) vowels in mapcode sequences, have been extended with - ABJAD conversion, to prevent more than two consecutive non-digits from occurring. - NOTE: as a result, mapcodes in Greek, Arab and Hebrew scripts are now often one character longer than in the roman script. +* Greek, Hebrew and Arabic, the scripts that have (implied) vowels in mapcode sequences, have been extended with + ABJAD conversion, to prevent more than two consecutive non-digits from occurring. + +* NOTE: as a result, mapcodes in Greek, Arab and Hebrew scripts are now often one character longer than in the roman script. -* 2.2.0 +### 2.2.0 - Solved 1-microdegree gap in a few spots on Earth, noticable now extreme precision is possible; +* Solved 1-microdegree gap in a few spots on Earth, noticable now extreme precision is possible; - Ran source through code prettifier +* Ran source through code prettifier -* 2.1.5 +### 2.1.5 - Added maxErrorInMeters to API; +* Added maxErrorInMeters to API; - Enforce encode(decode(m))=m except near territory borders +* Enforce `encode(decode(m)) == m` except near territory borders - Stricter unit tests; +* Stricter unit tests; -* 2.1.1 +### 2.1.1 - Added DistanceInMeters to API +* Added DistanceInMeters to API -* 2.1.0 +### 2.1.0 - Rewrote fraction floating points to integer arithmetic +* Rewrote fraction floating points to integer arithmetic -* 2.0.3 +### 2.0.3 - Minor fix. Added unittest\unittest.html - open to peform - tests that try to verify that the library works as intended; +* Minor fix. Added `unittest\unittest.html` - open to peform + tests that try to verify that the library works as intended; -* 2.0.1 +### 2.0.1 - Minor fixes. +* Minor fixes. -* 2.0.0 - July 2015 +### 2.0.0 - July 2015 - Fixes to the data rectangles (primarily intended for ISO proposal), see Word document for details. +* Fixes to the data rectangles (primarily intended for ISO proposal), see Word document for details. -* 1.54 - June 2015 +### 1.54 - June 2015 - Removed unneeded mminfo flags (no effect on functionality). +* Removed unneeded mminfo flags (no effect on functionality). -* 1.50.3 - May 2015 +### 1.50.3 - May 2015 - Redesign of the API to conform to Javascript standards and match the Java implementation of the mapcode system +* Redesign of the API to conform to Javascript standards and match the Java implementation of the mapcode system -* 1.50.1 - May 2015 +### 1.50.1 - May 2015 - Bugfix for mapcodes in IN-DD (in India). +* Bugfix for mapcodes in IN-DD (in India). -* 1.50 - May 2015 +### 1.50 - May 2015 - Major release. This version is not backwards compatible with mapcode 1.4x: is has dropped support for +* Major release. This version is not backwards compatible with mapcode 1.4x: it has dropped support for Antartica AT0-8 codes and has a changed (improved) way of dealing with the Greek alphabet. - Added 22-chararcter post-processing of all-digit mapcodes for the Greek alphabet. +* Added 22-chararcter post-processing of all-digit mapcodes for the Greek alphabet. + +* Retired legacy aliases EAZ and SKM, AU-QL, AU-TS, AU-NI and AU-JB. - Retired legacy aliases EAZ and SKM, AU-QL, AU-TS, AU-NI and AU-JB. +* Retired legacy Antarctica claims AT0 through AT8. - Retired legacy Antarctica claims AT0 through AT8. +### 1.41 - January 2015 -* 1.41 - January 2015 +* Added the India state Telangana (IN-TG), until 2014 a region in Adhra Pradesh. - Added the India state Telangana (IN-TG), until 2014 a region in Adhra Pradesh. +### 1.33 - August 2014 -* 1.33 - August 2014 +* Normalise results when longitude below -180 degrees. - Normalise results when longitude below -180 degrees. +### 1.32 - August 2014 -* 1.32 - August 2014 +* Prevent FIJI failing to decode at exactly 180 degrees. - Prevent FIJI failing to decode at exactly 180 degrees; prevent invalid filtering near the territory bounding rectangle. +* Prevent invalid filtering near the territory bounding rectangle. -* 1.31 - April 2014 +### 1.31 - April 2014 - Make iso2ccode() even more forgiving by allowing a state alias to be recognized in context. +* Make `iso2ccode()` even more forgiving by allowing a state alias to be recognized in context. -* 1.3 - April 2014 +### 1.3 - April 2014 - Disable 7-char state codes for large states in India, and instead generate country mapcodes for states. +* Disable 7-char state codes for large states in India, and instead generate country mapcodes for states. -* 1.28 - April 2014 +### 1.28 - April 2014 - Fix for starpipe "zoning" error, causing the last 2 mapcode characters to be ignored in certain areas. +* Fix for starpipe "zoning" error, causing the last 2 mapcode characters to be ignored in certain areas. -* 1.27 - April 2014 +### 1.27 - April 2014 - Support undefined ranges in data array (useful for partial JavaScript builds). +* Support undefined ranges in data array (useful for partial JavaScript builds). -* 1.26 - May 2013 +### 1.26 - May 2013 - Added alias OD for India, and 2.3 code for Daman and Diu. +* Added alias OD for India, and 2.3 code for Daman and Diu. -* 1.25 - May 2013 +### 1.25 - May 2013 - Ccode2iso(c,2) support added. +* `Ccode2iso(c, 2)` support added. -* 1.24 - May 2013 +### 1.24 - May 2013 - Public domain release. +* Public domain release. From 3a456faa5833ec888ad7c3cf3dd99f384c98191b Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Mon, 16 Jan 2017 10:32:20 +0100 Subject: [PATCH 36/54] Fixed capitalization of text --- unittest/unittest.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unittest/unittest.html b/unittest/unittest.html index b4e8ac0..f6cb584 100644 --- a/unittest/unittest.html +++ b/unittest/unittest.html @@ -662,7 +662,7 @@

Mapcode Javascript Unit Tests

test_failing_decodes(); break; case 7: - out('
Encode/Decode tests'); + out('
Encode/decode tests'); break; case 8: if (test_encodes_decodes()) { @@ -670,7 +670,7 @@

Mapcode Javascript Unit Tests

} break; case 9: - out('
Edge-case Encode/Decode tests'); + out('
Edge-case encode/decode tests'); break; case 10: if (test_corner_encodes()) { From 48beb28180a55a108f73f692a6eee9069fa7c927 Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Mon, 6 Mar 2017 12:08:42 +0100 Subject: [PATCH 37/54] Added CSV converter as an example --- csv/FileSave.js | 188 +++++++++ csv/converter.html | 161 ++++++++ csv/jquery.csv.js | 975 +++++++++++++++++++++++++++++++++++++++++++++ csv/sample.csv | 15 + 4 files changed, 1339 insertions(+) create mode 100644 csv/FileSave.js create mode 100644 csv/converter.html create mode 100644 csv/jquery.csv.js create mode 100644 csv/sample.csv diff --git a/csv/FileSave.js b/csv/FileSave.js new file mode 100644 index 0000000..940a516 --- /dev/null +++ b/csv/FileSave.js @@ -0,0 +1,188 @@ +/* FileSaver.js + * A saveAs() FileSaver implementation. + * 1.3.2 + * 2016-06-16 18:25:19 + * + * By Eli Grey, http://eligrey.com + * License: MIT + * See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md + */ + +/*global self */ +/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */ + +/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ + +var saveAs = saveAs || (function(view) { + "use strict"; + // IE <10 is explicitly unsupported + if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) { + return; + } + var + doc = view.document + // only get URL when necessary in case Blob.js hasn't overridden it yet + , get_URL = function() { + return view.URL || view.webkitURL || view; + } + , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a") + , can_use_save_link = "download" in save_link + , click = function(node) { + var event = new MouseEvent("click"); + node.dispatchEvent(event); + } + , is_safari = /constructor/i.test(view.HTMLElement) || view.safari + , is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent) + , throw_outside = function(ex) { + (view.setImmediate || view.setTimeout)(function() { + throw ex; + }, 0); + } + , force_saveable_type = "application/octet-stream" + // the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to + , arbitrary_revoke_timeout = 1000 * 40 // in ms + , revoke = function(file) { + var revoker = function() { + if (typeof file === "string") { // file is an object URL + get_URL().revokeObjectURL(file); + } else { // file is a File + file.remove(); + } + }; + setTimeout(revoker, arbitrary_revoke_timeout); + } + , dispatch = function(filesaver, event_types, event) { + event_types = [].concat(event_types); + var i = event_types.length; + while (i--) { + var listener = filesaver["on" + event_types[i]]; + if (typeof listener === "function") { + try { + listener.call(filesaver, event || filesaver); + } catch (ex) { + throw_outside(ex); + } + } + } + } + , auto_bom = function(blob) { + // prepend BOM for UTF-8 XML and text/* types (including HTML) + // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF + if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) { + return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type}); + } + return blob; + } + , FileSaver = function(blob, name, no_auto_bom) { + if (!no_auto_bom) { + blob = auto_bom(blob); + } + // First try a.download, then web filesystem, then object URLs + var + filesaver = this + , type = blob.type + , force = type === force_saveable_type + , object_url + , dispatch_all = function() { + dispatch(filesaver, "writestart progress write writeend".split(" ")); + } + // on any filesys errors revert to saving with object URLs + , fs_error = function() { + if ((is_chrome_ios || (force && is_safari)) && view.FileReader) { + // Safari doesn't allow downloading of blob urls + var reader = new FileReader(); + reader.onloadend = function() { + var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;'); + var popup = view.open(url, '_blank'); + if(!popup) view.location.href = url; + url=undefined; // release reference before dispatching + filesaver.readyState = filesaver.DONE; + dispatch_all(); + }; + reader.readAsDataURL(blob); + filesaver.readyState = filesaver.INIT; + return; + } + // don't create more object URLs than needed + if (!object_url) { + object_url = get_URL().createObjectURL(blob); + } + if (force) { + view.location.href = object_url; + } else { + var opened = view.open(object_url, "_blank"); + if (!opened) { + // Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html + view.location.href = object_url; + } + } + filesaver.readyState = filesaver.DONE; + dispatch_all(); + revoke(object_url); + } + ; + filesaver.readyState = filesaver.INIT; + + if (can_use_save_link) { + object_url = get_URL().createObjectURL(blob); + setTimeout(function() { + save_link.href = object_url; + save_link.download = name; + click(save_link); + dispatch_all(); + revoke(object_url); + filesaver.readyState = filesaver.DONE; + }); + return; + } + + fs_error(); + } + , FS_proto = FileSaver.prototype + , saveAs = function(blob, name, no_auto_bom) { + return new FileSaver(blob, name || blob.name || "download", no_auto_bom); + } + ; + // IE 10+ (native saveAs) + if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) { + return function(blob, name, no_auto_bom) { + name = name || blob.name || "download"; + + if (!no_auto_bom) { + blob = auto_bom(blob); + } + return navigator.msSaveOrOpenBlob(blob, name); + }; + } + + FS_proto.abort = function(){}; + FS_proto.readyState = FS_proto.INIT = 0; + FS_proto.WRITING = 1; + FS_proto.DONE = 2; + + FS_proto.error = + FS_proto.onwritestart = + FS_proto.onprogress = + FS_proto.onwrite = + FS_proto.onabort = + FS_proto.onerror = + FS_proto.onwriteend = + null; + + return saveAs; + }( + typeof self !== "undefined" && self + || typeof window !== "undefined" && window + || this.content + )); +// `self` is undefined in Firefox for Android content script context +// while `this` is nsIContentFrameMessageManager +// with an attribute `content` that corresponds to the window + +if (typeof module !== "undefined" && module.exports) { + module.exports.saveAs = saveAs; +} else if ((typeof define !== "undefined" && define !== null) && (define.amd !== null)) { + define("FileSaver.js", function() { + return saveAs; + }); +} diff --git a/csv/converter.html b/csv/converter.html new file mode 100644 index 0000000..eec48f2 --- /dev/null +++ b/csv/converter.html @@ -0,0 +1,161 @@ + + + + + + + + Mapcode CSV Converter + + + +

Mapcode CSV Converter

+

+ Select a CSV file which has the following columns:
+ latitude, longitude, territory (optional)

+

The context is used to specify the territory for which the shortest mapcode should be displayed. + For example, for South Africa, this would be ZAF.

+

Example of a CSF file:

+

+ -28.700225, 28.602905, (note the territory is missing)
+ -28.700225, 28.602905, ZAF
+ -28.433676, 19.986191, ZAF +

+

This produces the following output:

+

+ -28.700225,28.602905,LSO MRG.8XX,8KYVG.4C8Y
+ -28.700225,28.602905,ZAF QNW2.Y72,8KYVG.4C8Y
+ -28.433676,19.986191,ZAF 6MQP.506,8K70Z.7PB4 +

+

The output is automatically saved to mapcodes.csv in your Downloads folder.

+ +
+ +
+
+ + +
+ +
+ + + + + + + + + + diff --git a/csv/jquery.csv.js b/csv/jquery.csv.js new file mode 100644 index 0000000..6a64af2 --- /dev/null +++ b/csv/jquery.csv.js @@ -0,0 +1,975 @@ +/** + * jQuery-csv (jQuery Plugin) + * + * This document is licensed as free software under the terms of the + * MIT License: http://www.opensource.org/licenses/mit-license.php + * + * Acknowledgements: + * The original design and influence to implement this library as a jquery + * plugin is influenced by jquery-json (http://code.google.com/p/jquery-json/). + * If you're looking to use native JSON.Stringify but want additional backwards + * compatibility for browsers that don't support it, I highly recommend you + * check it out. + * + * A special thanks goes out to rwk@acm.org for providing a lot of valuable + * feedback to the project including the core for the new FSM + * (Finite State Machine) parsers. If you're looking for a stable TSV parser + * be sure to take a look at jquery-tsv (http://code.google.com/p/jquery-tsv/). + + * For legal purposes I'll include the "NO WARRANTY EXPRESSED OR IMPLIED. + * USE AT YOUR OWN RISK.". Which, in 'layman's terms' means, by using this + * library you are accepting responsibility if it breaks your code. + * + * Legal jargon aside, I will do my best to provide a useful and stable core + * that can effectively be built on. + * + * Copyrighted 2012 by Evan Plaice. + */ + +RegExp.escape= function(s) { + return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); +}; + +(function (undefined) { + 'use strict'; + + var $; + + // to keep backwards compatibility + if (typeof jQuery !== 'undefined' && jQuery) { + $ = jQuery; + } else { + $ = {}; + } + + + /** + * jQuery.csv.defaults + * Encapsulates the method paramater defaults for the CSV plugin module. + */ + + $.csv = { + defaults: { + separator:',', + delimiter:'"', + headers:true + }, + + hooks: { + castToScalar: function(value, state) { + var hasDot = /\./; + if (isNaN(value)) { + return value; + } else { + if (hasDot.test(value)) { + return parseFloat(value); + } else { + var integer = parseInt(value); + if(isNaN(integer)) { + return null; + } else { + return integer; + } + } + } + } + }, + + parsers: { + parse: function(csv, options) { + // cache settings + var separator = options.separator; + var delimiter = options.delimiter; + + // set initial state if it's missing + if(!options.state.rowNum) { + options.state.rowNum = 1; + } + if(!options.state.colNum) { + options.state.colNum = 1; + } + + // clear initial state + var data = []; + var entry = []; + var state = 0; + var value = ''; + var exit = false; + + function endOfEntry() { + // reset the state + state = 0; + value = ''; + + // if 'start' hasn't been met, don't output + if(options.start && options.state.rowNum < options.start) { + // update global state + entry = []; + options.state.rowNum++; + options.state.colNum = 1; + return; + } + + if(options.onParseEntry === undefined) { + // onParseEntry hook not set + data.push(entry); + } else { + var hookVal = options.onParseEntry(entry, options.state); // onParseEntry Hook + // false skips the row, configurable through a hook + if(hookVal !== false) { + data.push(hookVal); + } + } + //console.log('entry:' + entry); + + // cleanup + entry = []; + + // if 'end' is met, stop parsing + if(options.end && options.state.rowNum >= options.end) { + exit = true; + } + + // update global state + options.state.rowNum++; + options.state.colNum = 1; + } + + function endOfValue() { + if(options.onParseValue === undefined) { + // onParseValue hook not set + entry.push(value); + } else { + var hook = options.onParseValue(value, options.state); // onParseValue Hook + // false skips the row, configurable through a hook + if(hook !== false) { + entry.push(hook); + } + } + //console.log('value:' + value); + // reset the state + value = ''; + state = 0; + // update global state + options.state.colNum++; + } + + // escape regex-specific control chars + var escSeparator = RegExp.escape(separator); + var escDelimiter = RegExp.escape(delimiter); + + // compile the regEx str using the custom delimiter/separator + var match = /(D|S|\r\n|\n|\r|[^DS\r\n]+)/; + var matchSrc = match.source; + matchSrc = matchSrc.replace(/S/g, escSeparator); + matchSrc = matchSrc.replace(/D/g, escDelimiter); + match = new RegExp(matchSrc, 'gm'); + + // put on your fancy pants... + // process control chars individually, use look-ahead on non-control chars + csv.replace(match, function (m0) { + if(exit) { + return; + } + switch (state) { + // the start of a value + case 0: + // null last value + if (m0 === separator) { + value += ''; + endOfValue(); + break; + } + // opening delimiter + if (m0 === delimiter) { + state = 1; + break; + } + // null last value + if (/^(\r\n|\n|\r)$/.test(m0)) { + endOfValue(); + endOfEntry(); + break; + } + // un-delimited value + value += m0; + state = 3; + break; + + // delimited input + case 1: + // second delimiter? check further + if (m0 === delimiter) { + state = 2; + break; + } + // delimited data + value += m0; + state = 1; + break; + + // delimiter found in delimited input + case 2: + // escaped delimiter? + if (m0 === delimiter) { + value += m0; + state = 1; + break; + } + // null value + if (m0 === separator) { + endOfValue(); + break; + } + // end of entry + if (/^(\r\n|\n|\r)$/.test(m0)) { + endOfValue(); + endOfEntry(); + break; + } + // broken paser? + throw new Error('CSVDataError: Illegal State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']'); + + // un-delimited input + case 3: + // null last value + if (m0 === separator) { + endOfValue(); + break; + } + // end of entry + if (/^(\r\n|\n|\r)$/.test(m0)) { + endOfValue(); + endOfEntry(); + break; + } + if (m0 === delimiter) { + // non-compliant data + throw new Error('CSVDataError: Illegal Quote [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']'); + } + // broken parser? + throw new Error('CSVDataError: Illegal Data [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']'); + default: + // shenanigans + throw new Error('CSVDataError: Unknown State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']'); + } + //console.log('val:' + m0 + ' state:' + state); + }); + + // submit the last entry + // ignore null last line + if(entry.length !== 0) { + endOfValue(); + endOfEntry(); + } + + return data; + }, + + // a csv-specific line splitter + splitLines: function(csv, options) { + // cache settings + var separator = options.separator; + var delimiter = options.delimiter; + + // set initial state if it's missing + if(!options.state.rowNum) { + options.state.rowNum = 1; + } + + // clear initial state + var entries = []; + var state = 0; + var entry = ''; + var exit = false; + + function endOfLine() { + // reset the state + state = 0; + + // if 'start' hasn't been met, don't output + if(options.start && options.state.rowNum < options.start) { + // update global state + entry = ''; + options.state.rowNum++; + return; + } + + if(options.onParseEntry === undefined) { + // onParseEntry hook not set + entries.push(entry); + } else { + var hookVal = options.onParseEntry(entry, options.state); // onParseEntry Hook + // false skips the row, configurable through a hook + if(hookVal !== false) { + entries.push(hookVal); + } + } + + // cleanup + entry = ''; + + // if 'end' is met, stop parsing + if(options.end && options.state.rowNum >= options.end) { + exit = true; + } + + // update global state + options.state.rowNum++; + } + + // escape regex-specific control chars + var escSeparator = RegExp.escape(separator); + var escDelimiter = RegExp.escape(delimiter); + + // compile the regEx str using the custom delimiter/separator + var match = /(D|S|\n|\r|[^DS\r\n]+)/; + var matchSrc = match.source; + matchSrc = matchSrc.replace(/S/g, escSeparator); + matchSrc = matchSrc.replace(/D/g, escDelimiter); + match = new RegExp(matchSrc, 'gm'); + + // put on your fancy pants... + // process control chars individually, use look-ahead on non-control chars + csv.replace(match, function (m0) { + if(exit) { + return; + } + switch (state) { + // the start of a value/entry + case 0: + // null value + if (m0 === separator) { + entry += m0; + state = 0; + break; + } + // opening delimiter + if (m0 === delimiter) { + entry += m0; + state = 1; + break; + } + // end of line + if (m0 === '\n') { + endOfLine(); + break; + } + // phantom carriage return + if (/^\r$/.test(m0)) { + break; + } + // un-delimit value + entry += m0; + state = 3; + break; + + // delimited input + case 1: + // second delimiter? check further + if (m0 === delimiter) { + entry += m0; + state = 2; + break; + } + // delimited data + entry += m0; + state = 1; + break; + + // delimiter found in delimited input + case 2: + // escaped delimiter? + var prevChar = entry.substr(entry.length - 1); + if (m0 === delimiter && prevChar === delimiter) { + entry += m0; + state = 1; + break; + } + // end of value + if (m0 === separator) { + entry += m0; + state = 0; + break; + } + // end of line + if (m0 === '\n') { + endOfLine(); + break; + } + // phantom carriage return + if (m0 === '\r') { + break; + } + // broken paser? + throw new Error('CSVDataError: Illegal state [Row:' + options.state.rowNum + ']'); + + // un-delimited input + case 3: + // null value + if (m0 === separator) { + entry += m0; + state = 0; + break; + } + // end of line + if (m0 === '\n') { + endOfLine(); + break; + } + // phantom carriage return + if (m0 === '\r') { + break; + } + // non-compliant data + if (m0 === delimiter) { + throw new Error('CSVDataError: Illegal quote [Row:' + options.state.rowNum + ']'); + } + // broken parser? + throw new Error('CSVDataError: Illegal state [Row:' + options.state.rowNum + ']'); + default: + // shenanigans + throw new Error('CSVDataError: Unknown state [Row:' + options.state.rowNum + ']'); + } + //console.log('val:' + m0 + ' state:' + state); + }); + + // submit the last entry + // ignore null last line + if(entry !== '') { + endOfLine(); + } + + return entries; + }, + + // a csv entry parser + parseEntry: function(csv, options) { + // cache settings + var separator = options.separator; + var delimiter = options.delimiter; + + // set initial state if it's missing + if(!options.state.rowNum) { + options.state.rowNum = 1; + } + if(!options.state.colNum) { + options.state.colNum = 1; + } + + // clear initial state + var entry = []; + var state = 0; + var value = ''; + + function endOfValue() { + if(options.onParseValue === undefined) { + // onParseValue hook not set + entry.push(value); + } else { + var hook = options.onParseValue(value, options.state); // onParseValue Hook + // false skips the value, configurable through a hook + if(hook !== false) { + entry.push(hook); + } + } + // reset the state + value = ''; + state = 0; + // update global state + options.state.colNum++; + } + + // checked for a cached regEx first + if(!options.match) { + // escape regex-specific control chars + var escSeparator = RegExp.escape(separator); + var escDelimiter = RegExp.escape(delimiter); + + // compile the regEx str using the custom delimiter/separator + var match = /(D|S|\n|\r|[^DS\r\n]+)/; + var matchSrc = match.source; + matchSrc = matchSrc.replace(/S/g, escSeparator); + matchSrc = matchSrc.replace(/D/g, escDelimiter); + options.match = new RegExp(matchSrc, 'gm'); + } + + // put on your fancy pants... + // process control chars individually, use look-ahead on non-control chars + csv.replace(options.match, function (m0) { + switch (state) { + // the start of a value + case 0: + // null last value + if (m0 === separator) { + value += ''; + endOfValue(); + break; + } + // opening delimiter + if (m0 === delimiter) { + state = 1; + break; + } + // skip un-delimited new-lines + if (m0 === '\n' || m0 === '\r') { + break; + } + // un-delimited value + value += m0; + state = 3; + break; + + // delimited input + case 1: + // second delimiter? check further + if (m0 === delimiter) { + state = 2; + break; + } + // delimited data + value += m0; + state = 1; + break; + + // delimiter found in delimited input + case 2: + // escaped delimiter? + if (m0 === delimiter) { + value += m0; + state = 1; + break; + } + // null value + if (m0 === separator) { + endOfValue(); + break; + } + // skip un-delimited new-lines + if (m0 === '\n' || m0 === '\r') { + break; + } + // broken paser? + throw new Error('CSVDataError: Illegal State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']'); + + // un-delimited input + case 3: + // null last value + if (m0 === separator) { + endOfValue(); + break; + } + // skip un-delimited new-lines + if (m0 === '\n' || m0 === '\r') { + break; + } + // non-compliant data + if (m0 === delimiter) { + throw new Error('CSVDataError: Illegal Quote [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']'); + } + // broken parser? + throw new Error('CSVDataError: Illegal Data [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']'); + default: + // shenanigans + throw new Error('CSVDataError: Unknown State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']'); + } + //console.log('val:' + m0 + ' state:' + state); + }); + + // submit the last value + endOfValue(); + + return entry; + } + }, + + helpers: { + + /** + * $.csv.helpers.collectPropertyNames(objectsArray) + * Collects all unique property names from all passed objects. + * + * @param {Array} objects Objects to collect properties from. + * + * Returns an array of property names (array will be empty, + * if objects have no own properties). + */ + collectPropertyNames: function (objects) { + + var o, propName, props = []; + for (o in objects) { + for (propName in objects[o]) { + if ((objects[o].hasOwnProperty(propName)) && + (props.indexOf(propName) < 0) && + (typeof objects[o][propName] !== 'function')) { + + props.push(propName); + } + } + } + return props; + } + }, + + /** + * $.csv.toArray(csv) + * Converts a CSV entry string to a javascript array. + * + * @param {Array} csv The string containing the CSV data. + * @param {Object} [options] An object containing user-defined options. + * @param {Character} [separator] An override for the separator character. Defaults to a comma(,). + * @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote("). + * + * This method deals with simple CSV strings only. It's useful if you only + * need to parse a single entry. If you need to parse more than one line, + * use $.csv2Array instead. + */ + toArray: function(csv, options, callback) { + options = (options !== undefined ? options : {}); + var config = {}; + config.callback = ((callback !== undefined && typeof(callback) === 'function') ? callback : false); + config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator; + config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter; + var state = (options.state !== undefined ? options.state : {}); + + // setup + options = { + delimiter: config.delimiter, + separator: config.separator, + onParseEntry: options.onParseEntry, + onParseValue: options.onParseValue, + state: state + }; + + var entry = $.csv.parsers.parseEntry(csv, options); + + // push the value to a callback if one is defined + if(!config.callback) { + return entry; + } else { + config.callback('', entry); + } + }, + + /** + * $.csv.toArrays(csv) + * Converts a CSV string to a javascript array. + * + * @param {String} csv The string containing the raw CSV data. + * @param {Object} [options] An object containing user-defined options. + * @param {Character} [separator] An override for the separator character. Defaults to a comma(,). + * @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote("). + * + * This method deals with multi-line CSV. The breakdown is simple. The first + * dimension of the array represents the line (or entry/row) while the second + * dimension contains the values (or values/columns). + */ + toArrays: function(csv, options, callback) { + options = (options !== undefined ? options : {}); + var config = {}; + config.callback = ((callback !== undefined && typeof(callback) === 'function') ? callback : false); + config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator; + config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter; + + // setup + var data = []; + options = { + delimiter: config.delimiter, + separator: config.separator, + onPreParse: options.onPreParse, + onParseEntry: options.onParseEntry, + onParseValue: options.onParseValue, + onPostParse: options.onPostParse, + start: options.start, + end: options.end, + state: { + rowNum: 1, + colNum: 1 + } + }; + + // onPreParse hook + if(options.onPreParse !== undefined) { + options.onPreParse(csv, options.state); + } + + // parse the data + data = $.csv.parsers.parse(csv, options); + + // onPostParse hook + if(options.onPostParse !== undefined) { + options.onPostParse(data, options.state); + } + + // push the value to a callback if one is defined + if(!config.callback) { + return data; + } else { + config.callback('', data); + } + }, + + /** + * $.csv.toObjects(csv) + * Converts a CSV string to a javascript object. + * @param {String} csv The string containing the raw CSV data. + * @param {Object} [options] An object containing user-defined options. + * @param {Character} [separator] An override for the separator character. Defaults to a comma(,). + * @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote("). + * @param {Boolean} [headers] Indicates whether the data contains a header line. Defaults to true. + * + * This method deals with multi-line CSV strings. Where the headers line is + * used as the key for each value per entry. + */ + toObjects: function(csv, options, callback) { + options = (options !== undefined ? options : {}); + var config = {}; + config.callback = ((callback !== undefined && typeof(callback) === 'function') ? callback : false); + config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator; + config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter; + config.headers = 'headers' in options ? options.headers : $.csv.defaults.headers; + options.start = 'start' in options ? options.start : 1; + + // account for headers + if(config.headers) { + options.start++; + } + if(options.end && config.headers) { + options.end++; + } + + // setup + var lines = []; + var data = []; + + options = { + delimiter: config.delimiter, + separator: config.separator, + onPreParse: options.onPreParse, + onParseEntry: options.onParseEntry, + onParseValue: options.onParseValue, + onPostParse: options.onPostParse, + start: options.start, + end: options.end, + state: { + rowNum: 1, + colNum: 1 + }, + match: false, + transform: options.transform + }; + + // fetch the headers + var headerOptions = { + delimiter: config.delimiter, + separator: config.separator, + start: 1, + end: 1, + state: { + rowNum:1, + colNum:1 + } + }; + + // onPreParse hook + if(options.onPreParse !== undefined) { + options.onPreParse(csv, options.state); + } + + // parse the csv + var headerLine = $.csv.parsers.splitLines(csv, headerOptions); + var headers = $.csv.toArray(headerLine[0], options); + + // fetch the data + lines = $.csv.parsers.splitLines(csv, options); + + // reset the state for re-use + options.state.colNum = 1; + if(headers){ + options.state.rowNum = 2; + } else { + options.state.rowNum = 1; + } + + // convert data to objects + for(var i=0, len=lines.length; i -1) { + strValue = strValue.replace(config.delimiter, config.delimiter + config.delimiter); + } + + var escMatcher = '\n|\r|S|D'; + escMatcher = escMatcher.replace('S', config.separator); + escMatcher = escMatcher.replace('D', config.delimiter); + + if (strValue.search(escMatcher) > -1) { + strValue = config.delimiter + strValue + config.delimiter; + } + lineValues.push(strValue); + } + output += lineValues.join(config.separator) + '\r\n'; + } + + // push the value to a callback if one is defined + if(!config.callback) { + return output; + } else { + config.callback('', output); + } + }, + + /** + * $.csv.fromObjects(objects) + * Converts a javascript dictionary to a CSV string. + * + * @param {Object} objects An array of objects containing the data. + * @param {Object} [options] An object containing user-defined options. + * @param {Character} [separator] An override for the separator character. Defaults to a comma(,). + * @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote("). + * @param {Character} [sortOrder] Sort order of columns (named after + * object properties). Use 'alpha' for alphabetic. Default is 'declare', + * which means, that properties will _probably_ appear in order they were + * declared for the object. But without any guarantee. + * @param {Character or Array} [manualOrder] Manually order columns. May be + * a strin in a same csv format as an output or an array of header names + * (array items won't be parsed). All the properties, not present in + * `manualOrder` will be appended to the end in accordance with `sortOrder` + * option. So the `manualOrder` always takes preference, if present. + * + * This method generates a CSV file from an array of objects (name:value pairs). + * It starts by detecting the headers and adding them as the first line of + * the CSV file, followed by a structured dump of the data. + */ + fromObjects: function(objects, options, callback) { + options = (options !== undefined ? options : {}); + var config = {}; + config.callback = ((callback !== undefined && typeof(callback) === 'function') ? callback : false); + config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator; + config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter; + config.headers = 'headers' in options ? options.headers : $.csv.defaults.headers; + config.sortOrder = 'sortOrder' in options ? options.sortOrder : 'declare'; + config.manualOrder = 'manualOrder' in options ? options.manualOrder : []; + config.transform = options.transform; + + if (typeof config.manualOrder === 'string') { + config.manualOrder = $.csv.toArray(config.manualOrder, config); + } + + if (config.transform !== undefined) { + var origObjects = objects; + objects = []; + + var i; + for (i = 0; i < origObjects.length; i++) { + objects.push(config.transform.call(undefined, origObjects[i])); + } + } + + var props = $.csv.helpers.collectPropertyNames(objects); + + if (config.sortOrder === 'alpha') { + props.sort(); + } // else {} - nothing to do for 'declare' order + + if (config.manualOrder.length > 0) { + + var propsManual = [].concat(config.manualOrder); + var p; + for (p = 0; p < props.length; p++) { + if (propsManual.indexOf( props[p] ) < 0) { + propsManual.push( props[p] ); + } + } + props = propsManual; + } + + var o, p, line, output = [], propName; + if (config.headers) { + output.push(props); + } + + for (o = 0; o < objects.length; o++) { + line = []; + for (p = 0; p < props.length; p++) { + propName = props[p]; + if (propName in objects[o] && typeof objects[o][propName] !== 'function') { + line.push(objects[o][propName]); + } else { + line.push(''); + } + } + output.push(line); + } + + // push the value to a callback if one is defined + return $.csv.fromArrays(output, options, config.callback); + } + }; + + // Maintenance code to maintain backward-compatibility + // Will be removed in release 1.0 + $.csvEntry2Array = $.csv.toArray; + $.csv2Array = $.csv.toArrays; + $.csv2Dictionary = $.csv.toObjects; + + // CommonJS module is defined + if (typeof module !== 'undefined' && module.exports) { + module.exports = $.csv; + } + +}).call( this ); diff --git a/csv/sample.csv b/csv/sample.csv new file mode 100644 index 0000000..5b4e04c --- /dev/null +++ b/csv/sample.csv @@ -0,0 +1,15 @@ +-28.700225, 28.602905, +-28.700225, 28.602905, ZAF +-28.433676, 19.986191, ZAF +-28.433676, 19.986191, +-28.433676, 19.986191, NAM +13.661115, 144.560790000, +-20.529975, 57.356025000, +52.383984, 4.865401375, +26.904854, 95.138497, +-28.433676, 19.986191, +-28.433676, 19.986191, +13.661115, 144.560790000, ZAF +-20.529975, 57.356025000, ZAF +52.383984, 4.865401375, ZAF +26.904854, 95.138497, ZAF From c9027bac6b6f39540ba9e4332ad1d7476433cda8 Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Mon, 6 Mar 2017 12:38:13 +0100 Subject: [PATCH 38/54] Updated CSV converter --- csv/converter.html | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/csv/converter.html b/csv/converter.html index eec48f2..48742f1 100644 --- a/csv/converter.html +++ b/csv/converter.html @@ -19,17 +19,24 @@ - Mapcode CSV Converter + Simple Mapcode CSV Converter -

Mapcode CSV Converter

+

Simple Mapcode CSV Converter

- Select a CSV file which has the following columns:
- latitude, longitude, territory (optional)

-

The context is used to specify the territory for which the shortest mapcode should be displayed. - For example, for South Africa, this would be ZAF.

-

Example of a CSF file:

+ This page allows you to upload a CSV file with coordinates and convert + them to mapcodes. The CSV file needs to have 3 columns:
+ latitude (in degrees), longitude (in degrees), territory (optional)
+ Field delimiter: , (comma)
+ Decimal point: . (dot)
+

+

+ The context is used to specify the territory for which the shortest mapcode should be displayed. + For example, for South Africa, this would be ZAF. Note that if you leave the field empty, the result might + not be what you expected. +

+

Example of a CSV file:

-28.700225, 28.602905, (note the territory is missing)
-28.700225, 28.602905, ZAF
@@ -37,6 +44,7 @@

Mapcode CSV Converter

This produces the following output:

+ latitude,longitude,mapcode,international
-28.700225,28.602905,LSO MRG.8XX,8KYVG.4C8Y
-28.700225,28.602905,ZAF QNW2.Y72,8KYVG.4C8Y
-28.433676,19.986191,ZAF 6MQP.506,8K70Z.7PB4 @@ -94,10 +102,6 @@

Mapcode CSV Converter

// read the file metadata var output = '' - output += '' + escape(file.name) + '
\n'; - output += ' - FileType: ' + (file.type || 'n/a') + '
\n'; - output += ' - FileSize: ' + file.size + ' bytes
\n'; - output += ' - LastModified: ' + (file.lastModifiedDate ? file.lastModifiedDate.toLocaleDateString() : 'n/a') + '
\n'; // read the file contents printTable(file); @@ -113,8 +117,8 @@

Mapcode CSV Converter

var csv = event.target.result; var data = $.csv.toArrays(csv); var html = ''; - var csv = ''; - html += 'latitudelongitudemapcode<international/tr>'; + var csv = 'latitude,longitude,territory,mapcode,international\r\n'; + html += 'latitudelongitudeterritorymapcodeinternational/tr>'; for (var row in data) { var lat = Number(data[row][0]); var lon = Number(data[row][1]); @@ -131,12 +135,14 @@

Mapcode CSV Converter

} if (r.length > 0) { var shortest = r[0]; - html += '' + shortest.territoryAlphaCode + ' ' + shortest.mapcode + '\r\n'; - csv += shortest.territoryAlphaCode + ' ' + shortest.mapcode + ','; + html += '' + shortest.territoryAlphaCode + '\r\n'; + html += '' + shortest.mapcode + '\r\n'; + csv += shortest.territoryAlphaCode + ',' + shortest.mapcode + ','; } else { - html += "N/A" - csv += 'N/A,'; + html += "\r\n"; + html += "\r\n"; + csv += ",,"; } var international = encodeInternational(lat, lon)[0]; html += '' + international.mapcode + '\r\n'; From a66acb15b96d8a2844fbfc7b2ce4092588cb656d Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Mon, 6 Mar 2017 12:57:40 +0100 Subject: [PATCH 39/54] Added explanatory text --- csv/{FileSave.js => FileSaver.js} | 0 csv/converter.html | 14 +++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) rename csv/{FileSave.js => FileSaver.js} (100%) diff --git a/csv/FileSave.js b/csv/FileSaver.js similarity index 100% rename from csv/FileSave.js rename to csv/FileSaver.js diff --git a/csv/converter.html b/csv/converter.html index 48742f1..2ad4d7e 100644 --- a/csv/converter.html +++ b/csv/converter.html @@ -49,7 +49,15 @@

Simple Mapcode CSV Converter

-28.700225,28.602905,ZAF QNW2.Y72,8KYVG.4C8Y
-28.433676,19.986191,ZAF 6MQP.506,8K70Z.7PB4

-

The output is automatically saved to mapcodes.csv in your Downloads folder.

+

+ In some browsers the output will automatically be saved to mapcodes.csv in your Downloads folder. + However, not all browsers support this functionality and will shows the CSV file instead on your screen. + (Note: We've tried this with Google Chrome and it seems to work fine.) +

+

+ Troubleshooting: If you select a file and nothing happens, check the format of the file. It should contain exactly + 3 columns, separated by comma's and the latitude/longitudes must use decimal points. +

@@ -63,7 +71,7 @@

Simple Mapcode CSV Converter

- +