diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 7465856..970bf14 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -14,4 +14,5 @@ //= require jquery_ujs //= require turbolinks //= require bootstrap-sprockets +//= require typeahead.bundle //= require_tree . diff --git a/app/assets/stylesheets/application.sass b/app/assets/stylesheets/application.sass index 449637b..d9bc28b 100644 --- a/app/assets/stylesheets/application.sass +++ b/app/assets/stylesheets/application.sass @@ -15,6 +15,7 @@ */ @import "bootstrap-sprockets" @import "bootstrap" +@import "typeaheadjs" body padding-top: 20px diff --git a/app/controllers/cities_autocomplete_controller.rb b/app/controllers/cities_autocomplete_controller.rb new file mode 100644 index 0000000..8b90e43 --- /dev/null +++ b/app/controllers/cities_autocomplete_controller.rb @@ -0,0 +1,13 @@ +require 'CSV' +class CitiesAutocompleteController < ApplicationController + skip_before_action :verify_authenticity_token + + def index + @cities = CSV.read Rails.root.join('db', 'plz_ch.csv') + + @cities = @cities.select { |city| city.first =~ /#{params[:query]}/i || city.last =~ /#{params[:query]}/i } + @cities = @cities.map { |city| { plz: city.first, city: city.last } } + + render json: @cities.uniq + end +end diff --git a/app/views/layouts/application.html.slim b/app/views/layouts/application.html.slim index a049302..f223eb2 100644 --- a/app/views/layouts/application.html.slim +++ b/app/views/layouts/application.html.slim @@ -5,7 +5,7 @@ html = javascript_include_tag 'application', 'data-turbolinks-track' => true = csrf_meta_tags body - = console if Rails.env.development? + / = console if Rails.env.development? .container = render 'shared/flashes' = yield diff --git a/app/views/supporters/_form.slim b/app/views/supporters/_form.slim index 901e626..37d4383 100644 --- a/app/views/supporters/_form.slim +++ b/app/views/supporters/_form.slim @@ -9,3 +9,33 @@ h1 = title t('.title_html') = f.input :support, as: :radio_buttons, collection: t('support_type'), label_method: :last, value_method: :first = f.input :age_category, as: :radio_buttons, collection: t('age_category'), label_method: :last, value_method: :first = f.submit value: t('.submit'), class: 'btn btn-success' + +javascript: + var cities = new Bloodhound({ + datumTokenizer: Bloodhound.tokenizers.whitespace, + queryTokenizer: Bloodhound.tokenizers.whitespace, + remote: { + url: '/cities_autocomplete.json?query=%QUERY', + wildcard: '%QUERY', + } + }); + + $('#supporter_city').typeahead({ + minLength: 2, + highlight: true, + },{ + display: 'city', + source: cities + }).on('typeahead:selected', function(event, datum) { + $("#supporter_zip").val(datum.plz); + }); + + $('#supporter_zip').typeahead({ + minLength: 2, + highlight: true, + },{ + display: 'plz', + source: cities + }).on('typeahead:selected', function(event, datum) { + $("#supporter_city").val(datum.city); + }); diff --git a/db/plz_ch.csv b/db/plz_ch.csv new file mode 100644 index 0000000..e453a6b --- /dev/null +++ b/db/plz_ch.csv @@ -0,0 +1,6051 @@ +zip, city +8355,Aadorf +5000,Aarau +3270,Aarberg +4663,Aarburg +4912,Aarwangen +8607,Aathal-Seegräben +8522,Aawangen +1657,Abländschen +9030,Abtwil SG +5646,Abtwil AG +3725,Achseten +7185,Platta +7104,Versam +1123,Aclens +6718,Olivone +6716,Acquarossa +3715,Adelboden +4806,Wikon +8345,Adetswil +6043,Adligenswil +8452,Adlikon +8106,Adlikon b.Regensdf +8134,Adliswil +3673,Linden +4714,Aedermannsdorf +3426,Aefligen +2558,Aegerten +3147,Mittelhäusern +6287,Aesch LU +4147,Aesch BL +8904,Aesch ZH +8127,Forch +8412,Aesch (Neftenbach) +3536,Aeschau +4556,Aeschi SO +3703,Aeschi b. Spiez +3703,Aeschiried +3672,Aeschlen +3656,Aeschlen ob Gunten +4583,Aetigkofen +4587,Aetingen +5645,Aettenschwil +8914,Aeugst am Albis +8914,Aeugstertal +9466,Sennwald +7250,Klosters +7133,Obersaxen Affeier +9556,Affeltrangen +8910,Affoltern am Albis +8000,Zürich +3416,Affoltern BE +3951,Agarn +6597,Agarone +8308,Agasul +4923,Wynau +1352,Agiez +6982,Agno +6933,Muzzano +6927,Agra +3216,Agriswil +1860,Aigle +1219,Aïre +1288,Aire-la-Ville +6780,Airolo +3930,Visp +6248,Alberswil +1669,Albeuve +3955,Albinen +8135,Langnau am Albis +8915,Hausen am Albis +8000,Zürich +3183,Albligen +6962,Viganello +6958,Corticiasca +3422,Alchenflüh +3473,Alchenstorf +6974,Aldesago +2512,Tüscherz-Alfermée +9249,Algetshausen +5643,Alikon +6781,Bedretto +1165,Allaman +2942,Alle +3205,Gümmenen +1304,Allens +3054,Schüpfen +6319,Allenwinden +4615,Allerheiligenberg +1905,Dorénaz +1669,Montbovon +5706,Boniswil +3600,Thun +3112,Allmendingen b. BE +9428,Walzenhausen +4123,Allschwil +6372,Ennetmoos +7416,Almens +6315,Alosen +7710,Alp Grüm +6055,Alpnach Dorf +6053,Alpnachstad +8849,Alpthal +9656,Alt St. Johann +6776,Piotta +3280,Murten +8164,Bachs +6147,Altbüron +6460,Altdorf UR +6460,Altdorf UR +8243,Altdorf SH +8453,Alten +5210,Windisch +8852,Altendorf +9470,Buchs SG +8560,Märstetten +9423,Altenrhein +1715,Alterswil FR +9230,Flawil +8573,Alterswilen +5628,Aristau +8479,Altikon +8573,Altishausen +6246,Altishofen +8595,Altnau +2545,Selzach +5225,Bözberg +9450,Altstätten SG +8000,Zürich +6286,Altwis +7473,Alvaneu Bad +7492,Alvaneu Dorf +7451,Alvaschein +7447,Am Bach (Avers) +6775,Ambrì +8873,Amden +8133,Esslingen +3963,Aminona +8514,Amlikon-Bissegg +4573,Lohn-Ammannsegg +8506,Lanzenneunforn +5600,Ammerswil AG +3257,Ammerzwil BE +8580,Amriswil +3633,Amsoldingen +6474,Amsteg +7440,Andeer +8450,Andelfingen +6490,Andermatt +8572,Andhausen +7159,Andiast +9204,Andwil SG +9204,Andwil SG +8586,Andwil TG +9545,Wängi +4147,Aesch BL +5611,Anglikon +1247,Anières +7745,Li Curt +1867,Ollon VD +4469,Anwil +1882,Gryon +1972,Anzère +6748,Anzonico +9050,Appenzell +9050,Appenzell +9050,Appenzell +1143,Apples +1994,Aproz (Nendaz) +1994,Aproz (Nendaz) +6719,Aquila +1091,Aran +6994,Aranno +1212,Grand-Lancy +7062,Passugg-Araschgen +6340,Baar +1974,Arbaz +6517,Arbedo +4424,Arboldswil +9320,Arbon +6618,Arcegno +3296,Arch +1732,Arconciel +7546,Ardez +1957,Ardon +8268,Mannenbach-Salenst +2015,Areuse +7104,Arezen +1966,Argnou (Ayent) +4422,Arisdorf +5628,Aristau +4144,Arlesheim +8810,Horgen +9212,Arnegg +1277,Arnex-sur-Nyon +1321,Arnex-sur-Orbe +3508,Arni BE +8905,Arni AG +3508,Arni BE +6822,Arogno +1986,Arolla +7050,Arosa +6939,Arosio +1463,Rovray +1680,Romont FR +6415,Arth +6500,Bellinzona +1884,Arveyes +6543,Arvigo +1991,Arvillard (Salins) +1273,Arzier +6864,Arzo +7245,Ascharina +6612,Ascona +5025,Asp +1042,Assens +8572,Berg TG +6999,Astano +2954,Asuel +1285,Athenaz (Avusy) +1616,Attalens +5056,Attelwil +8544,Attikon +6468,Attinghausen +4533,Riedholz +4536,Attiswil +8804,Au ZH +9434,Au SG +5105,Auenstein +5105,Auenstein +8376,Au TG +1170,Aubonne +1673,Auboranges +1914,Auddes-sur-Riddes +5105,Auenstein +6547,Augio +4302,Augst BL +8426,Lufingen +1867,Ollon VD +1484,Aumont +6661,Auressio +6677,Aurigeno +8331,Auslikon +1891,Vérossaz +3938,Ausserberg +3995,Ausserbinn +8474,Dinhard +3619,Eriz +7444,Ausserferrera +8000,Zürich +4944,Auswil +1782,Autafond +1475,Autavaux +1742,Autigny +2012,Auvernier +5644,Auw +6670,Avegno +1976,Aven +1580,Avenches +1274,Signy +7447,Cresta (Avers) +1644,Avry-devant-Pont +1754,Avry-sur-Matran +1237,Avully +1285,Athenaz (Avusy) +3855,Axalp +3961,Ayer +9478,Azmoos +6340,Baar +1996,Baar (Nendaz) +8806,Bäch SZ +8806,Bäch SZ +8184,Bachenbülach +9452,Hinterforst +4000,Basel +9633,Bächli (Hemberg) +8164,Bachs +8342,Wernetshausen +6213,Knutwil +6213,Knutwil +7310,Bad Ragaz +5330,Bad Zurzach +5400,Baden +3267,Seedorf BE +1934,Le Châble VS +6283,Baldegg +5333,Baldingen +7317,Valens +6828,Balerna +9436,Balgach +1338,Ballaigues +1144,Ballens +3303,Ballmoos +6275,Ballwil +4525,Balm b. Günsberg +3860,Meiringen +3254,Balm b. Messen +4524,Balmberg +4710,Balsthal +8962,Bergdietikon +8303,Bassersdorf +8362,Balterswil +3937,Baltschieder +4856,Glashütten +6981,Banco +3256,Bangerten +3076,Worb +3076,Worb +8426,Lufingen +8514,Amlikon-Bissegg +8471,Bänk (Dägerlen) +4913,Bannwil +3065,Bolligen +3552,Bärau +6917,Barbengo +6917,Barbengo +1783,Barberêche +1257,La Croix-de-Rozon +8344,Bäretswil +3204,Rosshäusern +3204,Rosshäusern +3282,Bargen BE +8233,Bargen SH +3323,Bäriswil BE +5017,Barmelweid +4252,Bärschwil +4252,Bärschwil +8241,Barzheim +8254,Basadingen +4000,Basel +2854,Bassecourt +1996,Basse-Nendaz +8303,Bassersdorf +1269,Bassins +1786,Sugiez +8573,Siegershausen +3315,Bätterkinden +4112,Bättwil +6466,Bauen +1815,Clarens +1446,Baulmes +8494,Bauma +1372,Bavois +9602,Bazenheid +3803,Beatenberg +3658,Merligen +8414,Buch am Irchel +6375,Beckenried +6930,Bedano +6981,Bedigliora +6781,Bedretto +8228,Beggingen +1268,Begnins +4229,Beinwil SO +5637,Beinwil (Freiamt) +5712,Beinwil am See +3113,Rubigen +3914,Belalp +1782,Belfaux +2354,Goumois +4512,Bellach +1786,Sugiez +2713,Bellelay +1585,Bellerive VD +1222,Vésenaz +2805,Soyhières +2805,Soyhières +1293,Bellevue +5454,Bellikon +6500,Bellinzona +2564,Bellmund +3997,Bellwald +1092,Belmont-Lausanne +1432,Belmont-Yverdon +3123,Belp +3124,Belpberg +2744,Belprahon +2406,Le Brouillet +9042,Speicher +8802,Kilchberg ZH +1197,Prangins +8121,Benglen +8463,Benken ZH +4105,Biel-Benken BL +8717,Benken SG +8836,Bennau +4431,Bennwil +5636,Benzenschwil +1038,Bercher +8625,Gossau ZH +8471,Berg (Dägerlen) +9305,Berg SG +8572,Berg TG +8415,Berg am Irchel +8962,Bergdietikon +7482,Bergün/Bravuogn +6981,Biogno-Beride +8965,Berikon +8222,Beringen +3900,Brig +3376,Berken +1680,Berlens +2854,Bassecourt +8267,Berlingen +3000,Bern +5325,Leibstadt +9442,Berneck +9442,Berneck +1233,Bernex +9304,Bernhardzell +7504,Pontresina +8280,Kreuzlingen +1149,Berolle +6215,Beromünster +8892,Berschis +8614,Bertschikon Gossau +8543,Bertschikon +6661,Berzona +6863,Besazio +5627,Besenbüren +1609,Besencens +8546,Islikon +3000,Bern +8872,Weesen +8777,Betschwanden +3991,Betten +3366,Bettenhausen +1042,Bettens +4126,Bettingen +2544,Bettlach +3992,Bettmeralp +9553,Bettwiesen +5618,Bettwil +2935,Beurnevésin +1996,Beuson (Nendaz) +2022,Bevaix +7502,Bever +2735,Bévilard +8543,Bertschikon +1880,Bex +8735,St. Gallenkappel +5312,Döttingen +6710,Biasca +6710,Biasca +2336,Les Bois +8836,Bennau +8836,Bennau +3206,Biberen +4562,Biberist +8262,Ramsen +4578,Bibern SO +8242,Bibern SH +5023,Biberstein +8363,Bichelsee +9248,Bichwil +3472,Wynigen +8912,Obfelden +6958,Bidogno +4105,Biel-Benken BL +3989,Biel VS +2500,Biel/Bienne +3419,Biembach +4410,Liestal +1145,Bière +8580,Biessenhofen +8307,Effretikon +1996,Bieudron (Nendaz) +4585,Biezwil +3513,Bigenthal +3507,Biglen +6676,Bignasco +6927,Agra +6954,Bigorio +1681,Billens +8314,Kyburg +8865,Bilten +3996,Binn +4102,Binningen +8122,Binz +8627,Grüningen +6934,Bioggio +6981,Biogno-Beride +6932,Breganzona +1407,Bioley-Magnoux +1042,Bioley-Orjulaz +1670,Bionnens +8309,Nürensdorf +3903,Birgisch +8903,Birmensdorf ZH +5413,Birmenstorf AG +6804,Bironico +5242,Birr +5244,Birrhard +5628,Aristau +5708,Birrwil +4127,Birsfelden +4127,Birsfelden +8585,Birwinken +9220,Bischofszell +8307,Effretikon +6436,Bisisthal +8514,Amlikon-Bissegg +6816,Bissone +3983,Bister +3982,Bitsch +3255,Rapperswil BE +7457,Bivio +3771,Blankenburg +3537,Eggiwil +3919,Blatten(Lötschen) +6102,Malters +3914,Blatten b. Naters +4223,Blauen +3717,Blausee-Mitholz +4562,Biberist +3368,Bleienbach +8583,Sulgen +3674,Bleiken +1675,Blessens +6340,Baar +9220,Bischofszell +8494,Bauma +1966,Blignou (Ayent) +8493,Saland +3989,Blitzingen +1807,Blonay +3975,Randogne +3638,Blumenstein +5334,Böbikon +4461,Böckten +3715,Adelboden +6743,Bodio TI +2856,Boécourt +1353,Bofflens +1279,Bogis-Bossey +6216,Mauensee +6951,Bogno +6221,Rickenbach LU +6221,Rickenbach LU +1260,Nyon +2014,Bôle +4556,Bolken +3067,Boll +5610,Wohlen AG +3065,Bolligen +8715,Bollingen +1470,Bollion +3366,Bollodingen +3766,Boltigen +8561,Ottoberg +6981,Bombinasco +7402,Bonaduz +8554,Bonau +2926,Boncourt +7606,Promontogno +2944,Bonfol +3806,Bönigen +4618,Boningen +5706,Boniswil +1724,Bonnefontaine +8906,Bonstetten +1427,Bonvillars +8113,Boppelsen +1277,Borex +6658,Borgnone +7604,Borgonovo +8264,Eschenz +7545,Guarda +6852,Genestrerio +6935,Bosco Luganese +6685,Bosco/Gurin +3178,Bösingen +1615,Bossonnens +1239,Collex +5623,Boswil +9230,Flawil +1041,Bottens +4814,Bottenwil +1652,Botterens +8598,Bottighofen +4103,Bottmingen +5315,Böttstein +1966,Botyre (Ayent) +2043,Boudevilliers +2017,Boudry +1172,Bougy-Villars +1063,Boulens +1699,Bouloz +1242,Satigny +1946,Bourg-St-Pierre +1722,Bourguillon +1035,Bournens +2803,Bourrignon +1034,Boussens +1897,Bouveret +2113,Boveresse +1932,Bovernier +3533,Bowil +5076,Bözen +2500,Biel/Bienne +6544,Braggio +7527,Brail +3176,Neuenegg +6167,Bramboden +1967,Bramois +1944,La Fouly VS +1944,La Fouly VS +1926,Fully +3957,Bratsch +9502,Braunau +8784,Braunwald +6979,Brè sopra Lugano +6932,Breganzona +7165,Breil/Brigels +1783,Pensier +8309,Nürensdorf +4000,Basel +6130,Willisau +3983,Mörel +4226,Breitenbach +3474,Rüedisbach +9214,Kradolf +3000,Bern +8492,Wila +1121,Bremblens +5620,Bremgarten AG +3047,Bremgarten b. Bern +9426,Lutzenberg +1683,Brenles +6937,Breno +1817,Brent +3671,Brenzikofen +2904,Bressaucourt +1510,Moudon +1510,Moudon +1510,Moudon +1884,Villars-sur-Ollon +1053,Bretigny-Morrens +1329,Bretonnières +4207,Bretzwil +3951,Agarn +3966,Chalais +6672,Gordevio +3855,Brienz BE +7084,Brienz/Brinzauls +3856,Brienzwiler +3900,Brig +3900,Brigerbad +1996,Brignon (Nendaz) +6634,Brione (Verzasca) +6645,Brione s. Minusio +6645,Brione s. Minusio +6144,Zell LU +4225,Brislach +6614,Brissago +6475,Bristen +4588,Brittern +4805,Brittnau +1636,Broc +1636,Broc +3752,Wimmis +6693,Broglio +9552,Bronschhofen +6692,Brontallo +2149,Brot-Dessous +2318,Brot-Plamboz +2318,Brot-Plamboz +4000,Basel +4101,Bruderholz +4101,Bruderholz +5200,Brugg AG +2555,Brügg BE +3176,Neuenegg +9000,St. Gallen +4582,Brügglen +9058,Brülisau +9058,Brülisau +7122,Valendas +5505,Brunegg +8483,Kollbrunn +3860,Brünig +3860,Meiringen +1719,Brünisried +9125,Brunnadern +6440,Brunnen +3307,Brunnenthal +4717,Mümliswil +4717,Mümliswil +5637,Beinwil (Freiamt) +6883,Novazzano +8580,Amriswil +6827,Brusino Arsizio +7743,Brusio +1934,Bruson +3237,Brüttelen +8311,Brütten +8306,Brüttisellen +6837,Bruzella +4416,Bubendorf +8608,Bubikon +5512,Wohlenschwil +8263,Buch SH +8414,Buch am Irchel +8524,Buch b. Frauenfeld +8586,Buch b. Kümmertshs +9562,Buch b. Märwil +3205,Gümmenen +8586,Buchackern +8454,Buchberg +4586,Kyburg-Buchegg +9464,Rüthi (Rheintal) +3623,Buchen BE +7223,Buchen +8143,Stallikon +3615,Heimenschwand +3600,Thun +1164,Buchillon +6033,Buchrain +8107,Buchs ZH +6211,Buchs LU +9470,Buchs SG +5033,Buchs AG +3215,Büchslen +8203,Schaffhausen +4446,Buckten +9422,Staad SG +5622,Waltenschwil +3263,Büetigen +1180,Rolle +8500,Frauenfeld +3274,Bühl BE +9055,Bühler +9215,Buhwil +2925,Buix +8180,Bülach +1630,Bulle +1453,Bullet +6197,Schangnau +3000,Bern +3054,Schüpfen +3186,Düdingen +9630,Wattwil +5624,Bünzen +6374,Buochs +6343,Buonas +3935,Bürchen +2915,Bure +4413,Büren SO +5272,Gansingen +8558,Raperswilen +3294,Büren an der Aare +6382,Büren NW +3313,Büren zum Hof +2603,Péry +5736,Burg AG +8570,Weinfelden +8732,Neuhaus SG +3280,Murten +4117,Burg im Leimental +4556,Burgäschi +9230,Flawil +3400,Burgdorf +6363,Bürgenstock +6363,Bürgenstock +9470,Buchs SG +8805,Richterswil +3664,Burgistein +3664,Burgistein +3664,Burgistein +3816,Burglauenen +6463,Bürglen UR +6078,Bürglen OW +8575,Bürglen TG +1814,La Tour-de-Peilz +9425,Thal +9442,Büriswilen +6233,Büron +1195,Bursinel +1183,Bursins +1268,Burtigny +5522,Tägerig +5522,Tägerig +6542,Buseno +8330,Pfäffikon ZH +4227,Büsserach +1030,Bussigny-Lausanne +1608,Bussigny-sur-Oron +5453,Remetschwil +9565,Bussnang +8371,Busswil TG +3292,Busswil BE +3414,Oberburg +4917,Busswil b.Melchnau +1541,Bussy FR +1136,Bussy-Chardonney +1514,Bussy-sur-Moudon +3422,Kirchberg BE +9606,Bütschwil +8236,Büttenhardt +3203,Mühleberg +2115,Buttes +8863,Buttikon SZ +5619,Büttikon AG +6018,Buttisholz +5632,Buttwil +5085,Sulz AG +4922,Bützberg +4463,Buus +6838,Cabbio +6558,Lostallo +6658,Borgnone +6936,Cademario +6814,Cadempino +6593,Cadenazzo +6917,Barbengo +6965,Cadro +6955,Cagiallo +6655,Intragna +7027,Calfreisen +6746,Calonico +6760,Calpiogna +6900,Lugano +6557,Cama +7107,Safien Platz +6659,Camedo +6803,Camignolo +7187,Camischolas +6528,Camorino +7748,Campascio +6760,Campello +6718,Camperio +6950,Tesserete +7166,Trun +6720,Campo (Blenio) +6684,Campo (VM) +7744,Campocologno +6875,Campora +6718,Olivone +7446,Campsut-Cröt +7113,Camuns +6837,Caneggio +6952,Canobbio +7077,Valbella +6802,Rivera +6825,Capolago +6823,Pugerna +1243,Presinge +6913,Carabbia +6919,Carabietta +6500,Bellinzona +6600,Locarno +6584,Carena +6760,Carì +1565,Missy +6583,S. Antonio +6914,Carona +1227,Carouge GE +7122,Carrera +1084,Carrouge VD +1236,Cartigny +7602,Casaccia +6883,Novazzano +6875,Casima +6987,Caslano +6900,Lugano +6702,Claro +6990,Cassina d'Agno +6976,Castagnola +6540,Castaneda +7608,Castasegna +6874,Castel San Pietro +6980,Castelrotto +7433,Donat +7027,Castiel +6532,Castione +7126,Castrisch +6723,Castro +6777,Quinto +6546,Cauco +1824,Caux +7742,Poschiavo +6749,Cavagnago +7748,Campascio +6823,Pugerna +7182,Cavardiras +6690,Cavergno +6578,Caviano +6654,Cavigliano +7408,Cazis +7505,Celerina +1298,Céligny +6683,Cerentino +1863,Le Sépey +2336,Les Bois +1654,Cerniat FR +1682,Cerniaz VD +2053,Cernier +6959,Certara +6926,Montagnola +1258,Perly +6675,Cevio +1474,Châbles FR +1589,Chabrey +1000,Lausanne +1816,Chailly-Montreux +2732,Reconvilier +3966,Chalais +6330,Cham +1292,Chambésy +1763,Granges-Paccot +1763,Granges-Paccot +1436,Chamblon +2019,Chambrelien +2019,Chambrelien +1832,Chamby +1933,Chamoille +1937,Orsières +1955,Chamoson +1424,Champagne +2149,Champ-du-Moulin +2149,Champ-du-Moulin +1874,Champéry +1938,Champex-Lac +7512,Champfèr +7512,Champfèr +1971,Champlan +1588,Cudrefin +1873,Champoussin +2735,Champoz +1947,Champsec +1537,Champtauroz +1443,Champvent +3976,Noës +3976,Champzabé +7522,La Punt-Chamues-ch +1284,Chancy +3961,Chandolin +1965,Chandolin Savièse +1773,Chandon +1945,Chandonne (Liddes) +1583,Villarepos +1409,Chanéaz +7526,Cinuos-chel +1534,Chapelle (Broye) +1608,Chapelle (Glâne) +1063,Chapelle-s-Moudon +9032,Engelburg +4153,Reinach BL +1803,Chardonne +1041,Montaubion-Chardon +1637,Charmey (Gruyère) +2947,Charmoille +1906,Charrat +1257,La Croix-de-Rozon +2518,Nods +1452,Les Rasses +1297,Founex +1926,Fully +1660,Château-d'Oex +1950,Sion +1219,Châtelaine +1095,Lutry +2715,Châtelat +1618,Châtel-St-Denis +1653,Châtel-Montsalvens +1186,Essertines-Rolle +1610,Châtillens +1473,Châtillon FR +2843,Châtillon JU +1553,Châtonnaye +2067,Chaumont +2067,Chaumont +1279,Chavannes-de-Bogis +1290,Chavannes-des-Bois +1464,Chavannes-le-Chêne +1676,Chavannes-Forts +1148,Chavannes-Veyron +1022,Chavannes-Renens +1694,Chavannes-Orsonnen +1512,Chavannes-s-Moudon +1373,Chavornay +1529,Cheiry +3978,Flanthey +1872,Troistorrents +1927,Chemin +1927,Chemin +1091,Chenaux +1224,Chêne-Bougeries +1225,Chêne-Bourg +1744,Chénens +1464,Chêne-Pâquier +3971,Chermignon +3971,Chermignon-Bas +3971,Chermignon +1822,Chernex +2885,Epauvillers +1683,Chesalles-Moudon +1608,Chesalles-sur-Oron +1400,Cheseaux-Noréaz +1033,Cheseaux-Lausanne +1275,Chéserex +1885,Chesières +1720,Chésopelloz +1846,Chessel +2906,Chevenez +1316,Chevilly +1247,Anières +1233,Bernex +1244,Choulex +1545,Chevroux +1071,Chexbres +1071,Chexbres +1468,Cheyres +1347,Le Sentier +1945,Chez Petit(Liddes) +2054,Chézard-St-Martin +2883,Montmelon +2025,Chez-le-Bart +1937,Orsières +1937,Orsières +1348,Le Brassus +6830,Chiasso +6713,Malvaglia +6764,Chiggiogna +1134,Chigny +8912,Obfelden +3965,Chippis +8512,Thundorf +6747,Chironico +1871,Choëx +2830,Courrendlin +1253,Vandoeuvres +1244,Choulex +1242,Satigny +3453,Heimisbach +3538,Röthenbach i. E. +7000,Chur +7075,Churwalden +6959,Cimadera +6684,Cimalmotto +6992,Cimo +7526,Cinuos-chel +4000,Basel +1815,Clarens +1127,Clarmont +6702,Claro +7272,Davos Clavadel +1595,Clavaleyres +1993,Clèbes (Nendaz) +2057,Villiers +7442,Clugin +2932,Coeuve +2207,Coffrane +6678,Coglio +1267,Coinsins +1216,Cointrin +1216,Cointrin +1927,Chemin +6877,Coldrerio +1865,Les Diablerets +6951,Colla +1239,Collex +6683,Cerentino +1868,Collombey +1868,Collombey +1245,Collonge-Bellerive +1903,Collonges +7742,Poschiavo +1223,Cologny +1114,Colombier VD +2013,Colombier NE +6949,Comano +1535,Combremont-Grand +1536,Combremont-Petit +1937,Orsières +1291,Commugny +6663,Comologno +7562,Samnaun-Compatsch +6716,Acquarossa +1231,Conches +1231,Conches +1426,Concise +1996,Condémines (Nendaz +6954,Sala Capriasca +1232,Confignon +1587,Constantine +7241,Conters +1964,Conthey +6594,Contone +6646,Contra +3974,Mollens VS +1296,Coppet +2826,Corban +6663,Comologno +1856,Corbeyrier +1647,Corbières +6655,Intragna +1422,Grandson +2747,Corcelles BE +1616,Attalens +2035,Corcelles NE +1082,Corcelles-le-Jorat +1426,Corcelles-Concise +1562,Corcelles-Payerne +1374,Corcelles-Chavorn +1792,Cordast +3972,Miège +2606,Corgémont +3960,Corin-de-la-Crête +6631,Corippo +1754,Corjolens +1782,Cormagens +1752,Villars-sur-Glâne +1721,Cormérod +1720,Corminboeuf +2036,Cormondrèche +2612,Cormoret +2087,Cornaux NE +1072,Forel (Lavaux) +2952,Cornol +1727,Corpataux-Magneden +1410,St-Cierges +1410,Correvon +1772,Grolley +1802,Corseaux +1747,Corserey +1246,Corsier GE +1804,Corsier-sur-Vevey +1252,Meinier +1095,Lutry +2016,Cortaillod +2607,Cortébert +6873,Corteglia +6958,Corticiasca +6924,Sorengo +6722,Corzoneso +1305,Penthalaz +1304,Cossonay-Ville +1741,Cottens FR +1116,Cottens VD +1585,Cotterd +1934,Le Châble VS +1529,Cheiry +2823,Courcelon +2825,Courchapoix +2922,Courchavon +2853,Courfaivre +2950,Courgenay +1796,Courgevaux +1795,Courlevon +1721,Cournillens +2830,Courrendlin +2822,Courroux +2738,Court +1791,Courtaman +2905,Courtedoux +2608,Courtelary +2923,Courtemaîche +2950,Courtemautruy +1784,Courtepin +2852,Courtételle +1721,Courtion +1774,Cousset +1795,Courlevon +2108,Couvet +6951,Cozzo +6611,Crana +3963,Crans-Montana +3963,Crans-Montana +1299,Crans-près-Céligny +3963,Crans-Montana +3963,Crans-Montana +1263,Crassier +7505,Celerina +1845,Noville +1071,Chexbres +1526,Cremin +2746,Crémines +6705,Cresciano +1785,Cressier FR +2088,Cressier NE +7447,Cresta (Avers) +1653,Crésuz +1992,Crête-à-l'Oeil +2108,Couvet +1941,Cries (Vollèges) +1023,Crissier +6980,Castelrotto +1406,Cronay +7446,Campsut-Cröt +1322,Croy +7554,Crusch +1148,Cuarnens +1404,Cuarny +1588,Cudrefin +6516,Cugnasco +6516,Cugnasco +1482,Cugy FR +1053,Cugy VD +1096,Cully +7142,Cumbel +6722,Corzoneso +7176,Cumpadials +7452,Cunter +7184,Curaglia +6963,Cureggia +6944,Cureglia +6986,Curio +1521,Curtilles +6959,Curtina +1782,Belfaux +8932,Mettmenstetten +8447,Dachsen +8165,Schleinikon +8471,Dägerlen +6252,Dagmersellen +1306,Daillens +1976,Daillon +6126,Daiwil +7240,Küblis +7424,Dalin +6383,Dallenwil +8108,Dällikon +6774,Dalpe +3268,Lobsigen +2933,Damphreux +2914,Damvant +6717,Dangio-Torre +4658,Däniken SO +8114,Dänikon ZH +7163,Danis +1283,Dardagny +7164,Dardin +3707,Därligen +3973,Venthône +3973,Venthône +6500,Bellinzona +3763,Därstetten +7166,Trun +8421,Dättlikon +8400,Winterthur +5405,Dättwil AG +8452,Adlikon +6964,Davesco-Soragno +1891,Vérossaz +7260,Davos Dorf +7270,Davos Platz +7145,Degen +5426,Lengnau AG +9113,Degersheim +6777,Quinto +3993,Grengiols +3053,Deisswil Mbuchsee +3066,Stettlen +3066,Stettlen +4543,Deitingen +2800,Delémont +1567,Delley +1415,Démoret +1135,Denens +1410,Denezy +1026,Denges +5026,Densbüren +3076,Worb +1976,Erde +4552,Derendingen +3036,Detligen +4537,Wiedlisbach +8484,Neschwil +8574,Dettighofen Lengw. +8505,Dettighofen +2802,Develier +8354,Hofstetten ZH +9115,Dicken +6074,Giswil +4457,Diegten +8157,Dielsdorf +8733,Eschenbach SG +3053,Diemerswil +3754,Diemtigen +4442,Diepflingen +9444,Diepoldsau +6036,Dierikon +8777,Diesbach GL +3264,Diessbach b. Büren +2517,Diesse +8253,Diessenhofen +9526,Zuckenriet +3256,Dieterswil +9615,Dietfurt +8953,Dietikon +8524,Uesslingen +3184,Wünnewil +4448,Läufelfingen +8305,Dietlikon +6000,Luzern +9533,Dietschwil +6042,Dietwil +8637,Laupen ZH +7014,Trin +8500,Frauenfeld +8474,Dinhard +6967,Dino +5606,Dintikon +3963,Montana +1965,Diolly (Savièse) +8573,Siegershausen +7260,Davos Dorf +7180,Disentis/Mustér +7180,Disentis/Mustér +4243,Dittingen +1304,Dizy +7013,Domat/Ems +2056,Dombresson +1564,Domdidier +1041,Dommartin +1563,Dompierre FR +1682,Dompierre VD +7433,Donat +1580,Donatyre +6715,Dongio +1407,Donneloye +8583,Donzhausen +6112,Doppleschwand +1905,Dorénaz +8458,Dorf +8942,Oberrieden +8239,Dörflingen +4143,Dornach +4147,Aesch BL +8777,Diesbach GL +8566,Dotnacht +6718,Olivone +5605,Dottikon +5605,Dottikon +5312,Döttingen +3293,Dotzigen +8582,Dozwil +1945,Dranse (Liddes) +9612,Dreien +1680,Romont FR +1965,Drône (Savièse) +6809,Medeglia +8600,Dübendorf +3186,Düdingen +4202,Duggingen +1912,Dugny (Leytron) +1266,Duillier +4657,Dulliken +1195,Dully +8585,Langrickenbach +6702,Claro +8635,Dürnten +5724,Dürrenäsch +3600,Thun +3465,Dürrenroth +8335,Hittnau +8374,Dussnang +7112,Duvin +1236,Cartigny +1236,Cartigny +6245,Ebersecken +6276,Hohenrain +9122,Ebersol +9220,Bischofszell +8925,Ebertswil +6030,Ebikon +3855,Brienz BE +8123,Ebmatingen +9642,Ebnat-Kappel +6163,Ebnet +1040,Echallens +1026,Echandens +1646,Echarlens +1112,Echichens +1376,Eclagnens +1312,Eclépens +1908,Riddes +1612,Ecoteaux +1673,Ecublens FR +1024,Ecublens VD +1730,Ecuvillens +2813,Ederswiler +6073,Flüeli-Ranft +6313,Edlibach +5078,Effingen +8307,Effretikon +5225,Bözberg +4622,Egerkingen +8847,Egg SZ +9231,Egg (Flawil) +8132,Egg b. Zürich +7133,Obersaxen Affeier +3991,Betten +5445,Eggenwil +3939,Eggerberg +9034,Eggersriet +9050,Appenzell Eggerst. +8585,Langrickenbach +8523,Hagenbuch ZH +3537,Eggiwil +8193,Eglisau +5704,Egliswil +9322,Egnach +6243,Egolzwil +7104,Versam +8489,Wildberg +6205,Eich +4658,Däniken SO +9453,Eichberg +3254,Messen +3254,Messen +8400,Winterthur +5314,Kleindöttingen +6013,Eigenthal +3823,Eigergletscher +5074,Eiken +3646,Einigen +8840,Einsiedeln +3943,Eischoll +1969,Eison (St.Martin) +3922,Eisten +3919,Blatten(Lötschen) +5077,Elfingen +8353,Elgg +8566,Ellighausen +8464,Ellikon am Rhein +8548,Ellikon a d Thur +8767,Elm +8352,Elsau +3184,Wünnewil +3926,Embd +8424,Embrach +8424,Embrach +3711,Emdthal +6032,Emmen +6020,Emmenbrücke +3543,Emmenmatt +6020,Emmenbrücke +6376,Emmetten +8280,Kreuzlingen +8181,Höri +5304,Endingen +3655,Sigriswil +8000,Zürich +6390,Engelberg +5746,Walterswil SO +9032,Engelburg +8566,Dotnacht +2073,Enges +9050,Appenzell Enggenh. +3077,Enggistein +8765,Engi +4208,Nunningen +8586,Engishofen +3086,Englisberg +2063,Engollon +8556,Engwang +8564,Engwilen +8755,Ennenda +8586,Ennetaach +5408,Ennetbaden +9651,Ennetbühl +8755,Ennenda +6373,Ennetbürgen +8756,Mitlödi +6372,Ennetmoos +5300,Turgi +1667,Enney +6162,Entlebuch +2400,Le Locle +2829,Vermes +1323,Romainmôtier +2074,Marin-Epagnier +1663,Epagny +1066,Epalinges +1417,Epautheyres +2885,Epauvillers +1731,Ependes FR +1434,Ependes VD +1098,Epesses +1890,St-Maurice +2886,Epiquerez +5012,Eppenberg +8586,Erlen +3272,Epsach +4458,Eptingen +1976,Erde +3979,Grône +9315,Neukirch (Egnach) +3947,Ergisch +4952,Eriswil +3619,Eriz +3235,Erlach +8586,Erlen +8703,Erlenbach ZH +3762,Erlenbach i. S. +5018,Erlinsbach +5015,Erlinsbach SO +8340,Hinwil +8272,Ermatingen +6294,Ermensee +8734,Ermenswil +3995,Ernen +8725,Ernetschwil +3957,Erschmatt +4228,Erschwil +3423,Ersigen +6418,Rothenthurm +6472,Erstfeld +8500,Frauenfeld +6274,Eschenbach LU +8733,Eschenbach SG +8180,Bülach +8264,Eschenz +2743,Eschert +3766,Boltigen +1673,Ecublens FR +8553,Eschikofen +8315,Lindau +8474,Dinhard +8360,Eschlikon TG +6182,Escholzmatt +1670,Esmonts +1724,Essert FR +1078,Essertes +2886,Epiquerez +1186,Essertines-Rolle +1417,Essertines-Yverdon +1435,Essert-Pittet +1443,Essert-s-Champvent +8133,Esslingen +1665,Estavannens +1695,Estavayer-Gibloux +1470,Estavayer-le-Lac +1687,Estévenens +1037,Etagnières +1941,Vollèges +1163,Etoy +1551,Vers-chez-Perrin +8620,Wetzikon ZH +8356,Ettenhausen TG +8314,Kyburg +4107,Ettingen +6218,Ettiswil +8847,Egg SZ +8835,Feusisberg +3306,Etzelkofen +6231,Schlierbach +5275,Etzgen +4554,Etziken +5317,Hettenschwil +8259,Etzwilen +8508,Homburg +1982,Euseigne +8844,Euthal +2533,Evilard +1902,Evionnaz +1983,Evolène +1866,La Forclaz VD +3400,Burgdorf +3400,Burgdorf +3063,Ittigen +3930,Eyholz +3000,Bern +1262,Eysins +3919,Blatten(Lötschen) +8630,Rüti ZH +8109,Kloster Fahr +8525,Niederneunforn +3617,Fahrni b. Thun +5615,Fahrwangen +8951,Fahrweid +8951,Fahrweid +8951,Fahrweid +2916,Fahy +6760,Faido +6760,Faido +7226,Fajauna +7153,Falera +8117,Fällanden +8636,Wald ZH +7215,Fanas +3961,Vissoie +3557,Fankhaus (Trub) +1595,Faoug +7433,Farden +4539,Farnern +1726,Farvagny +1726,Farvagny +1726,Farvagny-le-Petit +3705,Faulensee +1173,Féchy +8320,Fehraltorf +4232,Fehren +5316,Leuggern +8552,Felben-Wellhausen +8714,Feldbach +8266,Steckborn +4532,Feldbrunnen +7404,Feldis/Veulden +8706,Meilen +9425,Thal +7012,Felsberg +3000,Bern +5316,Leuggern +8143,Stallikon +1880,Fenalet-sur-Bex +3178,Bösingen +1809,Fenil-sur-Corsier +2063,Fenin +5645,Fenkrieden +3916,Ferden +3206,Ferenbalm +3208,Gurbrü +3066,Stettlen +1076,Ferlens VD +1984,Les Haudères +1724,Ferpicloz +6277,Kleinwangen +1944,La Fouly VS +1313,Ferreyres +3956,Guttet-Feschel +6938,Fescoggia +1532,Fétigny +8245,Feuerthalen +8835,Feusisberg +3784,Feutersoey +7514,Fex +1044,Fey +1996,Fey (Nendaz) +1854,Leysin +1609,Fiaugères +7019,Fidaz +7235,Fideris +7235,Fideris +3984,Fiesch +3984,Fieschertal +6772,Rodi-Fiesso +1420,Fiez +6760,Rossura +6918,Figino +3983,Filet +7477,Filisur +3185,Schmitten FR +8757,Filzbach +8514,Amlikon-Bissegg +1925,Finhaut +2577,Finsterhennen +6313,Finstersee +6162,Finsterwald LU +1948,Fionnay +8307,Ottikon b.Kemptth. +6145,Fischbach LU +5525,Fischbach-Göslikon +8558,Raperswilen +8497,Fischenthal +8376,Fischingen +5467,Fisibach +5442,Fislisbach +8416,Flaach +3175,Flamatt +3978,Flanthey +7306,Fläsch +9230,Flawil +4852,Rothrist +1659,Flendruz +7426,Flerden +2114,Fleurier +7017,Flims Dorf +7017,Flims Dorf +7018,Flims Waldhaus +7137,Flond +6454,Flüelen +6073,Flüeli-Ranft +3065,Bolligen +4112,Flüh +6173,Flühli LU +4534,Flumenthal +8890,Flums +8000,Zürich +8247,Flurlingen +8872,Weesen +8872,Weesen +7057,Langwies +1473,Font +1945,Fontaine Dessous +1945,Fontaine Dessus +2052,Fontainemelon +2046,Fontaines NE +1421,Fontaines-Grandson +7553,Tarasp +6834,Morbio Inferiore +1423,Fontanezier +6110,Fontannen +1860,Aigle +2902,Fontenais +1934,Le Châble VS +9476,Fontnas +8127,Forch +8127,Forch +1867,Ollon VD +1475,Forel FR +1072,Forel (Lavaux) +1526,Forel-sur-Lucens +1782,Formangueires +6996,Ponte Cremenaga +2717,Fornet-Dessous +2718,Fornet-Dessus +1945,Fornex(Liddes) +6690,Cavergno +9450,Altstätten SG +3636,Forst +1966,Fortunau (Ayent) +6574,Vira (Gambarogno) +1225,Chêne-Bourg +1297,Founex +1489,Murist +3284,Fräschels +6636,Frasco +9320,Frasnacht +1483,Frasses +3312,Fraubrunnen +3255,Rapperswil BE +8500,Frauenfeld +3202,Frauenkappelen +7276,Davos Frauenkirch +6763,Osco +2953,Fregiécourt +3176,Neuenegg +9306,Freidorf TG +8807,Freienbach +8427,Freienstein +5423,Freienwil +3510,Freimettigen +1880,Frenières-sur-Bex +4402,Frenkendorf +2027,Fresens +2149,Fretereules +8615,Freudwil +1700,Fribourg +1700,Fribourg +5070,Frick +8964,Rudolfstetten +3267,Seedorf BE +6332,Hagendorn +3035,Frieswil +7136,Obers Friggahüs +9504,Friltschen +2535,Frinvillier +3436,Zollbrück +3436,Zollbrück +4634,Wisen SO +1055,Froideville +1223,Cologny +1618,Châtel-St-Denis +9467,Frümsen +8269,Fruthwilen +3714,Frutigen +6068,Melchsee-Frutt +7551,Ftan +8352,Elsau +7533,Fuldera +4629,Fulenbach +5324,Full-Reuenthal +4414,Füllinsdorf +1926,Fully +7185,Platta +3997,Bellwald +6363,Fürigen +7232,Furna +7414,Fürstenau +7413,Fürstenaubruck +9125,Brunnadern +6696,Fusio +3907,Gabi (Simplon) +8214,Gächlingen +4584,Gächliwil +8547,Gachnang +7244,Gadenstätt +3863,Gadmen +6934,Bioggio +6596,Gordola +6855,Stabio +9534,Gähwil +2513,Twann +9056,Gais +9030,Abtwil SG +8854,Galgenen +5225,Bözberg +3285,Galmiz +3238,Gals +5272,Gansingen +1712,Tafers +3153,Rüschegg Gambach +3206,Gammen +3454,Sumiswald +3945,Gampel +3236,Gampelen +9473,Gams +3900,Gamsen +6978,Gandria +4716,Gänsbrunnen +5272,Gansingen +9608,Ganterschwil +3935,Bürchen +3186,Düdingen +3766,Boltigen +8487,Zell ZH +3144,Gasel +3924,St. Niklaus VS +9473,Gams +7317,Valens +8136,Gattikon +5412,Gebenstorf +8725,Gebertingen +9203,Niederwil SG +8044,Zürich +8554,Bonau +3904,Naters +6123,Geiss +3860,Meiringen +6284,Gelfingen +3126,Gelterfingen +4460,Gelterkinden +5637,Geltwil +4145,Gempen +3215,Gempenach +6852,Genestrerio +1200,Genève +1272,Genolier +1294,Genthod +6925,Gentilino +9212,Arnegg +3065,Bolligen +4563,Gerlafingen +8500,Gerlikon +8302,Kloten +6020,Emmenbrücke +8954,Geroldswil +2575,Gerolfingen +6576,Gerra (Gambarogno) +6635,Gerra (Verzasca) +6516,Cugnasco +6442,Gersau +3115,Gerzensee +3985,Geschinen +6142,Gettnau +3945,Gampel +3945,Gampel +6232,Geuensee +9043,Trogen +8600,Dübendorf +4852,Rothrist +6720,Ghirone +7545,Guarda +8498,Gibswil +4304,Giebenach +3855,Brienz BE +8717,Benken SG +1925,Finhaut +1429,Giez +1735,Giffers +1673,Gillarens +1182,Gilly +1188,Gimel +3826,Gimmelwald +3272,Walperswil +1276,Gingins +6745,Giornico +5073,Gipf-Oberfrick +5316,Leuggern +7135,Obersaxen Giraniga +8340,Hinwil +8488,Turbenthal +8468,Guntalingen +8467,Truttikon +6038,Gisikon +6074,Giswil +6074,Giswil +6512,Giubiasco +6678,Giumaglio +1762,Givisiez +1271,Givrins +1115,Vullierens +1196,Gland +4852,Rothrist +3960,Sierre +7277,Davos Glaris +8266,Steckborn +8750,Glarus +7428,Glaspass +4856,Glashütten +8152,Glattbrugg +8192,Glattfelden +8152,Glattpark(Opfikon) +3999,Oberwald +1544,Gletterens +1823,Glion +3902,Glis +3612,Steffisburg +2855,Glovelier +3998,Gluringen +1867,Ollon VD +5524,Nesselnbach +6525,Gnosca +8044,Gockhausen +3553,Gohl +6950,Tesserete +3207,Golaten +9403,Goldach +6410,Goldau +8700,Küsnacht ZH +3432,Lützelflüh-Goldb +6085,Hasliberg Goldern +8638,Goldingen +3624,Goldiwil (Thun) +3805,Goldswil +6656,Golino +1124,Gollion +6475,Bristen +3415,Schafhausen i. E. +8737,Gommiswald +4955,Gondiswil +3907,Gondo +9108,Gonten +9108,Gontenbad +5728,Gontenschwil +3917,Goppenstein +3983,Goppisberg +6596,Gordola +6672,Gordevio +6596,Gordola +6518,Gorduno +2023,Gorgier +6874,Castel San Pietro +3920,Zermatt +6487,Göschenen +6487,Göschenen +5525,Fischbach-Göslikon +8625,Gossau ZH +9200,Gossau SG +1407,Gossens +8126,Zumikon +4579,Gossliwil +8583,Götighofen +1907,Saxon +4000,Basel +8274,Gottlieben +9225,Wilen (Gottshaus) +2552,Orpund +8400,Winterthur +1376,Goumoens-la-Ville +1376,Goumoens-le-Jux +2354,Goumois +3154,Rüschegg Heubach +3376,Graben +9472,Grabs +9472,Grabserberg +3925,Grächen +3045,Meikirch +6388,Grafenort +6388,Grafenort +3308,Grafenried +8310,Grafstal +8572,Graltshausen +9601,Lütisburg Station +6916,Grancia +1117,Grancy +1052,Mont-sur-Lausanne +2127,Les Bayards +1820,Montreux +1543,Grandcour +1421,Grandevent +2908,Grandfontaine +2923,Courtemaîche +1212,Grand-Lancy +1212,Grand-Lancy +2065,Savagnier +1775,Grandsivaz +1422,Grandson +1946,Bourg-St-Pierre +2745,Grandval +1091,Grandvaux +1666,Grandvillard +3977,Granges VS +1614,Granges (Veveyse) +1484,Granges-de-Vesin +1763,Granges-Paccot +1523,Granges-Marnand +1552,Trey +1686,Grangettes-Romont +5722,Gränichen +1965,Granois (Savièse) +8415,Gräslikon +3365,Grasswil +1624,Grattavache +3325,Hettiswil +6929,Gravesano +3983,Greich +8606,Greifensee +4203,Grellingen +2540,Grenchen +2540,Grenchen +3280,Greng +3993,Grengiols +1726,Grenilles +1274,Grens +6404,Greppen +6611,Gresso +1432,Gressy +9479,Gretschins +5014,Gretzenbach +6747,Chironico +3723,Kiental +3454,Sumiswald +8514,Amlikon-Bissegg +3961,Grimentz +1971,Grimisuat +3757,Schwenden +3864,Guttannen +4247,Grindel +3818,Grindelwald +3266,Wiler b. Seedorf +4658,Däniken SO +1772,Grolley +3979,Grône +6537,Grono +8841,Gross +3257,Grossaffoltern +8896,Flumserberg Bergh +6146,Grossdietwil +1792,Guschelmuth +3506,Grosshöchstetten +3175,Flamatt +6074,Giswil +6022,Grosswangen +9035,Grub AR +9036,Grub SG +3946,Gruben +3770,Zweisimmen +1955,Grugnay (Chamoson) +3783,Grund b. Gstaad +8554,Müllheim-Wigoltgn +3455,Grünen +3452,Grünenmatt +8627,Grüningen +7214,Grüsch +8624,Grüt (Gossau ZH) +8400,Winterthur +1663,Gruyères +1882,Gryon +3933,Staldenried +3780,Gstaad +3785,Gsteig b. Gstaad +3814,Gsteigwiler +7545,Guarda +6515,Gudo +1920,Martigny +1787,Môtier (Vully) +3158,Guggisberg +8127,Forch +1643,Gumefens +3073,Gümligen +3205,Gümmenen +4000,Basel +8507,Hörhausen +8543,Gundetswil +8322,Gündisau +8543,Bertschikon +3815,Gündlischwand +6276,Hohenrain +4524,Günsberg +8468,Guntalingen +3654,Gunten +8564,Gunterswilen +8357,Guntershausen +8572,Guntershausen Berg +8223,Guntmadingen +4617,Gunzgen +6222,Gunzwil +3208,Gurbrü +3212,Gurmels +3099,Rüti b. Riggisberg +9620,Lichtensteig +3084,Wabern +6482,Gurtnellen +3663,Gurzelen +1792,Guschelmuth +4932,Gutenburg +8605,Gutenswil +8478,Thalheim +3864,Guttannen +3956,Guttet-Feschel +8594,Güttingen +3645,Gwatt (Thun) +3645,Gwatt (Thun) +1251,Gy +3503,Gysenstein +2545,Selzach +9469,Haag (Rheintal) +3804,Habkern +5245,Habsburg +6166,Hasle LU +3065,Bolligen +8340,Hinwil +4445,Häfelfingen +9052,Niederteufen +8523,Hagenbuch ZH +4614,Hägendorf +6332,Hagendorn +5317,Hettenschwil +8577,Schönholzerswilen +8580,Hagenwil +9312,Häggenschwil +5607,Hägglingen +2575,Hagneck +8309,Nürensdorf +9032,Engelburg +9223,Halden +7023,Haldenstein +6469,Haldi b.Schattdorf +6469,Haldi b.Schattdorf +9548,Matzingen +8215,Hallau +5705,Hallwil +4566,Halten +9035,Grub AR +9035,Grub AR +6289,Hämikon +3508,Arni BE +3864,Guttannen +8585,Happerswil +3054,Schüpfen +9463,Oberriet SG +3250,Lyss +8553,Harenwilen +4624,Härkingen +3612,Steffisburg +8965,Berikon +8342,Wernetshausen +6166,Hasle LU +3415,Hasle b. Burgdorf +8773,Haslen GL +9054,Haslen AI +3415,Hasle b. Burgdorf +3132,Riggisberg +8554,Müllheim-Wigoltgn +8156,Oberhasli +6085,Hasliberg Goldern +8580,Amriswil +8564,Hattenhausen +8775,Hätzingen +4633,Hauenstein +9426,Lutzenberg +8926,Hauptikon +9213,Hauptwil +5212,Hausen AG +8915,Hausen am Albis +8475,Ossingen +3463,Häusernmoos +8554,Bonau +8522,Häuslenen +1997,Haute-Nendaz +2068,Hauterive NE +1648,Hauteville +1800,Vevey +3510,Häutligen +1789,Lugnorre +8908,Hedingen +9435,Heerbrugg +9435,Heerbrugg +9435,Heerbrugg +9435,Heerbrugg +8564,Hefenhausen +8580,Hefenhofen +3202,Frauenkappelen +8400,Winterthur +8604,Volketswil +9410,Heiden +3625,Heiligenschwendi +6166,Hasle LU +9000,St. Gallen +9000,St. Gallen +8888,Heiligkreuz (Mels) +9515,Hosenruck +3627,Heimberg +3373,Heimenhausen +8586,Andwil TG +3615,Heimenschwand +3453,Heimisbach +3412,Heimiswil +4558,Heinrichswil +8915,Hausen am Albis +1714,Heitenried +8957,Spreitenbach +9545,Wängi +9630,Wattwil +3186,Düdingen +9216,Heldswil +3155,Helgisried +6016,Hellbühl +6016,Hellbühl +4316,Hellikon +3429,Hellsau +9313,Muolen +8558,Raperswilen +9633,Hemberg +8261,Hemishofen +8231,Hemmental +8580,Amriswil +4465,Hemmiken +9247,Henau +5604,Hendschiken +8444,Henggart +1681,Hennens +1525,Henniez +4715,Herbetswil +3671,Herbligen +8207,Schaffhausen +3927,Herbriggen +8535,Herdern +1987,Hérémence +6052,Hergiswil NW +6133,Hergiswil LU +9100,Herisau +6028,Herlisberg +1248,Hermance +8330,Pfäffikon ZH +1513,Hermenches +5626,Hermetschwil-Staff +8600,Dübendorf +3475,Hermiswil +3132,Riggisberg +3274,Hermrigen +3503,Gysenstein +8585,Herrenhof +3037,Herrenschwanden +8704,Herrliberg +4423,Hersberg +8626,Ottikon +4558,Hersiwil +6353,Weggis +5415,Hertenstein AG +5025,Asp +5027,Herznach +3360,Herzogenbuchsee +3172,Niederwangen BE +8700,Küsnacht ZH +8583,Sulgen +4577,Hessigkofen +5317,Hettenschwil +3325,Hettiswil +8442,Hettlingen +3154,Rüschegg Heubach +8607,Aathal-Seegräben +3711,Emdthal +6024,Hildisrieden +6192,Wiggen +5613,Hilfikon +3652,Hilterfingen +4204,Himmelried +3324,Hindelbank +8806,Bäch SZ +8806,Bäch SZ +8132,Hinteregg +9452,Hinterforst +9452,Hinterforst +3089,Hinterfultigen +8638,Goldingen +9033,Untereggen +3032,Hinterkappelen +3032,Hinterkappelen +6260,Hintermoos +7438,Hinterrhein +6436,Muotathal +4813,Uerkheim +8340,Hinwil +9464,Rüthi (Rheintal) +3153,Rüschegg Gambach +3158,Guggisberg +5042,Hirschthal +8000,Zürich +3715,Adelboden +4000,Basel +8816,Hirzel +8636,Wald ZH +8335,Hittnau +6285,Hitzkirch +6280,Hochdorf +6280,Hochdorf +8182,Hochfelden +3429,Höchstetten +4146,Hochwald +8893,Flums Hochwiese +8842,Unteriberg +8842,Unteriberg +8304,Wallisellen +9404,Rorschacherberg +8590,Romanshorn +8730,Uznach +4943,Oeschenbach +8242,Hofen SH +3631,Höfen b. Thun +8370,Sirnach +9114,Hoffeld +6154,Hofstatt +8154,Oberglatt ZH +4114,Hofstetten SO +8354,Hofstetten ZH +3858,Hofstetten BE +3053,Münchenbuchsee +6276,Hohenrain +9216,Hohentannen +6083,Hasliberg Hohfluh +9404,Rorschacherberg +3949,Hohtenn +4718,Holderbank SO +5113,Holderbank AG +4434,Hölstein +8590,Romanshorn +6343,Holzhäusern ZG +8558,Raperswilen +5043,Holziken +3902,Glis +8360,Eschlikon TG +3622,Homberg b. Thun +8634,Hombrechtikon +8508,Homburg +6038,Honau +3702,Hondrich +4712,Laupersdorf +8000,Zürich +8524,Buch b. Frauenfeld +8308,Illnau +8372,Wiezikon b.Sirnach +3755,Horboden +8810,Horgen +8500,Frauenfeld +8815,Horgenberg +8507,Hörhausen +8181,Höri +9326,Horn +5075,Hornussen +3623,Horrenbach +4557,Horriwil +6048,Horw +9515,Hosenruck +6493,Hospental +8000,Zürich +5277,Hottwil +8637,Laupen ZH +6133,Hergiswil LU +8500,Frauenfeld +4535,Hubersdorf +8590,Romanshorn +9402,Mörschwil +1884,Huémoz +8565,Hugelshofen +8354,Hofstetten ZH +4245,Kleinlützel +8457,Humlikon +9064,Hundwil +6331,Hünenberg +8599,Salmsach +3626,Hünibach +3626,Hünibach +4554,Hüniken +8412,Hünikon +8194,Hüntwangen +5502,Hunzenschwil +9545,Wängi +8640,Hurden +8360,Eschlikon TG +3860,Meiringen +6152,Hüswil +8825,Hütten +8115,Hüttikon +8553,Hüttlingen +4950,Huttwil +8536,Hüttwilen +8488,Turbenthal +6438,Ibach +8400,Winterthur +8843,Oberiberg +4571,Ichertswil +1977,Icogne +4633,Hauenstein +3305,Iffwil +8362,Balterswil +7206,Igis +7130,Ilanz +3550,Langnau i. E. +1893,Muraz (Collombey) +6434,Illgau +8556,Illhart +8574,Illighausen +3033,Wohlen b. Bern +8308,Illnau +1656,Im Fang +4514,Lommiswil +6405,Immensee +6571,Indemini +3953,Inden +6440,Brunnen +3375,Inkwil +7050,Arosa +3044,Innerberg +3619,Innereriz +7445,Innerferrera +8858,Innerthal +3862,Innertkirchen +7136,Obers Friggahüs +3232,Ins +6951,Insone +3800,Interlaken +6655,Intragna +6476,Intschi +6034,Inwil +2563,Ipsach +6707,Iragna +8330,Pfäffikon ZH +4000,Basel +8524,Uesslingen +3807,Iseltwald +5637,Geltwil +3822,Isenfluh +6461,Isenthal +6993,Iseo +1914,Isérables +8335,Hittnau +6466,Bauen +8546,Islikon +8905,Islisberg +6614,Isole di Brissago +6810,Isone +1937,Orsières +8575,Istighofen +8362,Balterswil +4452,Itingen +3818,Grindelwald +3979,Grône +8700,Küsnacht ZH +1308,La Chaux-Cossonay +5083,Ittenthal +3063,Ittigen +8627,Grüningen +3629,Jaberg +9108,Jakobsbad +9545,Wängi +8354,Hofstetten ZH +3673,Linden +1656,Jaun +3303,Jegenstorf +3945,Gampel +7233,Jenaz +7307,Jenins +7494,Davos Wiesen +2565,Jens +3208,Gurbrü +3208,Gurbrü +3186,Düdingen +3038,Kirchlindach +1793,Jeuss +8645,Jona +8916,Jonen +1805,Jongny +9243,Jonschwil +1833,Les Avants +1789,Lugnorre +1008,Jouxtens-Mézery +3036,Detligen +3204,Rosshäusern +3476,Oschwand +8493,Saland +7448,Juf +7457,Bivio +3801,Jungfraujoch +1326,Juriens +1254,Jussy +1254,Jussy +6056,Kägiswil +9038,Rehetobel +4303,Kaiseraugst +6078,Bürglen OW +5466,Kaiserstuhl AG +5082,Kaisten +3415,Hasle b. Burgdorf +8536,Hüttwilen +5625,Kallern +3283,Kallnach +3922,Kalpetran +3413,Kaltacker +6212,Kaltbach +8722,Kaltbrunn +8259,Kaltenbach +8514,Amlikon-Bissegg +9508,Weingarten-Kalth +4535,Kammersrohr +3714,Frutigen +3716,Kandergrund +3718,Kandersteg +4447,Känerkinden +8810,Horgen +4616,Kappel SO +8508,Homburg +8926,Kappel am Albis +3273,Kappelen +3032,Hinterkappelen +3063,Ittigen +8532,Warth +6086,Hasliberg Reuti +6047,Kastanienbaum +8153,Rümlang +8105,Watt +3126,Kaufdorf +8546,Kefikon TG +8546,Kefikon TG +8712,Stäfa +8572,Berg TG +3122,Kehrsatz +6365,Kehrsiten +8307,Ottikon b.Kemptth. +6333,Hünenberg See +6197,Schangnau +5436,Würenlos +8640,Rapperswil SG +8623,Wetzikon ZH +8310,Kemptthal +3309,Kernenried +6064,Kerns +3210,Kerzers +8593,Kesswil +4703,Kestenholz +4468,Kienberg +3628,Uttigen +3855,Brienz BE +3723,Kiental +3629,Kiesen +8802,Kilchberg ZH +4496,Kilchberg BL +6204,Sempach +8956,Killwangen +8604,Volketswil +8962,Bergdietikon +3917,Kippel +3422,Kirchberg BE +9533,Kirchberg SG +5225,Bözberg +8474,Dinhard +3116,Kirchdorf BE +5416,Kirchdorf AG +3000,Bern +3128,Kirchenthurnen +6060,Sarnen +5054,Kirchleerau +3038,Kirchlindach +5044,Schlossrued +8585,Klarsreuti +8451,Kleinandelfingen +8498,Gibswil +3213,Kleinbösingen +4936,Kleindietwil +5314,Kleindöttingen +3823,Kleine Scheidegg +3205,Gümmenen +3212,Kleingurmels +1792,Guschelmuth +4000,Basel +8312,Winterberg ZH +4245,Kleinlützel +6074,Giswil +6277,Kleinwangen +4612,Wangen b. Olten +6375,Beckenried +8508,Homburg +8264,Eschenz +5313,Klingnau +8750,Klöntal +7252,Klosters Dorf +7250,Klosters +8302,Kloten +4710,Balsthal +4000,Basel +8881,Knoblisbühl +8934,Knonau +6213,Knutwil +9463,Oberriet SG +5322,Koblenz +8483,Kollbrunn +5742,Kölliken +5200,Brugg AG +3098,Köniz +3510,Konolfingen +3425,Koppigen +3262,Suberg +6217,Kottwil +9214,Kradolf +3315,Kräiligen +3704,Krattigen +3326,Krauchthal +8280,Kreuzlingen +3179,Kriechenwil +4566,Kriegstetten +6010,Kriens +9451,Kriessern +9546,Tuttwil +9622,Krinau +9300,Wittenbach +3555,Trubschachen +6232,Geuensee +9643,Krummenau +7240,Küblis +8506,Lanzenneunforn +3086,Zimmerwald +6234,Kulmerau +8586,Kümmertshausen +4665,Oftringen +7315,Vättis +5444,Künten +8500,Frauenfeld +8280,Kreuzlingen +8700,Küsnacht ZH +6403,Küssnacht am Rigi +5024,Küttigen +4581,Küttigkofen +8314,Kyburg +4586,Kyburg-Buchegg +1902,Evionnaz +1882,Gryon +1920,Martigny +2360,Le Bémont JU +2406,La Brévine +1222,Vésenaz +1222,Vésenaz +2406,La Châtagne +1308,La Chaux-Cossonay +2333,La Ferrière +2333,La Ferrière +2300,La Chaux-de-Fonds +2345,Chaux-des-Breuleux +1454,L'Auberson +2405,La Chaux-du-Milieu +1806,St-Légier-Chiésaz +2333,La Cibourg +2616,La Cibourg +2300,La Cibourg +1862,La Comballaz +1093,La Conversion +2314,La Sagne NE +1782,La Corbaz +2117,La Côte-aux-Fées +1148,La Coudre +2000,Neuchâtel +1920,Martigny +1923,Les Marécottes +1090,La Croix (Lutry) +1921,Martigny-Croix +1257,La Croix-de-Rozon +1265,La Cure +1891,Vérossaz +1937,Orsières +1763,Granges-Paccot +1763,Granges-Paccot +2333,La Ferrière +1921,Martigny-Croix +1866,La Forclaz VD +1985,La Forclaz VS +1920,Martigny +1944,La Fouly VS +1933,La Garde +1264,St-Cergue +1347,Le Sentier +1224,Chêne-Bougeries +2604,La Heutte +2400,Le Locle +2043,Boudevilliers +1697,La Joux FR +2058,Le Pâquier NE +1660,La Lécherette +1982,Euseigne +1687,La Magne +1462,Yvonand +1947,Champsec +1431,Vugelles-La Mothe +2889,Ocourt +1965,La Muraz (Savièse) +1686,La Neirigue +2520,La Neuveville +1222,Vésenaz +2316,Petit-Martel +1966,La Place (Ayent) +1283,La Plaine +1227,Carouge GE +1227,Carouge GE +2523,Lignières +1148,La Praz +7522,La Punt-Chamues-ch +1902,Evionnaz +1902,Evionnaz +1278,La Rippe +1417,Essertines-Yverdon +1634,La Roche FR +1613,Maracon +7742,La Rösa +1009,Pully +1937,Orsières +1623,Semsales +1356,La Russille +1985,La Sage +1450,La Sagne VD +2314,La Sagne NE +2314,La Sagne NE +1000,Lausanne +1315,La Sarraz +1943,Praz-de-Fort +1783,Pensier +2720,La Tanne +1658,La Tine +1984,La Tour VS +1814,La Tour-de-Peilz +1635,La Tour-de-Trême +2019,Rochefort +1637,Charmey (Gruyère) +1654,Cerniat FR +1992,La Vernaz +1624,La Verrerie +1904,Vernayaz +1489,Murist +1454,La Vraconnaz +2052,La Vue-des-Alpes +7031,Laax GR +1344,L'Abbaye +1355,L'Abergement +8853,Lachen SZ +9428,Walzenhausen +9000,St. Gallen +1287,Laconnex +7155,Ladir +7082,Vaz/Obervaz +2718,Lajoux JU +3931,Lalden +1880,Bex +1807,Blonay +1807,Blonay +2516,Lamboing +6814,Lamone +4432,Lampenberg +8556,Lamperswil TG +1983,Lanna +1212,Grand-Lancy +6545,Selma +1257,La Croix-de-Rozon +3036,Detligen +2046,Fontaines NE +8903,Birmensdorf ZH +3434,Landiswil +7302,Landquart +7302,Landquart +8597,Landschlacht +3427,Utzenstorf +8135,Langnau am Albis +6039,Root D4 +4438,Langenbruck +3636,Längenbühl +4513,Langendorf +3556,Trub +8486,Rikon im Tösstal +8555,Müllheim Dorf +3075,Rüfenacht BE +8467,Truttikon +3653,Oberhofen Thun'see +4900,Langenthal +9000,St. Gallen +3000,Bern +8135,Langnau am Albis +6262,Langnau b. Reiden +3550,Langnau i. E. +8585,Langrickenbach +7057,Langwies +8246,Langwiesen +9503,Lanterswil +7083,Lantsch/Lenz +3148,Lanzenhäusern +8506,Lanzenneunforn +7562,Samnaun-Compatsch +7265,Davos Wolfgang +6724,Largario +7484,Latsch +3758,Latterbach +3053,Lätti +2572,Sutz +1454,L'Auberson +3782,Lauenen b. Gstaad +6424,Lauerz +4448,Läufelfingen +4242,Laufen +5080,Laufenburg +8248,Uhwiesen +5200,Brugg AG +9466,Sennwald +8637,Laupen ZH +3177,Laupen BE +9524,Zuzwil SG +9524,Zuzwil SG +4712,Laupersdorf +3438,Lauperswil +1000,Lausanne +4415,Lausen +3414,Oberburg +3822,Lauterbrunnen +4426,Lauwil +6633,Lavertezzo +1892,Lavey-les-Bains +1892,Lavey-Village +1175,Lavigny +7543,Lavin +6718,Olivone +6746,Lavorgo +3994,Lax +2360,Le Bémont JU +1880,Bex +1937,Orsières +1997,Haute-Nendaz +2336,Les Bois +1932,Bovernier +1920,Martigny +1348,Le Brassus +1921,Martigny-Croix +2406,Le Brouillet +1645,Le Bry +1348,Le Brassus +1285,Athenaz (Avusy) +1348,Le Brassus +1921,Martigny-Croix +2414,Cerneux-Péquignot +2345,Le Cerneux-Veusil +2722,Les Reussilles +1934,Le Châble VS +1000,Lausanne 25 +2738,Court +1987,Hérémence +1450,Le Château-Croix +1925,Le Châtelard VS +1689,Châtelard-p-Romont +1347,Le Sentier +2400,Le Locle +2058,Le Pâquier NE +1372,Bavois +2314,La Sagne NE +2322,Le Crêt-du-Locle +1611,Le Crêt-p-Semsales +2400,Le Prévoux +1337,Vallorbe +1071,Rivaz +1921,Martigny-Croix +1947,Champsec +2712,Le Fuet +1218,Le Grand-Saconnex +2720,Tramelan +2318,Brot-Plamboz +1609,St-Martin FR +2525,Le Landeron +2023,Gorgier +1345,Le Lieu +1219,Le Lignon +2400,Le Locle +1348,Le Brassus +1947,Versegères +1801,Le Mont-Pèlerin +1052,Mont-sur-Lausanne +1948,Lourtier +1724,Le Mouret +1724,Le Mouret +1273,Le Muids +2340,Le Noirmont +1724,Bonnefontaine +1661,Pâquier-Montbarry +2058,Le Pâquier NE +1991,Salins +1788,Praz (Vully) +1200,Genève +2345,Les Breuleux +2336,Les Bois +2340,Le Noirmont +1948,Lourtier +1342,Le Pont +2534,Orvin +2714,Le Prédame +7746,Le Prese +2400,Le Prévoux +2400,Le Prévoux +2400,Le Locle +1347,Le Sentier +2345,Les Breuleux +1864,Vers-l'Eglise +1934,Le Châble VS +1678,Siviriez +1345,Le Séchey +1347,Le Sentier +1863,Le Sépey +1347,Le Solliat +1923,Le Trétien +1091,Grandvaux +1261,Le Vaud +1773,Léchelles +6556,Leggia +5325,Leibstadt +8041,Zürich +5733,Leimbach AG +8584,Leimbach TG +4935,Leimiswil +3706,Leissigen +6951,Odogno +9525,Lenggenwil +2543,Lengnau BE +5426,Lengnau AG +8574,Lengwil +3775,Lenk im Simmental +1978,Lens +1745,Lentigny +5600,Lenzburg +7077,Valbella +7078,Lenzerheide/Lai +8732,Neuhaus SG +6716,Leontica +3600,Thun +1227,Les Acacias +1227,Les Acacias +1992,Les Agettes +1943,Praz-de-Fort +1220,Les Avanchets +1833,Les Avants +1864,Vers-l'Eglise +2127,Les Bayards +1996,Basse-Nendaz +1346,Les Bioux +2336,Les Bois +1865,Les Diablerets +2416,Les Brenets +2345,Les Breuleux +2058,Le Pâquier NE +2350,Saignelégier +1343,Les Charbonnières +1680,Romont FR +1906,Charrat +1807,Blonay +1356,Les Clées +2314,La Sagne NE +1988,Les Collons +1066,Epalinges +1873,Les Crosets +1080,Les Cullayes +1752,Villars-sur-Glâne +1880,Bex +1865,Les Diablerets +1200,Genève +1697,Les Ecasseys +2748,Les Ecorcheresses +2338,Les Emibois +2363,Les Enfers +2300,La Chaux-de-Fonds +1897,Les Evouettes +2416,Les Brenets +1566,Les Friques +2206,Geneveys-Coffrane +2714,Les Genevez JU +1871,Les Giettes +1871,Les Giettes +1660,Château-d'Oex +1922,Granges (Salvan) +2019,Rochefort +1984,Les Haudères +2208,Les Hauts-Geneveys +1929,Trient +2300,La Chaux-de-Fonds +2052,Fontainemelon +1923,Les Marécottes +1987,Hérémence +1992,Les Mayens-de-Sion +1992,Les Mayens-de-Sion +1808,Monts-de-Corsier +1068,Les Monts-de-Pully +1862,Les Mosses +1660,Les Moulins +1945,Les Moulins VS +1868,Collombey +1619,Les Paccots +2318,Brot-Plamboz +1947,Versegères +1475,Autavaux +1863,Le Sépey +1052,Mont-sur-Lausanne +1820,Montreux +2325,Les Planchettes +1880,Les Plans-sur-Bex +2353,Les Pommerats +2610,Les Pontins +1627,Vaulruz +2316,Ponts-de-Martel +1880,Les Posses-sur-Bex +1981,Vex +2534,Les Prés-d'Orvin +2954,Asuel +1921,Martigny-Croix +1452,Les Rasses +2400,Le Locle +2722,Les Reussilles +2800,Delémont +2360,Le Bémont JU +2108,Couvet +2124,Les Sagnettes +2362,Montfaucon +1669,Sciernes-d'Albeuve +2406,Les Taillères +1607,Les Tavernes +1607,Les Thioleyres +1422,Grandson +2345,Les Breuleux +2714,Le Prédame +1932,Les Valettes +1955,Les Vérines +2126,Les Verrières +2054,Les Vieux-Prés +1862,La Comballaz +1424,Champagne +1669,Lessoc +1660,L'Etivaz +8487,Zell ZH +9428,Walzenhausen +8774,Leuggelbach +5316,Leuggern +3954,Leukerbad +3953,Leuk Stadt +5725,Leutwil +3297,Leuzigen +1942,Levron +1854,Leysin +1912,Leytron +7745,Li Curt +9614,Libingen +9620,Lichtensteig +1945,Liddes +1637,Charmey (Gruyère) +3097,Liebefeld +8506,Lanzenneunforn +8543,Bertschikon +3173,Oberwangen b. Bern +3213,Liebistorf +4303,Kaiseraugst +4436,Liedertswil +1688,Lieffrens +6277,Lieli +8966,Oberwil-Lieli +9464,Lienz +4253,Liesberg +4254,Liesberg Dorf +4410,Liestal +1969,Liez (St-Martin) +2514,Ligerz +1357,Lignerolle +2523,Lignières +6853,Ligornetto +8127,Forch +3317,Limpach +8315,Lindau +3673,Linden +4812,Mühlethal +4812,Mühlethal +6332,Hagendorn +4935,Leimiswil +3067,Boll +9032,Engelburg +6682,Linescio +5225,Bözberg +8783,Linthal +8494,Bauma +8564,Lipperswil +8566,Lippoldswilen +1148,L'Isle +6936,Cademario +6014,Luzern +9573,Littenheid +7058,Litzirüti +3178,Bösingen +3268,Lobsigen +3960,Loc +6600,Locarno +9404,Rorschacherberg +6661,Loco +6678,Lodano +6527,Lodrino +1233,Bernex +6563,Mesocco +4573,Lohn-Ammannsegg +8235,Lohn SH +7433,Lohn GR +8224,Löhningen +3127,Lohnstorf +9308,Lömmenschwil +9506,Lommis +4514,Lommiswil +1027,Lonay +1261,Longirod +6956,Lopagno +1341,Orient +6582,Pianezzo +3000,Bern +6300,Zug +6616,Losone +1782,Lossy +6558,Lostallo +4654,Lostorf +6716,Lottigna +4932,Lotzwil +1948,Lourtier +1682,Lovatens +1756,Lovens +2732,Loveresse +2813,Ederswiler +3979,Grône +7534,Lü +1966,Luc (Ayent) +2807,Lucelle +2807,Lucelle +1522,Lucens +9450,Lüchingen +9450,Lüchingen +8775,Luchsingen +8307,Ottikon b.Kemptth. +7185,Platta +8322,Madetswil +6721,Ludiano +8800,Thalwil +7027,Lüen +8426,Lufingen +6953,Lugaggia +6900,Lugano +2933,Lugnez +1789,Lugnorre +1184,Luins +1254,Jussy +1470,Lully FR +1132,Lully VD +1223,Cologny +7148,Lumbrein +6533,Lumino +7166,Trun +7222,Mittellunden +6078,Lungern +7116,Tersnaus +5242,Lupfig +4419,Lupsingen +6777,Quinto +3215,Lurtigen +2576,Lüscherz +1307,Lussery-Villars +4574,Lüsslingen +1690,Lussy FR +1167,Lussy-sur-Morges +8512,Lustdorf +9062,Lustmühle +4542,Luterbach +4571,Lüterkofen +4584,Lüterswil +6156,Luthern +6156,Luthern Bad +8712,Stäfa +9604,Lütisburg +9601,Lütisburg Station +1095,Lutry +3816,Lütschental +3432,Lützelflüh-Goldb +9426,Lutzenberg +7141,Luven +7242,Luzein +6000,Luzern +3250,Lyss +3421,Lyssach +1987,Hérémence +6475,Bristen +8322,Madetswil +4934,Madiswil +6995,Madonna del Piano +6780,Madrano +2500,Biel/Bienne +8886,Mädris-Vermol +7523,Madulain +6573,Magadino +4312,Magden +9116,Wolfertswil +5506,Mägenwil +6673,Maggia +2532,Magglingen/Macolin +6987,Caslano +6987,Caslano +6983,Magliaso +6959,Maglio di Colla +1727,Magnedens +1963,Vétroz +7442,Clugin +4654,Lostorf +7304,Maienfeld +6763,Mairengo +8357,Guntershausen +4464,Maisprach +7026,Maladers +1294,Genthod +9479,Malans SG +7208,Malans GR +1042,Assens +7074,Malix +2735,Malleray +1000,Lausanne +7516,Maloja +6102,Malters +6713,Malvaglia +1283,Dardagny +2043,Boudevilliers +3152,Mamishaus +8265,Mammern +5318,Mandach +8708,Männedorf +8268,Mannenbach-Salenst +1775,Mannens +3823,Wengen +6928,Manno +3770,Zweisimmen +8492,Wila +1613,Maracon +6196,Marbach LU +9437,Marbach SG +1261,Marchissy +3203,Mühleberg +3186,Düdingen +4115,Mariastein +2074,Marin-Epagnier +1723,Marly +7456,Marmorera +1524,Marnand +6817,Maroggia +6723,Marolta +1633,Marsens +8560,Märstetten +8560,Märstetten +2316,Ponts-de-Martel +8460,Marthalen +1063,Martherenges +1920,Martigny +1921,Martigny-Croix +7560,Martina +3994,Martisberg +9562,Märwil +6718,Olivone +7000,Chur +8933,Maschwanden +1968,Mase +7425,Masein +8723,Maseltrangen +6900,Massagno +1869,Massongex +1692,Massonnens +7303,Mastrils +1217,Meyrin +1438,Mathod +7433,Mathon +1753,Matran +8766,Matt +3773,Matten(St.Stephan) +3800,Matten b. Interl +4934,Madiswil +3000,Bern +4000,Basel +3927,Herbriggen +3322,Mattstetten +8585,Mattwil +4713,Matzendorf +3000,Bern +9548,Matzingen +3036,Detligen +1453,Mauborget +6216,Mauensee +1625,Maules +8124,Maur +3935,Bürchen +1148,Mauraz +8576,Mauren TG +3205,Gümmenen +1948,Lourtier +1899,Torgon +1911,Mayens-de-Chamoson +1965,Mayens-de-la-Zour +1973,Nax +1918,La Tzoumaz +3961,Vissoie +1926,Fully +6809,Medeglia +7184,Curaglia +7436,Medels +1936,Verbier +8620,Wetzikon ZH +6597,Agarone +6045,Meggen +6260,Mehlsecken +6485,Meien +5643,Meienberg +3294,Meienried +7134,Obersaxen Meierhof +6344,Meierskappel +3657,Schwanden Sigrisw +3045,Meikirch +8706,Meilen +1252,Meinier +2554,Meinisberg +4912,Aarwangen +3860,Meiringen +8543,Bertschikon +5616,Meisterschwanden +9050,Appenzell Meister. +9050,Appenzell Meister. +6818,Melano +3073,Gümligen +4917,Melchnau +6068,Melchsee-Frutt +6067,Melchtal +6584,Carena +6815,Melide +6584,Carena +5465,Mellikon +5507,Mellingen +5463,Wislikofen +8887,Mels +4233,Meltingen +6850,Mendrisio +3144,Gasel +1533,Ménières +6125,Menzberg +8546,Menzengrüt +5737,Menziken +6313,Menzingen +6122,Menznau +6692,Menzonio +5634,Merenschwand +6647,Mergoscia +6866,Meride +8232,Merishausen +3658,Merligen +1251,Gy +6402,Merlischachen +2827,Mervelier +3274,Merzligen +8308,Illnau +8308,Illnau +6563,Mesocco +3254,Messen +2608,Mtgne-Courtelary +2534,Orvin +2500,Biel/Bienne +5274,Mettau +2806,Mettembert +9200,Gossau SG +8553,Mettendorf TG +6204,Sempach +3665,Wattenwil +6034,Inwil +9517,Mettlen +8155,Niederhasli +6288,Schongau +8932,Mettmenstetten +8252,Schlatt TG +4116,Metzerlen +2126,Les Verrières +1031,Mex VD +1890,Mex VS +3280,Meyriez +1217,Meyrin +1217,Meyrin +1008,Jouxtens-Mézery +1407,Mézery-Donneloye +1684,Mézières FR +1083,Mézières VD +9542,Münchwilen TG +6828,Balerna +6828,Balerna +7249,Serneus +6805,Mezzovico +1749,Middes +2946,Miécourt +3972,Miège +1295,Mies +1904,Vernayaz +2314,La Sagne NE +1896,Miex +6986,Miglieglia +3157,Milken +6648,Minusio +7743,Miralago +7743,Miralago +7135,Obersaxen Giraniga +3532,Mirchel +7133,Obersaxen Affeier +2946,Miécourt +2947,Charmoille +1991,Misériez (Salins) +1721,Misery +3961,Mission +1565,Missy +3717,Blausee-Mitholz +8756,Mitlödi +3147,Mittelhäusern +7222,Mittellunden +9033,Untereggen +9122,Mogelsberg +6677,Moghegno +6695,Peccia +4313,Möhlin +9411,Reute AR +1225,Chêne-Bourg +1148,Moiry VD +6760,Molare +6524,Moleno +1663,Moléson-s-Gruyères +1950,Sion +6517,Arbedo +6500,Bellinzona +6995,Molinazzo +7056,Molinis +1148,Mont-la-Ville +1146,Mollens VD +3974,Mollens VS +1073,Mollie-Margot +8753,Mollis +1415,Molondin +8885,Mols +7186,Segnas +7458,Mon +7250,Klosters +8617,Mönchaltorf +8802,Kilchberg ZH +1936,Verbier +6659,Moneto +2715,Monible +1241,Puplinge +1241,Puplinge +1125,Monnaz +1254,Jussy +2000,Neuchâtel +7278,Davos Monstein +2608,Mtgne-Courtelary +2740,Moutier +2536,Plagne +2615,Montagne-Sonvilier +1934,Le Châble VS +6926,Montagnola +1912,Montagnon (Leytron +1776,Montagny-la-Ville +1774,Montagny-les-Monts +1442,Montagny-Yverdon +2027,Montalchez +3963,Montana +3963,Montana +3963,Montana +1041,Montaubion-Chardon +2857,Montavon +1000,Lausanne 27 +1489,Murist +1669,Montbovon +1475,Montbrelloz +1354,Montcherand +2610,Mont-Crosin +2116,Mont-de-Buttes +6875,Monte +6605,Monte Brè Locarno +6513,Monte Carasso +6802,Rivera +6655,Verdasio +6825,Capolago +6549,Laura +6900,Lugano +1724,Bonnefontaine +6998,Termine +1965,Monteiller +2884,Montenol +3212,Gurmels +1588,Cudrefin +1483,Montet (Broye) +1674,Montet (Glâne) +1724,Montévraz +2037,Montezillon +2362,Montfaucon +2362,Montfavergier +1242,Satigny +1242,Satigny +5237,Mönthal +1174,Montherod +1053,Cugy VD +1870,Monthey +6600,Locarno +6950,Tesserete +6576,Gerra (Gambarogno) +6596,Gordola +6500,Bellinzona +6808,Torricella +6533,Lumino +2924,Montignez +1148,Mont-la-Ville +9462,Montlingen +1587,Montmagny +2883,Montmelon +2075,Thielle +2037,Montmollin +2738,Court +1081,Montpreveyres +2206,Geneveys-Coffrane +1820,Montreux +1147,Montricher +2828,Montsevelier +2610,Mont-Soleil +1185,Mont-sur-Rolle +2723,Mont-Tramelan +8580,Amriswil +3256,Dieterswil +3543,Emmenmatt +5054,Moosleerau +3302,Moosseedorf +6834,Morbio Inferiore +6835,Morbio Superiore +1892,Morcles +6922,Morcote +1462,Yvonand +3983,Mörel +1541,Morens FR +6315,Morgarten +1110,Morges +1875,Morgins +2572,Mörigen +5103,Möriken AG +9543,St. Margarethen TG +9543,St. Margarethen TG +7143,Morissen +3043,Uettligen +1674,Morlens +6074,Giswil +1638,Morlon +2922,Courchavon +2712,Le Fuet +2735,Malleray +1054,Morrens VD +6443,Morschach +9402,Mörschwil +7504,Pontresina +3506,Grosshöchstetten +6612,Ascona +6295,Mosen +9607,Mosnang +6611,Mosogno +1675,Mossel +1787,Môtier (Vully) +2112,Môtiers NE +3324,Mötschwil +3961,Ayer +6721,Motto (Blenio) +1510,Moudon +2740,Moutier +2812,Movelier +6979,Brè sopra Lugano +6939,Mugena +6838,Muggio +5037,Muhen +5642,Mühlau +8580,Amriswil +3995,Mühlebach (Goms) +3203,Mühleberg +3116,Mühledorf BE +4583,Mühledorf SO +8874,Mühlehorn +4812,Mühlethal +3127,Mühlethurnen +3464,Schmidigen-Mühlew +9613,Mühlrüti +9427,Wolfhalden +3317,Mülchi +7082,Vaz/Obervaz +7455,Mulegns +3711,Mülenen +3711,Mülenen +4713,Matzendorf +7016,Trin Mulin +3185,Schmitten FR +3185,Schmitten FR +8558,Raperswilen +8555,Müllheim Dorf +8554,Müllheim-Wigoltgn +5243,Mülligen +4912,Aarwangen +4717,Mümliswil +7183,Mumpé Medel +4322,Mumpf +3053,Münchenbuchsee +4142,Münchenstein +1797,Münchenwiler +3303,Münchringen +4333,Münchwilen AG +9542,Münchwilen TG +3903,Mund +3436,Zollbrück +3110,Münsingen +3985,Münster VS +8596,Münsterlingen +3286,Muntelier +3225,Müntschemier +9313,Muolen +6436,Muotathal +1787,Mur (Vully) FR +1787,Mur (Vully) VD +7109,Thalkirch +6600,Muralto +1893,Muraz (Collombey) +3960,Muraz (Sierre) +8877,Murg +4853,Murgenthal +5630,Muri AG +3074,Muri b. Bern +2338,Muriaux +1489,Murist +9548,Matzingen +3825,Mürren +7032,Laax GR 2 +3280,Murten +3034,Murzelen +9602,Müselbach +7537,Müstair +6289,Müswangen +1428,Mutrux +8965,Berikon +8964,Rudolfstetten +8967,Widen +5621,Zufikon +7185,Platta +7431,Mutten +4132,Muttenz +6933,Muzzano +8752,Näfels +8606,Nänikon +1786,Sugiez +1804,Corsier-sur-Vevey +6780,Airolo +9123,Nassen +8155,Nassenwil +3904,Naters +1973,Nax +1041,Naz +6244,Nebikon +9126,Necker +9126,Necker +8173,Neerach +8413,Neftenbach +6991,Neggio +1669,Neirivue +1955,Némiaz (Chamoson) +4574,Nennigkofen +4224,Nenzlingen +8484,Neschwil +5524,Nesselnbach +3863,Gadmen +9650,Nesslau +8754,Netstal +9652,Neu St. Johann +6314,Neuägeri +6314,Neuägeri +6314,Neuägeri +4123,Allschwil +8164,Bachs +3000,Bern +3037,Herrenschwanden +8488,Turbenthal +2000,Neuchâtel +9200,Gossau SG +9615,Dietfurt +6025,Neudorf +9000,St. Gallen +4623,Neuendorf +3176,Neuenegg +5432,Neuenhof +6206,Neuenkirch +4142,Münchenstein +3600,Thun +8304,Wallisellen +8304,Wallisellen +8732,Neuhaus SG +8132,Hinteregg +8212,Neuhausen +6345,Neuheim +7107,Safien Platz +9315,Neukirch (Egnach) +9217,Neukirch +4142,Münchenstein +8213,Neunkirch +8252,Schlatt TG +8462,Rheinau +5225,Bözberg +8344,Bäretswil +8566,Neuwilen +1740,Neyruz FR +1515,Neyruz-sur-Moudon +2560,Nidau +2560,Nidau +8803,Rüschlikon +9200,Gossau SG +1714,Heitenried +9630,Wattwil +8772,Nidfurn +1462,Yvonand +8587,Oberaach +4704,Niederbipp +3000,Bern +4626,Niederbuchsiten +9246,Niederbüren +6375,Beckenried +4435,Niederdorf +5015,Erlinsbach SO +3945,Niedergampel +3942,Niedergesteln +8172,Niederglatt ZH +9240,Niederglatt SG +5013,Niedergösgen +8155,Niederhasli +9527,Niederhelfenschwil +8181,Höri +3504,Niederhünigen +5702,Niederlenz +3087,Niedermuhlern +3087,Niedermuhlern +1714,Heitenried +1714,Heitenried +8525,Niederneunforn +3362,Niederönz +3424,Niederösch +6383,Niederrickenbach +3853,Niederried Interl +3283,Niederried b. Kall +5443,Niederrohrdorf +3145,Niederscherli +6288,Schongau +8162,Steinmaur +9249,Niederstetten +3632,Niederstocken +9052,Niederteufen +8867,Niederurnen +9244,Niederuzwil +3989,Niederwald +3172,Niederwangen BE +8166,Niederweningen +3114,Wichtrach +8452,Adlikon +6221,Rickenbach LU +4523,Niederwil SO +9203,Niederwil SG +5524,Niederwil AG +8500,Frauenfeld +1772,Nierlet-les-Bois +1740,Neyruz FR +3711,Mülenen +3960,Niouc +6683,Niva (Vallemaggia) +6746,Nivo +2518,Nods +3976,Noës +3116,Noflen BE +3178,Bösingen +8212,Nohl +2103,Noiraigue +2115,Buttes +1417,Essertines-Yverdon +6915,Pambio-Noranco +1757,Noréaz +1400,Cheseaux-Noréaz +8172,Niederglatt ZH +8610,Uster +9000,St. Gallen +6207,Nottwil +6986,Novaggio +1431,Novalles +6883,Novazzano +1845,Noville +7437,Nufenen +4412,Nuglar +4208,Nunningen +6283,Baldegg +8855,Wangen SZ +8309,Nürensdorf +8843,Oberiberg +8180,Bülach +8537,Nussbaumen TG +5415,Nussbaumen AG +8418,Schlatt +4453,Nusshof +1485,Nuvilly +1260,Nyon +6363,Obbürgen +8587,Oberaach +6315,Oberägeri +6490,Andermatt +6490,Andermatt +9212,Arnegg +6414,Oberarth +3096,Oberbalm +4524,Oberbalmberg +4538,Oberbipp +3780,Gstaad +3000,Bern +5225,Bözberg +4625,Oberbuchsiten +6344,Meierskappel +9245,Oberbüren +3414,Oberburg +3414,Oberburg +9565,Oberbussnang +3088,Oberbütschel +3672,Oberdiessbach +6375,Beckenried +6370,Oberdorf NW +4515,Oberdorf SO +4436,Oberdorf BL +9200,Gossau SG +8105,Watt +8635,Dürnten +9413,Oberegg +8589,Sitterdorf +5420,Ehrendingen +3203,Mühleberg +3618,Süderen +8425,Oberembrach +3948,Oberems +8102,Oberengstringen +5036,Oberentfelden +9434,Au SG +5108,Oberflachs +5073,Gipf-Oberfrick +3551,Oberfrittenbach +4564,Obergerlafingen +3988,Obergesteln +8154,Oberglatt ZH +9230,Flawil +3434,Obergoldbach +4653,Obergösgen +8216,Oberhallau +8156,Oberhasli +9621,Oberhelfenschwil +8335,Hittnau +5062,Oberhof +8488,Turbenthal +5273,Oberhofen AG +9542,Münchwilen TG +3653,Oberhofen Thun'see +8574,Oberhofen TG +3533,Bowil +8636,Wald ZH +8181,Höri +8508,Homburg +3504,Oberhünigen +8843,Oberiberg +6208,Oberkirch LU +4234,Zullwil +4234,Zullwil +5727,Oberkulm +3616,Schwarzenegg +8134,Adliswil +3038,Kirchlindach +8917,Oberlunkhofen +8912,Obfelden +3550,Langnau i. E. +8706,Meilen +1713,St. Antoni +5037,Muhen +4324,Obermumpf +7431,Obermutten +6012,Obernau +8526,Oberneunforn +8472,Seuzach +3363,Oberönz +3424,Oberösch +4588,Oberramsern +6387,Oberrickenbach +3433,Schwanden i. E. +3854,Oberried Brienz +3145,Niederscherli +8942,Oberrieden +1724,Oberried FR +9463,Oberriet SG +9463,Oberriet SG +9604,Oberrindal +9604,Oberrindal +9604,Oberrindal +5452,Oberrohrdorf +3036,Detligen +5647,Oberrüti +7134,Obersaxen Meierhof +9479,Oberschan +3145,Niederscherli +8418,Schlatt +8523,Hagenbuch ZH +6438,Ibach +6288,Schongau +1716,Oberschrot +5415,Nussbaumen AG +5417,Untersiggenthal +8477,Oberstammheim +4924,Obersteckholz +9323,Steinach +8162,Steinmaur +9249,Oberstetten +3632,Oberstocken +8000,Zürich +5085,Sulz AG +8884,Oberterzen +3531,Oberthal +3144,Gasel +8902,Urdorf +8868,Oberurnen +9242,Oberuzwil +3999,Oberwald +8374,Oberwangen TG +3173,Oberwangen b. Bern +8165,Oberweningen +8620,Wetzikon ZH +3114,Wichtrach +8226,Schleitheim +4104,Oberwil BL +8966,Oberwil-Lieli +8500,Frauenfeld +3298,Oberwil b. Büren +8471,Oberwil (Dägerlen) +8309,Nürensdorf +6317,Oberwil b. Zug +3765,Oberwil i. S. +6062,Wilen (Sarnen) +8404,Winterthur +5079,Zeihen +3052,Zollikofen +3052,Zollikofen +8912,Obfelden +6874,Castel San Pietro +6078,Lungern +8758,Obstalden +3367,Ochlenberg +2889,Ocourt +6951,Odogno +4566,Oekingen +4702,Oensingen +8000,Zürich +8461,Oerlingen +3425,Koppigen +4943,Oeschenbach +5072,Oeschgen +3776,Oeschseite +8618,Oetwil am See +8955,Oetwil a.d. Limmat +3753,Oey +7530,Zernez +4665,Oftringen +1045,Ogens +6955,Oggio +6143,Ohmstal +8472,Seuzach +1580,Oleyres +6922,Morcote +6718,Olivone +1867,Ollon VD +3971,Ollon VS +4305,Olsberg +4305,Olsberg +4600,Olten +3036,Detligen +4494,Oltingen +1213,Onex +1756,Onnens FR +1425,Onnens VD +8584,Opfershofen TG +8236,Opfertshofen SH +8152,Opfikon +1047,Oppens +9565,Oppikon +3629,Oppligen +1350,Orbe +6513,Monte Carasso +1430,Orges +6945,Origlio +6713,Malvaglia +4466,Ormalingen +1965,Ormône (Savièse) +1862,Les Mosses +1865,Les Diablerets +1317,Orny +1610,Oron-la-Ville +1608,Oron-le-Châtel +2552,Orpund +6644,Orselina +1937,Orsières +1694,Orsonnens +3042,Ortschwaben +3042,Ortschwaben +2534,Orvin +1413,Orzens +3476,Oschwand +3476,Oschwand +6763,Osco +6703,Osogna +6703,Osogna +7710,Ospizio Bernina +6781,Villa Bedretto +8475,Ossingen +6814,Lamone +8218,Osterfingen +6130,Willisau +8500,Frauenfeld +3036,Detligen +3072,Ostermundigen +8112,Otelfingen +5504,Othmarsingen +8712,Stäfa +8913,Ottenbach +8492,Wila +6275,Ballwil +1738,Sangernboden +8626,Ottikon +8307,Ottikon b.Kemptth. +3257,Grossaffoltern +8561,Ottoberg +1000,Lausanne +1377,Oulens-Echallens +1522,Oulens-sur-Lucens +2950,Courgenay +1911,Ovronnaz +7028,Pagig +1416,Pailly +6657,Palagnedra +1945,Palasuit (Liddes) +1607,Palézieux +1607,Palézieux-Village +6915,Pambio-Noranco +1142,Pampigny +1867,Panex +7243,Pany +3063,Ittigen +8246,Langwiesen +6900,Paradiso +7185,Platta +7212,Seewis-Pardisla +7076,Parpan +7464,Parsonz +7417,Paspels +3988,Ulrichen +7062,Passugg-Araschgen +2353,Les Pommerats +7433,Farden +1094,Paudex +6582,Pianezzo +1530,Payerne +6912,Pazzallo +6695,Peccia +6513,Monte Carasso +6512,Giubiasco +6832,Pedrinate +7110,Peiden +7112,Duvin +7112,Duvin +1242,Satigny +7029,Peist +1242,Satigny +1445,Vuiteboeuf +1059,Peney-le-Jorat +1783,Pensier +1305,Penthalaz +1303,Penthaz +1375,Penthéréaz +6035,Perlen +6035,Perlen +1258,Perly +2742,Perrefitte +2017,Boudry +1166,Perroy +6744,Personico +2603,Péry +2034,Peseux +1052,Mont-sur-Lausanne +1945,Petit Vichères +2740,Moutier +1213,Petit-Lancy +2316,Petit-Martel +2065,Savagnier +1063,Peyres-Possens +7312,Pfäfers +7310,Bad Ragaz +3184,Wünnewil +8118,Pfaffhausen +8330,Pfäffikon ZH +8808,Pfäffikon SZ +6264,Pfaffnau +6034,Inwil +5735,Pfeffikon LU +4148,Pfeffingen +8422,Pfungen +8505,Pfyn +6563,Mesocco +6959,Piandera Paese +6582,Pianezzo +6557,Cama +6557,Cama +6684,Campo (VM) +6695,Piano di Peccia +6579,Piazzogna +1723,Pierrafortscha +2608,Mtgne-Courtelary +2542,Pieterlen +7443,Pignia +7156,Pigniu +1348,Le Brassus +1348,Le Brassus +6010,Pilatus Kulm +1234,Vessy +1234,Vessy +3961,Vissoie +6614,Brissago +6776,Piotta +6776,Piotta +7111,Pitasch +7323,Wangs +1174,Pizy +6833,Vacallo +1716,Plaffeien +2536,Plagne +1200,Genève +2314,La Sagne NE +1867,Panex +1964,Conthey +3855,Brienz BE +2108,Couvet +1815,Clarens +1228,Plan-les-Ouates +1737,Plasselb +7133,Obersaxen Affeier +7185,Platta +9428,Walzenhausen +7517,Plaun da Lej +2807,Pleigne +3951,Agarn +2953,Pleujouse +8889,Plons +3638,Pohlern +6827,Brusino Arsizio +1041,Poliez-le-Grand +1041,Poliez-Pittet +6742,Pollegio +1976,Erde +1318,Pompaples +1405,Pomy +1699,Pont (Veveyse) +1962,Pont-de-la-Morge +1962,Pont-de-la-Morge +1863,Le Sépey +6652,Tegna +6652,Tegna +6946,Ponte Capriasca +6996,Ponte Cremenaga +6988,Ponte Tresa +2733,Pontenet +1772,Ponthaux +6713,Malvaglia +1649,Pont-la-Ville +6724,Ponto Valentino +7504,Pontresina +2900,Porrentruy +1699,Porsel +2562,Port +1568,Portalban +7423,Portein +8895,Flumserberg Portel +6613,Porto Ronco +1897,Bouveret +6948,Porza +1726,Posat +3775,Lenk im Simmental +7742,Poschiavo +1725,Posieux +7745,Li Curt +7063,Praden +7231,Pragg-Jenaz +1408,Prahins +1987,Hérémence +3979,Grône +1197,Prangins +1528,Praratoud +1724,Le Mouret +1947,Versegères +1937,Orsières +6694,Prato-Sornico +6773,Prato (Leventina) +4133,Pratteln +7415,Pratval +1991,Pravidondaz +1944,La Fouly VS +1618,Châtel-St-Denis +1788,Praz (Vully) +7424,Präz +1943,Praz-de-Fort +1982,Euseigne +7482,Preda +2074,Marin-Epagnier +6963,Pregassona +1292,Chambésy +2515,Prêles +1324,Premier +1976,Erde +6523,Preonzo +2608,Mtgne-Courtelary +1243,Presinge +1253,Vandoeuvres +1253,Vandoeuvres +1028,Préverenges +1410,Prévondavaux +1682,Prévonloup +1746,Prez-vers-Noréaz +1677,Prez-vers-Siviriez +1008,Prilly +6760,Calpiogna +1663,Pringy +7741,S. Carlo GR +1912,Produit (Leytron) +1624,Progens +6515,Gudo +1987,Hérémence +1673,Promasens +7440,Andeer +7606,Promontogno +6526,Prosito +1428,Provence +6723,Prugiasco +6823,Pugerna +1070,Puidoux +1070,Puidoux +1009,Pully +7503,Samedan +1241,Puplinge +6984,Pura +6989,Purasca +7447,Am Bach (Avers) +7228,Pusserein +7224,Putz +8883,Quarten +6572,Quartino +8878,Quinten +6777,Quinto +8498,Gibswil +8175,Windlach +7172,Rabius +3271,Radelfingen +9470,Buchs SG +9470,Buchs SG +8197,Rafz +6026,Rain +6060,Ramersberg +8487,Rämismühle +4719,Ramiswil +4433,Ramlinsburg +7556,Ramosch +4448,Läufelfingen +8488,Turbenthal +3435,Ramsei +8262,Ramsen +3421,Lyssach +6862,Rancate +1439,Rances +3928,Randa +3975,Randogne +3439,Ranflüh +3439,Ranflüh +9475,Sevelen +6577,Ranzo +8558,Raperswilen +3255,Rapperswil BE +8640,Rapperswil SG +3942,Raron +6655,Rasa +8352,Elsau +6032,Emmen +8580,Amriswil +6500,Bellinzona +1928,Ravoire +6491,Realp +7408,Realta +2832,Rebeuvelier +2717,Rebévelier +9445,Rebstein +4565,Recherswil +1718,Rechthalten +3966,Réchy +8508,Homburg +3998,Reckingen VS +2912,Réclère +2824,Vicques +2732,Reconvilier +8158,Regensberg +8105,Regensdorf +9038,Rehetobel +3294,Büren an der Aare +7015,Tamins +3713,Reichenbach i. K. +8864,Reichenburg +6260,Reiden +3766,Boltigen +6260,Reidermoos +4418,Reigoldswil +4153,Reinach BL +5734,Reinach AG +7432,Zillis +4919,Reisiswil +5057,Reitnau +5332,Rekingen AG +1617,Remaufens +5453,Remetschwil +5236,Remigen +2616,Renan BE +1020,Renens VD +1024,Ecublens VD +6162,Rengg +1847,Rennaz +1937,Orsières +1543,Grandcour +6285,Retschwil +5703,Seon +2603,Péry +5324,Full-Reuenthal +5412,Gebenstorf +6015,Luzern +5643,Sins +6014,Luzern +3623,Teuffenthal BE +9411,Reute AR +8507,Hörhausen +6086,Hasliberg Reuti +8500,Frauenfeld +9517,Mettlen +3647,Reutigen +8404,Reutlingen +1899,Torgon +1128,Reverolle +7403,Rhäzüns +8462,Rheinau +9424,Rheineck +4310,Rheinfelden +8259,Rheinklingen +5084,Rheinsulz +1632,Riaz +6595,Riazzino +6595,Riazzino +4313,Möhlin +3763,Därstetten +6285,Hitzkirch +6263,Richenthal +3078,Richigen +8805,Richterswil +3178,Bösingen +8726,Ricken SG +8726,Ricken SG +8545,Rickenbach ZH +6221,Rickenbach LU +6432,Rickenbach SZ +4613,Rickenbach SO +4462,Rickenbach BL +5634,Merenschwand +8913,Ottenbach +9532,Rickenbach b. Wil +8352,Ricketwil +1908,Riddes +3724,Ried (Frutigen) +3772,St. Stephan +6476,Intschi +6436,Ried (Muotathal) +3997,Bellwald +3919,Blatten(Lötschen) +3216,Ried b. Kerzers +3082,Schlosswil +3000,Bern +3911,Ried-Brig +8304,Wallisellen +8739,Rieden SG +5415,Rieden AG +3987,Riederalp +3178,Bösingen +8750,Riedern +4533,Riedholz +8616,Riedikon +3986,Ried-Mörel +3159,Riedstätt +8586,Riedt b. Erlen +8173,Neerach +3475,Riedtwil +4125,Riehen +7128,Riein +6452,Riemenstalden +8000,Zürich +8498,Gibswil +8412,Riet (Neftenbach) +9651,Ennetbühl +5323,Rietheim +9000,St. Gallen +1097,Riex +3920,Zermatt +3156,Riffenmatt +8911,Rifferswil +6020,Emmenbrücke +9248,Bichwil +3132,Riggisberg +6356,Rigi Kaltbad +6410,Rigi Klösterli +6410,Rigi Kulm +6410,Rigi Scheidegg +6410,Rigi Staffel +4853,Riken AG +8307,Effretikon +8486,Rikon im Tösstal +3852,Ringgenberg BE +8142,Uitikon Waldegg +3762,Erlenbach i. S. +3656,Ringoldswil +8340,Hinwil +5223,Riniken +7463,Riom +6343,Risch +9548,Matzingen +3989,Ritzingen +8577,Schönholzerswilen +6826,Riva San Vitale +6648,Minusio +1071,Rivaz +1945,Rive Haute(Liddes) +6674,Riveo +6802,Rivera +3206,Rizenbach +6599,Robasacco +8620,Wetzikon ZH +6690,Cavergno +1852,Roche VD +2912,Roche-d'Or +2019,Rochefort +2762,Roches BE +2907,Rocourt +7415,Rodels +4118,Rodersdorf +6772,Rodi-Fiesso +9468,Sax +2814,Roggenburg +6833,Vacallo +6265,Roggliswil +4914,Roggwil BE +9325,Roggwil TG +5032,Aarau Rohr +4655,Rohr b. Olten +4938,Rohrbach +4938,Rohrbachgraben +6132,Rohrmatt +3421,Lyssach +1180,Rolle +1323,Romainmôtier +1423,Romairon +1032,Romanel-s-Lausanne +1122,Romanel-sur-Morges +1626,Romanens +8590,Romanshorn +5022,Rombach +6027,Römerswil LU +1722,Bourguillon +2538,Romont BE +1680,Romont FR +6113,Romoos +7454,Rona +6622,Ronco sopra Ascona +7430,Rongellen +6713,Malvaglia +6037,Root +1088,Ropraz +8427,Rorbas +9400,Rorschach +9404,Rorschacherberg +4244,Röschenz +1754,Rosé +9000,St. Gallen +8500,Gerlikon +3860,Rosenlaui +4000,Basel +9545,Wängi +6548,Rossa +8932,Mettmenstetten +8400,Winterthur +2842,Rossemaison +1513,Rossenges +1728,Rossens FR +1554,Rossens VD +3204,Rosshäusern +1658,Rossinière +9512,Rossrüti +6760,Rossura +3913,Rosswald +5746,Walterswil SO +3373,Röthenbach Hbsee +3538,Röthenbach i. E. +7405,Rothenbrunnen +6023,Rothenburg +4467,Rothenfluh +9565,Rothenhausen +6418,Rothenthurm +3855,Brienz BE +4852,Rothrist +3901,Rothwald +6343,Rotkreuz +9000,St. Gallen +8919,Rottenschwil +6362,Stansstad +1659,Rougemont +1965,Roumaz (Savièse) +6535,Roveredo GR +6957,Roveredo TI +6821,Rovio +1463,Rovray +3113,Rubigen +3268,Lobsigen +6074,Giswil +3437,Rüderswil +8455,Rüdlingen +8465,Rudolfingen +8964,Rudolfstetten +3423,Ersigen +3422,Rüdtligen +1673,Rue +1223,Cologny +3792,Saanen +6288,Schongau +3474,Rüedisbach +6017,Ruswil +3088,Rüeggisberg +3417,Rüegsau +3415,Rüegsauschachen +3415,Rüegsauschachen +3418,Rüegsbach +7189,Rueras +8735,Rüeterswil +7156,Rueun +1626,Rueyres-Treyfayes +1046,Rueyres +1542,Rueyres-les-Prés +1695,Rueyres-St-Laurent +5235,Rüfenach AG +3075,Rüfenacht BE +8723,Rufi +6153,Ufhusen +6153,Ufhusen +8903,Birmensdorf ZH +3953,Leuk Stadt +3472,Rumendingen +6332,Hagendorn +8352,Elsau +5464,Rümikon AG +4539,Rumisberg +8153,Rümlang +3128,Rümligen +8332,Rumlikon +4444,Rümlingen +4497,Rünenberg +3533,Bowil +3204,Rosshäusern +5102,Rupperswil +4663,Aarburg +3251,Ruppoldsried +3153,Rüschegg Gambach +7154,Ruschein +8803,Rüschlikon +8332,Russikon +1281,Russin +6662,Russo +1773,Russy +5644,Auw +6017,Ruswil +9464,Rüthi (Rheintal) +8630,Rüti ZH +3072,Ostermundigen +8782,Rüti GL +9030,Abtwil SG +8185,Winkel +3295,Rüti b. Büren +3421,Rüti b. Lyssach +3099,Rüti b. Riggisberg +5722,Gränichen +5406,Rütihof +6441,Rütli +4933,Rütschelen +8471,Rutschwil +4522,Rüttenen +3052,Zollikofen +6977,Ruvigliana +6577,Ranzo +6592,S. Antonino +7745,Li Curt +6583,S. Antonio +7174,S. Benedetg +6565,S. Bernardino +6690,S. Carlo +6780,Airolo +6575,S. Nazzaro +6854,S. Pietro +6534,S. Vittore +3792,Saanen +3777,Saanenmöser +3908,Saas-Balen +7247,Saas im Prättigau +3905,Saas-Almagell +3908,Saas-Balen +3906,Saas-Fee +3910,Saas-Grund +6072,Sachseln +1996,Saclentse +1212,Grand-Lancy +5745,Safenwil +7107,Safien Platz +7107,Safien Platz +2553,Safnern +6264,Pfaffnau +6839,Sagno +7152,Sagogn +2732,Saicourt +2350,Saignelégier +1913,Saillon +6954,Sala Capriasca +8493,Saland +1585,Salavaux +1867,Ollon VD +8507,Hörhausen +8268,Salenstein +1731,Ependes FR +1625,Sâles (Gruyère) +9465,Salez +3970,Salgesch +1991,Salins +8599,Salmsach +6872,Salorino +7462,Salouf +1922,Salvan +1794,Salvenach +3036,Detligen +7503,Samedan +7563,Samnaun Dorf +8833,Samstagern +7741,S. Carlo GR +1950,Sion +1738,Sangernboden +7057,Langwies +7320,Sargans +3049,Säriswil +5614,Sarmenstorf +7423,Sarn +6060,Sarnen +1948,Sarreyer +1683,Sarzens +1534,Sassel +8507,Hörhausen +1242,Satigny +6417,Sattel +1189,Saubraz +2024,St-Aubin-Sauges +2873,Saulcy +2732,Saules BE +2063,Saules +3054,Schüpfen +1290,Versoix +2065,Savagnier +1073,Savigny +7460,Savognin +6942,Savosa +1095,Lutry +9468,Sax +1926,Fully +3813,Saxeten +8894,Flumserberg Saxli +1907,Saxon +1966,Saxonne (Ayent) +7202,Says +6578,Caviano +6951,Scareglia +2855,Glovelier +8906,Bonstetten +6105,Schachen LU +6105,Schachen LU +6436,Muotathal +4653,Obergösgen +9112,Schachen b.Herisau +9414,Schachen b. Reute +8200,Schaffhausen +3415,Schafhausen i. E. +2514,Ligerz +5503,Schafisheim +8492,Wila +9533,Kirchberg SG +3314,Schalunen +7525,S-chanf +6197,Schangnau +8718,Schänis +7412,Scharans +7550,Scuol +6196,Marbach LU +3722,Scharnachtal +6467,Schattdorf +3860,Schattenhalb +7270,Davos Platz +7421,Summaprada +7419,Scheid +2827,Schelten +6214,Schenkon +2514,Ligerz +5246,Scherz +8596,Scherzingen +3305,Scheunen +3251,Wengi b. Büren +2556,Scheuren +7220,Schiers +5046,Walde AG +8834,Schindellegi +5116,Schinznach Bad +5107,Schinznach Dorf +7168,Schlans +9050,Appenzell Schlatt +8252,Schlatt TG +5316,Leuggern +8418,Schlatt +8255,Schlattingen +8165,Schleinikon +8226,Schleitheim +3325,Hettiswil +6231,Schlierbach +8952,Schlieren +3098,Schliern b. Köniz +5044,Schlossrued +3082,Schlosswil +7151,Schluein +8716,Schmerikon +3464,Schmidigen-Mühlew +8495,Schmidrüti +9565,Schmidshof +5046,Schmiedrued +3185,Schmitten FR +7493,Schmitten (Albula) +7212,Seewis-Schmitten +9444,Diepoldsau +8352,Elsau +7130,Schnaus +5425,Schneisingen +3253,Schnottwil +8581,Schocherswil +8165,Schöfflisdorf +5040,Schöftland +3322,Urtenen-Schönbühl +8585,Schönenbaumgarten +8824,Schönenberg ZH +9215,Schönenberg TG +4124,Schönenbuch +9105,Schönengrund +5012,Schönenwerd +6288,Schongau +8577,Schönholzerswilen +3778,Schönried +4414,Füllinsdorf +8802,Kilchberg ZH +4900,Langenthal +3600,Thun +5642,Mühlau +6055,Alpnach Dorf +3000,Bern +8352,Elsau +6247,Schötz +8580,Amriswil +8862,Schübelbach +7228,Schuders +3535,Schüpbach +3054,Schüpfen +4325,Schupfart +3054,Schüpfen +6170,Schüpfheim +8374,Dussnang +3613,Steffisburg +5326,Schwaderloch +8566,Neuwilen +2556,Schwadernau +9107,Urnäsch +8051,Zürich +3634,Thierachern +8762,Schwanden GL +3855,Schwanden-Brienz +3054,Schüpfen +3657,Schwanden Sigrisw +3433,Schwanden i. E. +8762,Schwändi GL +4953,Schwarzenbach BE +6215,Schwarzenbach LU +9536,Schwarzenbach SG +6103,Schwarzenberg LU +3156,Riffenmatt +3150,Schwarzenburg +3616,Schwarzenegg +3616,Schwarzenegg +3766,Boltigen +4911,Schwarzhäusern +1716,Schwarzsee +1738,Sangernboden +8925,Ebertswil +8506,Lanzenneunforn +4953,Schwarzenbach BE +4953,Schwarzenbach BE +4133,Pratteln +4133,Pratteln +9223,Schweizersholz +9103,Schwellbrunn +9057,Schwende +3757,Schwenden +8486,Rikon im Tösstal +9658,Wildhaus +9405,Wienacht-Tobel +3625,Heiligenschwendi +7325,Schwendi +3624,Schwendibach +8603,Schwerzenbach +6430,Schwyz +3800,Interlaken +6702,Claro +6838,Scudellate +7402,Bonaduz +7550,Scuol +1200,Genève +1554,Sédeilles +6020,Emmenbrücke +7188,Sedrun +8185,Winkel +8052,Zürich +3365,Seeberg +3267,Seedorf BE +6462,Seedorf UR +8607,Aathal-Seegräben +2747,Seehof +6377,Seelisberg +8488,Turbenthal +8400,Winterthur +5707,Seengen +6203,Sempach Station +6423,Seewen SZ +4206,Seewen SO +3256,Seewil +7212,Seewis Dorf +7212,Seewis Dorf +3047,Bremgarten b. Bern +3662,Seftigen +8193,Eglisau +7186,Segnas +2883,Montmelon +1525,Seigneux +1470,Seiry +2888,Seleute +7250,Klosters +3989,Selkingen +8143,Stallikon +6545,Selma +4411,Seltisberg +7189,Rueras +2545,Selzach +1933,Sembrancher +6514,Sementina +6714,Semione +6204,Sempach +6203,Sempach Station +1623,Semsales +1304,Senarclens +1724,Senèdes +8482,Sennhof +4852,Rothrist +8332,Russikon +9466,Sennwald +1975,St-Séverin +7554,Sent +5630,Muri AG +5630,Muri AG +5703,Seon +2857,Montavon +7558,Strada +6834,Morbio Inferiore +1355,Sergey +1607,Palézieux-Village +1412,Valeyres-Ursins +7249,Serneus +7249,Serneus +6982,Agno +6867,Serpiano +2000,Neuchâtel +2037,Montmollin +2037,Montmollin +7272,Davos Clavadel +1077,Servion +6832,Seseglio +6997,Sessa +8472,Seuzach +1541,Sévaz +9475,Sevelen +1141,Sévery +7127,Sevgein +1285,Athenaz (Avusy) +1233,Bernex +7742,Sfazù +7157,Siat +8225,Siblingen +8854,Siebnen +8854,Siebnen +8854,Siebnen +8573,Siegershausen +1255,Veyrier +3960,Sierre +5301,Siggenthal Station +5301,Siggenthal Station +6019,Sigigen +6806,Sigirino +5462,Siglistorf +1172,Bougy-Villars +3534,Signau +1966,Signèse (Ayent) +6951,Signôra +1274,Signy +3655,Sigriswil +6340,Sihlbrugg +6340,Sihlbrugg +6340,Sihlbrugg +8135,Sihlbrugg Station +8135,Sihlwald +6473,Silenen +7411,Sils im Domleschg +7515,Sils/Segl Baselgia +7515,Sils/Segl Baselgia +7514,Sils/Segl Maria +7513,Silvaplana +7513,Silvaplana-Surlej +3907,Simplon Hospiz +3907,Simplon Dorf +3067,Boll +5643,Sins +1950,Sion +8370,Sirnach +2577,Siselen BE +6452,Sisikon +4450,Sissach +4334,Sisseln AG +8589,Sitterdorf +9220,Bischofszell +8495,Schmidrüti +1997,Siviez (Nendaz) +1678,Siviriez +6562,Soazza +6749,Sobrio +7610,Soglio +1882,Gryon +6600,Solduno +8197,Rafz +7450,Tiefencastel +4500,Solothurn +4500,Solothurn +4500,Solothurn +6872,Somazzo +2605,Sonceboz-Sombeval +6674,Someo +1937,Orsières +1688,Sommentier +4444,Rümlingen +4444,Rümlingen +8580,Sommeri +2605,Sonceboz-Sombeval +9507,Stettfurt +8311,Brütten +9245,Sonnental +6637,Sonogno +8564,Sonterswil +7130,Ilanz +6968,Sonvico +2615,Sonvilier +1822,Chernex +8134,Adliswil +8762,Sool +6964,Davesco-Soragno +1286,Soral +6174,Sörenberg +6802,Rivera +6924,Sorengo +1642,Sorens +9213,Hauptwil +6802,Rivera +1997,Sornard (Nendaz) +2716,Sornetan +6694,Prato-Sornico +2736,Sorvilier +1062,Sottens +2887,Soubey +1937,Orsières +2864,Soulce +3961,Vissoie +2805,Soyhières +7553,Tarasp +9042,Speicher +9037,Speicherschwendi +3204,Rosshäusern +3095,Spiegel b. Bern +3700,Spiez +3700,Spiez +3700,Spiez +7502,Bever +3270,Aarberg +3803,Beatenberg +6464,Spiringen +8590,Romanshorn +2516,Lamboing +8816,Hirzel +7435,Splügen +7078,Lenzerheide/Lai +8957,Spreitenbach +6663,Spruga +4000,Basel +1713,St. Antoni +7246,St. Antönien +4126,Bettingen +6212,St. Erhard +9000,St. Gallen +9000,St. Gallen +8735,St. Gallenkappel +9000,St. Gallen +1965,St-Germain +3942,St. German +6372,Ennetmoos +4000,Basel +2525,Le Landeron +9030,St. Josefen +8253,Diessenhofen +9620,Lichtensteig +7304,Maienfeld +7304,Maienfeld +9543,St. Margarethen TG +9430,St. Margrethen SG +7313,St. Margrethenberg +7116,St. Martin +7500,St. Moritz +7500,St. Moritz +4532,Feldbrunnen +3924,St. Niklaus VS +3425,Koppigen +3274,Hermrigen +3274,Hermrigen +6005,St. Niklausen LU +6066,St. Niklausen OW +4421,St. Pantaleon +9225,St. Pelagiberg +7028,St. Peter +3235,Erlach +9127,St. Peterzell +1736,St. Silvester +3772,St. Stephan +4915,St. Urban +1717,St. Ursen +3186,Düdingen +6546,Cauco +6541,Sta. Maria +7536,Sta. Maria V. M. +2540,Grenchen +9422,Staad SG +9422,Staad SG +6855,Stabio +9320,Stachen +8272,Ermatingen +8404,Stadel(Winterthur) +8174,Stadel +6383,Dallenwil +8712,Stäfa +5053,Staffelbach +6063,Stalden (Sarnen) +3922,Stalden VS +3932,Visperterminen +3510,Konolfingen +3510,Konolfingen +3933,Staldenried +8143,Stallikon +7605,Stampa +6370,Stans +6362,Stansstad +5452,Oberrohrdorf +9656,Alt St. Johann +8717,Benken SG +4656,Starrkirch-Wil +1566,St-Aubin FR +2024,St-Aubin-Sauges +5603,Staufen +1040,St-Barthélemy VD +2072,St-Blaise +2364,St-Brais +1264,St-Cergue +1410,St-Cierges +1117,Grancy +1117,Grancy +3824,Stechelberg +8266,Steckborn +1450,Ste-Croix +3613,Steffisburg +3612,Steffisburg +3940,Steg VS +8496,Steg im Tösstal +8543,Bertschikon +9503,Stehrenberg +8354,Hofstetten ZH +9063,Stein AR +9655,Stein SG +4332,Stein AG +8260,Stein am Rhein +9323,Steinach +9314,Steinebrunn +9050,Appenzell Steinegg +8536,Hüttwilen +9320,Frasnacht +9320,Frasnacht +6422,Steinen +3534,Signau +3534,Signau +8499,Sternenberg +8492,Wila +6416,Steinerberg +3860,Meiringen +3995,Steinhaus +6312,Steinhausen +4556,Steinhof SO +6114,Steinhuserberg +8162,Steinmaur +7226,Stels +8499,Sternenberg +8600,Dübendorf +8234,Stetten SH +5608,Stetten AG +9507,Stettfurt +3066,Stettlen +1188,St-George +1213,Petit-Lancy +1898,St-Gingolph +7459,Stierva +5233,Stilli +2610,St-Imier +3961,St-Jean VS +1806,St-Légier-Chiésaz +1958,St-Léonard +1176,St-Livres +1318,Pompaples +3961,St-Luc +1609,St-Martin FR +1969,St-Martin VS +2054,Chézard-St-Martin +1424,Champagne +1890,St-Maurice +1222,Vésenaz +3632,Niederstocken +8842,Unteriberg +6433,Stoos SZ +1187,St-Oyens +1955,St-Pierre-Clages +1162,St-Prex +7558,Strada +8500,Frauenfeld +3600,Thun +4802,Strengelbach +8514,Amlikon-Bissegg +1966,St-Romain (Ayent) +1071,St-Saphorin-Lavaux +1113,St-Saphorin-Morges +1975,St-Séverin +1025,St-Sulpice VD +2123,St-Sulpice NE +1867,St-Triphon +3037,Herrenschwanden +3037,Herrenschwanden +8845,Studen SZ +9472,Grabs +2557,Studen BE +7482,Stugl/Stuls +2882,St-Ursanne +4655,Stüsslingen +3262,Suberg +4553,Subingen +1433,Suchy +3618,Süderen +1969,Suen (St-Martin) +7434,Sufers +1786,Sugiez +1043,Sugnens +5034,Suhr +6997,Sessa +8583,Sulgen +1036,Sullens +8545,Rickenbach Sulz +6284,Sulz LU +5085,Sulz AG +5444,Künten +8614,Sulzbach +3454,Sumiswald +7421,Summaprada +7175,Sumvitg +3800,Sundlauenen +8162,Sünikon +7456,Sur +7554,Sent +7472,Surava +7115,Surcasti +7138,Surcuolm +6953,Lugaggia +3204,Rosshäusern +7148,Surin +1528,Surpierre +7173,Surrein +6210,Sursee +6210,Sursee +6210,Sursee +7526,Cinuos-chel +1437,Suscévaz +7542,Susch +3952,Susten +2572,Sutz +1510,Syens +8492,Wila +1712,Tafers +8317,Tagelswangen +5522,Tägerig +6473,Silenen +9554,Tägerschen +3111,Tägertschi +8274,Tägerwilen +7015,Tamins +1896,Miex +8356,Ettenhausen TG +8632,Tann +6214,Schenkon +6214,Schenkon +1295,Tannay +8820,Wädenswil +8374,Dussnang +3068,Utzigen +8603,Schwerzenbach +8898,Flumserberg Tboden +8898,Flumserberg Tboden +8897,Flumserberg Theim +7553,Tarasp +7422,Tartar +1180,Tartegnin +3929,Täsch +1617,Tatroz +2575,Täuffelen +7162,Tavanasa +2710,Tavannes +6807,Taverne +4492,Tecknau +5306,Tegerfelden +6652,Tegna +3714,Frutigen +6598,Tenero +6760,Rossura +7173,Surrein +7106,Tenna +4456,Tenniken +5617,Tennwil +1734,Tentlingen +3912,Termen +6998,Termine +1820,Territet +7116,Tersnaus +6950,Tesserete +2052,La Vue-des-Alpes +8428,Teufen ZH +9053,Teufen AR +5723,Teufenthal AG +3623,Teuffenthal BE +9425,Thal +3432,Lützelflüh-Goldb +3432,Lützelflüh-Goldb +5112,Thalheim AG +8478,Thalheim +7109,Thalkirch +8800,Thalwil +8240,Thayngen +8484,Theilingen +4106,Therwil +2075,Thielle +3634,Thierachern +1410,Thierrens +8762,Schwanden GL +1226,Thônex +3326,Krauchthal +3367,Thörigen +3174,Thörishaus +3174,Thörishaus +3600,Thun +8512,Thundorf +4922,Thunstetten +4441,Thürnen +7430,Thusis +1988,Thyon +3000,Bern +7450,Tiefencastel +7453,Tinizong +4425,Titterten +8634,Hombrechtikon +9405,Wienacht-Tobel +9555,Tobel +3125,Toffen +8352,Elsau +1131,Tolochenaz +8577,Schönholzerswilen +3923,Törbel +1899,Torgon +1748,Torny-le-Grand +1749,Middes +6717,Torre +3954,Leukerbad +6808,Torricella +8400,Winterthur +8193,Eglisau +8912,Obfelden +3456,Trachselwald +3456,Trachselwald +8840,Trachslau +2720,Tramelan +8766,Matt +7407,Trans +8219,Trasadingen +2105,Travers +6957,Roveredo TI +6377,Seelisberg +3226,Treiten +1525,Henniez +1270,Trélex +6865,Tremona +1552,Trey +1436,Treycovagnes +1626,Treyfayes +1096,Cully +1538,Treytorrens-Payern +1733,Treyvaux +8273,Triboltingen +8000,Zürich +6234,Triengen +1929,Trient +4632,Trimbach +7203,Trimmis +3083,Trimstein +7014,Trin +7014,Trin +9043,Trogen +1969,Trogne (St-Martin) +1256,Troinex +1256,Troinex +1068,Les Monts-de-Pully +1872,Troistorrents +3556,Trub +9477,Trübbach +3555,Trubschachen +8466,Trüllikon +7166,Trun +8467,Truttikon +8524,Uesslingen +8843,Oberiberg +7189,Rueras +7136,Obers Friggahüs +7428,Tschappina +4576,Tscheppach +8881,Tscherlach +7064,Tschiertschen +7532,Tschierv +3656,Tschingel +7559,Tschlin +3233,Tschugg +9327,Tübach +9604,Lütisburg +3178,Bösingen +8856,Tuggen +7188,Sedrun +7418,Tumegl/Tomils +3781,Turbach +8488,Turbenthal +5300,Turgi +1991,Turin (Salins) +8915,Hausen am Albis +3942,Raron +3946,Turtmann +2512,Tüscherz-Alfermée +7135,Obersaxen Giraniga +9546,Tuttwil +2513,Twann +2516,Lamboing +6122,Menznau +6044,Udligenswil +3182,Ueberstorf +5237,Mönthal +3635,Uebeschi +1700,Fribourg +5028,Ueken +8712,Stäfa +8713,Uerikon +4813,Uerkheim +8537,Uerschhausen +8926,Uerzlikon +8124,Maur +8524,Uesslingen +3661,Uetendorf +3661,Uetendorf +8707,Uetikon am See +8143,Uetliberg +8738,Uetliburg SG +3043,Uettligen +5619,Uezwil +8808,Pfäffikon SZ +6253,Uffikon +6153,Ufhusen +8142,Uitikon Waldegg +9631,Ulisbach +3214,Ulmiz +3988,Ulrichen +7536,Sta. Maria V. M. +5222,Umiken +3792,Saanen +2863,Undervelier +6314,Unterägeri +3857,Unterbach BE +3944,Unterbäch VS +9404,Rorschacherberg +5225,Bözberg +8589,Sitterdorf +9033,Untereggen +5420,Ehrendingen +3948,Unterems +5305,Unterendingen +8103,Unterengstringen +5035,Unterentfelden +8570,Weinfelden +8570,Weinfelden +3857,Unterbach BE +8508,Homburg +8842,Unteriberg +5726,Unterkulm +3614,Unterlangenegg +9300,Wittenbach +8918,Unterlunkhofen +8912,Obfelden +8472,Seuzach +4588,Unterramsern +7408,Realta +9604,Unterrindal +5634,Merenschwand +6465,Unterschächen +8418,Schlatt +6440,Brunnen +3800,Unterseen +5417,Untersiggenthal +5417,Untersiggenthal +8476,Unterstammheim +4916,Untersteckholz +8000,Zürich +8882,Unterterzen +7204,Untervaz +7201,Untervaz Bahnhof +7201,Untervaz Bahnhof +9657,Unterwasser +3999,Oberwald +3052,Zollikofen +7114,Uors (Lumnezia) +8902,Urdorf +6465,Unterschächen +7427,Urmein +9107,Urnäsch +8751,Urnerboden +3510,Konolfingen +4937,Ursenbach +1412,Ursins +5225,Bözberg +6280,Urswil +1670,Ursy +3322,Urtenen-Schönbühl +8864,Reichenburg +8864,Reichenburg +8610,Uster +8934,Knonau +3628,Uttigen +8592,Uttwil +3427,Utzenstorf +3068,Utzigen +1958,Uvrier +8730,Uznach +8730,Uznach +8730,Uznach +9240,Uzwil +3978,Flanthey +6833,Vacallo +7314,Vadura +6947,Vaglio +6575,Vairano +7741,S. Carlo GR +7554,Sent +2042,Valangin +7138,Surcuolm +1293,Bellevue +7077,Valbella +7535,Valchava +6951,Scareglia +1873,Val-d'Illiez +7132,Vals +3978,Flanthey +7122,Valendas +7317,Valens +1441,Valeyres-Montagny +1358,Valeyres-Rances +1412,Valeyres-Ursins +1586,Vallamand +1586,Vallamand +7553,Tarasp +6780,Airolo +1565,Vallon +1337,Vallorbe +7132,Vals +7213,Valzeina +1922,Salvan +1922,Salvan +1253,Vandoeuvres +3953,Varen +6777,Varenzo +7317,Vasön +7315,Vättis +7146,Vattiz +1675,Vauderens +2537,Vauffelin +1423,Vaugondry +1325,Vaulion +1627,Vaulruz +2028,Vaumarcus +2354,Goumois +1126,Vaux-sur-Morges +7082,Vaz/Obervaz +7084,Brienz/Brinzauls +3067,Boll +1251,Gy +7144,Vella +6583,S. Antonio +2830,Vellerat +8400,Winterthur +5106,Veltheim AG +2943,Vendlincourt +1000,Lausanne +1933,Vens(Sembrancher) +3973,Venthône +1936,Verbier +3967,Vercorin +6538,Verdabbio +6655,Verdasio +6664,Vergeletto +1937,Orsières +3963,Crans-Montana +2829,Vermes +8886,Mädris-Vermol +1961,Vernamiège +1033,Cheseaux-Lausanne +1032,Romanel-s-Lausanne +6992,Vernate +1904,Vernayaz +2028,Vaumarcus +1820,Montreux +1214,Vernier +1214,Vernier +1891,Vérossaz +1420,Fiez +1926,Fully +7104,Versam +7104,Versam +1450,Ste-Croix +1000,Lausanne 26 +1551,Vers-chez-Perrin +6653,Verscio +1947,Versegères +1864,Vers-l'Eglise +1853,Yvorne +1290,Versoix +1290,Versoix +1290,Versoix +1852,Roche VD +1222,Vésenaz +1222,Vésenaz +1483,Vesin +1234,Vessy +1963,Vétroz +1800,Vevey +1981,Vex +3968,Veyras +1255,Veyrier +1993,Veysonnaz +1993,Veysonnaz +1820,Veytaux +6943,Vezia +6938,Vezio +7747,Viano +1267,Vich +1945,Vichères (Liddes) +6921,Vico Morcote +7603,Vicosoprano +2824,Vicques +3075,Vielbringen Worb +6962,Viganello +6763,Osco +7147,Vignogn +2063,Vilars NE +6781,Villa Bedretto +6877,Coldrerio +1966,Villa (Ayent) +6966,Villa Luganese +1673,Ecublens FR +1679,Villaraboud +1678,Siviriez +1652,Villarbeney +1148,Villars-Bozon +1832,Villard-sur-Chamby +1583,Villarepos +1432,Belmont-Yverdon +1774,Cousset +1694,Villargiroud +1685,Villariaz +1691,Villarimboud +1695,Villarlod +1682,Villars-Bramard +1423,Villars-Burquin +1695,Villarsel-Gibloux +1723,Villarsel-Marly +1404,Villars-Epeney +1694,Villarsiviriaux +1515,Villars-le-Comte +1584,Villars-le-Grand +1700,Fribourg +1040,Villars-le-Terroir +1307,Lussery-Villars +1061,Villars-Mendraz +1443,Villars-Champvent +1666,Villars-sous-Mont +1168,Villars-sous-Yens +1029,Villars-Ste-Croix +2903,Villars-Fontenais +1752,Villars-sur-Glâne +1884,Villars-sur-Ollon +1058,Villars-Tiercelin +1651,Villarvolard +1555,Villarzel +1985,Villa (Evolène) +1690,Villaz-St-Pierre +1527,Villeneuve FR +1844,Villeneuve VD +2613,Villeret +1934,Le Châble VS +1225,Chêne-Bourg +1096,Villette (Lavaux) +2057,Villiers +5234,Villigen +5612,Villmergen +5213,Villnachern +1867,Ollon VD +7324,Vilters +1182,Gilly +3234,Vinelz +2500,Biel/Bienne +1184,Vinzel +1895,Vionnaz +6805,Mezzovico +6574,Vira (Gambarogno) +1239,Collex +1239,Collex +1906,Charrat +3930,Visp +3932,Visperterminen +3961,Vissoie +6354,Vitznau +7557,Vnà +6663,Comologno +3255,Rapperswil BE +5426,Lengnau AG +5412,Vogelsang AG +6632,Vogorno +8459,Volken +8604,Volketswil +1941,Vollèges +8915,Hausen am Albis +4803,Vordemwald +3089,Hinterfultigen +9033,Untereggen +3412,Heimiswil +3418,Rüegsbach +8857,Vorderthal +3257,Grossaffoltern +1896,Vouvry +7149,Vrin +1628,Vuadens +1616,Attalens +1820,Montreux +1674,Vuarmarens +1418,Vuarrens +1418,Vuarrens +1509,Vucherens +1302,Vufflens-la-Ville +1134,Vufflens-Château +1431,Vugelles-La Mothe +1610,Vuibroye +1633,Vuippens +1486,Vuissens +1687,Vuisternens-Romont +1696,Vuisternens-Ogoz +1445,Vuiteboeuf +1085,Vulliens +1115,Vullierens +7552,Vulpera +8842,Unteriberg +3084,Wabern +3618,Süderen +3476,Oschwand +8820,Wädenswil +8646,Wagen +8259,Wagenhausen +8564,Wagerswil +4246,Wahlen b. Laufen +3046,Wahlendorf +1738,Sangernboden +3150,Schwarzenburg +6318,Walchwil +8636,Wald ZH +6034,Inwil +9044,Wald AR +9105,Schönengrund +8727,Walde SG +5046,Walde AG +3803,Beatenberg +8142,Uitikon Waldegg +4437,Waldenburg +3432,Lützelflüh-Goldb +5624,Waldhäusern AG +8564,Wäldi +9205,Waldkirch +9104,Waldstatt +8880,Walenstadt +8881,Walenstadtberg +3512,Walkringen +4323,Wallbach +3206,Wallenbuch +1784,Wallenried +5636,Benzenschwil +8360,Wallenwil +8330,Pfäffikon ZH +8304,Wallisellen +3380,Walliswil-Nbipp +3377,Walliswil b.Wangen +3272,Walperswil +8468,Waltalingen +7158,Waltensburg/Vuorz +5622,Waltenschwil +8418,Schlatt +4942,Walterswil BE +5746,Walterswil SO +8126,Zumikon +3463,Häusernmoos +3251,Wengi b. Büren +9428,Walzenhausen +9428,Walzenhausen +3615,Heimenschwand +8855,Wangen SZ +3380,Wangen an der Aare +8602,Wangen ZH +4612,Wangen b. Olten +3374,Wangenried +9545,Wängi +7323,Wangs +3372,Wanzwil +9478,Azmoos +8532,Warth +8165,Oberweningen +3457,Wasen im Emmental +6484,Wassen UR +9057,Wasserauen +9620,Lichtensteig +6084,Hasliberg Wasserw +8195,Wasterkingen +8105,Watt +3665,Wattenwil +3076,Worb +9630,Wattwil +6242,Wauwil +6243,Egolzwil +2075,Wavre +8532,Weiningen TG +8570,Weinfelden +8872,Weesen +4317,Wegenstetten +6353,Weggis +8187,Weiach +3462,Weier im Emmental +9523,Züberwangen +9547,Wittenwil +8570,Weinfelden +9508,Weingarten-Kalth +8104,Weiningen ZH +8532,Weiningen TG +4936,Kleindietwil +9057,Weissbad +9057,Weissbad +3766,Boltigen +5632,Buttwil +3000,Bern +3764,Weissenburg +3764,Weissenburg +3919,Blatten(Lötschen) +3045,Meikirch +3045,Meikirch +4515,Weissenstein +8484,Weisslingen +7326,Weisstannen +9476,Weite +9515,Hosenruck +8494,Bauma +8500,Frauenfeld +8552,Felben-Wellhausen +4716,Welschenrohr +8474,Dinhard +3823,Wengen +3251,Wengi b. Büren +3714,Wengi b. Frutigen +1715,Alterswil FR +4493,Wenslingen +8354,Hofstetten ZH +8919,Rottenschwil +9470,Werdenberg +3273,Kappelen +7433,Wergenstein +8615,Wermatswil +8342,Wernetshausen +8606,Nänikon +6106,Werthenstein +6106,Werthenstein +5430,Wettingen +4000,Basel +8907,Wettswil +8620,Wetzikon ZH +8512,Wetzikon TG +3036,Detligen +8967,Widen +5425,Schneisingen +4522,Rüttenen +9443,Widnau +9443,Widnau +8000,Zürich +4537,Wiedlisbach +9405,Wienacht-Tobel +3255,Rapperswil BE +7494,Davos Wiesen +6383,Wiesenberg +8542,Wiesendangen +8262,Ramsen +8372,Wiezikon b.Sirnach +9621,Oberhelfenschwil +6192,Wiggen +3053,Wiggiswil +5637,Beinwil (Freiamt) +8556,Wigoltingen +3512,Walkringen +4806,Wikon +8196,Wil ZH +6436,Muotathal +9500,Wil SG +5276,Wil AG +8600,Dübendorf +4656,Starrkirch-Wil +5300,Turgi +8492,Wila +8217,Wilchingen +8489,Wildberg +5103,Wildegg +8465,Wildensbuch +3812,Wilderswil +9658,Wildhaus +3928,Randa +6062,Wilen (Sarnen) +9100,Herisau +9428,Walzenhausen +9225,Wilen (Gottshaus) +8535,Herdern +8525,Wilen b. Neunforn +8525,Wilen b. Neunforn +9535,Wilen b. Wil +8832,Wilen b. Wollerau +8427,Rorbas +6482,Gurtnellen +4252,Bärschwil +3918,Wiler (Lötschen) +3266,Wiler b. Seedorf +3428,Wiler b.Utzenstorf +1714,Heitenried +3207,Wileroltigen +5058,Wiliberg +6236,Wilihof +3425,Willadingen +8846,Willerzell +3860,Meiringen +8618,Oetwil am See +6130,Willisau +8253,Willisdorf +3752,Wimmis +9315,Winden +5210,Windisch +8175,Windlach +2513,Twann +6235,Winikon +4558,Winistorf +8185,Winkel +9015,St. Gallen +8312,Winterberg ZH +5647,Oberrüti +5647,Oberrüti +5637,Beinwil (Freiamt) +4451,Wintersingen +8400,Winterthur +4652,Winznau +8000,Zürich +6383,Wirzweli +4634,Wisen SO +5463,Wislikofen +8000,Zürich +9300,Wittenbach +9547,Wittenwil +4108,Witterswil +9430,St. Margrethen SG +4443,Wittinsburg +5064,Wittnau +5053,Wittwil +3236,Gampelen +3033,Wohlen b. Bern +5610,Wohlen AG +3033,Wohlen b. Bern +5512,Wohlenschwil +6386,Wolfenschiessen +9116,Wolfertswil +7265,Davos Wolfgang +9427,Wolfhalden +9427,Wolfhalden +8633,Wolfhausen +9533,Kirchberg SG +8514,Amlikon-Bissegg +4704,Wolfisberg +5063,Wölflinswil +3036,Detligen +4628,Wolfwil +6110,Wolhusen +6110,Wolhusen +8832,Wollerau +8000,Zürich +8912,Obfelden +3076,Worb +3252,Worben +3048,Worblaufen +3048,Worblaufen +5012,Wöschnau +8400,Winterthur +3184,Wünnewil +9514,Wuppenau +5303,Würenlingen +5436,Würenlos +3862,Innertkirchen +4923,Wynau +3472,Wynigen +4954,Wyssachen +4934,Madiswil +1169,Yens +1981,Vex +1400,Yverdon-les-Bains +1462,Yvonand +1853,Yvorne +7748,Campascio +7107,Safien Platz +3309,Zauggenried +3532,Zäziwil +4495,Zeglingen +5079,Zeihen +4314,Zeiningen +9427,Wolfhalden +8487,Zell ZH +6144,Zell LU +1724,Zénauva +3934,Zeneggen +3920,Zermatt +7530,Zernez +5732,Zetzwil +9556,Zezikon +4417,Ziefen +8866,Ziegelbrücke +8866,Ziegelbrücke +3054,Schüpfen +4564,Zielebach +7167,Zignau +3238,Gals +8588,Zihlschlacht +7432,Zillis +8604,Volketswil +3255,Rapperswil BE +3086,Zimmerwald +3961,Zinal +7205,Zizers +4800,Zofingen +3436,Zollbrück +3436,Zollbrück +1716,Schwarzsee +8125,Zollikerberg +3052,Zollikofen +8702,Zollikon +8702,Zollikon +7082,Vaz/Obervaz +8585,Zuben +9523,Züberwangen +4528,Zuchwil +9526,Zuckenriet +5621,Zufikon +6300,Zug +6300,Zugerberg +4234,Zullwil +1713,St. Antoni +1719,Zumholz +8126,Zumikon +8543,Bertschikon +4455,Zunzgen +7557,Vnà +7524,Zuoz +9107,Urnäsch +8000,Zürich +4315,Zuzgen +3303,Zuzwil BE +9524,Zuzwil SG +8192,Zweidlen +3815,Zweilütschinen +3770,Zweisimmen +3645,Zwieselberg +8909,Zwillikon +4222,Zwingen +3907,Gondo +3756,Zwischenflüh diff --git a/spec/controllers/cities_autocomplete_controller_spec.rb b/spec/controllers/cities_autocomplete_controller_spec.rb new file mode 100644 index 0000000..f59ee0d --- /dev/null +++ b/spec/controllers/cities_autocomplete_controller_spec.rb @@ -0,0 +1,12 @@ +require 'rails_helper' + +describe CitiesAutocompleteController do + describe 'GET index' do + it 'searchs for cities' do + get :index, query: 'spei', format: :js + + result = JSON.parse response.body + expect(result).to eq [{ 'plz' => '9042', 'city' => 'Speicher' }, { 'plz' => '9037', 'city' => 'Speicherschwendi' }] + end + end +end diff --git a/vendor/assets/javascripts/typeahead.bundle.js b/vendor/assets/javascripts/typeahead.bundle.js new file mode 100644 index 0000000..bb0c8ae --- /dev/null +++ b/vendor/assets/javascripts/typeahead.bundle.js @@ -0,0 +1,2451 @@ +/*! + * typeahead.js 0.11.1 + * https://github.com/twitter/typeahead.js + * Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT + */ + +(function(root, factory) { + if (typeof define === "function" && define.amd) { + define("bloodhound", [ "jquery" ], function(a0) { + return root["Bloodhound"] = factory(a0); + }); + } else if (typeof exports === "object") { + module.exports = factory(require("jquery")); + } else { + root["Bloodhound"] = factory(jQuery); + } +})(this, function($) { + var _ = function() { + "use strict"; + return { + isMsie: function() { + return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false; + }, + isBlankString: function(str) { + return !str || /^\s*$/.test(str); + }, + escapeRegExChars: function(str) { + return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); + }, + isString: function(obj) { + return typeof obj === "string"; + }, + isNumber: function(obj) { + return typeof obj === "number"; + }, + isArray: $.isArray, + isFunction: $.isFunction, + isObject: $.isPlainObject, + isUndefined: function(obj) { + return typeof obj === "undefined"; + }, + isElement: function(obj) { + return !!(obj && obj.nodeType === 1); + }, + isJQuery: function(obj) { + return obj instanceof $; + }, + toStr: function toStr(s) { + return _.isUndefined(s) || s === null ? "" : s + ""; + }, + bind: $.proxy, + each: function(collection, cb) { + $.each(collection, reverseArgs); + function reverseArgs(index, value) { + return cb(value, index); + } + }, + map: $.map, + filter: $.grep, + every: function(obj, test) { + var result = true; + if (!obj) { + return result; + } + $.each(obj, function(key, val) { + if (!(result = test.call(null, val, key, obj))) { + return false; + } + }); + return !!result; + }, + some: function(obj, test) { + var result = false; + if (!obj) { + return result; + } + $.each(obj, function(key, val) { + if (result = test.call(null, val, key, obj)) { + return false; + } + }); + return !!result; + }, + mixin: $.extend, + identity: function(x) { + return x; + }, + clone: function(obj) { + return $.extend(true, {}, obj); + }, + getIdGenerator: function() { + var counter = 0; + return function() { + return counter++; + }; + }, + templatify: function templatify(obj) { + return $.isFunction(obj) ? obj : template; + function template() { + return String(obj); + } + }, + defer: function(fn) { + setTimeout(fn, 0); + }, + debounce: function(func, wait, immediate) { + var timeout, result; + return function() { + var context = this, args = arguments, later, callNow; + later = function() { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + } + }; + callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if (callNow) { + result = func.apply(context, args); + } + return result; + }; + }, + throttle: function(func, wait) { + var context, args, timeout, result, previous, later; + previous = 0; + later = function() { + previous = new Date(); + timeout = null; + result = func.apply(context, args); + }; + return function() { + var now = new Date(), remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0) { + clearTimeout(timeout); + timeout = null; + previous = now; + result = func.apply(context, args); + } else if (!timeout) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }, + stringify: function(val) { + return _.isString(val) ? val : JSON.stringify(val); + }, + noop: function() {} + }; + }(); + var VERSION = "0.11.1"; + var tokenizers = function() { + "use strict"; + return { + nonword: nonword, + whitespace: whitespace, + obj: { + nonword: getObjTokenizer(nonword), + whitespace: getObjTokenizer(whitespace) + } + }; + function whitespace(str) { + str = _.toStr(str); + return str ? str.split(/\s+/) : []; + } + function nonword(str) { + str = _.toStr(str); + return str ? str.split(/\W+/) : []; + } + function getObjTokenizer(tokenizer) { + return function setKey(keys) { + keys = _.isArray(keys) ? keys : [].slice.call(arguments, 0); + return function tokenize(o) { + var tokens = []; + _.each(keys, function(k) { + tokens = tokens.concat(tokenizer(_.toStr(o[k]))); + }); + return tokens; + }; + }; + } + }(); + var LruCache = function() { + "use strict"; + function LruCache(maxSize) { + this.maxSize = _.isNumber(maxSize) ? maxSize : 100; + this.reset(); + if (this.maxSize <= 0) { + this.set = this.get = $.noop; + } + } + _.mixin(LruCache.prototype, { + set: function set(key, val) { + var tailItem = this.list.tail, node; + if (this.size >= this.maxSize) { + this.list.remove(tailItem); + delete this.hash[tailItem.key]; + this.size--; + } + if (node = this.hash[key]) { + node.val = val; + this.list.moveToFront(node); + } else { + node = new Node(key, val); + this.list.add(node); + this.hash[key] = node; + this.size++; + } + }, + get: function get(key) { + var node = this.hash[key]; + if (node) { + this.list.moveToFront(node); + return node.val; + } + }, + reset: function reset() { + this.size = 0; + this.hash = {}; + this.list = new List(); + } + }); + function List() { + this.head = this.tail = null; + } + _.mixin(List.prototype, { + add: function add(node) { + if (this.head) { + node.next = this.head; + this.head.prev = node; + } + this.head = node; + this.tail = this.tail || node; + }, + remove: function remove(node) { + node.prev ? node.prev.next = node.next : this.head = node.next; + node.next ? node.next.prev = node.prev : this.tail = node.prev; + }, + moveToFront: function(node) { + this.remove(node); + this.add(node); + } + }); + function Node(key, val) { + this.key = key; + this.val = val; + this.prev = this.next = null; + } + return LruCache; + }(); + var PersistentStorage = function() { + "use strict"; + var LOCAL_STORAGE; + try { + LOCAL_STORAGE = window.localStorage; + LOCAL_STORAGE.setItem("~~~", "!"); + LOCAL_STORAGE.removeItem("~~~"); + } catch (err) { + LOCAL_STORAGE = null; + } + function PersistentStorage(namespace, override) { + this.prefix = [ "__", namespace, "__" ].join(""); + this.ttlKey = "__ttl__"; + this.keyMatcher = new RegExp("^" + _.escapeRegExChars(this.prefix)); + this.ls = override || LOCAL_STORAGE; + !this.ls && this._noop(); + } + _.mixin(PersistentStorage.prototype, { + _prefix: function(key) { + return this.prefix + key; + }, + _ttlKey: function(key) { + return this._prefix(key) + this.ttlKey; + }, + _noop: function() { + this.get = this.set = this.remove = this.clear = this.isExpired = _.noop; + }, + _safeSet: function(key, val) { + try { + this.ls.setItem(key, val); + } catch (err) { + if (err.name === "QuotaExceededError") { + this.clear(); + this._noop(); + } + } + }, + get: function(key) { + if (this.isExpired(key)) { + this.remove(key); + } + return decode(this.ls.getItem(this._prefix(key))); + }, + set: function(key, val, ttl) { + if (_.isNumber(ttl)) { + this._safeSet(this._ttlKey(key), encode(now() + ttl)); + } else { + this.ls.removeItem(this._ttlKey(key)); + } + return this._safeSet(this._prefix(key), encode(val)); + }, + remove: function(key) { + this.ls.removeItem(this._ttlKey(key)); + this.ls.removeItem(this._prefix(key)); + return this; + }, + clear: function() { + var i, keys = gatherMatchingKeys(this.keyMatcher); + for (i = keys.length; i--; ) { + this.remove(keys[i]); + } + return this; + }, + isExpired: function(key) { + var ttl = decode(this.ls.getItem(this._ttlKey(key))); + return _.isNumber(ttl) && now() > ttl ? true : false; + } + }); + return PersistentStorage; + function now() { + return new Date().getTime(); + } + function encode(val) { + return JSON.stringify(_.isUndefined(val) ? null : val); + } + function decode(val) { + return $.parseJSON(val); + } + function gatherMatchingKeys(keyMatcher) { + var i, key, keys = [], len = LOCAL_STORAGE.length; + for (i = 0; i < len; i++) { + if ((key = LOCAL_STORAGE.key(i)).match(keyMatcher)) { + keys.push(key.replace(keyMatcher, "")); + } + } + return keys; + } + }(); + var Transport = function() { + "use strict"; + var pendingRequestsCount = 0, pendingRequests = {}, maxPendingRequests = 6, sharedCache = new LruCache(10); + function Transport(o) { + o = o || {}; + this.cancelled = false; + this.lastReq = null; + this._send = o.transport; + this._get = o.limiter ? o.limiter(this._get) : this._get; + this._cache = o.cache === false ? new LruCache(0) : sharedCache; + } + Transport.setMaxPendingRequests = function setMaxPendingRequests(num) { + maxPendingRequests = num; + }; + Transport.resetCache = function resetCache() { + sharedCache.reset(); + }; + _.mixin(Transport.prototype, { + _fingerprint: function fingerprint(o) { + o = o || {}; + return o.url + o.type + $.param(o.data || {}); + }, + _get: function(o, cb) { + var that = this, fingerprint, jqXhr; + fingerprint = this._fingerprint(o); + if (this.cancelled || fingerprint !== this.lastReq) { + return; + } + if (jqXhr = pendingRequests[fingerprint]) { + jqXhr.done(done).fail(fail); + } else if (pendingRequestsCount < maxPendingRequests) { + pendingRequestsCount++; + pendingRequests[fingerprint] = this._send(o).done(done).fail(fail).always(always); + } else { + this.onDeckRequestArgs = [].slice.call(arguments, 0); + } + function done(resp) { + cb(null, resp); + that._cache.set(fingerprint, resp); + } + function fail() { + cb(true); + } + function always() { + pendingRequestsCount--; + delete pendingRequests[fingerprint]; + if (that.onDeckRequestArgs) { + that._get.apply(that, that.onDeckRequestArgs); + that.onDeckRequestArgs = null; + } + } + }, + get: function(o, cb) { + var resp, fingerprint; + cb = cb || $.noop; + o = _.isString(o) ? { + url: o + } : o || {}; + fingerprint = this._fingerprint(o); + this.cancelled = false; + this.lastReq = fingerprint; + if (resp = this._cache.get(fingerprint)) { + cb(null, resp); + } else { + this._get(o, cb); + } + }, + cancel: function() { + this.cancelled = true; + } + }); + return Transport; + }(); + var SearchIndex = window.SearchIndex = function() { + "use strict"; + var CHILDREN = "c", IDS = "i"; + function SearchIndex(o) { + o = o || {}; + if (!o.datumTokenizer || !o.queryTokenizer) { + $.error("datumTokenizer and queryTokenizer are both required"); + } + this.identify = o.identify || _.stringify; + this.datumTokenizer = o.datumTokenizer; + this.queryTokenizer = o.queryTokenizer; + this.reset(); + } + _.mixin(SearchIndex.prototype, { + bootstrap: function bootstrap(o) { + this.datums = o.datums; + this.trie = o.trie; + }, + add: function(data) { + var that = this; + data = _.isArray(data) ? data : [ data ]; + _.each(data, function(datum) { + var id, tokens; + that.datums[id = that.identify(datum)] = datum; + tokens = normalizeTokens(that.datumTokenizer(datum)); + _.each(tokens, function(token) { + var node, chars, ch; + node = that.trie; + chars = token.split(""); + while (ch = chars.shift()) { + node = node[CHILDREN][ch] || (node[CHILDREN][ch] = newNode()); + node[IDS].push(id); + } + }); + }); + }, + get: function get(ids) { + var that = this; + return _.map(ids, function(id) { + return that.datums[id]; + }); + }, + search: function search(query) { + var that = this, tokens, matches; + tokens = normalizeTokens(this.queryTokenizer(query)); + _.each(tokens, function(token) { + var node, chars, ch, ids; + if (matches && matches.length === 0) { + return false; + } + node = that.trie; + chars = token.split(""); + while (node && (ch = chars.shift())) { + node = node[CHILDREN][ch]; + } + if (node && chars.length === 0) { + ids = node[IDS].slice(0); + matches = matches ? getIntersection(matches, ids) : ids; + } else { + matches = []; + return false; + } + }); + return matches ? _.map(unique(matches), function(id) { + return that.datums[id]; + }) : []; + }, + all: function all() { + var values = []; + for (var key in this.datums) { + values.push(this.datums[key]); + } + return values; + }, + reset: function reset() { + this.datums = {}; + this.trie = newNode(); + }, + serialize: function serialize() { + return { + datums: this.datums, + trie: this.trie + }; + } + }); + return SearchIndex; + function normalizeTokens(tokens) { + tokens = _.filter(tokens, function(token) { + return !!token; + }); + tokens = _.map(tokens, function(token) { + return token.toLowerCase(); + }); + return tokens; + } + function newNode() { + var node = {}; + node[IDS] = []; + node[CHILDREN] = {}; + return node; + } + function unique(array) { + var seen = {}, uniques = []; + for (var i = 0, len = array.length; i < len; i++) { + if (!seen[array[i]]) { + seen[array[i]] = true; + uniques.push(array[i]); + } + } + return uniques; + } + function getIntersection(arrayA, arrayB) { + var ai = 0, bi = 0, intersection = []; + arrayA = arrayA.sort(); + arrayB = arrayB.sort(); + var lenArrayA = arrayA.length, lenArrayB = arrayB.length; + while (ai < lenArrayA && bi < lenArrayB) { + if (arrayA[ai] < arrayB[bi]) { + ai++; + } else if (arrayA[ai] > arrayB[bi]) { + bi++; + } else { + intersection.push(arrayA[ai]); + ai++; + bi++; + } + } + return intersection; + } + }(); + var Prefetch = function() { + "use strict"; + var keys; + keys = { + data: "data", + protocol: "protocol", + thumbprint: "thumbprint" + }; + function Prefetch(o) { + this.url = o.url; + this.ttl = o.ttl; + this.cache = o.cache; + this.prepare = o.prepare; + this.transform = o.transform; + this.transport = o.transport; + this.thumbprint = o.thumbprint; + this.storage = new PersistentStorage(o.cacheKey); + } + _.mixin(Prefetch.prototype, { + _settings: function settings() { + return { + url: this.url, + type: "GET", + dataType: "json" + }; + }, + store: function store(data) { + if (!this.cache) { + return; + } + this.storage.set(keys.data, data, this.ttl); + this.storage.set(keys.protocol, location.protocol, this.ttl); + this.storage.set(keys.thumbprint, this.thumbprint, this.ttl); + }, + fromCache: function fromCache() { + var stored = {}, isExpired; + if (!this.cache) { + return null; + } + stored.data = this.storage.get(keys.data); + stored.protocol = this.storage.get(keys.protocol); + stored.thumbprint = this.storage.get(keys.thumbprint); + isExpired = stored.thumbprint !== this.thumbprint || stored.protocol !== location.protocol; + return stored.data && !isExpired ? stored.data : null; + }, + fromNetwork: function(cb) { + var that = this, settings; + if (!cb) { + return; + } + settings = this.prepare(this._settings()); + this.transport(settings).fail(onError).done(onResponse); + function onError() { + cb(true); + } + function onResponse(resp) { + cb(null, that.transform(resp)); + } + }, + clear: function clear() { + this.storage.clear(); + return this; + } + }); + return Prefetch; + }(); + var Remote = function() { + "use strict"; + function Remote(o) { + this.url = o.url; + this.prepare = o.prepare; + this.transform = o.transform; + this.transport = new Transport({ + cache: o.cache, + limiter: o.limiter, + transport: o.transport + }); + } + _.mixin(Remote.prototype, { + _settings: function settings() { + return { + url: this.url, + type: "GET", + dataType: "json" + }; + }, + get: function get(query, cb) { + var that = this, settings; + if (!cb) { + return; + } + query = query || ""; + settings = this.prepare(query, this._settings()); + return this.transport.get(settings, onResponse); + function onResponse(err, resp) { + err ? cb([]) : cb(that.transform(resp)); + } + }, + cancelLastRequest: function cancelLastRequest() { + this.transport.cancel(); + } + }); + return Remote; + }(); + var oParser = function() { + "use strict"; + return function parse(o) { + var defaults, sorter; + defaults = { + initialize: true, + identify: _.stringify, + datumTokenizer: null, + queryTokenizer: null, + sufficient: 5, + sorter: null, + local: [], + prefetch: null, + remote: null + }; + o = _.mixin(defaults, o || {}); + !o.datumTokenizer && $.error("datumTokenizer is required"); + !o.queryTokenizer && $.error("queryTokenizer is required"); + sorter = o.sorter; + o.sorter = sorter ? function(x) { + return x.sort(sorter); + } : _.identity; + o.local = _.isFunction(o.local) ? o.local() : o.local; + o.prefetch = parsePrefetch(o.prefetch); + o.remote = parseRemote(o.remote); + return o; + }; + function parsePrefetch(o) { + var defaults; + if (!o) { + return null; + } + defaults = { + url: null, + ttl: 24 * 60 * 60 * 1e3, + cache: true, + cacheKey: null, + thumbprint: "", + prepare: _.identity, + transform: _.identity, + transport: null + }; + o = _.isString(o) ? { + url: o + } : o; + o = _.mixin(defaults, o); + !o.url && $.error("prefetch requires url to be set"); + o.transform = o.filter || o.transform; + o.cacheKey = o.cacheKey || o.url; + o.thumbprint = VERSION + o.thumbprint; + o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax; + return o; + } + function parseRemote(o) { + var defaults; + if (!o) { + return; + } + defaults = { + url: null, + cache: true, + prepare: null, + replace: null, + wildcard: null, + limiter: null, + rateLimitBy: "debounce", + rateLimitWait: 300, + transform: _.identity, + transport: null + }; + o = _.isString(o) ? { + url: o + } : o; + o = _.mixin(defaults, o); + !o.url && $.error("remote requires url to be set"); + o.transform = o.filter || o.transform; + o.prepare = toRemotePrepare(o); + o.limiter = toLimiter(o); + o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax; + delete o.replace; + delete o.wildcard; + delete o.rateLimitBy; + delete o.rateLimitWait; + return o; + } + function toRemotePrepare(o) { + var prepare, replace, wildcard; + prepare = o.prepare; + replace = o.replace; + wildcard = o.wildcard; + if (prepare) { + return prepare; + } + if (replace) { + prepare = prepareByReplace; + } else if (o.wildcard) { + prepare = prepareByWildcard; + } else { + prepare = idenityPrepare; + } + return prepare; + function prepareByReplace(query, settings) { + settings.url = replace(settings.url, query); + return settings; + } + function prepareByWildcard(query, settings) { + settings.url = settings.url.replace(wildcard, encodeURIComponent(query)); + return settings; + } + function idenityPrepare(query, settings) { + return settings; + } + } + function toLimiter(o) { + var limiter, method, wait; + limiter = o.limiter; + method = o.rateLimitBy; + wait = o.rateLimitWait; + if (!limiter) { + limiter = /^throttle$/i.test(method) ? throttle(wait) : debounce(wait); + } + return limiter; + function debounce(wait) { + return function debounce(fn) { + return _.debounce(fn, wait); + }; + } + function throttle(wait) { + return function throttle(fn) { + return _.throttle(fn, wait); + }; + } + } + function callbackToDeferred(fn) { + return function wrapper(o) { + var deferred = $.Deferred(); + fn(o, onSuccess, onError); + return deferred; + function onSuccess(resp) { + _.defer(function() { + deferred.resolve(resp); + }); + } + function onError(err) { + _.defer(function() { + deferred.reject(err); + }); + } + }; + } + }(); + var Bloodhound = function() { + "use strict"; + var old; + old = window && window.Bloodhound; + function Bloodhound(o) { + o = oParser(o); + this.sorter = o.sorter; + this.identify = o.identify; + this.sufficient = o.sufficient; + this.local = o.local; + this.remote = o.remote ? new Remote(o.remote) : null; + this.prefetch = o.prefetch ? new Prefetch(o.prefetch) : null; + this.index = new SearchIndex({ + identify: this.identify, + datumTokenizer: o.datumTokenizer, + queryTokenizer: o.queryTokenizer + }); + o.initialize !== false && this.initialize(); + } + Bloodhound.noConflict = function noConflict() { + window && (window.Bloodhound = old); + return Bloodhound; + }; + Bloodhound.tokenizers = tokenizers; + _.mixin(Bloodhound.prototype, { + __ttAdapter: function ttAdapter() { + var that = this; + return this.remote ? withAsync : withoutAsync; + function withAsync(query, sync, async) { + return that.search(query, sync, async); + } + function withoutAsync(query, sync) { + return that.search(query, sync); + } + }, + _loadPrefetch: function loadPrefetch() { + var that = this, deferred, serialized; + deferred = $.Deferred(); + if (!this.prefetch) { + deferred.resolve(); + } else if (serialized = this.prefetch.fromCache()) { + this.index.bootstrap(serialized); + deferred.resolve(); + } else { + this.prefetch.fromNetwork(done); + } + return deferred.promise(); + function done(err, data) { + if (err) { + return deferred.reject(); + } + that.add(data); + that.prefetch.store(that.index.serialize()); + deferred.resolve(); + } + }, + _initialize: function initialize() { + var that = this, deferred; + this.clear(); + (this.initPromise = this._loadPrefetch()).done(addLocalToIndex); + return this.initPromise; + function addLocalToIndex() { + that.add(that.local); + } + }, + initialize: function initialize(force) { + return !this.initPromise || force ? this._initialize() : this.initPromise; + }, + add: function add(data) { + this.index.add(data); + return this; + }, + get: function get(ids) { + ids = _.isArray(ids) ? ids : [].slice.call(arguments); + return this.index.get(ids); + }, + search: function search(query, sync, async) { + var that = this, local; + local = this.sorter(this.index.search(query)); + sync(this.remote ? local.slice() : local); + if (this.remote && local.length < this.sufficient) { + this.remote.get(query, processRemote); + } else if (this.remote) { + this.remote.cancelLastRequest(); + } + return this; + function processRemote(remote) { + var nonDuplicates = []; + _.each(remote, function(r) { + !_.some(local, function(l) { + return that.identify(r) === that.identify(l); + }) && nonDuplicates.push(r); + }); + async && async(nonDuplicates); + } + }, + all: function all() { + return this.index.all(); + }, + clear: function clear() { + this.index.reset(); + return this; + }, + clearPrefetchCache: function clearPrefetchCache() { + this.prefetch && this.prefetch.clear(); + return this; + }, + clearRemoteCache: function clearRemoteCache() { + Transport.resetCache(); + return this; + }, + ttAdapter: function ttAdapter() { + return this.__ttAdapter(); + } + }); + return Bloodhound; + }(); + return Bloodhound; +}); + +(function(root, factory) { + if (typeof define === "function" && define.amd) { + define("typeahead.js", [ "jquery" ], function(a0) { + return factory(a0); + }); + } else if (typeof exports === "object") { + module.exports = factory(require("jquery")); + } else { + factory(jQuery); + } +})(this, function($) { + var _ = function() { + "use strict"; + return { + isMsie: function() { + return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false; + }, + isBlankString: function(str) { + return !str || /^\s*$/.test(str); + }, + escapeRegExChars: function(str) { + return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); + }, + isString: function(obj) { + return typeof obj === "string"; + }, + isNumber: function(obj) { + return typeof obj === "number"; + }, + isArray: $.isArray, + isFunction: $.isFunction, + isObject: $.isPlainObject, + isUndefined: function(obj) { + return typeof obj === "undefined"; + }, + isElement: function(obj) { + return !!(obj && obj.nodeType === 1); + }, + isJQuery: function(obj) { + return obj instanceof $; + }, + toStr: function toStr(s) { + return _.isUndefined(s) || s === null ? "" : s + ""; + }, + bind: $.proxy, + each: function(collection, cb) { + $.each(collection, reverseArgs); + function reverseArgs(index, value) { + return cb(value, index); + } + }, + map: $.map, + filter: $.grep, + every: function(obj, test) { + var result = true; + if (!obj) { + return result; + } + $.each(obj, function(key, val) { + if (!(result = test.call(null, val, key, obj))) { + return false; + } + }); + return !!result; + }, + some: function(obj, test) { + var result = false; + if (!obj) { + return result; + } + $.each(obj, function(key, val) { + if (result = test.call(null, val, key, obj)) { + return false; + } + }); + return !!result; + }, + mixin: $.extend, + identity: function(x) { + return x; + }, + clone: function(obj) { + return $.extend(true, {}, obj); + }, + getIdGenerator: function() { + var counter = 0; + return function() { + return counter++; + }; + }, + templatify: function templatify(obj) { + return $.isFunction(obj) ? obj : template; + function template() { + return String(obj); + } + }, + defer: function(fn) { + setTimeout(fn, 0); + }, + debounce: function(func, wait, immediate) { + var timeout, result; + return function() { + var context = this, args = arguments, later, callNow; + later = function() { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + } + }; + callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if (callNow) { + result = func.apply(context, args); + } + return result; + }; + }, + throttle: function(func, wait) { + var context, args, timeout, result, previous, later; + previous = 0; + later = function() { + previous = new Date(); + timeout = null; + result = func.apply(context, args); + }; + return function() { + var now = new Date(), remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0) { + clearTimeout(timeout); + timeout = null; + previous = now; + result = func.apply(context, args); + } else if (!timeout) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }, + stringify: function(val) { + return _.isString(val) ? val : JSON.stringify(val); + }, + noop: function() {} + }; + }(); + var WWW = function() { + "use strict"; + var defaultClassNames = { + wrapper: "twitter-typeahead", + input: "tt-input", + hint: "tt-hint", + menu: "tt-menu", + dataset: "tt-dataset", + suggestion: "tt-suggestion", + selectable: "tt-selectable", + empty: "tt-empty", + open: "tt-open", + cursor: "tt-cursor", + highlight: "tt-highlight" + }; + return build; + function build(o) { + var www, classes; + classes = _.mixin({}, defaultClassNames, o); + www = { + css: buildCss(), + classes: classes, + html: buildHtml(classes), + selectors: buildSelectors(classes) + }; + return { + css: www.css, + html: www.html, + classes: www.classes, + selectors: www.selectors, + mixin: function(o) { + _.mixin(o, www); + } + }; + } + function buildHtml(c) { + return { + wrapper: '', + menu: '
' + }; + } + function buildSelectors(classes) { + var selectors = {}; + _.each(classes, function(v, k) { + selectors[k] = "." + v; + }); + return selectors; + } + function buildCss() { + var css = { + wrapper: { + position: "relative", + display: "inline-block" + }, + hint: { + position: "absolute", + top: "0", + left: "0", + borderColor: "transparent", + boxShadow: "none", + opacity: "1" + }, + input: { + position: "relative", + verticalAlign: "top", + backgroundColor: "transparent" + }, + inputWithNoHint: { + position: "relative", + verticalAlign: "top" + }, + menu: { + position: "absolute", + top: "100%", + left: "0", + zIndex: "100", + display: "none" + }, + ltr: { + left: "0", + right: "auto" + }, + rtl: { + left: "auto", + right: " 0" + } + }; + if (_.isMsie()) { + _.mixin(css.input, { + backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)" + }); + } + return css; + } + }(); + var EventBus = function() { + "use strict"; + var namespace, deprecationMap; + namespace = "typeahead:"; + deprecationMap = { + render: "rendered", + cursorchange: "cursorchanged", + select: "selected", + autocomplete: "autocompleted" + }; + function EventBus(o) { + if (!o || !o.el) { + $.error("EventBus initialized without el"); + } + this.$el = $(o.el); + } + _.mixin(EventBus.prototype, { + _trigger: function(type, args) { + var $e; + $e = $.Event(namespace + type); + (args = args || []).unshift($e); + this.$el.trigger.apply(this.$el, args); + return $e; + }, + before: function(type) { + var args, $e; + args = [].slice.call(arguments, 1); + $e = this._trigger("before" + type, args); + return $e.isDefaultPrevented(); + }, + trigger: function(type) { + var deprecatedType; + this._trigger(type, [].slice.call(arguments, 1)); + if (deprecatedType = deprecationMap[type]) { + this._trigger(deprecatedType, [].slice.call(arguments, 1)); + } + } + }); + return EventBus; + }(); + var EventEmitter = function() { + "use strict"; + var splitter = /\s+/, nextTick = getNextTick(); + return { + onSync: onSync, + onAsync: onAsync, + off: off, + trigger: trigger + }; + function on(method, types, cb, context) { + var type; + if (!cb) { + return this; + } + types = types.split(splitter); + cb = context ? bindContext(cb, context) : cb; + this._callbacks = this._callbacks || {}; + while (type = types.shift()) { + this._callbacks[type] = this._callbacks[type] || { + sync: [], + async: [] + }; + this._callbacks[type][method].push(cb); + } + return this; + } + function onAsync(types, cb, context) { + return on.call(this, "async", types, cb, context); + } + function onSync(types, cb, context) { + return on.call(this, "sync", types, cb, context); + } + function off(types) { + var type; + if (!this._callbacks) { + return this; + } + types = types.split(splitter); + while (type = types.shift()) { + delete this._callbacks[type]; + } + return this; + } + function trigger(types) { + var type, callbacks, args, syncFlush, asyncFlush; + if (!this._callbacks) { + return this; + } + types = types.split(splitter); + args = [].slice.call(arguments, 1); + while ((type = types.shift()) && (callbacks = this._callbacks[type])) { + syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args)); + asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args)); + syncFlush() && nextTick(asyncFlush); + } + return this; + } + function getFlush(callbacks, context, args) { + return flush; + function flush() { + var cancelled; + for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) { + cancelled = callbacks[i].apply(context, args) === false; + } + return !cancelled; + } + } + function getNextTick() { + var nextTickFn; + if (window.setImmediate) { + nextTickFn = function nextTickSetImmediate(fn) { + setImmediate(function() { + fn(); + }); + }; + } else { + nextTickFn = function nextTickSetTimeout(fn) { + setTimeout(function() { + fn(); + }, 0); + }; + } + return nextTickFn; + } + function bindContext(fn, context) { + return fn.bind ? fn.bind(context) : function() { + fn.apply(context, [].slice.call(arguments, 0)); + }; + } + }(); + var highlight = function(doc) { + "use strict"; + var defaults = { + node: null, + pattern: null, + tagName: "strong", + className: null, + wordsOnly: false, + caseSensitive: false + }; + return function hightlight(o) { + var regex; + o = _.mixin({}, defaults, o); + if (!o.node || !o.pattern) { + return; + } + o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ]; + regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly); + traverse(o.node, hightlightTextNode); + function hightlightTextNode(textNode) { + var match, patternNode, wrapperNode; + if (match = regex.exec(textNode.data)) { + wrapperNode = doc.createElement(o.tagName); + o.className && (wrapperNode.className = o.className); + patternNode = textNode.splitText(match.index); + patternNode.splitText(match[0].length); + wrapperNode.appendChild(patternNode.cloneNode(true)); + textNode.parentNode.replaceChild(wrapperNode, patternNode); + } + return !!match; + } + function traverse(el, hightlightTextNode) { + var childNode, TEXT_NODE_TYPE = 3; + for (var i = 0; i < el.childNodes.length; i++) { + childNode = el.childNodes[i]; + if (childNode.nodeType === TEXT_NODE_TYPE) { + i += hightlightTextNode(childNode) ? 1 : 0; + } else { + traverse(childNode, hightlightTextNode); + } + } + } + }; + function getRegex(patterns, caseSensitive, wordsOnly) { + var escapedPatterns = [], regexStr; + for (var i = 0, len = patterns.length; i < len; i++) { + escapedPatterns.push(_.escapeRegExChars(patterns[i])); + } + regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")"; + return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i"); + } + }(window.document); + var Input = function() { + "use strict"; + var specialKeyCodeMap; + specialKeyCodeMap = { + 9: "tab", + 27: "esc", + 37: "left", + 39: "right", + 13: "enter", + 38: "up", + 40: "down" + }; + function Input(o, www) { + o = o || {}; + if (!o.input) { + $.error("input is missing"); + } + www.mixin(this); + this.$hint = $(o.hint); + this.$input = $(o.input); + this.query = this.$input.val(); + this.queryWhenFocused = this.hasFocus() ? this.query : null; + this.$overflowHelper = buildOverflowHelper(this.$input); + this._checkLanguageDirection(); + if (this.$hint.length === 0) { + this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop; + } + } + Input.normalizeQuery = function(str) { + return _.toStr(str).replace(/^\s*/g, "").replace(/\s{2,}/g, " "); + }; + _.mixin(Input.prototype, EventEmitter, { + _onBlur: function onBlur() { + this.resetInputValue(); + this.trigger("blurred"); + }, + _onFocus: function onFocus() { + this.queryWhenFocused = this.query; + this.trigger("focused"); + }, + _onKeydown: function onKeydown($e) { + var keyName = specialKeyCodeMap[$e.which || $e.keyCode]; + this._managePreventDefault(keyName, $e); + if (keyName && this._shouldTrigger(keyName, $e)) { + this.trigger(keyName + "Keyed", $e); + } + }, + _onInput: function onInput() { + this._setQuery(this.getInputValue()); + this.clearHintIfInvalid(); + this._checkLanguageDirection(); + }, + _managePreventDefault: function managePreventDefault(keyName, $e) { + var preventDefault; + switch (keyName) { + case "up": + case "down": + preventDefault = !withModifier($e); + break; + + default: + preventDefault = false; + } + preventDefault && $e.preventDefault(); + }, + _shouldTrigger: function shouldTrigger(keyName, $e) { + var trigger; + switch (keyName) { + case "tab": + trigger = !withModifier($e); + break; + + default: + trigger = true; + } + return trigger; + }, + _checkLanguageDirection: function checkLanguageDirection() { + var dir = (this.$input.css("direction") || "ltr").toLowerCase(); + if (this.dir !== dir) { + this.dir = dir; + this.$hint.attr("dir", dir); + this.trigger("langDirChanged", dir); + } + }, + _setQuery: function setQuery(val, silent) { + var areEquivalent, hasDifferentWhitespace; + areEquivalent = areQueriesEquivalent(val, this.query); + hasDifferentWhitespace = areEquivalent ? this.query.length !== val.length : false; + this.query = val; + if (!silent && !areEquivalent) { + this.trigger("queryChanged", this.query); + } else if (!silent && hasDifferentWhitespace) { + this.trigger("whitespaceChanged", this.query); + } + }, + bind: function() { + var that = this, onBlur, onFocus, onKeydown, onInput; + onBlur = _.bind(this._onBlur, this); + onFocus = _.bind(this._onFocus, this); + onKeydown = _.bind(this._onKeydown, this); + onInput = _.bind(this._onInput, this); + this.$input.on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown); + if (!_.isMsie() || _.isMsie() > 9) { + this.$input.on("input.tt", onInput); + } else { + this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) { + if (specialKeyCodeMap[$e.which || $e.keyCode]) { + return; + } + _.defer(_.bind(that._onInput, that, $e)); + }); + } + return this; + }, + focus: function focus() { + this.$input.focus(); + }, + blur: function blur() { + this.$input.blur(); + }, + getLangDir: function getLangDir() { + return this.dir; + }, + getQuery: function getQuery() { + return this.query || ""; + }, + setQuery: function setQuery(val, silent) { + this.setInputValue(val); + this._setQuery(val, silent); + }, + hasQueryChangedSinceLastFocus: function hasQueryChangedSinceLastFocus() { + return this.query !== this.queryWhenFocused; + }, + getInputValue: function getInputValue() { + return this.$input.val(); + }, + setInputValue: function setInputValue(value) { + this.$input.val(value); + this.clearHintIfInvalid(); + this._checkLanguageDirection(); + }, + resetInputValue: function resetInputValue() { + this.setInputValue(this.query); + }, + getHint: function getHint() { + return this.$hint.val(); + }, + setHint: function setHint(value) { + this.$hint.val(value); + }, + clearHint: function clearHint() { + this.setHint(""); + }, + clearHintIfInvalid: function clearHintIfInvalid() { + var val, hint, valIsPrefixOfHint, isValid; + val = this.getInputValue(); + hint = this.getHint(); + valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0; + isValid = val !== "" && valIsPrefixOfHint && !this.hasOverflow(); + !isValid && this.clearHint(); + }, + hasFocus: function hasFocus() { + return this.$input.is(":focus"); + }, + hasOverflow: function hasOverflow() { + var constraint = this.$input.width() - 2; + this.$overflowHelper.text(this.getInputValue()); + return this.$overflowHelper.width() >= constraint; + }, + isCursorAtEnd: function() { + var valueLength, selectionStart, range; + valueLength = this.$input.val().length; + selectionStart = this.$input[0].selectionStart; + if (_.isNumber(selectionStart)) { + return selectionStart === valueLength; + } else if (document.selection) { + range = document.selection.createRange(); + range.moveStart("character", -valueLength); + return valueLength === range.text.length; + } + return true; + }, + destroy: function destroy() { + this.$hint.off(".tt"); + this.$input.off(".tt"); + this.$overflowHelper.remove(); + this.$hint = this.$input = this.$overflowHelper = $("
"); + } + }); + return Input; + function buildOverflowHelper($input) { + return $('').css({ + position: "absolute", + visibility: "hidden", + whiteSpace: "pre", + fontFamily: $input.css("font-family"), + fontSize: $input.css("font-size"), + fontStyle: $input.css("font-style"), + fontVariant: $input.css("font-variant"), + fontWeight: $input.css("font-weight"), + wordSpacing: $input.css("word-spacing"), + letterSpacing: $input.css("letter-spacing"), + textIndent: $input.css("text-indent"), + textRendering: $input.css("text-rendering"), + textTransform: $input.css("text-transform") + }).insertAfter($input); + } + function areQueriesEquivalent(a, b) { + return Input.normalizeQuery(a) === Input.normalizeQuery(b); + } + function withModifier($e) { + return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey; + } + }(); + var Dataset = function() { + "use strict"; + var keys, nameGenerator; + keys = { + val: "tt-selectable-display", + obj: "tt-selectable-object" + }; + nameGenerator = _.getIdGenerator(); + function Dataset(o, www) { + o = o || {}; + o.templates = o.templates || {}; + o.templates.notFound = o.templates.notFound || o.templates.empty; + if (!o.source) { + $.error("missing source"); + } + if (!o.node) { + $.error("missing node"); + } + if (o.name && !isValidName(o.name)) { + $.error("invalid dataset name: " + o.name); + } + www.mixin(this); + this.highlight = !!o.highlight; + this.name = o.name || nameGenerator(); + this.limit = o.limit || 5; + this.displayFn = getDisplayFn(o.display || o.displayKey); + this.templates = getTemplates(o.templates, this.displayFn); + this.source = o.source.__ttAdapter ? o.source.__ttAdapter() : o.source; + this.async = _.isUndefined(o.async) ? this.source.length > 2 : !!o.async; + this._resetLastSuggestion(); + this.$el = $(o.node).addClass(this.classes.dataset).addClass(this.classes.dataset + "-" + this.name); + } + Dataset.extractData = function extractData(el) { + var $el = $(el); + if ($el.data(keys.obj)) { + return { + val: $el.data(keys.val) || "", + obj: $el.data(keys.obj) || null + }; + } + return null; + }; + _.mixin(Dataset.prototype, EventEmitter, { + _overwrite: function overwrite(query, suggestions) { + suggestions = suggestions || []; + if (suggestions.length) { + this._renderSuggestions(query, suggestions); + } else if (this.async && this.templates.pending) { + this._renderPending(query); + } else if (!this.async && this.templates.notFound) { + this._renderNotFound(query); + } else { + this._empty(); + } + this.trigger("rendered", this.name, suggestions, false); + }, + _append: function append(query, suggestions) { + suggestions = suggestions || []; + if (suggestions.length && this.$lastSuggestion.length) { + this._appendSuggestions(query, suggestions); + } else if (suggestions.length) { + this._renderSuggestions(query, suggestions); + } else if (!this.$lastSuggestion.length && this.templates.notFound) { + this._renderNotFound(query); + } + this.trigger("rendered", this.name, suggestions, true); + }, + _renderSuggestions: function renderSuggestions(query, suggestions) { + var $fragment; + $fragment = this._getSuggestionsFragment(query, suggestions); + this.$lastSuggestion = $fragment.children().last(); + this.$el.html($fragment).prepend(this._getHeader(query, suggestions)).append(this._getFooter(query, suggestions)); + }, + _appendSuggestions: function appendSuggestions(query, suggestions) { + var $fragment, $lastSuggestion; + $fragment = this._getSuggestionsFragment(query, suggestions); + $lastSuggestion = $fragment.children().last(); + this.$lastSuggestion.after($fragment); + this.$lastSuggestion = $lastSuggestion; + }, + _renderPending: function renderPending(query) { + var template = this.templates.pending; + this._resetLastSuggestion(); + template && this.$el.html(template({ + query: query, + dataset: this.name + })); + }, + _renderNotFound: function renderNotFound(query) { + var template = this.templates.notFound; + this._resetLastSuggestion(); + template && this.$el.html(template({ + query: query, + dataset: this.name + })); + }, + _empty: function empty() { + this.$el.empty(); + this._resetLastSuggestion(); + }, + _getSuggestionsFragment: function getSuggestionsFragment(query, suggestions) { + var that = this, fragment; + fragment = document.createDocumentFragment(); + _.each(suggestions, function getSuggestionNode(suggestion) { + var $el, context; + context = that._injectQuery(query, suggestion); + $el = $(that.templates.suggestion(context)).data(keys.obj, suggestion).data(keys.val, that.displayFn(suggestion)).addClass(that.classes.suggestion + " " + that.classes.selectable); + fragment.appendChild($el[0]); + }); + this.highlight && highlight({ + className: this.classes.highlight, + node: fragment, + pattern: query + }); + return $(fragment); + }, + _getFooter: function getFooter(query, suggestions) { + return this.templates.footer ? this.templates.footer({ + query: query, + suggestions: suggestions, + dataset: this.name + }) : null; + }, + _getHeader: function getHeader(query, suggestions) { + return this.templates.header ? this.templates.header({ + query: query, + suggestions: suggestions, + dataset: this.name + }) : null; + }, + _resetLastSuggestion: function resetLastSuggestion() { + this.$lastSuggestion = $(); + }, + _injectQuery: function injectQuery(query, obj) { + return _.isObject(obj) ? _.mixin({ + _query: query + }, obj) : obj; + }, + update: function update(query) { + var that = this, canceled = false, syncCalled = false, rendered = 0; + this.cancel(); + this.cancel = function cancel() { + canceled = true; + that.cancel = $.noop; + that.async && that.trigger("asyncCanceled", query); + }; + this.source(query, sync, async); + !syncCalled && sync([]); + function sync(suggestions) { + if (syncCalled) { + return; + } + syncCalled = true; + suggestions = (suggestions || []).slice(0, that.limit); + rendered = suggestions.length; + that._overwrite(query, suggestions); + if (rendered < that.limit && that.async) { + that.trigger("asyncRequested", query); + } + } + function async(suggestions) { + suggestions = suggestions || []; + if (!canceled && rendered < that.limit) { + that.cancel = $.noop; + rendered += suggestions.length; + that._append(query, suggestions.slice(0, that.limit - rendered)); + that.async && that.trigger("asyncReceived", query); + } + } + }, + cancel: $.noop, + clear: function clear() { + this._empty(); + this.cancel(); + this.trigger("cleared"); + }, + isEmpty: function isEmpty() { + return this.$el.is(":empty"); + }, + destroy: function destroy() { + this.$el = $("
"); + } + }); + return Dataset; + function getDisplayFn(display) { + display = display || _.stringify; + return _.isFunction(display) ? display : displayFn; + function displayFn(obj) { + return obj[display]; + } + } + function getTemplates(templates, displayFn) { + return { + notFound: templates.notFound && _.templatify(templates.notFound), + pending: templates.pending && _.templatify(templates.pending), + header: templates.header && _.templatify(templates.header), + footer: templates.footer && _.templatify(templates.footer), + suggestion: templates.suggestion || suggestionTemplate + }; + function suggestionTemplate(context) { + return $("
").text(displayFn(context)); + } + } + function isValidName(str) { + return /^[_a-zA-Z0-9-]+$/.test(str); + } + }(); + var Menu = function() { + "use strict"; + function Menu(o, www) { + var that = this; + o = o || {}; + if (!o.node) { + $.error("node is required"); + } + www.mixin(this); + this.$node = $(o.node); + this.query = null; + this.datasets = _.map(o.datasets, initializeDataset); + function initializeDataset(oDataset) { + var node = that.$node.find(oDataset.node).first(); + oDataset.node = node.length ? node : $("
").appendTo(that.$node); + return new Dataset(oDataset, www); + } + } + _.mixin(Menu.prototype, EventEmitter, { + _onSelectableClick: function onSelectableClick($e) { + this.trigger("selectableClicked", $($e.currentTarget)); + }, + _onRendered: function onRendered(type, dataset, suggestions, async) { + this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty()); + this.trigger("datasetRendered", dataset, suggestions, async); + }, + _onCleared: function onCleared() { + this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty()); + this.trigger("datasetCleared"); + }, + _propagate: function propagate() { + this.trigger.apply(this, arguments); + }, + _allDatasetsEmpty: function allDatasetsEmpty() { + return _.every(this.datasets, isDatasetEmpty); + function isDatasetEmpty(dataset) { + return dataset.isEmpty(); + } + }, + _getSelectables: function getSelectables() { + return this.$node.find(this.selectors.selectable); + }, + _removeCursor: function _removeCursor() { + var $selectable = this.getActiveSelectable(); + $selectable && $selectable.removeClass(this.classes.cursor); + }, + _ensureVisible: function ensureVisible($el) { + var elTop, elBottom, nodeScrollTop, nodeHeight; + elTop = $el.position().top; + elBottom = elTop + $el.outerHeight(true); + nodeScrollTop = this.$node.scrollTop(); + nodeHeight = this.$node.height() + parseInt(this.$node.css("paddingTop"), 10) + parseInt(this.$node.css("paddingBottom"), 10); + if (elTop < 0) { + this.$node.scrollTop(nodeScrollTop + elTop); + } else if (nodeHeight < elBottom) { + this.$node.scrollTop(nodeScrollTop + (elBottom - nodeHeight)); + } + }, + bind: function() { + var that = this, onSelectableClick; + onSelectableClick = _.bind(this._onSelectableClick, this); + this.$node.on("click.tt", this.selectors.selectable, onSelectableClick); + _.each(this.datasets, function(dataset) { + dataset.onSync("asyncRequested", that._propagate, that).onSync("asyncCanceled", that._propagate, that).onSync("asyncReceived", that._propagate, that).onSync("rendered", that._onRendered, that).onSync("cleared", that._onCleared, that); + }); + return this; + }, + isOpen: function isOpen() { + return this.$node.hasClass(this.classes.open); + }, + open: function open() { + this.$node.addClass(this.classes.open); + }, + close: function close() { + this.$node.removeClass(this.classes.open); + this._removeCursor(); + }, + setLanguageDirection: function setLanguageDirection(dir) { + this.$node.attr("dir", dir); + }, + selectableRelativeToCursor: function selectableRelativeToCursor(delta) { + var $selectables, $oldCursor, oldIndex, newIndex; + $oldCursor = this.getActiveSelectable(); + $selectables = this._getSelectables(); + oldIndex = $oldCursor ? $selectables.index($oldCursor) : -1; + newIndex = oldIndex + delta; + newIndex = (newIndex + 1) % ($selectables.length + 1) - 1; + newIndex = newIndex < -1 ? $selectables.length - 1 : newIndex; + return newIndex === -1 ? null : $selectables.eq(newIndex); + }, + setCursor: function setCursor($selectable) { + this._removeCursor(); + if ($selectable = $selectable && $selectable.first()) { + $selectable.addClass(this.classes.cursor); + this._ensureVisible($selectable); + } + }, + getSelectableData: function getSelectableData($el) { + return $el && $el.length ? Dataset.extractData($el) : null; + }, + getActiveSelectable: function getActiveSelectable() { + var $selectable = this._getSelectables().filter(this.selectors.cursor).first(); + return $selectable.length ? $selectable : null; + }, + getTopSelectable: function getTopSelectable() { + var $selectable = this._getSelectables().first(); + return $selectable.length ? $selectable : null; + }, + update: function update(query) { + var isValidUpdate = query !== this.query; + if (isValidUpdate) { + this.query = query; + _.each(this.datasets, updateDataset); + } + return isValidUpdate; + function updateDataset(dataset) { + dataset.update(query); + } + }, + empty: function empty() { + _.each(this.datasets, clearDataset); + this.query = null; + this.$node.addClass(this.classes.empty); + function clearDataset(dataset) { + dataset.clear(); + } + }, + destroy: function destroy() { + this.$node.off(".tt"); + this.$node = $("
"); + _.each(this.datasets, destroyDataset); + function destroyDataset(dataset) { + dataset.destroy(); + } + } + }); + return Menu; + }(); + var DefaultMenu = function() { + "use strict"; + var s = Menu.prototype; + function DefaultMenu() { + Menu.apply(this, [].slice.call(arguments, 0)); + } + _.mixin(DefaultMenu.prototype, Menu.prototype, { + open: function open() { + !this._allDatasetsEmpty() && this._show(); + return s.open.apply(this, [].slice.call(arguments, 0)); + }, + close: function close() { + this._hide(); + return s.close.apply(this, [].slice.call(arguments, 0)); + }, + _onRendered: function onRendered() { + if (this._allDatasetsEmpty()) { + this._hide(); + } else { + this.isOpen() && this._show(); + } + return s._onRendered.apply(this, [].slice.call(arguments, 0)); + }, + _onCleared: function onCleared() { + if (this._allDatasetsEmpty()) { + this._hide(); + } else { + this.isOpen() && this._show(); + } + return s._onCleared.apply(this, [].slice.call(arguments, 0)); + }, + setLanguageDirection: function setLanguageDirection(dir) { + this.$node.css(dir === "ltr" ? this.css.ltr : this.css.rtl); + return s.setLanguageDirection.apply(this, [].slice.call(arguments, 0)); + }, + _hide: function hide() { + this.$node.hide(); + }, + _show: function show() { + this.$node.css("display", "block"); + } + }); + return DefaultMenu; + }(); + var Typeahead = function() { + "use strict"; + function Typeahead(o, www) { + var onFocused, onBlurred, onEnterKeyed, onTabKeyed, onEscKeyed, onUpKeyed, onDownKeyed, onLeftKeyed, onRightKeyed, onQueryChanged, onWhitespaceChanged; + o = o || {}; + if (!o.input) { + $.error("missing input"); + } + if (!o.menu) { + $.error("missing menu"); + } + if (!o.eventBus) { + $.error("missing event bus"); + } + www.mixin(this); + this.eventBus = o.eventBus; + this.minLength = _.isNumber(o.minLength) ? o.minLength : 1; + this.input = o.input; + this.menu = o.menu; + this.enabled = true; + this.active = false; + this.input.hasFocus() && this.activate(); + this.dir = this.input.getLangDir(); + this._hacks(); + this.menu.bind().onSync("selectableClicked", this._onSelectableClicked, this).onSync("asyncRequested", this._onAsyncRequested, this).onSync("asyncCanceled", this._onAsyncCanceled, this).onSync("asyncReceived", this._onAsyncReceived, this).onSync("datasetRendered", this._onDatasetRendered, this).onSync("datasetCleared", this._onDatasetCleared, this); + onFocused = c(this, "activate", "open", "_onFocused"); + onBlurred = c(this, "deactivate", "_onBlurred"); + onEnterKeyed = c(this, "isActive", "isOpen", "_onEnterKeyed"); + onTabKeyed = c(this, "isActive", "isOpen", "_onTabKeyed"); + onEscKeyed = c(this, "isActive", "_onEscKeyed"); + onUpKeyed = c(this, "isActive", "open", "_onUpKeyed"); + onDownKeyed = c(this, "isActive", "open", "_onDownKeyed"); + onLeftKeyed = c(this, "isActive", "isOpen", "_onLeftKeyed"); + onRightKeyed = c(this, "isActive", "isOpen", "_onRightKeyed"); + onQueryChanged = c(this, "_openIfActive", "_onQueryChanged"); + onWhitespaceChanged = c(this, "_openIfActive", "_onWhitespaceChanged"); + this.input.bind().onSync("focused", onFocused, this).onSync("blurred", onBlurred, this).onSync("enterKeyed", onEnterKeyed, this).onSync("tabKeyed", onTabKeyed, this).onSync("escKeyed", onEscKeyed, this).onSync("upKeyed", onUpKeyed, this).onSync("downKeyed", onDownKeyed, this).onSync("leftKeyed", onLeftKeyed, this).onSync("rightKeyed", onRightKeyed, this).onSync("queryChanged", onQueryChanged, this).onSync("whitespaceChanged", onWhitespaceChanged, this).onSync("langDirChanged", this._onLangDirChanged, this); + } + _.mixin(Typeahead.prototype, { + _hacks: function hacks() { + var $input, $menu; + $input = this.input.$input || $("
"); + $menu = this.menu.$node || $("
"); + $input.on("blur.tt", function($e) { + var active, isActive, hasActive; + active = document.activeElement; + isActive = $menu.is(active); + hasActive = $menu.has(active).length > 0; + if (_.isMsie() && (isActive || hasActive)) { + $e.preventDefault(); + $e.stopImmediatePropagation(); + _.defer(function() { + $input.focus(); + }); + } + }); + $menu.on("mousedown.tt", function($e) { + $e.preventDefault(); + }); + }, + _onSelectableClicked: function onSelectableClicked(type, $el) { + this.select($el); + }, + _onDatasetCleared: function onDatasetCleared() { + this._updateHint(); + }, + _onDatasetRendered: function onDatasetRendered(type, dataset, suggestions, async) { + this._updateHint(); + this.eventBus.trigger("render", suggestions, async, dataset); + }, + _onAsyncRequested: function onAsyncRequested(type, dataset, query) { + this.eventBus.trigger("asyncrequest", query, dataset); + }, + _onAsyncCanceled: function onAsyncCanceled(type, dataset, query) { + this.eventBus.trigger("asynccancel", query, dataset); + }, + _onAsyncReceived: function onAsyncReceived(type, dataset, query) { + this.eventBus.trigger("asyncreceive", query, dataset); + }, + _onFocused: function onFocused() { + this._minLengthMet() && this.menu.update(this.input.getQuery()); + }, + _onBlurred: function onBlurred() { + if (this.input.hasQueryChangedSinceLastFocus()) { + this.eventBus.trigger("change", this.input.getQuery()); + } + }, + _onEnterKeyed: function onEnterKeyed(type, $e) { + var $selectable; + if ($selectable = this.menu.getActiveSelectable()) { + this.select($selectable) && $e.preventDefault(); + } + }, + _onTabKeyed: function onTabKeyed(type, $e) { + var $selectable; + if ($selectable = this.menu.getActiveSelectable()) { + this.select($selectable) && $e.preventDefault(); + } else if ($selectable = this.menu.getTopSelectable()) { + this.autocomplete($selectable) && $e.preventDefault(); + } + }, + _onEscKeyed: function onEscKeyed() { + this.close(); + }, + _onUpKeyed: function onUpKeyed() { + this.moveCursor(-1); + }, + _onDownKeyed: function onDownKeyed() { + this.moveCursor(+1); + }, + _onLeftKeyed: function onLeftKeyed() { + if (this.dir === "rtl" && this.input.isCursorAtEnd()) { + this.autocomplete(this.menu.getTopSelectable()); + } + }, + _onRightKeyed: function onRightKeyed() { + if (this.dir === "ltr" && this.input.isCursorAtEnd()) { + this.autocomplete(this.menu.getTopSelectable()); + } + }, + _onQueryChanged: function onQueryChanged(e, query) { + this._minLengthMet(query) ? this.menu.update(query) : this.menu.empty(); + }, + _onWhitespaceChanged: function onWhitespaceChanged() { + this._updateHint(); + }, + _onLangDirChanged: function onLangDirChanged(e, dir) { + if (this.dir !== dir) { + this.dir = dir; + this.menu.setLanguageDirection(dir); + } + }, + _openIfActive: function openIfActive() { + this.isActive() && this.open(); + }, + _minLengthMet: function minLengthMet(query) { + query = _.isString(query) ? query : this.input.getQuery() || ""; + return query.length >= this.minLength; + }, + _updateHint: function updateHint() { + var $selectable, data, val, query, escapedQuery, frontMatchRegEx, match; + $selectable = this.menu.getTopSelectable(); + data = this.menu.getSelectableData($selectable); + val = this.input.getInputValue(); + if (data && !_.isBlankString(val) && !this.input.hasOverflow()) { + query = Input.normalizeQuery(val); + escapedQuery = _.escapeRegExChars(query); + frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(.+$)", "i"); + match = frontMatchRegEx.exec(data.val); + match && this.input.setHint(val + match[1]); + } else { + this.input.clearHint(); + } + }, + isEnabled: function isEnabled() { + return this.enabled; + }, + enable: function enable() { + this.enabled = true; + }, + disable: function disable() { + this.enabled = false; + }, + isActive: function isActive() { + return this.active; + }, + activate: function activate() { + if (this.isActive()) { + return true; + } else if (!this.isEnabled() || this.eventBus.before("active")) { + return false; + } else { + this.active = true; + this.eventBus.trigger("active"); + return true; + } + }, + deactivate: function deactivate() { + if (!this.isActive()) { + return true; + } else if (this.eventBus.before("idle")) { + return false; + } else { + this.active = false; + this.close(); + this.eventBus.trigger("idle"); + return true; + } + }, + isOpen: function isOpen() { + return this.menu.isOpen(); + }, + open: function open() { + if (!this.isOpen() && !this.eventBus.before("open")) { + this.menu.open(); + this._updateHint(); + this.eventBus.trigger("open"); + } + return this.isOpen(); + }, + close: function close() { + if (this.isOpen() && !this.eventBus.before("close")) { + this.menu.close(); + this.input.clearHint(); + this.input.resetInputValue(); + this.eventBus.trigger("close"); + } + return !this.isOpen(); + }, + setVal: function setVal(val) { + this.input.setQuery(_.toStr(val)); + }, + getVal: function getVal() { + return this.input.getQuery(); + }, + select: function select($selectable) { + var data = this.menu.getSelectableData($selectable); + if (data && !this.eventBus.before("select", data.obj)) { + this.input.setQuery(data.val, true); + this.eventBus.trigger("select", data.obj); + this.close(); + return true; + } + return false; + }, + autocomplete: function autocomplete($selectable) { + var query, data, isValid; + query = this.input.getQuery(); + data = this.menu.getSelectableData($selectable); + isValid = data && query !== data.val; + if (isValid && !this.eventBus.before("autocomplete", data.obj)) { + this.input.setQuery(data.val); + this.eventBus.trigger("autocomplete", data.obj); + return true; + } + return false; + }, + moveCursor: function moveCursor(delta) { + var query, $candidate, data, payload, cancelMove; + query = this.input.getQuery(); + $candidate = this.menu.selectableRelativeToCursor(delta); + data = this.menu.getSelectableData($candidate); + payload = data ? data.obj : null; + cancelMove = this._minLengthMet() && this.menu.update(query); + if (!cancelMove && !this.eventBus.before("cursorchange", payload)) { + this.menu.setCursor($candidate); + if (data) { + this.input.setInputValue(data.val); + } else { + this.input.resetInputValue(); + this._updateHint(); + } + this.eventBus.trigger("cursorchange", payload); + return true; + } + return false; + }, + destroy: function destroy() { + this.input.destroy(); + this.menu.destroy(); + } + }); + return Typeahead; + function c(ctx) { + var methods = [].slice.call(arguments, 1); + return function() { + var args = [].slice.call(arguments); + _.each(methods, function(method) { + return ctx[method].apply(ctx, args); + }); + }; + } + }(); + (function() { + "use strict"; + var old, keys, methods; + old = $.fn.typeahead; + keys = { + www: "tt-www", + attrs: "tt-attrs", + typeahead: "tt-typeahead" + }; + methods = { + initialize: function initialize(o, datasets) { + var www; + datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 1); + o = o || {}; + www = WWW(o.classNames); + return this.each(attach); + function attach() { + var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu, eventBus, input, menu, typeahead, MenuConstructor; + _.each(datasets, function(d) { + d.highlight = !!o.highlight; + }); + $input = $(this); + $wrapper = $(www.html.wrapper); + $hint = $elOrNull(o.hint); + $menu = $elOrNull(o.menu); + defaultHint = o.hint !== false && !$hint; + defaultMenu = o.menu !== false && !$menu; + defaultHint && ($hint = buildHintFromInput($input, www)); + defaultMenu && ($menu = $(www.html.menu).css(www.css.menu)); + $hint && $hint.val(""); + $input = prepInput($input, www); + if (defaultHint || defaultMenu) { + $wrapper.css(www.css.wrapper); + $input.css(defaultHint ? www.css.input : www.css.inputWithNoHint); + $input.wrap($wrapper).parent().prepend(defaultHint ? $hint : null).append(defaultMenu ? $menu : null); + } + MenuConstructor = defaultMenu ? DefaultMenu : Menu; + eventBus = new EventBus({ + el: $input + }); + input = new Input({ + hint: $hint, + input: $input + }, www); + menu = new MenuConstructor({ + node: $menu, + datasets: datasets + }, www); + typeahead = new Typeahead({ + input: input, + menu: menu, + eventBus: eventBus, + minLength: o.minLength + }, www); + $input.data(keys.www, www); + $input.data(keys.typeahead, typeahead); + } + }, + isEnabled: function isEnabled() { + var enabled; + ttEach(this.first(), function(t) { + enabled = t.isEnabled(); + }); + return enabled; + }, + enable: function enable() { + ttEach(this, function(t) { + t.enable(); + }); + return this; + }, + disable: function disable() { + ttEach(this, function(t) { + t.disable(); + }); + return this; + }, + isActive: function isActive() { + var active; + ttEach(this.first(), function(t) { + active = t.isActive(); + }); + return active; + }, + activate: function activate() { + ttEach(this, function(t) { + t.activate(); + }); + return this; + }, + deactivate: function deactivate() { + ttEach(this, function(t) { + t.deactivate(); + }); + return this; + }, + isOpen: function isOpen() { + var open; + ttEach(this.first(), function(t) { + open = t.isOpen(); + }); + return open; + }, + open: function open() { + ttEach(this, function(t) { + t.open(); + }); + return this; + }, + close: function close() { + ttEach(this, function(t) { + t.close(); + }); + return this; + }, + select: function select(el) { + var success = false, $el = $(el); + ttEach(this.first(), function(t) { + success = t.select($el); + }); + return success; + }, + autocomplete: function autocomplete(el) { + var success = false, $el = $(el); + ttEach(this.first(), function(t) { + success = t.autocomplete($el); + }); + return success; + }, + moveCursor: function moveCursoe(delta) { + var success = false; + ttEach(this.first(), function(t) { + success = t.moveCursor(delta); + }); + return success; + }, + val: function val(newVal) { + var query; + if (!arguments.length) { + ttEach(this.first(), function(t) { + query = t.getVal(); + }); + return query; + } else { + ttEach(this, function(t) { + t.setVal(newVal); + }); + return this; + } + }, + destroy: function destroy() { + ttEach(this, function(typeahead, $input) { + revert($input); + typeahead.destroy(); + }); + return this; + } + }; + $.fn.typeahead = function(method) { + if (methods[method]) { + return methods[method].apply(this, [].slice.call(arguments, 1)); + } else { + return methods.initialize.apply(this, arguments); + } + }; + $.fn.typeahead.noConflict = function noConflict() { + $.fn.typeahead = old; + return this; + }; + function ttEach($els, fn) { + $els.each(function() { + var $input = $(this), typeahead; + (typeahead = $input.data(keys.typeahead)) && fn(typeahead, $input); + }); + } + function buildHintFromInput($input, www) { + return $input.clone().addClass(www.classes.hint).removeData().css(www.css.hint).css(getBackgroundStyles($input)).prop("readonly", true).removeAttr("id name placeholder required").attr({ + autocomplete: "off", + spellcheck: "false", + tabindex: -1 + }); + } + function prepInput($input, www) { + $input.data(keys.attrs, { + dir: $input.attr("dir"), + autocomplete: $input.attr("autocomplete"), + spellcheck: $input.attr("spellcheck"), + style: $input.attr("style") + }); + $input.addClass(www.classes.input).attr({ + autocomplete: "off", + spellcheck: false + }); + try { + !$input.attr("dir") && $input.attr("dir", "auto"); + } catch (e) {} + return $input; + } + function getBackgroundStyles($el) { + return { + backgroundAttachment: $el.css("background-attachment"), + backgroundClip: $el.css("background-clip"), + backgroundColor: $el.css("background-color"), + backgroundImage: $el.css("background-image"), + backgroundOrigin: $el.css("background-origin"), + backgroundPosition: $el.css("background-position"), + backgroundRepeat: $el.css("background-repeat"), + backgroundSize: $el.css("background-size") + }; + } + function revert($input) { + var www, $wrapper; + www = $input.data(keys.www); + $wrapper = $input.parent().filter(www.selectors.wrapper); + _.each($input.data(keys.attrs), function(val, key) { + _.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val); + }); + $input.removeData(keys.typeahead).removeData(keys.www).removeData(keys.attr).removeClass(www.classes.input); + if ($wrapper.length) { + $input.detach().insertAfter($wrapper); + $wrapper.remove(); + } + } + function $elOrNull(obj) { + var isValid, $el; + isValid = _.isJQuery(obj) || _.isElement(obj); + $el = isValid ? $(obj).first() : []; + return $el.length ? $el : null; + } + })(); +}); \ No newline at end of file diff --git a/vendor/assets/stylesheets/typeaheadjs.css b/vendor/assets/stylesheets/typeaheadjs.css new file mode 100644 index 0000000..c68acd7 --- /dev/null +++ b/vendor/assets/stylesheets/typeaheadjs.css @@ -0,0 +1,54 @@ +span.twitter-typeahead { + width: 100%; +} +.input-group span.twitter-typeahead { + display: block !important; +} +.input-group span.twitter-typeahead .tt-dropdown-menu { + top: 32px !important; +} +.input-group.input-group-lg span.twitter-typeahead .tt-dropdown-menu { + top: 44px !important; +} +.input-group.input-group-sm span.twitter-typeahead .tt-dropdown-menu { + top: 28px !important; +} +.tt-query { + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.tt-hint { + color: #999 +} + +.tt-menu { // used to be tt-dropdown-menu in older versions + width: 422px; + margin-top: 4px; + padding: 4px 0; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2); + -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2); + box-shadow: 0 5px 10px rgba(0,0,0,.2); +} + +.tt-suggestion { + padding: 3px 20px; + line-height: 24px; +} + +.tt-suggestion.tt-cursor { + color: #fff; + background-color: #0097cf; + +} + +.tt-suggestion p { + margin: 0; +}