mirror of https://github.com/gogits/gogs.git
Michael Boke
10 years ago
289 changed files with 129308 additions and 2869 deletions
@ -1,12 +0,0 @@ |
|||||||
{ |
|
||||||
"paths": ["."], |
|
||||||
"depth": 2, |
|
||||||
"exclude": [], |
|
||||||
"include": ["\\.go$", "\\.ini$"], |
|
||||||
"command": [ |
|
||||||
"bash", "-c", "go build && ./gogs web" |
|
||||||
], |
|
||||||
"env": { |
|
||||||
"POWERED_BY": "github.com/shxsun/fswatch" |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,15 @@ |
|||||||
|
targets: |
||||||
|
ubuntu-14.04: |
||||||
|
ubuntu-12.04: |
||||||
|
debian-7: |
||||||
|
build_dependencies: |
||||||
|
- mercurial |
||||||
|
- bzr |
||||||
|
dependencies: |
||||||
|
- git |
||||||
|
before: |
||||||
|
- mv packager/Procfile . |
||||||
|
- mv packager/.godir . |
||||||
|
after: |
||||||
|
- mv bin/main gogs |
||||||
|
after_install: ./packager/debian/postinst |
@ -0,0 +1,158 @@ |
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package cmd |
||||||
|
|
||||||
|
import ( |
||||||
|
"crypto/ecdsa" |
||||||
|
"crypto/elliptic" |
||||||
|
"crypto/rand" |
||||||
|
"crypto/rsa" |
||||||
|
"crypto/x509" |
||||||
|
"crypto/x509/pkix" |
||||||
|
"encoding/pem" |
||||||
|
"log" |
||||||
|
"math/big" |
||||||
|
"net" |
||||||
|
"os" |
||||||
|
"strings" |
||||||
|
"time" |
||||||
|
|
||||||
|
"github.com/codegangsta/cli" |
||||||
|
) |
||||||
|
|
||||||
|
var CmdCert = cli.Command{ |
||||||
|
Name: "cert", |
||||||
|
Usage: "Generate self-signed certificate", |
||||||
|
Description: `Generate a self-signed X.509 certificate for a TLS server.
|
||||||
|
Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`, |
||||||
|
Action: runCert, |
||||||
|
Flags: []cli.Flag{ |
||||||
|
cli.StringFlag{"host", "", "Comma-separated hostnames and IPs to generate a certificate for", ""}, |
||||||
|
cli.StringFlag{"ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521", ""}, |
||||||
|
cli.IntFlag{"rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set", ""}, |
||||||
|
cli.StringFlag{"start-date", "", "Creation date formatted as Jan 1 15:04:05 2011", ""}, |
||||||
|
cli.DurationFlag{"duration", 365 * 24 * time.Hour, "Duration that certificate is valid for", ""}, |
||||||
|
cli.BoolFlag{"ca", "whether this cert should be its own Certificate Authority", ""}, |
||||||
|
}, |
||||||
|
} |
||||||
|
|
||||||
|
func publicKey(priv interface{}) interface{} { |
||||||
|
switch k := priv.(type) { |
||||||
|
case *rsa.PrivateKey: |
||||||
|
return &k.PublicKey |
||||||
|
case *ecdsa.PrivateKey: |
||||||
|
return &k.PublicKey |
||||||
|
default: |
||||||
|
return nil |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func pemBlockForKey(priv interface{}) *pem.Block { |
||||||
|
switch k := priv.(type) { |
||||||
|
case *rsa.PrivateKey: |
||||||
|
return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)} |
||||||
|
case *ecdsa.PrivateKey: |
||||||
|
b, err := x509.MarshalECPrivateKey(k) |
||||||
|
if err != nil { |
||||||
|
log.Fatal("unable to marshal ECDSA private key: %v", err) |
||||||
|
} |
||||||
|
return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b} |
||||||
|
default: |
||||||
|
return nil |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func runCert(ctx *cli.Context) { |
||||||
|
if len(ctx.String("host")) == 0 { |
||||||
|
log.Fatal("Missing required --host parameter") |
||||||
|
} |
||||||
|
|
||||||
|
var priv interface{} |
||||||
|
var err error |
||||||
|
switch ctx.String("ecdsa-curve") { |
||||||
|
case "": |
||||||
|
priv, err = rsa.GenerateKey(rand.Reader, ctx.Int("rsa-bits")) |
||||||
|
case "P224": |
||||||
|
priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader) |
||||||
|
case "P256": |
||||||
|
priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) |
||||||
|
case "P384": |
||||||
|
priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader) |
||||||
|
case "P521": |
||||||
|
priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) |
||||||
|
default: |
||||||
|
log.Fatalf("Unrecognized elliptic curve: %q", ctx.String("ecdsa-curve")) |
||||||
|
} |
||||||
|
if err != nil { |
||||||
|
log.Fatalf("Failed to generate private key: %s", err) |
||||||
|
} |
||||||
|
|
||||||
|
var notBefore time.Time |
||||||
|
if len(ctx.String("start-date")) == 0 { |
||||||
|
notBefore = time.Now() |
||||||
|
} else { |
||||||
|
notBefore, err = time.Parse("Jan 2 15:04:05 2006", ctx.String("start-date")) |
||||||
|
if err != nil { |
||||||
|
log.Fatalf("Failed to parse creation date: %s", err) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
notAfter := notBefore.Add(ctx.Duration("duration")) |
||||||
|
|
||||||
|
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) |
||||||
|
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) |
||||||
|
if err != nil { |
||||||
|
log.Fatalf("Failed to generate serial number: %s", err) |
||||||
|
} |
||||||
|
|
||||||
|
template := x509.Certificate{ |
||||||
|
SerialNumber: serialNumber, |
||||||
|
Subject: pkix.Name{ |
||||||
|
Organization: []string{"Acme Co"}, |
||||||
|
}, |
||||||
|
NotBefore: notBefore, |
||||||
|
NotAfter: notAfter, |
||||||
|
|
||||||
|
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, |
||||||
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, |
||||||
|
BasicConstraintsValid: true, |
||||||
|
} |
||||||
|
|
||||||
|
hosts := strings.Split(ctx.String("host"), ",") |
||||||
|
for _, h := range hosts { |
||||||
|
if ip := net.ParseIP(h); ip != nil { |
||||||
|
template.IPAddresses = append(template.IPAddresses, ip) |
||||||
|
} else { |
||||||
|
template.DNSNames = append(template.DNSNames, h) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if ctx.Bool("ca") { |
||||||
|
template.IsCA = true |
||||||
|
template.KeyUsage |= x509.KeyUsageCertSign |
||||||
|
} |
||||||
|
|
||||||
|
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) |
||||||
|
if err != nil { |
||||||
|
log.Fatalf("Failed to create certificate: %s", err) |
||||||
|
} |
||||||
|
|
||||||
|
certOut, err := os.Create("cert.pem") |
||||||
|
if err != nil { |
||||||
|
log.Fatalf("Failed to open cert.pem for writing: %s", err) |
||||||
|
} |
||||||
|
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) |
||||||
|
certOut.Close() |
||||||
|
log.Println("Written cert.pem") |
||||||
|
|
||||||
|
keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) |
||||||
|
if err != nil { |
||||||
|
log.Fatal("failed to open key.pem for writing: %v", err) |
||||||
|
} |
||||||
|
pem.Encode(keyOut, pemBlockForKey(priv)) |
||||||
|
keyOut.Close() |
||||||
|
log.Println("Written key.pem") |
||||||
|
} |
@ -0,0 +1,516 @@ |
|||||||
|
app_desc = Un service Git écrit en Go auto-hébergé |
||||||
|
|
||||||
|
home = Accueil |
||||||
|
dashboard = Tableau de bord |
||||||
|
explore = Explorer |
||||||
|
help = Aide |
||||||
|
sign_in = Connexion |
||||||
|
social_sign_in = Authentification via Internet: 2ème étape <small>associé le compte</small> |
||||||
|
sign_out = Déconnexion |
||||||
|
sign_up = Créer un compte |
||||||
|
register = S'inscrire |
||||||
|
website = Site web |
||||||
|
version = Version |
||||||
|
page = Page |
||||||
|
template = Gabarit |
||||||
|
language = Langage |
||||||
|
|
||||||
|
username = Usager |
||||||
|
email = Courriel |
||||||
|
password = Mot de passe |
||||||
|
re_type = Saisir à nouveau |
||||||
|
captcha = Captcha |
||||||
|
|
||||||
|
repository = Dépôt |
||||||
|
organization = Organisation |
||||||
|
mirror = Mirroir |
||||||
|
new_repo = Nouveau dépôt |
||||||
|
new_migrate = Nouvelle migration |
||||||
|
new_org = Nouvel organisation |
||||||
|
manage_org = Gestion des organisations |
||||||
|
admin_panel = Gestion |
||||||
|
account_settings = Profil usager |
||||||
|
settings = Configuration |
||||||
|
|
||||||
|
news_feed = Fil de nouvelles |
||||||
|
pull_requests = Demandes de fusion (pull requests) |
||||||
|
issues = Suivi de problèmes |
||||||
|
|
||||||
|
cancel = Annuler |
||||||
|
|
||||||
|
[home] |
||||||
|
uname_holder = Nom d'usager ou courriel |
||||||
|
password_holder = Mot de passe |
||||||
|
switch_dashboard_context = Changer de tableau de bord |
||||||
|
my_repos = Mes dépôts |
||||||
|
collaborative_repos = Dépôts partagés |
||||||
|
my_orgs = Mes organisations |
||||||
|
my_mirrors = Mes mirroirs |
||||||
|
|
||||||
|
[auth] |
||||||
|
create_new_account = Créer un nouveau compte |
||||||
|
register_hepler_msg = Déjà inscrits? Connectez-vous maintenant! |
||||||
|
social_register_hepler_msg = Déjà inscrits? Branchez-vous! |
||||||
|
disable_register_prompt = Désolé, l'auto-inscription n'est pas activée. Contactez l'admnistrateur du site. |
||||||
|
disable_register_mail = Désolé, la confirmation d'inscription par courriel est désactivée. Contactez l'administrateur du site. |
||||||
|
remember_me = Se souvenir de moi |
||||||
|
forgot_password= Mot de passe oublié |
||||||
|
forget_password = Mot de passe oublié? |
||||||
|
sign_up_now = Besoin d'un compte? Inscrivez-vous maintenant. |
||||||
|
confirmation_mail_sent_prompt = Un courriel de confirmation à été envoyé à <b>%s</b>, consultez vos courriels d'ici %d heures pour terminer l'inscription. |
||||||
|
sign_in_email = Connexion avec votre courriel |
||||||
|
active_your_account = Activez votre compte |
||||||
|
resent_limit_prompt = Désolé vous demandez trop souvent un courriel de confirmation. S.v.p. patientez 3 minutes. |
||||||
|
has_unconfirmed_mail = Bonjour %s, votre adresse courriel n'est pas vérifiée(<b>%s</b>). Si vous n'avez pas reçu de courriel de confirmation ou si vous avez besoin d'en envoyer un maintenant, appuyez sur le bouton ci-dessous. |
||||||
|
resend_mail = Appuyez ici pour envoyer de nouveau un courriel de confirmation. |
||||||
|
email_not_associate = Ce courriel ne correspond à aucun compte. |
||||||
|
send_reset_mail = Appuyez ici pour (ré)envoyer un courriel pour réinitialiser le mot de passe. |
||||||
|
reset_password = Réinitialiser votre mot de passe |
||||||
|
invalid_code = Désolé, ce code de confirmation est périmé ou non-valide. |
||||||
|
reset_password_helper = Appuyez ici pour réinitialiser votre mot de passe |
||||||
|
password_too_short = La longueur du mot de passe doit être d'au moins 6 caractères. |
||||||
|
|
||||||
|
[form] |
||||||
|
UserName = Nom d'usager |
||||||
|
RepoName = Nom du dépôt |
||||||
|
Email = Adresse de courriel |
||||||
|
Password = Mot de passe |
||||||
|
Retype = Mot de passe (confirmation) |
||||||
|
SSHTitle = Nom de la clé SSH |
||||||
|
HttpsUrl = URL HTTPS |
||||||
|
PayloadUrl = URL cible |
||||||
|
TeamName = Nom de l'équipe |
||||||
|
AuthName = Nom d'usager |
||||||
|
|
||||||
|
require_error = ` ne peut être vide.` |
||||||
|
alpha_dash_error = ` doit être composé de caractères alpha-numériques et/ou d'un tiret(-_).` |
||||||
|
alpha_dash_dot_error = ` doit être composé de caractères alpha-numérique, un point(.) et/ou tiret(-_).` |
||||||
|
min_size_error = ` doit être composé d'au moins %s caractères.` |
||||||
|
max_size_error = ` doit être conposé d'au plus %s caractères.` |
||||||
|
email_error = ` n'est pas une adresse de courriel bien formée.` |
||||||
|
url_error = ` n'est pas un URL valide.` |
||||||
|
unknown_error = Erreur inconnue: |
||||||
|
captcha_incorrect = Le captcha ne concorde pas. |
||||||
|
password_not_match = Les deux mots de passe diffèrent. |
||||||
|
|
||||||
|
username_been_taken = `Nom d'usager dèjà utilisé.` |
||||||
|
repo_name_been_taken = Nom de dépôt déjà utilisé. |
||||||
|
org_name_been_taken = Nom d'organisation déjà utilisé. |
||||||
|
team_name_been_taken = Nom d'équipe déjà utilisé. |
||||||
|
email_been_used = Adresse de courriel déjà utilisée. |
||||||
|
ssh_key_been_used = Nom de clé publique déjà utilisé. |
||||||
|
illegal_username = Votre nom d'usager contient des caractères interdits. |
||||||
|
illegal_repo_name = Le nom du dépôt contient des caractères interdits. |
||||||
|
illegal_org_name = Le nom de l'organisation contient des caractères interdits. |
||||||
|
illegal_team_name = Le nom de l'équipe contient des caractères interdits. |
||||||
|
username_password_incorrect = Nom d'usager ou mot de passe erroné. |
||||||
|
enterred_invalid_repo_name = Nom de dépôt inexistant. |
||||||
|
enterred_invalid_owner_name = Responsable de dépôt inexistant. |
||||||
|
enterred_invalid_password = Mot de passe erroné. |
||||||
|
user_not_exist = Nom d'usager inexistant. |
||||||
|
last_org_owner = Ceci est le dernier responsable du dépôt. Il doit y avoir obligatoirement au moins un usager responsable. |
||||||
|
|
||||||
|
invalid_ssh_key = Désolé, impossible de vérifier votre clé SSH: % |
||||||
|
auth_failed = Erreur d'authentification : %v |
||||||
|
|
||||||
|
still_own_repo = Votre compte est responsable d'au moins un dépôt. Vous devez soit détruire ces dépôts, soit transférer la responsabilité à un autre usager. |
||||||
|
org_still_own_repo = Cette organisation est responsable d'au moins un dépôt. Vous devez soit détruire ces dépôts, soit transférer la responsabilité à un autre usager ou organisation. |
||||||
|
|
||||||
|
still_own_user = Cette authentification est utilisée par un usager. |
||||||
|
|
||||||
|
[settings] |
||||||
|
profile = Profil |
||||||
|
password = Mot de passe |
||||||
|
ssh_keys = Clés SSH |
||||||
|
social = Comptes Internet |
||||||
|
orgs = Organisations |
||||||
|
delete = Supprimer votre compte |
||||||
|
|
||||||
|
public_profile = Profil public |
||||||
|
profile_desc = Votre adresse de courriel est publique et sera utilisée pour les avis produits par le site. |
||||||
|
full_name = Nom complet |
||||||
|
website = Site web |
||||||
|
location = Endroit |
||||||
|
update_profile = Mettre à jour le profil |
||||||
|
update_profile_success = Mise à jour du profil réussie. |
||||||
|
|
||||||
|
change_password = Changer le mot de passe |
||||||
|
old_password = Mot de passe actuel |
||||||
|
new_password = Nouveau mot de passe |
||||||
|
password_incorrect = Mot de passe actuel erroné. |
||||||
|
change_password_success = Modification du mot de passe effectuée. Vous pouvez dorénavant vous connecter avec le nouveau mot de passe. |
||||||
|
|
||||||
|
manage_ssh_keys = Gestion des clés SSH |
||||||
|
add_key = Ajouter une clé |
||||||
|
ssh_desc = Voici la liste de clés SSH associées à votre profil. Retirez les clés que vous ne reconnaissez pas. |
||||||
|
ssh_helper = <strong>Beson d'aide?</strong> Consultez le guide au <a href="https://help.github.com/articles/generating-ssh-keys">generating SSH keys</a> ou vérifiez <a href="https://help.github.com/ssh-issues/">les problèmes SSH fréquents</a>. |
||||||
|
add_new_key = Ajouter une clé SSH |
||||||
|
key_name = Nom de la clé |
||||||
|
key_content = Contenu |
||||||
|
add_key_success = Clé SSH ajoutée! |
||||||
|
delete_key = Détruire |
||||||
|
add_on = Ajoutée le |
||||||
|
last_used = Dernière utilisation le |
||||||
|
no_activity = Pas d'activité récente |
||||||
|
|
||||||
|
manage_social = Gestion des comptes Internets associés |
||||||
|
social_desc = Ceci est une liste de comptes Internet associés. Retirez les comptes que vous ne reconnaissez pas. |
||||||
|
unbind = Désassocier |
||||||
|
unbind_success = Compte Internet déassocié. |
||||||
|
|
||||||
|
delete_account = Detruire votre compte |
||||||
|
delete_prompt = Cette opération détruira votre compte et <strong>ne pourra être annulée</strong>! |
||||||
|
confirm_delete_account = Confirmez la suppression |
||||||
|
|
||||||
|
[repo] |
||||||
|
owner = Responsable |
||||||
|
repo_name = Nom du dépôt |
||||||
|
repo_name_helper = Les bons noms de dépôts sont courts, mémorables et <strong>uniques</strong>. |
||||||
|
visibility = Visibilité |
||||||
|
visiblity_helper = Ce dépôt est <span class="label label-red label-radius">privé</span> |
||||||
|
repo_desc = Description |
||||||
|
repo_lang = Langue |
||||||
|
repo_lang_helper = Choisir un fichier .gitignore |
||||||
|
license = License |
||||||
|
license_helper = Choisir un fichier de licence |
||||||
|
init_readme = Initialiser le dépôt avec un fichier README.md |
||||||
|
create_repo = Créer le dépôt |
||||||
|
default_branch = Branche par défaut |
||||||
|
mirror_interval = Intervale de synchronisation (heures) |
||||||
|
goget_meta = Métadonnées Go-Get |
||||||
|
goget_meta_helper = Ce dépôt sera <span class="label label-blue label-radius">Go-Getable</span> |
||||||
|
|
||||||
|
need_auth = Authorisation requise |
||||||
|
migrate_type = Type de migration |
||||||
|
migrate_type_helper = Ce dépôt sera un <span class="label label-blue label-radius">mirroir</span> |
||||||
|
migrate_repo = Migrer le dépôt |
||||||
|
|
||||||
|
copy_link = Copier |
||||||
|
clone_helper = Besoin d'aide pour cloner? Obtenez de l' <a target="_blank" href="http://git-scm.com/book/fr/Les-bases-de-Git-Démarrer-un-dépôt-Git">aide</a>! |
||||||
|
unwatch = Ne plus suivre |
||||||
|
watch = Suivre |
||||||
|
unstar = Retirer étoile |
||||||
|
star = Étoile |
||||||
|
fork = Fork |
||||||
|
|
||||||
|
quick_guide = Guide rapide |
||||||
|
clone_this_repo = Cloner ce dépôt |
||||||
|
create_new_repo_command = Créer un nouveau dépôt à la ligne de commande |
||||||
|
push_exist_repo = Pousser un dépôt existant depuis la ligne de commande |
||||||
|
|
||||||
|
settings = Réglages |
||||||
|
settings.options = Réglages de base |
||||||
|
settings.collaboration = Collaboration |
||||||
|
settings.hooks = Webhooks |
||||||
|
settings.deploy_keys = Clé de déploiement |
||||||
|
settings.basic_settings = réglages de base |
||||||
|
settings.danger_zone = Danger! |
||||||
|
settings.site = Site officiel |
||||||
|
settings.update_settings = Réglage des mises à jour |
||||||
|
settings.transfer = Transférer la responsabilité |
||||||
|
settings.transfer_desc = Transférer ce dépôt à un autre usager ou organisation si vous en avez la responsabilité. |
||||||
|
settings.delete = Détruire ce dépôt |
||||||
|
settings.delete_desc = La destruction est irrémédiable, impossible d'annuler. Soyez sûr de votre décision. |
||||||
|
settings.update_settings_success = Réglages modifiés |
||||||
|
settings.transfer_owner = Nouveau responsable |
||||||
|
settings.make_transfer = Faire le transfert |
||||||
|
settings.confirm_delete = Confirmer la destruction |
||||||
|
settings.add_collaborator = Ajouter un nouveau collaborateur |
||||||
|
settings.add_collaborator_success = Nouveau collaborateur ajouté. |
||||||
|
settings.remove_collaborator_success = Collaborateur supprimé. |
||||||
|
settings.add_webhook = Ajouter un Webhook |
||||||
|
settings.hooks_desc = Les Webhooks permettent à des services externes d'être avertis de certains changements sur Gogs. Lorque qu'un changement se produit, Gogs envoie une requête POST à chacun des URLs spécifiés. Plus d'info disponible sur notre <a target="_blank" href="http://gogs.io/docs/features/webhook.html">guide Webhooks'</a>. |
||||||
|
settings.remove_hook_success = Webhook supprimé. |
||||||
|
settings.add_webhook_desc = Gogs envoiera un POST à l'URL ci-dessous avec le détail de l'événement souscrit. Vous pouvez aussi spécifier dans quel format vous désirez recevoir les données (JSON,<code>x-www-form-urlencoded</code>, <em>etc</em>). Plus d'info disponible sur notre <a target="_blank" href="http://gogs.io/docs/features/webhook.html">guide Webhooks'</a>. |
||||||
|
settings.payload_url = URL cible |
||||||
|
settings.content_type = Content Type |
||||||
|
settings.secret = Secret |
||||||
|
settings.event_desc = Quels changements déclencheront le webhook? |
||||||
|
settings.event_push_only = Uniquement les <code>push</code>. |
||||||
|
settings.active = Activé |
||||||
|
settings.active_helper = Gogs fournira le détail de l'événement lorsque ce webhook sera déclenché. |
||||||
|
settings.add_hook_success = Nouveau webhook ajouté. |
||||||
|
settings.update_webhook = Mettre à jour le webhook |
||||||
|
settings.update_hook_success = Webhook mis à jour. |
||||||
|
settings.delete_webhook = Détruire le webhook |
||||||
|
settings.recent_deliveries = Livraisons récentes |
||||||
|
settings.hook_type = Type de déclencheur |
||||||
|
settings.add_slack_hook_desc = Ajouter la compatibilité <a href="http://slack.com">Slack</a> à ce dépôt. |
||||||
|
settings.slack_token = Jeton (token) |
||||||
|
settings.slack_domain = Domaine |
||||||
|
settings.slack_channel = Canal |
||||||
|
|
||||||
|
[org] |
||||||
|
org_name_holder = Nom de l'organisation |
||||||
|
org_name_helper = Les bons noms d'organisations sont courts, mémorables et uniques |
||||||
|
org_email_helper = Le courriel de l'organisation recevra toutes les notifications et les confirmations. |
||||||
|
create_org = Créer une organisation |
||||||
|
repo_updated = Changement effectué |
||||||
|
people = Personne |
||||||
|
invite_someone = Inviter quelqu'un |
||||||
|
teams = Équipes |
||||||
|
lower_members = Membres |
||||||
|
lower_repositories = Dépôts |
||||||
|
create_new_team = Créer une nouvelle équipe |
||||||
|
org_desc = Description |
||||||
|
team_name = Nom de l'équipe |
||||||
|
team_desc = Description |
||||||
|
team_name_helper = Le nom qui sera utilisé pour mentionner cette équipe dans les conversations. |
||||||
|
team_desc_helper = Quel est la raison d'être de cette équipe? |
||||||
|
team_permission_desc = Quel niveau de permission attribuer à cette équipe? |
||||||
|
|
||||||
|
settings = Réglages |
||||||
|
settings.options = Paramètres |
||||||
|
settings.full_name = Nom complet |
||||||
|
settings.website = Site web |
||||||
|
settings.location = Endroit |
||||||
|
settings.update_settings = Mettre à jour les paramètres |
||||||
|
settings.update_setting_success = Paramètres mis à jour. |
||||||
|
settings.delete = Détruire l'organisation |
||||||
|
settings.delete_account = Détruire cette organisation |
||||||
|
settings.delete_prompt = La destruction de l'organisation est irrémédiable, impossible d'annuler. Soyez sûr de votre décision. |
||||||
|
settings.confirm_delete_account = Confirmer la destruction |
||||||
|
|
||||||
|
members.public = Publique |
||||||
|
members.public_helper = Rendre privé |
||||||
|
members.private = Privé |
||||||
|
members.private_helper = Rendre publique |
||||||
|
members.owner = Responsable |
||||||
|
members.member = Membre |
||||||
|
members.conceal = Caché |
||||||
|
members.remove = Retirer |
||||||
|
members.leave = Quitter |
||||||
|
members.invite_desc = Commencez à saisir un nom d'usager pour l'inviter à %s: |
||||||
|
members.invite_now = Inviter |
||||||
|
|
||||||
|
teams.join = Rejoindre |
||||||
|
teams.leave = Quitter |
||||||
|
teams.read_access = Droits de lecture |
||||||
|
teams.read_access_helper = Cette équipe pourra voir et cloner ses dépôts. |
||||||
|
teams.write_access = Droits d'écriture |
||||||
|
teams.write_access_helper = Cette équipe pourra voir et cloner ses dépôts ainsi que pousser vers ceux-ci. |
||||||
|
teams.admin_access = Droits de gestion |
||||||
|
teams.admin_access_helper = En plus des droits d'écriture, cette équipe pourra gérer les collaborateurs. |
||||||
|
teams.no_desc = Cette équipe ne posséde pas de description |
||||||
|
teams.settings = Réglages |
||||||
|
teams.owners_permission_desc = Les responsables ont accès à <strong>tous</strong> les dépôts et en possédent les droits de gestion. |
||||||
|
teams.members = Membre de l'équipe |
||||||
|
teams.update_settings = Mettre à jour |
||||||
|
teams.delete_team = Détruire cette équipe |
||||||
|
teams.add_team_member = Ajouter un membre à l'équipe |
||||||
|
teams.delete_team_success = Équipe détruite |
||||||
|
teams.read_permission_desc = La participation à cette équipe confère les droits de lecture. Ses membres peuvent voir et cloner ses dépôts. |
||||||
|
teams.write_permission_desc = La participation à cette équipe confère les droits d'écriture en plus des droits de lecture. Ses membres peuvent pousser vers les dépôts de l'équipe. |
||||||
|
teams.admin_permission_desc = La participation à cette équire confère les droits de gestion. Ses membres peuvent voir, cloner, pousser et gérer les collaborateurs des dépôts. |
||||||
|
teams.repositories = Dépôts de l'équipe |
||||||
|
teams.add_team_repository = Ajouer un dépôt à l'équipe |
||||||
|
teams.remove_repo = Enlever |
||||||
|
|
||||||
|
[admin] |
||||||
|
dashboard = Tableau de bord |
||||||
|
users = Usagers |
||||||
|
organizations = Organisations |
||||||
|
repositories = Dépôts |
||||||
|
authentication = Sources d'authentifications |
||||||
|
config = Configuration |
||||||
|
monitor = Monitoring |
||||||
|
prev = Préc. |
||||||
|
next = Suiv. |
||||||
|
|
||||||
|
dashboard.statistic = Statistiques |
||||||
|
dashboard.operations = Opérations |
||||||
|
dashboard.system_status = État du monitoring système |
||||||
|
dashboard.statistic_info = La BD Gogs compte <b>%d</b> usagers, <b>%d</b> organisations, <b>%d</b> clé SSH, <b>%d</b> dépôts, <b>%d</b> suivis, <b>%d</b> étoiles, <b>%d</b> actions, <b>%d</b> accès, <b>%d</b> tickets, <b>%d</b> commentaires, <b>%d</b> comptes Internet, <b>%d</b> suivis, <b>%d</b> mirroirs, <b>%d</b> publications, <b>%d</b> sources d'authentification, <b>%d</b> webhooks, <b>%d</b> jalons, <b>%d</b> tags, <b>%d</b> tâches hook, <b>%d</b> équipes, <b>%d</b> tâches de mise à jours, <b>%d</b> fichiers joints. |
||||||
|
dashboard.operation_name = Nom de l'opération |
||||||
|
dashboard.operation_switch = Commande |
||||||
|
dashboard.operation_run = Lancer |
||||||
|
dashboard.clean_unbind_oauth = Nettoyer les OAuths orphelins |
||||||
|
dashboard.delete_inactivate_accounts = Détruire les comptes inactifs |
||||||
|
dashboard.server_uptime = Démarré depuis |
||||||
|
dashboard.current_goroutine = Nombre de Goroutines |
||||||
|
dashboard.current_memory_usage = Usage mémoire actuel |
||||||
|
dashboard.total_memory_allocated = Mémoire allouée totale |
||||||
|
dashboard.memory_obtained = Memoire obtenue |
||||||
|
dashboard.pointer_lookup_times = Accès pointeur |
||||||
|
dashboard.memory_allocate_times = Allocation mémoire |
||||||
|
dashboard.memory_free_times = Désallocation mémoire |
||||||
|
dashboard.current_heap_usage = Taille du heap actuelle |
||||||
|
dashboard.heap_memory_obtained = Mémoire heap obtenue |
||||||
|
dashboard.heap_memory_idle = Mémoire heap inactive |
||||||
|
dashboard.heap_memory_in_use = Mémoire heap utilisée |
||||||
|
dashboard.heap_memory_released = Mémoire heap relachée |
||||||
|
dashboard.heap_objects = Objets dans le heap |
||||||
|
dashboard.bootstrap_stack_usage = Bootstrap Stack Usage |
||||||
|
dashboard.stack_memory_obtained = Stack Memory Obtained |
||||||
|
dashboard.mspan_structures_usage = MSpan Structures Usage |
||||||
|
dashboard.mspan_structures_obtained = MSpan Structures Obtained |
||||||
|
dashboard.mcache_structures_usage = MCache Structures Usage |
||||||
|
dashboard.mcache_structures_obtained = MCache Structures Obtained |
||||||
|
dashboard.profiling_bucket_hash_table_obtained = Profiling Bucket Hash Table Obtained |
||||||
|
dashboard.gc_metadata_obtained = GC Metadada Obtained |
||||||
|
dashboard.other_system_allocation_obtained = Other System Allocation Obtained |
||||||
|
dashboard.next_gc_recycle = Next GC Recycle |
||||||
|
dashboard.last_gc_time = Since Last GC Time |
||||||
|
dashboard.total_gc_time = Total GC Pause |
||||||
|
dashboard.total_gc_pause = Total GC Pause |
||||||
|
dashboard.last_gc_pause = Last GC Pause |
||||||
|
dashboard.gc_times = GC Times |
||||||
|
|
||||||
|
users.user_manage_panel = Gestion des usager |
||||||
|
users.new_account = Creér un nouveau compte |
||||||
|
users.name = Nom |
||||||
|
users.activated = Activé |
||||||
|
users.admin = Gestionnaire |
||||||
|
users.repos = Dépôts |
||||||
|
users.created = Créé |
||||||
|
users.edit = Editer |
||||||
|
users.auth_source = Source d'authentification |
||||||
|
users.local = Locale |
||||||
|
users.auth_login_name = Identifiant d'authentification |
||||||
|
users.update_profile_success = Compte crée. |
||||||
|
users.edit_account = Éditer compte |
||||||
|
users.is_activated = Ce compte est activé |
||||||
|
users.is_admin = Ce compte a les droits de gestionnaire |
||||||
|
users.update_profile = Mettre à jour le compte |
||||||
|
users.delete_account = Détruire ce compte |
||||||
|
users.still_own_repo = Ce compte est responsables d'un dépôt. I faut détruire le dépôt ou transférer la responsabilité avant de détruire ce compte. |
||||||
|
|
||||||
|
orgs.org_manage_panel = Gestion des organisations |
||||||
|
orgs.name = Nom |
||||||
|
orgs.teams = Équipes |
||||||
|
orgs.members = Membres |
||||||
|
|
||||||
|
repos.repo_manage_panel = Gestion des dépôts |
||||||
|
repos.owner = Responsable |
||||||
|
repos.name = Nom |
||||||
|
repos.private = Privé |
||||||
|
repos.watches = Suivis |
||||||
|
repos.stars = Étoiles |
||||||
|
repos.issues = Ticket |
||||||
|
|
||||||
|
auths.auth_manage_panel = Gestion des sources d'authentification |
||||||
|
auths.new = Ajouter une nouvelle source d'authentification |
||||||
|
auths.name = Nom |
||||||
|
auths.type = Type |
||||||
|
auths.enabled = Activé |
||||||
|
auths.updated = Mis à jour |
||||||
|
auths.auth_type = Type d'authentification |
||||||
|
auths.auth_name = Nom de l'authentification |
||||||
|
auths.domain = Domaine |
||||||
|
auths.host = Serveur |
||||||
|
auths.port = Port |
||||||
|
auths.base_dn = DN de base |
||||||
|
auths.attributes = Attributs de recherche |
||||||
|
auths.filter = Filtre de recherche |
||||||
|
auths.ms_ad_sa = Microsoft Active Directory |
||||||
|
auths.smtp_auth = Authentification SMTP |
||||||
|
auths.smtphost = Serveur SMTP |
||||||
|
auths.smtpport = Port SMTP |
||||||
|
auths.enable_tls = Chiffrement TLS |
||||||
|
auths.enable_auto_register = Activer auto-abonnement |
||||||
|
auths.tips = Trucs |
||||||
|
auths.edit = Éditer réglages d'authentification |
||||||
|
auths.activated = Source d'authentification activée |
||||||
|
auths.update_success = Réglages mis à jour. |
||||||
|
auths.update = Mettre à jour réglages |
||||||
|
auths.delete = Détruire cette source |
||||||
|
|
||||||
|
config.server_config = Configuration du serveur |
||||||
|
config.app_name = Nom de l'applicaiton |
||||||
|
config.app_ver = Version de l'application |
||||||
|
config.app_url = URL de l'application |
||||||
|
config.domain = Domaine |
||||||
|
config.offline_mode = Mode hors-ligne |
||||||
|
config.disable_router_log = Journal du routeur désactivé |
||||||
|
config.run_user = Éxécuté en tant que |
||||||
|
config.run_mode = Mode de fonctionnement |
||||||
|
config.repo_root_path = Dossier contenant les dépôts |
||||||
|
config.static_file_root_path = Dossier contenant les fichiers statiques |
||||||
|
config.log_file_root_path = Dossier contenant les journaux |
||||||
|
config.script_type = Type de script |
||||||
|
config.reverse_auth_user = Usager d'authentification inversée |
||||||
|
config.db_config = Configuration de la BD |
||||||
|
config.db_type = Type |
||||||
|
config.db_host = Serveur |
||||||
|
config.db_name = Nom |
||||||
|
config.db_user = Usager |
||||||
|
config.db_ssl_mode = Mode SSL |
||||||
|
config.db_ssl_mode_helper = (pour "postgres" seulement) |
||||||
|
config.db_path = Path |
||||||
|
config.db_path_helper = (pour "sqlite3" seulement) |
||||||
|
config.service_config = Configuration du service |
||||||
|
config.register_email_confirm = Confirmation d'abonnement par courriel |
||||||
|
config.disable_register = Auto-inscription désactivée |
||||||
|
config.require_sign_in_view = Connexion requise pour visualiser |
||||||
|
config.mail_notify = Notifications par courriel |
||||||
|
config.enable_cache_avatar = Cache avatar activée |
||||||
|
config.active_code_lives = Jeton d'activation |
||||||
|
config.reset_password_code_lives = Jeton de modification mot-de-passe |
||||||
|
config.webhook_config = Configuration Webhook |
||||||
|
config.task_interval = Intervalle |
||||||
|
config.deliver_timeout = Expiration des appels |
||||||
|
config.mailer_config = Configuration expédition de courriels |
||||||
|
config.mailer_enabled = Activé |
||||||
|
config.mailer_name = Nom |
||||||
|
config.mailer_host = Serveur |
||||||
|
config.mailer_user = Usager |
||||||
|
config.oauth_config = Configuration OAuth |
||||||
|
config.oauth_enabled = Activé |
||||||
|
config.cache_config = Configuration du cache |
||||||
|
config.cache_adapter = Mécanisme de cache |
||||||
|
config.cache_interval = Intervalle |
||||||
|
config.cache_conn = Chaîne de connexion |
||||||
|
config.session_config = Configuration des session |
||||||
|
config.session_provider = Mécanisme |
||||||
|
config.provider_config = Configuration du mécanisme |
||||||
|
config.cookie_name = Nom du fichier témoin |
||||||
|
config.enable_set_cookie = Fichier témoin actvité |
||||||
|
config.gc_interval_time = Intervalle GC |
||||||
|
config.session_life_time = Durée de la session |
||||||
|
config.https_only = HTTPS exigé |
||||||
|
config.cookie_life_time = Expiration du fichier témoin |
||||||
|
config.session_hash_function = Fonction de hashage ID de session |
||||||
|
config.session_hash_key = Clé de hashage ID de session |
||||||
|
config.picture_config = Configuration des avatars |
||||||
|
config.picture_service = Service image |
||||||
|
config.disable_gravatar = Désactivé Gravatar |
||||||
|
config.log_config = Configuration du journal |
||||||
|
config.log_mode = Mode de journal |
||||||
|
|
||||||
|
monitor.cron = Cron Tasks |
||||||
|
monitor.name = Name |
||||||
|
monitor.schedule = Schedule |
||||||
|
monitor.next = Next Time |
||||||
|
monitor.previous = Previous Time |
||||||
|
monitor.execute_times = Execute Times |
||||||
|
monitor.process = Running Processes |
||||||
|
monitor.desc = Description |
||||||
|
monitor.start = Start Time |
||||||
|
monitor.execute_time = Execution Time |
||||||
|
|
||||||
|
[action] |
||||||
|
create_repo = a créé le dépôt <a href="/%s">%s</a> |
||||||
|
commit_repo = a poussé sur <a href="/%s/src/%s">%s</a> à <a href="/%s">%s</a> |
||||||
|
create_issue = a ouvert le ticket <a href="/%s/issues/%s">%s#%s</a> |
||||||
|
comment_issue = a commenté sur le ticket <a href="/%s/issues/%s">%s#%s</a> |
||||||
|
|
||||||
|
[tool] |
||||||
|
ago = auparavant |
||||||
|
from_now = depuis |
||||||
|
now = maintenant |
||||||
|
1s = 1 seconde %s |
||||||
|
1m = 1 minute %s |
||||||
|
1h = 1 heure %s |
||||||
|
1d = 1 jour %s |
||||||
|
1w = 1 semaine %s |
||||||
|
1mon = 1 mos %s |
||||||
|
1y = 1 an %s |
||||||
|
seconds = %d secondes %s |
||||||
|
minutes = %d minutes %s |
||||||
|
hours = %d heures %s |
||||||
|
days = %d jours %s |
||||||
|
weeks = %d semaines %s |
||||||
|
months = %d mois %s |
||||||
|
years = %d années %s |
||||||
|
raw_seconds = secondes |
||||||
|
raw_minutes = minutes |
@ -0,0 +1,89 @@ |
|||||||
|
Docker |
||||||
|
====== |
||||||
|
|
||||||
|
TOOLS ARE WRITTEN FOR TESTING AND TO SEE WHAT IT IS! |
||||||
|
|
||||||
|
For this to work you will need the nifty docker tool [fig]. |
||||||
|
|
||||||
|
The most simple setup will look like this: |
||||||
|
|
||||||
|
```sh |
||||||
|
./assemble_blocks.sh docker_gogs w_db option_db_mysql |
||||||
|
fig up |
||||||
|
|
||||||
|
``` |
||||||
|
|
||||||
|
That's it. You have GoGS running in docker linked to a MySQL docker container. |
||||||
|
|
||||||
|
Now visit http://localhost:3000/ and give details for the admin account an you're up and running. |
||||||
|
|
||||||
|
|
||||||
|
How does it work |
||||||
|
---------------- |
||||||
|
|
||||||
|
`./assemble_blocks.sh` will look in `blocks` for subdirectories. |
||||||
|
In the subdirectories there are three relevant files: `Dockerfile`, `config` and `fig`. |
||||||
|
|
||||||
|
`Dockerfile` will be copied to `docker/` (also means last `Dockerfile` wins). |
||||||
|
|
||||||
|
The `config` file contains lines which will in the gogs docker container end up in `$GOGS_PATH/custom/config/app.ini` and by this gogs will be configured. |
||||||
|
Here you can define things like the MySQL server for your database block. |
||||||
|
|
||||||
|
The `fig` file will just be added to `fig.yml`, which is used by fig to manage your containers. |
||||||
|
This inculdes container linking! |
||||||
|
|
||||||
|
Just have a look at them and it will be clear how to write your own blocks. |
||||||
|
|
||||||
|
Just some things |
||||||
|
|
||||||
|
- all files (`Dockerfile`, `fig` and `config`) are optional |
||||||
|
- the gogs block should always be the first block |
||||||
|
|
||||||
|
Currently the blocks are designed that, the blocks that start with `docker` pull in the base docker image. |
||||||
|
Then one block starting with `w` defines, what containers should be linked to the gogs container. |
||||||
|
For every option in the `w` block you need to add an `option` container. |
||||||
|
|
||||||
|
Example: |
||||||
|
|
||||||
|
```sh |
||||||
|
./assemble_blocks.sh docker_gogs w_db_cache option_db_mysql option_cache_redis |
||||||
|
``` |
||||||
|
|
||||||
|
|
||||||
|
More sophisticated Example |
||||||
|
-------------------------- |
||||||
|
|
||||||
|
Her is a more elaborated example |
||||||
|
|
||||||
|
```sh |
||||||
|
./assemble_blocks.sh docker_gogs w_db_cache_session option_db_postgresql option_cache_redis option_session_mysql |
||||||
|
fig up |
||||||
|
``` |
||||||
|
|
||||||
|
This will set up four containters and link them proberly. One for each of |
||||||
|
|
||||||
|
- gogs |
||||||
|
- database (postgresql) |
||||||
|
- cache (redis) |
||||||
|
- session (mysql) |
||||||
|
|
||||||
|
WARNING: This will not work at the Moment! MySQL session is broken! |
||||||
|
|
||||||
|
|
||||||
|
Remark |
||||||
|
------ |
||||||
|
|
||||||
|
After you execute `assemble_blocks.sh` you should always trigger `fig build` to inculde the the new init script `init_gogs.sh` in the docker image. |
||||||
|
|
||||||
|
If you want to use another GoGS docker file, but keep everything else the same, you can create a block, e.g. `docker_gogs_custom`, with only a `Dockerfile` and call |
||||||
|
|
||||||
|
```sh |
||||||
|
./assemble_blocks.sh docker_gogs_custom w_db option_database_mysql |
||||||
|
``` |
||||||
|
|
||||||
|
This will pull in the `Dockerfile` from `docker_gogs` instead of the one from `docker_gogs`. |
||||||
|
|
||||||
|
`Dockerfile`s for the `master` and `dev` branch are provided as `docker_gogs` and `docker_gogs_dev` |
||||||
|
|
||||||
|
|
||||||
|
[fig]:http://www.fig.sh/ |
@ -0,0 +1,72 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
blocks_dir=blocks |
||||||
|
docker_dir=docker |
||||||
|
template_dir=templates |
||||||
|
|
||||||
|
docker_file=Dockerfile |
||||||
|
|
||||||
|
gogs_config_file=conf.tmp |
||||||
|
gogs_config=config |
||||||
|
gogs_init_file=$docker_dir/init_gogs.sh |
||||||
|
|
||||||
|
fig_file=fig.yml |
||||||
|
fig_config=fig |
||||||
|
|
||||||
|
gogs_init_template=$template_dir/init_gogs.sh.tpl |
||||||
|
|
||||||
|
if [ "$#" == 0 ]; then |
||||||
|
blocks=`ls $blocks_dir` |
||||||
|
if [ -z "$blocks" ]; then |
||||||
|
echo "No Blocks available in $blocks_dir" |
||||||
|
else |
||||||
|
echo "Available Blocks:" |
||||||
|
for block in $blocks; do |
||||||
|
echo " $block" |
||||||
|
done |
||||||
|
fi |
||||||
|
exit 0 |
||||||
|
fi |
||||||
|
|
||||||
|
for file in $gogs_config_file $fig_file; do |
||||||
|
if [ -e $file ]; then |
||||||
|
echo "Deleting $file" |
||||||
|
rm $file |
||||||
|
fi |
||||||
|
done |
||||||
|
|
||||||
|
for dir in $@; do |
||||||
|
current_dir=$blocks_dir/$dir |
||||||
|
if [ ! -d "$current_dir" ]; then |
||||||
|
echo "$current_dir is not a directory" |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
|
||||||
|
if [ -e $current_dir/$docker_file ]; then |
||||||
|
echo "Copying $current_dir/$docker_file to $docker_dir/$docker_file" |
||||||
|
cp $current_dir/$docker_file $docker_dir/$docker_file |
||||||
|
fi |
||||||
|
|
||||||
|
if [ -e $current_dir/$gogs_config ]; then |
||||||
|
echo "Adding $current_dir/$gogs_config to $gogs_config_file" |
||||||
|
cat $current_dir/$gogs_config >> $gogs_config_file |
||||||
|
echo "" >> $gogs_config_file |
||||||
|
fi |
||||||
|
|
||||||
|
if [ -e $current_dir/$fig_config ]; then |
||||||
|
echo "Adding $current_dir/$fig_config to $fig_file" |
||||||
|
cat $current_dir/fig >> $fig_file |
||||||
|
echo "" >> $fig_file |
||||||
|
fi |
||||||
|
done |
||||||
|
|
||||||
|
echo "Creating $gogs_init_file" |
||||||
|
sed "/{{ CONFIG }}/{ |
||||||
|
r $gogs_config_file |
||||||
|
d |
||||||
|
}" $gogs_init_template > $gogs_init_file |
||||||
|
|
||||||
|
if [ -e $gogs_config_file ]; then |
||||||
|
echo "Removing temporary GoGS config" |
||||||
|
rm $gogs_config_file |
||||||
|
fi |
@ -0,0 +1,52 @@ |
|||||||
|
FROM ubuntu:14.04 |
||||||
|
|
||||||
|
# This part is taken from the official docker image -------------------- |
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y \ |
||||||
|
build-essential ca-certificates curl \ |
||||||
|
bzr git mercurial \ |
||||||
|
--no-install-recommends |
||||||
|
|
||||||
|
ENV GOLANG_VERSION 1.3 |
||||||
|
|
||||||
|
RUN curl -sSL http://golang.org/dl/go$GOLANG_VERSION.src.tar.gz \ |
||||||
|
| tar -v -C /usr/src -xz |
||||||
|
WORKDIR /usr/src/go |
||||||
|
|
||||||
|
RUN cd src && ./make.bash --no-clean 2>&1 |
||||||
|
|
||||||
|
ENV PATH /usr/src/go/bin:$PATH |
||||||
|
|
||||||
|
RUN mkdir -p /go/src |
||||||
|
ENV GOPATH /go |
||||||
|
ENV PATH /go/bin:$PATH |
||||||
|
WORKDIR /go |
||||||
|
|
||||||
|
# ---------------------------------------------------------------------- |
||||||
|
|
||||||
|
|
||||||
|
RUN useradd -m git |
||||||
|
|
||||||
|
ENV GOGS_PATH $GOPATH/src/github.com/gogits/gogs |
||||||
|
ENV GOGS_CUSTOM_CONF_PATH $GOGS_PATH/custom/conf |
||||||
|
ENV GOGS_CUSTOM_CONF $GOGS_CUSTOM_CONF_PATH/app.ini |
||||||
|
|
||||||
|
RUN go get -u -d github.com/gogits/gogs |
||||||
|
# WORKDIR $GOGS_PATH |
||||||
|
WORKDIR /go/src/github.com/gogits/gogs |
||||||
|
RUN go build github.com/gogits/gogs |
||||||
|
RUN chown -R git $GOGS_PATH |
||||||
|
|
||||||
|
ADD init_gogs.sh /tmp/ |
||||||
|
RUN chown git /tmp/init_gogs.sh |
||||||
|
RUN chmod +x /tmp/init_gogs.sh |
||||||
|
|
||||||
|
USER git |
||||||
|
ENV HOME /home/git |
||||||
|
ENV USER git |
||||||
|
ENV PATH $GOGS_PATH:$PATH |
||||||
|
|
||||||
|
RUN git config --global user.name "GoGS" |
||||||
|
|
||||||
|
ENTRYPOINT ["/tmp/init_gogs.sh"] |
||||||
|
CMD ["gogs", "web"] |
@ -0,0 +1,53 @@ |
|||||||
|
FROM ubuntu:14.04 |
||||||
|
|
||||||
|
# This part is derived from the official docker image ------------------ |
||||||
|
|
||||||
|
RUN DEBIAN_FRONTEND=noninteractive apt-get update && \ |
||||||
|
apt-get install -qy \ |
||||||
|
build-essential ca-certificates curl \ |
||||||
|
bzr git mercurial \ |
||||||
|
--no-install-recommends |
||||||
|
|
||||||
|
ENV GOLANG_VERSION 1.3 |
||||||
|
|
||||||
|
RUN curl -sSL http://golang.org/dl/go$GOLANG_VERSION.src.tar.gz \ |
||||||
|
| tar -v -C /usr/src -xz |
||||||
|
WORKDIR /usr/src/go |
||||||
|
|
||||||
|
RUN cd src && ./make.bash --no-clean 2>&1 |
||||||
|
|
||||||
|
ENV PATH /usr/src/go/bin:$PATH |
||||||
|
|
||||||
|
RUN mkdir -p /go/src |
||||||
|
ENV GOPATH /go |
||||||
|
ENV PATH /go/bin:$PATH |
||||||
|
WORKDIR /go |
||||||
|
|
||||||
|
# ---------------------------------------------------------------------- |
||||||
|
|
||||||
|
|
||||||
|
RUN useradd -m git |
||||||
|
|
||||||
|
ENV GOGS_PATH $GOPATH/src/github.com/gogits/gogs |
||||||
|
ENV GOGS_CUSTOM_CONF_PATH $GOGS_PATH/custom/conf |
||||||
|
ENV GOGS_CUSTOM_CONF $GOGS_CUSTOM_CONF_PATH/app.ini |
||||||
|
|
||||||
|
RUN git clone -b dev https://github.com/gogits/gogs.git $GOGS_PATH |
||||||
|
# WORKDIR $GOGS_PATH |
||||||
|
WORKDIR /go/src/github.com/gogits/gogs |
||||||
|
RUN go get -d && go build |
||||||
|
RUN chown -R git $GOGS_PATH |
||||||
|
|
||||||
|
ADD init_gogs.sh /tmp/ |
||||||
|
RUN chown git /tmp/init_gogs.sh |
||||||
|
RUN chmod +x /tmp/init_gogs.sh |
||||||
|
|
||||||
|
USER git |
||||||
|
ENV HOME /home/git |
||||||
|
ENV USER git |
||||||
|
ENV PATH $GOGS_PATH:$PATH |
||||||
|
|
||||||
|
RUN git config --global user.name "GoGS" |
||||||
|
|
||||||
|
ENTRYPOINT ["/tmp/init_gogs.sh"] |
||||||
|
CMD ["gogs", "web"] |
@ -0,0 +1,3 @@ |
|||||||
|
[cache] |
||||||
|
DB_TYPE = memcache |
||||||
|
HOST = HOST = ${CACHE_1_PORT_11211_TCP_ADDR}:${CACHE_1_PORT_11211_TCP_PORT} |
@ -0,0 +1,2 @@ |
|||||||
|
cache: |
||||||
|
image: sylvainlasnier/memcached:latest |
@ -0,0 +1,3 @@ |
|||||||
|
[cache] |
||||||
|
DB_TYPE = redis |
||||||
|
HOST = ${CACHE_1_PORT_6379_TCP_ADDR}:${CACHE_1_PORT_6379_TCP_PORT} |
@ -0,0 +1,6 @@ |
|||||||
|
[database] |
||||||
|
DB_TYPE = mysql |
||||||
|
HOST = ${DB_1_PORT_3306_TCP_ADDR}:${DB_1_PORT_3306_TCP_PORT} |
||||||
|
NAME = ${DB_1_ENV_MYSQL_DATABASE} |
||||||
|
USER = ${DB_1_ENV_MYSQL_USER} |
||||||
|
PASSWD = ${DB_1_ENV_MYSQL_PASSWORD} |
@ -0,0 +1,7 @@ |
|||||||
|
db: |
||||||
|
image: mysql:latest |
||||||
|
environment: |
||||||
|
MYSQL_ROOT_PASSWORD: rootpass |
||||||
|
MYSQL_DATABASE: gogs |
||||||
|
MYSQL_USER: gogs |
||||||
|
MYSQL_PASSWORD: password |
@ -0,0 +1,6 @@ |
|||||||
|
[database] |
||||||
|
DB_TYPE = postgres |
||||||
|
HOST = ${DB_1_PORT_5432_TCP_ADDR}:${DB_1_PORT_5432_TCP_PORT} |
||||||
|
NAME = ${DB_1_ENV_POSTGRESQL_DB} |
||||||
|
USER = ${DB_1_ENV_POSTGRESQL_USER} |
||||||
|
PASSWD = ${DB_1_ENV_POSTGRESQL_PASS} |
@ -0,0 +1,6 @@ |
|||||||
|
db: |
||||||
|
image: wyaeld/postgres:9.3 |
||||||
|
environment: |
||||||
|
POSTGRESQL_DB: gogs |
||||||
|
POSTGRESQL_USER: gogs |
||||||
|
POSTGRESQL_PASS: password |
@ -0,0 +1,3 @@ |
|||||||
|
[session] |
||||||
|
PROVIDER = mysql |
||||||
|
PROVIDER_CONFIG = ${SESSION_1_ENV_MYSQL_USER}:${SESSION_1_ENV_MYSQL_PASSWORD}@SESSION_1_PORT_3306_TCP_PROTO(${SESSION_1_PORT_3306_TCP_ADDR}:${SESSION_1_PORT_3306_TCP_PORT})/${SESSION_1_ENV_MYSQL_DATABASE} |
@ -0,0 +1,7 @@ |
|||||||
|
session: |
||||||
|
image: mysql:latest |
||||||
|
environment: |
||||||
|
MYSQL_ROOT_PASSWORD: rootpass |
||||||
|
MYSQL_DATABASE: gogs_session |
||||||
|
MYSQL_USER: gogs |
||||||
|
MYSQL_PASSWORD: password |
@ -0,0 +1,6 @@ |
|||||||
|
gogs: |
||||||
|
build: docker |
||||||
|
links: |
||||||
|
- cache |
||||||
|
ports: |
||||||
|
- "3000:3000" |
@ -0,0 +1,7 @@ |
|||||||
|
gogs: |
||||||
|
build: docker |
||||||
|
links: |
||||||
|
- cache |
||||||
|
- session |
||||||
|
ports: |
||||||
|
- "3000:3000" |
@ -0,0 +1,6 @@ |
|||||||
|
gogs: |
||||||
|
build: docker |
||||||
|
links: |
||||||
|
- db |
||||||
|
ports: |
||||||
|
- "3000:3000" |
@ -0,0 +1,7 @@ |
|||||||
|
gogs: |
||||||
|
build: docker |
||||||
|
links: |
||||||
|
- db |
||||||
|
- cache |
||||||
|
ports: |
||||||
|
- "3000:3000" |
@ -0,0 +1,8 @@ |
|||||||
|
gogs: |
||||||
|
build: docker |
||||||
|
links: |
||||||
|
- db |
||||||
|
- cache |
||||||
|
- session |
||||||
|
ports: |
||||||
|
- "3000:3000" |
@ -0,0 +1,7 @@ |
|||||||
|
gogs: |
||||||
|
build: docker |
||||||
|
links: |
||||||
|
- db |
||||||
|
- session |
||||||
|
ports: |
||||||
|
- "3000:3000" |
@ -0,0 +1,4 @@ |
|||||||
|
gogs: |
||||||
|
build: docker |
||||||
|
ports: |
||||||
|
- "3000:3000" |
@ -0,0 +1,6 @@ |
|||||||
|
gogs: |
||||||
|
build: docker |
||||||
|
links: |
||||||
|
- session |
||||||
|
ports: |
||||||
|
- "3000:3000" |
@ -0,0 +1,12 @@ |
|||||||
|
#!/bin/sh |
||||||
|
|
||||||
|
if [ ! -d "$DIRECTORY" ]; then |
||||||
|
mkdir -p $GOGS_CUSTOM_CONF_PATH |
||||||
|
|
||||||
|
echo " |
||||||
|
{{ CONFIG }} |
||||||
|
" >> $GOGS_CUSTOM_CONF |
||||||
|
|
||||||
|
fi |
||||||
|
|
||||||
|
exec "$@" |
@ -1,40 +0,0 @@ |
|||||||
### Install Gogs With Docker |
|
||||||
|
|
||||||
Deploying gogs in [Docker](http://www.docker.io/) is just as easy as eating a pie, what you do is just open the `dockerfiles/build.sh` file, replace the configs: |
|
||||||
|
|
||||||
``` |
|
||||||
DB_TYPE="YOUR_DB_TYPE" # type of database, support 'mysql' and 'postgres' |
|
||||||
MEM_TYPE="YOUR_MEM_TYPE" # type of memory database, support 'redis' and 'memcache' |
|
||||||
DB_PASSWORD="YOUR_DB_PASSWORD" # The database password. |
|
||||||
DB_RUN_NAME="YOUR_DB_RUN_NAME" # The --name option value when run the database image. |
|
||||||
MEM_RUN_NAME="YOUR_MEM_RUN_NAME" # The --name option value when run the mem database image. |
|
||||||
HOST_PORT="YOUR_HOST_PORT" # The port on host, which will be redirected to the port 3000 inside gogs container. |
|
||||||
``` |
|
||||||
|
|
||||||
And run: |
|
||||||
``` |
|
||||||
cd dockerfiles |
|
||||||
./build.sh |
|
||||||
``` |
|
||||||
|
|
||||||
The build might take some time, just be patient. After it finishes, you will receive the message: |
|
||||||
|
|
||||||
``` |
|
||||||
Now we have the MySQL image(running) and gogs image, use the follow command to start gogs service( the content might be different, according to your own configs): |
|
||||||
docker run -i -t --link YOUR_DB_RUN_NAME:db --link YOUR_MEM_RUN_NAME:mem -p YOUR_HOST_PORT:3000 gogits/gogs |
|
||||||
``` |
|
||||||
|
|
||||||
Just follow the message, run: |
|
||||||
|
|
||||||
``` |
|
||||||
docker run -i -t --link YOUR_DB_RUN_NAME:db --link YOUR_MEM_RUN_NAME:mem -p YOUR_HOST_PORT:3000 gogits/gogs |
|
||||||
``` |
|
||||||
|
|
||||||
Now we have gogs running! Open the browser and navigate to: |
|
||||||
|
|
||||||
``` |
|
||||||
http://YOUR_HOST_IP:YOUR_HOST_PORT |
|
||||||
``` |
|
||||||
|
|
||||||
Let's 'gogs'! |
|
||||||
Ouya~ |
|
@ -0,0 +1,125 @@ |
|||||||
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package models |
||||||
|
|
||||||
|
import ( |
||||||
|
"encoding/json" |
||||||
|
"errors" |
||||||
|
"fmt" |
||||||
|
"strings" |
||||||
|
) |
||||||
|
|
||||||
|
const ( |
||||||
|
SLACK_COLOR string = "#dd4b39" |
||||||
|
) |
||||||
|
|
||||||
|
type Slack struct { |
||||||
|
Domain string `json:"domain"` |
||||||
|
Token string `json:"token"` |
||||||
|
Channel string `json:"channel"` |
||||||
|
} |
||||||
|
|
||||||
|
type SlackPayload struct { |
||||||
|
Channel string `json:"channel"` |
||||||
|
Text string `json:"text"` |
||||||
|
Username string `json:"username"` |
||||||
|
IconUrl string `json:"icon_url"` |
||||||
|
UnfurlLinks int `json:"unfurl_links"` |
||||||
|
LinkNames int `json:"link_names"` |
||||||
|
Attachments []SlackAttachment `json:"attachments"` |
||||||
|
} |
||||||
|
|
||||||
|
type SlackAttachment struct { |
||||||
|
Color string `json:"color"` |
||||||
|
Text string `json:"text"` |
||||||
|
} |
||||||
|
|
||||||
|
func GetSlackURL(domain string, token string) string { |
||||||
|
return fmt.Sprintf( |
||||||
|
"https://%s.slack.com/services/hooks/incoming-webhook?token=%s", |
||||||
|
domain, |
||||||
|
token, |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
func (p SlackPayload) GetJSONPayload() ([]byte, error) { |
||||||
|
data, err := json.Marshal(p) |
||||||
|
if err != nil { |
||||||
|
return []byte{}, err |
||||||
|
} |
||||||
|
return data, nil |
||||||
|
} |
||||||
|
|
||||||
|
func GetSlackPayload(p *Payload, meta string) (*SlackPayload, error) { |
||||||
|
slack := &Slack{} |
||||||
|
slackPayload := &SlackPayload{} |
||||||
|
if err := json.Unmarshal([]byte(meta), &slack); err != nil { |
||||||
|
return slackPayload, errors.New("GetSlackPayload meta json:" + err.Error()) |
||||||
|
} |
||||||
|
|
||||||
|
// TODO: handle different payload types: push, new branch, delete branch etc.
|
||||||
|
// when they are added to gogs. Only handles push now
|
||||||
|
return getSlackPushPayload(p, slack) |
||||||
|
} |
||||||
|
|
||||||
|
func getSlackPushPayload(p *Payload, slack *Slack) (*SlackPayload, error) { |
||||||
|
// n new commits
|
||||||
|
refSplit := strings.Split(p.Ref, "/") |
||||||
|
branchName := refSplit[len(refSplit)-1] |
||||||
|
var commitString string |
||||||
|
|
||||||
|
if len(p.Commits) == 1 { |
||||||
|
commitString = "1 new commit" |
||||||
|
if p.CompareUrl != "" { |
||||||
|
commitString = SlackLinkFormatter(p.CompareUrl, commitString) |
||||||
|
} |
||||||
|
} else { |
||||||
|
commitString = fmt.Sprintf("%d new commits", len(p.Commits)) |
||||||
|
if p.CompareUrl != "" { |
||||||
|
commitString = SlackLinkFormatter(p.CompareUrl, commitString) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
repoLink := SlackLinkFormatter(p.Repo.Url, p.Repo.Name) |
||||||
|
branchLink := SlackLinkFormatter(p.Repo.Url+"/src/"+branchName, branchName) |
||||||
|
text := fmt.Sprintf("[%s:%s] %s pushed by %s", repoLink, branchLink, commitString, p.Pusher.Name) |
||||||
|
var attachmentText string |
||||||
|
|
||||||
|
// for each commit, generate attachment text
|
||||||
|
for i, commit := range p.Commits { |
||||||
|
attachmentText += fmt.Sprintf("%s: %s - %s", SlackLinkFormatter(commit.Url, commit.Id[:7]), SlackTextFormatter(commit.Message), SlackTextFormatter(commit.Author.Name)) |
||||||
|
// add linebreak to each commit but the last
|
||||||
|
if i < len(p.Commits)-1 { |
||||||
|
attachmentText += "\n" |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
slackAttachments := []SlackAttachment{{Color: SLACK_COLOR, Text: attachmentText}} |
||||||
|
|
||||||
|
return &SlackPayload{ |
||||||
|
Channel: slack.Channel, |
||||||
|
Text: text, |
||||||
|
Username: "gogs", |
||||||
|
IconUrl: "https://raw.githubusercontent.com/gogits/gogs/master/public/img/favicon.png", |
||||||
|
UnfurlLinks: 0, |
||||||
|
LinkNames: 0, |
||||||
|
Attachments: slackAttachments, |
||||||
|
}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// see: https://api.slack.com/docs/formatting
|
||||||
|
func SlackTextFormatter(s string) string { |
||||||
|
// take only first line of commit
|
||||||
|
first := strings.Split(s, "\n")[0] |
||||||
|
// replace & < >
|
||||||
|
first = strings.Replace(first, "&", "&", -1) |
||||||
|
first = strings.Replace(first, "<", "<", -1) |
||||||
|
first = strings.Replace(first, ">", ">", -1) |
||||||
|
return first |
||||||
|
} |
||||||
|
|
||||||
|
func SlackLinkFormatter(url string, text string) string { |
||||||
|
return fmt.Sprintf("<%s|%s>", url, SlackTextFormatter(text)) |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
Copyright (c) 2012 The Go Authors. All rights reserved. |
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without |
||||||
|
modification, are permitted provided that the following conditions are |
||||||
|
met: |
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer. |
||||||
|
* Redistributions in binary form must reproduce the above |
||||||
|
copyright notice, this list of conditions and the following disclaimer |
||||||
|
in the documentation and/or other materials provided with the |
||||||
|
distribution. |
||||||
|
* Neither the name of Google Inc. nor the names of its |
||||||
|
contributors may be used to endorse or promote products derived from |
||||||
|
this software without specific prior written permission. |
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
@ -0,0 +1,11 @@ |
|||||||
|
# Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
# Use of this source code is governed by a BSD-style
|
||||||
|
# license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
include $(GOROOT)/src/Make.inc |
||||||
|
|
||||||
|
TARG=github.com/mmitton/asn1-ber
|
||||||
|
GOFILES=\
|
||||||
|
ber.go\
|
||||||
|
|
||||||
|
include $(GOROOT)/src/Make.pkg |
@ -0,0 +1,14 @@ |
|||||||
|
ASN1 BER Encoding / Decoding Library for the GO programming language. |
||||||
|
|
||||||
|
Required Librarys: |
||||||
|
None |
||||||
|
|
||||||
|
Working: |
||||||
|
Very basic encoding / decoding needed for LDAP protocol |
||||||
|
|
||||||
|
Tests Implemented: |
||||||
|
None |
||||||
|
|
||||||
|
TODO: |
||||||
|
Fix all encoding / decoding to conform to ASN1 BER spec |
||||||
|
Implement Tests / Benchmarks |
@ -0,0 +1,492 @@ |
|||||||
|
package ber |
||||||
|
|
||||||
|
import ( |
||||||
|
"bytes" |
||||||
|
"fmt" |
||||||
|
"io" |
||||||
|
"reflect" |
||||||
|
) |
||||||
|
|
||||||
|
type Packet struct { |
||||||
|
ClassType uint8 |
||||||
|
TagType uint8 |
||||||
|
Tag uint8 |
||||||
|
Value interface{} |
||||||
|
ByteValue []byte |
||||||
|
Data *bytes.Buffer |
||||||
|
Children []*Packet |
||||||
|
Description string |
||||||
|
} |
||||||
|
|
||||||
|
const ( |
||||||
|
TagEOC = 0x00 |
||||||
|
TagBoolean = 0x01 |
||||||
|
TagInteger = 0x02 |
||||||
|
TagBitString = 0x03 |
||||||
|
TagOctetString = 0x04 |
||||||
|
TagNULL = 0x05 |
||||||
|
TagObjectIdentifier = 0x06 |
||||||
|
TagObjectDescriptor = 0x07 |
||||||
|
TagExternal = 0x08 |
||||||
|
TagRealFloat = 0x09 |
||||||
|
TagEnumerated = 0x0a |
||||||
|
TagEmbeddedPDV = 0x0b |
||||||
|
TagUTF8String = 0x0c |
||||||
|
TagRelativeOID = 0x0d |
||||||
|
TagSequence = 0x10 |
||||||
|
TagSet = 0x11 |
||||||
|
TagNumericString = 0x12 |
||||||
|
TagPrintableString = 0x13 |
||||||
|
TagT61String = 0x14 |
||||||
|
TagVideotexString = 0x15 |
||||||
|
TagIA5String = 0x16 |
||||||
|
TagUTCTime = 0x17 |
||||||
|
TagGeneralizedTime = 0x18 |
||||||
|
TagGraphicString = 0x19 |
||||||
|
TagVisibleString = 0x1a |
||||||
|
TagGeneralString = 0x1b |
||||||
|
TagUniversalString = 0x1c |
||||||
|
TagCharacterString = 0x1d |
||||||
|
TagBMPString = 0x1e |
||||||
|
TagBitmask = 0x1f // xxx11111b
|
||||||
|
) |
||||||
|
|
||||||
|
var TagMap = map[uint8]string{ |
||||||
|
TagEOC: "EOC (End-of-Content)", |
||||||
|
TagBoolean: "Boolean", |
||||||
|
TagInteger: "Integer", |
||||||
|
TagBitString: "Bit String", |
||||||
|
TagOctetString: "Octet String", |
||||||
|
TagNULL: "NULL", |
||||||
|
TagObjectIdentifier: "Object Identifier", |
||||||
|
TagObjectDescriptor: "Object Descriptor", |
||||||
|
TagExternal: "External", |
||||||
|
TagRealFloat: "Real (float)", |
||||||
|
TagEnumerated: "Enumerated", |
||||||
|
TagEmbeddedPDV: "Embedded PDV", |
||||||
|
TagUTF8String: "UTF8 String", |
||||||
|
TagRelativeOID: "Relative-OID", |
||||||
|
TagSequence: "Sequence and Sequence of", |
||||||
|
TagSet: "Set and Set OF", |
||||||
|
TagNumericString: "Numeric String", |
||||||
|
TagPrintableString: "Printable String", |
||||||
|
TagT61String: "T61 String", |
||||||
|
TagVideotexString: "Videotex String", |
||||||
|
TagIA5String: "IA5 String", |
||||||
|
TagUTCTime: "UTC Time", |
||||||
|
TagGeneralizedTime: "Generalized Time", |
||||||
|
TagGraphicString: "Graphic String", |
||||||
|
TagVisibleString: "Visible String", |
||||||
|
TagGeneralString: "General String", |
||||||
|
TagUniversalString: "Universal String", |
||||||
|
TagCharacterString: "Character String", |
||||||
|
TagBMPString: "BMP String", |
||||||
|
} |
||||||
|
|
||||||
|
const ( |
||||||
|
ClassUniversal = 0 // 00xxxxxxb
|
||||||
|
ClassApplication = 64 // 01xxxxxxb
|
||||||
|
ClassContext = 128 // 10xxxxxxb
|
||||||
|
ClassPrivate = 192 // 11xxxxxxb
|
||||||
|
ClassBitmask = 192 // 11xxxxxxb
|
||||||
|
) |
||||||
|
|
||||||
|
var ClassMap = map[uint8]string{ |
||||||
|
ClassUniversal: "Universal", |
||||||
|
ClassApplication: "Application", |
||||||
|
ClassContext: "Context", |
||||||
|
ClassPrivate: "Private", |
||||||
|
} |
||||||
|
|
||||||
|
const ( |
||||||
|
TypePrimitive = 0 // xx0xxxxxb
|
||||||
|
TypeConstructed = 32 // xx1xxxxxb
|
||||||
|
TypeBitmask = 32 // xx1xxxxxb
|
||||||
|
) |
||||||
|
|
||||||
|
var TypeMap = map[uint8]string{ |
||||||
|
TypePrimitive: "Primative", |
||||||
|
TypeConstructed: "Constructed", |
||||||
|
} |
||||||
|
|
||||||
|
var Debug bool = false |
||||||
|
|
||||||
|
func PrintBytes(buf []byte, indent string) { |
||||||
|
data_lines := make([]string, (len(buf)/30)+1) |
||||||
|
num_lines := make([]string, (len(buf)/30)+1) |
||||||
|
|
||||||
|
for i, b := range buf { |
||||||
|
data_lines[i/30] += fmt.Sprintf("%02x ", b) |
||||||
|
num_lines[i/30] += fmt.Sprintf("%02d ", (i+1)%100) |
||||||
|
} |
||||||
|
|
||||||
|
for i := 0; i < len(data_lines); i++ { |
||||||
|
fmt.Print(indent + data_lines[i] + "\n") |
||||||
|
fmt.Print(indent + num_lines[i] + "\n\n") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func PrintPacket(p *Packet) { |
||||||
|
printPacket(p, 0, false) |
||||||
|
} |
||||||
|
|
||||||
|
func printPacket(p *Packet, indent int, printBytes bool) { |
||||||
|
indent_str := "" |
||||||
|
|
||||||
|
for len(indent_str) != indent { |
||||||
|
indent_str += " " |
||||||
|
} |
||||||
|
|
||||||
|
class_str := ClassMap[p.ClassType] |
||||||
|
|
||||||
|
tagtype_str := TypeMap[p.TagType] |
||||||
|
|
||||||
|
tag_str := fmt.Sprintf("0x%02X", p.Tag) |
||||||
|
|
||||||
|
if p.ClassType == ClassUniversal { |
||||||
|
tag_str = TagMap[p.Tag] |
||||||
|
} |
||||||
|
|
||||||
|
value := fmt.Sprint(p.Value) |
||||||
|
description := "" |
||||||
|
|
||||||
|
if p.Description != "" { |
||||||
|
description = p.Description + ": " |
||||||
|
} |
||||||
|
|
||||||
|
fmt.Printf("%s%s(%s, %s, %s) Len=%d %q\n", indent_str, description, class_str, tagtype_str, tag_str, p.Data.Len(), value) |
||||||
|
|
||||||
|
if printBytes { |
||||||
|
PrintBytes(p.Bytes(), indent_str) |
||||||
|
} |
||||||
|
|
||||||
|
for _, child := range p.Children { |
||||||
|
printPacket(child, indent+1, printBytes) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func resizeBuffer(in []byte, new_size uint64) (out []byte) { |
||||||
|
out = make([]byte, new_size) |
||||||
|
|
||||||
|
copy(out, in) |
||||||
|
|
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
func readBytes(reader io.Reader, buf []byte) error { |
||||||
|
idx := 0 |
||||||
|
buflen := len(buf) |
||||||
|
|
||||||
|
for idx < buflen { |
||||||
|
n, err := reader.Read(buf[idx:]) |
||||||
|
if err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
idx += n |
||||||
|
} |
||||||
|
|
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
func ReadPacket(reader io.Reader) (*Packet, error) { |
||||||
|
buf := make([]byte, 2) |
||||||
|
|
||||||
|
err := readBytes(reader, buf) |
||||||
|
|
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
idx := uint64(2) |
||||||
|
datalen := uint64(buf[1]) |
||||||
|
|
||||||
|
if Debug { |
||||||
|
fmt.Printf("Read: datalen = %d len(buf) = %d ", datalen, len(buf)) |
||||||
|
|
||||||
|
for _, b := range buf { |
||||||
|
fmt.Printf("%02X ", b) |
||||||
|
} |
||||||
|
|
||||||
|
fmt.Printf("\n") |
||||||
|
} |
||||||
|
|
||||||
|
if datalen&128 != 0 { |
||||||
|
a := datalen - 128 |
||||||
|
|
||||||
|
idx += a |
||||||
|
buf = resizeBuffer(buf, 2+a) |
||||||
|
|
||||||
|
err := readBytes(reader, buf[2:]) |
||||||
|
|
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
datalen = DecodeInteger(buf[2 : 2+a]) |
||||||
|
|
||||||
|
if Debug { |
||||||
|
fmt.Printf("Read: a = %d idx = %d datalen = %d len(buf) = %d", a, idx, datalen, len(buf)) |
||||||
|
|
||||||
|
for _, b := range buf { |
||||||
|
fmt.Printf("%02X ", b) |
||||||
|
} |
||||||
|
|
||||||
|
fmt.Printf("\n") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
buf = resizeBuffer(buf, idx+datalen) |
||||||
|
err = readBytes(reader, buf[idx:]) |
||||||
|
|
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
if Debug { |
||||||
|
fmt.Printf("Read: len( buf ) = %d idx=%d datalen=%d idx+datalen=%d\n", len(buf), idx, datalen, idx+datalen) |
||||||
|
|
||||||
|
for _, b := range buf { |
||||||
|
fmt.Printf("%02X ", b) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
p := DecodePacket(buf) |
||||||
|
|
||||||
|
return p, nil |
||||||
|
} |
||||||
|
|
||||||
|
func DecodeString(data []byte) (ret string) { |
||||||
|
for _, c := range data { |
||||||
|
ret += fmt.Sprintf("%c", c) |
||||||
|
} |
||||||
|
|
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
func DecodeInteger(data []byte) (ret uint64) { |
||||||
|
for _, i := range data { |
||||||
|
ret = ret * 256 |
||||||
|
ret = ret + uint64(i) |
||||||
|
} |
||||||
|
|
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
func EncodeInteger(val uint64) []byte { |
||||||
|
var out bytes.Buffer |
||||||
|
|
||||||
|
found := false |
||||||
|
|
||||||
|
shift := uint(56) |
||||||
|
|
||||||
|
mask := uint64(0xFF00000000000000) |
||||||
|
|
||||||
|
for mask > 0 { |
||||||
|
if !found && (val&mask != 0) { |
||||||
|
found = true |
||||||
|
} |
||||||
|
|
||||||
|
if found || (shift == 0) { |
||||||
|
out.Write([]byte{byte((val & mask) >> shift)}) |
||||||
|
} |
||||||
|
|
||||||
|
shift -= 8 |
||||||
|
mask = mask >> 8 |
||||||
|
} |
||||||
|
|
||||||
|
return out.Bytes() |
||||||
|
} |
||||||
|
|
||||||
|
func DecodePacket(data []byte) *Packet { |
||||||
|
p, _ := decodePacket(data) |
||||||
|
|
||||||
|
return p |
||||||
|
} |
||||||
|
|
||||||
|
func decodePacket(data []byte) (*Packet, []byte) { |
||||||
|
if Debug { |
||||||
|
fmt.Printf("decodePacket: enter %d\n", len(data)) |
||||||
|
} |
||||||
|
|
||||||
|
p := new(Packet) |
||||||
|
|
||||||
|
p.ClassType = data[0] & ClassBitmask |
||||||
|
p.TagType = data[0] & TypeBitmask |
||||||
|
p.Tag = data[0] & TagBitmask |
||||||
|
|
||||||
|
datalen := DecodeInteger(data[1:2]) |
||||||
|
datapos := uint64(2) |
||||||
|
|
||||||
|
if datalen&128 != 0 { |
||||||
|
datalen -= 128 |
||||||
|
datapos += datalen |
||||||
|
datalen = DecodeInteger(data[2 : 2+datalen]) |
||||||
|
} |
||||||
|
|
||||||
|
p.Data = new(bytes.Buffer) |
||||||
|
|
||||||
|
p.Children = make([]*Packet, 0, 2) |
||||||
|
|
||||||
|
p.Value = nil |
||||||
|
|
||||||
|
value_data := data[datapos : datapos+datalen] |
||||||
|
|
||||||
|
if p.TagType == TypeConstructed { |
||||||
|
for len(value_data) != 0 { |
||||||
|
var child *Packet |
||||||
|
|
||||||
|
child, value_data = decodePacket(value_data) |
||||||
|
p.AppendChild(child) |
||||||
|
} |
||||||
|
} else if p.ClassType == ClassUniversal { |
||||||
|
p.Data.Write(data[datapos : datapos+datalen]) |
||||||
|
p.ByteValue = value_data |
||||||
|
|
||||||
|
switch p.Tag { |
||||||
|
case TagEOC: |
||||||
|
case TagBoolean: |
||||||
|
val := DecodeInteger(value_data) |
||||||
|
|
||||||
|
p.Value = val != 0 |
||||||
|
case TagInteger: |
||||||
|
p.Value = DecodeInteger(value_data) |
||||||
|
case TagBitString: |
||||||
|
case TagOctetString: |
||||||
|
p.Value = DecodeString(value_data) |
||||||
|
case TagNULL: |
||||||
|
case TagObjectIdentifier: |
||||||
|
case TagObjectDescriptor: |
||||||
|
case TagExternal: |
||||||
|
case TagRealFloat: |
||||||
|
case TagEnumerated: |
||||||
|
p.Value = DecodeInteger(value_data) |
||||||
|
case TagEmbeddedPDV: |
||||||
|
case TagUTF8String: |
||||||
|
case TagRelativeOID: |
||||||
|
case TagSequence: |
||||||
|
case TagSet: |
||||||
|
case TagNumericString: |
||||||
|
case TagPrintableString: |
||||||
|
p.Value = DecodeString(value_data) |
||||||
|
case TagT61String: |
||||||
|
case TagVideotexString: |
||||||
|
case TagIA5String: |
||||||
|
case TagUTCTime: |
||||||
|
case TagGeneralizedTime: |
||||||
|
case TagGraphicString: |
||||||
|
case TagVisibleString: |
||||||
|
case TagGeneralString: |
||||||
|
case TagUniversalString: |
||||||
|
case TagCharacterString: |
||||||
|
case TagBMPString: |
||||||
|
} |
||||||
|
} else { |
||||||
|
p.Data.Write(data[datapos : datapos+datalen]) |
||||||
|
} |
||||||
|
|
||||||
|
return p, data[datapos+datalen:] |
||||||
|
} |
||||||
|
|
||||||
|
func (p *Packet) DataLength() uint64 { |
||||||
|
return uint64(p.Data.Len()) |
||||||
|
} |
||||||
|
|
||||||
|
func (p *Packet) Bytes() []byte { |
||||||
|
var out bytes.Buffer |
||||||
|
|
||||||
|
out.Write([]byte{p.ClassType | p.TagType | p.Tag}) |
||||||
|
packet_length := EncodeInteger(p.DataLength()) |
||||||
|
|
||||||
|
if p.DataLength() > 127 || len(packet_length) > 1 { |
||||||
|
out.Write([]byte{byte(len(packet_length) | 128)}) |
||||||
|
out.Write(packet_length) |
||||||
|
} else { |
||||||
|
out.Write(packet_length) |
||||||
|
} |
||||||
|
|
||||||
|
out.Write(p.Data.Bytes()) |
||||||
|
|
||||||
|
return out.Bytes() |
||||||
|
} |
||||||
|
|
||||||
|
func (p *Packet) AppendChild(child *Packet) { |
||||||
|
p.Data.Write(child.Bytes()) |
||||||
|
|
||||||
|
if len(p.Children) == cap(p.Children) { |
||||||
|
newChildren := make([]*Packet, cap(p.Children)*2) |
||||||
|
|
||||||
|
copy(newChildren, p.Children) |
||||||
|
p.Children = newChildren[0:len(p.Children)] |
||||||
|
} |
||||||
|
|
||||||
|
p.Children = p.Children[0 : len(p.Children)+1] |
||||||
|
p.Children[len(p.Children)-1] = child |
||||||
|
} |
||||||
|
|
||||||
|
func Encode(ClassType, TagType, Tag uint8, Value interface{}, Description string) *Packet { |
||||||
|
p := new(Packet) |
||||||
|
|
||||||
|
p.ClassType = ClassType |
||||||
|
p.TagType = TagType |
||||||
|
p.Tag = Tag |
||||||
|
p.Data = new(bytes.Buffer) |
||||||
|
|
||||||
|
p.Children = make([]*Packet, 0, 2) |
||||||
|
|
||||||
|
p.Value = Value |
||||||
|
p.Description = Description |
||||||
|
|
||||||
|
if Value != nil { |
||||||
|
v := reflect.ValueOf(Value) |
||||||
|
|
||||||
|
if ClassType == ClassUniversal { |
||||||
|
switch Tag { |
||||||
|
case TagOctetString: |
||||||
|
sv, ok := v.Interface().(string) |
||||||
|
|
||||||
|
if ok { |
||||||
|
p.Data.Write([]byte(sv)) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return p |
||||||
|
} |
||||||
|
|
||||||
|
func NewSequence(Description string) *Packet { |
||||||
|
return Encode(ClassUniversal, TypePrimitive, TagSequence, nil, Description) |
||||||
|
} |
||||||
|
|
||||||
|
func NewBoolean(ClassType, TagType, Tag uint8, Value bool, Description string) *Packet { |
||||||
|
intValue := 0 |
||||||
|
|
||||||
|
if Value { |
||||||
|
intValue = 1 |
||||||
|
} |
||||||
|
|
||||||
|
p := Encode(ClassType, TagType, Tag, nil, Description) |
||||||
|
|
||||||
|
p.Value = Value |
||||||
|
p.Data.Write(EncodeInteger(uint64(intValue))) |
||||||
|
|
||||||
|
return p |
||||||
|
} |
||||||
|
|
||||||
|
func NewInteger(ClassType, TagType, Tag uint8, Value uint64, Description string) *Packet { |
||||||
|
p := Encode(ClassType, TagType, Tag, nil, Description) |
||||||
|
|
||||||
|
p.Value = Value |
||||||
|
p.Data.Write(EncodeInteger(Value)) |
||||||
|
|
||||||
|
return p |
||||||
|
} |
||||||
|
|
||||||
|
func NewString(ClassType, TagType, Tag uint8, Value, Description string) *Packet { |
||||||
|
p := Encode(ClassType, TagType, Tag, nil, Description) |
||||||
|
|
||||||
|
p.Value = Value |
||||||
|
p.Data.Write([]byte(Value)) |
||||||
|
|
||||||
|
return p |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package git |
||||||
|
|
||||||
|
import ( |
||||||
|
"strings" |
||||||
|
) |
||||||
|
|
||||||
|
type SubModule struct { |
||||||
|
Name string |
||||||
|
Url string |
||||||
|
} |
||||||
|
|
||||||
|
// SubModuleFile represents a file with submodule type.
|
||||||
|
type SubModuleFile struct { |
||||||
|
*Commit |
||||||
|
|
||||||
|
refUrl string |
||||||
|
refId string |
||||||
|
} |
||||||
|
|
||||||
|
func NewSubModuleFile(c *Commit, refUrl, refId string) *SubModuleFile { |
||||||
|
return &SubModuleFile{ |
||||||
|
Commit: c, |
||||||
|
refUrl: refUrl, |
||||||
|
refId: refId, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// RefUrl guesses and returns reference URL.
|
||||||
|
func (sf *SubModuleFile) RefUrl() string { |
||||||
|
url := strings.TrimSuffix(sf.refUrl, ".git") |
||||||
|
|
||||||
|
// git://xxx/user/repo
|
||||||
|
if strings.HasPrefix(url, "git://") { |
||||||
|
return "http://" + strings.TrimPrefix(url, "git://") |
||||||
|
} |
||||||
|
|
||||||
|
// http[s]://xxx/user/repo
|
||||||
|
if strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") { |
||||||
|
return url |
||||||
|
} |
||||||
|
|
||||||
|
// sysuser@xxx:user/repo
|
||||||
|
i := strings.Index(url, "@") |
||||||
|
j := strings.LastIndex(url, ":") |
||||||
|
if i > -1 && j > -1 { |
||||||
|
return "http://" + url[i+1:j] + "/" + url[j+1:] |
||||||
|
} |
||||||
|
return url |
||||||
|
} |
||||||
|
|
||||||
|
// RefId returns reference ID.
|
||||||
|
func (sf *SubModuleFile) RefId() string { |
||||||
|
return sf.refId |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
Copyright (c) 2012 The Go Authors. All rights reserved. |
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without |
||||||
|
modification, are permitted provided that the following conditions are |
||||||
|
met: |
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer. |
||||||
|
* Redistributions in binary form must reproduce the above |
||||||
|
copyright notice, this list of conditions and the following disclaimer |
||||||
|
in the documentation and/or other materials provided with the |
||||||
|
distribution. |
||||||
|
* Neither the name of Google Inc. nor the names of its |
||||||
|
contributors may be used to endorse or promote products derived from |
||||||
|
this software without specific prior written permission. |
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
@ -0,0 +1,33 @@ |
|||||||
|
Basic LDAP v3 functionality for the GO programming language. |
||||||
|
|
||||||
|
Required Librarys: |
||||||
|
github.com/johnweldon/asn1-ber |
||||||
|
|
||||||
|
Working: |
||||||
|
Connecting to LDAP server |
||||||
|
Binding to LDAP server |
||||||
|
Searching for entries |
||||||
|
Compiling string filters to LDAP filters |
||||||
|
Paging Search Results |
||||||
|
Modify Requests / Responses |
||||||
|
|
||||||
|
Examples: |
||||||
|
search |
||||||
|
modify |
||||||
|
|
||||||
|
Tests Implemented: |
||||||
|
Filter Compile / Decompile |
||||||
|
|
||||||
|
TODO: |
||||||
|
Add Requests / Responses |
||||||
|
Delete Requests / Responses |
||||||
|
Modify DN Requests / Responses |
||||||
|
Compare Requests / Responses |
||||||
|
Implement Tests / Benchmarks |
||||||
|
|
||||||
|
This feature is disabled at the moment, because in some cases the "Search Request Done" packet will be handled before the last "Search Request Entry": |
||||||
|
Mulitple internal goroutines to handle network traffic |
||||||
|
Makes library goroutine safe |
||||||
|
Can perform multiple search requests at the same time and return |
||||||
|
the results to the proper goroutine. All requests are blocking |
||||||
|
requests, so the goroutine does not need special handling |
@ -0,0 +1,63 @@ |
|||||||
|
dn: dc=enterprise,dc=org |
||||||
|
objectClass: dcObject |
||||||
|
objectClass: organization |
||||||
|
o: acme |
||||||
|
|
||||||
|
dn: cn=admin,dc=enterprise,dc=org |
||||||
|
objectClass: person |
||||||
|
cn: admin |
||||||
|
sn: admin |
||||||
|
description: "LDAP Admin" |
||||||
|
|
||||||
|
dn: ou=crew,dc=enterprise,dc=org |
||||||
|
ou: crew |
||||||
|
objectClass: organizationalUnit |
||||||
|
|
||||||
|
|
||||||
|
dn: cn=kirkj,ou=crew,dc=enterprise,dc=org |
||||||
|
cn: kirkj |
||||||
|
sn: Kirk |
||||||
|
gn: James Tiberius |
||||||
|
mail: james.kirk@enterprise.org |
||||||
|
objectClass: inetOrgPerson |
||||||
|
|
||||||
|
dn: cn=spock,ou=crew,dc=enterprise,dc=org |
||||||
|
cn: spock |
||||||
|
sn: Spock |
||||||
|
mail: spock@enterprise.org |
||||||
|
objectClass: inetOrgPerson |
||||||
|
|
||||||
|
dn: cn=mccoyl,ou=crew,dc=enterprise,dc=org |
||||||
|
cn: mccoyl |
||||||
|
sn: McCoy |
||||||
|
gn: Leonard |
||||||
|
mail: leonard.mccoy@enterprise.org |
||||||
|
objectClass: inetOrgPerson |
||||||
|
|
||||||
|
dn: cn=scottm,ou=crew,dc=enterprise,dc=org |
||||||
|
cn: scottm |
||||||
|
sn: Scott |
||||||
|
gn: Montgomery |
||||||
|
mail: Montgomery.scott@enterprise.org |
||||||
|
objectClass: inetOrgPerson |
||||||
|
|
||||||
|
dn: cn=uhuran,ou=crew,dc=enterprise,dc=org |
||||||
|
cn: uhuran |
||||||
|
sn: Uhura |
||||||
|
gn: Nyota |
||||||
|
mail: nyota.uhura@enterprise.org |
||||||
|
objectClass: inetOrgPerson |
||||||
|
|
||||||
|
dn: cn=suluh,ou=crew,dc=enterprise,dc=org |
||||||
|
cn: suluh |
||||||
|
sn: Sulu |
||||||
|
gn: Hikaru |
||||||
|
mail: hikaru.sulu@enterprise.org |
||||||
|
objectClass: inetOrgPerson |
||||||
|
|
||||||
|
dn: cn=chekovp,ou=crew,dc=enterprise,dc=org |
||||||
|
cn: chekovp |
||||||
|
sn: Chekov |
||||||
|
gn: pavel |
||||||
|
mail: pavel.chekov@enterprise.org |
||||||
|
objectClass: inetOrgPerson |
@ -0,0 +1,89 @@ |
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package main |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
"fmt" |
||||||
|
"log" |
||||||
|
|
||||||
|
"github.com/gogits/gogs/modules/ldap" |
||||||
|
) |
||||||
|
|
||||||
|
var ( |
||||||
|
LdapServer string = "localhost" |
||||||
|
LdapPort uint16 = 389 |
||||||
|
BaseDN string = "dc=enterprise,dc=org" |
||||||
|
BindDN string = "cn=admin,dc=enterprise,dc=org" |
||||||
|
BindPW string = "enterprise" |
||||||
|
Filter string = "(cn=kirkj)" |
||||||
|
) |
||||||
|
|
||||||
|
func search(l *ldap.Conn, filter string, attributes []string) (*ldap.Entry, *ldap.Error) { |
||||||
|
search := ldap.NewSearchRequest( |
||||||
|
BaseDN, |
||||||
|
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, |
||||||
|
filter, |
||||||
|
attributes, |
||||||
|
nil) |
||||||
|
|
||||||
|
sr, err := l.Search(search) |
||||||
|
if err != nil { |
||||||
|
log.Fatalf("ERROR: %s\n", err) |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
log.Printf("Search: %s -> num of entries = %d\n", search.Filter, len(sr.Entries)) |
||||||
|
if len(sr.Entries) == 0 { |
||||||
|
return nil, ldap.NewError(ldap.ErrorDebugging, errors.New(fmt.Sprintf("no entries found for: %s", filter))) |
||||||
|
} |
||||||
|
return sr.Entries[0], nil |
||||||
|
} |
||||||
|
|
||||||
|
func main() { |
||||||
|
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", LdapServer, LdapPort)) |
||||||
|
if err != nil { |
||||||
|
log.Fatalf("ERROR: %s\n", err.Error()) |
||||||
|
} |
||||||
|
defer l.Close() |
||||||
|
// l.Debug = true
|
||||||
|
|
||||||
|
l.Bind(BindDN, BindPW) |
||||||
|
|
||||||
|
log.Printf("The Search for Kirk ... %s\n", Filter) |
||||||
|
entry, err := search(l, Filter, []string{}) |
||||||
|
if err != nil { |
||||||
|
log.Fatal("could not get entry") |
||||||
|
} |
||||||
|
entry.PrettyPrint(0) |
||||||
|
|
||||||
|
log.Printf("modify the mail address and add a description ... \n") |
||||||
|
modify := ldap.NewModifyRequest(entry.DN) |
||||||
|
modify.Add("description", []string{"Captain of the USS Enterprise"}) |
||||||
|
modify.Replace("mail", []string{"captain@enterprise.org"}) |
||||||
|
if err := l.Modify(modify); err != nil { |
||||||
|
log.Fatalf("ERROR: %s\n", err.Error()) |
||||||
|
} |
||||||
|
|
||||||
|
entry, err = search(l, Filter, []string{}) |
||||||
|
if err != nil { |
||||||
|
log.Fatal("could not get entry") |
||||||
|
} |
||||||
|
entry.PrettyPrint(0) |
||||||
|
|
||||||
|
log.Printf("reset the entry ... \n") |
||||||
|
modify = ldap.NewModifyRequest(entry.DN) |
||||||
|
modify.Delete("description", []string{}) |
||||||
|
modify.Replace("mail", []string{"james.kirk@enterprise.org"}) |
||||||
|
if err := l.Modify(modify); err != nil { |
||||||
|
log.Fatalf("ERROR: %s\n", err.Error()) |
||||||
|
} |
||||||
|
|
||||||
|
entry, err = search(l, Filter, []string{}) |
||||||
|
if err != nil { |
||||||
|
log.Fatal("could not get entry") |
||||||
|
} |
||||||
|
entry.PrettyPrint(0) |
||||||
|
} |
@ -0,0 +1,52 @@ |
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package main |
||||||
|
|
||||||
|
import ( |
||||||
|
"fmt" |
||||||
|
"log" |
||||||
|
|
||||||
|
"github.com/gogits/gogs/modules/ldap" |
||||||
|
) |
||||||
|
|
||||||
|
var ( |
||||||
|
ldapServer string = "adserver" |
||||||
|
ldapPort uint16 = 3268 |
||||||
|
baseDN string = "dc=*,dc=*" |
||||||
|
filter string = "(&(objectClass=user)(sAMAccountName=*)(memberOf=CN=*,OU=*,DC=*,DC=*))" |
||||||
|
Attributes []string = []string{"memberof"} |
||||||
|
user string = "*" |
||||||
|
passwd string = "*" |
||||||
|
) |
||||||
|
|
||||||
|
func main() { |
||||||
|
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort)) |
||||||
|
if err != nil { |
||||||
|
log.Fatalf("ERROR: %s\n", err.Error()) |
||||||
|
} |
||||||
|
defer l.Close() |
||||||
|
// l.Debug = true
|
||||||
|
|
||||||
|
err = l.Bind(user, passwd) |
||||||
|
if err != nil { |
||||||
|
log.Printf("ERROR: Cannot bind: %s\n", err.Error()) |
||||||
|
return |
||||||
|
} |
||||||
|
search := ldap.NewSearchRequest( |
||||||
|
baseDN, |
||||||
|
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, |
||||||
|
filter, |
||||||
|
Attributes, |
||||||
|
nil) |
||||||
|
|
||||||
|
sr, err := l.Search(search) |
||||||
|
if err != nil { |
||||||
|
log.Fatalf("ERROR: %s\n", err.Error()) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
log.Printf("Search: %s -> num of entries = %d\n", search.Filter, len(sr.Entries)) |
||||||
|
sr.PrettyPrint(0) |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package main |
||||||
|
|
||||||
|
import ( |
||||||
|
"fmt" |
||||||
|
"log" |
||||||
|
|
||||||
|
"github.com/gogits/gogs/modules/ldap" |
||||||
|
) |
||||||
|
|
||||||
|
var ( |
||||||
|
LdapServer string = "localhost" |
||||||
|
LdapPort uint16 = 636 |
||||||
|
BaseDN string = "dc=enterprise,dc=org" |
||||||
|
Filter string = "(cn=kirkj)" |
||||||
|
Attributes []string = []string{"mail"} |
||||||
|
) |
||||||
|
|
||||||
|
func main() { |
||||||
|
l, err := ldap.DialSSL("tcp", fmt.Sprintf("%s:%d", LdapServer, LdapPort), nil) |
||||||
|
if err != nil { |
||||||
|
log.Fatalf("ERROR: %s\n", err.String()) |
||||||
|
} |
||||||
|
defer l.Close() |
||||||
|
// l.Debug = true
|
||||||
|
|
||||||
|
search := ldap.NewSearchRequest( |
||||||
|
BaseDN, |
||||||
|
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, |
||||||
|
Filter, |
||||||
|
Attributes, |
||||||
|
nil) |
||||||
|
|
||||||
|
sr, err := l.Search(search) |
||||||
|
if err != nil { |
||||||
|
log.Fatalf("ERROR: %s\n", err.String()) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
log.Printf("Search: %s -> num of entries = %d\n", search.Filter, len(sr.Entries)) |
||||||
|
sr.PrettyPrint(0) |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package main |
||||||
|
|
||||||
|
import ( |
||||||
|
"fmt" |
||||||
|
"log" |
||||||
|
|
||||||
|
"github.com/gogits/gogs/modules/ldap" |
||||||
|
) |
||||||
|
|
||||||
|
var ( |
||||||
|
LdapServer string = "localhost" |
||||||
|
LdapPort uint16 = 389 |
||||||
|
BaseDN string = "dc=enterprise,dc=org" |
||||||
|
Filter string = "(cn=kirkj)" |
||||||
|
Attributes []string = []string{"mail"} |
||||||
|
) |
||||||
|
|
||||||
|
func main() { |
||||||
|
l, err := ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", LdapServer, LdapPort), nil) |
||||||
|
if err != nil { |
||||||
|
log.Fatalf("ERROR: %s\n", err.Error()) |
||||||
|
} |
||||||
|
defer l.Close() |
||||||
|
// l.Debug = true
|
||||||
|
|
||||||
|
search := ldap.NewSearchRequest( |
||||||
|
BaseDN, |
||||||
|
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, |
||||||
|
Filter, |
||||||
|
Attributes, |
||||||
|
nil) |
||||||
|
|
||||||
|
sr, err := l.Search(search) |
||||||
|
if err != nil { |
||||||
|
log.Fatalf("ERROR: %s\n", err.Error()) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
log.Printf("Search: %s -> num of entries = %d\n", search.Filter, len(sr.Entries)) |
||||||
|
sr.PrettyPrint(0) |
||||||
|
} |
@ -0,0 +1,67 @@ |
|||||||
|
# |
||||||
|
# See slapd.conf(5) for details on configuration options. |
||||||
|
# This file should NOT be world readable. |
||||||
|
# |
||||||
|
include /private/etc/openldap/schema/core.schema |
||||||
|
include /private/etc/openldap/schema/cosine.schema |
||||||
|
include /private/etc/openldap/schema/inetorgperson.schema |
||||||
|
|
||||||
|
# Define global ACLs to disable default read access. |
||||||
|
|
||||||
|
# Do not enable referrals until AFTER you have a working directory |
||||||
|
# service AND an understanding of referrals. |
||||||
|
#referral ldap://root.openldap.org |
||||||
|
|
||||||
|
pidfile /private/var/db/openldap/run/slapd.pid |
||||||
|
argsfile /private/var/db/openldap/run/slapd.args |
||||||
|
|
||||||
|
# Load dynamic backend modules: |
||||||
|
# modulepath /usr/libexec/openldap |
||||||
|
# moduleload back_bdb.la |
||||||
|
# moduleload back_hdb.la |
||||||
|
# moduleload back_ldap.la |
||||||
|
|
||||||
|
# Sample security restrictions |
||||||
|
# Require integrity protection (prevent hijacking) |
||||||
|
# Require 112-bit (3DES or better) encryption for updates |
||||||
|
# Require 63-bit encryption for simple bind |
||||||
|
# security ssf=1 update_ssf=112 simple_bind=64 |
||||||
|
|
||||||
|
# Sample access control policy: |
||||||
|
# Root DSE: allow anyone to read it |
||||||
|
# Subschema (sub)entry DSE: allow anyone to read it |
||||||
|
# Other DSEs: |
||||||
|
# Allow self write access |
||||||
|
# Allow authenticated users read access |
||||||
|
# Allow anonymous users to authenticate |
||||||
|
# Directives needed to implement policy: |
||||||
|
# access to dn.base="" by * read |
||||||
|
# access to dn.base="cn=Subschema" by * read |
||||||
|
# access to * |
||||||
|
# by self write |
||||||
|
# by users read |
||||||
|
# by anonymous auth |
||||||
|
# |
||||||
|
# if no access controls are present, the default policy |
||||||
|
# allows anyone and everyone to read anything but restricts |
||||||
|
# updates to rootdn. (e.g., "access to * by * read") |
||||||
|
# |
||||||
|
# rootdn can always read and write EVERYTHING! |
||||||
|
|
||||||
|
####################################################################### |
||||||
|
# BDB database definitions |
||||||
|
####################################################################### |
||||||
|
|
||||||
|
database bdb |
||||||
|
suffix "dc=enterprise,dc=org" |
||||||
|
rootdn "cn=admin,dc=enterprise,dc=org" |
||||||
|
# Cleartext passwords, especially for the rootdn, should |
||||||
|
# be avoid. See slappasswd(8) and slapd.conf(5) for details. |
||||||
|
# Use of strong authentication encouraged. |
||||||
|
rootpw {SSHA}laO00HsgszhK1O0Z5qR0/i/US69Osfeu |
||||||
|
# The database directory MUST exist prior to running slapd AND |
||||||
|
# should only be accessible by the slapd and slap tools. |
||||||
|
# Mode 700 recommended. |
||||||
|
directory /private/var/db/openldap/openldap-data |
||||||
|
# Indices to maintain |
||||||
|
index objectClass eq |
@ -0,0 +1,55 @@ |
|||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package ldap |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
|
||||||
|
"github.com/gogits/gogs/modules/asn1-ber" |
||||||
|
) |
||||||
|
|
||||||
|
func (l *Conn) Bind(username, password string) error { |
||||||
|
messageID := l.nextMessageID() |
||||||
|
|
||||||
|
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") |
||||||
|
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID")) |
||||||
|
bindRequest := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request") |
||||||
|
bindRequest.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version")) |
||||||
|
bindRequest.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, username, "User Name")) |
||||||
|
bindRequest.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, password, "Password")) |
||||||
|
packet.AppendChild(bindRequest) |
||||||
|
|
||||||
|
if l.Debug { |
||||||
|
ber.PrintPacket(packet) |
||||||
|
} |
||||||
|
|
||||||
|
channel, err := l.sendMessage(packet) |
||||||
|
if err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
if channel == nil { |
||||||
|
return NewError(ErrorNetwork, errors.New("ldap: could not send message")) |
||||||
|
} |
||||||
|
defer l.finishMessage(messageID) |
||||||
|
|
||||||
|
packet = <-channel |
||||||
|
if packet == nil { |
||||||
|
return NewError(ErrorNetwork, errors.New("ldap: could not retrieve response")) |
||||||
|
} |
||||||
|
|
||||||
|
if l.Debug { |
||||||
|
if err := addLDAPDescriptions(packet); err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
ber.PrintPacket(packet) |
||||||
|
} |
||||||
|
|
||||||
|
resultCode, resultDescription := getLDAPResultCode(packet) |
||||||
|
if resultCode != 0 { |
||||||
|
return NewError(resultCode, errors.New(resultDescription)) |
||||||
|
} |
||||||
|
|
||||||
|
return nil |
||||||
|
} |
@ -0,0 +1,275 @@ |
|||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package ldap |
||||||
|
|
||||||
|
import ( |
||||||
|
"crypto/tls" |
||||||
|
"errors" |
||||||
|
"log" |
||||||
|
"net" |
||||||
|
"sync" |
||||||
|
|
||||||
|
"github.com/gogits/gogs/modules/asn1-ber" |
||||||
|
) |
||||||
|
|
||||||
|
const ( |
||||||
|
MessageQuit = 0 |
||||||
|
MessageRequest = 1 |
||||||
|
MessageResponse = 2 |
||||||
|
MessageFinish = 3 |
||||||
|
) |
||||||
|
|
||||||
|
type messagePacket struct { |
||||||
|
Op int |
||||||
|
MessageID uint64 |
||||||
|
Packet *ber.Packet |
||||||
|
Channel chan *ber.Packet |
||||||
|
} |
||||||
|
|
||||||
|
// Conn represents an LDAP Connection
|
||||||
|
type Conn struct { |
||||||
|
conn net.Conn |
||||||
|
isTLS bool |
||||||
|
isClosing bool |
||||||
|
Debug debugging |
||||||
|
chanConfirm chan bool |
||||||
|
chanResults map[uint64]chan *ber.Packet |
||||||
|
chanMessage chan *messagePacket |
||||||
|
chanMessageID chan uint64 |
||||||
|
wgSender sync.WaitGroup |
||||||
|
wgClose sync.WaitGroup |
||||||
|
once sync.Once |
||||||
|
} |
||||||
|
|
||||||
|
// Dial connects to the given address on the given network using net.Dial
|
||||||
|
// and then returns a new Conn for the connection.
|
||||||
|
func Dial(network, addr string) (*Conn, error) { |
||||||
|
c, err := net.Dial(network, addr) |
||||||
|
if err != nil { |
||||||
|
return nil, NewError(ErrorNetwork, err) |
||||||
|
} |
||||||
|
conn := NewConn(c) |
||||||
|
conn.start() |
||||||
|
return conn, nil |
||||||
|
} |
||||||
|
|
||||||
|
// DialTLS connects to the given address on the given network using tls.Dial
|
||||||
|
// and then returns a new Conn for the connection.
|
||||||
|
func DialTLS(network, addr string, config *tls.Config) (*Conn, error) { |
||||||
|
c, err := tls.Dial(network, addr, config) |
||||||
|
if err != nil { |
||||||
|
return nil, NewError(ErrorNetwork, err) |
||||||
|
} |
||||||
|
conn := NewConn(c) |
||||||
|
conn.isTLS = true |
||||||
|
conn.start() |
||||||
|
return conn, nil |
||||||
|
} |
||||||
|
|
||||||
|
// NewConn returns a new Conn using conn for network I/O.
|
||||||
|
func NewConn(conn net.Conn) *Conn { |
||||||
|
return &Conn{ |
||||||
|
conn: conn, |
||||||
|
chanConfirm: make(chan bool), |
||||||
|
chanMessageID: make(chan uint64), |
||||||
|
chanMessage: make(chan *messagePacket, 10), |
||||||
|
chanResults: map[uint64]chan *ber.Packet{}, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func (l *Conn) start() { |
||||||
|
go l.reader() |
||||||
|
go l.processMessages() |
||||||
|
l.wgClose.Add(1) |
||||||
|
} |
||||||
|
|
||||||
|
// Close closes the connection.
|
||||||
|
func (l *Conn) Close() { |
||||||
|
l.once.Do(func() { |
||||||
|
l.isClosing = true |
||||||
|
l.wgSender.Wait() |
||||||
|
|
||||||
|
l.Debug.Printf("Sending quit message and waiting for confirmation") |
||||||
|
l.chanMessage <- &messagePacket{Op: MessageQuit} |
||||||
|
<-l.chanConfirm |
||||||
|
close(l.chanMessage) |
||||||
|
|
||||||
|
l.Debug.Printf("Closing network connection") |
||||||
|
if err := l.conn.Close(); err != nil { |
||||||
|
log.Print(err) |
||||||
|
} |
||||||
|
|
||||||
|
l.conn = nil |
||||||
|
l.wgClose.Done() |
||||||
|
}) |
||||||
|
l.wgClose.Wait() |
||||||
|
} |
||||||
|
|
||||||
|
// Returns the next available messageID
|
||||||
|
func (l *Conn) nextMessageID() uint64 { |
||||||
|
if l.chanMessageID != nil { |
||||||
|
if messageID, ok := <-l.chanMessageID; ok { |
||||||
|
return messageID |
||||||
|
} |
||||||
|
} |
||||||
|
return 0 |
||||||
|
} |
||||||
|
|
||||||
|
// StartTLS sends the command to start a TLS session and then creates a new TLS Client
|
||||||
|
func (l *Conn) StartTLS(config *tls.Config) error { |
||||||
|
messageID := l.nextMessageID() |
||||||
|
|
||||||
|
if l.isTLS { |
||||||
|
return NewError(ErrorNetwork, errors.New("ldap: already encrypted")) |
||||||
|
} |
||||||
|
|
||||||
|
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") |
||||||
|
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID")) |
||||||
|
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationExtendedRequest, nil, "Start TLS") |
||||||
|
request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, "1.3.6.1.4.1.1466.20037", "TLS Extended Command")) |
||||||
|
packet.AppendChild(request) |
||||||
|
l.Debug.PrintPacket(packet) |
||||||
|
|
||||||
|
_, err := l.conn.Write(packet.Bytes()) |
||||||
|
if err != nil { |
||||||
|
return NewError(ErrorNetwork, err) |
||||||
|
} |
||||||
|
|
||||||
|
packet, err = ber.ReadPacket(l.conn) |
||||||
|
if err != nil { |
||||||
|
return NewError(ErrorNetwork, err) |
||||||
|
} |
||||||
|
|
||||||
|
if l.Debug { |
||||||
|
if err := addLDAPDescriptions(packet); err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
ber.PrintPacket(packet) |
||||||
|
} |
||||||
|
|
||||||
|
if packet.Children[1].Children[0].Value.(uint64) == 0 { |
||||||
|
conn := tls.Client(l.conn, config) |
||||||
|
l.isTLS = true |
||||||
|
l.conn = conn |
||||||
|
} |
||||||
|
|
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
func (l *Conn) sendMessage(packet *ber.Packet) (chan *ber.Packet, error) { |
||||||
|
if l.isClosing { |
||||||
|
return nil, NewError(ErrorNetwork, errors.New("ldap: connection closed")) |
||||||
|
} |
||||||
|
out := make(chan *ber.Packet) |
||||||
|
message := &messagePacket{ |
||||||
|
Op: MessageRequest, |
||||||
|
MessageID: packet.Children[0].Value.(uint64), |
||||||
|
Packet: packet, |
||||||
|
Channel: out, |
||||||
|
} |
||||||
|
l.sendProcessMessage(message) |
||||||
|
return out, nil |
||||||
|
} |
||||||
|
|
||||||
|
func (l *Conn) finishMessage(messageID uint64) { |
||||||
|
if l.isClosing { |
||||||
|
return |
||||||
|
} |
||||||
|
message := &messagePacket{ |
||||||
|
Op: MessageFinish, |
||||||
|
MessageID: messageID, |
||||||
|
} |
||||||
|
l.sendProcessMessage(message) |
||||||
|
} |
||||||
|
|
||||||
|
func (l *Conn) sendProcessMessage(message *messagePacket) bool { |
||||||
|
if l.isClosing { |
||||||
|
return false |
||||||
|
} |
||||||
|
l.wgSender.Add(1) |
||||||
|
l.chanMessage <- message |
||||||
|
l.wgSender.Done() |
||||||
|
return true |
||||||
|
} |
||||||
|
|
||||||
|
func (l *Conn) processMessages() { |
||||||
|
defer func() { |
||||||
|
for messageID, channel := range l.chanResults { |
||||||
|
l.Debug.Printf("Closing channel for MessageID %d", messageID) |
||||||
|
close(channel) |
||||||
|
delete(l.chanResults, messageID) |
||||||
|
} |
||||||
|
close(l.chanMessageID) |
||||||
|
l.chanConfirm <- true |
||||||
|
close(l.chanConfirm) |
||||||
|
}() |
||||||
|
|
||||||
|
var messageID uint64 = 1 |
||||||
|
for { |
||||||
|
select { |
||||||
|
case l.chanMessageID <- messageID: |
||||||
|
messageID++ |
||||||
|
case messagePacket, ok := <-l.chanMessage: |
||||||
|
if !ok { |
||||||
|
l.Debug.Printf("Shutting down - message channel is closed") |
||||||
|
return |
||||||
|
} |
||||||
|
switch messagePacket.Op { |
||||||
|
case MessageQuit: |
||||||
|
l.Debug.Printf("Shutting down - quit message received") |
||||||
|
return |
||||||
|
case MessageRequest: |
||||||
|
// Add to message list and write to network
|
||||||
|
l.Debug.Printf("Sending message %d", messagePacket.MessageID) |
||||||
|
l.chanResults[messagePacket.MessageID] = messagePacket.Channel |
||||||
|
// go routine
|
||||||
|
buf := messagePacket.Packet.Bytes() |
||||||
|
|
||||||
|
_, err := l.conn.Write(buf) |
||||||
|
if err != nil { |
||||||
|
l.Debug.Printf("Error Sending Message: %s", err.Error()) |
||||||
|
break |
||||||
|
} |
||||||
|
case MessageResponse: |
||||||
|
l.Debug.Printf("Receiving message %d", messagePacket.MessageID) |
||||||
|
if chanResult, ok := l.chanResults[messagePacket.MessageID]; ok { |
||||||
|
chanResult <- messagePacket.Packet |
||||||
|
} else { |
||||||
|
log.Printf("Received unexpected message %d", messagePacket.MessageID) |
||||||
|
ber.PrintPacket(messagePacket.Packet) |
||||||
|
} |
||||||
|
case MessageFinish: |
||||||
|
// Remove from message list
|
||||||
|
l.Debug.Printf("Finished message %d", messagePacket.MessageID) |
||||||
|
close(l.chanResults[messagePacket.MessageID]) |
||||||
|
delete(l.chanResults, messagePacket.MessageID) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func (l *Conn) reader() { |
||||||
|
defer func() { |
||||||
|
l.Close() |
||||||
|
}() |
||||||
|
|
||||||
|
for { |
||||||
|
packet, err := ber.ReadPacket(l.conn) |
||||||
|
if err != nil { |
||||||
|
l.Debug.Printf("reader: %s", err.Error()) |
||||||
|
return |
||||||
|
} |
||||||
|
addLDAPDescriptions(packet) |
||||||
|
message := &messagePacket{ |
||||||
|
Op: MessageResponse, |
||||||
|
MessageID: packet.Children[0].Value.(uint64), |
||||||
|
Packet: packet, |
||||||
|
} |
||||||
|
if !l.sendProcessMessage(message) { |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,157 @@ |
|||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package ldap |
||||||
|
|
||||||
|
import ( |
||||||
|
"fmt" |
||||||
|
|
||||||
|
"github.com/gogits/gogs/modules/asn1-ber" |
||||||
|
) |
||||||
|
|
||||||
|
const ( |
||||||
|
ControlTypePaging = "1.2.840.113556.1.4.319" |
||||||
|
) |
||||||
|
|
||||||
|
var ControlTypeMap = map[string]string{ |
||||||
|
ControlTypePaging: "Paging", |
||||||
|
} |
||||||
|
|
||||||
|
type Control interface { |
||||||
|
GetControlType() string |
||||||
|
Encode() *ber.Packet |
||||||
|
String() string |
||||||
|
} |
||||||
|
|
||||||
|
type ControlString struct { |
||||||
|
ControlType string |
||||||
|
Criticality bool |
||||||
|
ControlValue string |
||||||
|
} |
||||||
|
|
||||||
|
func (c *ControlString) GetControlType() string { |
||||||
|
return c.ControlType |
||||||
|
} |
||||||
|
|
||||||
|
func (c *ControlString) Encode() *ber.Packet { |
||||||
|
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control") |
||||||
|
packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, c.ControlType, "Control Type ("+ControlTypeMap[c.ControlType]+")")) |
||||||
|
if c.Criticality { |
||||||
|
packet.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, c.Criticality, "Criticality")) |
||||||
|
} |
||||||
|
packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, c.ControlValue, "Control Value")) |
||||||
|
return packet |
||||||
|
} |
||||||
|
|
||||||
|
func (c *ControlString) String() string { |
||||||
|
return fmt.Sprintf("Control Type: %s (%q) Criticality: %t Control Value: %s", ControlTypeMap[c.ControlType], c.ControlType, c.Criticality, c.ControlValue) |
||||||
|
} |
||||||
|
|
||||||
|
type ControlPaging struct { |
||||||
|
PagingSize uint32 |
||||||
|
Cookie []byte |
||||||
|
} |
||||||
|
|
||||||
|
func (c *ControlPaging) GetControlType() string { |
||||||
|
return ControlTypePaging |
||||||
|
} |
||||||
|
|
||||||
|
func (c *ControlPaging) Encode() *ber.Packet { |
||||||
|
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control") |
||||||
|
packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, ControlTypePaging, "Control Type ("+ControlTypeMap[ControlTypePaging]+")")) |
||||||
|
|
||||||
|
p2 := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Control Value (Paging)") |
||||||
|
seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Search Control Value") |
||||||
|
seq.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, uint64(c.PagingSize), "Paging Size")) |
||||||
|
cookie := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Cookie") |
||||||
|
cookie.Value = c.Cookie |
||||||
|
cookie.Data.Write(c.Cookie) |
||||||
|
seq.AppendChild(cookie) |
||||||
|
p2.AppendChild(seq) |
||||||
|
|
||||||
|
packet.AppendChild(p2) |
||||||
|
return packet |
||||||
|
} |
||||||
|
|
||||||
|
func (c *ControlPaging) String() string { |
||||||
|
return fmt.Sprintf( |
||||||
|
"Control Type: %s (%q) Criticality: %t PagingSize: %d Cookie: %q", |
||||||
|
ControlTypeMap[ControlTypePaging], |
||||||
|
ControlTypePaging, |
||||||
|
false, |
||||||
|
c.PagingSize, |
||||||
|
c.Cookie) |
||||||
|
} |
||||||
|
|
||||||
|
func (c *ControlPaging) SetCookie(cookie []byte) { |
||||||
|
c.Cookie = cookie |
||||||
|
} |
||||||
|
|
||||||
|
func FindControl(controls []Control, controlType string) Control { |
||||||
|
for _, c := range controls { |
||||||
|
if c.GetControlType() == controlType { |
||||||
|
return c |
||||||
|
} |
||||||
|
} |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
func DecodeControl(packet *ber.Packet) Control { |
||||||
|
ControlType := packet.Children[0].Value.(string) |
||||||
|
Criticality := false |
||||||
|
|
||||||
|
packet.Children[0].Description = "Control Type (" + ControlTypeMap[ControlType] + ")" |
||||||
|
value := packet.Children[1] |
||||||
|
if len(packet.Children) == 3 { |
||||||
|
value = packet.Children[2] |
||||||
|
packet.Children[1].Description = "Criticality" |
||||||
|
Criticality = packet.Children[1].Value.(bool) |
||||||
|
} |
||||||
|
|
||||||
|
value.Description = "Control Value" |
||||||
|
switch ControlType { |
||||||
|
case ControlTypePaging: |
||||||
|
value.Description += " (Paging)" |
||||||
|
c := new(ControlPaging) |
||||||
|
if value.Value != nil { |
||||||
|
valueChildren := ber.DecodePacket(value.Data.Bytes()) |
||||||
|
value.Data.Truncate(0) |
||||||
|
value.Value = nil |
||||||
|
value.AppendChild(valueChildren) |
||||||
|
} |
||||||
|
value = value.Children[0] |
||||||
|
value.Description = "Search Control Value" |
||||||
|
value.Children[0].Description = "Paging Size" |
||||||
|
value.Children[1].Description = "Cookie" |
||||||
|
c.PagingSize = uint32(value.Children[0].Value.(uint64)) |
||||||
|
c.Cookie = value.Children[1].Data.Bytes() |
||||||
|
value.Children[1].Value = c.Cookie |
||||||
|
return c |
||||||
|
} |
||||||
|
c := new(ControlString) |
||||||
|
c.ControlType = ControlType |
||||||
|
c.Criticality = Criticality |
||||||
|
c.ControlValue = value.Value.(string) |
||||||
|
return c |
||||||
|
} |
||||||
|
|
||||||
|
func NewControlString(controlType string, criticality bool, controlValue string) *ControlString { |
||||||
|
return &ControlString{ |
||||||
|
ControlType: controlType, |
||||||
|
Criticality: criticality, |
||||||
|
ControlValue: controlValue, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func NewControlPaging(pagingSize uint32) *ControlPaging { |
||||||
|
return &ControlPaging{PagingSize: pagingSize} |
||||||
|
} |
||||||
|
|
||||||
|
func encodeControls(controls []Control) *ber.Packet { |
||||||
|
packet := ber.Encode(ber.ClassContext, ber.TypeConstructed, 0, nil, "Controls") |
||||||
|
for _, control := range controls { |
||||||
|
packet.AppendChild(control.Encode()) |
||||||
|
} |
||||||
|
return packet |
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
package ldap |
||||||
|
|
||||||
|
import ( |
||||||
|
"log" |
||||||
|
|
||||||
|
"github.com/gogits/gogs/modules/asn1-ber" |
||||||
|
) |
||||||
|
|
||||||
|
// debbuging type
|
||||||
|
// - has a Printf method to write the debug output
|
||||||
|
type debugging bool |
||||||
|
|
||||||
|
// write debug output
|
||||||
|
func (debug debugging) Printf(format string, args ...interface{}) { |
||||||
|
if debug { |
||||||
|
log.Printf(format, args...) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func (debug debugging) PrintPacket(packet *ber.Packet) { |
||||||
|
if debug { |
||||||
|
ber.PrintPacket(packet) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,248 @@ |
|||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package ldap |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
"fmt" |
||||||
|
|
||||||
|
"github.com/gogits/gogs/modules/asn1-ber" |
||||||
|
) |
||||||
|
|
||||||
|
const ( |
||||||
|
FilterAnd = 0 |
||||||
|
FilterOr = 1 |
||||||
|
FilterNot = 2 |
||||||
|
FilterEqualityMatch = 3 |
||||||
|
FilterSubstrings = 4 |
||||||
|
FilterGreaterOrEqual = 5 |
||||||
|
FilterLessOrEqual = 6 |
||||||
|
FilterPresent = 7 |
||||||
|
FilterApproxMatch = 8 |
||||||
|
FilterExtensibleMatch = 9 |
||||||
|
) |
||||||
|
|
||||||
|
var FilterMap = map[uint64]string{ |
||||||
|
FilterAnd: "And", |
||||||
|
FilterOr: "Or", |
||||||
|
FilterNot: "Not", |
||||||
|
FilterEqualityMatch: "Equality Match", |
||||||
|
FilterSubstrings: "Substrings", |
||||||
|
FilterGreaterOrEqual: "Greater Or Equal", |
||||||
|
FilterLessOrEqual: "Less Or Equal", |
||||||
|
FilterPresent: "Present", |
||||||
|
FilterApproxMatch: "Approx Match", |
||||||
|
FilterExtensibleMatch: "Extensible Match", |
||||||
|
} |
||||||
|
|
||||||
|
const ( |
||||||
|
FilterSubstringsInitial = 0 |
||||||
|
FilterSubstringsAny = 1 |
||||||
|
FilterSubstringsFinal = 2 |
||||||
|
) |
||||||
|
|
||||||
|
var FilterSubstringsMap = map[uint64]string{ |
||||||
|
FilterSubstringsInitial: "Substrings Initial", |
||||||
|
FilterSubstringsAny: "Substrings Any", |
||||||
|
FilterSubstringsFinal: "Substrings Final", |
||||||
|
} |
||||||
|
|
||||||
|
func CompileFilter(filter string) (*ber.Packet, error) { |
||||||
|
if len(filter) == 0 || filter[0] != '(' { |
||||||
|
return nil, NewError(ErrorFilterCompile, errors.New("ldap: filter does not start with an '('")) |
||||||
|
} |
||||||
|
packet, pos, err := compileFilter(filter, 1) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
if pos != len(filter) { |
||||||
|
return nil, NewError(ErrorFilterCompile, errors.New("ldap: finished compiling filter with extra at end: "+fmt.Sprint(filter[pos:]))) |
||||||
|
} |
||||||
|
return packet, nil |
||||||
|
} |
||||||
|
|
||||||
|
func DecompileFilter(packet *ber.Packet) (ret string, err error) { |
||||||
|
defer func() { |
||||||
|
if r := recover(); r != nil { |
||||||
|
err = NewError(ErrorFilterDecompile, errors.New("ldap: error decompiling filter")) |
||||||
|
} |
||||||
|
}() |
||||||
|
ret = "(" |
||||||
|
err = nil |
||||||
|
childStr := "" |
||||||
|
|
||||||
|
switch packet.Tag { |
||||||
|
case FilterAnd: |
||||||
|
ret += "&" |
||||||
|
for _, child := range packet.Children { |
||||||
|
childStr, err = DecompileFilter(child) |
||||||
|
if err != nil { |
||||||
|
return |
||||||
|
} |
||||||
|
ret += childStr |
||||||
|
} |
||||||
|
case FilterOr: |
||||||
|
ret += "|" |
||||||
|
for _, child := range packet.Children { |
||||||
|
childStr, err = DecompileFilter(child) |
||||||
|
if err != nil { |
||||||
|
return |
||||||
|
} |
||||||
|
ret += childStr |
||||||
|
} |
||||||
|
case FilterNot: |
||||||
|
ret += "!" |
||||||
|
childStr, err = DecompileFilter(packet.Children[0]) |
||||||
|
if err != nil { |
||||||
|
return |
||||||
|
} |
||||||
|
ret += childStr |
||||||
|
|
||||||
|
case FilterSubstrings: |
||||||
|
ret += ber.DecodeString(packet.Children[0].Data.Bytes()) |
||||||
|
ret += "=" |
||||||
|
switch packet.Children[1].Children[0].Tag { |
||||||
|
case FilterSubstringsInitial: |
||||||
|
ret += ber.DecodeString(packet.Children[1].Children[0].Data.Bytes()) + "*" |
||||||
|
case FilterSubstringsAny: |
||||||
|
ret += "*" + ber.DecodeString(packet.Children[1].Children[0].Data.Bytes()) + "*" |
||||||
|
case FilterSubstringsFinal: |
||||||
|
ret += "*" + ber.DecodeString(packet.Children[1].Children[0].Data.Bytes()) |
||||||
|
} |
||||||
|
case FilterEqualityMatch: |
||||||
|
ret += ber.DecodeString(packet.Children[0].Data.Bytes()) |
||||||
|
ret += "=" |
||||||
|
ret += ber.DecodeString(packet.Children[1].Data.Bytes()) |
||||||
|
case FilterGreaterOrEqual: |
||||||
|
ret += ber.DecodeString(packet.Children[0].Data.Bytes()) |
||||||
|
ret += ">=" |
||||||
|
ret += ber.DecodeString(packet.Children[1].Data.Bytes()) |
||||||
|
case FilterLessOrEqual: |
||||||
|
ret += ber.DecodeString(packet.Children[0].Data.Bytes()) |
||||||
|
ret += "<=" |
||||||
|
ret += ber.DecodeString(packet.Children[1].Data.Bytes()) |
||||||
|
case FilterPresent: |
||||||
|
ret += ber.DecodeString(packet.Children[0].Data.Bytes()) |
||||||
|
ret += "=*" |
||||||
|
case FilterApproxMatch: |
||||||
|
ret += ber.DecodeString(packet.Children[0].Data.Bytes()) |
||||||
|
ret += "~=" |
||||||
|
ret += ber.DecodeString(packet.Children[1].Data.Bytes()) |
||||||
|
} |
||||||
|
|
||||||
|
ret += ")" |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
func compileFilterSet(filter string, pos int, parent *ber.Packet) (int, error) { |
||||||
|
for pos < len(filter) && filter[pos] == '(' { |
||||||
|
child, newPos, err := compileFilter(filter, pos+1) |
||||||
|
if err != nil { |
||||||
|
return pos, err |
||||||
|
} |
||||||
|
pos = newPos |
||||||
|
parent.AppendChild(child) |
||||||
|
} |
||||||
|
if pos == len(filter) { |
||||||
|
return pos, NewError(ErrorFilterCompile, errors.New("ldap: unexpected end of filter")) |
||||||
|
} |
||||||
|
|
||||||
|
return pos + 1, nil |
||||||
|
} |
||||||
|
|
||||||
|
func compileFilter(filter string, pos int) (*ber.Packet, int, error) { |
||||||
|
var packet *ber.Packet |
||||||
|
var err error |
||||||
|
|
||||||
|
defer func() { |
||||||
|
if r := recover(); r != nil { |
||||||
|
err = NewError(ErrorFilterCompile, errors.New("ldap: error compiling filter")) |
||||||
|
} |
||||||
|
}() |
||||||
|
|
||||||
|
newPos := pos |
||||||
|
switch filter[pos] { |
||||||
|
case '(': |
||||||
|
packet, newPos, err = compileFilter(filter, pos+1) |
||||||
|
newPos++ |
||||||
|
return packet, newPos, err |
||||||
|
case '&': |
||||||
|
packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterAnd, nil, FilterMap[FilterAnd]) |
||||||
|
newPos, err = compileFilterSet(filter, pos+1, packet) |
||||||
|
return packet, newPos, err |
||||||
|
case '|': |
||||||
|
packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterOr, nil, FilterMap[FilterOr]) |
||||||
|
newPos, err = compileFilterSet(filter, pos+1, packet) |
||||||
|
return packet, newPos, err |
||||||
|
case '!': |
||||||
|
packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterNot, nil, FilterMap[FilterNot]) |
||||||
|
var child *ber.Packet |
||||||
|
child, newPos, err = compileFilter(filter, pos+1) |
||||||
|
packet.AppendChild(child) |
||||||
|
return packet, newPos, err |
||||||
|
default: |
||||||
|
attribute := "" |
||||||
|
condition := "" |
||||||
|
for newPos < len(filter) && filter[newPos] != ')' { |
||||||
|
switch { |
||||||
|
case packet != nil: |
||||||
|
condition += fmt.Sprintf("%c", filter[newPos]) |
||||||
|
case filter[newPos] == '=': |
||||||
|
packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterEqualityMatch, nil, FilterMap[FilterEqualityMatch]) |
||||||
|
case filter[newPos] == '>' && filter[newPos+1] == '=': |
||||||
|
packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterGreaterOrEqual, nil, FilterMap[FilterGreaterOrEqual]) |
||||||
|
newPos++ |
||||||
|
case filter[newPos] == '<' && filter[newPos+1] == '=': |
||||||
|
packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterLessOrEqual, nil, FilterMap[FilterLessOrEqual]) |
||||||
|
newPos++ |
||||||
|
case filter[newPos] == '~' && filter[newPos+1] == '=': |
||||||
|
packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterApproxMatch, nil, FilterMap[FilterLessOrEqual]) |
||||||
|
newPos++ |
||||||
|
case packet == nil: |
||||||
|
attribute += fmt.Sprintf("%c", filter[newPos]) |
||||||
|
} |
||||||
|
newPos++ |
||||||
|
} |
||||||
|
if newPos == len(filter) { |
||||||
|
err = NewError(ErrorFilterCompile, errors.New("ldap: unexpected end of filter")) |
||||||
|
return packet, newPos, err |
||||||
|
} |
||||||
|
if packet == nil { |
||||||
|
err = NewError(ErrorFilterCompile, errors.New("ldap: error parsing filter")) |
||||||
|
return packet, newPos, err |
||||||
|
} |
||||||
|
packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute, "Attribute")) |
||||||
|
switch { |
||||||
|
case packet.Tag == FilterEqualityMatch && condition == "*": |
||||||
|
packet.Tag = FilterPresent |
||||||
|
packet.Description = FilterMap[uint64(packet.Tag)] |
||||||
|
case packet.Tag == FilterEqualityMatch && condition[0] == '*' && condition[len(condition)-1] == '*': |
||||||
|
// Any
|
||||||
|
packet.Tag = FilterSubstrings |
||||||
|
packet.Description = FilterMap[uint64(packet.Tag)] |
||||||
|
seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Substrings") |
||||||
|
seq.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, FilterSubstringsAny, condition[1:len(condition)-1], "Any Substring")) |
||||||
|
packet.AppendChild(seq) |
||||||
|
case packet.Tag == FilterEqualityMatch && condition[0] == '*': |
||||||
|
// Final
|
||||||
|
packet.Tag = FilterSubstrings |
||||||
|
packet.Description = FilterMap[uint64(packet.Tag)] |
||||||
|
seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Substrings") |
||||||
|
seq.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, FilterSubstringsFinal, condition[1:], "Final Substring")) |
||||||
|
packet.AppendChild(seq) |
||||||
|
case packet.Tag == FilterEqualityMatch && condition[len(condition)-1] == '*': |
||||||
|
// Initial
|
||||||
|
packet.Tag = FilterSubstrings |
||||||
|
packet.Description = FilterMap[uint64(packet.Tag)] |
||||||
|
seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Substrings") |
||||||
|
seq.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, FilterSubstringsInitial, condition[:len(condition)-1], "Initial Substring")) |
||||||
|
packet.AppendChild(seq) |
||||||
|
default: |
||||||
|
packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, condition, "Condition")) |
||||||
|
} |
||||||
|
newPos++ |
||||||
|
return packet, newPos, err |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,78 @@ |
|||||||
|
package ldap |
||||||
|
|
||||||
|
import ( |
||||||
|
"testing" |
||||||
|
|
||||||
|
"github.com/gogits/gogs/modules/asn1-ber" |
||||||
|
) |
||||||
|
|
||||||
|
type compileTest struct { |
||||||
|
filterStr string |
||||||
|
filterType int |
||||||
|
} |
||||||
|
|
||||||
|
var testFilters = []compileTest{ |
||||||
|
compileTest{filterStr: "(&(sn=Miller)(givenName=Bob))", filterType: FilterAnd}, |
||||||
|
compileTest{filterStr: "(|(sn=Miller)(givenName=Bob))", filterType: FilterOr}, |
||||||
|
compileTest{filterStr: "(!(sn=Miller))", filterType: FilterNot}, |
||||||
|
compileTest{filterStr: "(sn=Miller)", filterType: FilterEqualityMatch}, |
||||||
|
compileTest{filterStr: "(sn=Mill*)", filterType: FilterSubstrings}, |
||||||
|
compileTest{filterStr: "(sn=*Mill)", filterType: FilterSubstrings}, |
||||||
|
compileTest{filterStr: "(sn=*Mill*)", filterType: FilterSubstrings}, |
||||||
|
compileTest{filterStr: "(sn>=Miller)", filterType: FilterGreaterOrEqual}, |
||||||
|
compileTest{filterStr: "(sn<=Miller)", filterType: FilterLessOrEqual}, |
||||||
|
compileTest{filterStr: "(sn=*)", filterType: FilterPresent}, |
||||||
|
compileTest{filterStr: "(sn~=Miller)", filterType: FilterApproxMatch}, |
||||||
|
// compileTest{ filterStr: "()", filterType: FilterExtensibleMatch },
|
||||||
|
} |
||||||
|
|
||||||
|
func TestFilter(t *testing.T) { |
||||||
|
// Test Compiler and Decompiler
|
||||||
|
for _, i := range testFilters { |
||||||
|
filter, err := CompileFilter(i.filterStr) |
||||||
|
if err != nil { |
||||||
|
t.Errorf("Problem compiling %s - %s", i.filterStr, err.Error()) |
||||||
|
} else if filter.Tag != uint8(i.filterType) { |
||||||
|
t.Errorf("%q Expected %q got %q", i.filterStr, FilterMap[uint64(i.filterType)], FilterMap[uint64(filter.Tag)]) |
||||||
|
} else { |
||||||
|
o, err := DecompileFilter(filter) |
||||||
|
if err != nil { |
||||||
|
t.Errorf("Problem compiling %s - %s", i.filterStr, err.Error()) |
||||||
|
} else if i.filterStr != o { |
||||||
|
t.Errorf("%q expected, got %q", i.filterStr, o) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func BenchmarkFilterCompile(b *testing.B) { |
||||||
|
b.StopTimer() |
||||||
|
filters := make([]string, len(testFilters)) |
||||||
|
|
||||||
|
// Test Compiler and Decompiler
|
||||||
|
for idx, i := range testFilters { |
||||||
|
filters[idx] = i.filterStr |
||||||
|
} |
||||||
|
|
||||||
|
maxIdx := len(filters) |
||||||
|
b.StartTimer() |
||||||
|
for i := 0; i < b.N; i++ { |
||||||
|
CompileFilter(filters[i%maxIdx]) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func BenchmarkFilterDecompile(b *testing.B) { |
||||||
|
b.StopTimer() |
||||||
|
filters := make([]*ber.Packet, len(testFilters)) |
||||||
|
|
||||||
|
// Test Compiler and Decompiler
|
||||||
|
for idx, i := range testFilters { |
||||||
|
filters[idx], _ = CompileFilter(i.filterStr) |
||||||
|
} |
||||||
|
|
||||||
|
maxIdx := len(filters) |
||||||
|
b.StartTimer() |
||||||
|
for i := 0; i < b.N; i++ { |
||||||
|
DecompileFilter(filters[i%maxIdx]) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,302 @@ |
|||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package ldap |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
"fmt" |
||||||
|
"io/ioutil" |
||||||
|
|
||||||
|
"github.com/gogits/gogs/modules/asn1-ber" |
||||||
|
) |
||||||
|
|
||||||
|
// LDAP Application Codes
|
||||||
|
const ( |
||||||
|
ApplicationBindRequest = 0 |
||||||
|
ApplicationBindResponse = 1 |
||||||
|
ApplicationUnbindRequest = 2 |
||||||
|
ApplicationSearchRequest = 3 |
||||||
|
ApplicationSearchResultEntry = 4 |
||||||
|
ApplicationSearchResultDone = 5 |
||||||
|
ApplicationModifyRequest = 6 |
||||||
|
ApplicationModifyResponse = 7 |
||||||
|
ApplicationAddRequest = 8 |
||||||
|
ApplicationAddResponse = 9 |
||||||
|
ApplicationDelRequest = 10 |
||||||
|
ApplicationDelResponse = 11 |
||||||
|
ApplicationModifyDNRequest = 12 |
||||||
|
ApplicationModifyDNResponse = 13 |
||||||
|
ApplicationCompareRequest = 14 |
||||||
|
ApplicationCompareResponse = 15 |
||||||
|
ApplicationAbandonRequest = 16 |
||||||
|
ApplicationSearchResultReference = 19 |
||||||
|
ApplicationExtendedRequest = 23 |
||||||
|
ApplicationExtendedResponse = 24 |
||||||
|
) |
||||||
|
|
||||||
|
var ApplicationMap = map[uint8]string{ |
||||||
|
ApplicationBindRequest: "Bind Request", |
||||||
|
ApplicationBindResponse: "Bind Response", |
||||||
|
ApplicationUnbindRequest: "Unbind Request", |
||||||
|
ApplicationSearchRequest: "Search Request", |
||||||
|
ApplicationSearchResultEntry: "Search Result Entry", |
||||||
|
ApplicationSearchResultDone: "Search Result Done", |
||||||
|
ApplicationModifyRequest: "Modify Request", |
||||||
|
ApplicationModifyResponse: "Modify Response", |
||||||
|
ApplicationAddRequest: "Add Request", |
||||||
|
ApplicationAddResponse: "Add Response", |
||||||
|
ApplicationDelRequest: "Del Request", |
||||||
|
ApplicationDelResponse: "Del Response", |
||||||
|
ApplicationModifyDNRequest: "Modify DN Request", |
||||||
|
ApplicationModifyDNResponse: "Modify DN Response", |
||||||
|
ApplicationCompareRequest: "Compare Request", |
||||||
|
ApplicationCompareResponse: "Compare Response", |
||||||
|
ApplicationAbandonRequest: "Abandon Request", |
||||||
|
ApplicationSearchResultReference: "Search Result Reference", |
||||||
|
ApplicationExtendedRequest: "Extended Request", |
||||||
|
ApplicationExtendedResponse: "Extended Response", |
||||||
|
} |
||||||
|
|
||||||
|
// LDAP Result Codes
|
||||||
|
const ( |
||||||
|
LDAPResultSuccess = 0 |
||||||
|
LDAPResultOperationsError = 1 |
||||||
|
LDAPResultProtocolError = 2 |
||||||
|
LDAPResultTimeLimitExceeded = 3 |
||||||
|
LDAPResultSizeLimitExceeded = 4 |
||||||
|
LDAPResultCompareFalse = 5 |
||||||
|
LDAPResultCompareTrue = 6 |
||||||
|
LDAPResultAuthMethodNotSupported = 7 |
||||||
|
LDAPResultStrongAuthRequired = 8 |
||||||
|
LDAPResultReferral = 10 |
||||||
|
LDAPResultAdminLimitExceeded = 11 |
||||||
|
LDAPResultUnavailableCriticalExtension = 12 |
||||||
|
LDAPResultConfidentialityRequired = 13 |
||||||
|
LDAPResultSaslBindInProgress = 14 |
||||||
|
LDAPResultNoSuchAttribute = 16 |
||||||
|
LDAPResultUndefinedAttributeType = 17 |
||||||
|
LDAPResultInappropriateMatching = 18 |
||||||
|
LDAPResultConstraintViolation = 19 |
||||||
|
LDAPResultAttributeOrValueExists = 20 |
||||||
|
LDAPResultInvalidAttributeSyntax = 21 |
||||||
|
LDAPResultNoSuchObject = 32 |
||||||
|
LDAPResultAliasProblem = 33 |
||||||
|
LDAPResultInvalidDNSyntax = 34 |
||||||
|
LDAPResultAliasDereferencingProblem = 36 |
||||||
|
LDAPResultInappropriateAuthentication = 48 |
||||||
|
LDAPResultInvalidCredentials = 49 |
||||||
|
LDAPResultInsufficientAccessRights = 50 |
||||||
|
LDAPResultBusy = 51 |
||||||
|
LDAPResultUnavailable = 52 |
||||||
|
LDAPResultUnwillingToPerform = 53 |
||||||
|
LDAPResultLoopDetect = 54 |
||||||
|
LDAPResultNamingViolation = 64 |
||||||
|
LDAPResultObjectClassViolation = 65 |
||||||
|
LDAPResultNotAllowedOnNonLeaf = 66 |
||||||
|
LDAPResultNotAllowedOnRDN = 67 |
||||||
|
LDAPResultEntryAlreadyExists = 68 |
||||||
|
LDAPResultObjectClassModsProhibited = 69 |
||||||
|
LDAPResultAffectsMultipleDSAs = 71 |
||||||
|
LDAPResultOther = 80 |
||||||
|
|
||||||
|
ErrorNetwork = 200 |
||||||
|
ErrorFilterCompile = 201 |
||||||
|
ErrorFilterDecompile = 202 |
||||||
|
ErrorDebugging = 203 |
||||||
|
) |
||||||
|
|
||||||
|
var LDAPResultCodeMap = map[uint8]string{ |
||||||
|
LDAPResultSuccess: "Success", |
||||||
|
LDAPResultOperationsError: "Operations Error", |
||||||
|
LDAPResultProtocolError: "Protocol Error", |
||||||
|
LDAPResultTimeLimitExceeded: "Time Limit Exceeded", |
||||||
|
LDAPResultSizeLimitExceeded: "Size Limit Exceeded", |
||||||
|
LDAPResultCompareFalse: "Compare False", |
||||||
|
LDAPResultCompareTrue: "Compare True", |
||||||
|
LDAPResultAuthMethodNotSupported: "Auth Method Not Supported", |
||||||
|
LDAPResultStrongAuthRequired: "Strong Auth Required", |
||||||
|
LDAPResultReferral: "Referral", |
||||||
|
LDAPResultAdminLimitExceeded: "Admin Limit Exceeded", |
||||||
|
LDAPResultUnavailableCriticalExtension: "Unavailable Critical Extension", |
||||||
|
LDAPResultConfidentialityRequired: "Confidentiality Required", |
||||||
|
LDAPResultSaslBindInProgress: "Sasl Bind In Progress", |
||||||
|
LDAPResultNoSuchAttribute: "No Such Attribute", |
||||||
|
LDAPResultUndefinedAttributeType: "Undefined Attribute Type", |
||||||
|
LDAPResultInappropriateMatching: "Inappropriate Matching", |
||||||
|
LDAPResultConstraintViolation: "Constraint Violation", |
||||||
|
LDAPResultAttributeOrValueExists: "Attribute Or Value Exists", |
||||||
|
LDAPResultInvalidAttributeSyntax: "Invalid Attribute Syntax", |
||||||
|
LDAPResultNoSuchObject: "No Such Object", |
||||||
|
LDAPResultAliasProblem: "Alias Problem", |
||||||
|
LDAPResultInvalidDNSyntax: "Invalid DN Syntax", |
||||||
|
LDAPResultAliasDereferencingProblem: "Alias Dereferencing Problem", |
||||||
|
LDAPResultInappropriateAuthentication: "Inappropriate Authentication", |
||||||
|
LDAPResultInvalidCredentials: "Invalid Credentials", |
||||||
|
LDAPResultInsufficientAccessRights: "Insufficient Access Rights", |
||||||
|
LDAPResultBusy: "Busy", |
||||||
|
LDAPResultUnavailable: "Unavailable", |
||||||
|
LDAPResultUnwillingToPerform: "Unwilling To Perform", |
||||||
|
LDAPResultLoopDetect: "Loop Detect", |
||||||
|
LDAPResultNamingViolation: "Naming Violation", |
||||||
|
LDAPResultObjectClassViolation: "Object Class Violation", |
||||||
|
LDAPResultNotAllowedOnNonLeaf: "Not Allowed On Non Leaf", |
||||||
|
LDAPResultNotAllowedOnRDN: "Not Allowed On RDN", |
||||||
|
LDAPResultEntryAlreadyExists: "Entry Already Exists", |
||||||
|
LDAPResultObjectClassModsProhibited: "Object Class Mods Prohibited", |
||||||
|
LDAPResultAffectsMultipleDSAs: "Affects Multiple DSAs", |
||||||
|
LDAPResultOther: "Other", |
||||||
|
} |
||||||
|
|
||||||
|
// Adds descriptions to an LDAP Response packet for debugging
|
||||||
|
func addLDAPDescriptions(packet *ber.Packet) (err error) { |
||||||
|
defer func() { |
||||||
|
if r := recover(); r != nil { |
||||||
|
err = NewError(ErrorDebugging, errors.New("ldap: cannot process packet to add descriptions")) |
||||||
|
} |
||||||
|
}() |
||||||
|
packet.Description = "LDAP Response" |
||||||
|
packet.Children[0].Description = "Message ID" |
||||||
|
|
||||||
|
application := packet.Children[1].Tag |
||||||
|
packet.Children[1].Description = ApplicationMap[application] |
||||||
|
|
||||||
|
switch application { |
||||||
|
case ApplicationBindRequest: |
||||||
|
addRequestDescriptions(packet) |
||||||
|
case ApplicationBindResponse: |
||||||
|
addDefaultLDAPResponseDescriptions(packet) |
||||||
|
case ApplicationUnbindRequest: |
||||||
|
addRequestDescriptions(packet) |
||||||
|
case ApplicationSearchRequest: |
||||||
|
addRequestDescriptions(packet) |
||||||
|
case ApplicationSearchResultEntry: |
||||||
|
packet.Children[1].Children[0].Description = "Object Name" |
||||||
|
packet.Children[1].Children[1].Description = "Attributes" |
||||||
|
for _, child := range packet.Children[1].Children[1].Children { |
||||||
|
child.Description = "Attribute" |
||||||
|
child.Children[0].Description = "Attribute Name" |
||||||
|
child.Children[1].Description = "Attribute Values" |
||||||
|
for _, grandchild := range child.Children[1].Children { |
||||||
|
grandchild.Description = "Attribute Value" |
||||||
|
} |
||||||
|
} |
||||||
|
if len(packet.Children) == 3 { |
||||||
|
addControlDescriptions(packet.Children[2]) |
||||||
|
} |
||||||
|
case ApplicationSearchResultDone: |
||||||
|
addDefaultLDAPResponseDescriptions(packet) |
||||||
|
case ApplicationModifyRequest: |
||||||
|
addRequestDescriptions(packet) |
||||||
|
case ApplicationModifyResponse: |
||||||
|
case ApplicationAddRequest: |
||||||
|
addRequestDescriptions(packet) |
||||||
|
case ApplicationAddResponse: |
||||||
|
case ApplicationDelRequest: |
||||||
|
addRequestDescriptions(packet) |
||||||
|
case ApplicationDelResponse: |
||||||
|
case ApplicationModifyDNRequest: |
||||||
|
addRequestDescriptions(packet) |
||||||
|
case ApplicationModifyDNResponse: |
||||||
|
case ApplicationCompareRequest: |
||||||
|
addRequestDescriptions(packet) |
||||||
|
case ApplicationCompareResponse: |
||||||
|
case ApplicationAbandonRequest: |
||||||
|
addRequestDescriptions(packet) |
||||||
|
case ApplicationSearchResultReference: |
||||||
|
case ApplicationExtendedRequest: |
||||||
|
addRequestDescriptions(packet) |
||||||
|
case ApplicationExtendedResponse: |
||||||
|
} |
||||||
|
|
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
func addControlDescriptions(packet *ber.Packet) { |
||||||
|
packet.Description = "Controls" |
||||||
|
for _, child := range packet.Children { |
||||||
|
child.Description = "Control" |
||||||
|
child.Children[0].Description = "Control Type (" + ControlTypeMap[child.Children[0].Value.(string)] + ")" |
||||||
|
value := child.Children[1] |
||||||
|
if len(child.Children) == 3 { |
||||||
|
child.Children[1].Description = "Criticality" |
||||||
|
value = child.Children[2] |
||||||
|
} |
||||||
|
value.Description = "Control Value" |
||||||
|
|
||||||
|
switch child.Children[0].Value.(string) { |
||||||
|
case ControlTypePaging: |
||||||
|
value.Description += " (Paging)" |
||||||
|
if value.Value != nil { |
||||||
|
valueChildren := ber.DecodePacket(value.Data.Bytes()) |
||||||
|
value.Data.Truncate(0) |
||||||
|
value.Value = nil |
||||||
|
valueChildren.Children[1].Value = valueChildren.Children[1].Data.Bytes() |
||||||
|
value.AppendChild(valueChildren) |
||||||
|
} |
||||||
|
value.Children[0].Description = "Real Search Control Value" |
||||||
|
value.Children[0].Children[0].Description = "Paging Size" |
||||||
|
value.Children[0].Children[1].Description = "Cookie" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func addRequestDescriptions(packet *ber.Packet) { |
||||||
|
packet.Description = "LDAP Request" |
||||||
|
packet.Children[0].Description = "Message ID" |
||||||
|
packet.Children[1].Description = ApplicationMap[packet.Children[1].Tag] |
||||||
|
if len(packet.Children) == 3 { |
||||||
|
addControlDescriptions(packet.Children[2]) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func addDefaultLDAPResponseDescriptions(packet *ber.Packet) { |
||||||
|
resultCode := packet.Children[1].Children[0].Value.(uint64) |
||||||
|
packet.Children[1].Children[0].Description = "Result Code (" + LDAPResultCodeMap[uint8(resultCode)] + ")" |
||||||
|
packet.Children[1].Children[1].Description = "Matched DN" |
||||||
|
packet.Children[1].Children[2].Description = "Error Message" |
||||||
|
if len(packet.Children[1].Children) > 3 { |
||||||
|
packet.Children[1].Children[3].Description = "Referral" |
||||||
|
} |
||||||
|
if len(packet.Children) == 3 { |
||||||
|
addControlDescriptions(packet.Children[2]) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func DebugBinaryFile(fileName string) error { |
||||||
|
file, err := ioutil.ReadFile(fileName) |
||||||
|
if err != nil { |
||||||
|
return NewError(ErrorDebugging, err) |
||||||
|
} |
||||||
|
ber.PrintBytes(file, "") |
||||||
|
packet := ber.DecodePacket(file) |
||||||
|
addLDAPDescriptions(packet) |
||||||
|
ber.PrintPacket(packet) |
||||||
|
|
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
type Error struct { |
||||||
|
Err error |
||||||
|
ResultCode uint8 |
||||||
|
} |
||||||
|
|
||||||
|
func (e *Error) Error() string { |
||||||
|
return fmt.Sprintf("LDAP Result Code %d %q: %s", e.ResultCode, LDAPResultCodeMap[e.ResultCode], e.Err.Error()) |
||||||
|
} |
||||||
|
|
||||||
|
func NewError(resultCode uint8, err error) error { |
||||||
|
return &Error{ResultCode: resultCode, Err: err} |
||||||
|
} |
||||||
|
|
||||||
|
func getLDAPResultCode(packet *ber.Packet) (code uint8, description string) { |
||||||
|
if len(packet.Children) >= 2 { |
||||||
|
response := packet.Children[1] |
||||||
|
if response.ClassType == ber.ClassApplication && response.TagType == ber.TypeConstructed && len(response.Children) == 3 { |
||||||
|
return uint8(response.Children[0].Value.(uint64)), response.Children[2].Value.(string) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return ErrorNetwork, "Invalid packet format" |
||||||
|
} |
@ -0,0 +1,123 @@ |
|||||||
|
package ldap |
||||||
|
|
||||||
|
import ( |
||||||
|
"fmt" |
||||||
|
"testing" |
||||||
|
) |
||||||
|
|
||||||
|
var ldapServer = "ldap.itd.umich.edu" |
||||||
|
var ldapPort = uint16(389) |
||||||
|
var baseDN = "dc=umich,dc=edu" |
||||||
|
var filter = []string{ |
||||||
|
"(cn=cis-fac)", |
||||||
|
"(&(objectclass=rfc822mailgroup)(cn=*Computer*))", |
||||||
|
"(&(objectclass=rfc822mailgroup)(cn=*Mathematics*))"} |
||||||
|
var attributes = []string{ |
||||||
|
"cn", |
||||||
|
"description"} |
||||||
|
|
||||||
|
func TestConnect(t *testing.T) { |
||||||
|
fmt.Printf("TestConnect: starting...\n") |
||||||
|
l, err := Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort)) |
||||||
|
if err != nil { |
||||||
|
t.Errorf(err.Error()) |
||||||
|
return |
||||||
|
} |
||||||
|
defer l.Close() |
||||||
|
fmt.Printf("TestConnect: finished...\n") |
||||||
|
} |
||||||
|
|
||||||
|
func TestSearch(t *testing.T) { |
||||||
|
fmt.Printf("TestSearch: starting...\n") |
||||||
|
l, err := Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort)) |
||||||
|
if err != nil { |
||||||
|
t.Errorf(err.Error()) |
||||||
|
return |
||||||
|
} |
||||||
|
defer l.Close() |
||||||
|
|
||||||
|
searchRequest := NewSearchRequest( |
||||||
|
baseDN, |
||||||
|
ScopeWholeSubtree, DerefAlways, 0, 0, false, |
||||||
|
filter[0], |
||||||
|
attributes, |
||||||
|
nil) |
||||||
|
|
||||||
|
sr, err := l.Search(searchRequest) |
||||||
|
if err != nil { |
||||||
|
t.Errorf(err.Error()) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
fmt.Printf("TestSearch: %s -> num of entries = %d\n", searchRequest.Filter, len(sr.Entries)) |
||||||
|
} |
||||||
|
|
||||||
|
func TestSearchWithPaging(t *testing.T) { |
||||||
|
fmt.Printf("TestSearchWithPaging: starting...\n") |
||||||
|
l, err := Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort)) |
||||||
|
if err != nil { |
||||||
|
t.Errorf(err.Error()) |
||||||
|
return |
||||||
|
} |
||||||
|
defer l.Close() |
||||||
|
|
||||||
|
err = l.Bind("", "") |
||||||
|
if err != nil { |
||||||
|
t.Errorf(err.Error()) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
searchRequest := NewSearchRequest( |
||||||
|
baseDN, |
||||||
|
ScopeWholeSubtree, DerefAlways, 0, 0, false, |
||||||
|
filter[1], |
||||||
|
attributes, |
||||||
|
nil) |
||||||
|
sr, err := l.SearchWithPaging(searchRequest, 5) |
||||||
|
if err != nil { |
||||||
|
t.Errorf(err.Error()) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
fmt.Printf("TestSearchWithPaging: %s -> num of entries = %d\n", searchRequest.Filter, len(sr.Entries)) |
||||||
|
} |
||||||
|
|
||||||
|
func testMultiGoroutineSearch(t *testing.T, l *Conn, results chan *SearchResult, i int) { |
||||||
|
searchRequest := NewSearchRequest( |
||||||
|
baseDN, |
||||||
|
ScopeWholeSubtree, DerefAlways, 0, 0, false, |
||||||
|
filter[i], |
||||||
|
attributes, |
||||||
|
nil) |
||||||
|
sr, err := l.Search(searchRequest) |
||||||
|
if err != nil { |
||||||
|
t.Errorf(err.Error()) |
||||||
|
results <- nil |
||||||
|
return |
||||||
|
} |
||||||
|
results <- sr |
||||||
|
} |
||||||
|
|
||||||
|
func TestMultiGoroutineSearch(t *testing.T) { |
||||||
|
fmt.Printf("TestMultiGoroutineSearch: starting...\n") |
||||||
|
l, err := Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort)) |
||||||
|
if err != nil { |
||||||
|
t.Errorf(err.Error()) |
||||||
|
return |
||||||
|
} |
||||||
|
defer l.Close() |
||||||
|
|
||||||
|
results := make([]chan *SearchResult, len(filter)) |
||||||
|
for i := range filter { |
||||||
|
results[i] = make(chan *SearchResult) |
||||||
|
go testMultiGoroutineSearch(t, l, results[i], i) |
||||||
|
} |
||||||
|
for i := range filter { |
||||||
|
sr := <-results[i] |
||||||
|
if sr == nil { |
||||||
|
t.Errorf("Did not receive results from goroutine for %q", filter[i]) |
||||||
|
} else { |
||||||
|
fmt.Printf("TestMultiGoroutineSearch(%d): %s -> num of entries = %d\n", i, filter[i], len(sr.Entries)) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,156 @@ |
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
//
|
||||||
|
// File contains Modify functionality
|
||||||
|
//
|
||||||
|
// https://tools.ietf.org/html/rfc4511
|
||||||
|
//
|
||||||
|
// ModifyRequest ::= [APPLICATION 6] SEQUENCE {
|
||||||
|
// object LDAPDN,
|
||||||
|
// changes SEQUENCE OF change SEQUENCE {
|
||||||
|
// operation ENUMERATED {
|
||||||
|
// add (0),
|
||||||
|
// delete (1),
|
||||||
|
// replace (2),
|
||||||
|
// ... },
|
||||||
|
// modification PartialAttribute } }
|
||||||
|
//
|
||||||
|
// PartialAttribute ::= SEQUENCE {
|
||||||
|
// type AttributeDescription,
|
||||||
|
// vals SET OF value AttributeValue }
|
||||||
|
//
|
||||||
|
// AttributeDescription ::= LDAPString
|
||||||
|
// -- Constrained to <attributedescription>
|
||||||
|
// -- [RFC4512]
|
||||||
|
//
|
||||||
|
// AttributeValue ::= OCTET STRING
|
||||||
|
//
|
||||||
|
|
||||||
|
package ldap |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
"log" |
||||||
|
|
||||||
|
"github.com/gogits/gogs/modules/asn1-ber" |
||||||
|
) |
||||||
|
|
||||||
|
const ( |
||||||
|
AddAttribute = 0 |
||||||
|
DeleteAttribute = 1 |
||||||
|
ReplaceAttribute = 2 |
||||||
|
) |
||||||
|
|
||||||
|
type PartialAttribute struct { |
||||||
|
attrType string |
||||||
|
attrVals []string |
||||||
|
} |
||||||
|
|
||||||
|
func (p *PartialAttribute) encode() *ber.Packet { |
||||||
|
seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "PartialAttribute") |
||||||
|
seq.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, p.attrType, "Type")) |
||||||
|
set := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSet, nil, "AttributeValue") |
||||||
|
for _, value := range p.attrVals { |
||||||
|
set.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, value, "Vals")) |
||||||
|
} |
||||||
|
seq.AppendChild(set) |
||||||
|
return seq |
||||||
|
} |
||||||
|
|
||||||
|
type ModifyRequest struct { |
||||||
|
dn string |
||||||
|
addAttributes []PartialAttribute |
||||||
|
deleteAttributes []PartialAttribute |
||||||
|
replaceAttributes []PartialAttribute |
||||||
|
} |
||||||
|
|
||||||
|
func (m *ModifyRequest) Add(attrType string, attrVals []string) { |
||||||
|
m.addAttributes = append(m.addAttributes, PartialAttribute{attrType: attrType, attrVals: attrVals}) |
||||||
|
} |
||||||
|
|
||||||
|
func (m *ModifyRequest) Delete(attrType string, attrVals []string) { |
||||||
|
m.deleteAttributes = append(m.deleteAttributes, PartialAttribute{attrType: attrType, attrVals: attrVals}) |
||||||
|
} |
||||||
|
|
||||||
|
func (m *ModifyRequest) Replace(attrType string, attrVals []string) { |
||||||
|
m.replaceAttributes = append(m.replaceAttributes, PartialAttribute{attrType: attrType, attrVals: attrVals}) |
||||||
|
} |
||||||
|
|
||||||
|
func (m ModifyRequest) encode() *ber.Packet { |
||||||
|
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationModifyRequest, nil, "Modify Request") |
||||||
|
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, m.dn, "DN")) |
||||||
|
changes := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Changes") |
||||||
|
for _, attribute := range m.addAttributes { |
||||||
|
change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change") |
||||||
|
change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(AddAttribute), "Operation")) |
||||||
|
change.AppendChild(attribute.encode()) |
||||||
|
changes.AppendChild(change) |
||||||
|
} |
||||||
|
for _, attribute := range m.deleteAttributes { |
||||||
|
change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change") |
||||||
|
change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(DeleteAttribute), "Operation")) |
||||||
|
change.AppendChild(attribute.encode()) |
||||||
|
changes.AppendChild(change) |
||||||
|
} |
||||||
|
for _, attribute := range m.replaceAttributes { |
||||||
|
change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change") |
||||||
|
change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(ReplaceAttribute), "Operation")) |
||||||
|
change.AppendChild(attribute.encode()) |
||||||
|
changes.AppendChild(change) |
||||||
|
} |
||||||
|
request.AppendChild(changes) |
||||||
|
return request |
||||||
|
} |
||||||
|
|
||||||
|
func NewModifyRequest( |
||||||
|
dn string, |
||||||
|
) *ModifyRequest { |
||||||
|
return &ModifyRequest{ |
||||||
|
dn: dn, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func (l *Conn) Modify(modifyRequest *ModifyRequest) error { |
||||||
|
messageID := l.nextMessageID() |
||||||
|
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") |
||||||
|
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID")) |
||||||
|
packet.AppendChild(modifyRequest.encode()) |
||||||
|
|
||||||
|
l.Debug.PrintPacket(packet) |
||||||
|
|
||||||
|
channel, err := l.sendMessage(packet) |
||||||
|
if err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
if channel == nil { |
||||||
|
return NewError(ErrorNetwork, errors.New("ldap: could not send message")) |
||||||
|
} |
||||||
|
defer l.finishMessage(messageID) |
||||||
|
|
||||||
|
l.Debug.Printf("%d: waiting for response", messageID) |
||||||
|
packet = <-channel |
||||||
|
l.Debug.Printf("%d: got response %p", messageID, packet) |
||||||
|
if packet == nil { |
||||||
|
return NewError(ErrorNetwork, errors.New("ldap: could not retrieve message")) |
||||||
|
} |
||||||
|
|
||||||
|
if l.Debug { |
||||||
|
if err := addLDAPDescriptions(packet); err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
ber.PrintPacket(packet) |
||||||
|
} |
||||||
|
|
||||||
|
if packet.Children[1].Tag == ApplicationModifyResponse { |
||||||
|
resultCode, resultDescription := getLDAPResultCode(packet) |
||||||
|
if resultCode != 0 { |
||||||
|
return NewError(resultCode, errors.New(resultDescription)) |
||||||
|
} |
||||||
|
} else { |
||||||
|
log.Printf("Unexpected Response: %d", packet.Children[1].Tag) |
||||||
|
} |
||||||
|
|
||||||
|
l.Debug.Printf("%d: returning", messageID) |
||||||
|
return nil |
||||||
|
} |
@ -0,0 +1,350 @@ |
|||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
//
|
||||||
|
// File contains Search functionality
|
||||||
|
//
|
||||||
|
// https://tools.ietf.org/html/rfc4511
|
||||||
|
//
|
||||||
|
// SearchRequest ::= [APPLICATION 3] SEQUENCE {
|
||||||
|
// baseObject LDAPDN,
|
||||||
|
// scope ENUMERATED {
|
||||||
|
// baseObject (0),
|
||||||
|
// singleLevel (1),
|
||||||
|
// wholeSubtree (2),
|
||||||
|
// ... },
|
||||||
|
// derefAliases ENUMERATED {
|
||||||
|
// neverDerefAliases (0),
|
||||||
|
// derefInSearching (1),
|
||||||
|
// derefFindingBaseObj (2),
|
||||||
|
// derefAlways (3) },
|
||||||
|
// sizeLimit INTEGER (0 .. maxInt),
|
||||||
|
// timeLimit INTEGER (0 .. maxInt),
|
||||||
|
// typesOnly BOOLEAN,
|
||||||
|
// filter Filter,
|
||||||
|
// attributes AttributeSelection }
|
||||||
|
//
|
||||||
|
// AttributeSelection ::= SEQUENCE OF selector LDAPString
|
||||||
|
// -- The LDAPString is constrained to
|
||||||
|
// -- <attributeSelector> in Section 4.5.1.8
|
||||||
|
//
|
||||||
|
// Filter ::= CHOICE {
|
||||||
|
// and [0] SET SIZE (1..MAX) OF filter Filter,
|
||||||
|
// or [1] SET SIZE (1..MAX) OF filter Filter,
|
||||||
|
// not [2] Filter,
|
||||||
|
// equalityMatch [3] AttributeValueAssertion,
|
||||||
|
// substrings [4] SubstringFilter,
|
||||||
|
// greaterOrEqual [5] AttributeValueAssertion,
|
||||||
|
// lessOrEqual [6] AttributeValueAssertion,
|
||||||
|
// present [7] AttributeDescription,
|
||||||
|
// approxMatch [8] AttributeValueAssertion,
|
||||||
|
// extensibleMatch [9] MatchingRuleAssertion,
|
||||||
|
// ... }
|
||||||
|
//
|
||||||
|
// SubstringFilter ::= SEQUENCE {
|
||||||
|
// type AttributeDescription,
|
||||||
|
// substrings SEQUENCE SIZE (1..MAX) OF substring CHOICE {
|
||||||
|
// initial [0] AssertionValue, -- can occur at most once
|
||||||
|
// any [1] AssertionValue,
|
||||||
|
// final [2] AssertionValue } -- can occur at most once
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// MatchingRuleAssertion ::= SEQUENCE {
|
||||||
|
// matchingRule [1] MatchingRuleId OPTIONAL,
|
||||||
|
// type [2] AttributeDescription OPTIONAL,
|
||||||
|
// matchValue [3] AssertionValue,
|
||||||
|
// dnAttributes [4] BOOLEAN DEFAULT FALSE }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
package ldap |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
"fmt" |
||||||
|
"strings" |
||||||
|
|
||||||
|
"github.com/gogits/gogs/modules/asn1-ber" |
||||||
|
) |
||||||
|
|
||||||
|
const ( |
||||||
|
ScopeBaseObject = 0 |
||||||
|
ScopeSingleLevel = 1 |
||||||
|
ScopeWholeSubtree = 2 |
||||||
|
) |
||||||
|
|
||||||
|
var ScopeMap = map[int]string{ |
||||||
|
ScopeBaseObject: "Base Object", |
||||||
|
ScopeSingleLevel: "Single Level", |
||||||
|
ScopeWholeSubtree: "Whole Subtree", |
||||||
|
} |
||||||
|
|
||||||
|
const ( |
||||||
|
NeverDerefAliases = 0 |
||||||
|
DerefInSearching = 1 |
||||||
|
DerefFindingBaseObj = 2 |
||||||
|
DerefAlways = 3 |
||||||
|
) |
||||||
|
|
||||||
|
var DerefMap = map[int]string{ |
||||||
|
NeverDerefAliases: "NeverDerefAliases", |
||||||
|
DerefInSearching: "DerefInSearching", |
||||||
|
DerefFindingBaseObj: "DerefFindingBaseObj", |
||||||
|
DerefAlways: "DerefAlways", |
||||||
|
} |
||||||
|
|
||||||
|
type Entry struct { |
||||||
|
DN string |
||||||
|
Attributes []*EntryAttribute |
||||||
|
} |
||||||
|
|
||||||
|
func (e *Entry) GetAttributeValues(attribute string) []string { |
||||||
|
for _, attr := range e.Attributes { |
||||||
|
if attr.Name == attribute { |
||||||
|
return attr.Values |
||||||
|
} |
||||||
|
} |
||||||
|
return []string{} |
||||||
|
} |
||||||
|
|
||||||
|
func (e *Entry) GetAttributeValue(attribute string) string { |
||||||
|
values := e.GetAttributeValues(attribute) |
||||||
|
if len(values) == 0 { |
||||||
|
return "" |
||||||
|
} |
||||||
|
return values[0] |
||||||
|
} |
||||||
|
|
||||||
|
func (e *Entry) Print() { |
||||||
|
fmt.Printf("DN: %s\n", e.DN) |
||||||
|
for _, attr := range e.Attributes { |
||||||
|
attr.Print() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func (e *Entry) PrettyPrint(indent int) { |
||||||
|
fmt.Printf("%sDN: %s\n", strings.Repeat(" ", indent), e.DN) |
||||||
|
for _, attr := range e.Attributes { |
||||||
|
attr.PrettyPrint(indent + 2) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
type EntryAttribute struct { |
||||||
|
Name string |
||||||
|
Values []string |
||||||
|
} |
||||||
|
|
||||||
|
func (e *EntryAttribute) Print() { |
||||||
|
fmt.Printf("%s: %s\n", e.Name, e.Values) |
||||||
|
} |
||||||
|
|
||||||
|
func (e *EntryAttribute) PrettyPrint(indent int) { |
||||||
|
fmt.Printf("%s%s: %s\n", strings.Repeat(" ", indent), e.Name, e.Values) |
||||||
|
} |
||||||
|
|
||||||
|
type SearchResult struct { |
||||||
|
Entries []*Entry |
||||||
|
Referrals []string |
||||||
|
Controls []Control |
||||||
|
} |
||||||
|
|
||||||
|
func (s *SearchResult) Print() { |
||||||
|
for _, entry := range s.Entries { |
||||||
|
entry.Print() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func (s *SearchResult) PrettyPrint(indent int) { |
||||||
|
for _, entry := range s.Entries { |
||||||
|
entry.PrettyPrint(indent) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
type SearchRequest struct { |
||||||
|
BaseDN string |
||||||
|
Scope int |
||||||
|
DerefAliases int |
||||||
|
SizeLimit int |
||||||
|
TimeLimit int |
||||||
|
TypesOnly bool |
||||||
|
Filter string |
||||||
|
Attributes []string |
||||||
|
Controls []Control |
||||||
|
} |
||||||
|
|
||||||
|
func (s *SearchRequest) encode() (*ber.Packet, error) { |
||||||
|
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationSearchRequest, nil, "Search Request") |
||||||
|
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, s.BaseDN, "Base DN")) |
||||||
|
request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(s.Scope), "Scope")) |
||||||
|
request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(s.DerefAliases), "Deref Aliases")) |
||||||
|
request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, uint64(s.SizeLimit), "Size Limit")) |
||||||
|
request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, uint64(s.TimeLimit), "Time Limit")) |
||||||
|
request.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, s.TypesOnly, "Types Only")) |
||||||
|
// compile and encode filter
|
||||||
|
filterPacket, err := CompileFilter(s.Filter) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
request.AppendChild(filterPacket) |
||||||
|
// encode attributes
|
||||||
|
attributesPacket := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attributes") |
||||||
|
for _, attribute := range s.Attributes { |
||||||
|
attributesPacket.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute, "Attribute")) |
||||||
|
} |
||||||
|
request.AppendChild(attributesPacket) |
||||||
|
return request, nil |
||||||
|
} |
||||||
|
|
||||||
|
func NewSearchRequest( |
||||||
|
BaseDN string, |
||||||
|
Scope, DerefAliases, SizeLimit, TimeLimit int, |
||||||
|
TypesOnly bool, |
||||||
|
Filter string, |
||||||
|
Attributes []string, |
||||||
|
Controls []Control, |
||||||
|
) *SearchRequest { |
||||||
|
return &SearchRequest{ |
||||||
|
BaseDN: BaseDN, |
||||||
|
Scope: Scope, |
||||||
|
DerefAliases: DerefAliases, |
||||||
|
SizeLimit: SizeLimit, |
||||||
|
TimeLimit: TimeLimit, |
||||||
|
TypesOnly: TypesOnly, |
||||||
|
Filter: Filter, |
||||||
|
Attributes: Attributes, |
||||||
|
Controls: Controls, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func (l *Conn) SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32) (*SearchResult, error) { |
||||||
|
if searchRequest.Controls == nil { |
||||||
|
searchRequest.Controls = make([]Control, 0) |
||||||
|
} |
||||||
|
|
||||||
|
pagingControl := NewControlPaging(pagingSize) |
||||||
|
searchRequest.Controls = append(searchRequest.Controls, pagingControl) |
||||||
|
searchResult := new(SearchResult) |
||||||
|
for { |
||||||
|
result, err := l.Search(searchRequest) |
||||||
|
l.Debug.Printf("Looking for Paging Control...") |
||||||
|
if err != nil { |
||||||
|
return searchResult, err |
||||||
|
} |
||||||
|
if result == nil { |
||||||
|
return searchResult, NewError(ErrorNetwork, errors.New("ldap: packet not received")) |
||||||
|
} |
||||||
|
|
||||||
|
for _, entry := range result.Entries { |
||||||
|
searchResult.Entries = append(searchResult.Entries, entry) |
||||||
|
} |
||||||
|
for _, referral := range result.Referrals { |
||||||
|
searchResult.Referrals = append(searchResult.Referrals, referral) |
||||||
|
} |
||||||
|
for _, control := range result.Controls { |
||||||
|
searchResult.Controls = append(searchResult.Controls, control) |
||||||
|
} |
||||||
|
|
||||||
|
l.Debug.Printf("Looking for Paging Control...") |
||||||
|
pagingResult := FindControl(result.Controls, ControlTypePaging) |
||||||
|
if pagingResult == nil { |
||||||
|
pagingControl = nil |
||||||
|
l.Debug.Printf("Could not find paging control. Breaking...") |
||||||
|
break |
||||||
|
} |
||||||
|
|
||||||
|
cookie := pagingResult.(*ControlPaging).Cookie |
||||||
|
if len(cookie) == 0 { |
||||||
|
pagingControl = nil |
||||||
|
l.Debug.Printf("Could not find cookie. Breaking...") |
||||||
|
break |
||||||
|
} |
||||||
|
pagingControl.SetCookie(cookie) |
||||||
|
} |
||||||
|
|
||||||
|
if pagingControl != nil { |
||||||
|
l.Debug.Printf("Abandoning Paging...") |
||||||
|
pagingControl.PagingSize = 0 |
||||||
|
l.Search(searchRequest) |
||||||
|
} |
||||||
|
|
||||||
|
return searchResult, nil |
||||||
|
} |
||||||
|
|
||||||
|
func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error) { |
||||||
|
messageID := l.nextMessageID() |
||||||
|
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") |
||||||
|
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID")) |
||||||
|
// encode search request
|
||||||
|
encodedSearchRequest, err := searchRequest.encode() |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
packet.AppendChild(encodedSearchRequest) |
||||||
|
// encode search controls
|
||||||
|
if searchRequest.Controls != nil { |
||||||
|
packet.AppendChild(encodeControls(searchRequest.Controls)) |
||||||
|
} |
||||||
|
|
||||||
|
l.Debug.PrintPacket(packet) |
||||||
|
|
||||||
|
channel, err := l.sendMessage(packet) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
if channel == nil { |
||||||
|
return nil, NewError(ErrorNetwork, errors.New("ldap: could not send message")) |
||||||
|
} |
||||||
|
defer l.finishMessage(messageID) |
||||||
|
|
||||||
|
result := &SearchResult{ |
||||||
|
Entries: make([]*Entry, 0), |
||||||
|
Referrals: make([]string, 0), |
||||||
|
Controls: make([]Control, 0)} |
||||||
|
|
||||||
|
foundSearchResultDone := false |
||||||
|
for !foundSearchResultDone { |
||||||
|
l.Debug.Printf("%d: waiting for response", messageID) |
||||||
|
packet = <-channel |
||||||
|
l.Debug.Printf("%d: got response %p", messageID, packet) |
||||||
|
if packet == nil { |
||||||
|
return nil, NewError(ErrorNetwork, errors.New("ldap: could not retrieve message")) |
||||||
|
} |
||||||
|
|
||||||
|
if l.Debug { |
||||||
|
if err := addLDAPDescriptions(packet); err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
ber.PrintPacket(packet) |
||||||
|
} |
||||||
|
|
||||||
|
switch packet.Children[1].Tag { |
||||||
|
case 4: |
||||||
|
entry := new(Entry) |
||||||
|
entry.DN = packet.Children[1].Children[0].Value.(string) |
||||||
|
for _, child := range packet.Children[1].Children[1].Children { |
||||||
|
attr := new(EntryAttribute) |
||||||
|
attr.Name = child.Children[0].Value.(string) |
||||||
|
for _, value := range child.Children[1].Children { |
||||||
|
attr.Values = append(attr.Values, value.Value.(string)) |
||||||
|
} |
||||||
|
entry.Attributes = append(entry.Attributes, attr) |
||||||
|
} |
||||||
|
result.Entries = append(result.Entries, entry) |
||||||
|
case 5: |
||||||
|
resultCode, resultDescription := getLDAPResultCode(packet) |
||||||
|
if resultCode != 0 { |
||||||
|
return result, NewError(resultCode, errors.New(resultDescription)) |
||||||
|
} |
||||||
|
if len(packet.Children) == 3 { |
||||||
|
for _, child := range packet.Children[2].Children { |
||||||
|
result.Controls = append(result.Controls, DecodeControl(child)) |
||||||
|
} |
||||||
|
} |
||||||
|
foundSearchResultDone = true |
||||||
|
case 19: |
||||||
|
result.Referrals = append(result.Referrals, packet.Children[1].Children[0].Value.(string)) |
||||||
|
} |
||||||
|
} |
||||||
|
l.Debug.Printf("%d: returning", messageID) |
||||||
|
return result, nil |
||||||
|
} |
@ -0,0 +1,844 @@ |
|||||||
|
package mahonia |
||||||
|
|
||||||
|
import ( |
||||||
|
"fmt" |
||||||
|
"sync" |
||||||
|
) |
||||||
|
|
||||||
|
// Converters for simple 8-bit character sets.
|
||||||
|
|
||||||
|
type eightBitInfo struct { |
||||||
|
Name string |
||||||
|
Aliases []string |
||||||
|
|
||||||
|
// the character used for characters that can't be converted
|
||||||
|
SubstitutionChar byte |
||||||
|
|
||||||
|
// a string containing all 256 characters, in order.
|
||||||
|
Repertoire string |
||||||
|
|
||||||
|
// used to synchronize unpacking Repertoire into the conversion tables
|
||||||
|
once *sync.Once |
||||||
|
|
||||||
|
// true if the first 128 characters are the same as US-ASCII
|
||||||
|
asciiCompatible bool |
||||||
|
|
||||||
|
byte2char [256]rune |
||||||
|
char2byte map[rune]byte |
||||||
|
} |
||||||
|
|
||||||
|
const asciiRepertoire = "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f" |
||||||
|
|
||||||
|
func (info *eightBitInfo) register() { |
||||||
|
var cs Charset |
||||||
|
cs.Name = info.Name |
||||||
|
cs.Aliases = info.Aliases |
||||||
|
|
||||||
|
info.once = new(sync.Once) |
||||||
|
|
||||||
|
cs.NewDecoder = func() Decoder { |
||||||
|
info.once.Do(func() { info.unpack() }) |
||||||
|
|
||||||
|
return func(p []byte) (c rune, size int, status Status) { |
||||||
|
if len(p) == 0 { |
||||||
|
status = NO_ROOM |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
c = info.byte2char[p[0]] |
||||||
|
|
||||||
|
if c == 0xfffd { |
||||||
|
status = INVALID_CHAR |
||||||
|
} else { |
||||||
|
status = SUCCESS |
||||||
|
} |
||||||
|
|
||||||
|
size = 1 |
||||||
|
return |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
cs.NewEncoder = func() Encoder { |
||||||
|
info.once.Do(func() { info.unpack() }) |
||||||
|
|
||||||
|
return func(p []byte, c rune) (size int, status Status) { |
||||||
|
if len(p) == 0 { |
||||||
|
status = NO_ROOM |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
if c < 128 && info.asciiCompatible { |
||||||
|
p[0] = byte(c) |
||||||
|
return 1, SUCCESS |
||||||
|
} |
||||||
|
|
||||||
|
b, ok := info.char2byte[c] |
||||||
|
if !ok { |
||||||
|
b = info.SubstitutionChar |
||||||
|
status = INVALID_CHAR |
||||||
|
} else { |
||||||
|
status = SUCCESS |
||||||
|
} |
||||||
|
p[0] = b |
||||||
|
size = 1 |
||||||
|
return |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
RegisterCharset(&cs) |
||||||
|
} |
||||||
|
|
||||||
|
func (info *eightBitInfo) unpack() { |
||||||
|
info.asciiCompatible = info.Repertoire[:128] == asciiRepertoire |
||||||
|
|
||||||
|
info.char2byte = make(map[rune]byte, 256) |
||||||
|
i := 0 |
||||||
|
for _, c := range info.Repertoire { |
||||||
|
info.byte2char[i] = c |
||||||
|
if c != 0xfffd { |
||||||
|
info.char2byte[c] = byte(i) |
||||||
|
} |
||||||
|
i++ |
||||||
|
} |
||||||
|
if i != 256 { |
||||||
|
panic(fmt.Errorf("%s has only %d characters", info.Name, i)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func init() { |
||||||
|
for i := 0; i < len(eightBitCharsets); i++ { |
||||||
|
eightBitCharsets[i].register() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
var eightBitCharsets = []eightBitInfo{ |
||||||
|
{ |
||||||
|
Name: "ISO-8859-2", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0104\u02d8\u0141\u00a4\u013d\u015a\u00a7\u00a8\u0160\u015e\u0164\u0179\u00ad\u017d\u017b\u00b0\u0105\u02db\u0142\u00b4\u013e\u015b\u02c7\u00b8\u0161\u015f\u0165\u017a\u02dd\u017e\u017c\u0154\u00c1\u00c2\u0102\u00c4\u0139\u0106\u00c7\u010c\u00c9\u0118\u00cb\u011a\u00cd\u00ce\u010e\u0110\u0143\u0147\u00d3\u00d4\u0150\u00d6\u00d7\u0158\u016e\u00da\u0170\u00dc\u00dd\u0162\u00df\u0155\u00e1\u00e2\u0103\u00e4\u013a\u0107\u00e7\u010d\u00e9\u0119\u00eb\u011b\u00ed\u00ee\u010f\u0111\u0144\u0148\u00f3\u00f4\u0151\u00f6\u00f7\u0159\u016f\u00fa\u0171\u00fc\u00fd\u0163\u02d9", |
||||||
|
Aliases: []string{"ISO_8859-2:1987", "iso-ir-101", "latin2", "l2", "csISOLatin2"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ISO-8859-3", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0126\u02d8\u00a3\u00a4\ufffd\u0124\u00a7\u00a8\u0130\u015e\u011e\u0134\u00ad\ufffd\u017b\u00b0\u0127\u00b2\u00b3\u00b4\u00b5\u0125\u00b7\u00b8\u0131\u015f\u011f\u0135\u00bd\ufffd\u017c\u00c0\u00c1\u00c2\ufffd\u00c4\u010a\u0108\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\ufffd\u00d1\u00d2\u00d3\u00d4\u0120\u00d6\u00d7\u011c\u00d9\u00da\u00db\u00dc\u016c\u015c\u00df\u00e0\u00e1\u00e2\ufffd\u00e4\u010b\u0109\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\ufffd\u00f1\u00f2\u00f3\u00f4\u0121\u00f6\u00f7\u011d\u00f9\u00fa\u00fb\u00fc\u016d\u015d\u02d9", |
||||||
|
Aliases: []string{"ISO_8859-3:1988", "iso-ir-109", "latin3", "l3", "csISOLatin3"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ISO-8859-4", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0104\u0138\u0156\u00a4\u0128\u013b\u00a7\u00a8\u0160\u0112\u0122\u0166\u00ad\u017d\u00af\u00b0\u0105\u02db\u0157\u00b4\u0129\u013c\u02c7\u00b8\u0161\u0113\u0123\u0167\u014a\u017e\u014b\u0100\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u012e\u010c\u00c9\u0118\u00cb\u0116\u00cd\u00ce\u012a\u0110\u0145\u014c\u0136\u00d4\u00d5\u00d6\u00d7\u00d8\u0172\u00da\u00db\u00dc\u0168\u016a\u00df\u0101\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u012f\u010d\u00e9\u0119\u00eb\u0117\u00ed\u00ee\u012b\u0111\u0146\u014d\u0137\u00f4\u00f5\u00f6\u00f7\u00f8\u0173\u00fa\u00fb\u00fc\u0169\u016b\u02d9", |
||||||
|
Aliases: []string{"ISO_8859-4:1988", "iso-ir-110", "latin4", "l4", "csISOLatin4"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ISO-8859-5", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0401\u0402\u0403\u0404\u0405\u0406\u0407\u0408\u0409\u040a\u040b\u040c\u00ad\u040e\u040f\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u2116\u0451\u0452\u0453\u0454\u0455\u0456\u0457\u0458\u0459\u045a\u045b\u045c\u00a7\u045e\u045f", |
||||||
|
Aliases: []string{"ISO_8859-5:1988", "iso-ir-144", "cyrillic", "csISOLatinCyrillic"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ISO-8859-6", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\ufffd\ufffd\ufffd\u00a4\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u060c\u00ad\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u061b\ufffd\ufffd\ufffd\u061f\ufffd\u0621\u0622\u0623\u0624\u0625\u0626\u0627\u0628\u0629\u062a\u062b\u062c\u062d\u062e\u062f\u0630\u0631\u0632\u0633\u0634\u0635\u0636\u0637\u0638\u0639\u063a\ufffd\ufffd\ufffd\ufffd\ufffd\u0640\u0641\u0642\u0643\u0644\u0645\u0646\u0647\u0648\u0649\u064a\u064b\u064c\u064d\u064e\u064f\u0650\u0651\u0652\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd", |
||||||
|
Aliases: []string{"ISO_8859-6:1987", "iso-ir-127", "ECMA-114", "ASMO-708", "arabic", "csISOLatinArabic"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ISO-8859-7", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u2018\u2019\u00a3\u20ac\u20af\u00a6\u00a7\u00a8\u00a9\u037a\u00ab\u00ac\u00ad\ufffd\u2015\u00b0\u00b1\u00b2\u00b3\u0384\u0385\u0386\u00b7\u0388\u0389\u038a\u00bb\u038c\u00bd\u038e\u038f\u0390\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\ufffd\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab\u03ac\u03ad\u03ae\u03af\u03b0\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\u03ca\u03cb\u03cc\u03cd\u03ce\ufffd", |
||||||
|
Aliases: []string{"ISO_8859-7:2003", "iso-ir-126", "ELOT_928", "ECMA-118", "greek", "greek8", "csISOLatinGreek"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ISO-8859-8", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\ufffd\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00d7\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00f7\u00bb\u00bc\u00bd\u00be\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u2017\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\ufffd\ufffd\u200e\u200f\ufffd", |
||||||
|
Aliases: []string{"ISO_8859-8:1999", "iso-ir-138", "hebrew", "csISOLatinHebrew"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ISO-8859-9", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u011e\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u0130\u015e\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u011f\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u0131\u015f\u00ff", |
||||||
|
Aliases: []string{"ISO_8859-9:1999", "iso-ir-148", "latin5", "l5", "csISOLatin5"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ISO-8859-10", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0104\u0112\u0122\u012a\u0128\u0136\u00a7\u013b\u0110\u0160\u0166\u017d\u00ad\u016a\u014a\u00b0\u0105\u0113\u0123\u012b\u0129\u0137\u00b7\u013c\u0111\u0161\u0167\u017e\u2015\u016b\u014b\u0100\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u012e\u010c\u00c9\u0118\u00cb\u0116\u00cd\u00ce\u00cf\u00d0\u0145\u014c\u00d3\u00d4\u00d5\u00d6\u0168\u00d8\u0172\u00da\u00db\u00dc\u00dd\u00de\u00df\u0101\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u012f\u010d\u00e9\u0119\u00eb\u0117\u00ed\u00ee\u00ef\u00f0\u0146\u014d\u00f3\u00f4\u00f5\u00f6\u0169\u00f8\u0173\u00fa\u00fb\u00fc\u00fd\u00fe\u0138", |
||||||
|
Aliases: []string{"iso_8859-10:1992", "l6", "iso-ir-157", "latin6", "csISOLatin6"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ISO-8859-11", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e2f\u0e30\u0e31\u0e32\u0e33\u0e34\u0e35\u0e36\u0e37\u0e38\u0e39\u0e3a\ufffd\ufffd\ufffd\ufffd\u0e3f\u0e40\u0e41\u0e42\u0e43\u0e44\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a\u0e4b\u0e4c\u0e4d\u0e4e\u0e4f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e5a\u0e5b\ufffd\ufffd\ufffd\ufffd", |
||||||
|
Aliases: []string{"iso_8859-11:2001", "Latin/Thai", "TIS-620"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ISO-8859-13", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u201d\u00a2\u00a3\u00a4\u201e\u00a6\u00a7\u00d8\u00a9\u0156\u00ab\u00ac\u00ad\u00ae\u00c6\u00b0\u00b1\u00b2\u00b3\u201c\u00b5\u00b6\u00b7\u00f8\u00b9\u0157\u00bb\u00bc\u00bd\u00be\u00e6\u0104\u012e\u0100\u0106\u00c4\u00c5\u0118\u0112\u010c\u00c9\u0179\u0116\u0122\u0136\u012a\u013b\u0160\u0143\u0145\u00d3\u014c\u00d5\u00d6\u00d7\u0172\u0141\u015a\u016a\u00dc\u017b\u017d\u00df\u0105\u012f\u0101\u0107\u00e4\u00e5\u0119\u0113\u010d\u00e9\u017a\u0117\u0123\u0137\u012b\u013c\u0161\u0144\u0146\u00f3\u014d\u00f5\u00f6\u00f7\u0173\u0142\u015b\u016b\u00fc\u017c\u017e\u2019", |
||||||
|
Aliases: []string{"latin7", "Baltic Rim"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ISO-8859-14", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u1e02\u1e03\u00a3\u010a\u010b\u1e0a\u00a7\u1e80\u00a9\u1e82\u1e0b\u1ef2\u00ad\u00ae\u0178\u1e1e\u1e1f\u0120\u0121\u1e40\u1e41\u00b6\u1e56\u1e81\u1e57\u1e83\u1e60\u1ef3\u1e84\u1e85\u1e61\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u0174\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u1e6a\u00d8\u00d9\u00da\u00db\u00dc\u00dd\u0176\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u0175\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u1e6b\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u0177\u00ff", |
||||||
|
Aliases: []string{"iso-ir-199", "ISO_8859-14:1998", "latin8", "iso-celtic", "l8"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ISO-8859-15", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u00a1\u00a2\u00a3\u20ac\u00a5\u0160\u00a7\u0161\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u017d\u00b5\u00b6\u00b7\u017e\u00b9\u00ba\u00bb\u0152\u0153\u0178\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u00d0\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u00dd\u00de\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u00f0\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u00fe\u00ff", |
||||||
|
Aliases: []string{"Latin-9"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ISO-8859-16", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0104\u0105\u0141\u20ac\u201e\u0160\u00a7\u0161\u00a9\u0218\u00ab\u0179\u00ad\u017a\u017b\u00b0\u00b1\u010c\u0142\u017d\u201d\u00b6\u00b7\u017e\u010d\u0219\u00bb\u0152\u0153\u0178\u017c\u00c0\u00c1\u00c2\u0102\u00c4\u0106\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u0110\u0143\u00d2\u00d3\u00d4\u0150\u00d6\u015a\u0170\u00d9\u00da\u00db\u00dc\u0118\u021a\u00df\u00e0\u00e1\u00e2\u0103\u00e4\u0107\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u0111\u0144\u00f2\u00f3\u00f4\u0151\u00f6\u015b\u0171\u00f9\u00fa\u00fb\u00fc\u0119\u021b\u00ff", |
||||||
|
Aliases: []string{"iso-ir-226", "ISO_8859-16:2001", "latin10", "l10"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "macos-0_2-10.2", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c4\u00c5\u00c7\u00c9\u00d1\u00d6\u00dc\u00e1\u00e0\u00e2\u00e4\u00e3\u00e5\u00e7\u00e9\u00e8\u00ea\u00eb\u00ed\u00ec\u00ee\u00ef\u00f1\u00f3\u00f2\u00f4\u00f6\u00f5\u00fa\u00f9\u00fb\u00fc\u2020\u00b0\u00a2\u00a3\u00a7\u2022\u00b6\u00df\u00ae\u00a9\u2122\u00b4\u00a8\u2260\u00c6\u00d8\u221e\u00b1\u2264\u2265\u00a5\u00b5\u2202\u2211\u220f\u03c0\u222b\u00aa\u00ba\u03a9\u00e6\u00f8\u00bf\u00a1\u00ac\u221a\u0192\u2248\u2206\u00ab\u00bb\u2026\u00a0\u00c0\u00c3\u00d5\u0152\u0153\u2013\u2014\u201c\u201d\u2018\u2019\u00f7\u25ca\u00ff\u0178\u2044\u20ac\u2039\u203a\ufb01\ufb02\u2021\u00b7\u201a\u201e\u2030\u00c2\u00ca\u00c1\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00d3\u00d4\uf8ff\u00d2\u00da\u00db\u00d9\u0131\u02c6\u02dc\u00af\u02d8\u02d9\u02da\u00b8\u02dd\u02db\u02c7", |
||||||
|
Aliases: []string{"macos-0_2-10.2", "macintosh", "mac", "csMacintosh", "windows-10000", "macroman"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "macos-6_2-10.4", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c4\u00b9\u00b2\u00c9\u00b3\u00d6\u00dc\u0385\u00e0\u00e2\u00e4\u0384\u00a8\u00e7\u00e9\u00e8\u00ea\u00eb\u00a3\u2122\u00ee\u00ef\u2022\u00bd\u2030\u00f4\u00f6\u00a6\u20ac\u00f9\u00fb\u00fc\u2020\u0393\u0394\u0398\u039b\u039e\u03a0\u00df\u00ae\u00a9\u03a3\u03aa\u00a7\u2260\u00b0\u00b7\u0391\u00b1\u2264\u2265\u00a5\u0392\u0395\u0396\u0397\u0399\u039a\u039c\u03a6\u03ab\u03a8\u03a9\u03ac\u039d\u00ac\u039f\u03a1\u2248\u03a4\u00ab\u00bb\u2026\u00a0\u03a5\u03a7\u0386\u0388\u0153\u2013\u2015\u201c\u201d\u2018\u2019\u00f7\u0389\u038a\u038c\u038e\u03ad\u03ae\u03af\u03cc\u038f\u03cd\u03b1\u03b2\u03c8\u03b4\u03b5\u03c6\u03b3\u03b7\u03b9\u03be\u03ba\u03bb\u03bc\u03bd\u03bf\u03c0\u03ce\u03c1\u03c3\u03c4\u03b8\u03c9\u03c2\u03c7\u03c5\u03b6\u03ca\u03cb\u0390\u03b0\u00ad", |
||||||
|
Aliases: []string{"macos-6_2-10.4", "x-mac-greek", "windows-10006", "macgr"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "macos-7_3-10.2", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u2020\u00b0\u0490\u00a3\u00a7\u2022\u00b6\u0406\u00ae\u00a9\u2122\u0402\u0452\u2260\u0403\u0453\u221e\u00b1\u2264\u2265\u0456\u00b5\u0491\u0408\u0404\u0454\u0407\u0457\u0409\u0459\u040a\u045a\u0458\u0405\u00ac\u221a\u0192\u2248\u2206\u00ab\u00bb\u2026\u00a0\u040b\u045b\u040c\u045c\u0455\u2013\u2014\u201c\u201d\u2018\u2019\u00f7\u201e\u040e\u045e\u040f\u045f\u2116\u0401\u0451\u044f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u20ac", |
||||||
|
Aliases: []string{"macos-7_3-10.2", "x-mac-cyrillic", "windows-10007", "mac-cyrillic", "maccy"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "macos-29-10.2", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c4\u0100\u0101\u00c9\u0104\u00d6\u00dc\u00e1\u0105\u010c\u00e4\u010d\u0106\u0107\u00e9\u0179\u017a\u010e\u00ed\u010f\u0112\u0113\u0116\u00f3\u0117\u00f4\u00f6\u00f5\u00fa\u011a\u011b\u00fc\u2020\u00b0\u0118\u00a3\u00a7\u2022\u00b6\u00df\u00ae\u00a9\u2122\u0119\u00a8\u2260\u0123\u012e\u012f\u012a\u2264\u2265\u012b\u0136\u2202\u2211\u0142\u013b\u013c\u013d\u013e\u0139\u013a\u0145\u0146\u0143\u00ac\u221a\u0144\u0147\u2206\u00ab\u00bb\u2026\u00a0\u0148\u0150\u00d5\u0151\u014c\u2013\u2014\u201c\u201d\u2018\u2019\u00f7\u25ca\u014d\u0154\u0155\u0158\u2039\u203a\u0159\u0156\u0157\u0160\u201a\u201e\u0161\u015a\u015b\u00c1\u0164\u0165\u00cd\u017d\u017e\u016a\u00d3\u00d4\u016b\u016e\u00da\u016f\u0170\u0171\u0172\u0173\u00dd\u00fd\u0137\u017b\u0141\u017c\u0122\u02c7", |
||||||
|
Aliases: []string{"macos-29-10.2", "x-mac-centraleurroman", "windows-10029", "x-mac-ce", "macce", "maccentraleurope"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "macos-35-10.2", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c4\u00c5\u00c7\u00c9\u00d1\u00d6\u00dc\u00e1\u00e0\u00e2\u00e4\u00e3\u00e5\u00e7\u00e9\u00e8\u00ea\u00eb\u00ed\u00ec\u00ee\u00ef\u00f1\u00f3\u00f2\u00f4\u00f6\u00f5\u00fa\u00f9\u00fb\u00fc\u2020\u00b0\u00a2\u00a3\u00a7\u2022\u00b6\u00df\u00ae\u00a9\u2122\u00b4\u00a8\u2260\u00c6\u00d8\u221e\u00b1\u2264\u2265\u00a5\u00b5\u2202\u2211\u220f\u03c0\u222b\u00aa\u00ba\u03a9\u00e6\u00f8\u00bf\u00a1\u00ac\u221a\u0192\u2248\u2206\u00ab\u00bb\u2026\u00a0\u00c0\u00c3\u00d5\u0152\u0153\u2013\u2014\u201c\u201d\u2018\u2019\u00f7\u25ca\u00ff\u0178\u011e\u011f\u0130\u0131\u015e\u015f\u2021\u00b7\u201a\u201e\u2030\u00c2\u00ca\u00c1\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00d3\u00d4\uf8ff\u00d2\u00da\u00db\u00d9\uf8a0\u02c6\u02dc\u00af\u02d8\u02d9\u02da\u00b8\u02dd\u02db\u02c7", |
||||||
|
Aliases: []string{"macos-35-10.2", "x-mac-turkish", "windows-10081", "mactr"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "windows-1250", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\ufffd\u201e\u2026\u2020\u2021\ufffd\u2030\u0160\u2039\u015a\u0164\u017d\u0179\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\ufffd\u2122\u0161\u203a\u015b\u0165\u017e\u017a\u00a0\u02c7\u02d8\u0141\u00a4\u0104\u00a6\u00a7\u00a8\u00a9\u015e\u00ab\u00ac\u00ad\u00ae\u017b\u00b0\u00b1\u02db\u0142\u00b4\u00b5\u00b6\u00b7\u00b8\u0105\u015f\u00bb\u013d\u02dd\u013e\u017c\u0154\u00c1\u00c2\u0102\u00c4\u0139\u0106\u00c7\u010c\u00c9\u0118\u00cb\u011a\u00cd\u00ce\u010e\u0110\u0143\u0147\u00d3\u00d4\u0150\u00d6\u00d7\u0158\u016e\u00da\u0170\u00dc\u00dd\u0162\u00df\u0155\u00e1\u00e2\u0103\u00e4\u013a\u0107\u00e7\u010d\u00e9\u0119\u00eb\u011b\u00ed\u00ee\u010f\u0111\u0144\u0148\u00f3\u00f4\u0151\u00f6\u00f7\u0159\u016f\u00fa\u0171\u00fc\u00fd\u0163\u02d9", |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "windows-1251", |
||||||
|
Aliases: []string{"CP1251"}, |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0402\u0403\u201a\u0453\u201e\u2026\u2020\u2021\u20ac\u2030\u0409\u2039\u040a\u040c\u040b\u040f\u0452\u2018\u2019\u201c\u201d\u2022\u2013\u2014\ufffd\u2122\u0459\u203a\u045a\u045c\u045b\u045f\u00a0\u040e\u045e\u0408\u00a4\u0490\u00a6\u00a7\u0401\u00a9\u0404\u00ab\u00ac\u00ad\u00ae\u0407\u00b0\u00b1\u0406\u0456\u0491\u00b5\u00b6\u00b7\u0451\u2116\u0454\u00bb\u0458\u0405\u0455\u0457\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f", |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "windows-1252", |
||||||
|
Aliases: []string{"cp1252"}, |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\u0160\u2039\u0152\ufffd\u017d\ufffd\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u02dc\u2122\u0161\u203a\u0153\ufffd\u017e\u0178\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u00d0\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u00dd\u00de\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u00f0\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u00fe\u00ff", |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "windows-1253", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\u0192\u201e\u2026\u2020\u2021\ufffd\u2030\ufffd\u2039\ufffd\ufffd\ufffd\ufffd\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\ufffd\u2122\ufffd\u203a\ufffd\ufffd\ufffd\ufffd\u00a0\u0385\u0386\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\ufffd\u00ab\u00ac\u00ad\u00ae\u2015\u00b0\u00b1\u00b2\u00b3\u0384\u00b5\u00b6\u00b7\u0388\u0389\u038a\u00bb\u038c\u00bd\u038e\u038f\u0390\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\ufffd\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab\u03ac\u03ad\u03ae\u03af\u03b0\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\u03ca\u03cb\u03cc\u03cd\u03ce\ufffd", |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "windows-1254", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\u0160\u2039\u0152\ufffd\ufffd\ufffd\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u02dc\u2122\u0161\u203a\u0153\ufffd\ufffd\u0178\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u011e\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u0130\u015e\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u011f\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u0131\u015f\u00ff", |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "windows-1255", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\ufffd\u2039\ufffd\ufffd\ufffd\ufffd\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u02dc\u2122\ufffd\u203a\ufffd\ufffd\ufffd\ufffd\u00a0\u00a1\u00a2\u00a3\u20aa\u00a5\u00a6\u00a7\u00a8\u00a9\u00d7\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00f7\u00bb\u00bc\u00bd\u00be\u00bf\u05b0\u05b1\u05b2\u05b3\u05b4\u05b5\u05b6\u05b7\u05b8\u05b9\ufffd\u05bb\u05bc\u05bd\u05be\u05bf\u05c0\u05c1\u05c2\u05c3\u05f0\u05f1\u05f2\u05f3\u05f4\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\ufffd\ufffd\u200e\u200f\ufffd", |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "windows-1256", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\u067e\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\u0679\u2039\u0152\u0686\u0698\u0688\u06af\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u06a9\u2122\u0691\u203a\u0153\u200c\u200d\u06ba\u00a0\u060c\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u06be\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u061b\u00bb\u00bc\u00bd\u00be\u061f\u06c1\u0621\u0622\u0623\u0624\u0625\u0626\u0627\u0628\u0629\u062a\u062b\u062c\u062d\u062e\u062f\u0630\u0631\u0632\u0633\u0634\u0635\u0636\u00d7\u0637\u0638\u0639\u063a\u0640\u0641\u0642\u0643\u00e0\u0644\u00e2\u0645\u0646\u0647\u0648\u00e7\u00e8\u00e9\u00ea\u00eb\u0649\u064a\u00ee\u00ef\u064b\u064c\u064d\u064e\u00f4\u064f\u0650\u00f7\u0651\u00f9\u0652\u00fb\u00fc\u200e\u200f\u06d2", |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "windows-1257", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\ufffd\u201e\u2026\u2020\u2021\ufffd\u2030\ufffd\u2039\ufffd\u00a8\u02c7\u00b8\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\ufffd\u2122\ufffd\u203a\ufffd\u00af\u02db\ufffd\u00a0\ufffd\u00a2\u00a3\u00a4\ufffd\u00a6\u00a7\u00d8\u00a9\u0156\u00ab\u00ac\u00ad\u00ae\u00c6\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00f8\u00b9\u0157\u00bb\u00bc\u00bd\u00be\u00e6\u0104\u012e\u0100\u0106\u00c4\u00c5\u0118\u0112\u010c\u00c9\u0179\u0116\u0122\u0136\u012a\u013b\u0160\u0143\u0145\u00d3\u014c\u00d5\u00d6\u00d7\u0172\u0141\u015a\u016a\u00dc\u017b\u017d\u00df\u0105\u012f\u0101\u0107\u00e4\u00e5\u0119\u0113\u010d\u00e9\u017a\u0117\u0123\u0137\u012b\u013c\u0161\u0144\u0146\u00f3\u014d\u00f5\u00f6\u00f7\u0173\u0142\u015b\u016b\u00fc\u017c\u017e\u02d9", |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "windows-1258", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\ufffd\u2039\u0152\ufffd\ufffd\ufffd\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u02dc\u2122\ufffd\u203a\u0153\ufffd\ufffd\u0178\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u0102\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u0300\u00cd\u00ce\u00cf\u0110\u00d1\u0309\u00d3\u00d4\u01a0\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u01af\u0303\u00df\u00e0\u00e1\u00e2\u0103\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u0301\u00ed\u00ee\u00ef\u0111\u00f1\u0323\u00f3\u00f4\u01a1\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u01b0\u20ab\u00ff", |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "windows-874", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\ufffd\ufffd\ufffd\u2026\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u00a0\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e2f\u0e30\u0e31\u0e32\u0e33\u0e34\u0e35\u0e36\u0e37\u0e38\u0e39\u0e3a\ufffd\ufffd\ufffd\ufffd\u0e3f\u0e40\u0e41\u0e42\u0e43\u0e44\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a\u0e4b\u0e4c\u0e4d\u0e4e\u0e4f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e5a\u0e5b\ufffd\ufffd\ufffd\ufffd", |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "IBM037", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00a2.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df!$*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5~stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae^\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u00af\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"cp037", "ebcdic-cp-us", "ebcdic-cp-ca", "ebcdic-cp-wt", "ebcdic-cp-nl", "csIBM037"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-273_P100-1995", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2{\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00c4.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec~\u00dc$*);^-/\u00c2[\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00f6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#\u00a7'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5\u00dfstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9@\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e4ABCDEFGHI\u00ad\u00f4\u00a6\u00f2\u00f3\u00f5\u00fcJKLMNOPQR\u00b9\u00fb}\u00f9\u00fa\u00ff\u00d6\u00f7STUVWXYZ\u00b2\u00d4\\\u00d2\u00d3\u00d50123456789\u00b3\u00db]\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-273_P100-1995", "ibm-273", "IBM273", "CP273", "csIBM273", "ebcdic-de", "273"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-277_P100-1995", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3}\u00e7\u00f1#.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u00a4\u00c5*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3$\u00c7\u00d1\u00f8,%_>?\u00a6\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:\u00c6\u00d8'=\"@abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba{\u00b8[]\u00b5\u00fcstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e6ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5\u00e5JKLMNOPQR\u00b9\u00fb~\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-277_P100-1995", "ibm-277", "IBM277", "cp277", "EBCDIC-CP-DK", "EBCDIC-CP-NO", "csIBM277", "ebcdic-dk", "277"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-278_P100-1995", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2{\u00e0\u00e1\u00e3}\u00e7\u00f1\u00a7.<(+!&`\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u00a4\u00c5*);^-/\u00c2#\u00c0\u00c1\u00c3$\u00c7\u00d1\u00f6,%_>?\u00f8\\\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00e9:\u00c4\u00d6'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6]\u00b5\u00fcstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9[\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e4ABCDEFGHI\u00ad\u00f4\u00a6\u00f2\u00f3\u00f5\u00e5JKLMNOPQR\u00b9\u00fb~\u00f9\u00fa\u00ff\u00c9\u00f7STUVWXYZ\u00b2\u00d4@\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-278_P100-1995", "ibm-278", "IBM278", "cp278", "ebcdic-cp-fi", "ebcdic-cp-se", "csIBM278", "ebcdic-sv", "278"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-280_P100-1995", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4{\u00e1\u00e3\u00e5\\\u00f1\u00b0.<(+!&]\u00ea\u00eb}\u00ed\u00ee\u00ef~\u00df\u00e9$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00f2,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00f9:\u00a3\u00a7'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1[jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5\u00ecstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2#\u00a5\u00b7\u00a9@\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e0ABCDEFGHI\u00ad\u00f4\u00f6\u00a6\u00f3\u00f5\u00e8JKLMNOPQR\u00b9\u00fb\u00fc`\u00fa\u00ff\u00e7\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-280_P100-1995", "ibm-280", "IBM280", "CP280", "ebcdic-cp-it", "csIBM280", "280"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-284_P100-1995", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00a6[.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df]$*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7#\u00f1,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:\u00d1@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5\u00a8stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be^!\u00af~\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-284_P100-1995", "ibm-284", "IBM284", "CP284", "ebcdic-cp-es", "csIBM284", "cpibm284", "284"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-285_P100-1995", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1$.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df!\u00a3*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5\u00afstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2[\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be^]~\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-285_P100-1995", "ibm-285", "IBM285", "CP285", "ebcdic-cp-gb", "csIBM285", "cpibm285", "ebcdic-gb", "285"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-290_P100-1995", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \uff61\uff62\uff63\uff64\uff65\uff66\uff67\uff68\uff69\u00a3.<(+|&\uff6a\uff6b\uff6c\uff6d\uff6e\uff6f\ufffd\uff70\ufffd!\u00a5*);\u00ac-/abcdefgh\ufffd,%_>?[ijklmnop`:#@'=\"]\uff71\uff72\uff73\uff74\uff75\uff76\uff77\uff78\uff79\uff7aq\uff7b\uff7c\uff7d\uff7e\uff7f\uff80\uff81\uff82\uff83\uff84\uff85\uff86\uff87\uff88\uff89r\ufffd\uff8a\uff8b\uff8c~\u203e\uff8d\uff8e\uff8f\uff90\uff91\uff92\uff93\uff94\uff95s\uff96\uff97\uff98\uff99^\u00a2\\tuvwxyz\uff9a\uff9b\uff9c\uff9d\uff9e\uff9f{ABCDEFGHI\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd}JKLMNOPQR\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd$\ufffdSTUVWXYZ\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\ufffd\ufffd\ufffd\ufffd\ufffd\u009f", |
||||||
|
Aliases: []string{"ibm-290_P100-1995", "ibm-290", "IBM290", "cp290", "EBCDIC-JP-kana", "csIBM290"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-297_P100-1995", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4@\u00e1\u00e3\u00e5\\\u00f1\u00b0.<(+!&{\u00ea\u00eb}\u00ed\u00ee\u00ef\u00ec\u00df\u00a7$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00f9,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00b5:\u00a3\u00e0'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1[jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4`\u00a8stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2#\u00a5\u00b7\u00a9]\u00b6\u00bc\u00bd\u00be\u00ac|\u00af~\u00b4\u00d7\u00e9ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5\u00e8JKLMNOPQR\u00b9\u00fb\u00fc\u00a6\u00fa\u00ff\u00e7\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-297_P100-1995", "ibm-297", "IBM297", "cp297", "ebcdic-cp-fr", "csIBM297", "cpibm297", "297"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-420_X120-1999", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0651\ufe7d\u0640\u200b\u0621\u0622\ufe82\u0623\u00a2.<(+|&\ufe84\u0624\ufffd\ufffd\u0626\u0627\ufe8e\u0628\ufe91!$*);\u00ac-/\u0629\u062a\ufe97\u062b\ufe9b\u062c\ufe9f\u062d\u00a6,%_>?\ufea3\u062e\ufea7\u062f\u0630\u0631\u0632\u0633\ufeb3\u060c:#@'=\"\u0634abcdefghi\ufeb7\u0635\ufebb\u0636\ufebf\u0637\u0638jklmnopqr\u0639\ufeca\ufecb\ufecc\u063a\ufece\ufecf\u00f7stuvwxyz\ufed0\u0641\ufed3\u0642\ufed7\u0643\ufedb\u0644\ufef5\ufef6\ufef7\ufef8\ufffd\ufffd\ufefb\ufefc\ufedf\u0645\ufee3\u0646\ufee7\u0647\u061bABCDEFGHI\u00ad\ufeeb\ufffd\ufeec\ufffd\u0648\u061fJKLMNOPQR\u0649\ufef0\u064a\ufef2\ufef3\u0660\u00d7\ufffdSTUVWXYZ\u0661\u0662\ufffd\u0663\u0664\u06650123456789\ufffd\u0666\u0667\u0668\u0669\u009f", |
||||||
|
Aliases: []string{"ibm-420_X120-1999", "ibm-420", "IBM420", "cp420", "ebcdic-cp-ar1", "csIBM420", "420"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "IBM424", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u00a2.<(+|&\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1!$*);\u00ac-/\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u00a6,%_>?\ufffd\u05ea\ufffd\ufffd\u00a0\ufffd\ufffd\ufffd\u2017`:#@'=\"\ufffdabcdefghi\u00ab\u00bb\ufffd\ufffd\ufffd\u00b1\u00b0jklmnopqr\ufffd\ufffd\ufffd\u00b8\ufffd\u00a4\u00b5~stuvwxyz\ufffd\ufffd\ufffd\ufffd\ufffd\u00ae^\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u00af\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\ufffd\ufffd\ufffd\ufffd\ufffd}JKLMNOPQR\u00b9\ufffd\ufffd\ufffd\ufffd\ufffd\\\u00f7STUVWXYZ\u00b2\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\u00b3\ufffd\ufffd\ufffd\ufffd\u009f", |
||||||
|
Aliases: []string{"cp424", "ebcdic-cp-he", "csIBM424"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "IBM437", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00a2\u00a3\u00a5\u20a7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u2310\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u00b5\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0", |
||||||
|
Aliases: []string{"cp437", "437", "csPC8CodePage437"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "IBM500", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1[.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df]$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5~stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"CP500", "ebcdic-cp-be", "ebcdic-cp-ch", "csIBM500"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-720_P100-1997", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\ufffd\ufffd\u00e9\u00e2\ufffd\u00e0\ufffd\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\ufffd\ufffd\ufffd\ufffd\u0651\u0652\u00f4\u00a4\u0640\u00fb\u00f9\u0621\u0622\u0623\u0624\u00a3\u0625\u0626\u0627\u0628\u0629\u062a\u062b\u062c\u062d\u062e\u062f\u0630\u0631\u0632\u0633\u0634\u0635\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u0636\u0637\u0638\u0639\u063a\u0641\u00b5\u0642\u0643\u0644\u0645\u0646\u0647\u0648\u0649\u064a\u2261\u064b\u064c\u064d\u064e\u064f\u0650\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0", |
||||||
|
Aliases: []string{"ibm-720_P100-1997", "ibm-720", "windows-720", "DOS-720"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "IBM737", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u03c2\u03c4\u03c5\u03c6\u03c7\u03c8\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03c9\u03ac\u03ad\u03ae\u03ca\u03af\u03cc\u03cd\u03cb\u03ce\u0386\u0388\u0389\u038a\u038c\u038e\u038f\u00b1\u2265\u2264\u03aa\u03ab\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0", |
||||||
|
Aliases: []string{"cp737", "cp737_DOSGreek"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "IBM775", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0106\u00fc\u00e9\u0101\u00e4\u0123\u00e5\u0107\u0142\u0113\u0156\u0157\u012b\u0179\u00c4\u00c5\u00c9\u00e6\u00c6\u014d\u00f6\u0122\u00a2\u015a\u015b\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u00a4\u0100\u012a\u00f3\u017b\u017c\u017a\u201d\u00a6\u00a9\u00ae\u00ac\u00bd\u00bc\u0141\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u0104\u010c\u0118\u0116\u2563\u2551\u2557\u255d\u012e\u0160\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u0172\u016a\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u017d\u0105\u010d\u0119\u0117\u012f\u0161\u0173\u016b\u017e\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u00d3\u00df\u014c\u0143\u00f5\u00d5\u00b5\u0144\u0136\u0137\u013b\u013c\u0146\u0112\u0145\u2019\u00ad\u00b1\u201c\u00be\u00b6\u00a7\u00f7\u201e\u00b0\u2219\u00b7\u00b9\u00b3\u00b2\u25a0\u00a0", |
||||||
|
Aliases: []string{"cp775", "csPC775Baltic"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-803_P100-1999", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd$.<(+|\u05d0\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd!\u00a2*);\u00ac-/\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd,%_>?\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd:#@'=\"\ufffd\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdABCDEFGHI\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdJKLMNOPQR\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdSTUVWXYZ\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\ufffd\ufffd\ufffd\ufffd\ufffd\u009f", |
||||||
|
Aliases: []string{"ibm-803_P100-1999", "ibm-803", "cp803"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-838_P100-1995", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07[\u00a2.<(+|&\u0e48\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e]!$*);\u00ac-/\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15^\u00a6,%_>?\u0e3f\u0e4e\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c`:#@'=\"\u0e4fabcdefghi\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e5ajklmnopqr\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e5b~stuvwxyz\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e2f\u0e30\u0e31\u0e32\u0e33\u0e34{ABCDEFGHI\u0e49\u0e35\u0e36\u0e37\u0e38\u0e39}JKLMNOPQR\u0e3a\u0e40\u0e41\u0e42\u0e43\u0e44\\\u0e4aSTUVWXYZ\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a0123456789\u0e4b\u0e4c\u0e4d\u0e4b\u0e4c\u009f", |
||||||
|
Aliases: []string{"ibm-838_P100-1995", "ibm-838", "IBM838", "IBM-Thai", "csIBMThai", "cp838", "838", "ibm-9030"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "IBM850", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u00c1\u00c2\u00c0\u00a9\u2563\u2551\u2557\u255d\u00a2\u00a5\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u00e3\u00c3\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u00a4\u00f0\u00d0\u00ca\u00cb\u00c8\u0131\u00cd\u00ce\u00cf\u2518\u250c\u2588\u2584\u00a6\u00cc\u2580\u00d3\u00df\u00d4\u00d2\u00f5\u00d5\u00b5\u00fe\u00de\u00da\u00db\u00d9\u00fd\u00dd\u00af\u00b4\u00ad\u00b1\u2017\u00be\u00b6\u00a7\u00f7\u00b8\u00b0\u00a8\u00b7\u00b9\u00b3\u00b2\u25a0\u00a0", |
||||||
|
Aliases: []string{"cp850", "850", "csPC850Multilingual"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-851_P100-1995", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u0386\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u0388\u00c4\u0389\u038a\ufffd\u038c\u00f4\u00f6\u038e\u00fb\u00f9\u038f\u00d6\u00dc\u03ac\u00a3\u03ad\u03ae\u03af\u03ca\u0390\u03cc\u03cd\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u00bd\u0398\u0399\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u039a\u039b\u039c\u039d\u2563\u2551\u2557\u255d\u039e\u039f\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u03a0\u03a1\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03b1\u03b2\u03b3\u2518\u250c\u2588\u2584\u03b4\u03b5\u2580\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u03c2\u03c4\u00b4\u00ad\u00b1\u03c5\u03c6\u03c7\u00a7\u03c8\u00b8\u00b0\u00a8\u03c9\u03cb\u03b0\u03ce\u25a0\u00a0", |
||||||
|
Aliases: []string{"ibm-851_P100-1995", "ibm-851", "IBM851", "cp851", "851", "csPC851"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "IBM852", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c7\u00fc\u00e9\u00e2\u00e4\u016f\u0107\u00e7\u0142\u00eb\u0150\u0151\u00ee\u0179\u00c4\u0106\u00c9\u0139\u013a\u00f4\u00f6\u013d\u013e\u015a\u015b\u00d6\u00dc\u0164\u0165\u0141\u00d7\u010d\u00e1\u00ed\u00f3\u00fa\u0104\u0105\u017d\u017e\u0118\u0119\u00ac\u017a\u010c\u015f\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u00c1\u00c2\u011a\u015e\u2563\u2551\u2557\u255d\u017b\u017c\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u0102\u0103\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u00a4\u0111\u0110\u010e\u00cb\u010f\u0147\u00cd\u00ce\u011b\u2518\u250c\u2588\u2584\u0162\u016e\u2580\u00d3\u00df\u00d4\u0143\u0144\u0148\u0160\u0161\u0154\u00da\u0155\u0170\u00fd\u00dd\u0163\u00b4\u00ad\u02dd\u02db\u02c7\u02d8\u00a7\u00f7\u00b8\u00b0\u00a8\u02d9\u0171\u0158\u0159\u25a0\u00a0", |
||||||
|
Aliases: []string{"cp852", "852", "csPCp852"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "IBM855", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0452\u0402\u0453\u0403\u0451\u0401\u0454\u0404\u0455\u0405\u0456\u0406\u0457\u0407\u0458\u0408\u0459\u0409\u045a\u040a\u045b\u040b\u045c\u040c\u045e\u040e\u045f\u040f\u044e\u042e\u044a\u042a\u0430\u0410\u0431\u0411\u0446\u0426\u0434\u0414\u0435\u0415\u0444\u0424\u0433\u0413\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u0445\u0425\u0438\u0418\u2563\u2551\u2557\u255d\u0439\u0419\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u043a\u041a\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u00a4\u043b\u041b\u043c\u041c\u043d\u041d\u043e\u041e\u043f\u2518\u250c\u2588\u2584\u041f\u044f\u2580\u042f\u0440\u0420\u0441\u0421\u0442\u0422\u0443\u0423\u0436\u0416\u0432\u0412\u044c\u042c\u2116\u00ad\u044b\u042b\u0437\u0417\u0448\u0428\u044d\u042d\u0449\u0429\u0447\u0427\u00a7\u25a0\u00a0", |
||||||
|
Aliases: []string{"cp855", "855", "csIBM855"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "IBM856", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\ufffd\u00a3\ufffd\u00d7\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u00ae\u00ac\u00bd\u00bc\ufffd\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\ufffd\ufffd\ufffd\u00a9\u2563\u2551\u2557\u255d\u00a2\u00a5\u2510\u2514\u2534\u252c\u251c\u2500\u253c\ufffd\ufffd\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u00a4\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u2518\u250c\u2588\u2584\u00a6\ufffd\u2580\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u00b5\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u00af\u00b4\u00ad\u00b1\u2017\u00be\u00b6\u00a7\u00f7\u00b8\u00b0\u00a8\u00b7\u00b9\u00b3\u00b2\u25a0\u00a0", |
||||||
|
Aliases: []string{"cp856", "cp856_Hebrew_PC"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-857_P100-1995", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u0131\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u0130\u00d6\u00dc\u00f8\u00a3\u00d8\u015e\u015f\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u011e\u011f\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u00c1\u00c2\u00c0\u00a9\u2563\u2551\u2557\u255d\u00a2\u00a5\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u00e3\u00c3\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u00a4\u00ba\u00aa\u00ca\u00cb\u00c8\ufffd\u00cd\u00ce\u00cf\u2518\u250c\u2588\u2584\u00a6\u00cc\u2580\u00d3\u00df\u00d4\u00d2\u00f5\u00d5\u00b5\ufffd\u00d7\u00da\u00db\u00d9\u00ec\u00ff\u00af\u00b4\u00ad\u00b1\ufffd\u00be\u00b6\u00a7\u00f7\u00b8\u00b0\u00a8\u00b7\u00b9\u00b3\u00b2\u25a0\u00a0", |
||||||
|
Aliases: []string{"ibm-857_P100-1995", "ibm-857", "IBM857", "cp857", "857", "csIBM857", "windows-857"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-858_P100-1997", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u00c1\u00c2\u00c0\u00a9\u2563\u2551\u2557\u255d\u00a2\u00a5\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u00e3\u00c3\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u00a4\u00f0\u00d0\u00ca\u00cb\u00c8\u20ac\u00cd\u00ce\u00cf\u2518\u250c\u2588\u2584\u00a6\u00cc\u2580\u00d3\u00df\u00d4\u00d2\u00f5\u00d5\u00b5\u00fe\u00de\u00da\u00db\u00d9\u00fd\u00dd\u00af\u00b4\u00ad\u00b1\u2017\u00be\u00b6\u00a7\u00f7\u00b8\u00b0\u00a8\u00b7\u00b9\u00b3\u00b2\u25a0\u00a0", |
||||||
|
Aliases: []string{"ibm-858_P100-1997", "ibm-858", "IBM00858", "CCSID00858", "CP00858", "PC-Multilingual-850+euro", "cp858", "windows-858"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-860_P100-1995", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00e3\u00e0\u00c1\u00e7\u00ea\u00ca\u00e8\u00cd\u00d4\u00ec\u00c3\u00c2\u00c9\u00c0\u00c8\u00f4\u00f5\u00f2\u00da\u00f9\u00cc\u00d5\u00dc\u00a2\u00a3\u00d9\u20a7\u00d3\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00d2\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0", |
||||||
|
Aliases: []string{"ibm-860_P100-1995", "ibm-860", "IBM860", "cp860", "860", "csIBM860"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-861_P100-1995", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00d0\u00f0\u00de\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00fe\u00fb\u00dd\u00fd\u00d6\u00dc\u00f8\u00a3\u00d8\u20a7\u0192\u00e1\u00ed\u00f3\u00fa\u00c1\u00cd\u00d3\u00da\u00bf\u2310\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0", |
||||||
|
Aliases: []string{"ibm-861_P100-1995", "ibm-861", "IBM861", "cp861", "861", "cp-is", "csIBM861", "windows-861"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-862_P100-1995", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\u00a2\u00a3\u00a5\u20a7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u2310\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0", |
||||||
|
Aliases: []string{"ibm-862_P100-1995", "ibm-862", "IBM862", "cp862", "862", "csPC862LatinHebrew", "DOS-862", "windows-862"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-863_P100-1995", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00c2\u00e0\u00b6\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u2017\u00c0\u00a7\u00c9\u00c8\u00ca\u00f4\u00cb\u00cf\u00fb\u00f9\u00a4\u00d4\u00dc\u00a2\u00a3\u00d9\u00db\u0192\u00a6\u00b4\u00f3\u00fa\u00a8\u00b8\u00b3\u00af\u00ce\u2310\u00ac\u00bd\u00bc\u00be\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0", |
||||||
|
Aliases: []string{"ibm-863_P100-1995", "ibm-863", "IBM863", "cp863", "863", "csIBM863"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-864_X110-1999", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00b0\u00b7\u2219\u221a\u2592\u2500\u2502\u253c\u2524\u252c\u251c\u2534\u2510\u250c\u2514\u2518\u03b2\u221e\u03c6\u00b1\u00bd\u00bc\u2248\u00ab\u00bb\ufef7\ufef8\ufffd\ufffd\ufefb\ufefc\u200b\u00a0\u00ad\ufe82\u00a3\u00a4\ufe84\ufffd\ufffd\ufe8e\ufe8f\ufe95\ufe99\u060c\ufe9d\ufea1\ufea5\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\ufed1\u061b\ufeb1\ufeb5\ufeb9\u061f\u00a2\ufe80\ufe81\ufe83\ufe85\ufeca\ufe8b\ufe8d\ufe91\ufe93\ufe97\ufe9b\ufe9f\ufea3\ufea7\ufea9\ufeab\ufead\ufeaf\ufeb3\ufeb7\ufebb\ufebf\ufec3\ufec7\ufecb\ufecf\u00a6\u00ac\u00f7\u00d7\ufec9\u0640\ufed3\ufed7\ufedb\ufedf\ufee3\ufee7\ufeeb\ufeed\ufeef\ufef3\ufebd\ufecc\ufece\ufecd\ufee1\ufe7d\ufe7c\ufee5\ufee9\ufeec\ufef0\ufef2\ufed0\ufed5\ufef5\ufef6\ufedd\ufed9\ufef1\u25a0\ufffd", |
||||||
|
Aliases: []string{"ibm-864_X110-1999", "ibm-864", "IBM864", "cp864", "csIBM864"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-865_P100-1995", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u20a7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u2310\u00ac\u00bd\u00bc\u00a1\u00ab\u00a4\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0", |
||||||
|
Aliases: []string{"ibm-865_P100-1995", "ibm-865", "IBM865", "cp865", "865", "csIBM865"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "IBM866", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u0401\u0451\u0404\u0454\u0407\u0457\u040e\u045e\u00b0\u2219\u00b7\u221a\u2116\u00a4\u25a0\u00a0", |
||||||
|
Aliases: []string{"cp866", "866", "csIBM866"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-867_P100-1998", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\u00a2\u00a3\u00a5\ufffd\u20aa\u200e\u200f\u202a\u202b\u202d\u202e\u202c\ufffd\ufffd\u2310\u00ac\u00bd\u00bc\u20ac\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0", |
||||||
|
Aliases: []string{"ibm-867_P100-1998", "ibm-867"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-868_P100-1995", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u060c\u061b\u061f\ufe81\ufe8d\ufe8e\uf8fb\ufe8f\ufe91\ufb56\ufb58\ufe93\ufe95\ufe97\ufb66\ufb68\ufe99\ufe9b\ufe9d\ufe9f\ufb7a\ufb7c\ufea1\ufea3\ufea5\ufea7\ufea9\ufb88\ufeab\ufead\ufb8c\ufeaf\ufb8a\ufeb1\ufeb3\ufeb5\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\ufeb7\ufeb9\ufebb\ufebd\u2563\u2551\u2557\u255d\ufebf\ufec3\u2510\u2514\u2534\u252c\u251c\u2500\u253c\ufec7\ufec9\u255a\u2554\u2569\u2566\u2560\u2550\u256c\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\ufed0\ufed1\ufed3\ufed5\u2518\u250c\u2588\u2584\ufed7\ufb8e\u2580\ufedb\ufb92\ufb94\ufedd\ufedf\ufee0\ufee1\ufee3\ufb9e\ufee5\ufee7\ufe85\ufeed\ufba6\ufba8\ufba9\u00ad\ufbaa\ufe80\ufe89\ufe8a\ufe8b\ufbfc\ufbfd\ufbfe\ufbb0\ufbae\ufe7c\ufe7d\ufffd\u25a0\u00a0", |
||||||
|
Aliases: []string{"ibm-868_P100-1995", "ibm-868", "IBM868", "CP868", "868", "csIBM868", "cp-ar"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-869_P100-1995", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u0386\ufffd\u0387\u00ac\u00a6\u2018\u2019\u0388\u2015\u0389\u038a\u03aa\u038c\ufffd\ufffd\u038e\u03ab\u00a9\u038f\u00b2\u00b3\u03ac\u00a3\u03ad\u03ae\u03af\u03ca\u0390\u03cc\u03cd\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u00bd\u0398\u0399\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u039a\u039b\u039c\u039d\u2563\u2551\u2557\u255d\u039e\u039f\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u03a0\u03a1\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03b1\u03b2\u03b3\u2518\u250c\u2588\u2584\u03b4\u03b5\u2580\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u03c2\u03c4\u00b4\u00ad\u00b1\u03c5\u03c6\u03c7\u00a7\u03c8\u0385\u00b0\u00a8\u03c9\u03cb\u03b0\u03ce\u25a0\u00a0", |
||||||
|
Aliases: []string{"ibm-869_P100-1995", "ibm-869", "IBM869", "cp869", "869", "cp-gr", "csIBM869", "windows-869"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-870_P100-1995", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u0163\u00e1\u0103\u010d\u00e7\u0107[.<(+!&\u00e9\u0119\u00eb\u016f\u00ed\u00ee\u013e\u013a\u00df]$*);^-/\u00c2\u00c4\u02dd\u00c1\u0102\u010c\u00c7\u0106|,%_>?\u02c7\u00c9\u0118\u00cb\u016e\u00cd\u00ce\u013d\u0139`:#@'=\"\u02d8abcdefghi\u015b\u0148\u0111\u00fd\u0159\u015f\u00b0jklmnopqr\u0142\u0144\u0161\u00b8\u02db\u00a4\u0105~stuvwxyz\u015a\u0147\u0110\u00dd\u0158\u015e\u02d9\u0104\u017c\u0162\u017b\u00a7\u017e\u017a\u017d\u0179\u0141\u0143\u0160\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u0155\u00f3\u0151}JKLMNOPQR\u011a\u0171\u00fc\u0165\u00fa\u011b\\\u00f7STUVWXYZ\u010f\u00d4\u00d6\u0154\u00d3\u01500123456789\u010e\u0170\u00dc\u0164\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-870_P100-1995", "ibm-870", "IBM870", "CP870", "ebcdic-cp-roece", "ebcdic-cp-yu", "csIBM870"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-871_P100-1995", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00de.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u00c6$*);\u00d6-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00f0:#\u00d0'=\"\u00d8abcdefghi\u00ab\u00bb`\u00fd{\u00b1\u00b0jklmnopqr\u00aa\u00ba}\u00b8]\u00a4\u00b5\u00f6stuvwxyz\u00a1\u00bf@\u00dd[\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\\\u00d7\u00feABCDEFGHI\u00ad\u00f4~\u00f2\u00f3\u00f5\u00e6JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\u00b4\u00f7STUVWXYZ\u00b2\u00d4^\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-871_P100-1995", "ibm-871", "IBM871", "ebcdic-cp-is", "csIBM871", "CP871", "ebcdic-is", "871"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-874_P100-1995", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u0e48\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e2f\u0e30\u0e31\u0e32\u0e33\u0e34\u0e35\u0e36\u0e37\u0e38\u0e39\u0e3a\u0e49\u0e4a\u0e4b\u0e4c\u0e3f\u0e40\u0e41\u0e42\u0e43\u0e44\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a\u0e4b\u0e4c\u0e4d\u0e4e\u0e4f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e5a\u0e5b\u00a2\u00ac\u00a6\u00a0", |
||||||
|
Aliases: []string{"ibm-874_P100-1995", "ibm-874", "ibm-9066", "cp874", "tis620.2533", "eucTH"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-875_P100-1995", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399[.<(+!&\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3]$*);^-/\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab|,%_>?\u00a8\u0386\u0388\u0389\u00a0\u038a\u038c\u038e\u038f`:#@'=\"\u0385abcdefghi\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u00b0jklmnopqr\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u00b4~stuvwxyz\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u00a3\u03ac\u03ad\u03ae\u03ca\u03af\u03cc\u03cd\u03cb\u03ce\u03c2\u03c4\u03c5\u03c6\u03c7\u03c8{ABCDEFGHI\u00ad\u03c9\u0390\u03b0\u2018\u2015}JKLMNOPQR\u00b1\u00bd\ufffd\u0387\u2019\u00a6\\\ufffdSTUVWXYZ\u00b2\u00a7\ufffd\ufffd\u00ab\u00ac0123456789\u00b3\u00a9\ufffd\ufffd\u00bb\u009f", |
||||||
|
Aliases: []string{"ibm-875_P100-1995", "ibm-875", "IBM875", "cp875", "875"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-901_P100-1999", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u201d\u00a2\u00a3\u20ac\u201e\u00a6\u00a7\u00d8\u00a9\u0156\u00ab\u00ac\u00ad\u00ae\u00c6\u00b0\u00b1\u00b2\u00b3\u201c\u00b5\u00b6\u00b7\u00f8\u00b9\u0157\u00bb\u00bc\u00bd\u00be\u00e6\u0104\u012e\u0100\u0106\u00c4\u00c5\u0118\u0112\u010c\u00c9\u0179\u0116\u0122\u0136\u012a\u013b\u0160\u0143\u0145\u00d3\u014c\u00d5\u00d6\u00d7\u0172\u0141\u015a\u016a\u00dc\u017b\u017d\u00df\u0105\u012f\u0101\u0107\u00e4\u00e5\u0119\u0113\u010d\u00e9\u017a\u0117\u0123\u0137\u012b\u013c\u0161\u0144\u0146\u00f3\u014d\u00f5\u00f6\u00f7\u0173\u0142\u015b\u016b\u00fc\u017c\u017e\u2019", |
||||||
|
Aliases: []string{"ibm-901_P100-1999", "ibm-901"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-902_P100-1999", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u00a1\u00a2\u00a3\u20ac\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u0160\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u00dd\u017d\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u0161\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u017e\u00ff", |
||||||
|
Aliases: []string{"ibm-902_P100-1999", "ibm-902"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-916_P100-1995", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\ufffd\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00d7\u00ab\u00ac\u00ad\u00ae\u203e\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u2022\u00b8\u00b9\u00f7\u00bb\u00bc\u00bd\u00be\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u2017\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\ufffd\ufffd\ufffd\ufffd\ufffd", |
||||||
|
Aliases: []string{"ibm-916_P100-1995", "ibm-916", "cp916", "916"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-918_P100-1995", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u060c\u061b\u061f\ufe81\ufe8d\ufe8e\uf8fb\ufe8f[.<(+!&\ufe91\ufb56\ufb58\ufe93\ufe95\ufe97\ufb66\ufb68\ufe99]$*);^-/\ufe9b\ufe9d\ufe9f\ufb7a\ufb7c\ufea1\ufea3\ufea5`,%_>?\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9:#@'=\"\ufea7abcdefghi\ufea9\ufb88\ufeab\ufead\ufb8c\ufeaf\ufb8ajklmnopqr\ufeb1\ufeb3\ufeb5\ufeb7\ufeb9\ufebb\ufebd~stuvwxyz\ufebf\ufec3\ufec7\ufec9\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\ufed0\ufed1\ufed3\ufed5\ufed7\ufb8e\ufedb|\ufb92\ufb94\ufedd\ufedf{ABCDEFGHI\u00ad\ufee0\ufee1\ufee3\ufb9e\ufee5}JKLMNOPQR\ufee7\ufe85\ufeed\ufba6\ufba8\ufba9\\\ufbaaSTUVWXYZ\ufe80\ufe89\ufe8a\ufe8b\ufbfc\ufbfd0123456789\ufbfe\ufbb0\ufbae\ufe7c\ufe7d\u009f", |
||||||
|
Aliases: []string{"ibm-918_P100-1995", "ibm-918", "IBM918", "CP918", "ebcdic-cp-ar2", "csIBM918"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-922_P100-1999", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u0160\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u00dd\u017d\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u0161\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u017e\u00ff", |
||||||
|
Aliases: []string{"ibm-922_P100-1999", "ibm-922", "IBM922", "cp922", "922"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1006_P100-1995", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u060c\u061b\u00ad\u061f\ufe81\ufe8d\ufe8e\uf8fb\ufe8f\ufe91\ufb56\ufb58\ufe93\ufe95\ufe97\ufb66\ufb68\ufe99\ufe9b\ufe9d\ufe9f\ufb7a\ufb7c\ufea1\ufea3\ufea5\ufea7\ufea9\ufb88\ufeab\ufead\ufb8c\ufeaf\ufb8a\ufeb1\ufeb3\ufeb5\ufeb7\ufeb9\ufebb\ufebd\ufebf\ufec3\ufec7\ufec9\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\ufed0\ufed1\ufed3\ufed5\ufed7\ufb8e\ufedb\ufb92\ufb94\ufedd\ufedf\ufee0\ufee1\ufee3\ufb9e\ufee5\ufee7\ufe85\ufeed\ufba6\ufba8\ufba9\ufbaa\ufe80\ufe89\ufe8a\ufe8b\ufbfc\ufbfd\ufbfe\ufbb0\ufbae\ufe7c\ufe7d", |
||||||
|
Aliases: []string{"ibm-1006_P100-1995", "ibm-1006", "IBM1006", "cp1006", "1006"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1025_P100-1995", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0452\u0453\u0451\u0454\u0455\u0456\u0457\u0458[.<(+!&\u0459\u045a\u045b\u045c\u045e\u045f\u042a\u2116\u0402]$*);^-/\u0403\u0401\u0404\u0405\u0406\u0407\u0408\u0409|,%_>?\u040a\u040b\u040c\u00ad\u040e\u040f\u044e\u0430\u0431`:#@'=\"\u0446abcdefghi\u0434\u0435\u0444\u0433\u0445\u0438\u0439jklmnopqr\u043a\u043b\u043c\u043d\u043e\u043f\u044f~stuvwxyz\u0440\u0441\u0442\u0443\u0436\u0432\u044c\u044b\u0437\u0448\u044d\u0449\u0447\u044a\u042e\u0410\u0411\u0426\u0414\u0415\u0424\u0413{ABCDEFGHI\u0425\u0418\u0419\u041a\u041b\u041c}JKLMNOPQR\u041d\u041e\u041f\u042f\u0420\u0421\\\u00a7STUVWXYZ\u0422\u0423\u0416\u0412\u042c\u042b0123456789\u0417\u0428\u042d\u0429\u0427\u009f", |
||||||
|
Aliases: []string{"ibm-1025_P100-1995", "ibm-1025", "cp1025", "1025"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1026_P100-1995", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5{\u00f1\u00c7.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u011e\u0130*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5[\u00d1\u015f,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u0131:\u00d6\u015e'=\u00dc\u00d8abcdefghi\u00ab\u00bb}`\u00a6\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5\u00f6stuvwxyz\u00a1\u00bf]$@\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e7ABCDEFGHI\u00ad\u00f4~\u00f2\u00f3\u00f5\u011fJKLMNOPQR\u00b9\u00fb\\\u00f9\u00fa\u00ff\u00fc\u00f7STUVWXYZ\u00b2\u00d4#\u00d2\u00d3\u00d50123456789\u00b3\u00db\"\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-1026_P100-1995", "ibm-1026", "IBM1026", "CP1026", "csIBM1026", "1026"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1047_P100-1995", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00a2.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df!$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5~stuvwxyz\u00a1\u00bf\u00d0[\u00de\u00ae\u00ac\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00dd\u00a8\u00af]\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-1047_P100-1995", "ibm-1047", "IBM1047", "cp1047", "1047"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1097_P100-1995", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u060c\u064b\ufe81\ufe82\uf8fa\ufe8d\ufe8e\uf8fb\u00a4.<(+|&\ufe80\ufe83\ufe84\uf8f9\ufe85\ufe8b\ufe8f\ufe91\ufb56!$*);\u00ac-/\ufb58\ufe95\ufe97\ufe99\ufe9b\ufe9d\ufe9f\ufb7a\u061b,%_>?\ufb7c\ufea1\ufea3\ufea5\ufea7\ufea9\ufeab\ufead\ufeaf`:#@'=\"\ufb8aabcdefghi\u00ab\u00bb\ufeb1\ufeb3\ufeb5\ufeb7\ufeb9jklmnopqr\ufebb\ufebd\ufebf\ufec1\ufec3\ufec5\ufec7~stuvwxyz\ufec9\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\ufed0\ufed1\ufed3\ufed5\ufed7\ufb8e\ufedb\ufb92\ufb94[]\ufedd\ufedf\ufee1\u00d7{ABCDEFGHI\u00ad\ufee3\ufee5\ufee7\ufeed\ufee9}JKLMNOPQR\ufeeb\ufeec\ufba4\ufbfc\ufbfd\ufbfe\\\u061fSTUVWXYZ\u0640\u06f0\u06f1\u06f2\u06f3\u06f40123456789\u06f5\u06f6\u06f7\u06f8\u06f9\u009f", |
||||||
|
Aliases: []string{"ibm-1097_P100-1995", "ibm-1097", "cp1097", "1097"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1098_P100-1995", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\ufffd\ufffd\u060c\u061b\u061f\u064b\ufe81\ufe82\uf8fa\ufe8d\ufe8e\uf8fb\ufe80\ufe83\ufe84\uf8f9\ufe85\ufe8b\ufe8f\ufe91\ufb56\ufb58\ufe95\ufe97\ufe99\ufe9b\ufe9d\ufe9f\ufb7a\ufb7c\u00d7\ufea1\ufea3\ufea5\ufea7\ufea9\ufeab\ufead\ufeaf\ufb8a\ufeb1\ufeb3\ufeb5\ufeb7\ufeb9\ufebb\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\ufebd\ufebf\ufec1\ufec3\u2563\u2551\u2557\u255d\u00a4\ufec5\u2510\u2514\u2534\u252c\u251c\u2500\u253c\ufec7\ufec9\u255a\u2554\u2569\u2566\u2560\u2550\u256c\ufffd\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\ufed0\ufed1\ufed3\u2518\u250c\u2588\u2584\ufed5\ufed7\u2580\ufb8e\ufedb\ufb92\ufb94\ufedd\ufedf\ufee1\ufee3\ufee5\ufee7\ufeed\ufee9\ufeeb\ufeec\ufba4\ufbfc\u00ad\ufbfd\ufbfe\u0640\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u25a0\u00a0", |
||||||
|
Aliases: []string{"ibm-1098_P100-1995", "ibm-1098", "IBM1098", "cp1098", "1098"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1112_P100-1995", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0161\u00e4\u0105\u012f\u016b\u00e5\u0113\u017e\u00a2.<(+|&\u00e9\u0119\u0117\u010d\u0173\u201e\u201c\u0123\u00df!$*);\u00ac-/\u0160\u00c4\u0104\u012e\u016a\u00c5\u0112\u017d\u00a6,%_>?\u00f8\u00c9\u0118\u0116\u010c\u0172\u012a\u013b\u0122`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u0101\u017c\u0144\u00b1\u00b0jklmnopqr\u0156\u0157\u00e6\u0137\u00c6\u00a4\u00b5~stuvwxyz\u201d\u017a\u0100\u017b\u0143\u00ae^\u00a3\u012b\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u0179\u0136\u013c\u00d7{ABCDEFGHI\u00ad\u014d\u00f6\u0146\u00f3\u00f5}JKLMNOPQR\u00b9\u0107\u00fc\u0142\u015b\u2019\\\u00f7STUVWXYZ\u00b2\u014c\u00d6\u0145\u00d3\u00d50123456789\u00b3\u0106\u00dc\u0141\u015a\u009f", |
||||||
|
Aliases: []string{"ibm-1112_P100-1995", "ibm-1112", "cp1112", "1112"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1122_P100-1999", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2{\u00e0\u00e1\u00e3}\u00e7\u00f1\u00a7.<(+!&`\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u00a4\u00c5*);^-/\u00c2#\u00c0\u00c1\u00c3$\u00c7\u00d1\u00f6,%_>?\u00f8\\\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00e9:\u00c4\u00d6'=\"\u00d8abcdefghi\u00ab\u00bb\u0161\u00fd\u017e\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6]\u00b5\u00fcstuvwxyz\u00a1\u00bf\u0160\u00dd\u017d\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9[\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e4ABCDEFGHI\u00ad\u00f4\u00a6\u00f2\u00f3\u00f5\u00e5JKLMNOPQR\u00b9\u00fb~\u00f9\u00fa\u00ff\u00c9\u00f7STUVWXYZ\u00b2\u00d4@\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-1122_P100-1999", "ibm-1122", "cp1122", "1122"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1123_P100-1995", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0452\u0491\u0451\u0454\u0455\u0456\u0457\u0458[.<(+!&\u0459\u045a\u045b\u045c\u045e\u045f\u042a\u2116\u0402]$*);^-/\u0490\u0401\u0404\u0405\u0406\u0407\u0408\u0409|,%_>?\u040a\u040b\u040c\u00ad\u040e\u040f\u044e\u0430\u0431`:#@'=\"\u0446abcdefghi\u0434\u0435\u0444\u0433\u0445\u0438\u0439jklmnopqr\u043a\u043b\u043c\u043d\u043e\u043f\u044f~stuvwxyz\u0440\u0441\u0442\u0443\u0436\u0432\u044c\u044b\u0437\u0448\u044d\u0449\u0447\u044a\u042e\u0410\u0411\u0426\u0414\u0415\u0424\u0413{ABCDEFGHI\u0425\u0418\u0419\u041a\u041b\u041c}JKLMNOPQR\u041d\u041e\u041f\u042f\u0420\u0421\\\u00a7STUVWXYZ\u0422\u0423\u0416\u0412\u042c\u042b0123456789\u0417\u0428\u042d\u0429\u0427\u009f", |
||||||
|
Aliases: []string{"ibm-1123_P100-1995", "ibm-1123", "cp1123", "1123"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1124_P100-1996", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0401\u0402\u0490\u0404\u0405\u0406\u0407\u0408\u0409\u040a\u040b\u040c\u00ad\u040e\u040f\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u2116\u0451\u0452\u0491\u0454\u0455\u0456\u0457\u0458\u0459\u045a\u045b\u045c\u00a7\u045e\u045f", |
||||||
|
Aliases: []string{"ibm-1124_P100-1996", "ibm-1124", "cp1124", "1124"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1125_P100-1997", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u0401\u0451\u0490\u0491\u0404\u0454\u0406\u0456\u0407\u0457\u00f7\u00b1\u2116\u00a4\u25a0\u00a0", |
||||||
|
Aliases: []string{"ibm-1125_P100-1997", "ibm-1125", "cp1125"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1129_P100-1997", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u0153\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u0178\u00b5\u00b6\u00b7\u0152\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u0102\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u0300\u00cd\u00ce\u00cf\u0110\u00d1\u0309\u00d3\u00d4\u01a0\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u01af\u0303\u00df\u00e0\u00e1\u00e2\u0103\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u0301\u00ed\u00ee\u00ef\u0111\u00f1\u0323\u00f3\u00f4\u01a1\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u01b0\u20ab\u00ff", |
||||||
|
Aliases: []string{"ibm-1129_P100-1997", "ibm-1129"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1130_P100-1997", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u0103\u00e5\u00e7\u00f1[.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u0303\u00df]$*);^-/\u00c2\u00c4\u00c0\u00c1\u0102\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u20ab`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u0111\u0309\u0300\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u0152\u00c6\u00a4\u00b5~stuvwxyz\u00a1\u00bf\u0110\u0323\u0301\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u0153\u0178\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u01b0\u00f3\u01a1}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u01af\u00d3\u01a00123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-1130_P100-1997", "ibm-1130"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1131_P100-1997", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u0401\u0451\u0404\u0454\u0407\u0457\u040e\u045e\u0406\u0456\u00b7\u00a4\u0490\u0491\u2219\u00a0", |
||||||
|
Aliases: []string{"ibm-1131_P100-1997", "ibm-1131", "cp1131"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1132_P100-1998", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0e81\u0e82\u0e84\u0e87\u0e88\u0eaa\u0e8a[\u00a2.<(+|&\ufffd\u0e8d\u0e94\u0e95\u0e96\u0e97\u0e99\u0e9a]!$*);\u00ac-/\u0e9b\u0e9c\u0e9d\u0e9e\u0e9f\u0ea1\u0ea2^\u00a6,%_>?\u20ad\ufffd\u0ea3\u0ea5\u0ea7\u0eab\u0ead\u0eae\ufffd`:#@'=\"\ufffdabcdefghi\ufffd\ufffd\u0eaf\u0eb0\u0eb2\u0eb3\ufffdjklmnopqr\u0eb4\u0eb5\u0eb6\u0eb7\u0eb8\u0eb9\ufffd~stuvwxyz\u0ebc\u0eb1\u0ebb\u0ebd\ufffd\ufffd\u0ed0\u0ed1\u0ed2\u0ed3\u0ed4\u0ed5\u0ed6\u0ed7\u0ed8\u0ed9\ufffd\u0ec0\u0ec1\u0ec2\u0ec3\u0ec4{ABCDEFGHI\ufffd\u0ec8\u0ec9\u0eca\u0ecb\u0ecc}JKLMNOPQR\u0ecd\u0ec6\ufffd\u0edc\u0edd\ufffd\\\ufffdSTUVWXYZ\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\ufffd\ufffd\ufffd\ufffd\ufffd\u009f", |
||||||
|
Aliases: []string{"ibm-1132_P100-1998", "ibm-1132"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1133_P100-1997", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\ufffd\u0e81\u0e82\u0e84\u0e87\u0e88\u0eaa\u0e8a\u0e8d\u0e94\u0e95\u0e96\u0e97\u0e99\u0e9a\u0e9b\u0e9c\u0e9d\u0e9e\u0e9f\u0ea1\u0ea2\u0ea3\u0ea5\u0ea7\u0eab\u0ead\u0eae\ufffd\ufffd\ufffd\u0eaf\u0eb0\u0eb2\u0eb3\u0eb4\u0eb5\u0eb6\u0eb7\u0eb8\u0eb9\u0ebc\u0eb1\u0ebb\u0ebd\ufffd\ufffd\ufffd\u0ec0\u0ec1\u0ec2\u0ec3\u0ec4\u0ec8\u0ec9\u0eca\u0ecb\u0ecc\u0ecd\u0ec6\ufffd\u0edc\u0eddk\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u0ed0\u0ed1\u0ed2\u0ed3\u0ed4\u0ed5\u0ed6\u0ed7\u0ed8\u0ed9\ufffd\ufffd\u00a2\u00ac\u00a6\u00a0", |
||||||
|
Aliases: []string{"ibm-1133_P100-1997", "ibm-1133"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1137_P100-1999", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0901\u0902\u0903\u0905\u0906\u0907\u0908\u0909\u090a.<(+|&\u090b\u090c\u090d\u090e\u090f\u0910\u0911\u0912\u0913!$*);^-/\u0914\u0915\u0916\u0917\u0918\u0919\u091a\u091b\u091c,%_>?\u091d\u091e\u091f\u0920\u0921\u0922\u0923\u0924\u0925`:#@'=\"\u0926abcdefghi\u0927\u0928\u092a\u092b\u092c\u092d\u092ejklmnopqr\u092f\u0930\u0932\u0933\u0935\u0936\u200c~stuvwxyz\u0937\u0938\u0939[\u093c\u093d\u093e\u093f\u0940\u0941\u0942\u0943\u0944\u0945\u0946\u0947\u0948\u0949\u094a]\u094b\u094c{ABCDEFGHI\u094d\u0950\u0951\u0952\ufffd\ufffd}JKLMNOPQR\u0960\u0961\u0962\u0963\u0964\u0965\\\u200dSTUVWXYZ\u0966\u0967\u0968\u0969\u096a\u096b0123456789\u096c\u096d\u096e\u096f\u0970\u009f", |
||||||
|
Aliases: []string{"ibm-1137_P100-1999", "ibm-1137"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1140_P100-1997", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00a2.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df!$*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5~stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae^\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u00af\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-1140_P100-1997", "ibm-1140", "IBM01140", "CCSID01140", "CP01140", "cp1140", "ebcdic-us-37+euro"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1141_P100-1997", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2{\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00c4.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec~\u00dc$*);^-/\u00c2[\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00f6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#\u00a7'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5\u00dfstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9@\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e4ABCDEFGHI\u00ad\u00f4\u00a6\u00f2\u00f3\u00f5\u00fcJKLMNOPQR\u00b9\u00fb}\u00f9\u00fa\u00ff\u00d6\u00f7STUVWXYZ\u00b2\u00d4\\\u00d2\u00d3\u00d50123456789\u00b3\u00db]\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-1141_P100-1997", "ibm-1141", "IBM01141", "CCSID01141", "CP01141", "cp1141", "ebcdic-de-273+euro"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1142_P100-1997", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3}\u00e7\u00f1#.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u20ac\u00c5*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3$\u00c7\u00d1\u00f8,%_>?\u00a6\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:\u00c6\u00d8'=\"@abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba{\u00b8[]\u00b5\u00fcstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e6ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5\u00e5JKLMNOPQR\u00b9\u00fb~\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-1142_P100-1997", "ibm-1142", "IBM01142", "CCSID01142", "CP01142", "cp1142", "ebcdic-dk-277+euro", "ebcdic-no-277+euro"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1143_P100-1997", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2{\u00e0\u00e1\u00e3}\u00e7\u00f1\u00a7.<(+!&`\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u20ac\u00c5*);^-/\u00c2#\u00c0\u00c1\u00c3$\u00c7\u00d1\u00f6,%_>?\u00f8\\\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00e9:\u00c4\u00d6'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6]\u00b5\u00fcstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9[\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e4ABCDEFGHI\u00ad\u00f4\u00a6\u00f2\u00f3\u00f5\u00e5JKLMNOPQR\u00b9\u00fb~\u00f9\u00fa\u00ff\u00c9\u00f7STUVWXYZ\u00b2\u00d4@\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-1143_P100-1997", "ibm-1143", "IBM01143", "CCSID01143", "CP01143", "cp1143", "ebcdic-fi-278+euro", "ebcdic-se-278+euro"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1144_P100-1997", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4{\u00e1\u00e3\u00e5\\\u00f1\u00b0.<(+!&]\u00ea\u00eb}\u00ed\u00ee\u00ef~\u00df\u00e9$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00f2,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00f9:\u00a3\u00a7'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1[jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5\u00ecstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2#\u00a5\u00b7\u00a9@\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e0ABCDEFGHI\u00ad\u00f4\u00f6\u00a6\u00f3\u00f5\u00e8JKLMNOPQR\u00b9\u00fb\u00fc`\u00fa\u00ff\u00e7\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-1144_P100-1997", "ibm-1144", "IBM01144", "CCSID01144", "CP01144", "cp1144", "ebcdic-it-280+euro"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1145_P100-1997", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00a6[.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df]$*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7#\u00f1,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:\u00d1@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5\u00a8stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be^!\u00af~\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-1145_P100-1997", "ibm-1145", "IBM01145", "CCSID01145", "CP01145", "cp1145", "ebcdic-es-284+euro"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1146_P100-1997", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1$.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df!\u00a3*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5\u00afstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2[\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be^]~\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-1146_P100-1997", "ibm-1146", "IBM01146", "CCSID01146", "CP01146", "cp1146", "ebcdic-gb-285+euro"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1147_P100-1997", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4@\u00e1\u00e3\u00e5\\\u00f1\u00b0.<(+!&{\u00ea\u00eb}\u00ed\u00ee\u00ef\u00ec\u00df\u00a7$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00f9,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00b5:\u00a3\u00e0'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1[jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac`\u00a8stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2#\u00a5\u00b7\u00a9]\u00b6\u00bc\u00bd\u00be\u00ac|\u00af~\u00b4\u00d7\u00e9ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5\u00e8JKLMNOPQR\u00b9\u00fb\u00fc\u00a6\u00fa\u00ff\u00e7\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-1147_P100-1997", "ibm-1147", "IBM01147", "CCSID01147", "CP01147", "cp1147", "ebcdic-fr-297+euro"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1148_P100-1997", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1[.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df]$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5~stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-1148_P100-1997", "ibm-1148", "IBM01148", "CCSID01148", "CP01148", "cp1148", "ebcdic-international-500+euro"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1149_P100-1997", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00de.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u00c6$*);\u00d6-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00f0:#\u00d0'=\"\u00d8abcdefghi\u00ab\u00bb`\u00fd{\u00b1\u00b0jklmnopqr\u00aa\u00ba}\u00b8]\u20ac\u00b5\u00f6stuvwxyz\u00a1\u00bf@\u00dd[\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\\\u00d7\u00feABCDEFGHI\u00ad\u00f4~\u00f2\u00f3\u00f5\u00e6JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\u00b4\u00f7STUVWXYZ\u00b2\u00d4^\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-1149_P100-1997", "ibm-1149", "IBM01149", "CCSID01149", "CP01149", "cp1149", "ebcdic-is-871+euro"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1153_P100-1999", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u0163\u00e1\u0103\u010d\u00e7\u0107[.<(+!&\u00e9\u0119\u00eb\u016f\u00ed\u00ee\u013e\u013a\u00df]$*);^-/\u00c2\u00c4\u02dd\u00c1\u0102\u010c\u00c7\u0106|,%_>?\u02c7\u00c9\u0118\u00cb\u016e\u00cd\u00ce\u013d\u0139`:#@'=\"\u02d8abcdefghi\u015b\u0148\u0111\u00fd\u0159\u015f\u00b0jklmnopqr\u0142\u0144\u0161\u00b8\u02db\u20ac\u0105~stuvwxyz\u015a\u0147\u0110\u00dd\u0158\u015e\u02d9\u0104\u017c\u0162\u017b\u00a7\u017e\u017a\u017d\u0179\u0141\u0143\u0160\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u0155\u00f3\u0151}JKLMNOPQR\u011a\u0171\u00fc\u0165\u00fa\u011b\\\u00f7STUVWXYZ\u010f\u00d4\u00d6\u0154\u00d3\u01500123456789\u010e\u0170\u00dc\u0164\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-1153_P100-1999", "ibm-1153"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1154_P100-1999", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0452\u0453\u0451\u0454\u0455\u0456\u0457\u0458[.<(+!&\u0459\u045a\u045b\u045c\u045e\u045f\u042a\u2116\u0402]$*);^-/\u0403\u0401\u0404\u0405\u0406\u0407\u0408\u0409|,%_>?\u040a\u040b\u040c\u00ad\u040e\u040f\u044e\u0430\u0431`:#@'=\"\u0446abcdefghi\u0434\u0435\u0444\u0433\u0445\u0438\u0439jklmnopqr\u043a\u043b\u043c\u043d\u043e\u043f\u044f~stuvwxyz\u0440\u0441\u0442\u0443\u0436\u0432\u044c\u044b\u0437\u0448\u044d\u0449\u0447\u044a\u042e\u0410\u0411\u0426\u0414\u0415\u0424\u0413{ABCDEFGHI\u0425\u0418\u0419\u041a\u041b\u041c}JKLMNOPQR\u041d\u041e\u041f\u042f\u0420\u0421\\\u20acSTUVWXYZ\u0422\u0423\u0416\u0412\u042c\u042b0123456789\u0417\u0428\u042d\u0429\u0427\u009f", |
||||||
|
Aliases: []string{"ibm-1154_P100-1999", "ibm-1154"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1155_P100-1999", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5{\u00f1\u00c7.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u011e\u0130*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5[\u00d1\u015f,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u0131:\u00d6\u015e'=\u00dc\u00d8abcdefghi\u00ab\u00bb}`\u00a6\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5\u00f6stuvwxyz\u00a1\u00bf]$@\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e7ABCDEFGHI\u00ad\u00f4~\u00f2\u00f3\u00f5\u011fJKLMNOPQR\u00b9\u00fb\\\u00f9\u00fa\u00ff\u00fc\u00f7STUVWXYZ\u00b2\u00d4#\u00d2\u00d3\u00d50123456789\u00b3\u00db\"\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-1155_P100-1999", "ibm-1155"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1156_P100-1999", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0161\u00e4\u0105\u012f\u016b\u00e5\u0113\u017e\u00a2.<(+|&\u00e9\u0119\u0117\u010d\u0173\u201e\u201c\u0123\u00df!$*);\u00ac-/\u0160\u00c4\u0104\u012e\u016a\u00c5\u0112\u017d\u00a6,%_>?\u00f8\u00c9\u0118\u0116\u010c\u0172\u012a\u013b\u0122`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u0101\u017c\u0144\u00b1\u00b0jklmnopqr\u0156\u0157\u00e6\u0137\u00c6\u20ac\u00b5~stuvwxyz\u201d\u017a\u0100\u017b\u0143\u00ae^\u00a3\u012b\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u0179\u0136\u013c\u00d7{ABCDEFGHI\u00ad\u014d\u00f6\u0146\u00f3\u00f5}JKLMNOPQR\u00b9\u0107\u00fc\u0142\u015b\u2019\\\u00f7STUVWXYZ\u00b2\u014c\u00d6\u0145\u00d3\u00d50123456789\u00b3\u0106\u00dc\u0141\u015a\u009f", |
||||||
|
Aliases: []string{"ibm-1156_P100-1999", "ibm-1156"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1157_P100-1999", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2{\u00e0\u00e1\u00e3}\u00e7\u00f1\u00a7.<(+!&`\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u20ac\u00c5*);^-/\u00c2#\u00c0\u00c1\u00c3$\u00c7\u00d1\u00f6,%_>?\u00f8\\\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00e9:\u00c4\u00d6'=\"\u00d8abcdefghi\u00ab\u00bb\u0161\u00fd\u017e\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6]\u00b5\u00fcstuvwxyz\u00a1\u00bf\u0160\u00dd\u017d\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9[\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e4ABCDEFGHI\u00ad\u00f4\u00a6\u00f2\u00f3\u00f5\u00e5JKLMNOPQR\u00b9\u00fb~\u00f9\u00fa\u00ff\u00c9\u00f7STUVWXYZ\u00b2\u00d4@\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-1157_P100-1999", "ibm-1157"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1158_P100-1999", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0452\u0491\u0451\u0454\u0455\u0456\u0457\u0458[.<(+!&\u0459\u045a\u045b\u045c\u045e\u045f\u042a\u2116\u0402]$*);^-/\u0490\u0401\u0404\u0405\u0406\u0407\u0408\u0409|,%_>?\u040a\u040b\u040c\u00ad\u040e\u040f\u044e\u0430\u0431`:#@'=\"\u0446abcdefghi\u0434\u0435\u0444\u0433\u0445\u0438\u0439jklmnopqr\u043a\u043b\u043c\u043d\u043e\u043f\u044f~stuvwxyz\u0440\u0441\u0442\u0443\u0436\u0432\u044c\u044b\u0437\u0448\u044d\u0449\u0447\u044a\u042e\u0410\u0411\u0426\u0414\u0415\u0424\u0413{ABCDEFGHI\u0425\u0418\u0419\u041a\u041b\u041c}JKLMNOPQR\u041d\u041e\u041f\u042f\u0420\u0421\\\u20acSTUVWXYZ\u0422\u0423\u0416\u0412\u042c\u042b0123456789\u0417\u0428\u042d\u0429\u0427\u009f", |
||||||
|
Aliases: []string{"ibm-1158_P100-1999", "ibm-1158"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1160_P100-1999", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07[\u00a2.<(+|&\u0e48\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e]!$*);\u00ac-/\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15^\u00a6,%_>?\u0e3f\u0e4e\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c`:#@'=\"\u0e4fabcdefghi\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e5ajklmnopqr\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e5b~stuvwxyz\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e2f\u0e30\u0e31\u0e32\u0e33\u0e34{ABCDEFGHI\u0e49\u0e35\u0e36\u0e37\u0e38\u0e39}JKLMNOPQR\u0e3a\u0e40\u0e41\u0e42\u0e43\u0e44\\\u0e4aSTUVWXYZ\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a0123456789\u0e4b\u0e4c\u0e4d\u0e4b\u20ac\u009f", |
||||||
|
Aliases: []string{"ibm-1160_P100-1999", "ibm-1160"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1162_P100-1999", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\u0081\u0082\u0083\u0084\u2026\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e2f\u0e30\u0e31\u0e32\u0e33\u0e34\u0e35\u0e36\u0e37\u0e38\u0e39\u0e3a\ufffd\ufffd\ufffd\ufffd\u0e3f\u0e40\u0e41\u0e42\u0e43\u0e44\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a\u0e4b\u0e4c\u0e4d\u0e4e\u0e4f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e5a\u0e5b\ufffd\ufffd\ufffd\ufffd", |
||||||
|
Aliases: []string{"ibm-1162_P100-1999", "ibm-1162"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1164_P100-1999", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u0103\u00e5\u00e7\u00f1[.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u0303\u00df]$*);^-/\u00c2\u00c4\u00c0\u00c1\u0102\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u20ab`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u0111\u0309\u0300\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u0152\u00c6\u20ac\u00b5~stuvwxyz\u00a1\u00bf\u0110\u0323\u0301\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u0153\u0178\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u01b0\u00f3\u01a1}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u01af\u00d3\u01a00123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ibm-1164_P100-1999", "ibm-1164"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-4517_P100-2005", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\ufe7c\ufe7d\u0640\u200b\ufe80\ufe81\ufe82\ufe83\u00b0.<(+!&\ufe84\ufe85\ufffd\ufffd\ufe8b\ufe8d\ufe8e\ufe8f\ufe91\u00a7$*);^-/\ufe93\ufe95\ufe97\ufe99\ufe9b\ufe9d\ufe9f\ufea1\u00fa,%_>?\ufea3\ufea5\ufea7\ufea9\ufeab\ufead\ufeaf\ufeb1\ufeb3\u00a3:\u00b5\u00e1'=\"\ufeb5abcdefghi\ufeb7\ufeb9\ufebb\ufebd\ufebf\ufec3\ufec7jklmnopqr\ufec9\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\u00a8stuvwxyz\ufed0\ufed1\ufed3\ufed5\ufed7\ufed9\ufedb\ufedd\ufef5\ufef6\ufef7\ufef8\ufffd\ufffd\ufefb\ufefc\ufedf\ufee1\ufee3\ufee5\ufee7\ufee9\u00e9ABCDEFGHI\u00ad\ufeeb\ufffd\ufeec\ufffd\ufeed\u00e8JKLMNOPQR\ufeef\ufef0\ufef1\ufef2\ufef3\ufffd\u00e7\u2007STUVWXYZ\u00f7\u060c\ufffd\u00d7\u061f\u061b0123456789\ufffd\ufffd\ufffd\ufffd\ufffd\u009f", |
||||||
|
Aliases: []string{"ibm-4517_P100-2005", "ibm-4517"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-4899_P100-1998", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd$.<(+|\u05d0\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd!\u00a2*);\u00ac-/\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd,%_>?\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd:#@'=\"\ufffd\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\ufffd\ufffd\u20ac\ufffd\u20aa\ufffd\ufffd\ufffd\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdABCDEFGHI\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdJKLMNOPQR\ufffd\u202d\u202e\u202c\ufffd\ufffd\ufffd\ufffdSTUVWXYZ\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\ufffd\u202a\u202b\u200e\u200f\u009f", |
||||||
|
Aliases: []string{"ibm-4899_P100-1998", "ibm-4899"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-4909_P100-1999", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u2018\u2019\u00a3\u20ac\ufffd\u00a6\u00a7\u00a8\u00a9\ufffd\u00ab\u00ac\u00ad\ufffd\u2015\u00b0\u00b1\u00b2\u00b3\u00b4\u0385\u0386\u0387\u0388\u0389\u038a\u00bb\u038c\u00bd\u038e\u038f\u0390\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\ufffd\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab\u03ac\u03ad\u03ae\u03af\u03b0\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\u03ca\u03cb\u03cc\u03cd\u03ce\ufffd", |
||||||
|
Aliases: []string{"ibm-4909_P100-1999", "ibm-4909"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-4971_P100-1999", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399[.<(+!&\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3]$*);^-/\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab|,%_>?\u00a8\u0386\u0388\u0389\u00a0\u038a\u038c\u038e\u038f`:#@'=\"\u0385abcdefghi\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u00b0jklmnopqr\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u00b4~stuvwxyz\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u00a3\u03ac\u03ad\u03ae\u03ca\u03af\u03cc\u03cd\u03cb\u03ce\u03c2\u03c4\u03c5\u03c6\u03c7\u03c8{ABCDEFGHI\u00ad\u03c9\u0390\u03b0\u2018\u2015}JKLMNOPQR\u00b1\u00bd\ufffd\u0387\u2019\u00a6\\\ufffdSTUVWXYZ\u00b2\u00a7\ufffd\ufffd\u00ab\u00ac0123456789\u00b3\u00a9\u20ac\ufffd\u00bb\u009f", |
||||||
|
Aliases: []string{"ibm-4971_P100-1999", "ibm-4971"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-5123_P100-1999", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \ufffd\uff61\uff62\uff63\uff64\uff65\uff66\uff67\uff68\u00a2.<(+|&\uff69\uff6a\uff6b\uff6c\uff6d\uff6e\uff6f\uff70\uff71!$*);\u00ac-/\uff72\uff73\uff74\uff75\uff76\uff77\uff78\uff79\ufffd,%_>?\uff7a\uff7b\uff7c\uff7d\uff7e\uff7f\uff80\uff81\uff82`:#@'=\"\ufffdabcdefghi\uff83\uff84\uff85\uff86\uff87\uff88\ufffdjklmnopqr\uff89\uff8a\uff8b\uff8c\uff8d\uff8e\u203e~stuvwxyz\uff8f\uff90\uff91[\uff92\uff93^\u00a3\u00a5\uff94\uff95\uff96\uff97\uff98\uff99\uff9a\uff9b\uff9c\uff9d]\uff9e\uff9f{ABCDEFGHI\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd}JKLMNOPQR\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\\\u20acSTUVWXYZ\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\ufffd\ufffd\ufffd\ufffd\ufffd\u009f", |
||||||
|
Aliases: []string{"ibm-5123_P100-1999", "ibm-5123"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-8482_P100-1999", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \uff61\uff62\uff63\uff64\uff65\uff66\uff67\uff68\uff69\u00a3.<(+|&\uff6a\uff6b\uff6c\uff6d\uff6e\uff6f\ufffd\uff70\ufffd!\u00a5*);\u00ac-/abcdefgh\ufffd,%_>?[ijklmnop`:#@'=\"]\uff71\uff72\uff73\uff74\uff75\uff76\uff77\uff78\uff79\uff7aq\uff7b\uff7c\uff7d\uff7e\uff7f\uff80\uff81\uff82\uff83\uff84\uff85\uff86\uff87\uff88\uff89r\ufffd\uff8a\uff8b\uff8c~\u203e\uff8d\uff8e\uff8f\uff90\uff91\uff92\uff93\uff94\uff95s\uff96\uff97\uff98\uff99^\u00a2\\tuvwxyz\uff9a\uff9b\uff9c\uff9d\uff9e\uff9f{ABCDEFGHI\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd}JKLMNOPQR\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd$\u20acSTUVWXYZ\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\ufffd\ufffd\ufffd\ufffd\ufffd\u009f", |
||||||
|
Aliases: []string{"ibm-8482_P100-1999", "ibm-8482"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-9067_X100-2005", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399[.<(+!&\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3]$*);^-/\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab|,%_>?\u00a8\u0386\u0388\u0389\u00a0\u038a\u038c\u038e\u038f`:#@'=\"\u0385abcdefghi\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u00b0jklmnopqr\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u00b4~stuvwxyz\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u00a3\u03ac\u03ad\u03ae\u03ca\u03af\u03cc\u03cd\u03cb\u03ce\u03c2\u03c4\u03c5\u03c6\u03c7\u03c8{ABCDEFGHI\u00ad\u03c9\u0390\u03b0\u2018\u2015}JKLMNOPQR\u00b1\u00bd\ufffd\u0387\u2019\u00a6\\\u20afSTUVWXYZ\u00b2\u00a7\u037a\ufffd\u00ab\u00ac0123456789\u00b3\u00a9\u20ac\ufffd\u00bb\u009f", |
||||||
|
Aliases: []string{"ibm-9067_X100-2005", "ibm-9067"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-12712_P100-1998", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u00a2.<(+|&\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1!$*);\u00ac-/\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u00a6,%_>?\ufffd\u05ea\ufffd\ufffd\u00a0\ufffd\ufffd\ufffd\u2017`:#@'=\"\ufffdabcdefghi\u00ab\u00bb\ufffd\ufffd\ufffd\u00b1\u00b0jklmnopqr\ufffd\ufffd\u20ac\u00b8\u20aa\u00a4\u00b5~stuvwxyz\ufffd\ufffd\ufffd\ufffd\ufffd\u00ae^\u00a3\u00a5\u2022\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u203e\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\ufffd\ufffd\ufffd\ufffd\ufffd}JKLMNOPQR\u00b9\u202d\u202e\u202c\ufffd\ufffd\\\u00f7STUVWXYZ\u00b2\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\u00b3\u202a\u202b\u200e\u200f\u009f", |
||||||
|
Aliases: []string{"ibm-12712_P100-1998", "ibm-12712", "ebcdic-he"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-16804_X110-1999", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0651\ufe7d\u0640\u200b\u0621\u0622\ufe82\u0623\u00a2.<(+|&\ufe84\u0624\ufffd\ufffd\u0626\u0627\ufe8e\u0628\ufe91!$*);\u00ac-/\u0629\u062a\ufe97\u062b\ufe9b\u062c\ufe9f\u062d\u00a6,%_>?\ufea3\u062e\ufea7\u062f\u0630\u0631\u0632\u0633\ufeb3\u060c:#@'=\"\u0634abcdefghi\ufeb7\u0635\ufebb\u0636\ufebf\u0637\u0638jklmnopqr\u0639\ufeca\ufecb\ufecc\u063a\ufece\ufecf\u00f7stuvwxyz\ufed0\u0641\ufed3\u0642\ufed7\u0643\ufedb\u0644\ufef5\ufef6\ufef7\ufef8\ufffd\ufffd\ufefb\ufefc\ufedf\u0645\ufee3\u0646\ufee7\u0647\u061bABCDEFGHI\u00ad\ufeeb\ufffd\ufeec\ufffd\u0648\u061fJKLMNOPQR\u0649\ufef0\u064a\ufef2\ufef3\u0660\u00d7\u2007STUVWXYZ\u0661\u0662\ufffd\u0663\u0664\u06650123456789\u20ac\u0666\u0667\u0668\u0669\u009f", |
||||||
|
Aliases: []string{"ibm-16804_X110-1999", "ibm-16804", "ebcdic-ar"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "KOI8-R", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u2500\u2502\u250c\u2510\u2514\u2518\u251c\u2524\u252c\u2534\u253c\u2580\u2584\u2588\u258c\u2590\u2591\u2592\u2593\u2320\u25a0\u2219\u221a\u2248\u2264\u2265\u00a0\u2321\u00b0\u00b2\u00b7\u00f7\u2550\u2551\u2552\u0451\u2553\u2554\u2555\u2556\u2557\u2558\u2559\u255a\u255b\u255c\u255d\u255e\u255f\u2560\u2561\u0401\u2562\u2563\u2564\u2565\u2566\u2567\u2568\u2569\u256a\u256b\u256c\u00a9\u044e\u0430\u0431\u0446\u0434\u0435\u0444\u0433\u0445\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u044f\u0440\u0441\u0442\u0443\u0436\u0432\u044c\u044b\u0437\u0448\u044d\u0449\u0447\u044a\u042e\u0410\u0411\u0426\u0414\u0415\u0424\u0413\u0425\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u042f\u0420\u0421\u0422\u0423\u0416\u0412\u042c\u042b\u0417\u0428\u042d\u0429\u0427\u042a", |
||||||
|
Aliases: []string{"csKOI8R"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "KOI8-U", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u2500\u2502\u250c\u2510\u2514\u2518\u251c\u2524\u252c\u2534\u253c\u2580\u2584\u2588\u258c\u2590\u2591\u2592\u2593\u2320\u25a0\u2219\u221a\u2248\u2264\u2265\u00a0\u2321\u00b0\u00b2\u00b7\u00f7\u2550\u2551\u2552\u0451\u0454\u2554\u0456\u0457\u2557\u2558\u2559\u255a\u255b\u0491\u255d\u255e\u255f\u2560\u2561\u0401\u0404\u2563\u0406\u0407\u2566\u2567\u2568\u2569\u256a\u0490\u256c\u00a9\u044e\u0430\u0431\u0446\u0434\u0435\u0444\u0433\u0445\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u044f\u0440\u0441\u0442\u0443\u0436\u0432\u044c\u044b\u0437\u0448\u044d\u0449\u0447\u044a\u042e\u0410\u0411\u0426\u0414\u0415\u0424\u0413\u0425\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u042f\u0420\u0421\u0422\u0423\u0416\u0412\u042c\u042b\u0417\u0428\u042d\u0429\u0427\u042a", |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1051_P100-1995", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\ufffd\u00c0\u00c2\u00c8\u00ca\u00cb\u00ce\u00cf\u00b4`\u02c6\u00a8\u02dc\u00d9\u00db\u00a3\u203e\u00dd\u00fd\u02da\u00c7\u00e7\u00d1\u00f1\u00a1\u00bf\u00a4\u00a3\u00a5\u00a7\u0192\u00a2\u00e2\u00ea\u00f4\u00fb\u00e1\u00e9\u00f3\u00fa\u00e0\u00e8\u00f2\u00f9\u00e4\u00eb\u00f6\u00fc\u00c5\u00ee\u00d8\u00c6\u00e5\u00ed\u00f8\u00e6\u00c4\u00ec\u00d6\u00dc\u00c9\u00ef\u00df\u00d4\u00c1\u00c3\u00e3\u00d0\u00f0\u00cd\u00cc\u00d3\u00d2\u00d5\u00f5\u0160\u0161\u00da\u0178\u00ff\u00de\u00fe\u00b7\u03bc\u00b6\u00be-\u00bc\u00bd\u00aa\u00ba\u00ab\u25a0\u00bb\u00b1\ufffd", |
||||||
|
Aliases: []string{"ibm-1051_P100-1995", "ibm-1051", "hp-roman8", "roman8", "r8", "csHPRoman8"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ibm-1276_P100-1995", |
||||||
|
SubstitutionChar: '?', |
||||||
|
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&\u2019()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_\u2018abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\ufffd\u00a1\u00a2\u00a3\u2044\u00a5\u0192\u00a7\u00a4'\u201c\u00ab\u2039\u203a\ufb01\ufb02\ufffd\u2013\u2020\u2021\u00b7\ufffd\u00b6\u2022\u201a\u201e\u201d\u00bb\u2026\u2030\ufffd\u00bf\ufffd`\u00b4\u02c6\u02dc\u00af\u02d8\u02d9\u00a8\ufffd\u02da\u00b8\ufffd\u02dd\u02db\u02c7\u2014\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u00c6\ufffd\u00aa\ufffd\ufffd\ufffd\ufffd\u0141\u00d8\u0152\u00ba\ufffd\ufffd\ufffd\ufffd\ufffd\u00e6\ufffd\ufffd\ufffd\u0131\ufffd\ufffd\u0142\u00f8\u0153\u00df\ufffd\ufffd\ufffd\ufffd", |
||||||
|
Aliases: []string{"ibm-1276_P100-1995", "ibm-1276", "Adobe-Standard-Encoding", "csAdobeStandardEncoding"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ebcdic-xml-us", |
||||||
|
SubstitutionChar: 0x6f, |
||||||
|
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\n\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00a2.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df!$*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5~stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae^\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u00af\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||||
|
Aliases: []string{"ebcdic-xml-us"}, |
||||||
|
}, |
||||||
|
} |
@ -0,0 +1,76 @@ |
|||||||
|
package mahonia |
||||||
|
|
||||||
|
// Converters for ASCII and ISO-8859-1
|
||||||
|
|
||||||
|
func init() { |
||||||
|
for i := 0; i < len(asciiCharsets); i++ { |
||||||
|
RegisterCharset(&asciiCharsets[i]) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
var asciiCharsets = []Charset{ |
||||||
|
{ |
||||||
|
Name: "US-ASCII", |
||||||
|
NewDecoder: func() Decoder { return decodeASCIIRune }, |
||||||
|
NewEncoder: func() Encoder { return encodeASCIIRune }, |
||||||
|
Aliases: []string{"ASCII", "US", "ISO646-US", "IBM367", "cp367", "ANSI_X3.4-1968", "iso-ir-6", "ANSI_X3.4-1986", "ISO_646.irv:1991", "csASCII"}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
Name: "ISO-8859-1", |
||||||
|
NewDecoder: func() Decoder { return decodeLatin1Rune }, |
||||||
|
NewEncoder: func() Encoder { return encodeLatin1Rune }, |
||||||
|
Aliases: []string{"latin1", "ISO Latin 1", "IBM819", "cp819", "ISO_8859-1:1987", "iso-ir-100", "l1", "csISOLatin1"}, |
||||||
|
}, |
||||||
|
} |
||||||
|
|
||||||
|
func decodeASCIIRune(p []byte) (c rune, size int, status Status) { |
||||||
|
if len(p) == 0 { |
||||||
|
status = NO_ROOM |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
b := p[0] |
||||||
|
if b > 127 { |
||||||
|
return 0xfffd, 1, INVALID_CHAR |
||||||
|
} |
||||||
|
return rune(b), 1, SUCCESS |
||||||
|
} |
||||||
|
|
||||||
|
func encodeASCIIRune(p []byte, c rune) (size int, status Status) { |
||||||
|
if len(p) == 0 { |
||||||
|
status = NO_ROOM |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
if c < 128 { |
||||||
|
p[0] = byte(c) |
||||||
|
return 1, SUCCESS |
||||||
|
} |
||||||
|
|
||||||
|
p[0] = '?' |
||||||
|
return 1, INVALID_CHAR |
||||||
|
} |
||||||
|
|
||||||
|
func decodeLatin1Rune(p []byte) (c rune, size int, status Status) { |
||||||
|
if len(p) == 0 { |
||||||
|
status = NO_ROOM |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
return rune(p[0]), 1, SUCCESS |
||||||
|
} |
||||||
|
|
||||||
|
func encodeLatin1Rune(p []byte, c rune) (size int, status Status) { |
||||||
|
if len(p) == 0 { |
||||||
|
status = NO_ROOM |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
if c < 256 { |
||||||
|
p[0] = byte(c) |
||||||
|
return 1, SUCCESS |
||||||
|
} |
||||||
|
|
||||||
|
p[0] = '?' |
||||||
|
return 1, INVALID_CHAR |
||||||
|
} |
@ -0,0 +1,89 @@ |
|||||||
|
package mahonia |
||||||
|
|
||||||
|
// Converters for Big 5 encoding.
|
||||||
|
|
||||||
|
import ( |
||||||
|
"sync" |
||||||
|
) |
||||||
|
|
||||||
|
func init() { |
||||||
|
RegisterCharset(&Charset{ |
||||||
|
Name: "Big5", |
||||||
|
Aliases: []string{"csBig5"}, |
||||||
|
NewDecoder: func() Decoder { |
||||||
|
return decodeBig5Rune |
||||||
|
}, |
||||||
|
NewEncoder: func() Encoder { |
||||||
|
big5Once.Do(reverseBig5Table) |
||||||
|
return encodeBig5Rune |
||||||
|
}, |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
func decodeBig5Rune(p []byte) (r rune, size int, status Status) { |
||||||
|
if len(p) == 0 { |
||||||
|
status = NO_ROOM |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
b := p[0] |
||||||
|
if b < 128 { |
||||||
|
return rune(b), 1, SUCCESS |
||||||
|
} |
||||||
|
|
||||||
|
if len(p) < 2 { |
||||||
|
status = NO_ROOM |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
c := int(p[0])<<8 + int(p[1]) |
||||||
|
c = int(big5ToUnicode[c]) |
||||||
|
if c > 0 { |
||||||
|
return rune(c), 2, SUCCESS |
||||||
|
} |
||||||
|
|
||||||
|
return 0xfffd, 1, INVALID_CHAR |
||||||
|
} |
||||||
|
|
||||||
|
func encodeBig5Rune(p []byte, r rune) (size int, status Status) { |
||||||
|
if len(p) == 0 { |
||||||
|
status = NO_ROOM |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
if r < 128 { |
||||||
|
p[0] = byte(r) |
||||||
|
return 1, SUCCESS |
||||||
|
} |
||||||
|
|
||||||
|
if len(p) < 2 { |
||||||
|
status = NO_ROOM |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
if r < 0x10000 { |
||||||
|
c := unicodeToBig5[r] |
||||||
|
if c > 0 { |
||||||
|
p[0] = byte(c >> 8) |
||||||
|
p[1] = byte(c) |
||||||
|
return 2, SUCCESS |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
p[0] = '?' |
||||||
|
return 1, INVALID_CHAR |
||||||
|
} |
||||||
|
|
||||||
|
var big5Once sync.Once |
||||||
|
|
||||||
|
var unicodeToBig5 []uint16 |
||||||
|
|
||||||
|
func reverseBig5Table() { |
||||||
|
unicodeToBig5 = make([]uint16, 65536) |
||||||
|
|
||||||
|
for big5, unicode := range big5ToUnicode { |
||||||
|
if unicode > 0 { |
||||||
|
unicodeToBig5[unicode] = uint16(big5) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,115 @@ |
|||||||
|
// This package is a character-set conversion library for Go.
|
||||||
|
//
|
||||||
|
// (DEPRECATED: use code.google.com/p/go.text/encoding, perhaps along with
|
||||||
|
// code.google.com/p/go.net/html/charset)
|
||||||
|
package mahonia |
||||||
|
|
||||||
|
import ( |
||||||
|
"bytes" |
||||||
|
"unicode" |
||||||
|
) |
||||||
|
|
||||||
|
// Status is the type for the status return value from a Decoder or Encoder.
|
||||||
|
type Status int |
||||||
|
|
||||||
|
const ( |
||||||
|
// SUCCESS means that the character was converted with no problems.
|
||||||
|
SUCCESS = Status(iota) |
||||||
|
|
||||||
|
// INVALID_CHAR means that the source contained invalid bytes, or that the character
|
||||||
|
// could not be represented in the destination encoding.
|
||||||
|
// The Encoder or Decoder should have output a substitute character.
|
||||||
|
INVALID_CHAR |
||||||
|
|
||||||
|
// NO_ROOM means there were not enough input bytes to form a complete character,
|
||||||
|
// or there was not enough room in the output buffer to write a complete character.
|
||||||
|
// No bytes were written, and no internal state was changed in the Encoder or Decoder.
|
||||||
|
NO_ROOM |
||||||
|
|
||||||
|
// STATE_ONLY means that bytes were read or written indicating a state transition,
|
||||||
|
// but no actual character was processed. (Examples: byte order marks, ISO-2022 escape sequences)
|
||||||
|
STATE_ONLY |
||||||
|
) |
||||||
|
|
||||||
|
// A Decoder is a function that decodes a character set, one character at a time.
|
||||||
|
// It works much like utf8.DecodeRune, but has an aditional status return value.
|
||||||
|
type Decoder func(p []byte) (c rune, size int, status Status) |
||||||
|
|
||||||
|
// An Encoder is a function that encodes a character set, one character at a time.
|
||||||
|
// It works much like utf8.EncodeRune, but has an additional status return value.
|
||||||
|
type Encoder func(p []byte, c rune) (size int, status Status) |
||||||
|
|
||||||
|
// A Charset represents a character set that can be converted, and contains functions
|
||||||
|
// to create Converters to encode and decode strings in that character set.
|
||||||
|
type Charset struct { |
||||||
|
// Name is the character set's canonical name.
|
||||||
|
Name string |
||||||
|
|
||||||
|
// Aliases returns a list of alternate names.
|
||||||
|
Aliases []string |
||||||
|
|
||||||
|
// NewDecoder returns a Decoder to convert from the charset to Unicode.
|
||||||
|
NewDecoder func() Decoder |
||||||
|
|
||||||
|
// NewEncoder returns an Encoder to convert from Unicode to the charset.
|
||||||
|
NewEncoder func() Encoder |
||||||
|
} |
||||||
|
|
||||||
|
// The charsets are stored in charsets under their canonical names.
|
||||||
|
var charsets = make(map[string]*Charset) |
||||||
|
|
||||||
|
// aliases maps their aliases to their canonical names.
|
||||||
|
var aliases = make(map[string]string) |
||||||
|
|
||||||
|
// simplifyName converts a name to lower case and removes non-alphanumeric characters.
|
||||||
|
// This is how the names are used as keys to the maps.
|
||||||
|
func simplifyName(name string) string { |
||||||
|
var buf bytes.Buffer |
||||||
|
for _, c := range name { |
||||||
|
switch { |
||||||
|
case unicode.IsDigit(c): |
||||||
|
buf.WriteRune(c) |
||||||
|
case unicode.IsLetter(c): |
||||||
|
buf.WriteRune(unicode.ToLower(c)) |
||||||
|
default: |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return buf.String() |
||||||
|
} |
||||||
|
|
||||||
|
// RegisterCharset adds a charset to the charsetMap.
|
||||||
|
func RegisterCharset(cs *Charset) { |
||||||
|
name := cs.Name |
||||||
|
charsets[name] = cs |
||||||
|
aliases[simplifyName(name)] = name |
||||||
|
for _, alias := range cs.Aliases { |
||||||
|
aliases[simplifyName(alias)] = name |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// GetCharset fetches a charset by name.
|
||||||
|
// If the name is not found, it returns nil.
|
||||||
|
func GetCharset(name string) *Charset { |
||||||
|
return charsets[aliases[simplifyName(name)]] |
||||||
|
} |
||||||
|
|
||||||
|
// NewDecoder returns a Decoder to decode the named charset.
|
||||||
|
// If the name is not found, it returns nil.
|
||||||
|
func NewDecoder(name string) Decoder { |
||||||
|
cs := GetCharset(name) |
||||||
|
if cs == nil { |
||||||
|
return nil |
||||||
|
} |
||||||
|
return cs.NewDecoder() |
||||||
|
} |
||||||
|
|
||||||
|
// NewEncoder returns an Encoder to encode the named charset.
|
||||||
|
func NewEncoder(name string) Encoder { |
||||||
|
cs := GetCharset(name) |
||||||
|
if cs == nil { |
||||||
|
return nil |
||||||
|
} |
||||||
|
return cs.NewEncoder() |
||||||
|
} |
@ -0,0 +1,135 @@ |
|||||||
|
package mahonia |
||||||
|
|
||||||
|
import ( |
||||||
|
"unicode/utf8" |
||||||
|
) |
||||||
|
|
||||||
|
// ConvertString converts a string from UTF-8 to e's encoding.
|
||||||
|
func (e Encoder) ConvertString(s string) string { |
||||||
|
dest := make([]byte, len(s)+10) |
||||||
|
destPos := 0 |
||||||
|
|
||||||
|
for _, rune := range s { |
||||||
|
retry: |
||||||
|
size, status := e(dest[destPos:], rune) |
||||||
|
|
||||||
|
if status == NO_ROOM { |
||||||
|
newDest := make([]byte, len(dest)*2) |
||||||
|
copy(newDest, dest) |
||||||
|
dest = newDest |
||||||
|
goto retry |
||||||
|
} |
||||||
|
|
||||||
|
if status == STATE_ONLY { |
||||||
|
destPos += size |
||||||
|
goto retry |
||||||
|
} |
||||||
|
|
||||||
|
destPos += size |
||||||
|
} |
||||||
|
|
||||||
|
return string(dest[:destPos]) |
||||||
|
} |
||||||
|
|
||||||
|
// ConvertString converts a string from d's encoding to UTF-8.
|
||||||
|
func (d Decoder) ConvertString(s string) string { |
||||||
|
bytes := []byte(s) |
||||||
|
runes := make([]rune, len(s)) |
||||||
|
destPos := 0 |
||||||
|
|
||||||
|
for len(bytes) > 0 { |
||||||
|
c, size, status := d(bytes) |
||||||
|
|
||||||
|
if status == STATE_ONLY { |
||||||
|
bytes = bytes[size:] |
||||||
|
continue |
||||||
|
} |
||||||
|
|
||||||
|
if status == NO_ROOM { |
||||||
|
c = 0xfffd |
||||||
|
size = len(bytes) |
||||||
|
status = INVALID_CHAR |
||||||
|
} |
||||||
|
|
||||||
|
bytes = bytes[size:] |
||||||
|
runes[destPos] = c |
||||||
|
destPos++ |
||||||
|
} |
||||||
|
|
||||||
|
return string(runes[:destPos]) |
||||||
|
} |
||||||
|
|
||||||
|
// ConvertStringOK converts a string from UTF-8 to e's encoding. It also
|
||||||
|
// returns a boolean indicating whether every character was converted
|
||||||
|
// successfully.
|
||||||
|
func (e Encoder) ConvertStringOK(s string) (result string, ok bool) { |
||||||
|
dest := make([]byte, len(s)+10) |
||||||
|
destPos := 0 |
||||||
|
ok = true |
||||||
|
|
||||||
|
for i, r := range s { |
||||||
|
// The following test is copied from utf8.ValidString.
|
||||||
|
if r == utf8.RuneError && ok { |
||||||
|
_, size := utf8.DecodeRuneInString(s[i:]) |
||||||
|
if size == 1 { |
||||||
|
ok = false |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
retry: |
||||||
|
size, status := e(dest[destPos:], r) |
||||||
|
|
||||||
|
switch status { |
||||||
|
case NO_ROOM: |
||||||
|
newDest := make([]byte, len(dest)*2) |
||||||
|
copy(newDest, dest) |
||||||
|
dest = newDest |
||||||
|
goto retry |
||||||
|
|
||||||
|
case STATE_ONLY: |
||||||
|
destPos += size |
||||||
|
goto retry |
||||||
|
|
||||||
|
case INVALID_CHAR: |
||||||
|
ok = false |
||||||
|
} |
||||||
|
|
||||||
|
destPos += size |
||||||
|
} |
||||||
|
|
||||||
|
return string(dest[:destPos]), ok |
||||||
|
} |
||||||
|
|
||||||
|
// ConvertStringOK converts a string from d's encoding to UTF-8.
|
||||||
|
// It also returns a boolean indicating whether every character was converted
|
||||||
|
// successfully.
|
||||||
|
func (d Decoder) ConvertStringOK(s string) (result string, ok bool) { |
||||||
|
bytes := []byte(s) |
||||||
|
runes := make([]rune, len(s)) |
||||||
|
destPos := 0 |
||||||
|
ok = true |
||||||
|
|
||||||
|
for len(bytes) > 0 { |
||||||
|
c, size, status := d(bytes) |
||||||
|
|
||||||
|
switch status { |
||||||
|
case STATE_ONLY: |
||||||
|
bytes = bytes[size:] |
||||||
|
continue |
||||||
|
|
||||||
|
case NO_ROOM: |
||||||
|
c = 0xfffd |
||||||
|
size = len(bytes) |
||||||
|
ok = false |
||||||
|
|
||||||
|
case INVALID_CHAR: |
||||||
|
ok = false |
||||||
|
} |
||||||
|
|
||||||
|
bytes = bytes[size:] |
||||||
|
runes[destPos] = c |
||||||
|
destPos++ |
||||||
|
} |
||||||
|
|
||||||
|
return string(runes[:destPos]), ok |
||||||
|
} |
@ -0,0 +1,76 @@ |
|||||||
|
package mahonia |
||||||
|
|
||||||
|
import ( |
||||||
|
"unicode/utf8" |
||||||
|
) |
||||||
|
|
||||||
|
// Converters for Microsoft's version of the EUC-JP encoding
|
||||||
|
|
||||||
|
func init() { |
||||||
|
RegisterCharset(&Charset{ |
||||||
|
Name: "cp51932", |
||||||
|
Aliases: []string{"windows-51932"}, |
||||||
|
NewDecoder: func() Decoder { |
||||||
|
return decodeCP51932 |
||||||
|
}, |
||||||
|
NewEncoder: func() Encoder { |
||||||
|
msJISTable.Reverse() |
||||||
|
return encodeCP51932 |
||||||
|
}, |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
func decodeCP51932(p []byte) (c rune, size int, status Status) { |
||||||
|
if len(p) == 0 { |
||||||
|
return 0, 0, NO_ROOM |
||||||
|
} |
||||||
|
|
||||||
|
b := p[0] |
||||||
|
switch { |
||||||
|
case b < 0x80: |
||||||
|
return rune(b), 1, SUCCESS |
||||||
|
|
||||||
|
case b == 0x8e: |
||||||
|
if len(p) < 2 { |
||||||
|
return 0, 0, NO_ROOM |
||||||
|
} |
||||||
|
b2 := p[1] |
||||||
|
if b2 < 0xa1 || b2 > 0xdf { |
||||||
|
return utf8.RuneError, 1, INVALID_CHAR |
||||||
|
} |
||||||
|
return rune(b2) + (0xff61 - 0xa1), 2, SUCCESS |
||||||
|
|
||||||
|
case 0xa1 <= b && b <= 0xfe: |
||||||
|
return msJISTable.DecodeHigh(p) |
||||||
|
} |
||||||
|
|
||||||
|
return utf8.RuneError, 1, INVALID_CHAR |
||||||
|
} |
||||||
|
|
||||||
|
func encodeCP51932(p []byte, c rune) (size int, status Status) { |
||||||
|
if len(p) == 0 { |
||||||
|
return 0, NO_ROOM |
||||||
|
} |
||||||
|
|
||||||
|
if c < 0x80 { |
||||||
|
p[0] = byte(c) |
||||||
|
return 1, SUCCESS |
||||||
|
} |
||||||
|
|
||||||
|
if len(p) < 2 { |
||||||
|
return 0, NO_ROOM |
||||||
|
} |
||||||
|
|
||||||
|
if c > 0xffff { |
||||||
|
p[0] = '?' |
||||||
|
return 1, INVALID_CHAR |
||||||
|
} |
||||||
|
|
||||||
|
if 0xff61 <= c && c <= 0xff9f { |
||||||
|
p[0] = 0x8e |
||||||
|
p[1] = byte(c - (0xff61 - 0xa1)) |
||||||
|
return 2, SUCCESS |
||||||
|
} |
||||||
|
|
||||||
|
return msJISTable.EncodeHigh(p, c) |
||||||
|
} |
@ -0,0 +1,179 @@ |
|||||||
|
package mahonia |
||||||
|
|
||||||
|
// decoding HTML entities
|
||||||
|
|
||||||
|
import ( |
||||||
|
"sort" |
||||||
|
) |
||||||
|
|
||||||
|
// EntityDecoder returns a Decoder that decodes HTML character entities.
|
||||||
|
// If there is no valid character entity at the current position, it returns INVALID_CHAR.
|
||||||
|
// So it needs to be combined with another Decoder via FallbackDecoder.
|
||||||
|
func EntityDecoder() Decoder { |
||||||
|
var leftover rune // leftover rune from two-rune entity
|
||||||
|
return func(p []byte) (r rune, size int, status Status) { |
||||||
|
if leftover != 0 { |
||||||
|
r = leftover |
||||||
|
leftover = 0 |
||||||
|
return r, 0, SUCCESS |
||||||
|
} |
||||||
|
|
||||||
|
if len(p) == 0 { |
||||||
|
return 0, 0, NO_ROOM |
||||||
|
} |
||||||
|
|
||||||
|
if p[0] != '&' { |
||||||
|
return 0xfffd, 1, INVALID_CHAR |
||||||
|
} |
||||||
|
|
||||||
|
if len(p) < 3 { |
||||||
|
return 0, 1, NO_ROOM |
||||||
|
} |
||||||
|
|
||||||
|
r, size, status = 0xfffd, 1, INVALID_CHAR |
||||||
|
n := 1 // number of bytes read so far
|
||||||
|
|
||||||
|
if p[n] == '#' { |
||||||
|
n++ |
||||||
|
c := p[n] |
||||||
|
hex := false |
||||||
|
if c == 'x' || c == 'X' { |
||||||
|
hex = true |
||||||
|
n++ |
||||||
|
} |
||||||
|
|
||||||
|
var x rune |
||||||
|
for n < len(p) { |
||||||
|
c = p[n] |
||||||
|
n++ |
||||||
|
if hex { |
||||||
|
if '0' <= c && c <= '9' { |
||||||
|
x = 16*x + rune(c) - '0' |
||||||
|
continue |
||||||
|
} else if 'a' <= c && c <= 'f' { |
||||||
|
x = 16*x + rune(c) - 'a' + 10 |
||||||
|
continue |
||||||
|
} else if 'A' <= c && c <= 'F' { |
||||||
|
x = 16*x + rune(c) - 'A' + 10 |
||||||
|
continue |
||||||
|
} |
||||||
|
} else if '0' <= c && c <= '9' { |
||||||
|
x = 10*x + rune(c) - '0' |
||||||
|
continue |
||||||
|
} |
||||||
|
if c != ';' { |
||||||
|
n-- |
||||||
|
} |
||||||
|
break |
||||||
|
} |
||||||
|
|
||||||
|
if n == len(p) && p[n-1] != ';' { |
||||||
|
return 0, 0, NO_ROOM |
||||||
|
} |
||||||
|
|
||||||
|
size = n |
||||||
|
if p[n-1] == ';' { |
||||||
|
n-- |
||||||
|
} |
||||||
|
if hex { |
||||||
|
n-- |
||||||
|
} |
||||||
|
n-- |
||||||
|
// Now n is the number of actual digits read.
|
||||||
|
if n == 0 { |
||||||
|
return 0xfffd, 1, INVALID_CHAR |
||||||
|
} |
||||||
|
|
||||||
|
if 0x80 <= x && x <= 0x9F { |
||||||
|
// Replace characters from Windows-1252 with UTF-8 equivalents.
|
||||||
|
x = replacementTable[x-0x80] |
||||||
|
} else if x == 0 || (0xD800 <= x && x <= 0xDFFF) || x > 0x10FFFF { |
||||||
|
// Replace invalid characters with the replacement character.
|
||||||
|
return 0xfffd, size, INVALID_CHAR |
||||||
|
} |
||||||
|
|
||||||
|
r = x |
||||||
|
status = SUCCESS |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// Look for a named entity in EntityList.
|
||||||
|
|
||||||
|
possible := entityList |
||||||
|
for len(possible) > 0 { |
||||||
|
if len(p) <= n { |
||||||
|
leftover = 0 |
||||||
|
return 0, 0, NO_ROOM |
||||||
|
} |
||||||
|
|
||||||
|
c := p[n] |
||||||
|
|
||||||
|
// Narrow down the selection in possible to those items that have c in the
|
||||||
|
// appropriate byte.
|
||||||
|
first := sort.Search(len(possible), func(i int) bool { |
||||||
|
e := possible[i].name |
||||||
|
if len(e) < n { |
||||||
|
return false |
||||||
|
} |
||||||
|
return e[n-1] >= c |
||||||
|
}) |
||||||
|
possible = possible[first:] |
||||||
|
last := sort.Search(len(possible), func(i int) bool { |
||||||
|
return possible[i].name[n-1] > c |
||||||
|
}) |
||||||
|
possible = possible[:last] |
||||||
|
|
||||||
|
n++ |
||||||
|
if len(possible) > 0 && len(possible[0].name) == n-1 { |
||||||
|
r, leftover = possible[0].r1, possible[0].r2 |
||||||
|
size = n |
||||||
|
status = SUCCESS |
||||||
|
// but don't return yet, since we need the longest match
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// This table is copied from /src/pkg/html/escape.go in the Go source
|
||||||
|
//
|
||||||
|
// These replacements permit compatibility with old numeric entities that
|
||||||
|
// assumed Windows-1252 encoding.
|
||||||
|
// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#consume-a-character-reference
|
||||||
|
var replacementTable = [...]rune{ |
||||||
|
'\u20AC', // First entry is what 0x80 should be replaced with.
|
||||||
|
'\u0081', |
||||||
|
'\u201A', |
||||||
|
'\u0192', |
||||||
|
'\u201E', |
||||||
|
'\u2026', |
||||||
|
'\u2020', |
||||||
|
'\u2021', |
||||||
|
'\u02C6', |
||||||
|
'\u2030', |
||||||
|
'\u0160', |
||||||
|
'\u2039', |
||||||
|
'\u0152', |
||||||
|
'\u008D', |
||||||
|
'\u017D', |
||||||
|
'\u008F', |
||||||
|
'\u0090', |
||||||
|
'\u2018', |
||||||
|
'\u2019', |
||||||
|
'\u201C', |
||||||
|
'\u201D', |
||||||
|
'\u2022', |
||||||
|
'\u2013', |
||||||
|
'\u2014', |
||||||
|
'\u02DC', |
||||||
|
'\u2122', |
||||||
|
'\u0161', |
||||||
|
'\u203A', |
||||||
|
'\u0153', |
||||||
|
'\u009D', |
||||||
|
'\u017E', |
||||||
|
'\u0178', // Last entry is 0x9F.
|
||||||
|
// 0x00->'\uFFFD' is handled programmatically.
|
||||||
|
// 0x0D->'\u000D' is a no-op.
|
||||||
|
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue