Dokumentation für das Modul GetNumber/Test[Ansicht] [Bearbeiten] [Versionsgeschichte] [Aktualisieren]

Verwendung

Das Submodul ist eine Testversion des Moduls GetNumber und nicht für den Produktivbetrieb geeignet. Es dient der Weiterentwicklung des Moduls GetNumber, damit sich Änderungen nicht auf alle Artikel auswirken, die das Modul benutzen.

Das Modul ist eine Spielwiese und nicht zum produktiven Einsatz vorgesehen. Der derzeitige Code ist eine finale Testversion. Er enthält für Analysezwecke zusätzliche Wikidata-Abfragen und Ausgaben.

Beispiele

getNumbersWithUnit

Fläche:

  • Sabah (Standard): {{#invoke:GetNumber/Test|getNumbersWithUnit|Q1208|P2046}} – 29.479 km²
  • Sabah (Standard, 2 Kommastellen): {{#invoke:GetNumber/Test|getNumbersWithUnit|Q1208|P2046|||2}} – 29.478,63 km²
  • Manhattan (Standard, lang): {{#invoke:GetNumber/Test|getNumbersWithUnit|Q11299|P2046|6=long}} – 86.971.801 Quadratkilometer
  • Manhattan (km² angefordert, auf WD vorhanden): {{#invoke:GetNumber/Test|getNumbersWithUnit|Q11299|P2046|Q712226}} – 86.971.801 km²
  • Manhattan (mi² angefordert, auf WD vorhanden): {{#invoke:GetNumber/Test|getNumbersWithUnit|Q11299|P2046|Q232291}} – 34 mi²
  • Manhattan (ft² angefordert, auf WD nicht vorhanden): {{#invoke:GetNumber/Test|getNumbersWithUnit|Q11299|P2046|Q857027}} – 936.156.672
  • Manhattan (ha angefordert, auf WD nicht vorhanden): {{#invoke:GetNumber/Test|getNumbersWithUnit|Q11299|P2046|Q35852}} – 8.697 ha
  • Manhattan (ft² angefordert, auf WD nicht vorhanden, aber beide Werte umgerechnet - sollten eigentlich gleich sein): {{#invoke:GetNumber/Test|getNumbersWithUnit|Q11299|P2046|Q857027|all}} – 936.156.672
  • Manhattan (ac angefordert, im Modul nicht bekannt): {{#invoke:GetNumber/Test|getNumbersWithUnit|Q11299|P2046|Q81292}} – (keine Ausgabe, nur Fehlerkategorie)

Höhe:

  • Cottbus (Standard): {{#invoke:GetNumber/Test|getNumbersWithUnit|Q3214|P2044}} – 76 m

Netzspannung

  • Demokratische Republik Kongo {{#invoke:GetNumber/Test|getNumbersWithUnit|Q974|P2884}} – 220 V, 50 Hz

weitere Größen

  • Inle-See
    • Länge: {{#invoke:GetNumber/Test|getNumbersWithUnit|Q1043461|P2043}} – 22 km
    • Länge in Metern: {{#invoke:GetNumber/Test|getNumbersWithUnit|Q1043461|P2043|Q11573}} – 22.000 m
    • Breite: {{#invoke:GetNumber/Test|getNumbersWithUnit|Q1043461|P2049}} – 10 km
    • Tiefe: {{#invoke:GetNumber/Test|getNumbersWithUnit|Q1043461|P4511}} – 4 m
    • Fläche: {{#invoke:GetNumber/Test|getNumbersWithUnit|Q1043461|P2046}} – 120 km²

Preis:

  • Pfund Sterling (Umrechnungskurs): {{#invoke:GetNumber/Test|getNumbersWithUnit|Q25224|P2284|5{{=}}2|6{{=}}short-date-ref}} – 1,18 € (17.10.2023)[1]

Fehler:

  • Cottbus (keine richtige Property angegeben, z. B. "P" vergessen): {{#invoke:GetNumber/Test|getNumbersWithUnit|Q3214|0} (keine Ausgabe, nur Fehlerkategorie)
  • Cottbus (keine bekannte Property angegeben): {{#invoke:GetNumber/Test|getNumbersWithUnit|Q3214|P0}} (keine Ausgabe, nur Fehlerkategorie)
Cottbus
Höhe76 m
Fläche166 km²


Cottbus
Höhe77 m
Fläche166 km²


getNumbersWithDate

Einwohnerzahl:

  • Kleinmachnow (Einwohnerzahl): {{#invoke:GetNumber/Test|getNumbersWithDate|Q104192|P1082}} – 20.152
  • Kleinmachnow (Einwohnerzahl+Jahr): {{#invoke:GetNumber/Test|getNumbersWithDate|Q104192|P1082||year}} – 20.152 (2023)

Passagierzahl:

  • Flughafen Frankfurt am Main (Passagierzahl): {{#invoke:GetNumber/Test|getNumbersWithDate|Q46033|P3872}} – 48.918.482
  • Flughafen Frankfurt am Main (Passagierzahl+Jahr): {{#invoke:GetNumber/Test|getNumbersWithDate|Q46033|P3872||year}} – 48.918.482 (2022)
  • Flughafen Frankfurt am Main (Passagierzahl unformatiert): {{#invoke:GetNumber/Test|getNumbersWithDate|Q46033|P3872||plain}} – 48918482

getNumbersWithUnitQuickbar + getNumbersWithDateQuickbar

Beispiele von oben
Höhe76 m
Fläche166 km²
Einwohnerzahl20.152 (2023)
Passagierzahl48.918.482 (2022)


getCoordinateAsText

Koordinate:

  • Kota Kinabalu: {{#invoke:GetNumber/Test|getCoordinateAsText|Q137271}} – 5,975; 116,0725

Quickbars

Test WD-Abgleich anhand Hà Giang (Provinz). Daten fehlen auf WD > sollten nicht als unterschiedlich dargestellt werden.

Beispiele von oben
Fläche7.884,3 km²
Einwohnerzahl660.700
Postleitzahl20000–20999
Webseitewww.hagiang.gov.vn


Quickbars mit Unterdrückung der Anzeige

Test Abwahl über "no" anhand Hà Giang (Provinz).

Beispiele von oben
Postleitzahl20000–20999
Webseitewww.hagiang.gov.vn



Währungen

LandWährungKurs WikidataKurs Commons
AfghanistanAFN 0,01161 € (03.02.2019)
ÄgyptenEGP 0,018 € (06.03.2024)[23]0,030789 € (23.02.2023)[2]
AlbanienALL 0,008224 € (03.02.2019)0,008685 € (23.02.2023)[2]
AlgerienDZD 0,007354 € (03.02.2019)0,006894 € (23.02.2023)[2]
AndorraEUR 
AngolaAOA 0,002792 € (03.02.2019)
Antigua und BarbudaXCD 0,347994 € (23.02.2023)[2]
ÄquatorialguineaXAF 0,001524 € (23.02.2023)[2]
ArgentinienARS 0,01511 € (26.01.2020)0,004838 € (23.02.2023)[2]
ArmenienAMD 0,001792 € (03.02.2019)
ArzachAMD 0,001792 € (03.02.2019)
AserbaidschanAZN 0,48044 € (20.03.2018)
ÄthiopienETB 0,030593 € (03.02.2019)
AustralienAUD 0,61699 € (03.01.2024)0,601287 € (19.12.2024)[5]
BahamasBSD 0,943058 € (23.02.2023)[2]
BahrainBHD 2,508151 € (23.02.2023)[2]
BangladeschBDT 0,008815 € (23.02.2023)[2]
BarbadosBBD 0,471531 € (23.02.2023)[2]
BelarusBYN 0,41234 €
BelgienEUR 
BelizeBZD 
BeninXOF 0,001524 €0,001524 € (23.02.2023)[2]
BhutanBTN 
BolivienBOB 0,128041 € (03.02.2019)0,136338 € (23.02.2023)[2]
Bosnien und HerzegowinaBAM 0,511292 € (23.02.2023)[2]
BotsuanaBWP 0,071103 € (23.02.2023)[2]
BrasilienBRL 0,23234 € (23.05.2018)0,153057 € (19.12.2024)[5]
BruneiBND 
BulgarienBGN 0,511291 €[7][8]0,5113 € (19.12.2024)[5]
Burkina FasoXOF 0,001524 €0,001524 € (23.02.2023)[2]
BurundiBIF 0,000496 €
ChileCLP 0,001182 € (23.02.2023)[2]
ChinaCNY 0,131825 € (19.12.2024)[5]
CookinselnNZD 0,585 € (07.02.2020)0,543863 € (19.12.2024)[5]
Costa RicaCRC 0,001423 € (27.08.2020)0,00169 € (23.02.2023)[2]
DänemarkDKK 0,13404 € (18.09.2018)[28]0,134025 € (19.12.2024)[5]
Demokratische Republik KongoCDF 0,000556 € (03.02.2019)
DeutschlandEUR 
DominicaXCD 0,347994 € (23.02.2023)[2]
Dominikanische RepublikDOP 0,017293 € (03.02.2019)0,016897 € (23.02.2023)[2]
DschibutiDJF 
EcuadorUSD 0,8403 € (23.11.2020)[3]0,962001 € (19.12.2024)[5]
El SalvadorUSD 0,8403 € (23.11.2020)[3]0,962001 € (19.12.2024)[5]
ElfenbeinküsteXOF 0,001524 €0,001524 € (23.02.2023)[2]
EritreaERN 
EstlandEUR 
EswatiniSZL 
FäröerFOK 
FidschiFJD 0,41292 €0,428234 € (23.02.2023)[2]
FinnlandEUR 
FrankreichEUR 
GabunXAF 0,001524 € (23.02.2023)[2]
GambiaGMD 0,017641 € (03.02.2019)
GeorgienGEL 0,356318 € (01.08.2022)0,348374 € (26.11.2024)[2]
GhanaGHS 0,17689 € (03.02.2019)
GrenadaXCD 0,347994 € (23.02.2023)[2]
GriechenlandEUR 
GuatemalaGTQ 0,1126 € (03.02.2019)0,12075 € (23.02.2023)[2]
Guinea-BissauXOF 0,001524 €0,001524 € (23.02.2023)[2]
GuineaGNF 0 € (03.02.2019)
GuyanaGYD 0,004053 € (27.08.2020)
HaitiHTG 0,00755 € (27.08.2020)
HondurasHNL 0,035873 € (03.02.2019)
IndienINR 0,012761 € (07.02.2020)0,011302 € (19.12.2024)[5]
IndonesienIDR 0 € (19.12.2024)[5]
IrakIQD 0,00071 € (27.08.2020)0,000646 € (23.02.2023)[2]
IranIRR 0 € (23.02.2023)[2]
IrlandEUR 
IslandISK 0,006596 € (18.03.2021)[11]0,006911 € (19.12.2024)[5]
IsraelILS 0,265625 € (19.12.2024)[5]
ItalienEUR 
JamaikaJMD 0,005635 € (27.08.2020)0,006072 € (23.02.2023)[2]
JapanJPY 0,0086 € (04.05.2020)0,006132 € (19.12.2024)[5]
JemenYER 
JordanienJOD 1,330123 € (23.02.2023)[2]
KambodschaKHR 0,000207 € (27.08.2020)
KamerunXAF 0,001524 € (23.02.2023)[2]
KanadaCAD 0,685 € (07.02.2020)0,669792 € (19.12.2024)[5]
Kap VerdeCVE 0,009069 €
KasachstanKZT 
KatarQAR 0,259083 € (23.02.2023)[2]
KeniaKES 0,007818 € (28.08.2020)0,007465 € (23.02.2023)[2]
KirgisistanKGS 0,010816 € (27.08.2020)
KiribatiKID 
KolumbienCOP 0,000193 € (23.02.2023)[2]
KomorenKMF 0,002033 €
KosovoEUR 
KroatienEUR 
KubaCUP 0,039428 € (23.02.2023)[2]
KuwaitKWD 3,073141 € (23.02.2023)[2]
LaosLAK 0 € (27.08.2020)
LesothoLSL 
LettlandEUR 
LibanonLBP 0 € (23.02.2023)[2]
LiberiaLRD 0,005429 € (03.02.2019)
LibyenLYD 0,61786 € (28.08.2020)
LiechtensteinCHF 0,9341 € (07.02.2020)1,073077 € (19.12.2024)[5]
LitauenEUR 
LuxemburgEUR 
MadagaskarMGA 0,00022 € (28.08.2020)
MalawiMWK 
MalaysiaMYR 0,220206 € (07.02.2020)0,213516 € (19.12.2024)[5]
MaledivenMVR 0,055741 € (03.02.2019)
MaliXOF 0,001524 €0,001524 € (23.02.2023)[2]
MaltaEUR 
MarokkoMAD 0,1 € (06.05.2024)0,0907 € (23.02.2023)[2]
MarshallinselnUSD 0,8403 € (23.11.2020)[3]0,962001 € (19.12.2024)[5]
MauretanienMRO 0,027176 € (17.03.2023)
MauritiusMUR 0,020438 € (23.02.2023)[2]
MexikoMXN 0,048714 € (07.02.2020)0,047317 € (19.12.2024)[5]
MikronesienUSD 0,8403 € (23.11.2020)[3]0,962001 € (19.12.2024)[5]
MoldauMDL 0,051195 € (26.01.2020)
MonacoEUR 
MongoleiMNT 0,000334 € (03.02.2019)
MontenegroEUR 
MosambikMZN 0,011812 € (28.08.2020)
MyanmarMMK 0,000631 € (27.08.2020)
NamibiaNAD 
NauruAUD 0,61699 € (03.01.2024)0,601287 € (19.12.2024)[5]
NepalNPR 0,007072 € (26.11.2024)[2]
NeuseelandNZD 0,585 € (07.02.2020)0,543863 € (19.12.2024)[5]
NicaraguaNIO 0,024271 € (27.08.2020)
NiederlandeEUR 
NigerXOF 0,001524 €0,001524 € (23.02.2023)[2]
NigeriaNGN 0,002266 € (20.03.2018)0,002048 € (23.02.2023)[2]
NiueNZD 0,585 € (07.02.2020)0,543863 € (19.12.2024)[5]
NordkoreaKPW 0,0009 € (23.03.2018)
Nördliche MarianenUSD 0,8403 € (23.11.2020)[3]0,962001 € (19.12.2024)[5]
NordmazedonienMKD 0,016226 € (27.08.2020)
NordzypernTRY 0,1845 € (04.06.2018)0,02743 € (19.12.2024)[5]
NorwegenNOK 0,086 € (09.04.2024)0,084643 € (19.12.2024)[5]
OmanOMR 2,44924 € (23.02.2023)[2]
ÖsterreichEUR 
OsttimorUSD 0,8403 € (23.11.2020)[3]0,962001 € (19.12.2024)[5]
PakistanPKR 0,005864 € (26.01.2020)0,003605 € (23.02.2023)[2]
PalästinaJOD 1,330123 € (23.02.2023)[2]
PalauUSD 0,8403 € (23.11.2020)[3]0,962001 € (19.12.2024)[5]
PanamaPAB 
Papua-NeuguineaPGK 0,24281 € (27.08.2020)
ParaguayPYG 0,000139 € (26.01.2020)0,000129 € (23.02.2023)[2]
PeruPEN 0,23735 € (27.08.2020)0,248315 € (23.02.2023)[2]
PhilippinenPHP 0,01617 € (09.08.2023)0,016288 € (19.12.2024)[5]
PolenPLN 0,227035 € (24.07.2020)[21]0,235294 € (19.12.2024)[5]
PortugalEUR 
Republik KongoXAF 0,001524 € (23.02.2023)[2]
RuandaRWF 
RumänienRON 0,2 € (06.11.2024)0,200965 € (19.12.2024)[5]
RusslandRUB 0,012572 € (23.02.2023)[2]
Saint Kitts und NevisXCD 0,347994 € (23.02.2023)[2]
Saint LuciaXCD 0,347994 € (23.02.2023)[2]
Saint Vincent und die GrenadinenXCD 0,347994 € (23.02.2023)[2]
SalomonenSBD 0,109146 € (03.02.2019)
SambiaZMW 0,047849 € (23.02.2023)[2]
SamoaWST 
San MarinoEUR 
Saudi-ArabienSAR 0,251483 € (23.02.2023)[2]
SchwedenSEK 0,09718 € (23.05.2018)0,087241 € (19.12.2024)[5]
SchweizCHF 0,9341 € (07.02.2020)1,073077 € (19.12.2024)[5]
SenegalXOF 0,001524 €0,001524 € (23.02.2023)[2]
SerbienRSD 0,00849 € (27.08.2020)
SeychellenSCR 0,047399 € (28.08.2020)
Sierra LeoneSEK 0,09718 € (23.05.2018)0,087241 € (19.12.2024)[5]
SimbabweUSD 0,8403 € (23.11.2020)[3]0,962001 € (19.12.2024)[5]
SingapurSGD 0,66845 € (17.01.2020)0,707664 € (19.12.2024)[5]
SlowakeiEUR 
SlowenienEUR 
SomaliaSOS 0,001467 € (28.08.2020)
SpanienEUR 
Sri LankaLKR 0,002582 € (23.02.2023)[2]
SüdafrikaZAR 0,052535 € (19.12.2024)[5]
SudanSDG 0,0019 € (03.02.2019)
SüdkoreaKRW 0,000763 € (07.02.2020)0,000664 € (19.12.2024)[5]
SüdsudanSSP 0,00647 € (24.10.2020)
SurinameSRD 0,11774 € (03.02.2019)
SyrienSYP 0,001653 € (27.08.2020)
São Tomé und PríncipeSTN 0,040816 €
TadschikistanTJS 0,08202 € (27.08.2020)
TaiwanTWD 0,028008 € (20.03.2018)0,031029 € (23.02.2023)[2]
TansaniaTZS 0,000396 € (04.02.2023)
ThailandTHB 0,027993 € (08.02.2019)0,02782 € (19.12.2024)[5]
TogoXOF 0,001524 €0,001524 € (23.02.2023)[2]
TongaTOP 
TransnistrienPRB 
Trinidad und TobagoTTD 0,138855 € (23.02.2023)[2]
TschadXAF 0,001524 € (23.02.2023)[2]
TschechienCZK 0,039 € (07.06.2018)0,039798 € (19.12.2024)[5]
TunesienTND 0,33958 €0,303385 € (23.02.2023)[2]
TürkeiTRY 0,1845 € (04.06.2018)0,02743 € (19.12.2024)[5]
TurkmenistanTMT 
TuvaluTVD 
UgandaUGX 0,00023 € (28.08.2020)
UkraineUAH 0,028976 € (06.02.2018)[16]0,025699 € (23.02.2023)[2]
UngarnHUF 0,00296 € (07.02.2020)0,002404 € (19.12.2024)[5]
UruguayUYU 0,023965 € (23.02.2023)[2]
UsbekistanUZS 0 € (27.08.2020)
VanuatuVUV 0,007755 € (03.02.2019)
VatikanstadtEUR 
VenezuelaVES 0 € (01.12.2020)
Vereinigte Arabische EmirateAED 0,25679 € (23.02.2023)[2]
Vereinigte StaatenUSD 0,8403 € (23.11.2020)[3]0,962001 € (19.12.2024)[5]
Vereinigtes KönigreichGBP 1,180998 € (17.10.2023)[25]1,21293 € (19.12.2024)[5]
VietnamVND 0 € (03.02.2019)0 € (23.02.2023)[2]
WestsaharaMAD 0,1 € (06.05.2024)0,0907 € (23.02.2023)[2]
Zentralafrikanische RepublikXAF 0,001524 € (23.02.2023)[2]
ZypernEUR 

Einzelnachweise

  1. https://www.visa.de/support/verbraucher/visa-reiseservices/exchange-rate-calculator.html
  2. 2,00 2,01 2,02 2,03 2,04 2,05 2,06 2,07 2,08 2,09 2,10 2,11 2,12 2,13 2,14 2,15 2,16 2,17 2,18 2,19 2,20 2,21 2,22 2,23 2,24 2,25 2,26 2,27 2,28 2,29 2,30 2,31 2,32 2,33 2,34 2,35 2,36 2,37 2,38 2,39 2,40 2,41 2,42 2,43 2,44 2,45 2,46 2,47 2,48 2,49 2,50 2,51 2,52 2,53 2,54 2,55 2,56 2,57 2,58 2,59 2,60 2,61 2,62 2,63 2,64 2,65 2,66 2,67 www.xe.com
  3. 3,0 3,1 3,2 3,3 3,4 3,5 3,6 3,7 3,8 www.ecb.europa.eu
  4. https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/eurofxref-graph-usd.en.html
  5. 5,00 5,01 5,02 5,03 5,04 5,05 5,06 5,07 5,08 5,09 5,10 5,11 5,12 5,13 5,14 5,15 5,16 5,17 5,18 5,19 5,20 5,21 5,22 5,23 5,24 5,25 5,26 5,27 5,28 5,29 5,30 5,31 5,32 5,33 5,34 5,35 5,36 5,37 5,38 5,39 5,40 5,41 5,42 www.ecb.europa.eu
  6. https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/eurofxref-graph-usd.en.html
  7. eur-lex.europa.eu
  8. eur-lex.europa.eu
  9. https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:31998Y1231(01)
  10. https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:C2020/244/01
  11. eur-lex.europa.eu
  12. https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=uriserv:OJ.C_.2021.093.01.0015.01.ENG
  13. https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/eurofxref-graph-usd.en.html
  14. https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/eurofxref-graph-usd.en.html
  15. https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/eurofxref-graph-usd.en.html
  16. bank.gov.ua
  17. http://bank.gov.ua/NBUStatService/v1/statdirectory/exchange?json
  18. https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/eurofxref-graph-usd.en.html
  19. https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/eurofxref-graph-usd.en.html
  20. https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/eurofxref-graph-usd.en.html
  21. eur-lex.europa.eu
  22. https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=uriserv:OJ.C_.2020.246.01.0001.01.DEU
  23. www.xe.com
  24. https://www.xe.com/currencyconverter/convert/?Amount=1&From=EGP&To=EUR
  25. www.visa.de
  26. https://www.visa.de/support/verbraucher/visa-reiseservices/exchange-rate-calculator.html
  27. https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/eurofxref-graph-usd.en.html
  28. www.nationalbanken.dk
  29. http://www.nationalbanken.dk/da/statistik/valutakurs/Sider/Default.aspx
Hinweise
--[=[ GetNumber 2023-12-31
* local nilIf (nil handling function for internal use)
* local coalesce (nil handling function for internal use)
* local _round (rounding function for internal use)
*
* local getNumbersAsTable (internal use)
* local getCoordinatesAsTable (internal use)
*
* getNumbersWithUnit
* getNumbersWithDate
* getCoordinate
* getCoordinateAsText
* getNumbersWithUnitQuickbar
* getNumbersWithDateQuickbar
* getExchangeRatesList 
]=]
local GetNumber = {}

-- local tables > maybe moving into a separate module later
-- categories for data evaluation
local wikidataCat = {
   -- common wikidata categories
   noConversion    = '[[Kategorie:Wikidata:Fehlende Umrechnung]]',
   noProperty      = '[[Kategorie:Wikidata:Fehlende Eigenschaft]]',
   unknownProperty = '[[Kategorie:Wikidata:Unbekannte Eigenschaft]]',
   unknownUnit     = '[[Kategorie:Wikidata:Unbekannte Einheit]]',
   -- area
   P2046 = {
      equalData    = '[[Kategorie:Artikel mit identischer Fläche auf Wikidata]]',
      noEqualData  = '[[Kategorie:Artikel mit abweichender Fläche auf Wikidata]]',
      noData       = '[[Kategorie:Artikel ohne Fläche auf Wikidata]]'
   },
   -- altitude
   P2044 = {
      equalData    = '[[Kategorie:Artikel mit identischer Höhe über dem Meeresspiegel auf Wikidata]]',
      noEqualData  = '[[Kategorie:Artikel mit abweichender Höhe über dem Meeresspiegel auf Wikidata]]',
      noData       = '[[Kategorie:Artikel ohne Höhe über dem Meeresspiegel auf Wikidata]]'
   },
   -- height
   P2048 = {
      equalData    = '[[Kategorie:Artikel mit identischer Höhe auf Wikidata]]',
      noEqualData  = '[[Kategorie:Artikel mit abweichender Höhe auf Wikidata]]',
      noData       = '[[Kategorie:Artikel ohne Höhe auf Wikidata]]'
   },
   -- population
   P1082 = {
      equalData    = '[[Kategorie:Artikel mit identischer Einwohnerzahl auf Wikidata]]',
      noEqualData  = '[[Kategorie:Artikel mit abweichender Einwohnerzahl auf Wikidata]]',
      noData       = '[[Kategorie:Artikel ohne Einwohnerzahl auf Wikidata]]'
   },
   -- passengers
   P3872 = {
      equalData    = '[[Kategorie:Artikel mit identischer Passagierzahl auf Wikidata]]',
      noEqualData  = '[[Kategorie:Artikel mit abweichender Passagierzahl auf Wikidata]]',
      noData       = '[[Kategorie:Artikel ohne Passagierzahl auf Wikidata]]'
   },
   -- Koordinaten
   P625 = {
      noData       = '[[Kategorie:Artikel ohne Koordinaten auf Wikidata]]'
   },
   -- Preis
   P2284 = {
      noData       = '[[Kategorie:Artikel ohne Preis auf Wikidata]]'
   }

}

local lang = mw.language.new( 'de' )

-- units and conversion
-- getting conversion data from wikidata is not implemented yet
local units = require ( 'Modul:GetNumber/Units' )

-- returns nil, if both values are equal, otherwise the value
-- similar to the SQL function nullif()
local function nilIf ( value, equalValue )

   if ( value == nil ) then
      return nil
   elseif ( tostring ( value ) == tostring ( equalValue ) ) then
      return nil
   else
      return value
   end

end

-- returns the first value that is not nil
-- similar to the SQL function coalesce()
local function coalesce ( value1, value2, value3 )
   return value1 or value2 or value3
end

-- round function, which is not available in Lua
local _round = function  ( value, precision )
   local rescale = math.pow(10, precision or 0);
   return math.floor(value * rescale + 0.5) / rescale;
end

-- getNumbersAsTable() -> just for internal use.
-- gets the amount of a property including its unit and date of validity
--   id: Wikidata-ID (own, if not provided)
--   property: requested property
--   unit: wanted unit (standard unit, if not provided)
--         if the wanted unit is not provided, a conversion will be tried based on the given conversion numbers
--   values:
--      - single (standard): Only one (first) entry is shown
--      - all: All entries are fetched

-- the functions returns a table with the folowing columns:
-- amount
-- unit
-- unitOriginal (differs to unit, if the requested unit is converted)
-- year (set to 0, if not provided)
local getNumbersAsTable = function ( id, property, unit, values )

   -- local variables
   -- ID of the item
   -- Determined, if not provided
   local localID = id or mw.wikibase.getEntityIdForCurrentPage() or ''
   
   -- compatibility to existing modules and templates:
   -- some use the keyword "self" for using the own entity-ID
   if coalesce ( nilIf ( localID, 'self' ), '' ) == '' then
      localID = mw.wikibase.getEntityIdForCurrentPage() or ''
   end

   -- no Wikidata object
   if localID == '' then
      return {}, '', ''
   end
   
   -- maintenance categories
   local maintenanceCategory = ''

   -- property
   local requestedProperty = property or 'none';
   if string.sub(requestedProperty,1,1) ~= 'P' then
      requestedProperty = 'none'
   end

   -- no property given: category and exit
   if requestedProperty == 'none' then
      maintenanceCategory = maintenanceCategory .. wikidataCat.noProperty
      return {}, localID, maintenanceCategory
   end

   -- property unknown in table "units": category and exit
   if units[requestedProperty] == nil then
      maintenanceCategory = maintenanceCategory .. wikidataCat.unknownProperty
      return {}, localID, maintenanceCategory
   end

   -- unit
   local requestedUnit = 'none'
   if coalesce ( unit, '' ) == '' then
      if units[requestedProperty] ~= nil then
         requestedUnit = units[requestedProperty].standard
      end
   else
      requestedUnit = unit
      if units[requestedUnit] == nil then
         maintenanceCategory = maintenanceCategory .. wikidataCat.unknownUnit
      end
   end

   -- values
   local requestedValues = values or 'single'

   -- control variable
   -- is set to true, when requested unit is got on the first run
   local hasRequested = false

   -- getting the values
   local wdStatements = mw.wikibase.getBestStatements( localID, requestedProperty )

   -- running through the array and store it in a simple table
   local wdValues = {}
   local referenceValues = {}
   local entryValue
   for i, entry in ipairs ( wdStatements ) do

      -- check for value
      if entry.mainsnak.snaktype == 'value' then

         -- check for number
         if entry.mainsnak.datatype == 'quantity' then

            -- new data set
            entryValue = {}

            -- getting the amount, converted into a number
            entryValue.amount = tonumber ( entry.mainsnak.datavalue.value.amount )

            -- getting the unit
            entryValue.unit = entry.mainsnak.datavalue.value.unit:gsub( 'https?://www.wikidata.org/entity/', '' ) or ''

            -- save a copy of the original unit
            -- in case somebody wants to know, whether a value is converted
            entryValue.unitOriginal = entryValue.unit

            -- check, whether its the requested unit
            if entryValue.unit == requestedUnit then
               hasRequested = true
            end
            
            -- initialising qualifiers
            entryValue.year = 0
            
            -- read qualifiers
            if entry.qualifiers ~= nil then

               -- read P585-Qualifiers (date/time of validity)
               if entry.qualifiers.P585 ~= nil then
                  if entry.qualifiers.P585[1].datavalue.value.precision == 9 then
                     entryValue.year = tonumber ( entry.qualifiers.P585[1].datavalue.value.time:sub( 2, 5 ) )
                     entryValue.time = entry.qualifiers.P585[1].datavalue.value.time
                  end
                  if entry.qualifiers.P585[1].datavalue.value.precision == 10 then
                     entryValue.year = tonumber ( entry.qualifiers.P585[1].datavalue.value.time:sub( 2, 5 ) )
                     entryValue.time = entry.qualifiers.P585[1].datavalue.value.time
                  end
                  if entry.qualifiers.P585[1].datavalue.value.precision == 11 then
                     entryValue.year = tonumber ( entry.qualifiers.P585[1].datavalue.value.time:sub( 2, 5 ) )
                     entryValue.time = entry.qualifiers.P585[1].datavalue.value.time
                  end
               end
               
               -- read P2144-Qualifier (frequency)
               if entry.qualifiers.P2144 ~= nil then
                  if entry.qualifiers.P2144[1].datavalue ~= nil then
                     entryValue.P2144 = tonumber ( entry.qualifiers.P2144[1].datavalue.value.amount )
                     maintenanceCategory = maintenanceCategory .. '[[Kategorie:Seiten, die die Wikidata-Eigenschaft P2144 benutzen]]'
                  end
               end
               
            end

            referenceValues = {}

            -- read references
            if entry.references ~= nil then

               for j, referenceEntry in ipairs ( entry.references ) do
                  if referenceEntry.snaks ~= nil then
                     if referenceEntry.snaks.P854 ~= nil then
                        if referenceEntry.snaks.P854[1].snaktype == 'value' then
                           table.insert( referenceValues, referenceEntry.snaks.P854[1].datavalue.value )
                        end
                     end
                  end
               end -- for j, referenceEntry in ipairs ( entry.references )

            end -- if entry.references ~= nil

            entryValue.references = referenceValues

            -- adding to the list
            table.insert( wdValues, entryValue )

         end -- if entry.mainsnak.datatype == 'quantity'

      end -- if entry.mainsnak.snaktype == 'value'

   end -- for i, entry in ipairs ( wdStatements )


   -- nothing found then exit
   if wdValues == {} then
      if wikidataCat[requestedProperty] ~= nil then
         maintenanceCategory = maintenanceCategory .. wikidataCat[requestedProperty].noData
      end
      return {}, localID, maintenanceCategory
   end

   -- generating the returning values
   local returnValues = {}

   -- controll tag, for getting all or just one value
   local noFetch = false

   -- iterating variable
   local i = 1

   -- requested unit found?
   if hasRequested then

      -- getting the values, no conversion needed
      repeat

         -- getting a row
         entryValue = wdValues[i]

         -- put the entry to the list, if its the requested unit
         if entryValue.unit == requestedUnit then

            -- adding the row to the final result table
            table.insert( returnValues, entryValue )

            -- stopping, if only one value is requested
            if requestedValues == 'single' then
               noFetch = true
            end

         end

         -- counting up
         i = i + 1

      until noFetch or i > #wdValues

   -- requested unit not found
   -- trying conversion
   else
      
      -- tagging, if its succeeded at least once
      local conversionSuccess = true

      -- check, whether there is at least on data set
      if wdValues[i] ~= nil then

         -- initialize with false
         conversionSuccess = false

         -- getting the values and trying conversion
         repeat

            -- getting a row
            entryValue = wdValues[i]

            -- put the entry to the list, if the unit and conversion are available
            if units[entryValue.unit] ~= nil then
               if units[entryValue.unit].conversion[requestedUnit] ~= nil then

                  -- adding the row to the final result table
                  table.insert( 
                     returnValues, 
                     { 
                        amount = entryValue.amount * units[entryValue.unit].conversion[requestedUnit],
                        unit = requestedUnit,
                        unitOriginal = entryValue.unit,
                        year = entryValue.year
                     }
                  )

                  -- stopping, if only one value is requested
                  if requestedValues == 'single' then
                     noFetch = true
                  end

                  -- tagging as success
                  conversionSuccess = true

               end
            end

            -- counting up
            i = i + 1

         until noFetch or i > #wdValues

      end

      -- setting category, if not successfull
      if not conversionSuccess then
         maintenanceCategory = maintenanceCategory .. wikidataCat.noConversion
      end

   end -- if hasRequested then

   -- adding category
   if #returnValues > 0 then
      maintenanceCategory = maintenanceCategory .. '[[Kategorie:Seiten, die die Wikidata-Eigenschaft ' .. requestedProperty .. ' benutzen]]'
   end

   maintenanceCategory = maintenanceCategory -- .. mw.dumpObject( returnValues )

   return returnValues, localID, maintenanceCategory
 
end


-- getCoordinatesAsTable() -> just for internal use.
--   id: Wikidata-ID (own, if not provided)
--   property: Property (Standard: P625)

-- the functions returns a table with the following columns:
--   latitude
--   longitude
--   precision
local getCoordinatesAsTable = function ( id, property )

   -- local variables
   -- ID of the item
   -- Determined, if not provided
   local localID = id or mw.wikibase.getEntityIdForCurrentPage() or ''
   
   -- compatibility to existing modules and templates:
   -- some use the keyword "self" for using the own entity-ID
   if ( ( localID == 'self' ) or ( localID == '' ) ) then
      localID = mw.wikibase.getEntityIdForCurrentPage() or ''
   end

   -- no Wikidata object
   if localID == '' then
      return {}, '', ''
   end
   
   -- maintenance categories
   local maintenanceCategory = ''

   -- property
   local requestedProperty = property or 'none';
   if string.sub(requestedProperty,1,1) ~= 'P' then
      requestedProperty = 'none'
   end

   -- no property given: category and exit
   if requestedProperty == 'none' then
      maintenanceCategory = maintenanceCategory .. wikidataCat.noProperty
      return {}, localID, maintenanceCategory
   end

   -- property unknown in table "units": category and exit
   if units[requestedProperty] == nil then
      maintenanceCategory = maintenanceCategory .. wikidataCat.unknownProperty
      return {}, localID, maintenanceCategory
   end

   -- getting the values
   local wdStatements = mw.wikibase.getBestStatements( localID, requestedProperty )

   -- running through the array and store it in a simple table
   local wdValues = {}
   local entryValue
   for i, entry in ipairs ( wdStatements ) do

      -- check for value
      if entry.mainsnak.snaktype == 'value' then

         -- check for number
         if entry.mainsnak.datatype == 'globe-coordinate' then

            -- new data set
            entryValue = {}

            -- getting the values, converted into a number
            entryValue.latitude = tonumber ( entry.mainsnak.datavalue.value.latitude )
            entryValue.longitude = tonumber ( entry.mainsnak.datavalue.value.longitude )
            entryValue.precision = tonumber ( entry.mainsnak.datavalue.value.precision )

            -- adding to the list
            table.insert( wdValues, entryValue )

         end -- if entry.mainsnak.datatype == 'globe-coordinate'

      end -- if entry.mainsnak.snaktype == 'value'

   end -- for i, entry in ipairs ( wdStatements )

   -- nothing found then exit
   if wdValues == {} then
      return {}, localID, maintenanceCategory
   end

   -- adding category
   if #wdValues > 0 then
      maintenanceCategory = maintenanceCategory .. '[[Kategorie:Seiten, die die Wikidata-Eigenschaft ' .. requestedProperty .. ' benutzen]]'
   end

   return wdValues, localID, maintenanceCategory
 
end


-- getNumbersWithUnit() 
-- gets the amount of a property including its unit
--   first parameters: see internal function
--   values:
--      - single (standard): Only one (first) entry is shown
--      - all: All entries are fetched
--   precision: precision of the number (Standard: 0) 
--   show:
--      - number: formatted amount without unit
--      - plain: not formatted amount without unit
--      - short (standard): amount with short unit
--      - long: amount with long unit
--      - short-date: short with date
--      - short-date-ref: short with date and reference(s)
--   delimiter: delimiter between the numbers; standard is comma and breakable space
GetNumber.getNumbersWithUnit = function ( id, property, unit, values, precision, show, delimiter, frame )

   -- returning String
   local numberString = ''

   -- making empty parameters to nil
   if unit == '' then unit = nil end
   if values == '' then values = nil end

   -- WD-Values
   local numberList
   local wikidataID
   local categories
   numberList, wikidataID, categories = getNumbersAsTable ( id, property, unit, values )

   -- precision
   local numberPrecision = tonumber ( precision ) or 0

   -- show options
   local numberShow = show or 'short'

   -- no delimiter in front of the first entry
   local numberDelimiter = ''

   if numberList[1] == nil then
      return categories
   end

   -- displaying the values
   for i, entry in ipairs( numberList ) do

      -- no unit given or wanted
      if numberShow == 'number' then 
         numberString = numberString .. numberDelimiter .. lang:formatNum ( _round ( entry.amount, precision ) )
         
      elseif numberShow == 'plain' then 
         numberString = numberString .. numberDelimiter .. tostring ( entry.amount, precision )

      -- displaying with unit using its long name
      elseif numberShow == 'long' then

         if units[entry.unit] ~= nil then
            if _round ( entry.amount, precision ) == 1 then 
               numberString = numberString .. numberDelimiter .. lang:formatNum ( _round ( entry.amount, precision ) ) .. ' ' .. units[entry.unit].longSingle
            else
               numberString = numberString .. numberDelimiter .. lang:formatNum ( _round ( entry.amount, precision ) ) .. ' ' .. units[entry.unit].long
            end
         else
            numberString = numberString .. numberDelimiter .. lang:formatNum ( _round ( entry.amount, precision ) )
         end

      -- displaying with unit using its abbreviation
      elseif numberShow == 'short-date' then 

         if units[entry.unit] ~= nil then
            if entry.time ~= nil then
               numberString = numberString .. numberDelimiter .. lang:formatNum ( _round ( entry.amount, precision ) ) .. ' ' .. units[entry.unit].short .. ' <small>(' .. lang:formatDate( 'd.m.Y', entry.time ) .. ')</small>'
            else
               numberString = numberString .. numberDelimiter .. lang:formatNum ( _round ( entry.amount, precision ) ) .. ' ' .. units[entry.unit].short
            end
         else
            numberString = numberString .. numberDelimiter .. lang:formatNum ( _round ( entry.amount, precision ) )
         end

      -- displaying with unit using its abbreviation
      elseif numberShow == 'short-date-ref' then 

         if units[entry.unit] ~= nil then
            if entry.time ~= nil then
               numberString = numberString .. numberDelimiter .. lang:formatNum ( _round ( entry.amount, precision ) ) .. ' ' .. units[entry.unit].short .. ' <small>(' .. lang:formatDate( 'd.m.Y', entry.time ) .. ')</small>'
            else
               numberString = numberString .. numberDelimiter .. lang:formatNum ( _round ( entry.amount, precision ) ) .. ' ' .. units[entry.unit].short
            end
         else
            numberString = numberString .. numberDelimiter .. lang:formatNum ( _round ( entry.amount, precision ) )
         end

         if #entry.references > 0 then 
            for j, refEntry in ipairs ( entry.references ) do
               numberString = numberString .. frame:extensionTag{ name = 'ref', content = '[' .. refEntry .. ' ' .. refEntry .. ']' }
            end
         end

      -- displaying with unit using its abbreviation
      else 

         if units[entry.unit] ~=nil then
            numberString = numberString .. numberDelimiter .. lang:formatNum ( _round ( entry.amount, precision ) ) .. ' ' .. units[entry.unit].short
         else
            numberString = numberString .. numberDelimiter .. lang:formatNum ( _round ( entry.amount, precision ) )
         end

      end
      
      -- adding the frequency qualifikator, in case of mains voltage is requested
      if property == 'P2884' and entry.P2144 ~= nil then
         numberString = numberString .. ',&nbsp;' .. entry.P2144 .. '&#x202F;Hz'
      end

      -- DEBUG: show the unit-IDs
      -- numberString = numberString .. ' Einheit:' .. entry.unit .. ' Einheit (original):' .. entry.unitOriginal
      
      -- setting the delimiter after the first entry
      numberDelimiter = delimiter or ', '
   end

   -- providing the list of numbers
   return numberString .. categories

end

-- getNumbersWithDate() 
-- gets the amount of a property including "valid at" date
--   first parameters: see internal function
--   values:
--      - single (standard): Only one (first) entry is shown
--      - all: All entries are fetched
--   show:
--      - number: Only the formatted number is shown (Standard)
--      - plain: Only the Not formatted number is shown
--      - year: the year of validity is shown
--   delimiter: delimiter between the numbers; standard is comma and breakable space
GetNumber.getNumbersWithDate = function ( id, property, values, show, delimiter )

   -- returning String
   local numberString = ''

   -- making empty parameters to nil
   if values == '' then values = nil end
   if show == '' then show = nil end

   -- setting to defaul, if necessary
   values = values or 'single'
   show = show or 'number'

   -- WD-Values
   local numberList
   local wikidataID
   local categories
   -- always fetching all to be sorted later, because "singles" normally means the "most recent"
   numberList, wikidataID, categories = getNumbersAsTable ( id, property, nil, 'all' )

   if numberList[1] == nil then
      return categories
   end

   --- Sorting the table by year
   table.sort(numberList, function(a,b) return a.year < b.year end)

   -- no delimiter in front of the first entry
   local numberDelimiter = ''

   -- displaying the values
   if values == 'single' then
      -- using the first table row
      if show == 'year' then
         numberString = lang:formatNum ( numberList[1].amount ) .. ' (' .. numberList[1].year .. ')'
      elseif show == 'plain' then
         numberString = numberList[1].amount
      else
         numberString = lang:formatNum ( numberList[1].amount )
      end
   else
      -- running through the table
      for i, entry in ipairs( numberList ) do

         -- adding an entry
         if show == 'year' then
            numberString = numberString .. numberDelimiter .. lang:formatNum ( entry.amount ) .. '&#x202F;<span class="voy-small">(' .. entry.year .. ')</span>'
         elseif show == 'plain' then
            numberString = numberString .. numberDelimiter .. tostring ( entry.amount )
         else
            numberString = numberString .. numberDelimiter .. lang:formatNum ( entry.amount )
         end

         -- setting the delimiter after the first entry
         numberDelimiter = delimiter or ', '
      end
   end

   -- providing the list of numbers
   return numberString .. categories

end


-- getCoordinate()  > only used in other modules
-- gets a coordinate of an item
-- special properties can be provided. Standard is P625
-- it always delivers the first one
GetNumber.getCoordinate = function ( id, property )

   -- WD-Values
   local coordinateList
   local wikidataID
   local categories
   coordinateList, wikidataID, categories = getCoordinatesAsTable ( id, coalesce ( nilIf ( property, '' ), 'P625' ) )

   if #coordinateList > 0 then

      -- providing the list of numbers
      return coordinateList[1].latitude, coordinateList[1].longitude, coordinateList[1].precision, categories

   else

      if wikidataCat[property] ~= nil then
         categories = categories .. wikidataCat[property].nodata
      end
      return 0, 0, 0, categories

   end

end


-- getCoordinateAsText()
-- gets a coordinate of an item
-- is shown as text with comma separated latitude and longitude
-- special properties can be provided. Standard is P625
-- it always delivers the first one
GetNumber.getCoordinateAsText = function ( id, property )

   -- WD-Values
   local coordinateList
   local wikidataID
   local categories
   coordinateList, wikidataID, categories = getCoordinatesAsTable ( id, coalesce ( nilIf ( property, '' ), 'P625' ) )

   if #coordinateList > 0 then

      -- providing the list of numbers
      return lang:formatNum ( coordinateList[1].latitude ) .. '; ' .. lang:formatNum ( coordinateList[1].longitude ) .. categories

   else

      return '' .. categories

   end

end


-- The next two quickbar-functions have a lot in common
-- the developer of this modul thought a lot about it
-- at the end he was too lazy to put everything in one function

-- Get the number as wiki markup for quickbars (infoboxes)
-- includes the number and short unit
GetNumber.getNumbersWithUnitQuickbar = function ( id, property, unit, precision, wikiValue )

   -- precision
   local numberPrecision = tonumber ( precision ) or 0
   
   -- getting the numbers with the base function above
   local wikidataID
   local wikidataNumber = {}
   local wikidataCategories
   wikidataNumber, wikidataID, wikidataCategories = getNumbersAsTable ( id, property, unit )
   
   -- if it is taken from wikidata, this variable provides an additional class for: MediaWiki:Gadget-Wikidata-Content.css
   -- space is needed becaus its simply added to the existing class string
   local wikidataClass = ' voy-wikidata-content'

   -- comparing a possibly given value with Wikidata
   local category = ''

   -- is Wikidata value not available?
   local wikidataNoData = false
   if wikidataID == '' then
      if wikidataCat[property] ~= nil then
         category = wikidataCat[property].noData
         wikidataNoData = true
      end
      wikidataClass = ''
   end

   -- creating text for display
   local numberString = ''
   local wikidataString = ''
   if wikidataNumber[1] ~= nil then
      if units[wikidataNumber[1].unit] ~=nil then
         numberString = lang:formatNum ( _round ( wikidataNumber[1].amount, numberPrecision ) ) .. ' ' .. units[wikidataNumber[1].unit].short
         wikidataString = lang:formatNum ( _round ( wikidataNumber[1].amount, numberPrecision ) ) .. ' ' .. units[wikidataNumber[1].unit].short
      else
         numberString = lang:formatNum ( _round ( wikidataNumber[1].amount, numberPrecision ) )
         wikidataString = lang:formatNum ( _round ( wikidataNumber[1].amount, numberPrecision ) )
      end
   else
      -- wikidata values not available
      wikidataClass = ''
      if wikidataCat[property] ~= nil then
         category = wikidataCat[property].noData
      end
   end

   -- is a wiki value defined?
   local wikidataEqualData = false
   local wikidataNoEqualData = false
   
   -- processing nil value for wikiValue
   if wikiValue == nil then wikiValue = '' end
   
   -- wikivalues, that can be interpreted as "TRUE" are removed and Wikidata is used
   -- it's used to switch entries on and off in Quickbars
   if wikiValue =='yes'
      or wikiValue == 'y'
      or wikiValue == 'true'
      or wikiValue == 'wahr'
      or wikiValue == 'ja'
      or wikiValue == 'j'
   then
      wikiValue = ''
   end

   -- wikivalues, that can be interpreted as "FALSE" suppress the whole row
   if wikiValue =='no'
      or wikiValue == 'n'
      or wikiValue == 'false'
      or wikiValue == 'falsch'
      or wikiValue == 'nein'
   then
      return wikidataCategories
   end

   
   -- processing wikiValue
   if wikiValue ~= '' then
      
      -- displaying the wikiValue
      numberString = wikiValue

      -- removing wikidata content class
      wikidataClass = ''
      
      -- removing spaces and letters
      wikiValue = string.gsub ( wikiValue, '[^%d.,]', '' )
      
      -- replace comma with period
      wikiValue = string.gsub ( wikiValue, ',', '.' )
      
      -- comparison
      if ( wikiValue ~= '' ) and ( wikidataNumber[1] ~= nil ) and ( wikidataCat[property] ~= nil ) then
         -- are the values equal?
         if _round ( wikidataNumber[1].amount, numberPrecision ) == tonumber ( wikiValue ) then
            category = wikidataCat[property].equalData
            wikidataEqualData = true
         else
            category = wikidataCat[property].noEqualData
            wikidataNoEqualData = true
         end         
      end
   end

   -- displaying only, if any data available
   local trClass = ''
   if numberString == '' then
      trClass = ' voy-qb-empty'
   end

   -- creating the table row 
   local tr = mw.html.create ( 'tr' )
   
   -- first table cell (heading)
   local trLabel = '&nbsp;'
   if units[property] ~= nil then
        trClass = ' ' .. units[property].cssClass .. trClass
        trLabel = units[property].label
   end
   tr:addClass('voy-qb-item' .. trClass )
      :tag('th')
      :addClass('voy-qb-item-key')
      :wikitext(trLabel)
   
   -- second table cell (the requested number)
   if wikidataNoData then
      tr:tag('td')
         :addClass( 'voy-qb-item-value1 voy-qb-item-value-nowikidata' .. wikidataClass )
            :attr('data-wikidata-id',wikidataID)
            :attr('title','Kein(e) ' .. trLabel .. ' auf Wikidata' )
         :wikitext( numberString )
   elseif wikidataEqualData then
      tr:tag('td')
            :addClass( 'voy-qb-item-value1 voy-qb-item-value-wikidata-equal' .. wikidataClass )
            :attr('data-wikidata-id',wikidataID)
            :attr('data-wikidata-value',wikidataString)
            :attr('title','Daten identisch - Angabe auf Wikidata: ' .. wikidataString)
            :wikitext( numberString )
   elseif wikidataNoEqualData then
      tr:tag('td')
            :addClass( 'voy-qb-item-value1 voy-qb-item-value-wikidata-noequal' .. wikidataClass )
            :attr('data-wikidata-id',wikidataID)
            :attr('data-wikidata-value',wikidataString)
            :attr('title','Daten unterschiedlich - Angabe auf Wikidata: ' .. wikidataString)
            :wikitext( numberString )
   else
      tr:tag('td')
            :addClass( 'voy-qb-item-value1' .. wikidataClass )
            :attr('data-wikidata-id',wikidataID)
            :attr('data-wikidata-value',wikidataString)
            :wikitext( numberString )
   end

   -- returning the row
   return tostring ( tr ) .. category .. wikidataCategories
   
end

-- Get the number as wiki markup for quickbars (infoboxes)
-- includes the number and the date
GetNumber.getNumbersWithDateQuickbar = function ( id, property, wikiValue )

   -- getting the numbers with the base function above
   local wikidataID
   local wikidataNumber = {}
   local wikidataCategories
   wikidataNumber, wikidataID, wikidataCategories = getNumbersAsTable ( id, property, nil, 'all' )

   --- Sorting the table by year
   table.sort(wikidataNumber, function(a,b) return a.year < b.year end)
   
   -- if it is taken from wikidata, this variable provides an additional class for: MediaWiki:Gadget-Wikidata-Content.css
   -- space is needed becaus its simply added to the existing class string
   local wikidataClass = ' voy-wikidata-content'

   -- comparing a possibly given value with Wikidata
   local category = ''

   -- is Wikidata value not available?
   local wikidataNoData = false
   if wikidataID == '' then
      if wikidataCat[property] ~= nil then
         category = wikidataCat[property].noData
         wikidataNoData = true
      end
      wikidataClass = ''
   end

   -- creating text for display
   local numberString = ''
   local wikidataString = ''
   if wikidataNumber[1] ~= nil then
      if wikidataNumber[1].year > 0 then
         numberString = lang:formatNum ( ( wikidataNumber[1].amount ) ) .. '&#x202F;<span class="voy-small">(' .. tostring ( wikidataNumber[1].year ).. ')</span>'
      else
         numberString = lang:formatNum ( ( wikidataNumber[1].amount ) )
      end
      wikidataString = wikidataNumber[1].amount
   else
      -- wikidata values not available
      wikidataClass = ''
      if wikidataCat[property] ~= nil then
         category = wikidataCat[property].noData
      end
   end

   -- is a wiki value defined?
   local wikidataEqualData = false
   local wikidataNoEqualData = false
   
   -- processing nil value for wikiValue
   if wikiValue == nil then wikiValue = '' end
   
   -- wikivalues, that can be interpreted as "TRUE" are removed and Wikidata is used
   -- it's used to switch entries on and off in Quickbars
   if wikiValue =='yes'
      or wikiValue == 'y'
      or wikiValue == 'true'
      or wikiValue == 'wahr'
      or wikiValue == 'ja'
      or wikiValue == 'j'
   then
      wikiValue = ''
   end


   -- wikivalues, that can be interpreted as "FALSE" suppress the whole row
   if wikiValue =='no'
      or wikiValue == 'n'
      or wikiValue == 'false'
      or wikiValue == 'falsch'
      or wikiValue == 'nein'
   then
      return wikidataCategories
   end

   -- processing wikiValue
   if wikiValue ~= '' then
      
      -- displaying the wikiValue
      numberString = wikiValue

      -- removing wikidata content class
      wikidataClass = ''
      
      -- removing spaces, periods and letters
      wikiValue = string.gsub ( wikiValue, '[^%d,]', '' )
      
      -- comparison
      if ( wikiValue ~= '' ) and ( wikidataNumber[1] ~= nil ) and ( wikidataCat[property] ~= nil ) then
         -- are the values equal?
         if wikidataNumber[1].amount == tonumber ( wikiValue ) then
            category = wikidataCat[property].equalData
            wikidataEqualData = true
         else
            category = wikidataCat[property].noEqualData
            wikidataNoEqualData = true
         end         
      end
   end

   -- displaying only, if any data available
   local trClass = ''
   if numberString == '' then
      trClass = ' voy-qb-empty'
   end

   -- creating the table row 
   local tr = mw.html.create ( 'tr' )
   
   -- first table cell (heading)
   local trLabel = '&nbsp;'
   if units[property] ~= nil then
        trClass = ' ' .. units[property].cssClass .. trClass
        trLabel = units[property].label
   end
   tr:addClass('voy-qb-item' .. trClass )
      :tag('th')
      :addClass('voy-qb-item-key')
      :wikitext(trLabel)
   
   -- second table cell (the requested number)
   if wikidataNoData then
      tr:tag('td')
         :addClass( 'voy-qb-item-value1 voy-qb-item-value-nowikidata' .. wikidataClass )
            :attr('data-wikidata-id',wikidataID)
            :attr('title','Kein(e) ' .. trLabel .. ' auf Wikidata' )
         :wikitext( numberString )
   elseif wikidataEqualData then
      tr:tag('td')
            :addClass( 'voy-qb-item-value1 voy-qb-item-value-wikidata-equal' .. wikidataClass )
            :attr('data-wikidata-id',wikidataID)
            :attr('data-wikidata-value',wikidataString)
            :attr('title','Daten identisch - Angabe auf Wikidata: ' .. wikidataString)
            :wikitext( numberString )
   elseif wikidataNoEqualData then
      tr:tag('td')
            :addClass( 'voy-qb-item-value1 voy-qb-item-value-wikidata-noequal' .. wikidataClass )
            :attr('data-wikidata-id',wikidataID)
            :attr('data-wikidata-value',wikidataString)
            :attr('title','Daten unterschiedlich - Angabe auf Wikidata: ' .. wikidataString)
            :wikitext( numberString )
   else
      tr:tag('td')
            :addClass( 'voy-qb-item-value1' .. wikidataClass )
            :attr('data-wikidata-id',wikidataID)
            :attr('data-wikidata-value',wikidataString)
            :wikitext( numberString )
   end

   -- returning the row
   return tostring ( tr ) .. category .. wikidataCategories
   
end

-- Language-dependent sorting substitutes
local substitutes = {
   { l = 'ä', as = 'a' },
   { l = 'ö', as = 'o' },
   { l = 'ü', as = 'u' },
   { l = 'ß', as = 'ss' }
}

local function convertForSort( s )
   s = mw.ustring.lower( s )
   for i, obj in ipairs( substitutes ) do
      s = mw.ustring.gsub( s, obj.l, obj.as )
   end
   return s
end

GetNumber.getExchangeRatesList = function ( frame )

   local uu = require( 'Module:URLutil' )

   local cdg = mw.loadData( 'Module:CountryData/Geography' )
   local cdc = mw.loadData( 'Module:CountryData/Currencies' )
   local rows = {}
   local iso


   -- Wikidata-Values
   local numberList
   local wikidataID
   local categories
   local wikidataString
   local wikidataDelimiter


   -- Commons: two tables with currency exchange rates
   exchangeTable1 = mw.ext.data.get( 'ECB euro foreign exchange reference rates.tab' )
   exchangeTable2 = mw.ext.data.get( 'Xe.com exchange rates.tab' )

   local exchangeRate
   local exchangeDate
   local exchangeSource
   local exchangeTable
   local exchangeString

   -- List of References to avoid multiple references
   local referenceList = {}
   local referenceCount = 1

   for key, value in pairs( cdg.countries ) do

      if cdc.currencies[value.currency] ~= nil then
         iso = cdc.currencies[value.currency].iso
      else
         iso = ''
      end

      -- Wikidata
      wikidataString = '&nbsp;'
      wikidataDelimiter = ''

      numberList, wikidataID, categories = getNumbersAsTable ( value.currency, 'P2284' )

      for i, entry in ipairs( numberList ) do

         if entry.time ~= nil then
            wikidataString = wikidataString .. wikidataDelimiter .. lang:formatNum ( _round ( entry.amount, 6 ) ) .. '&#x202F;€&nbsp;<small>(' .. lang:formatDate( 'd.m.Y', entry.time ) .. ')</small>'
         else
            wikidataString = wikidataString .. wikidataDelimiter .. lang:formatNum ( _round ( entry.amount, 6 ) ) .. '&#x202F;€'
         end

         if #entry.references > 0 then 
            for j, refEntry in ipairs ( entry.references ) do
               -- does reference exists already or not?
               if referenceList[refEntry] ~= nil then
                  wikidataString = wikidataString .. frame:extensionTag{ name = 'ref', content = '', args = { name = referenceList[refEntry] } }
               else
                  wikidataString = wikidataString .. frame:extensionTag{ name = 'ref', content = '[' .. refEntry .. ' ' .. uu.URLutil().getHost( refEntry ) .. ']', args = { name = 'ref_' .. referenceCount } }
                  referenceList[refEntry] = 'ref_' .. referenceCount
                  referenceCount = referenceCount + 1
               end
            end
         end

         wikidataDelimiter = ';'

      end

      -- Commons
      exchangeRate = 0
      exchangeDate = ''
      exchangeSource = ''
      exchangeTable = {}
      exchangeString = ''

      if iso ~= '' and iso ~= 'EUR' then

         wikidataRate = GetNumber.getNumbersWithUnit ( value.currency, 'P2284', nil, nil, 5, 'short-date-ref', nil, frame )

         for i, entry in pairs ( exchangeTable1.data ) do
            if entry[1] == iso then
               exchangeRate = tonumber ( entry[2] )
               exchangeDate = entry[3]
               exchangeSource = coalesce ( exchangeTable1.sources, '' )
               break
            end
         end

         -- trying Commons: Data:Xe.com exchange rates.tab
         if exchangeRate == 0 then

            for i, entry in pairs ( exchangeTable2.data ) do
               if entry[1] == iso then
                  exchangeRate = tonumber ( entry[3] )
                  exchangeDate = entry[6]
                  exchangeSource = coalesce ( exchangeTable2.sources, '' )
                  break
               end
            end

         end

         if exchangeRate > 0 then

            -- does reference exists already or not?
            if referenceList[exchangeSource] ~= nil then
               exchangeString = lang:formatNum ( _round ( 1 / exchangeRate, 6 ) ) .. '&#x202F;€&nbsp;<small>(' .. lang:formatDate ( 'd.m.Y', exchangeDate ) .. ')</small>' .. frame:extensionTag{ name = 'ref', content = '', args = { name = referenceList[exchangeSource] } }
            else
               exchangeString = lang:formatNum ( _round ( 1 / exchangeRate, 6 ) ) .. '&#x202F;€&nbsp;<small>(' .. lang:formatDate ( 'd.m.Y', exchangeDate ) .. ')</small>' .. frame:extensionTag{ name = 'ref', content = '[' .. exchangeSource .. ' ' .. uu.URLutil().getHost( exchangeSource ) .. ']', args = { name = 'ref_' .. referenceCount } }
               referenceList[exchangeSource] = 'ref_' .. referenceCount
               referenceCount = referenceCount + 1
            end

         end

      end      

      if iso ~= '' then
         table.insert( rows, ( '<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>' ):format (
            coalesce ( value.country, 'unbekannt' ), iso, wikidataString, exchangeString ) )
      end

   end

   table.sort( rows, 
      function( a, b ) return convertForSort ( a ) < convertForSort ( b ) end
   )

   table.insert( rows, 1, '<table class="prettytable sortable multiline" cellspacing="0">\n'
      .. '<tr><th>Land</th><th>Währung</th><th>Kurs Wikidata</th><th>Kurs Commons</th></tr>' )   

   table.insert( rows, '</table>' )

   return table.concat( rows, '\n' ) .. categories

end

-- Providing template access
local p = {}

function p.getNumbersWithUnit( frame )
   return GetNumber.getNumbersWithUnit( frame.args[ 1 ], frame.args[ 2 ], frame.args[ 3 ], frame.args[ 4 ], frame.args[ 5 ], frame.args[ 6 ], frame.args[ 7 ], frame ) or ""
end

function p.getNumbersWithDate( frame )
   return GetNumber.getNumbersWithDate( frame.args[ 1 ], frame.args[ 2 ], frame.args[ 3 ], frame.args[ 4 ], frame.args[ 5 ], frame.args[ 6 ], frame.args[ 7 ] ) or ""
end

function p.getCoordinateAsText( frame )
   return GetNumber.getCoordinateAsText( frame.args[ 1 ], frame.args[ 2 ] ) or ""
end

function p.getNumbersWithUnitQuickbar( frame )
   return GetNumber.getNumbersWithUnitQuickbar( frame.args[ 1 ], frame.args[ 2 ], frame.args[ 3 ], frame.args[ 4 ], frame.args[ 5 ] ) or ""
end

function p.getNumbersWithDateQuickbar( frame )
   return GetNumber.getNumbersWithDateQuickbar( frame.args[ 1 ], frame.args[ 2 ], frame.args[ 3 ] ) or ""
end

function p.getExchangeRatesList( frame )
   return GetNumber.getExchangeRatesList( frame ) or ""
end
-- for usage in other modules
-- using it the following way:
--
-- local getNumber = require( 'Module:GetNumber' )
-- foo = getNumber.GetNumber().xxx( id, lang )
function p.GetNumber()
   return GetNumber
end

return p