;;;; -*- coding:utf-8 -*-
;;;;****************************************************************************
;;;;FILE:               iso4217.lisp
;;;;LANGUAGE:           Common-Lisp
;;;;SYSTEM:             Common-Lisp
;;;;USER-INTERFACE:     NONE
;;;;DESCRIPTION
;;;;
;;;;    This package exports functions and data to process
;;;;    iso4217 currency codes.
;;;;
;;;;AUTHORS
;;;;    <PJB> Pascal J. Bourguignon <pjb@informatimago.com>
;;;;MODIFICATIONS
;;;;    2004-10-13 <PJB> Created.
;;;;BUGS
;;;;LEGAL
;;;;    AGPL3
;;;;
;;;;    Copyright Pascal J. Bourguignon 2003 - 2015
;;;;
;;;;    This program is free software: you can redistribute it and/or modify
;;;;    it under the terms of the GNU Affero General Public License as published by
;;;;    the Free Software Foundation, either version 3 of the License, or
;;;;    (at your option) any later version.
;;;;
;;;;    This program is distributed in the hope that it will be useful,
;;;;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;;;;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;;;    GNU Affero General Public License for more details.
;;;;
;;;;    You should have received a copy of the GNU Affero General Public License
;;;;    along with this program.  If not, see <http://www.gnu.org/licenses/>
;;;;****************************************************************************

(in-package "COMMON-LISP-USER")
(defpackage "COM.INFORMATIMAGO.COMMON-LISP.CESARUM.ISO4217"
  (:use "COMMON-LISP")
  (:export "GET-CURRENCIES" "FIND-CURRENCY" "CURRENCY-NAME"
           "CURRENCY-MINOR-UNIT" "CURRENCY-NUMERIC-CODE" "CURRENCY-ALPHABETIC-CODE"
           "CC-NOTE" "CC-CURRENCY" "CC-COUNTRY")
  (:documentation
   "

This package exports functions and data to process iso4217 currency codes.


License:

    AGPL3

    Copyright Pascal J. Bourguignon 2004 - 2012

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.
    If not, see <http://www.gnu.org/licenses/>

"))
(in-package "COM.INFORMATIMAGO.COMMON-LISP.CESARUM.ISO4217")


;; http://www.unece.org/cefact/rec/cocucod.htm
;; http://www.xe.com/iso4217.htm
;; http://en.wikipedia.org/wiki/ISO_4217


(defparameter +country-currency-notes+
  #("Notes"
    "Effective date is 7th October 2002. The conversion rate is 1AFN
     to 1000 AFA. The two codes will run concurent until 2nd January 2003."
    "CFA Franc BCEAO ; Responsible authority: Banque Centrale des États de
     l'Afrique de l'Ouest."
    "Customarily known as Bermuda Dollar."
    "Funds code."
    "CFA Franc BEAC ; Responsible authority; Banque des États de l'Afrique
     Centrale."
    "There is no current withdrawal date for TPE."
    "Effective on 1st January 2001. There is no current withdrawal date
     for SVC."
    "Currency name was effective 4th September 1985."
    "Effective on 1stJanuary 2004."
    "Will be suppressed on 1st January 2004."
    "Dinar is used in Serbia, Euro is used in Montenegro. Effective
     from February 2003."
    "The minor unit was changed from 0 to 2, for this edition, since
     the English Version of ISO 4217 had the wrong information.")
  "Notes for country-currency relations.")


(defstruct (country-currency-row  (:type list) (:conc-name cc-))
  country currency note)

(setf (documentation 'cc-country 'function)
      "The country of the currency."
      (documentation 'cc-currency 'function)
      "The currency."
      (documentation 'cc-note 'function)
      "A note.")


(defparameter +country-currency+
  '(
    ("AD" "EUR")
    ("AE" "AED")
    ("AF" "AFN"  1)
    ("AG" "XCD")
    ("AI" "XCD")
    ("AL" "ALL")
    ("AM" "AMD")
    ("AN" "ANG")
    ("AO" "AOA")
    ("AR" "ARS")
    ("AS" "USD")
    ("AT" "EUR")
    ("AU" "AUD")
    ("AW" "AWG")
    ("AZ" "AZM")
    ("BA" "BAM")
    ("BB" "BBD")
    ("BD" "BDT")
    ("BE" "EUR")
    ("BF" "XOF"  2)
    ("BG" "BGN")
    ("BH" "BHD")
    ("BI" "BIF")
    ("BJ" "XOF"  2)
    ("BM" "BMD"  3)
    ("BN" "BND")
    ("BO" "BOV"  4)
    ("BO" "BOB")
    ("BR" "BRL")
    ("BS" "BSD")
    ("BT" "BTN")
    ("BT" "INR")
    ("BV" "NOK")
    ("BW" "BWP")
    ("BY" "BYR")
    ("BZ" "BZD")
    ("CA" "CAD")
    ("CC" "AUD")
    ("CD" "CDF")
    ("CF" "XAF"  5)
    ("CG" "XAF"  5)
    ("CH" "CHF")
    ("CI" "XOF"  2)
    ("CK" "NZD")
    ("CL" "CLF"  4)
    ("CL" "CLP")
    ("CM" "XAF"  5)
    ("CN" "CNY")
    ("CO" "COU")
    ("CO" "COP")
    ("CR" "CRC")
    ("CS" "CSD" 11)
    ("CS" "EUR" 11)
    ("CU" "CUP")
    ("CV" "CVE")
    ("CX" "AUD")
    ("CY" "CYP")
    ("CZ" "CZK")
    ("DE" "EUR")
    ("DJ" "DJF")
    ("DK" "DKK")
    ("DM" "XCD")
    ("DO" "DOP")
    ("DZ" "DZD")
    ("EC" "USD")
    ("EE" "EEK")
    ("EG" "EGP")
    ("EH" "MAD")
    ("ER" "ERN")
    ("ES" "EUR")
    ("ET" "ETB")
    ("FI" "EUR")
    ("FJ" "FJD")
    ("FK" "FKP")
    ("FM" "USD")
    ("FO" "DKK")
    ("FR" "EUR")
    ("GA" "XAF"  5)
    ("GB" "GBP")
    ("GD" "XCD")
    ("GE" "GEL")
    ("GF" "EUR")
    ("GH" "GHC")
    ("GI" "GIP")
    ("GL" "DKK")
    ("GM" "GMD")
    ("GN" "GNF")
    ("GP" "EUR")
    ("GQ" "XAF"  5)
    ("GR" "EUR")
    ("GT" "GTQ")
    ("GU" "USD")
    ("GW" "XOF"  4)
    ("GW" "GWP")
    ("GY" "GYD")
    ("HK" "HKD")
    ("HM" "AUD")
    ("HN" "HNL")
    ("HR" "HRK")
    ("HT" "USD")
    ("HT" "HTG")
    ("HU" "HUF")
    ("ID" "IDR")
    ("IE" "EUR")
    ("IL" "ILS"  8)
    ("IN" "INR")
    ("IO" "USD")
    ("IQ" "IQD")
    ("IR" "IRR")
    ("IS" "ISK")
    ("IT" "EUR")
    ("JM" "JMD")
    ("JO" "JOD")
    ("JP" "JPY")
    ("KE" "KES")
    ("KG" "KGS")
    ("KH" "KHR")
    ("KI" "AUD")
    ("KM" "KMF")
    ("KN" "XCD")
    ("KP" "KPW")
    ("KR" "KRW")
    ("KW" "KWD")
    ("KY" "KYD")
    ("KZ" "KZT")
    ("LA" "LAK")
    ("LB" "LBP")
    ("LC" "XCD")
    ("LI" "CHF")
    ("LK" "LKR")
    ("LR" "LRD")
    ("LS" "LSL")
    ("LS" "ZAR")
    ("LT" "LTL")
    ("LU" "EUR")
    ("LV" "LVL")
    ("LY" "LYD")
    ("MA" "MAD")
    ("MC" "EUR")
    ("MD" "MDL")
    ("MG" "MGF")
    ("MG" "MGA"  9)
    ("MH" "USD")
    ("MK" "MKD")
    ("ML" "XOF"  2)
    ("MM" "MMK")
    ("MN" "MNT")
    ("MO" "MOP")
    ("MP" "USD")
    ("MQ" "EUR")
    ("MR" "MRO")
    ("MS" "XCD")
    ("MT" "MTL")
    ("MU" "MUR")
    ("MV" "MVR")
    ("MW" "MWK")
    ("MX" "MXV"  4)
    ("MX" "MXN")
    ("MY" "MYR")
    ("MZ" "MZM")
    ("NA" "NAD")
    ("NA" "ZAR")
    ("NC" "XPF")
    ("NE" "XOF"  2)
    ("NF" "AUD")
    ("NG" "NGN")
    ("NI" "NIO")
    ("NL" "EUR")
    ("NO" "NOK")
    ("NP" "NPR")
    ("NR" "AUD")
    ("NU" "NZD")
    ("NZ" "NZD")
    ("OM" "OMR")
    ("PA" "USD")
    ("PA" "PAB")
    ("PE" "PEN")
    ("PF" "XPF")
    ("PG" "PGK")
    ("PH" "PHP")
    ("PK" "PKR")
    ("PL" "PLN")
    ("PM" "EUR")
    ("PN" "NZD")
    ("PR" "USD")
    ("PT" "EUR")
    ("PW" "USD")
    ("PY" "PYG")
    ("QA" "QAR")
    ("RE" "EUR")
    ("RO" "ROL")
    ("RU" "RUB")
    ("RU" "RUR" 10)
    ("RW" "RWF")
    ("SA" "SAR")
    ("SB" "SBD")
    ("SC" "SCR")
    ("SD" "SDD")
    ("SE" "SEK")
    ("SG" "SGD")
    ("SH" "SHP")
    ("SI" "SIT")
    ("SJ" "NOK")
    ("SK" "SKK")
    ("SL" "SLL")
    ("SM" "EUR")
    ("SN" "XOF"  2)
    ("SO" "SOS")
    ("SR" "SRD"  9)
    ("ST" "STD")
    ("SV" "USD"  7)
    ("SV" "SVC"  7)
    ("SY" "SYP")
    ("SZ" "SZL")
    ("TC" "USD")
    ("TD" "XAF"  5)
    ("TF" "EUR")
    ("TG" "XOF"  2)
    ("TH" "THB")
    ("TJ" "TJS")
    ("TK" "NZD")
    ("TL" "USD")
    ("TM" "TMM")
    ("TN" "TND")
    ("TO" "TOP")
    ("TR" "TRL")
    ("TT" "TTD")
    ("TV" "AUD")
    ("TW" "TWD")
    ("TZ" "TZS")
    ("UA" "UAH")
    ("UG" "UGX" 12)
    ("UM" "USD")
    ("US" "USN"  4)
    ("US" "USS"  4)
    ("US" "USD")
    ("UY" "UYU")
    ("UZ" "UZS")
    ("VA" "EUR")
    ("VC" "XCD")
    ("VE" "VEB")
    ("VG" "USD")
    ("VI" "USD")
    ("VN" "VND")
    ("VU" "VUV")
    ("WF" "XPF")
    ("WS" "WST")
    ("YE" "YER")
    ("YT" "EUR")
    ("ZA" "ZAR")
    ("ZM" "ZMK")
    ("ZW" "ZWD")
    )
  "Relation N-N between countries and currencies.") ;;+COUNTRY-CURRENCY+


(eval-when (:compile-toplevel :load-toplevel :execute)

  (defstruct (currency (:type list))
    alphabetic-code numeric-code minor-unit name )

  (setf (documentation 'currency-alphabetic-code 'function)
        "The alphabetic code (3 letters) of the currency."
        (documentation 'currency-numeric-code 'function)
        "The numeric code (between 0 and 999) of the currency."
        (documentation 'currency-minor-unit 'function)
        "The number of digits after the decimal point for amounts in the currency."
        (documentation 'currency-name 'function)
        "The name of the currency")

  (defparameter +currencies+
    '(
      ("AED" 784 2 "UAE Dirham"                     )
      ("AFN" 971 2 "Afghani"                        )
      ("ALL"   8 2 "Lek"                            )
      ("AMD"  51 2 "Armenian Dram"                  )
      ("ANG" 532 2 "Netherlands Antillan Guilder"   )
      ("AOA" 973 2 "Kwanza"                         )
      ("ARS"  32 2 "Argentine Peso"                 )
      ("AUD"  36 2 "Australian Dollar"              )
      ("AWG" 533 2 "Aruban Guilder"                 )
      ("AZM"  31 2 "Azerbaijanian Manat"            )
      ("BAM" 977 2 "Convertible Marks"              )
      ("BBD"  52 2 "Barbados Dollar"                )
      ("BDT"  50 2 "Taka"                           )
      ("BGN" 975 2 "Bulgarian Lev"                  )
      ("BHD"  48 3 "Bahraini Dinar"                 )
      ("BIF" 108 0 "Burundi Franc"                  )
      ("BMD"  60 2 "Bermudian Dollar"               )
      ("BND"  96 2 "Brunei Dollar"                  )
      ("BOB"  68 2 "Boliviano"                      )
      ("BOV" 984 2 "Mvdol"                          )
      ("BRL" 986 2 "Brazilian Real"                 )
      ("BSD"  44 2 "Bahamian Dollar"                )
      ("BTN"  64 2 "Ngultrum"                       )
      ("BWP"  72 2 "Pula"                           )
      ("BYR" 974 0 "Belarussian Ruble"              )
      ("BZD"  84 2 "Belize Dollar"                  )
      ("CAD" 124 2 "Canadian Dollar"                )
      ("CDF" 976 2 "Franc Congolais"                )
      ("CHF" 756 2 "Swiss Franc"                    )
      ("CLF" 990 0 "Unidades de fomento"            )
      ("CLP" 152 0 "Chilean Peso"                   )
      ("CNY" 156 2 "Yuan Renminbi"                  )
      ("COP" 170 2 "Colombian Peso"                 )
      ("COU" 970 2 "Unidad de Valor Real"           )
      ("CRC" 188 2 "Costa Rican Colon"              )
      ("CSD" 891 2 "Serbian Dinar"                  )
      ("CUP" 192 2 "Cuban Peso"                     )
      ("CVE" 132 2 "Cape Verde Escudo"              )
      ("CYP" 196 2 "Cyprus Pound"                   )
      ("CZK" 203 2 "Czech Koruna"                   )
      ("DJF" 262 0 "Djibouti Franc"                 )
      ("DKK" 208 2 "Danish Krone"                   )
      ("DOP" 214 2 "Dominican Peso"                 )
      ("DZD"  12 2 "Algerian Dinar"                 )
      ("EEK" 233 2 "Kroon"                          )
      ("EGP" 818 2 "Egyptian Pound"                 )
      ("ERN" 232 2 "Nakfa"                          )
      ("ETB" 230 2 "Ethiopian Birr"                 )
      ("EUR" 978 2 "Euro"                           )
      ("FJD" 242 2 "Fiji Dollar"                    )
      ("FKP" 238 2 "Falkland Islands Pound"         )
      ("GBP" 826 2 "Pound Sterling"                 )
      ("GEL" 981 2 "Lari"                           )
      ("GHC" 288 2 "Cedi"                           )
      ("GIP" 292 2 "Gibraltar Pound"                )
      ("GMD" 270 2 "Dalasi"                         )
      ("GNF" 324 0 "Guinea Franc"                   )
      ("GTQ" 320 2 "Quetzal"                        )
      ("GWP" 624 2 "Guinea-Bissau Peso"             )
      ("GYD" 328 2 "Guyana Dollar"                  )
      ("HKD" 344 2 "Hong Kong Dollar"               )
      ("HNL" 340 2 "Lempira"                        )
      ("HRK" 191 2 "Croatian kuna"                  )
      ("HTG" 332 2 "Gourde"                         )
      ("HUF" 348 2 "Forint"                         )
      ("IDR" 360 2 "Rupiah"                         )
      ("ILS" 376 2 "New Israeli Sheqel"             )
      ("INR" 356 2 "Indian Rupee"                   )
      ("IQD" 368 3 "Iraqi Dinar"                    )
      ("IRR" 364 2 "Iranian Rial"                   )
      ("ISK" 352 2 "Iceland Krona"                  )
      ("JMD" 388 2 "Jamaican Dollar"                )
      ("JOD" 400 3 "Jordanian Dinar"                )
      ("JPY" 392 0 "Yen"                            )
      ("KES" 404 2 "Kenyan Shilling"                )
      ("KGS" 417 2 "Som"                            )
      ("KHR" 116 2 "Riel"                           )
      ("KMF" 174 0 "Comoro Franc"                   )
      ("KPW" 408 2 "North Korean Won"               )
      ("KRW" 410 0 "Won"                            )
      ("KWD" 414 3 "Kuwaiti Dinar"                  )
      ("KYD" 136 2 "Cayman Islands Dollar"          )
      ("KZT" 398 2 "Tenge"                          )
      ("LAK" 418 2 "Kip"                            )
      ("LBP" 422 2 "Lebanese Pound"                 )
      ("LKR" 144 2 "Sri Lanka Rupee"                )
      ("LRD" 430 2 "Liberian Dollar"                )
      ("LSL" 426 2 "Loti"                           )
      ("LTL" 440 2 "Lithuanian Litas"               )
      ("LVL" 428 2 "Latvian Lats"                   )
      ("LYD" 434 3 "Lybian Dinar"                   )
      ("MAD" 504 2 "Moroccan Dirham"                )
      ("MDL" 498 2 "Moldovan Leu"                   )
      ("MGA" 969 0 "Ariary"                         )
      ("MGF" 450 0 "Malagasy Franc"                 )
      ("MKD" 807 2 "Denar"                          )
      ("MMK" 104 2 "Kyat"                           )
      ("MNT" 496 2 "Tugrik"                         )
      ("MOP" 446 2 "Pataca"                         )
      ("MRO" 478 2 "Ouguiya"                        )
      ("MTL" 470 2 "Maltese Lira"                   )
      ("MUR" 480 2 "Mauritius Rupee"                )
      ("MVR" 462 2 "Rufiyaa"                        )
      ("MWK" 454 2 "Kwacha"                         )
      ("MXN" 484 2 "Mexican Peso"                   )
      ("MXV" 979 2 "Mexican Unidad de Inversion"    )
      ("MYR" 458 2 "Malaysian Ringgit"              )
      ("MZM" 508 2 "Metical"                        )
      ("NAD" 516 2 "Namibia Dollar"                 )
      ("NGN" 566 2 "Naira"                          )
      ("NIO" 558 2 "Cordoba Oro"                    )
      ("NOK" 578 2 "Norwegian Krone"                )
      ("NOK" 578 2 "Norvegian Krone"                )
      ("NPR" 524 2 "Nepalese Rupee"                 )
      ("NZD" 554 2 "New Zealand Dollar"             )
      ("OMR" 512 3 "Rial Omani"                     )
      ("PAB" 590 2 "Balboa"                         )
      ("PEN" 604 2 "Nuevo Sol"                      )
      ("PGK" 598 2 "Kina"                           )
      ("PHP" 608 2 "Philippine Peso"                )
      ("PKR" 586 2 "Pakistan Rupee"                 )
      ("PLN" 985 2 "Zloty"                          )
      ("PYG" 600 0 "Guarani"                        )
      ("QAR" 634 2 "Qatari Rial"                    )
      ("ROL" 642 2 "Leu"                            )
      ("RUB" 643 2 "Russian Ruble"                  )
      ("RUR" 810 2 "Russian Ruble"                  )
      ("RWF" 646 0 "Rwanda Franc"                   )
      ("SAR" 682 2 "Saudi Riyal"                    )
      ("SBD"  90 2 "Solomon Islands Dollar"         )
      ("SCR" 690 2 "Seychelles Rupee"               )
      ("SDD" 736 2 "Sudanese Dinar"                 )
      ("SEK" 752 2 "Swedish Krona"                  )
      ("SGD" 702 2 "Singapore Dollar"               )
      ("SHP" 654 2 "Saint Helena Pound"             )
      ("SIT" 705 2 "Tolar"                          )
      ("SKK" 703 2 "Slovak Koruna"                  )
      ("SLL" 694 2 "Leone"                          )
      ("SOS" 706 2 "Somali Shilling"                )
      ("SRD" 968 2 "Suriname Dollar"                )
      ("STD" 678 2 "Dobra"                          )
      ("SVC" 222 2 "El Salvador Colon"              )
      ("SYP" 760 2 "Syrian Pound"                   )
      ("SZL" 748 2 "Lilangeni"                      )
      ("THB" 764 2 "Baht"                           )
      ("TJS" 972 2 "Somoni"                         )
      ("TMM" 795 2 "Manat"                          )
      ("TND" 788 3 "Tunisian Dinar"                 )
      ("TOP" 776 2 "Pa'anga"                        )
      ("TRL" 792 0 "Turkish Lira"                   )
      ("TTD" 780 2 "Trinidad and Tobago Dollar"     )
      ("TWD" 901 2 "New Taiwan Dollar"              )
      ("TZS" 834 2 "Tanzanian Shilling"             )
      ("UAH" 980 2 "Hryvnia"                        )
      ("UGX" 800 2 "Uganda Shilling"                )
      ("USD" 840 2 "US Dollar"                      )
      ("USN" 997 2 "US Dollar (Next day)"           )
      ("USS" 998 2 "US Dollar (Same day)"           )
      ("UYU" 858 2 "Peso Uruguayo"                  )
      ("UZS" 860 2 "Uzbekistan Sum"                 )
      ("VEB" 862 2 "Bolivar"                        )
      ("VND" 704 2 "Dong"                           )
      ("VUV" 548 0 "Vatu"                           )
      ("WST" 882 2 "Tala"                           )
      ("XAF" 950 0 "CFA Franc BEAC"                 )
      ("XCD" 951 2 "East Caribbean Dollar"          )
      ("XCD" 951 2 "East Carribean Dollar"          )
      ("XCD" 951 2 "East Carribbean Dollar"         )
      ("XOF" 952 0 "CFA Franc BCEAO"                )
      ("XPF" 953 0 "CFP Franc"                      )
      ("YER" 886 2 "Yemeni Rial"                    )
      ("ZAR" 710 2 "Rand"                           )
      ("ZMK" 894 2 "Kwacha"                         )
      ("ZWD" 716 2 "Zimbabwe Dollar"                )
      )
    "Information about currencies.")


  (defparameter *currency-map* (make-hash-table :test (function eql))
    "Maps codes to currencies.")


  (dolist (cur +currencies+)
    (setf (gethash (currency-alphabetic-code cur) *currency-map*) cur
          (gethash (with-standard-io-syntax
                     (intern (currency-alphabetic-code cur)
                             "KEYWORD"))          *currency-map*) cur
          (gethash (currency-numeric-code    cur) *currency-map*) cur
          (gethash cur                            *currency-map*) cur))
  ) ;;eval-when


(defun find-currency (designator)
  "
DESIGNATOR:  An integer between 0 and 999, or a string or a symbol,
             or a list whose first element is an integer between 0 and 999,
                                              or a string or a symbol,
RETURN:      A currency structure (list) if the designator matches one,
             or nil if none found.
RAISE:       An error when the type of DESIGNATOR is not as described above.
"
  (or (gethash designator *currency-map*)
      (when (listp designator) (gethash (first designator) *currency-map*))
      (progn
        (setf designator (if (listp designator) (first designator) designator))
        (if (or (stringp designator) (symbolp designator))
            (car (member-if
                  (lambda (c)
                    (or (string-equal designator (currency-alphabetic-code c))
                        (string-equal designator (currency-name c))))
                  +currencies+))
            (error "Invalid currency designator: ~S"
                   designator))))) ;;FIND-CURRENCY


(defun get-currencies (&key only-existing order (language :en))
  "
     ONLY-EXISTING:  NOT IMPLEMENTED YET. Select only currencly in current use.
     LANGUAGE:       NOT IMPLEMENTED YET.
     ORDER:          :NAME or :ALPHABETIC-CODE or :NUMERIC-CODE.
     if not specified, no ordering is done.
     RETURN:         A list of CURRENCY:
     (alphabetic-code numeric-code minor-unit name).
     "
  (declare (ignore only-existing language))
  (let ((result (copy-seq +currencies+)))
    (when order
      (setq result
            (sort result
                  (case order
                    ((:name)
                     (lambda (a b) (string-lessp (currency-name a)
                                                 (currency-name b))))
                    ((:alphabetic-code)
                     (lambda (a b) (string-lessp (currency-alphabetic-code a)
                                                 (currency-alphabetic-code b))))
                    ((:numeric-code)
                     (lambda (a b) (string-lessp (currency-numeric-code a)
                                                 (currency-numeric-code b))))
                    (otherwise
                     (error "Invalid order: ~S. Expected one of: ~
      :NAME or :ALPHABETIC-CODE or :NUMERIC-CODE." order))))))
    result)) ;;GET-CURRENCIES



#|| //######################################################################

(defparameter +wikipedia-active+
  '(
    ("AED" "United Arab Emirates Dirham")
    ("AFN" "Afghani")
    ("ALL" "Albanian Lek")
    ("AMD" "Armenian Dram")
    ("ANG" "Netherlands Antillian Guilder")
    ("AOA" "Angolan Kwanza")
    ("ARS" "Argentine Peso")
    ("AUD" "Australian Dollar")
    ("AWG" "Aruban Guilder")
    ("AZM" "Azerbaijani Manat")
    ("BAM" "Bosnia-Herzegovina Convertible Marks")
    ("BBD" "Barbados Dollar")
    ("BDT" "Bangladesh Taka")
    ("BGN" "Bulgarian Lev (since 1999-07-05)")
    ("BHD" "Bahraini Dinar")
    ("BIF" "Burundi Franc")
    ("BMD" "Bermuda Dollar")
    ("BND" "Brunei Dollar")
    ("BOB" "Bolivian Boliviano")
    ("BOV" "Bolivian Mvdol (Funds code)")
    ("BRL" "Brazilian Real")
    ("BSD" "Bahamian Dollar")
    ("BTN" "Bhutan Ngultrum")
    ("BWP" "Botswana Pula")
    ("BYR" "Belarussian Ruble")
    ("BZD" "Belize Dollar")
    ("CAD" "Canadian Dollar")
    ("CDF" "Franc Congolais")
    ("CHF" "Swiss franc")
    ("CLF" "Chilean Unidades de fomento (Funds code)")
    ("CLP" "Chilean Peso")
    ("CNY" "Yuan Renminbi")
    ("COP" "Colombian peso")
    ("COU" "Columbian unidad de valor real (added to the COP)")
    ("CRC" "Costa Rican Colón")
    ("CSD" "Serbian Dinar")
    ("CUP" "Cuban Peso")
    ("CVE" "Cape Verde Escudo")
    ("CYP" "Cyprus Pound")
    ("CZK" "Czech Koruna")
    ("DJF" "Djibouti Franc")
    ("DKK" "Danish Krone")
    ("DOP" "Dominican Peso")
    ("DZD" "Algerian Dinar")
    ("EEK" "Estonian Kroon")
    ("EGP" "Egyptian Pound")
    ("ERN" "Eritrea Nakfa")
    ("ETB" "Ethiopian Birr")
    ("EUR" "Euro")
    ("FJD" "Fiji Dollar")
    ("FKP" "Falkland Islands Pound")
    ("GBP" "Pound Sterling")
    ("GEL" "Georgian Lari")
    ("GHC" "Ghana Cedi")
    ("GIP" "Gibraltar Pound")
    ("GMD" "Gambian Dalasi")
    ("GNF" "Guinea Franc")
    ("GTQ" "Guatemalan Quetzal")
    ("GWP" "Guinea-Bissau Peso")
    ("GYD" "Guyana Dollar")
    ("HKD" "Hong Kong Dollar")
    ("HNL" "Honduran Lempira")
    ("HRK" "Croatian Kuna")
    ("HTG" "Haitian Gourde")
    ("HUF" "Hungarian Forint")
    ("IDR" "Indonesian Rupiah")
    ("ILS" "New Israeli Shekel")
    ("INR" "Indian Rupee")
    ("IQD" "Iraqi Dinar")
    ("IRR" "Iranian Rial")
    ("ISK" "Iceland Krona")
    ("JMD" "Jamaican Dollar")
    ("JOD" "Jordanian Dinar")
    ("JPY" "Japanese Yen")
    ("KES" "Kenyan Shilling")
    ("KGS" "Kyrgyzstan Som")
    ("KHR" "Cambodian Riel")
    ("KMF" "Comoro Franc")
    ("KPW" "North Korean Won")
    ("KRW" "South Korean Won")
    ("KWD" "Kuwaiti Dinar")
    ("KYD" "Cayman Islands Dollar")
    ("KZT" "Kazakhstan Tenge")
    ("LAK" "Lao Kip")
    ("LBP" "Lebanese Pound")
    ("LKR" "Sri Lanka Rupee")
    ("LRD" "Liberian Dollar")
    ("LSL" "Lesotho Loti")
    ("LTL" "Lithuanian Litus")
    ("LVL" "Latvian Lats")
    ("LYD" "Libyan Dinar")
    ("MAD" "Moroccan Dirham")
    ("MDL" "Moldovan Leu")
    ("MGA" "Malagasy ariary")
    ("MGF" "Malagasy Franc")
    ("MKD" "Macedonian(Former Yug. Rep.) Denar")
    ("MMK" "Myanmar Kyat")
    ("MNT" "Mongolian Tugrik")
    ("MOP" "Macau Pataca")
    ("MRO" "Mauritanian Ouguiya")
    ("MTL" "Maltese Lira")
    ("MUR" "Mauritius Rupee")
    ("MVR" "Maldives Rufiyaa")
    ("MWK" "Malawi Kwacha")
    ("MXN" "Mexican Peso")
    ("MXV" "Mexican Unidad de Inversion (UDI) (Funds code)")
    ("MYR" "Malaysian Ringgit")
    ("MZM" "Moazambique Metical")
    ("NAD" "Namibian Dollar")
    ("NGN" "Nigerian Naira")
    ("NIO" "Nicaraguan Córdoba Oro")
    ("NOK" "Norwegian Krone")
    ("NPR" "Nepalese Rupee")
    ("NZD" "New Zealand Dollar")
    ("OMR" "Omani Rial")
    ("PAB" "Panama Balboa")
    ("PEN" "Peruvian Nuevo Sol")
    ("PGK" "Papua New Guinea Kina")
    ("PHP" "Philippine peso")
    ("PKR" "Pakistani Rupee")
    ("PLN" "Polish Zloty")
    ("PYG" "Paraguay Guarani")
    ("QAR" "Qatari Rial")
    ("ROL" "Romanian Leu")
    ("RUB" "Russian Ruble")
    ("RWF" "Rwanda Franc")
    ("SAR" "Saudi Riya")
    ("SBD" "Solomon Islands Dollar")
    ("SCR" "Seychelles Rupee")
    ("SDD" "Sudanese Dinar")
    ("SEK" "Swedish Krona")
    ("SGD" "Singapore Dollar")
    ("SHP" "Saint Helena Pound")
    ("SIT" "Slovene Tolar")
    ("SKK" "Slovak Koruna")
    ("SLL" "Sierra Leonean Leone")
    ("SOS" "Somali Shilling")
    ("SRD" "Suriname dollar (since 2004-01-01)")
    ("STD" "So Tom and Principe Dobra")
    ("SVC" "El Salvador Colón")
    ("SYP" "Syrian Pound")
    ("SZL" "Swaziland Lilangeni")
    ("THB" "Thai Baht")
    ("TJS" "Tajikistani Somoni")
    ("TMM" "Turkmenistan Manat")
    ("TND" "Tunisian Dinar")
    ("TOP" "Tongan Pa'anga")
    ("TPE" "Timor Escudo")
    ("TRL" "Turkish Lira")
    ("TTD" "Trinidad and Tobago Dollar")
    ("TWD" "New Taiwan Dollar")
    ("TZS" "Tanzanian Shilling")
    ("UAH" "Ukrainian Hryvnia")
    ("UGX" "Uganda Shilling")
    ("USD" "United States Dollar")
    ("USN" "United States Dollar (Next day) (Funds code)")
    ("USS" "United States Dollar (Same day) (Funds code) (one source claims it is no longer used, but it is still on the ISO 4217-MA list)")
    ("UYU" "Peso Uruguayo")
    ("UZS" "Uzbekistan Sum")
    ("VEB" "Venezuelan Bolivar")
    ("VND" "Viet Nam Dong")
    ("VUV" "Vanuatu Vatu")
    ("WST" "Samoa Tala")
    ("XAF" "CFA Franc BEAC")
    ("XAG" "Silver Ounce")
    ("XAU" "Gold Ounce")
    ("XBA" "European Composite Unit (EURCO) (Bonds market unit)")
    ("XBB" "European Monetary Unit (E.M.U.-6) (Bonds market unit)")
    ("XBC" "European Unit of Account 9 (E.U.A.-9) (Bonds market unit)")
    ("XBD" "European Unit of Account 17 (E.U.A.-17) (Bonds market unit)")
    ("XCD" "East Caribbean Dollar")
    ("XDR" "Special Drawing Rights (IMF)")
    ("XFO" "Gold-Franc (Special settlement currency)")
    ("XFU" "UIC Franc (Special settlement currency)")
    ("XOF" "CFA Franc BCEAO")
    ("XPD" "Palladium Ounce")
    ("XPF" "CFP Franc")
    ("XPT" "Platinum Ounce")
    ("XTS" "Code reserved for testing purposes")
    ("XXX" "No currency")
    ("YER" "Yemeni Rial")
    ("ZAR" "South African Rand")
    ("ZMK" "Zambian Kwacha")
    ("ZWD" "Zimbabwe Dollar")
    )) ;;+wikipedia-active+


(defparameter +wikipedia-Obsolete+
  '(
    ("ADP" "Andorran Peseta (Euro)")
    ("AFA" "Afghani (replaced by AFN)")
    ("AON" "Angolan New Kwanza (replaced by AOA)")
    ("AOR" "Angolan Kwanza Readjustado (replaced by AOA)")
    ("ATS" "Austrian Schilling (Euro)")
    ("BEC" "Belgian Franc (convertible)")
    ("BEF" "Belgian Franc (Euro)")
    ("BEL" "Belgian Franc (financial)")
    ("BGL" "Bulgarian Lev (before 1999-07-05)")
    ("CSK" "Czechoslovakia Koruna")
    ("DDM" "Mark der DDR (East Germany)")
    ("DEM" "Deutsche Mark (Euro)")
    ("ECS" "Ecuador Sucre (replaced by USD)")
    ("ECV" "Ecuador Unidad de Valor Constante (Funds code) (discontinued)")
    ("ESA" "Spanish Peseta (account A)")
    ("ESB" "Spanish Peseta (account B)")
    ("ESP" "Spanish Peseta (Euro)")
    ("FIM" "Finnish Markka (Euro)")
    ("FRF" "French Franc (Euro)")
    ("GRD" "Greek Drachma (Euro)")
    ("IEP" "Irish Pound (Euro)")
    ("ITL" "Italian Lira (Euro)")
    ("LUF" "Luxembourg Franc (Euro)")
    ("MXP" "Mexican Peso (replaced by MXN)")
    ("NLG" "Netherlands Guilder (Euro)")
    ("PLZ" "Polish Zloty (replaced by PLN)")
    ("PTE" "Portuguese Escudo (Euro)")
    ("RUR" "Russian Ruble (replaced by RUB)")
    ("SRG" "Suriname Guilder (replaced by SRD)")
    ("SUR" "Soviet Union Rouble")
    ("XEU" "European Currency Unit (replaced by EUR)")
    ("YUD" "New Yugoslavian Dinar (replaced by YUM)")
    ("YUM" "Yugoslavian Dinar (Serbian dinar - CSD)")
    ("ZAL" "South African financial rand (Funds code) (discontinued)")
    ("ZRN" "New Zaire (replaced by CDF)")
    ("ZRZ" "Zaire (replaced by ZRN, then by CDF)")
    )) ;;+wikipedia-Obsolete+


(defparameter +xe-countries+
  '(
    ("AFA"  "Afghanistan"  "Afghanis")
    ("ALL"  "Albania"  "Leke")
    ("DZD"  "Algeria"  "Dinars")
    ("USD"  "America (United States of America)"  "Dollars")
    ("USD"  "American Samoa"  "United States Dollars")
    ("USD"  "American Virgin Islands"  "United States Dollars")
    ("EUR"  "Andorra"  "Euro")
    ("AOA"  "Angola"  "Kwanza")
    ("XCD"  "Anguilla"  "East Caribbean Dollars")
    ("XCD"  "Antigua and Barbuda"  "East Caribbean Dollars")
    ("ARS"  "Argentina"  "Pesos")
    ("AMD"  "Armenia"  "Drams")
    ("AWG"  "Aruba"  "Guilders")
    ("ANG"  "Aruba"  "Netherlands Antilles Guilders")
    ("AUD"  "Australia"  "Dollars")
    ("EUR"  "Austria"  "Euro")
    ("AZM"  "Azerbaijan"  "Manats")
    ("EUR"  "Azores"  "Euro")
    ("BSD"  "Bahamas"  "Dollars")
    ("BHD"  "Bahrain"  "Dinars")
    ("EUR"  "Baleares (Balearic Islands)"  "Euro")
    ("BDT"  "Bangladesh"  "Taka")
    ("BBD"  "Barbados"  "Dollars")
    ("XCD"  "Barbuda and Antigua"  "East Caribbean Dollars")
    ("BYR"  "Belarus"  "Rubles")
    ("EUR"  "Belgium"  "Euro")
    ("BZD"  "Belize"  "Dollars")
    ("XOF"  "Benin"  "Communauté Financière Africaine Francs(BCEAO)")
    ("BMD"  "Bermuda"  "Dollars")
    ("BTN"  "Bhutan"  "Ngultrum")
    ("INR"  "Bhutan"  "India Rupeess")
    ("BOB"  "Bolivia"  "Bolivianos")
    ("ANG"  "Bonaire"  "Netherlands Antilles Guilders")
    ("BAM"  "Bosnia and Herzegovina"  "Convertible Marka")
    ("BWP"  "Botswana"  "Pulas")
    ("NOK"  "Bouvet Island"  "Norway Kroner")
    ("BRL"  "Brazil"  "Real")
    ("GBP"  "Britain (United Kingdom)"  "Pounds")
    ("USD"  "British Indian Ocean Territory"  "United States Dollars")
    ("USD"  "British Virgin Islands"  "United States Dollars")
    ("BND"  "Brunei Darussalam"  "Dollars")
    ("BGN"  "Bulgaria"  "Leva")
    ("XOF"  "Burkina Faso"  "Communauté Financière Africaine Francs(BCEAO)")
    ("MMK"  "Burma (Myanmar)"  "Kyats")
    ("BIF"  "Burundi"  "Francs")
    ("XOF"  "Côte D'Ivoire"  "Communauté Financière Africaine Francs(BCEAO)")
    ("USD"  "Caicos and Turks Islands"  "United States Dollars")
    ("KHR"  "Cambodia"  "Riels")
    ("XAF"  "Cameroon"  "Communauté Financière Africaine Francs(BEAC)")
    ("CAD"  "Canada"  "Dollars")
    ("EUR"  "Canary Islands"  "Euro")
    ("CVE"  "Cape Verde"  "Escudos")
    ("KYD"  "Cayman Islands"  "Dollars")
    ("XAF"  "Central African Republic"  "Communauté Financière Africaine Francs(BEAC)")
    ("XAF"  "Chad"  "Communauté Financière Africaine Francs(BEAC)")
    ("CLP"  "Chile"  "Pesos")
    ("CNY"  "China"  "Yuan Renminbi")
    ("AUD"  "Christmas Island"  "Australia Dollars")
    ("AUD"  "Cocos (Keeling) Islands"  "Australia Dollars")
    ("COP"  "Colombia"  "Pesos")
    ("XAF"  "Communauté Financière Africaine (CFA)"  "Francs")
    ("KMF"  "Comoros"  "Francs")
    ("XPF"  "Comptoirs Français du Pacifique (CFP)"  "Francs")
    ("XAF"  "Congo/Brazzaville"  "Communauté Financière Africaine Francs(BEAC)")
    ("CDF"  "Congo/Kinshasa"  "Francs")
    ("NZD"  "Cook Islands"  "New Zealand Dollars")
    ("CRC"  "Costa Rica"  "Colones")
    ("HRK"  "Croatia"  "Kuna")
    ("CUP"  "Cuba"  "Pesos")
    ("ANG"  "Curaço"  "Netherlands Antilles Guilders")
    ("CYP"  "Cyprus"  "Pounds")
    ("CZK"  "Czech Republic"  "Koruny")
    ("DKK"  "Denmark"  "Kroner")
    ("DJF"  "Djibouti"  "Francs")
    ("XCD"  "Dominica"  "East Caribbean Dollars")
    ("DOP"  "Dominican Republic"  "Pesos")
    ("EUR"  "Dutch (Netherlands)"   "Euro")
    ("XCD"  "East Caribbean"  "Dollars")
    ("IDR"  "East Timor"  "Indonesia Rupiahs")
    ("USD"  "Ecuador"  "United States Dollars")
    ("EGP"  "Egypt"  "Pounds")
    ("EUR"  "Eire (Ireland)"  "Euro")
    ("SVC"  "El Salvador"  "Colones")
    ("GBP"  "England (United Kingdom)"  "Pounds")
    ("XAF"  "Equatorial Guinea"  "Communauté Financière Africaine Francs(BEAC)")
    ("ETB"  "Eritrea"  "Ethiopia Birr")
    ("ERN"  "Eritrea"  "Nakfa")
    ("EEK"  "Estonia"  "Krooni")
    ("ETB"  "Ethiopia"  "Birr")
    ("EUR"  "Euro Member Countries"  "Euro")
    ("FKP"  "Falkland Islands (Malvinas)"  "Pounds")
    ("DKK"  "Faroe Islands"  "Denmark Kroner")
    ("FJD"  "Fiji"  "Dollars")
    ("EUR"  "Finland"  "Euro")
    ("EUR"  "France"  "Euro")
    ("EUR"  "French Guiana"  "Euro")
    ("XPF"  "French Pacific Islands (French Polynesia)"  "Comptoirs Français du Pacifique Francs")
    ("XPF"  "French Polynesia (French Pacific Islands)"  "Comptoirs Français du Pacifique Francs")
    ("EUR"  "French Southern Territories"  "Euro")
    ("XPF"  "Futuna and Wallis Islands"  "Comptoirs Français du Pacifique Francs")
    ("XAF"  "Gabon"  "Communauté Financière Africaine Francs(BEAC)")
    ("GMD"  "Gambia"  "Dalasi")
    ("GEL"  "Georgia"  "Lari")
    ("EUR"  "Germany"  "Euro")
    ("GHC"  "Ghana"  "Cedis")
    ("GIP"  "Gibraltar"  "Pounds")
    ("XAU"  "Gold"  "Ounces")
    ("GBP"  "Great Britain (United Kingdom)"  "Pounds")
    ("EUR"  "Greece"  "Euro")
    ("DKK"  "Greenland"  "Denmark Kroner")
    ("XCD"  "Grenada"  "East Caribbean Dollars")
    ("XCD"  "Grenadines (The) and Saint Vincent"  "East Caribbean Dollars")
    ("EUR"  "Guadeloupe"  "Euro")
    ("USD"  "Guam"  "United States Dollars")
    ("GTQ"  "Guatemala"  "Quetzales")
    ("GGP"  "Guernsey"  "Pounds")
    ("GNF"  "Guinea"  "Francs")
    ("XOF"  "Guinea-Bissau"  "Communauté Financière Africaine Francs(BCEAO)")
    ("GYD"  "Guyana"  "Dollars")
    ("HTG"  "Haiti"  "Gourdes")
    ("USD"  "Haiti"  "United States Dollars")
    ("AUD"  "Heard Island and McDonald Islands"  "Australia Dollars")
    ("BAM"  "Herzegovina and Bosnia"  "Convertible Marka")
    ("EUR"  "Holland (Netherlands)"  "Euro")
    ("EUR  Holy See"  "(Vatican City)"  "Euro")
    ("HNL"  "Honduras"  "Lempiras")
    ("HKD"  "Hong Kong"  "Dollars")
    ("HUF"  "Hungary"  "Forint")
    ("ISK"  "Iceland"  "Kronur")
    ("INR"  "India"  "Rupees")
    ("IDR"  "Indonesia"  "Rupiahs")
    ("XDR"  "International Monetary Fund (IMF)"  "Special Drawing Rights")
    ("IRR"  "Iran"  "Rials")
    ("IQD"  "Iraq"  "Dinars")
    ("EUR"  "Ireland (Eire)"  "Euro")
    ("IMP"  "Isle of Man"  "Pounds")
    ("ILS"  "Israel"  "New Shekels")
    ("EUR"  "Italy"  "Euro")
    ("JMD"  "Jamaica"  "Dollars")
    ("NOK"  "Jan Mayen and Svalbard"  "Norway Kroner")
    ("JPY"  "Japan"  "Yen")
    ("JEP"  "Jersey"  "Pounds")
    ("JOD"  "Jordan"  "Dinars")
    ("KZT"  "Kazakstan"  "Tenge")
    ("AUD"  "Keeling (Cocos) Islands"  "Australia Dollars")
    ("KES"  "Kenya"  "Shillings")
    ("AUD"  "Kiribati"  "Australia Dollars")
    ("KPW"  "Korea (North)"  "Won")
    ("KRW"  "Korea (South)"  "Won")
    ("KWD"  "Kuwait"  "Dinars")
    ("KGS"  "Kyrgyzstan"  "Soms")
    ("LAK"  "Laos"  "Kips")
    ("LVL"  "Latvia"  "Lati")
    ("LBP"  "Lebanon"  "Pounds")
    ("LSL"  "Lesotho"  "Maloti")
    ("ZAR"  "Lesotho"  "South Africa Rand")
    ("LRD"  "Liberia"  "Dollars")
    ("LYD"  "Libya"  "Dinars")
    ("CHF"  "Liechtenstein"  "Switzerland Francs")
    ("LTL"  "Lithuania"  "Litai")
    ("EUR"  "Luxembourg"  "Euro")
    ("MOP"  "Macau"  "Patacas")
    ("MKD"  "Macedonia"  "Denars")
    ("MGA"  "Madagascar"  "Ariary")
    ("EUR"  "Madeira Islands"  "Euro")
    ("MWK"  "Malawi"  "Kwachas")
    ("MYR"  "Malaysia"  "Ringgits")
    ("MVR"  "Maldives (Maldive Islands)"  "Rufiyaa")
    ("XOF"  "Mali"  "Communauté Financière Africaine Francs(BCEAO)")
    ("MTL"  "Malta"  "Liri")
    ("FKP"  "Malvinas (Falkland Islands)"  "Pounds")
    ("USD"  "Mariana Islands (Northern)"  "United States Dollars")
    ("USD"  "Marshall Islands"  "United States Dollars")
    ("EUR"  "Martinique"  "Euro")
    ("MRO"  "Mauritania"  "Ouguiyas")
    ("MUR"  "Mauritius"  "Rupees")
    ("EUR"  "Mayotte"  "Euro")
    ("AUD"  "McDonald Islands and Heard Island"  "Australia Dollars")
    ("MXN"  "Mexico"  "Pesos")
    ("USD"  "Micronesia (Federated States of)"  "United States Dollars")
    ("USD"  "Midway Islands"  "United States Dollars")
    ("EUR"  "Miquelon and Saint Pierre"  "Euro")
    ("MDL"  "Moldova"  "Lei")
    ("EUR"  "Monaco"  "Euro")
    ("MNT"  "Mongolia"  "Tugriks")
    ("EUR"  "Montenegro"  "Euro")
    ("XCD"  "Montserrat"  "East Caribbean Dollars")
    ("MAD"  "Morocco"  "Dirhams")
    ("MZM"  "Mozambique"  "Meticais")
    ("MMK"  "Myanmar (Burma)"  "Kyats")
    ("NAD"  "Namibia"  "Dollars")
    ("ZAR"  "Namibia"  "South Africa Rand")
    ("AUD"  "Nauru"  "Australia Dollars")
    ("NPR"  "Nepal"  "Rupees")
    ("ANG"  "Netherlands Antilles"  "Guilders")
    ("EUR"  "Netherlands"  "Euro")
    ("XCD"  "Nevis and Saint Kitts"  "East Caribbean Dollars")
    ("XPF"  "New Caledonia"  "Comptoirs Français du Pacifique Francs")
    ("NZD"  "New Zealand"  "Dollars")
    ("NIO"  "Nicaragua"  "Gold Cordobas")
    ("XOF"  "Niger"  "Communauté Financière Africaine Francs(BCEAO)")
    ("NGN"  "Nigeria"  "Nairas")
    ("NZD"  "Niue"  "New Zealand Dollars")
    ("AUD"  "Norfolk Island"  "Australia Dollars")
    ("USD"  "Northern Mariana Islands"  "United States Dollars")
    ("NOK"  "Norway"  "Kroner")
    ("OMR"  "Oman"  "Rials")
    ("PKR"  "Pakistan"  "Rupees")
    ("USD"  "Palau"  "United States Dollars")
    ("XPD"  "Palladium"  "Ounces")
    ("PAB"  "Panama"  "Balboa")
    ("USD"  "Panama"  "United States Dollars")
    ("PGK"  "Papua New Guinea"  "Kina")
    ("PYG"  "Paraguay"  "Guarani")
    ("PEN"  "Peru"  "Nuevos Soles")
    ("PHP"  "Philippines"  "Pesos")
    ("NZD"  "Pitcairn Islands"  "New Zealand Dollars")
    ("XPT"  "Platinum"  "Ounces")
    ("PLN"  "Poland"  "Zlotych")
    ("EUR"  "Portugal"  "Euro")
    ("STD"  "Principe and São Tome"  "Dobras")
    ("USD"  "Puerto Rico"  "United States Dollars")
    ("QAR"  "Qatar"  "Rials")
    ("EUR"  "Réunion"  "Euro")
    ("ROL"  "Romania"  "Lei")
    ("RUR"  "Russia"  "Rubles")
    ("RWF"  "Rwanda"  "Francs")
    ("STD"  "São Tome and Principe"  "Dobras")
    ("ANG"  "Saba"  "Netherlands Antilles Guilders")
    ("MAD"  "Sahara (Western)"  "Morocco Dirhams")
    ("XCD"  "Saint Christopher"  "East Caribbean Dollars")
    ("SHP"  "Saint Helena"  "Pounds")
    ("XCD"  "Saint Kitts and Nevis"  "East Caribbean Dollars")
    ("XCD"  "Saint Lucia"  "East Caribbean Dollars")
    ("EUR"  "Saint Pierre and Miquelon"  "Euro")
    ("XCD"  "Saint Vincent and The Grenadines"  "East Caribbean Dollars")
    ("EUR"  "Saint-Martin"  "Euro")
    ("USD"  "Samoa (American)"  "United States Dollars")
    ("WST"  "Samoa"  "Tala")
    ("EUR"  "San Marino"  "Euro")
    ("SAR"  "Saudi Arabia"  "Riyals")
    ("SPL"  "Seborga"  "Luigini")
    ("XOF"  "Senegal"  "Communauté Financière Africaine Francs(BCEAO)")
    ("CSD"  "Serbia"  "Dinars")
    ("SCR"  "Seychelles"  "Rupees")
    ("SLL"  "Sierra Leone"  "Leones")
    ("XAG"  "Silver"  "Ounces")
    ("SGD"  "Singapore"  "Dollars")
    ("ANG"  "Sint Eustatius"  "Netherlands Antilles Guilders")
    ("ANG"  "Sint Maarten"  "Netherlands Antilles Guilders")
    ("SKK"  "Slovakia"  "Koruny")
    ("SIT"  "Slovenia"  "Tolars")
    ("SBD"  "Solomon Islands"  "Dollars")
    ("SOS"  "Somalia"  "Shillings")
    ("ZAR"  "South Africa"  "Rand")
    ("GBP"  "South Georgia"  "United Kingdom Pounds")
    ("GBP"  "South Sandwich Islands"  "United Kingdom Pounds")
    ("EUR"  "Spain"  "Euro")
    ("XDR"  NIL  "Special Drawing Rights")
    ("LKR"  "Sri Lanka"  "Rupees")
    ("SDD"  "Sudan"  "Dinars")
    ("SRD"  "Suriname"  "Dollars")
    ("NOK"  "Svalbard and Jan Mayen"  "Norway Kroner")
    ("SZL"  "Swaziland"  "Emalangeni")
    ("SEK"  "Sweden"  "Kronor")
    ("CHF"  "Switzerland"  "Francs")
    ("SYP"  "Syria"  "Pounds")
    ("TWD"  "Taiwan"  "New Dollars")
    ("RUR"  "Tajikistan"  "Russia Rubles")
    ("TJS"  "Tajikistan"  "Somoni")
    ("TZS"  "Tanzania"  "Shillings")
    ("THB"  "Thailand"  "Baht")
    ("IDR"  "Timor (East)"  "Indonesia Rupiahs")
    ("TTD"  "Tobago and Trinidad"  "Dollars")
    ("XOF"  "Togo"  "Communauté Financière Africaine Francs(BCEAO)")
    ("NZD"  "Tokelau"  "New Zealand Dollars")
    ("TOP"  "Tonga"  "Pa'anga")
    ("TTD"  "Trinidad and Tobago"  "Dollars")
    ("TND"  "Tunisia"  "Dinars")
    ("TRL"  "Turkey"  "Liras")
    ("TMM"  "Turkmenistan"  "Manats")
    ("USD"  "Turks and Caicos Islands"  "United States Dollars")
    ("TVD"  "Tuvalu"  "Tuvalu Dollars")
    ("UGX"  "Uganda"  "Shillings")
    ("UAH"  "Ukraine"  "Hryvnia")
    ("AED"  "United Arab Emirates"  "Dirhams")
    ("GBP"  "United Kingdom"  "Pounds")
    ("USD"  "United States Minor Outlying Islands"  "United States Dollars")
    ("USD"  "United States of America"  "Dollars")
    ("UYU"  "Uruguay"  "Pesos")
    ("USD"  "US Virgin Islands"  "United States Dollars")
    ("UZS"  "Uzbekistan"  "Sums")
    ("VUV"  "Vanuatu"  "Vatu")
    ("EUR"  "Vatican City (The Holy See)"  "Euro")
    ("VEB"  "Venezuela"  "Bolivares")
    ("VND"  "Viet Nam"  "Dong")
    ("USD"  "Virgin Islands (American)"  "United States Dollars")
    ("USD"  "Virgin Islands (British)"  "United States Dollars")
    ("USD"  "Wake Island"  "United States Dollars")
    ("XPF"  "Wallis and Futuna Islands"  "Comptoirs Français du Pacifique Francs")
    ("WST"  "West Samoa (Samoa)"  "Tala")
    ("MAD"  "Western Sahara"  "Morocco Dirhams")
    ("WST"  "Western Samoa (Samoa)"  "Tala")
    ("YER"  "Yemen"  "Rials")
    ("ZMK"  "Zambia"  "Kwacha")
    ("ZWD"  "Zimbabwe"  "Zimbabwe Dollars")
    )) ;;+xe-countries+


(defparameter +xe-currencies+
  '(
    ("AED"   "United Arab Emirates"           "Dirhams")
    ("AFA"   "Afghanistan"                    "Afghanis")
    ("ALL"   "Albania"                        "Leke")
    ("AMD"   "Armenia"                        "Drams")
    ("ANG"   "Netherlands Antilles"           "Guilders")
    ("AOA"   "Angola"                         "Kwanza")
    ("ARS"   "Argentina"                      "Pesos")
    ("AUD"   "Australia"                      "Dollars")
    ("AWG"   "Aruba"                          "Guilders")
    ("AZM"   "Azerbaijan"                     "Manats")
    ("BAM"   "Bosnia and Herzegovina"         "Convertible Marka")
    ("BBD"   "Barbados"                       "Dollars")
    ("BDT"   "Bangladesh"                     "Taka")
    ("BGN"   "Bulgaria"                       "Leva")
    ("BHD"   "Bahrain"                        "Dinars")
    ("BIF"   "Burundi"                        "Francs")
    ("BMD"   "Bermuda"                        "Dollars")
    ("BND"   "Brunei Darussalam"              "Dollars")
    ("BOB"   "Bolivia"                        "Bolivianos")
    ("BRL"   "Brazil"                         "Brazil Real")
    ("BSD"   "Bahamas"                        "Dollars")
    ("BTN"   "Bhutan"                         "Ngultrum")
    ("BWP"   "Botswana"                       "Pulas")
    ("BYR"   "Belarus"                        "Rubles")
    ("BZD"   "Belize"                         "Dollars")
    ("CAD"   "Canada"                         "Dollars")
    ("CDF"   "Congo/Kinshasa"                 "Congolese Francs")
    ("CHF"   "Switzerland"                    "Francs")
    ("CLP"   "Chile"                          "Pesos")
    ("CNY"   "China"                          "Yuan Renminbi")
    ("COP"   "Colombia"                       "Pesos")
    ("CRC"   "Costa Rica"                     "Colones")
    ("CSD"   "Serbia"                         "Dinars")
    ("CUP"   "Cuba"                           "Pesos")
    ("CVE"   "Cape Verde"                     "Escudos")
    ("CYP"   "Cyprus"                         "Pounds")
    ("CZK"   "Czech Republic"                 "Koruny")
    ("DJF"   "Djibouti"                       "Francs")
    ("DKK"   "Denmark"                        "Kroner")
    ("DOP"   "Dominican Republic"             "Pesos")
    ("DZD"   "Algeria"                        "Algeria Dinars")
    ("EEK"   "Estonia"                        "Krooni")
    ("EGP"   "Egypt"                          "Pounds")
    ("ERN"   "Eritrea"                        "Nakfa")
    ("ETB"   "Ethiopia"                       "Birr")
    ("EUR"   "Euro Member Countries"          "Euro")
    ("FJD"   "Fiji"                           "Dollars")
    ("FKP"   "Falkland Islands (Malvinas)"    "Pounds")
    ("GBP"   "United Kingdom"                 "Pounds")
    ("GEL"   "Georgia"                        "Lari")
    ("GGP"   "Guernsey"                       "Pounds")
    ("GHC"   "Ghana"                          "Cedis")
    ("GIP"   "Gibraltar"                      "Pounds")
    ("GMD"   "Gambia"                         "Dalasi")
    ("GNF"   "Guinea"                         "Francs")
    ("GTQ"   "Guatemala"                      "Quetzales")
    ("GYD"   "Guyana"                         "Dollars")
    ("HKD"   "Hong Kong"                      "Dollars")
    ("HNL"   "Honduras"                       "Lempiras")
    ("HRK"   "Croatia"                        "Kuna")
    ("HTG"   "Haiti"                          "Gourdes")
    ("HUF"   "Hungary"                        "Forint")
    ("IDR"   "Indonesia"                      "Rupiahs")
    ("ILS"   "Israel"                         "New Shekels")
    ("IMP"   "Isle of Man"                    "Pounds")
    ("INR"   "India"                          "Rupees")
    ("IQD"   "Iraq"                           "Dinars")
    ("IRR"   "Iran"                           "Rials")
    ("ISK"   "Iceland"                        "Kronur")
    ("JEP"   "Jersey"                         "Pounds")
    ("JMD"   "Jamaica"                        "Dollars")
    ("JOD"   "Jordan"                         "Dinars")
    ("JPY"   "Japan"                          "Yen")
    ("KES"   "Kenya"                          "Shillings")
    ("KGS"   "Kyrgyzstan"                     "Soms")
    ("KHR"   "Cambodia"                       "Riels")
    ("KMF"   "Comoros"                        "Francs")
    ("KPW"   "Korea (North)"                  "Won")
    ("KRW"   "Korea (South)"                  "Won")
    ("KWD"   "Kuwait"                         "Dinars")
    ("KYD"   "Cayman Islands"                 "Dollars")
    ("KZT"   "Kazakstan"                      "Tenge")
    ("LAK"   "Laos"                           "Kips")
    ("LBP"   "Lebanon"                        "Pounds")
    ("LKR"   "Sri Lanka"                      "Rupees")
    ("LRD"   "Liberia"                        "Dollars")
    ("LSL"   "Lesotho"                        "Maloti")
    ("LTL"   "Lithuania"                      "Litai")
    ("LVL"   "Latvia"                         "Lati")
    ("LYD"   "Libya"                          "Dinars")
    ("MAD"   "Morocco"                        "Dirhams")
    ("MDL"   "Moldova"                        "Lei")
    ("MGA"   "Madagascar"                     "Ariary")
    ("MKD"   "Macedonia"                      "Denars")
    ("MMK"   "Myanmar (Burma)"                "Kyats")
    ("MNT"   "Mongolia"                       "Tugriks")
    ("MOP"   "Macau"                          "Patacas")
    ("MRO"   "Mauritania"                     "Ouguiyas")
    ("MTL"   "Malta"                          "Liri")
    ("MUR"   "Mauritius"                      "Rupees")
    ("MVR"   "Maldives (Maldive Islands)"     "Rufiyaa")
    ("MWK"   "Malawi"                         "Kwachas")
    ("MXN"   "Mexico"                         "Pesos")
    ("MYR"   "Malaysia"                       "Ringgits")
    ("MZM"   "Mozambique"                     "Meticais")
    ("NAD"   "Namibia"                        "Dollars")
    ("NGN"   "Nigeria"                        "Nairas")
    ("NIO"   "Nicaragua"                      "Gold Cordobas")
    ("NOK"   "Norway"                         "Krone")
    ("NPR"   "Nepal"                          "Nepal Rupees")
    ("NZD"   "New Zealand"                    "Dollars")
    ("OMR"   "Oman"                           "Rials")
    ("PAB"   "Panama"                         "Balboa")
    ("PEN"   "Peru"                           "Nuevos Soles")
    ("PGK"   "Papua New Guinea"               "Kina")
    ("PHP"   "Philippines"                    "Pesos")
    ("PKR"   "Pakistan"                       "Rupees")
    ("PLN"   "Poland"                         "Zlotych")
    ("PYG"   "Paraguay"                       "Guarani")
    ("QAR"   "Qatar"                          "Rials")
    ("ROL"   "Romania"                        "Lei")
    ("RUR"   "Russia"                         "Rubles")
    ("RWF"   "Rwanda"                         "Rwanda Francs")
    ("SAR"   "Saudi Arabia"                   "Riyals")
    ("SBD"   "Solomon Islands"                "Dollars")
    ("SCR"   "Seychelles"                     "Rupees")
    ("SDD"   "Sudan"                          "Dinars")
    ("SEK"   "Sweden"                         "Kronor")
    ("SGD"   "Singapore"                      "Dollars")
    ("SHP"   "Saint Helena"                   "Pounds")
    ("SIT"   "Slovenia"                       "Tolars")
    ("SKK"   "Slovakia"                       "Koruny")
    ("SLL"   "Sierra Leone"                   "Leones")
    ("SOS"   "Somalia"                        "Shillings")
    ("SPL"   "Seborga"                        "Luigini")
    ("SRD"   "Suriname"                       "Dollars")
    ("STD"   "São Tome and Principe"          "Dobras")
    ("SVC"   "El Salvador"                    "Colones")
    ("SYP"   "Syria"                          "Pounds")
    ("SZL"   "Swaziland"                      "Emalangeni")
    ("THB"   "Thailand"                       "Baht")
    ("TJS"   "Tajikistan"                     "Somoni")
    ("TMM"   "Turkmenistan"                   "Manats")
    ("TND"   "Tunisia"                        "Dinars")
    ("TOP"   "Tonga"                          "Pa'anga")
    ("TRL"   "Turkey"                         "Liras")
    ("TTD"   "Trinidad and Tobago"            "Dollars")
    ("TVD"   "Tuvalu"                         "Tuvalu Dollars")
    ("TWD"   "Taiwan"                         "New Dollars")
    ("TZS"   "Tanzania"                       "Shillings")
    ("UAH"   "Ukraine"                        "Hryvnia")
    ("UGX"   "Uganda"                         "Shillings")
    ("USD"   "United States of America"       "Dollars")
    ("UYU"   "Uruguay"                        "Pesos")
    ("UZS"   "Uzbekistan"                     "Sums")
    ("VEB"   "Venezuela"                      "Bolivares")
    ("VND"   "Viet Nam"                       "Dong")
    ("VUV"   "Vanuatu"                        "Vatu")
    ("WST"   "Samoa"                          "Tala")
    ("XAF"   "Communauté Financière Africaine, BEAC" "Francs")
    ("XAG"   "Silver"                         "Ounces")
    ("XAU"   "Gold"                           "Ounces")
    ("XCD"   "East Caribbean"                 "Dollars")
    ("XDR"   "International Monetary Fund (IMF)" "Special Drawing Rights")
    ("XOF"   "Communauté Financière Africaine, BCEAO" "Francs")
    ("XPD"   "Palladium"                      "Ounces")
    ("XPF"   "Comptoirs Français du Pacifique" "Francs")
    ("XPT"   "Platinum"                       "Ounces")
    ("YER"   "Yemen"                          "Rials")
    ("ZAR"   "South Africa"                   "Rand")
    ("ZMK"   "Zambia"                         "Kwacha")
    ("ZWD"   "Zimbabwe"                       "Zimbabwe Dollars")
    )) ;;+xe-currencies+


(defun print-formated-data ()
  (dolist (x '(+xe-countries+ +xe-currencies+
               +wikipedia-active+ +wikipedia-Obsolete+))
    (let ((maxes (make-array (list 20) :initial-element 0)))
      (dolist (y (eval x))
        (do ((z y (cdr z))
             (i 0 (1+ i)))
            ((null z))
          (setf (aref maxes i)  (max  (aref maxes i)
                                      (length
                                       (if (typep (car z) 'sequence)
                                           (car z)
                                           (format nil "~A" (car z))))))))
      (let* ((widths (map 'list (function identity)
                          (subseq maxes 0
                                  (1+ (position-if-not
                                       (function zerop) maxes :from-end t)))))
             (tot-width (apply (function +) widths)))
        ;; (format t "~&;; ~5D : ~{~4D ~}~%"  tot-width widths)
        (unless (< tot-width 72)
          (let ((big-cnt 0) (big-wid 0) (sma-wid 0) (big-rat))
            (dolist (w widths)
              (if (< 20 w)
                  (incf big-wid (+ 3 w))
                  (incf sma-wid (+ 3 w))))
            ;;(print (list :tot-width tot-width :sma-wid sma-wid :big-wid big-wid))
            (setf big-rat (/ (- (+ (length widths) tot-width) sma-wid)
                             (- 64 sma-wid)))
            (map-into widths
                      (lambda (w)
                        (if (< 20 w)
                            (+ 2 (truncate w big-rat))
                            (+ 2 w))) widths)))
        ;;(format t "~&;; ~5D : ~{~4D ~}~%"  (apply (function +) widths) widths)
        (format t "~%(defparameter ~A~%'(~%" x)
        (dolist (y (mapcar (lambda (y) y) (eval x)))
          (format t "(")
          (do ((y y (cdr y))
               (w widths (cdr w)))
              ((null y) (format t ")~%"))
            (if (numberp (car y))
                (format t "~VD " (car w) (car y))
                (format t "~VS " (car w) (car y)))))
        (format t "))~2%"))))) ;;print-formated-data


(DOLIST (CUR +COCUCOD+)
  (LET ((COU (CAR (MEMBER (SECOND CUR) +COUNTRIES+
                          :TEST (FUNCTION STRING-EQUAL)
                          :KEY (FUNCTION FIRST)))))
    (IF (NOT COU)
        (FORMAT T "NOT FOUND: ~S~%" CUR)
        (IF (NOT (STRING-EQUAL (SECOND COU) (FIRST CUR)))
            (FORMAT T "COUNTRY NAME DOESN'T MATCH ~S ~%    ~S~%    ~S~%"
                    (second cur) (first CUR) (second COU))))))

(progn
  (defparameter +country-currency+ '())
  (defparameter +currencies+       '())
  (dolist (cocu +cocucod+)
    (push (list (first cocu) (third cocu) (sixth cocu)) +country-currency+)
    (push (list (third cocu) (fourth cocu) (fifth cocu) (second cocu))
          +currencies+))
  (setf +country-currency+  (sort (delete-duplicates +country-currency+
                                                     :test (function equalp))
                                  (function string<) :key (function first))
        +currencies+        (sort (delete-duplicates +currencies+
                                                     :test (function equalp))
                                  (function string<) :key (function first))))
||#

;;;; iso4217.lisp                     --                     --          ;;;;
ViewGit