olinox14 3 年 前
コミット
ce68802028

+ 13 - 0
.gitignore

@@ -0,0 +1,13 @@
+*.pyc
+.project
+.pydevproject
+*.pyproj
+*.pyproj.user
+*.sln
+.vs/
+.settings/
+temp/
+test/
+output/
+*.log
+setup-pardit.exe

+ 27 - 0
.gitlab-ci.yml

@@ -0,0 +1,27 @@
+
+stages:
+  - test
+  - deploy
+
+#variables:
+#  CI_DEBUG_TRACE: "true"
+
+nose2_job:
+  stage: test
+  before_script:
+  - pip67 install -r requirements.txt
+  script:
+  - nose2
+      
+deploy_job:
+  stage: deploy
+  variables:
+    DEPLOY_TO: \\BUILD-01\build\pardit
+  script:
+    - echo Deploy to %DEPLOY_TO%
+    - copy /Y %cd%\VERSION.txt %DEPLOY_TO%
+    - iscc /O%DEPLOY_TO% setup.iss
+    # Attention: iscc.exe provoque un exit, il doit etre execute en dernier
+  when: manual
+  only:
+  - master

+ 33 - 0
README.md

@@ -0,0 +1,33 @@
+# Pardit - Production automatisée de réponse aux demandes d'intention de travaux
+
+[![pipeline status](http://CODEBOX/Culture-Territo-BI/pardit/badges/master/pipeline.svg)](http://CODEBOX/Culture-Territo-BI/pardit/commits/master)
+
+**Pardit** est un programme python utilisé pour générer automatiquement des récépissés de demandes d'intention de travaux (DT/DICT).
+
+Les demandes, initialement transmises au format PDF, sont désormais accompagnées d'un fichier XML, selon la réglementation.
+C'est ce dernier fichier qui est utilisé pour générer les réponses.
+
+> Application développée avec Python 3.6 + Pyqt5
+
+### Principe de fonctionnement
+
+Fichier XML => Traitement Pardit => Récépissé(s) au format PDF + Mail de réponse
+
+Le fichier XML est traité, les récépissés sont créés et automatiquement joints à un mail de réponse prêt à l'envoi.
+
+### Configuration
+
+Le traitement est contrôlé par le fichier de configuration `pardit.yaml`.
+
+Outre les principaux paramètres (répertoire de sortie, construction des emails...), ce fichier permet de faire correspondre les champs du XML source et ceux du PDF cible, de leur attribuer des valeurs fixes, ou d'y appliquer quelques fonctions simples.
+
+Cette configuration peut être partiellement surchargée par les paramètres du fichier utilisateur (`%appdata%\pardit\userdata.yml`).
+
+### Installation
+
+-	Télécharger et installer le [Pack Python 3.6 CD67](http://depot.bas-rhin.fr/build/python/) depuis le dépot.
+-	Télécharger et installer [Pardit](http://depot.bas-rhin.fr/build/pardit/setup-pardit.exe) depuis le dépot.
+
+> Répertoire d’installation : C:\Applications_CD67\MRI-PARDIT
+
+A l’installation, un raccourci sera placé sur le bureau.

+ 0 - 0
core/__init__.py


+ 119 - 0
core/config.py

@@ -0,0 +1,119 @@
+'''
+Created on 17 avr. 2018
+
+@author: olivier.massot
+'''
+import collections
+
+from cerberus.validator import Validator
+import yaml
+from yaml.parser import ParserError
+
+from core import constants
+
+
+CONFIG = {}
+
+_SCHEMA = {
+          'repertoire_defaut': {'type': 'string', 'required': True},
+          'repertoire_sortie': {'type': 'string', 'required': True},
+          'donnees': {
+                      'type': 'dict',
+                      'schema': {
+                                 'dict': {'type': 'dict', 'required': True},
+                                 'dt': {'type': 'dict', 'required': True},
+                                 'commun': {'type': 'dict', 'required': True},
+                                },
+                      'required': True
+                      },
+          'mail': {'type': 'dict',
+                   'schema': {
+                                'dict': {
+                                            'type': 'dict',
+                                            'schema': {
+                                                       'dest': {'type': 'string', 'required': True},
+                                                       'objet': {'type': 'string', 'required': True},
+                                                       'texte': {'type': 'string', 'required': True},
+                                                       },
+                                            'required': True
+                                        },
+                                'dt':  {
+                                            'type': 'dict',
+                                            'schema': {
+                                                       'dest': {'type': 'string'},
+                                                       'objet': {'type': 'string'},
+                                                       'texte': {'type': 'string'},
+                                                       },
+                                            'required': True
+                                        }
+                             },
+                    'required': True
+                   },
+          'modifiables': {'type': 'list', 'required': True}
+         }
+
+class MissingConfigFile(Exception):
+    """ Fichier de configuration manquant """
+    pass
+
+class InvalidConfigFile(Exception):
+    """ Fichier de configuration invalide """
+    pass
+
+def deepupdate(d, u):
+    for k, v in u.items():
+        if isinstance(v, collections.Mapping):
+            d[k] = deepupdate(d.get(k, {}), v)
+        else:
+            d[k] = v
+    return d
+
+def load():
+
+    # charge le fichier de configuration de base
+    try:
+        with open(constants.CONFIG_FILE_PATH, "rb") as f:
+            baseconf = yaml.load(f)
+    except FileNotFoundError:
+        raise MissingConfigFile("Le fichier de configuration '{}' est introuvable".format(constants.CONFIG_FILE_PATH))
+    except ParserError as e:
+        raise InvalidConfigFile("Le fichier de configuration '{}' comporte des erreurs ({})".format(constants.CONFIG_FILE_PATH, e))
+
+    deepupdate(CONFIG, baseconf)
+
+    # surcharge la config avec la config utilisateur
+    try:
+        with open(constants.USER_DATA_PATH, "rb") as f:
+            userconf = yaml.load(f)
+    except FileNotFoundError:
+        pass
+    except ParserError as e:
+        raise InvalidConfigFile("Le fichier de configuration '{}' comporte des erreurs ({})".format(constants.USER_DATA_PATH, e))
+
+    userconf = patch1(userconf)
+
+    userconf = {key: value for key, value in userconf.items() if value}
+
+    deepupdate(CONFIG, userconf)
+
+    # contrôle le schema de la config
+    validator = Validator(_SCHEMA, allow_unknown=True)
+    if not validator.validate(CONFIG):
+        raise InvalidConfigFile("Erreur dans les fichiers de configuration: {}".format(validator.errors))
+
+def get(*keys):
+    dataset = dict(CONFIG)
+    for key in keys:
+        dataset = dataset[key]
+    return dataset
+
+def patch1(userconf):
+    """ corrige le fichier de données utilisateur entre la verison 1.0 et 1.1 """
+    if not "donnees" in userconf:
+        userconf = {"donnees": {"commun": userconf}}
+    return userconf
+
+
+if __name__ == "__main__":
+    load()
+    print(CONFIG)

+ 25 - 0
core/constants.py

@@ -0,0 +1,25 @@
+'''
+
+    Configuration standard de pardit.
+
+@author: olivier.massot,sept. 2017
+'''
+from tempfile import mkdtemp
+
+from path import Path
+
+# Répertoire de l'application
+APP_DIR = Path(__file__).parent.parent
+
+# Chemin d'accès au modèle PDF
+TEMPLATE_PATH = APP_DIR / r"templates\template.pdf"
+
+# Chemin d'accès au fichier de config
+CONFIG_FILE_PATH = APP_DIR / "pardit.yaml"
+
+# Chemin d'accès au fichier de config utilisateur (et création s'il n'existe pas)
+USER_DATA_DIR = Path("%appdata%").expandvars() / "pardit"
+USER_DATA_PATH = USER_DATA_DIR / "userdata.yml"
+
+# Repertoire temporaire: est nettoyé à la fermeture de pardit, sauf en cas d'erreur.
+TMPDIR = Path(mkdtemp(prefix='pardit_'))

+ 30 - 0
core/outlook.py

@@ -0,0 +1,30 @@
+'''
+
+    Interface avec MS Outlook (via win32)
+
+@author: olivier.massot, sept. 2017
+'''
+import win32com.client as win32
+
+def display_mail(to, subject, content, attachments=[]):
+    """ Créé et affiche le mail de réponse prêt à l'envoi """
+    outlook = win32.Dispatch('outlook.application')
+    mail = outlook.CreateItem(0)
+    mail.To = to
+    mail.Subject = subject
+    mail.HtmlBody = content
+
+    for path in attachments:
+        mail.Attachments.Add(path)
+
+    mail.Display(True)
+
+class Mail():
+    def __init__(self, to, subject, content, attachments=[]):
+        self.to = to
+        self.subject = subject
+        self.content = content
+        self.attachments = attachments
+
+    def display(self):
+        display_mail(self.to, self.subject, self.content, self.attachments)

+ 77 - 0
core/pdfform.py

@@ -0,0 +1,77 @@
+'''
+
+    Manipulation des formulaires PDF
+
+@author: olivier.massot, sept. 2017
+'''
+import codecs
+import subprocess
+
+from path import Path
+
+
+PDFTK_PATH = Path(__file__).parent.parent / r"bin\pdftk.exe"
+
+def gen_xfdf(filename, datas={}):
+    ''' Generates a temp XFDF file suited for fill_form function, based on dict input data '''
+
+    fields = []
+    for key, value in datas.items():
+        fields.append("""<field name="%s"><value>%s</value></field>""" % (key, _normalize(value)))
+
+    tpl = """<?xml version="1.0" encoding="UTF-8"?>
+    <xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">
+        <fields>
+            %s
+        </fields>
+    </xfdf>""" % "\n\t\t\t".join(fields)
+
+    filename = Path(filename)
+    with open(filename, 'w') as f:
+        f.write(tpl)
+
+    convert_to_utf8(filename)
+
+    return filename
+
+def convert_to_utf8(filename):
+    f = codecs.open(filename, 'r', 'cp1252', errors='ignore')
+    u = f.read()  # now the contents have been transformed to a Unicode string
+    out = codecs.open(filename, 'w', 'utf-8', errors='ignore')
+    out.write(u)  # and now the contents have been output as UTF-8
+    f.close()
+    out.close()
+
+def fill_form(pdfname, xfdfname, out_file, flatten=True):
+    '''
+        Fills a PDF form with given dict input data.
+        Return temp file if no out_file provided.
+    '''
+    cmd = "%s %s fill_form %s output %s need_appearances" % (PDFTK_PATH, pdfname, xfdfname, out_file)
+    if flatten:
+        cmd += ' flatten'
+
+    run_command(cmd, True)
+
+    return out_file
+
+def check_output(*popenargs, **kwargs):
+    if 'stdout' in kwargs:
+        raise ValueError('stdout argument not allowed, it will be overridden.')
+    process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
+    output, unused_err = process.communicate()
+    retcode = process.poll()
+    if retcode:
+        cmd = kwargs.get("args")
+        if cmd is None:
+            cmd = popenargs[0]
+        raise subprocess.CalledProcessError(retcode, cmd)
+    return output
+
+def _normalize(value):
+    return str(value).replace("\"", "'").replace("<", "&lt;").replace(">", "&gt;")
+
+def run_command(command, shell=False):
+    ''' run a system command and yield output '''
+    p = check_output(command, shell=shell)
+    return str(p).split('\n')

+ 207 - 0
core/process.py

@@ -0,0 +1,207 @@
+'''
+
+  process(xmlpath) : Process principal de Pardit
+
+* Parse un fichier XML
+* Transforme les données selon les consignes issues des fichiers de configurations pardit.yaml et userdata.yaml
+* Génère un fichier XFDF avec ces données
+* Injecte ce fichier dans le formulaire PDF.
+
+Retourne le(s) chemin(s) d'accès du/des fichier(s) généré(s), ainsi que la ou les adresses mails des contacts correspondants.
+
+@author: olivier.massot, sept. 2017
+'''
+import datetime
+import re
+from shutil import SameFileError
+import subprocess
+import tempfile
+
+from path import Path
+
+from core import config
+from core.constants import TEMPLATE_PATH
+from core.outlook import Mail
+from core.pdfform import fill_form, gen_xfdf
+from core.xmlparser import parse
+
+
+class XmlFileError(Exception):
+    pass
+
+class ProcessNotNeeded(Exception):
+    pass
+
+class MissingValue(ValueError):
+    """ erreur levée par les fonctions additionnelles lorsque la valeur manque """
+    pass
+
+
+# *************** METHODES SPECIALES DU FICHIER DE CONFIG ***************
+
+def _parsedate(datestring):
+    """ parse a string to a datetime """
+    if not datestring:
+        raise MissingValue
+    return datetime.datetime.strptime(datestring[:10], "%Y-%m-%d")
+
+def _day(datestring):
+    """ extrait le jour 'dd' d'une datestring ('dd/mm/yyyy') """
+    return _parsedate(datestring).strftime("%d")
+
+def _month(datestring):
+    """ extrait le mois 'mm' d'une datestring ('dd/mm/yyyy') """
+    return _parsedate(datestring).strftime("%m")
+
+def _year(datestring):
+    """ extrait l'année 'yyyy' d'une datestring ('dd/mm/yyyy') """
+    return _parsedate(datestring).strftime("%Y")
+
+def _now(*args):  # @UnusedVariable
+    """ retourne la date du jour ('dd/mm/yyyy')  """
+    # return datestring: dd/mm/yyyy
+    return datetime.date.today().strftime("%Y-%m-%d")
+
+_FUNCTIONS = {"JOUR": _day,
+              "MOIS": _month,
+              "ANNEE": _year,
+              "MAINTENANT": _now}
+
+
+
+
+# *************** FONCTIONS DE TRAITEMENT DES DONNEES ***************
+
+def process(xmlpath):
+    """ Traite les données XML au moyen du fichier de configuration
+    pour générer le ou les Pdf de réponse """
+
+    # Chemin d'accès au fichier de données
+    xmlpath = Path(xmlpath)
+
+    # Détermine et créé le répertoire de sortie
+    output_dir = Path(config.get("repertoire_sortie")).abspath() / xmlpath.namebase
+    output_dir.makedirs_p()
+
+    # Parse une premiere fois les données du fichier XML
+    xmldata = parse(xmlpath)
+
+    # Determine le type de demande (dt, dict, conjointe)
+    first_nodes = {node.split(".")[0] for node in xmldata}
+    if "dtDictConjointes" in first_nodes:
+        if xmldata.get("dtDictConjointes.partieDT.souhaitsPourLeRecepisse.souhaiteRecevoirLeRecepisse", "") == "true":
+            a_traiter = {"dict": parse(xmlpath, "partieDICT"), "dt": parse(xmlpath, "partieDT")}
+        else:
+            a_traiter = {"dict": parse(xmlpath, "partieDICT")}
+    elif "DT" in first_nodes:
+        a_traiter = {"dt": parse(xmlpath, "DT")}
+    elif "DICT" in first_nodes:
+        a_traiter = {"dict": parse(xmlpath, "DICT")}
+    else:
+        raise XmlFileError("Le format du fichier XML n'est pas reconnu")
+
+    # Traite la ou les demandes de réponse
+    outputfiles = []
+    mails = []
+
+    for doctype, xmldata in a_traiter.items():
+
+        # Construit le modele de reponse
+        modele = {}
+        modele.update(config.get("donnees", "commun"))  # Donnees communes à toutes les réponses
+        modele.update(config.get("donnees", doctype))  # Données spécifique au type de réponse
+
+        # inject_data remplace les <...> par les valeurs des champs correspondants
+        # eval_ parse et évalue les éventuelles fonctions de l'expression
+        reponse = {field: eval_(inject_data(str(value), xmldata)) for field, value in modele.items()}
+
+        # Patch 1: on coche la case 'demande conjointe' lorsque la demande est conjointe
+        if "dtDictConjointes" in first_nodes:
+            reponse["Recepisse_DT"] = "Non"
+            reponse["Recepisse_DICT"] = "Non"
+            reponse["Recepisse_DC"] = "Oui"
+
+        outputname = output_dir / "Recepisse_{}.pdf".format(doctype.upper())
+
+        make_pdf(reponse, outputname, keep_xfdf=True)
+        outputfiles.append(outputname)
+
+        if doctype == "dict" or xmldata.get("souhaitsPourLeRecepisse.souhaiteRecevoirLeRecepisse") == "true":
+            contact = eval_(inject_data(config.get("mail", doctype, "dest"), xmldata))
+            subject = eval_(inject_data(config.get("mail", doctype, "objet"), xmldata))
+            content = eval_(inject_data(config.get("mail", doctype, "texte"), xmldata))
+            mail = Mail(contact, subject, content)
+
+            if not contact in [mail.to for mail in mails]:
+                mails.append(mail)
+
+    with open(output_dir / "contact.txt", "w+") as f:
+        f.write("\n".join([mail.to for mail in mails]))
+
+    # Patch 2: en cas de demande conjointe, et si le demandeur DT est le même que le demandeur DICT, on ne joint qu'un seul document au mail.
+    # On supprime le recepisse DT, et on renomme le recepisse DICT en recepisse DC
+    if len(mails) == 1 and len(outputfiles) > 1:
+        rec_dict, rec_dt = outputfiles
+        rec_dc = rec_dict.parent / "Recepisse_DC.pdf"
+        rec_dc.remove_p()
+        rec_dict.rename(rec_dc)
+        rec_dt.remove_p()
+        outputfiles = [rec_dc]
+
+    # Créé une svg du fichier XML traité
+    try:
+        xmlpath.copy(output_dir)
+    except SameFileError:
+        pass
+
+    return outputfiles, mails
+
+
+def inject_data(value, xmldata):
+    """ injecte les données issues du fichier XML parsé
+        dans la valeur du champ. """
+    def _get(matchobj):
+        key = matchobj.group(1)
+        return xmldata.get(key, "")
+    value = re.sub(r"<([^<>]*)>", _get, value)
+    return value
+
+def eval_(value):
+    """ applique les éventuelles fonctions à la valeur du champ """
+    value = str(value) if value != None else ""
+
+    for name, fct in _FUNCTIONS.items():
+        match = re.search(r"{}\((.*)\)".format(name), str(value))
+        if match:
+            value = match.group(1) if match.group(1) else ''
+            value = eval_(value)
+
+            try:
+                value = fct(value)
+            except MissingValue:
+                value = ""
+
+    return value
+
+def make_pdf(data, outputname, keep_xfdf=False):
+    """ injecte les données 'data' dans le Pdf modèle """
+    with tempfile.TemporaryDirectory() as tmpdir:
+        tmpdir = Path(tmpdir)
+
+        tmpform = TEMPLATE_PATH.copy(tmpdir)  # @UndefinedVariable
+        filledform = tmpdir / "filled.pdf"
+
+        xfdf = gen_xfdf(tmpdir / "data.fdf", data)
+
+        try:
+            fill_form(tmpform, xfdf, filledform, flatten=False)
+        except subprocess.CalledProcessError:
+            print("Erreur lors de l'écriture du PDF, assurez-vous qu'il n'est pas ouvert")
+            return
+
+        if outputname.isfile():
+            outputname.remove()
+        filledform.move(outputname)
+
+        if keep_xfdf:
+            xfdf.copy(outputname.parent)

+ 83 - 0
core/xmlparser.py

@@ -0,0 +1,83 @@
+'''
+Parser de fichiers XML
+
+Fournit un dictionnaire des données sous la forme
+{'root.child1.child2.node': 'value'}
+
+@author: olivier.massot, sept. 2017
+'''
+
+import re
+
+from lxml import etree  # @UnresolvedImport
+from path import Path
+
+
+_regex = re.compile(r"(?:\{https?:\/\/.*\})(.*)")
+
+CACHE = {}
+
+class XmlError(Exception):
+    pass
+
+def _clean_tag(tag):
+    """ retire un eventuel schema {http://*} en debut de chaine """
+    try:
+        return _regex.search(tag).group(1)
+    except:
+        return tag
+
+def _parse(filepath):
+    if not filepath in CACHE:
+        try:
+            tree = etree.parse(filepath)
+            CACHE[filepath] = tree
+        except etree.XMLSyntaxError:
+            raise XmlError("Le fichier XML contient des erreurs! ('{}')".format(filepath.name))
+    return CACHE[filepath]
+
+def getroottag(filepath):
+    return _clean_tag(_parse(filepath).getroot().tag)
+
+def first_children_tags(filepath):
+    return [_clean_tag(elt.tag) for elt in _parse(filepath).getroot()]
+
+def parse(filepath, start=""):
+    """ parse un fichier Xml et retourne un dictionnaire
+    de la forme {"node1.node2.element.tag": value}
+    """
+    tree = _parse(filepath)
+
+    root = tree.getroot()
+
+    data = {}
+
+    def _iter(elt, in_start_node=False, breadcrumb=tuple()):
+
+        if in_start_node:
+            breadcrumb += (_clean_tag(elt.tag),)
+
+        if not start or _clean_tag(elt.tag) == start:
+            in_start_node = True
+
+        for child in elt:
+            if not len(child) > 0 and in_start_node:
+                key = ".".join(breadcrumb + (_clean_tag(child.tag),))
+                data[key] = child.text
+            else:
+                _iter(child, in_start_node, breadcrumb)
+
+    _iter(root)
+
+    return data
+
+
+if __name__ == "__main__":
+    import sys
+    try:
+        filepath = Path(sys.argv[1])
+    except IndexError:
+        print("Erreur: vous devez passer le chemin d'un fichier en parametre\nExemple:\n  python xmlparser.py c:\dict.xml")
+        sys.exit(1)
+
+    print("\n".join(list(parse(filepath).keys())))

BIN
doc/DICT_annotee.pdf


BIN
doc/Notice_PARDIT.pdf


BIN
doc/Recepisse_annotee.pdf


+ 82 - 0
doc/xml_fields.txt

@@ -0,0 +1,82 @@
+noConsultationDuTeleservice
+dateDeLaDeclaration
+partieDT.noConsultationDuTeleservice
+partieDT.noAffaireDuResponsableDuProjet
+partieDT.dateDeLaDeclaration
+partieDT.typeEntite
+partieDT.declarationConjointeDTDICT
+partieDT.responsableDuProjet.denomination
+partieDT.responsableDuProjet.pays
+partieDT.representantDuResponsableDeProjet.denomination
+partieDT.representantDuResponsableDeProjet.numero
+partieDT.representantDuResponsableDeProjet.voie
+partieDT.representantDuResponsableDeProjet.codePostal
+partieDT.representantDuResponsableDeProjet.commune
+partieDT.representantDuResponsableDeProjet.tel
+partieDT.representantDuResponsableDeProjet.fax
+partieDT.representantDuResponsableDeProjet.courriel
+partieDT.emplacementDuProjet.adresse
+partieDT.emplacementDuProjet.CP
+partieDT.emplacementDuProjet.communePrincipale
+partieDT.emplacementDuProjet.codeINSEE
+partieDT.emplacementDuProjet.nombreDeCommunes
+partieDT.emplacementDuProjet.listeDesEmplacementsDesCommunesConcernees.emplacementDeLaCommuneConcernee.nomDeLaCommune
+partieDT.emplacementDuProjet.listeDesEmplacementsDesCommunesConcernees.emplacementDeLaCommuneConcernee.codeCommune
+partieDT.emplacementDuProjet.listeDesEmplacementsDesCommunesConcernees.emplacementDeLaCommuneConcernee.codeINSEE
+partieDT.emprise.geometrie.surfaceMembers.Polygon.exterior.LinearRing.coordinates
+partieDT.emprise.surface
+partieDT.souhaitsPourLeRecepisse.souhaiteRecevoirLeRecepisse
+partieDT.souhaitsPourLeRecepisse.modeReceptionElectronique.tailleDesPlans
+partieDT.souhaitsPourLeRecepisse.modeReceptionElectronique.couleurDesPlans
+partieDT.souhaitsPourLeRecepisse.modeReceptionElectronique.souhaitDePlansVectoriels
+partieDT.souhaitsPourLeRecepisse.modeReceptionElectronique.formatDesPlansVectoriels
+partieDT.projetEtSonCalendrier.natureDesTravaux
+partieDT.projetEtSonCalendrier.decrivezLeProjet
+partieDT.projetEtSonCalendrier.emploiDeTechniquesSansTranchees
+partieDT.projetEtSonCalendrier.souhaitLesPlansDesReseauxElectriqueAeriens
+partieDT.projetEtSonCalendrier.datePrevuePourLeCommencementDesTravaux
+partieDT.projetEtSonCalendrier.dureeDuChantierEnJours
+partieDT.signatureDuResponsableDuProjetOuDeSonRepresentant.nomDuSignataire
+partieDT.signatureDuResponsableDuProjetOuDeSonRepresentant.nombrePagesJointes
+partieDICT.noConsultationDuTeleservice
+partieDICT.noAffaireDeLexecutantDesTravaux
+partieDICT.dateDeLaDeclaration
+partieDICT.natureDeLaDeclaration
+partieDICT.executantDesTravaux.denomination
+partieDICT.executantDesTravaux.complementService
+partieDICT.executantDesTravaux.voie
+partieDICT.executantDesTravaux.lieuDitBP
+partieDICT.executantDesTravaux.codePostal
+partieDICT.executantDesTravaux.commune
+partieDICT.executantDesTravaux.pays
+partieDICT.executantDesTravaux.nomDeLaPersonneAContacter
+partieDICT.executantDesTravaux.tel
+partieDICT.executantDesTravaux.fax
+partieDICT.executantDesTravaux.courriel
+partieDICT.emplacementDesTravaux.adresse
+partieDICT.emplacementDesTravaux.CP
+partieDICT.emplacementDesTravaux.communePrincipale
+partieDICT.emplacementDesTravaux.codeINSEE
+partieDICT.emplacementDesTravaux.nombreDeCommunes
+partieDICT.emplacementDesTravaux.listeDesEmplacementsDesCommunesConcernees.emplacementDeLaCommuneConcernee.nomDeLaCommune
+partieDICT.emplacementDesTravaux.listeDesEmplacementsDesCommunesConcernees.emplacementDeLaCommuneConcernee.codeCommune
+partieDICT.emplacementDesTravaux.listeDesEmplacementsDesCommunesConcernees.emplacementDeLaCommuneConcernee.codeINSEE
+partieDICT.emprise.geometrie.surfaceMembers.Polygon.exterior.LinearRing.coordinates
+partieDICT.emprise.surface
+partieDICT.souhaitsPourLeRecepisse.modeReceptionElectronique.tailleDesPlans
+partieDICT.souhaitsPourLeRecepisse.modeReceptionElectronique.couleurDesPlans
+partieDICT.souhaitsPourLeRecepisse.modeReceptionElectronique.souhaitDePlansVectoriels
+partieDICT.souhaitsPourLeRecepisse.modeReceptionElectronique.formatDesPlansVectoriels
+partieDICT.travauxEtLeurCalendrier.natureDesTravaux
+partieDICT.travauxEtLeurCalendrier.decrivezLesTravaux
+partieDICT.travauxEtLeurCalendrier.techniquesUtilisees
+partieDICT.travauxEtLeurCalendrier.profondeurMaxDExcavation
+partieDICT.travauxEtLeurCalendrier.modificationProfilTerrain
+partieDICT.travauxEtLeurCalendrier.communicationResultatsInvestigations
+partieDICT.travauxEtLeurCalendrier.souhaitLesPlansDesReseauxElectriqueAeriens
+partieDICT.travauxEtLeurCalendrier.datePrevuePourLeCommencementDesTravaux
+partieDICT.travauxEtLeurCalendrier.dureeDuChantierEnJours
+partieDICT.signatureDeLExecutantDesTravauxOuDeSonRepresentant.nomDuSignataire
+partieDICT.signatureDeLExecutantDesTravauxOuDeSonRepresentant.nombrePagesJointes
+nomDuSignataire
+nombrePagesJointes

BIN
logo.png


BIN
pardit.ico


+ 70 - 0
pardit.py

@@ -0,0 +1,70 @@
+"""
+
+Pardit - Production automatisée de réponse aux demandes d'intention de travaux
+
+Pour traiter automatiquement un fichier XML, utilisez l'argument optionnel '-file=<filename>'.
+
+  ex: pardit.py -file c:\...\fichier.xml
+
+@author: olivier.massot, 2017
+"""
+
+import re
+import sys
+
+from PyQt5.Qt import QApplication
+from PyQt5.QtWidgets import QMessageBox
+
+from core import constants, config
+from ui.window import MainWindow
+import updater
+
+try:
+    import ipdb  # @UnusedImport  Necessaire à l'affichage des stack traces
+except:
+    pass
+
+# Look for a -file=<filename> argument
+args = sys.argv
+regex = re.compile(r"""^-file="?(.*)"?$""")
+filename = ""
+for arg in args:
+    match = regex.match(arg)
+    if match != None:
+        filename = match.group(1)
+
+app = QApplication(sys.argv)
+mainw = MainWindow()
+
+sys_err = sys.excepthook
+def gestionnaire_erreurs(typ, value, traceback):
+    QApplication.restoreOverrideCursor()
+    sys_err(typ, value, traceback)
+    QMessageBox.critical(mainw, "Erreur: {}".format(typ.__name__), """{}""".format(value))
+    mainw.cancel()
+sys.excepthook = gestionnaire_erreurs
+
+try:
+    if updater.update_needed():
+        QMessageBox.information(mainw,
+                                "Mise à jour requise",
+                                """Une nouvelle version de Pardit est disponible,
+veuillez patienter pendant la mise à jour.
+
+Pardit sera relancé automatiqement une fois l'installation terminée.""",
+                                QMessageBox.Ok)
+        updater.update()
+        sys.exit(0)
+except updater.Unavailable:
+    print("Request error: unable to fetch last version")
+
+# Charge la configuration
+config.load()
+
+mainw.show()
+if filename:
+    mainw.process(filename)
+r = app.exec_()
+
+# Nettoyage
+constants.TMPDIR.rmdir_p()

+ 97 - 0
pardit.yaml

@@ -0,0 +1,97 @@
+# -- Fichier de configuration de PARDIT --
+# Notes:
+# * Champ à reprendre dans le fichier XML: <nom.du.champ>
+# * Fonctions disponibles: JOUR(date), MOIS(date), ANNEE(date), MAINTENANT()
+
+# Répertoire par défaut pour la selection de fichiers
+repertoire_defaut: \\public\publicno\M-MRI\prod\outils\Globaux\Pardit
+
+# Répertoire de sortie des PDF
+repertoire_sortie: C:\Applications_CD67\MRI-PARDIT
+
+# Données pour l'édition des PDF
+donnees:
+    # Cas de l'édition d'une DICT
+    dict:
+        Denomination: <executantDesTravaux.denomination>
+        ComplementAdresse: <executantDesTravaux.complementService>
+        NoVoie: <executantDesTravaux.voie>
+        LieuditBP: <executantDesTravaux.lieuDitBP>
+        CodePostal: <executantDesTravaux.codePostal>
+        Commune: <executantDesTravaux.commune>
+        Pays: <responsableDuProjet.pays>
+        NoGU: <noConsultationDuTeleservice>
+        NoAffaireDeclarant: <noAffaireDeLexecutantDesTravaux>
+        Personne_Contacter: <nomDeLaPersonneAContacter>
+        JourReception: JOUR(<dateDeLaDeclaration>)
+        MoisReception: MOIS(<dateDeLaDeclaration>)
+        AnneeReception: ANNEE(<dateDeLaDeclaration>)     
+        CommuneTravaux: <emplacementDesTravaux.communePrincipale>
+        AdresseTravaux: <emplacementDesTravaux.adresse>
+        Recepisse_DICT: Oui
+        
+    # Cas de l'édition d'une DT        
+    dt:
+        Denomination: <representantDuResponsableDeProjet.denomination>
+        ComplementAdresse: <representantDuResponsableDeProjet.complementService>
+        NoVoie: "<representantDuResponsableDeProjet.numero> <representantDuResponsableDeProjet.voie>"
+        LieuditBP: <representantDuResponsableDeProjet.lieuDitBP>
+        CodePostal: <representantDuResponsableDeProjet.codePostal>
+        Commune: <representantDuResponsableDeProjet.commune>
+        Pays: <responsableDuProjet.pays>
+        NoGU: <noConsultationDuTeleservice>
+        NoAffaireDeclarant: <noAffaireDuResponsableDuProjet>
+        Personne_Contacter: <nomDeLaPersonneAContacter>
+        JourReception: JOUR(<dateDeLaDeclaration>)
+        MoisReception: MOIS(<dateDeLaDeclaration>)
+        AnneeReception: ANNEE(<dateDeLaDeclaration>)  
+        CommuneTravaux: <emplacementDuProjet.communePrincipale>
+        AdresseTravaux: <emplacementDuProjet.adresse>    
+        Recepisse_DT: Oui
+
+    # Champs communs aux deux types de demandes
+    commun:
+        PasConcerne: Oui
+        NbPJ: 0
+        RaisonSocialeExploitant: "Département du Bas-Rhin"
+        ContactExploitant: ""
+        NoVoieExploitant: ""
+        LieuditBPExploitant: STRASBOURG
+        CodePostalExploitant: "67000"
+        CommuneExploitant: ""
+        TelExploitant: ""
+        FaxExploitant: ""
+        NomResponsableDossier: ""
+        DésignationService: ""
+        TelResponsableDossier: ""
+        TelEndommagement: ""
+        NomSignataire: ""     
+        JourRecepisse: JOUR(MAINTENANT())
+        MoisRecepisse: MOIS(MAINTENANT())
+        AnneeRecepisse: ANNEE(MAINTENANT())   
+
+# Configuration de l'édition des mails        
+mail:
+    dict:
+      dest: <executantDesTravaux.courriel>
+      objet: "Réponse à la demande <noConsultationDuTeleservice>"
+      texte: "Veuillez trouver ci-joint la réponse à votre demande.\nCordialement,"
+    dt:
+      dest: <representantDuResponsableDeProjet.courriel>
+      objet: "Réponse à la demande <noConsultationDuTeleservice>"
+      texte: "Veuillez trouver ci-joint la réponse à votre demande.\nCordialement,"
+ 
+ # Champs modifiables via la fenêtre 'Configuration'
+modifiables:
+- ContactExploitant
+- NoVoieExploitant
+- LieuditBPExploitant
+- CodePostalExploitant
+- CommuneExploitant
+- TelExploitant
+- FaxExploitant
+- NomResponsableDossier
+- DésignationService
+- TelResponsableDossier
+- TelEndommagement
+- NomSignataire

+ 7 - 0
requirements.txt

@@ -0,0 +1,7 @@
+path.py
+pyyaml==3.12
+PyQt5==5.8.2
+pypiwin32==220
+lxml==3.7.3
+cerberus
+requests_ntlm

+ 108 - 0
setup.iss

@@ -0,0 +1,108 @@
+; Script de création du programme d'installation Pardit
+
+#define MyAppName "pardit"
+#define MyAppVersion "0.2"
+#define FileVersion "0-2"
+#define MyAppPublisher "Conseil Départemental du Bas-Rhin"
+#define MyAppURL "http://codebox/Culture-Territo-BI/pardit"
+#define MyAppLocation "C:\Applications_CD67\MRI-PARDIT\"
+#define PythonVersion "3.6-32"
+[Setup]
+AppId={{C8002CE1-D79C-4B0C-AD8A-73F43D219CD6}}
+AppName={#MyAppName}
+AppVersion={#MyAppVersion}
+AppPublisher={#MyAppPublisher}
+AppPublisherURL={#MyAppURL}
+AppSupportURL={#MyAppURL}
+AppUpdatesURL={#MyAppURL}
+DefaultDirName={#MyAppLocation}{#MyAppName}
+DefaultGroupName={#MyAppName}
+Compression=lzma
+PrivilegesRequired=lowest
+SolidCompression=yes
+VersionInfoCompany=Conseil Départemental du Bas-Rhin
+
+DisableDirPage=yes
+DisableProgramGroupPage=yes
+DisableFinishedPage=yes
+
+OutputDir=.
+OutputBaseFilename=setup-{#MyAppName}
+
+ChangesEnvironment=yes
+
+UninstallFilesDir={app}\uninstall\
+
+[Languages]
+Name: "french"; MessagesFile: "compiler:Languages\French.isl"
+
+[Files]
+Source: "ui\*"; DestDir: "{app}\ui"; Flags: ignoreversion recursesubdirs    
+Source: "core\*"; DestDir: "{app}\core"; Flags: ignoreversion recursesubdirs
+Source: "bin\*"; DestDir: "{app}\bin"; Flags: ignoreversion recursesubdirs
+Source: "doc\*"; DestDir: "{app}\doc"; Flags: ignoreversion recursesubdirs
+Source: "templates\*"; DestDir: "{app}\templates"; Flags: ignoreversion recursesubdirs
+Source: "pardit.py"; DestDir: "{app}"; Flags: ignoreversion
+Source: "pardit.yaml"; DestDir: "{app}"; Flags: ignoreversion
+Source: "README.md"; DestDir: "{app}"; Flags: ignoreversion
+Source: "requirements.txt"; DestDir: "{app}"; Flags: ignoreversion
+Source: "logo.png"; DestDir: "{app}"; Flags: ignoreversion
+Source: "pardit.ico"; DestDir: "{app}"; Flags: ignoreversion
+Source: "updater.py"; DestDir: "{app}"; Flags: ignoreversion
+Source: "version.txt"; DestDir: "{app}"; Flags: ignoreversion
+Source: "bin\pip67.exe"; DestDir: "{code:PythonDir}\Scripts"; Flags: onlyifdoesntexist
+
+[Icons]
+Name: "{group}\{#MyAppName}"; Filename: "pythonw.exe"; Parameters: "{app}\{#MyAppName}.py"; WorkingDir: "{app}"; IconFilename: "{app}\pardit.ico"
+Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
+Name: "{commondesktop}\{#MyAppName}"; Filename: "pythonw.exe"; Parameters: "{app}\{#MyAppName}.py"; WorkingDir: "{app}"; IconFilename: "{app}\pardit.ico"
+
+[Run]
+Filename: "pip67.exe"; Parameters: "install -r {app}\requirements.txt"; StatusMsg: "Installation des librairies complémentaires"; Flags: runhidden
+
+[Code]
+function PythonDir(Param: String): String;
+var
+  ErrorCode: Integer;
+  PythonDirpath: String;
+begin
+  if RegQueryStringValue(HKLM, 'SOFTWARE\Wow6432Node\Python\PythonCore\{#PythonVersion}\InstallPath', '', PythonDirpath) OR 
+  RegQueryStringValue(HKLM, 'SOFTWARE\Python\PythonCore\{#PythonVersion}\InstallPath', '', PythonDirpath) then
+  begin
+    Result := PythonDirpath;
+  end
+  else
+  begin
+    Result := '';
+  end
+end;
+
+function PythonExec(Param: String): String;
+var
+  PythonDirPath: String;
+  PythonPath: String;
+begin
+  PythonDirPath := PythonDir('');
+  if DirExists(PythonDirPath) then
+    begin
+    Result := PythonDirPath + 'python.exe';
+    end
+  else
+    begin
+    Result := '';
+    end
+end;
+
+function InitializeSetup(): Boolean;
+var
+  PythonPath : String;
+begin
+  PythonPath := PythonExec('');
+  if not FileExists(PythonPath) then
+  begin
+     MsgBox('Python {#PythonVersion} doit être installé.' + #13#10 + 'Installation annulée.', mbError, MB_OK);
+     Result := False;
+     Exit; 
+  end
+  Result := True;
+end;

BIN
templates/template.pdf


+ 4 - 0
tests/__init__.py

@@ -0,0 +1,4 @@
+from path import Path
+
+
+HERE = Path(__file__).parent

+ 41 - 0
tests/rsc/test_process/ref.fdf

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+    <xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">
+        <fields>
+            <field name="PasConcerne"><value>Oui</value></field>
+			<field name="NbPJ"><value>0</value></field>
+			<field name="RaisonSocialeExploitant"><value>Conseil Planétaire Martien</value></field>
+			<field name="ContactExploitant"><value>Albert Dupont</value></field>
+			<field name="NoVoieExploitant"><value>1 rue Alpha</value></field>
+			<field name="LieuditBPExploitant"><value>Mars</value></field>
+			<field name="CodePostalExploitant"><value>99999</value></field>
+			<field name="CommuneExploitant"><value>Omega</value></field>
+			<field name="TelExploitant"><value></value></field>
+			<field name="FaxExploitant"><value></value></field>
+			<field name="NomResponsableDossier"><value>CT Chief</value></field>
+			<field name="DésignationService"><value>CT Mars</value></field>
+			<field name="TelResponsableDossier"><value></value></field>
+			<field name="TelEndommagement"><value></value></field>
+			<field name="NomSignataire"><value>CT Chief</value></field>
+			<field name="JourRecepisse"><value>{day:02d}</value></field>
+			<field name="MoisRecepisse"><value>{month:02d}</value></field>
+			<field name="AnneeRecepisse"><value>{year:04d}</value></field>
+			<field name="Denomination"><value>Albert Dupont</value></field>
+			<field name="ComplementAdresse"><value></value></field>
+			<field name="NoVoie"><value>1 rue Alpha</value></field>
+			<field name="LieuditBP"><value></value></field>
+			<field name="CodePostal"><value>99999</value></field>
+			<field name="Commune"><value>Omega</value></field>
+			<field name="Pays"><value>France</value></field>
+			<field name="NoGU"><value>000001</value></field>
+			<field name="NoAffaireDeclarant"><value>ABC01234</value></field>
+			<field name="Personne_Contacter"><value></value></field>
+			<field name="JourReception"><value>01</value></field>
+			<field name="MoisReception"><value>01</value></field>
+			<field name="AnneeReception"><value>2017</value></field>
+			<field name="CommuneTravaux"><value>Daisy Town</value></field>
+			<field name="AdresseTravaux"><value>1 rue Averell Dalton</value></field>
+			<field name="Recepisse_DT"><value>Non</value></field>
+			<field name="Recepisse_DICT"><value>Non</value></field>
+			<field name="Recepisse_DC"><value>Oui</value></field>
+        </fields>
+    </xfdf>

+ 156 - 0
tests/rsc/test_process/testfile.xml

@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<dossierConsultation xmlns="http://www.reseaux-et-canalisations.gouv.fr/schema-teleservice/2.2" xmlns:ns2="http://www.opengis.net/gml/3.2" xmlns:ns3="http://www.w3.org/1999/xlink" xmlns:ns4="http://xml.insee.fr/schema">
+	<dtDictConjointes>
+		<noConsultationDuTeleservice>000001</noConsultationDuTeleservice>
+		<dateDeLaDeclaration>2017-01-01T00:00:00.000+02:00</dateDeLaDeclaration>
+		<partieDT>
+			<noConsultationDuTeleservice>000001</noConsultationDuTeleservice>
+			<noAffaireDuResponsableDuProjet>ABC01234</noAffaireDuResponsableDuProjet>
+			<dateDeLaDeclaration>2017-01-01T00:00:00.000+02:00</dateDeLaDeclaration>
+			<typeEntite>PERSONNE_MORALE</typeEntite>
+			<declarationConjointeDTDICT>true</declarationConjointeDTDICT>
+			<responsableDuProjet>
+				<denomination>SpaceX</denomination>
+				<pays>France</pays>
+			</responsableDuProjet>
+			<representantDuResponsableDeProjet>
+				<denomination>Albert Dupont</denomination>
+				<numero>1</numero>
+				<voie>rue Alpha</voie>
+				<codePostal>99999</codePostal>
+				<commune>Omega</commune>
+				<tel>+33600000000</tel>
+				<fax>+33600000000</fax>
+				<courriel>dt@spacex.net</courriel>
+			</representantDuResponsableDeProjet>
+			<emplacementDuProjet>
+				<adresse>1 rue Averell Dalton</adresse>
+				<CP>99999</CP>
+				<communePrincipale>Daisy Town</communePrincipale>
+				<codeINSEE>99999</codeINSEE>
+				<nombreDeCommunes>1</nombreDeCommunes>
+				<listeDesEmplacementsDesCommunesConcernees>
+					<emplacementDeLaCommuneConcernee>
+						<nomDeLaCommune>Daisy Town</nomDeLaCommune>
+						<codeCommune>99999</codeCommune>
+						<codeINSEE>99999</codeINSEE>
+					</emplacementDeLaCommuneConcernee>
+				</listeDesEmplacementsDesCommunesConcernees>
+			</emplacementDuProjet>
+			<emprise>
+				<geometrie srsDimension="2" srsName="urn:ogc:def:crs:EPSG::4171" ns2:id="dtemprise0">
+					<ns2:surfaceMembers>
+						<ns2:Polygon ns2:id="dt0">
+							<ns2:exterior>
+								<ns2:LinearRing>
+									<ns2:coordinates>7.379824136757299,48.28582540690356 7.379791950249108,48.28580755907809 7.37989923860971,48.28573081335732 7.379939471744939,48.28575223077942 7.379824136757299,48.28582540690356</ns2:coordinates>
+								</ns2:LinearRing>
+							</ns2:exterior>
+						</ns2:Polygon>
+					</ns2:surfaceMembers>
+				</geometrie>
+				<surface>40.39448290783912</surface>
+			</emprise>
+			<souhaitsPourLeRecepisse>
+				<souhaiteRecevoirLeRecepisse>true</souhaiteRecevoirLeRecepisse>
+				<modeReceptionElectronique>
+					<tailleDesPlans>A4</tailleDesPlans>
+					<couleurDesPlans>true</couleurDesPlans>
+					<souhaitDePlansVectoriels>true</souhaitDePlansVectoriels>
+					<formatDesPlansVectoriels>DXF</formatDesPlansVectoriels>
+				</modeReceptionElectronique>
+			</souhaitsPourLeRecepisse>
+			<projetEtSonCalendrier>
+				<natureDesTravaux>HYP</natureDesTravaux>
+				<natureDesTravaux>ERS</natureDesTravaux>
+				<natureDesTravaux>PAT</natureDesTravaux>
+				<decrivezLeProjet>Portail hyperspatial</decrivezLeProjet>
+				<emploiDeTechniquesSansTranchees>false</emploiDeTechniquesSansTranchees>
+				<souhaitLesPlansDesReseauxElectriqueAeriens>true</souhaitLesPlansDesReseauxElectriqueAeriens>
+				<datePrevuePourLeCommencementDesTravaux>2018-01-01+02:00</datePrevuePourLeCommencementDesTravaux>
+				<dureeDuChantierEnJours>1</dureeDuChantierEnJours>
+			</projetEtSonCalendrier>
+			<signatureDuResponsableDuProjetOuDeSonRepresentant>
+				<nomDuSignataire>SpaceX</nomDuSignataire>
+				<nombrePagesJointes>0</nombrePagesJointes>
+			</signatureDuResponsableDuProjetOuDeSonRepresentant>
+		</partieDT>
+		<partieDICT>
+			<noConsultationDuTeleservice>000001</noConsultationDuTeleservice>
+			<noAffaireDeLexecutantDesTravaux>ABC01234</noAffaireDeLexecutantDesTravaux>
+			<dateDeLaDeclaration>2017-01-01T00:00:00.000+02:00</dateDeLaDeclaration>
+			<natureDeLaDeclaration>INITIAL</natureDeLaDeclaration>
+			<executantDesTravaux>
+				<denomination>Les maçons de l'espace</denomination>
+				<complementService>éôè</complementService>
+				<voie>1 avenue diste</voie>
+				<lieuDitBP>Plage</lieuDitBP>
+				<codePostal>99999</codePostal>
+				<commune>Naboo</commune>
+				<pays>France</pays>
+				<nomDeLaPersonneAContacter>Mlle Amidala</nomDeLaPersonneAContacter>
+				<tel>+33600000000</tel>
+				<fax>+33600000000</fax>
+				<courriel>dict@spacex.net</courriel>
+			</executantDesTravaux>
+			<emplacementDesTravaux>
+				<adresse>1 rue Averell Dalton</adresse>
+				<CP>99999</CP>
+				<communePrincipale>Daisy Town</communePrincipale>
+				<codeINSEE>99999</codeINSEE>
+				<nombreDeCommunes>1</nombreDeCommunes>
+				<listeDesEmplacementsDesCommunesConcernees>
+					<emplacementDeLaCommuneConcernee>
+						<nomDeLaCommune>CHATENOIS</nomDeLaCommune>
+						<codeCommune>67730</codeCommune>
+						<codeINSEE>67073</codeINSEE>
+					</emplacementDeLaCommuneConcernee>
+				</listeDesEmplacementsDesCommunesConcernees>
+			</emplacementDesTravaux>
+			<emprise>
+				<geometrie srsDimension="2" srsName="urn:ogc:def:crs:EPSG::4171" ns2:id="dictemprise0">
+					<ns2:surfaceMembers>
+						<ns2:Polygon ns2:id="dict0">
+							<ns2:exterior>
+								<ns2:LinearRing>
+									<ns2:coordinates>7.379824136757299,48.28582540690356 7.379791950249108,48.28580755907809 7.37989923860971,48.28573081335732 7.379939471744939,48.28575223077942 7.379824136757299,48.28582540690356</ns2:coordinates>
+								</ns2:LinearRing>
+							</ns2:exterior>
+						</ns2:Polygon>
+					</ns2:surfaceMembers>
+				</geometrie>
+				<surface>40.39448290783912</surface>
+			</emprise>
+			<souhaitsPourLeRecepisse>
+				<souhaiteRecevoirLeRecepisse>true</souhaiteRecevoirLeRecepisse>
+				<modeReceptionElectronique>
+					<tailleDesPlans>A4</tailleDesPlans>
+					<couleurDesPlans>true</couleurDesPlans>
+					<souhaitDePlansVectoriels>true</souhaitDePlansVectoriels>
+					<formatDesPlansVectoriels>DXF</formatDesPlansVectoriels>
+				</modeReceptionElectronique>
+			</souhaitsPourLeRecepisse>
+			<travauxEtLeurCalendrier>
+				<natureDesTravaux>RBL</natureDesTravaux>
+				<natureDesTravaux>SOU</natureDesTravaux>
+				<natureDesTravaux>TER</natureDesTravaux>
+				<decrivezLesTravaux>Fouille pour implantation d'un support bois pour la reprise du réseau BT. </decrivezLesTravaux>
+				<techniquesUtilisees>MAN</techniquesUtilisees>
+				<techniquesUtilisees>PEL</techniquesUtilisees>
+				<techniquesUtilisees>VIB</techniquesUtilisees>
+				<profondeurMaxDExcavation>150</profondeurMaxDExcavation>
+				<modificationProfilTerrain>false</modificationProfilTerrain>
+				<communicationResultatsInvestigations>false</communicationResultatsInvestigations>
+				<souhaitLesPlansDesReseauxElectriqueAeriens>true</souhaitLesPlansDesReseauxElectriqueAeriens>
+				<datePrevuePourLeCommencementDesTravaux>2017-08-29+02:00</datePrevuePourLeCommencementDesTravaux>
+				<dureeDuChantierEnJours>1</dureeDuChantierEnJours>
+			</travauxEtLeurCalendrier>
+			<signatureDeLExecutantDesTravauxOuDeSonRepresentant>
+				<nomDuSignataire>GUTH 0682371987 Maximilien</nomDuSignataire>
+				<nombrePagesJointes>1</nombrePagesJointes>
+			</signatureDeLExecutantDesTravauxOuDeSonRepresentant>
+		</partieDICT>
+		<nomDuSignataire>SpaceX</nomDuSignataire>
+		<nombrePagesJointes>1</nombrePagesJointes>
+	</dtDictConjointes>
+</dossierConsultation>

+ 8 - 0
tests/rsc/test_process/userdata.yaml

@@ -0,0 +1,8 @@
+donnees:
+  commun: {CodePostalExploitant: '99999', CommuneExploitant: Omega, ContactExploitant: Albert
+      Dupont, "D\xE9signationService": CT Mars, FaxExploitant: '', LieuditBPExploitant: Mars,
+    NoVoieExploitant: '1 rue Alpha', NomResponsableDossier: CT Chief, NomSignataire: CT Chief,
+    RaisonSocialeExploitant: "Conseil Plan\xE9taire Martien", TelEndommagement: '',
+    TelExploitant: '', TelResponsableDossier: ''}
+repertoire_defaut: .
+repertoire_sortie: .

+ 380 - 0
tests/rsc/test_xmlparser/testfile.xml

@@ -0,0 +1,380 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<dossierConsultation xmlns="http://www.reseaux-et-canalisations.gouv.fr/schema-teleservice/2.2" xmlns:ns2="http://www.opengis.net/gml/3.2" xmlns:ns3="http://www.w3.org/1999/xlink" xmlns:ns4="http://xml.insee.fr/schema">
+	<dtDictConjointes>
+		<noConsultationDuTeleservice>2017082500228P</noConsultationDuTeleservice>
+		<dateDeLaDeclaration>2017-08-25T10:23:22.272+02:00</dateDeLaDeclaration>
+		<partieDT>
+			<noConsultationDuTeleservice>2017082500228P</noConsultationDuTeleservice>
+			<noAffaireDuResponsableDuProjet>EM 34789909</noAffaireDuResponsableDuProjet>
+			<dateDeLaDeclaration>2017-08-25T10:23:22.272+02:00</dateDeLaDeclaration>
+			<typeEntite>PERSONNE_MORALE</typeEntite>
+			<declarationConjointeDTDICT>true</declarationConjointeDTDICT>
+			<responsableDuProjet>
+				<denomination>ENEDIS-UREAFC-CHATENOIS</denomination>
+				<pays>France</pays>
+			</responsableDuProjet>
+			<representantDuResponsableDeProjet>
+				<denomination>GUTH Construction</denomination>
+				<numero>1</numero>
+				<voie>rue du Moulin</voie>
+				<codePostal>67390</codePostal>
+				<commune>OHNENHEIM</commune>
+				<tel>+33682371987</tel>
+				<fax>+33970322232</fax>
+				<courriel>dt@guthconstruction.fr</courriel>
+			</representantDuResponsableDeProjet>
+			<emplacementDuProjet>
+				<adresse>6 R DE VILLE</adresse>
+				<CP>67730</CP>
+				<communePrincipale>CHATENOIS</communePrincipale>
+				<codeINSEE>67073</codeINSEE>
+				<nombreDeCommunes>1</nombreDeCommunes>
+				<listeDesEmplacementsDesCommunesConcernees>
+					<emplacementDeLaCommuneConcernee>
+						<nomDeLaCommune>CHATENOIS</nomDeLaCommune>
+						<codeCommune>67730</codeCommune>
+						<codeINSEE>67073</codeINSEE>
+					</emplacementDeLaCommuneConcernee>
+				</listeDesEmplacementsDesCommunesConcernees>
+			</emplacementDuProjet>
+			<emprise>
+				<geometrie srsDimension="2" srsName="urn:ogc:def:crs:EPSG::4171" ns2:id="dtemprise0">
+					<ns2:surfaceMembers>
+						<ns2:Polygon ns2:id="dt0">
+							<ns2:exterior>
+								<ns2:LinearRing>
+									<ns2:coordinates>7.379824136757299,48.28582540690356 7.379791950249108,48.28580755907809 7.37989923860971,48.28573081335732 7.379939471744939,48.28575223077942 7.379824136757299,48.28582540690356</ns2:coordinates>
+								</ns2:LinearRing>
+							</ns2:exterior>
+						</ns2:Polygon>
+					</ns2:surfaceMembers>
+				</geometrie>
+				<surface>40.39448290783912</surface>
+			</emprise>
+			<souhaitsPourLeRecepisse>
+				<souhaiteRecevoirLeRecepisse>true</souhaiteRecevoirLeRecepisse>
+				<modeReceptionElectronique>
+					<tailleDesPlans>A4</tailleDesPlans>
+					<couleurDesPlans>true</couleurDesPlans>
+					<souhaitDePlansVectoriels>true</souhaitDePlansVectoriels>
+					<formatDesPlansVectoriels>DXF</formatDesPlansVectoriels>
+				</modeReceptionElectronique>
+			</souhaitsPourLeRecepisse>
+			<projetEtSonCalendrier>
+				<natureDesTravaux>RBL</natureDesTravaux>
+				<natureDesTravaux>SOU</natureDesTravaux>
+				<natureDesTravaux>TER</natureDesTravaux>
+				<decrivezLeProjet>Fouille pour implantation d'un support bois pour la reprise du réseau BT. </decrivezLeProjet>
+				<emploiDeTechniquesSansTranchees>false</emploiDeTechniquesSansTranchees>
+				<souhaitLesPlansDesReseauxElectriqueAeriens>true</souhaitLesPlansDesReseauxElectriqueAeriens>
+				<datePrevuePourLeCommencementDesTravaux>2017-08-29+02:00</datePrevuePourLeCommencementDesTravaux>
+				<dureeDuChantierEnJours>1</dureeDuChantierEnJours>
+			</projetEtSonCalendrier>
+			<signatureDuResponsableDuProjetOuDeSonRepresentant>
+				<nomDuSignataire>MULE EMERIC</nomDuSignataire>
+				<nombrePagesJointes>0</nombrePagesJointes>
+			</signatureDuResponsableDuProjetOuDeSonRepresentant>
+		</partieDT>
+		<partieDICT>
+			<noConsultationDuTeleservice>2017082500228P</noConsultationDuTeleservice>
+			<noAffaireDeLexecutantDesTravaux>EM 34789909</noAffaireDeLexecutantDesTravaux>
+			<dateDeLaDeclaration>2017-08-25T10:23:22.272+02:00</dateDeLaDeclaration>
+			<natureDeLaDeclaration>INITIAL</natureDeLaDeclaration>
+			<executantDesTravaux>
+				<denomination>ENEDIS-DRAFC-MOE-Ent GUTH</denomination>
+				<complementService>PRESTATAIRE POUR Enedis  AFC</complementService>
+				<voie>1 rue du Moulin</voie>
+				<lieuDitBP>ZAC</lieuDitBP>
+				<codePostal>67390</codePostal>
+				<commune>OHNENHEIM</commune>
+				<pays>France</pays>
+				<nomDeLaPersonneAContacter>Paul KOEBERLE</nomDeLaPersonneAContacter>
+				<tel>+330667332720</tel>
+				<fax>+330970322232</fax>
+				<courriel>dict@guthconstruction.fr</courriel>
+			</executantDesTravaux>
+			<emplacementDesTravaux>
+				<adresse>6 R DE VILLE</adresse>
+				<CP>67730</CP>
+				<communePrincipale>CHATENOIS</communePrincipale>
+				<codeINSEE>67073</codeINSEE>
+				<nombreDeCommunes>1</nombreDeCommunes>
+				<listeDesEmplacementsDesCommunesConcernees>
+					<emplacementDeLaCommuneConcernee>
+						<nomDeLaCommune>CHATENOIS</nomDeLaCommune>
+						<codeCommune>67730</codeCommune>
+						<codeINSEE>67073</codeINSEE>
+					</emplacementDeLaCommuneConcernee>
+				</listeDesEmplacementsDesCommunesConcernees>
+			</emplacementDesTravaux>
+			<emprise>
+				<geometrie srsDimension="2" srsName="urn:ogc:def:crs:EPSG::4171" ns2:id="dictemprise0">
+					<ns2:surfaceMembers>
+						<ns2:Polygon ns2:id="dict0">
+							<ns2:exterior>
+								<ns2:LinearRing>
+									<ns2:coordinates>7.379824136757299,48.28582540690356 7.379791950249108,48.28580755907809 7.37989923860971,48.28573081335732 7.379939471744939,48.28575223077942 7.379824136757299,48.28582540690356</ns2:coordinates>
+								</ns2:LinearRing>
+							</ns2:exterior>
+						</ns2:Polygon>
+					</ns2:surfaceMembers>
+				</geometrie>
+				<surface>40.39448290783912</surface>
+			</emprise>
+			<souhaitsPourLeRecepisse>
+				<souhaiteRecevoirLeRecepisse>true</souhaiteRecevoirLeRecepisse>
+				<modeReceptionElectronique>
+					<tailleDesPlans>A4</tailleDesPlans>
+					<couleurDesPlans>true</couleurDesPlans>
+					<souhaitDePlansVectoriels>true</souhaitDePlansVectoriels>
+					<formatDesPlansVectoriels>DXF</formatDesPlansVectoriels>
+				</modeReceptionElectronique>
+			</souhaitsPourLeRecepisse>
+			<travauxEtLeurCalendrier>
+				<natureDesTravaux>RBL</natureDesTravaux>
+				<natureDesTravaux>SOU</natureDesTravaux>
+				<natureDesTravaux>TER</natureDesTravaux>
+				<decrivezLesTravaux>Fouille pour implantation d'un support bois pour la reprise du réseau BT. </decrivezLesTravaux>
+				<techniquesUtilisees>MAN</techniquesUtilisees>
+				<techniquesUtilisees>PEL</techniquesUtilisees>
+				<techniquesUtilisees>VIB</techniquesUtilisees>
+				<profondeurMaxDExcavation>150</profondeurMaxDExcavation>
+				<modificationProfilTerrain>false</modificationProfilTerrain>
+				<communicationResultatsInvestigations>false</communicationResultatsInvestigations>
+				<souhaitLesPlansDesReseauxElectriqueAeriens>true</souhaitLesPlansDesReseauxElectriqueAeriens>
+				<datePrevuePourLeCommencementDesTravaux>2017-08-29+02:00</datePrevuePourLeCommencementDesTravaux>
+				<dureeDuChantierEnJours>1</dureeDuChantierEnJours>
+			</travauxEtLeurCalendrier>
+			<signatureDeLExecutantDesTravauxOuDeSonRepresentant>
+				<nomDuSignataire>GUTH 0682371987 Maximilien</nomDuSignataire>
+				<nombrePagesJointes>1</nombrePagesJointes>
+			</signatureDeLExecutantDesTravauxOuDeSonRepresentant>
+		</partieDICT>
+		<nomDuSignataire>GUTH  Maximilien</nomDuSignataire>
+		<nombrePagesJointes>1</nombrePagesJointes>
+	</dtDictConjointes>
+	<listeDesOuvrages>
+		<ouvrage>
+			<contact>
+				<nom>
+					<ns4:NomFamille>BAZILLE</ns4:NomFamille>
+				</nom>
+				<prenom>
+					<ns4:Prenom>daniel</ns4:Prenom>
+				</prenom>
+				<societe>mairie de CHATENOIS</societe>
+				<numero>81</numero>
+				<voie> rue du Maréchal Foch</voie>
+				<codePostal>67730</codePostal>
+				<commune>CHATENOIS</commune>
+				<codePays>FR</codePays>
+				<fax>0388823951</fax>
+				<telephone>0388820274</telephone>
+				<telephoneUrgence>0388820274</telephoneUrgence>
+				<faxUrgence>0388823951</faxUrgence>
+				<telEndommagement>0388820274</telEndommagement>
+				<gestionDesFichiersDematerialises>
+					<gereLesFichiersDematerialises>false</gereLesFichiersDematerialises>
+				</gestionDesFichiersDematerialises>
+			</contact>
+			<categorieOuvrage>S</categorieOuvrage>
+			<classeOuvrage>LIGNES_ELECTRIQUES_ET_ECLAIRAGE_PUBLIC_HORS_TBT</classeOuvrage>
+			<codeOuvrage>EP</codeOuvrage>
+			<denominationOuvrage>ECLAIRAGE PUBLIC</denominationOuvrage>
+			<statut>ACTIF</statut>
+			<dateCreation>2012-07-08+02:00</dateCreation>
+			<polygoneConcerne>false</polygoneConcerne>
+		</ouvrage>
+		<ouvrage>
+			<contact>
+				<societe>ENEDIS-DRAFC-EXPLOIT DT-DICT 67-68</societe>
+				<agence>CHEZ PROTYS P0087</agence>
+				<lieuDitBP>CS 90125</lieuDitBP>
+				<codePostal>27091</codePostal>
+				<commune>EVREUX CEDEX 9</commune>
+				<codePays>FR</codePays>
+				<fax>0344625450</fax>
+				<courriel>1043.ENEDIS@demat.protys.fr</courriel>
+				<telephone>0381906956</telephone>
+				<telephoneUrgence>0181624701</telephoneUrgence>
+				<faxUrgence>0344625450</faxUrgence>
+				<mailUrgence>1043.ENEDIS@demat.protys.fr</mailUrgence>
+				<telEndommagement>0176614701</telEndommagement>
+				<referenceInterne>_|ERDFNAT$1043|_</referenceInterne>
+				<gestionDesFichiersDematerialises>
+					<gereLesFichiersDematerialises>true</gereLesFichiersDematerialises>
+					<formatDesFichiersDematerialises>XML_PDF</formatDesFichiersDematerialises>
+				</gestionDesFichiersDematerialises>
+			</contact>
+			<categorieOuvrage>S</categorieOuvrage>
+			<classeOuvrage>LIGNES_ELECTRIQUES_ET_ECLAIRAGE_PUBLIC_HORS_TBT</classeOuvrage>
+			<codeOuvrage>ENEDIS</codeOuvrage>
+			<denominationOuvrage>RESEAUX ENEDIS HTA ET BT AERIEN ET SOUTERRAIN</denominationOuvrage>
+			<statut>ACTIF</statut>
+			<dateCreation>2017-07-30+02:00</dateCreation>
+			<polygoneConcerne>false</polygoneConcerne>
+		</ouvrage>
+		<ouvrage>
+			<contact>
+				<societe>Conseil Départemental du Bas-Rhin</societe>
+				<agence>Unité Technique de Sélestat</agence>
+				<complement>BP 204</complement>
+				<voie>Route d’Orschwiller</voie>
+				<codePostal>67604</codePostal>
+				<commune>SELESTAT cedex</commune>
+				<codePays>FR</codePays>
+				<fax>0388822983</fax>
+				<courriel>utcd.selestat@bas-rhin.fr</courriel>
+				<telephone>0369067220</telephone>
+				<telephoneUrgence>0369067220</telephoneUrgence>
+				<faxUrgence>0388822983</faxUrgence>
+				<mailUrgence>utcd.selestat@bas-rhin.fr</mailUrgence>
+				<telEndommagement>0369067220</telEndommagement>
+				<referenceInterne/>
+				<gestionDesFichiersDematerialises>
+					<gereLesFichiersDematerialises>true</gereLesFichiersDematerialises>
+					<formatDesFichiersDematerialises>XML_PDF</formatDesFichiersDematerialises>
+				</gestionDesFichiersDematerialises>
+			</contact>
+			<categorieOuvrage>S</categorieOuvrage>
+			<classeOuvrage>LIGNES_ELECTRIQUES_ET_ECLAIRAGE_PUBLIC_HORS_TBT</classeOuvrage>
+			<codeOuvrage>ECLAIR</codeOuvrage>
+			<denominationOuvrage>Réseau d’éclairage public géré par le département</denominationOuvrage>
+			<statut>ACTIF</statut>
+			<dateCreation>2017-07-23+02:00</dateCreation>
+			<polygoneConcerne>true</polygoneConcerne>
+		</ouvrage>
+		<ouvrage>
+			<contact>
+				<societe>Conseil Départemental du Bas-Rhin</societe>
+				<agence>Unité Technique de Sélestat</agence>
+				<complement>BP 204</complement>
+				<voie>Route d’Orschwiller</voie>
+				<codePostal>67604</codePostal>
+				<commune>SELESTAT cedex</commune>
+				<codePays>FR</codePays>
+				<fax>0388822983</fax>
+				<courriel>utcd.selestat@bas-rhin.fr</courriel>
+				<telephone>0369067220</telephone>
+				<telephoneUrgence>0369067220</telephoneUrgence>
+				<faxUrgence>0388822983</faxUrgence>
+				<mailUrgence>utcd.selestat@bas-rhin.fr</mailUrgence>
+				<telEndommagement>0369067220</telEndommagement>
+				<referenceInterne/>
+				<gestionDesFichiersDematerialises>
+					<gereLesFichiersDematerialises>false</gereLesFichiersDematerialises>
+				</gestionDesFichiersDematerialises>
+			</contact>
+			<categorieOuvrage>NS</categorieOuvrage>
+			<classeOuvrage>AUTRE</classeOuvrage>
+			<codeOuvrage>RRD</codeOuvrage>
+			<denominationOuvrage>Réseau routier départemental</denominationOuvrage>
+			<statut>ACTIF</statut>
+			<dateCreation>2017-05-28+02:00</dateCreation>
+			<polygoneConcerne>true</polygoneConcerne>
+		</ouvrage>
+		<ouvrage>
+			<contact>
+				<nom>
+					<ns4:NomFamille>Cellule DICT du SDEA</ns4:NomFamille>
+				</nom>
+				<societe>Syndicat des Eaux et de l’Assainissement Alsace-Moselle</societe>
+				<complement>Espace Européen de l’Entreprise BP 10020</complement>
+				<numero>1</numero>
+				<voie>rue de Rome</voie>
+				<codePostal>67300</codePostal>
+				<commune>SCHILTIGHEIM</commune>
+				<codePays>FR</codePays>
+				<fax>0388811891</fax>
+				<courriel>dr-dict@sdea.fr</courriel>
+				<telephone>0388192919</telephone>
+				<telephoneUrgence>0388199709</telephoneUrgence>
+				<telEndommagement>0388199709</telEndommagement>
+				<consigne>Adresse mail pour les DT, DICT, ATU : dr-dict@sdea.fr&#xD;
+&#xD;
+Pour les urgences (traçages, repérages...) prière d'appeler le numéro de téléphone ci dessus.&#xD;
+&#xD;
+Pour les DT/DICT qui nous parviennent, privilégier SVP le XML ou le courrier papier.</consigne>
+				<referenceInterne/>
+				<site>www.sdea.fr</site>
+				<gestionDesFichiersDematerialises>
+					<gereLesFichiersDematerialises>true</gereLesFichiersDematerialises>
+					<formatDesFichiersDematerialises>XML</formatDesFichiersDematerialises>
+				</gestionDesFichiersDematerialises>
+			</contact>
+			<categorieOuvrage>NS</categorieOuvrage>
+			<classeOuvrage>CANALISATIONS_EAU_POTABLE</classeOuvrage>
+			<positionnementOuvrage>SOUTERRAIN</positionnementOuvrage>
+			<codeOuvrage>1-999</codeOuvrage>
+			<denominationOuvrage>Installations eau potable</denominationOuvrage>
+			<statut>ACTIF</statut>
+			<dateCreation>2017-07-30+02:00</dateCreation>
+			<polygoneConcerne>true</polygoneConcerne>
+		</ouvrage>
+		<ouvrage>
+			<contact>
+				<nom>
+					<ns4:NomFamille>M RAMTANE</ns4:NomFamille>
+				</nom>
+				<societe>NUMERICABLE</societe>
+				<agence>SERVICE DICT NORD EST</agence>
+				<complement>CS 50507 CHAMPS SUR MARNE</complement>
+				<numero>10</numero>
+				<voie>rue Albert Einstein</voie>
+				<codePostal>77447</codePostal>
+				<commune>MARNE LA VALLEE CEDEX 02</commune>
+				<codePays>FR</codePays>
+				<fax>0000000000</fax>
+				<courriel>dictnumericable@ncnumericable.com</courriel>
+				<telephone>0171583123</telephone>
+				<telephoneUrgence>0171583123</telephoneUrgence>
+				<faxUrgence>0000000000</faxUrgence>
+				<mailUrgence>dictnumericable@ncnumericable.com</mailUrgence>
+				<telEndommagement>0170015555</telEndommagement>
+				<referenceInterne/>
+				<gestionDesFichiersDematerialises>
+					<gereLesFichiersDematerialises>true</gereLesFichiersDematerialises>
+					<formatDesFichiersDematerialises>XML_PDF</formatDesFichiersDematerialises>
+				</gestionDesFichiersDematerialises>
+			</contact>
+			<categorieOuvrage>NS</categorieOuvrage>
+			<classeOuvrage>COMMUNICATIONS_ELECTRONIQUES_ET_LIGNES_ELECTRIQUES_ECLAIRAGE_TBT</classeOuvrage>
+			<positionnementOuvrage>AERIEN_ET_SOUTERRAIN</positionnementOuvrage>
+			<codeOuvrage>NC_NATIONAL_2015</codeOuvrage>
+			<denominationOuvrage>NC NUMERICABLE</denominationOuvrage>
+			<statut>ACTIF</statut>
+			<dateCreation>2017-06-25+02:00</dateCreation>
+			<polygoneConcerne>true</polygoneConcerne>
+		</ouvrage>
+		<ouvrage>
+			<contact>
+				<societe>Orange  L1</societe>
+				<agence>Orange DT/DICT</agence>
+				<voie>TSA 40111</voie>
+				<codePostal>69949</codePostal>
+				<commune>LYON CEDEX 20</commune>
+				<codePays>FR</codePays>
+				<fax>0489430095</fax>
+				<courriel>FT83L1.FTO@demat.protys.fr</courriel>
+				<telephone>0497461600</telephone>
+				<telephoneUrgence>0497461600</telephoneUrgence>
+				<mailUrgence>FT83L1.FTO@demat.protys.fr</mailUrgence>
+				<telEndommagement>0810300111</telEndommagement>
+				<referenceInterne>_|FTO$FT83L1|_</referenceInterne>
+				<site>www.protys.fr</site>
+				<gestionDesFichiersDematerialises>
+					<gereLesFichiersDematerialises>true</gereLesFichiersDematerialises>
+					<formatDesFichiersDematerialises>XML_PDF</formatDesFichiersDematerialises>
+				</gestionDesFichiersDematerialises>
+			</contact>
+			<categorieOuvrage>NS</categorieOuvrage>
+			<classeOuvrage>COMMUNICATIONS_ELECTRONIQUES_ET_LIGNES_ELECTRIQUES_ECLAIRAGE_TBT</classeOuvrage>
+			<codeOuvrage>FTO-67</codeOuvrage>
+			<denominationOuvrage>RESEAUX DE TELECOMMUNICATION FTO  -- BAS-RHIN (67)</denominationOuvrage>
+			<statut>ACTIF</statut>
+			<dateCreation>2017-08-06+02:00</dateCreation>
+			<polygoneConcerne>true</polygoneConcerne>
+		</ouvrage>
+	</listeDesOuvrages>
+	<listeDesREADE/>
+</dossierConsultation>

+ 76 - 0
tests/test_process.py

@@ -0,0 +1,76 @@
+'''
+
+'''
+import datetime
+import tempfile
+import unittest
+
+from path import Path
+from tests import HERE
+
+from core import constants, config
+from core.process import process
+
+
+class Test(unittest.TestCase):
+
+    def loadconfig(self):
+        constants.USER_DATA_PATH = HERE / r"rsc\test_process\userdata.yaml"
+        config.load()
+
+    def test_process(self):
+
+        self.loadconfig()
+
+        xmlpath = HERE / r"rsc\test_process\testfile.xml"
+
+        with tempfile.TemporaryDirectory() as outputdir:
+
+            outputdir = Path(outputdir)
+
+            config.CONFIG["repertoire_sortie"] = outputdir
+
+            # Returned results
+            files, mails = process(xmlpath)
+
+            self.assertEqual(files, [outputdir / r'testfile\Recepisse_DICT.pdf',
+                                      outputdir / r'testfile\Recepisse_DT.pdf'])
+
+            # mails
+            mail1, mail2 = mails
+
+            self.assertEqual(mail1.to, 'dict@spacex.net')
+            self.assertEqual(mail1.subject, 'Réponse à la demande 000001')
+            self.assertEqual(mail1.content, 'Veuillez trouver ci-joint la réponse à votre demande.\nCordialement,')
+            self.assertEqual(mail1.attachments, [])
+
+            self.assertEqual(mail2.to, 'dt@spacex.net')
+            self.assertEqual(mail2.subject, 'Réponse à la demande 000001')
+            self.assertEqual(mail2.content, 'Veuillez trouver ci-joint la réponse à votre demande.\nCordialement,')
+            self.assertEqual(mail2.attachments, [])
+
+            # Generated files
+            outputdir /= 'testfile'
+
+            self.assertTrue(Path(outputdir / 'contact.txt').exists())
+            with open(outputdir / 'contact.txt') as f:
+                self.assertEqual(f.read(), "dict@spacex.net\ndt@spacex.net")
+
+            self.assertTrue(Path(outputdir / 'data.fdf').exists())
+
+            with open(outputdir / 'data.fdf') as f, open(HERE / r'rsc\test_process\ref.fdf') as fref:
+                today = datetime.date.today()
+                self.assertEqual(f.read(), fref.read().format(day=today.day,
+                                                              month=today.month,
+                                                              year=today.year))
+
+            self.assertTrue(Path(outputdir / 'testfile.xml').exists())
+            with open(xmlpath) as f1, open(outputdir / 'testfile.xml') as f2:
+                self.assertEqual(f1.read(), f2.read())
+
+            self.assertTrue(Path(outputdir / 'Recepisse_DICT.pdf').exists())
+            self.assertTrue(Path(outputdir / 'Recepisse_DT.pdf').exists())
+
+
+if __name__ == "__main__":
+    unittest.main()

+ 20 - 0
tests/test_xmlparser.py

@@ -0,0 +1,20 @@
+'''
+Tests unitaires: parser de fichier XML
+
+@author: olivier.massot, oct. 2017
+'''
+import unittest
+
+from tests import HERE
+
+from core import xmlparser
+
+
+class Test(unittest.TestCase):
+
+    def test_parser(self):
+        data = xmlparser.parse(HERE / r"rsc\test_xmlparser\testfile.xml")
+        self.assertEqual(data['dtDictConjointes.noConsultationDuTeleservice'], '2017082500228P')
+
+if __name__ == "__main__":
+    unittest.main()

+ 0 - 0
ui/__init__.py


+ 0 - 0
ui/qt/__init__.py


+ 26 - 0
ui/qt/_generer.py

@@ -0,0 +1,26 @@
+'''
+Created on 17 avr. 2018
+
+@author: olivier.massot
+'''
+import subprocess
+
+from PyQt5 import uic
+from path import Path
+
+
+# http://pyqt.sourceforge.net/Docs/PyQt4/designer.html#pyuic4
+# http://pyqt.sourceforge.net/Docs/PyQt4/resources.html#pyrcc4
+
+HERE = Path(__file__).parent
+
+def rename(dirname, filename):
+    return dirname, (Path(dirname) / filename).name.stripext() + "_ui.py"
+
+uic.compileUiDir(HERE, map=rename, from_imports=True)
+
+for f in HERE.files("*.qrc"):
+    output = f.name.stripext() + "_rc.py"
+    subprocess.call(["pyrcc5", f, "-o", output])
+
+print("Génération terminée")

+ 119 - 0
ui/qt/filename_label.ui

@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Frame</class>
+ <widget class="QFrame" name="Frame">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>365</width>
+    <height>22</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>0</width>
+    <height>22</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>16777215</width>
+    <height>22</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Frame</string>
+  </property>
+  <property name="frameShape">
+   <enum>QFrame::StyledPanel</enum>
+  </property>
+  <property name="frameShadow">
+   <enum>QFrame::Raised</enum>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="spacing">
+    <number>0</number>
+   </property>
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
+   <item>
+    <widget class="QLineEdit" name="txtFilename">
+     <property name="minimumSize">
+      <size>
+       <width>345</width>
+       <height>20</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>20</height>
+      </size>
+     </property>
+     <property name="palette">
+      <palette>
+       <active>
+        <colorrole role="Base">
+         <brush brushstyle="SolidPattern">
+          <color alpha="0">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+       </active>
+       <inactive>
+        <colorrole role="Base">
+         <brush brushstyle="SolidPattern">
+          <color alpha="0">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+       </inactive>
+       <disabled>
+        <colorrole role="Base">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>240</red>
+           <green>240</green>
+           <blue>240</blue>
+          </color>
+         </brush>
+        </colorrole>
+       </disabled>
+      </palette>
+     </property>
+     <property name="font">
+      <font>
+       <family>Arial</family>
+       <italic>true</italic>
+      </font>
+     </property>
+     <property name="text">
+      <string/>
+     </property>
+     <property name="frame">
+      <bool>false</bool>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 52 - 0
ui/qt/filename_label_ui.py

@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'C:\dev\python\pardit\ui\qt\filename_label.ui'
+#
+# Created by: PyQt5 UI code generator 5.8.2
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+class Ui_Frame(object):
+    def setupUi(self, Frame):
+        Frame.setObjectName("Frame")
+        Frame.resize(365, 22)
+        Frame.setMinimumSize(QtCore.QSize(0, 22))
+        Frame.setMaximumSize(QtCore.QSize(16777215, 22))
+        Frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
+        Frame.setFrameShadow(QtWidgets.QFrame.Raised)
+        self.verticalLayout = QtWidgets.QVBoxLayout(Frame)
+        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
+        self.verticalLayout.setSpacing(0)
+        self.verticalLayout.setObjectName("verticalLayout")
+        self.txtFilename = QtWidgets.QLineEdit(Frame)
+        self.txtFilename.setMinimumSize(QtCore.QSize(345, 20))
+        self.txtFilename.setMaximumSize(QtCore.QSize(16777215, 20))
+        palette = QtGui.QPalette()
+        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255, 0))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255, 0))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(240, 240, 240))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
+        self.txtFilename.setPalette(palette)
+        font = QtGui.QFont()
+        font.setFamily("Arial")
+        font.setItalic(True)
+        self.txtFilename.setFont(font)
+        self.txtFilename.setText("")
+        self.txtFilename.setFrame(False)
+        self.txtFilename.setObjectName("txtFilename")
+        self.verticalLayout.addWidget(self.txtFilename)
+
+        self.retranslateUi(Frame)
+        QtCore.QMetaObject.connectSlotsByName(Frame)
+
+    def retranslateUi(self, Frame):
+        _translate = QtCore.QCoreApplication.translate
+        Frame.setWindowTitle(_translate("Frame", "Frame"))
+

+ 600 - 0
ui/qt/main.ui

@@ -0,0 +1,600 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>mainWindow</class>
+ <widget class="QMainWindow" name="mainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>521</width>
+    <height>292</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>521</width>
+    <height>292</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>521</width>
+    <height>300</height>
+   </size>
+  </property>
+  <property name="font">
+   <font>
+    <family>Verdana</family>
+    <pointsize>8</pointsize>
+   </font>
+  </property>
+  <property name="windowTitle">
+   <string>Pardit</string>
+  </property>
+  <property name="windowIcon">
+   <iconset resource="pardit.qrc">
+    <normaloff>:/img/rsc/cone.png</normaloff>:/img/rsc/cone.png</iconset>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <layout class="QVBoxLayout" name="verticalLayout">
+    <property name="spacing">
+     <number>3</number>
+    </property>
+    <property name="leftMargin">
+     <number>3</number>
+    </property>
+    <property name="topMargin">
+     <number>3</number>
+    </property>
+    <property name="rightMargin">
+     <number>3</number>
+    </property>
+    <property name="bottomMargin">
+     <number>3</number>
+    </property>
+    <item>
+     <widget class="QStackedWidget" name="mainStack">
+      <property name="currentIndex">
+       <number>0</number>
+      </property>
+      <widget class="QWidget" name="page0">
+       <layout class="QVBoxLayout" name="verticalLayout_2">
+        <item>
+         <widget class="DropLabel" name="lblDropzone">
+          <property name="minimumSize">
+           <size>
+            <width>0</width>
+            <height>150</height>
+           </size>
+          </property>
+          <property name="palette">
+           <palette>
+            <active>
+             <colorrole role="Base">
+              <brush brushstyle="SolidPattern">
+               <color alpha="255">
+                <red>255</red>
+                <green>255</green>
+                <blue>255</blue>
+               </color>
+              </brush>
+             </colorrole>
+             <colorrole role="Window">
+              <brush brushstyle="SolidPattern">
+               <color alpha="110">
+                <red>255</red>
+                <green>255</green>
+                <blue>255</blue>
+               </color>
+              </brush>
+             </colorrole>
+            </active>
+            <inactive>
+             <colorrole role="Base">
+              <brush brushstyle="SolidPattern">
+               <color alpha="255">
+                <red>255</red>
+                <green>255</green>
+                <blue>255</blue>
+               </color>
+              </brush>
+             </colorrole>
+             <colorrole role="Window">
+              <brush brushstyle="SolidPattern">
+               <color alpha="110">
+                <red>255</red>
+                <green>255</green>
+                <blue>255</blue>
+               </color>
+              </brush>
+             </colorrole>
+            </inactive>
+            <disabled>
+             <colorrole role="Base">
+              <brush brushstyle="SolidPattern">
+               <color alpha="110">
+                <red>255</red>
+                <green>255</green>
+                <blue>255</blue>
+               </color>
+              </brush>
+             </colorrole>
+             <colorrole role="Window">
+              <brush brushstyle="SolidPattern">
+               <color alpha="110">
+                <red>255</red>
+                <green>255</green>
+                <blue>255</blue>
+               </color>
+              </brush>
+             </colorrole>
+            </disabled>
+           </palette>
+          </property>
+          <property name="font">
+           <font>
+            <pointsize>9</pointsize>
+            <weight>75</weight>
+            <bold>true</bold>
+           </font>
+          </property>
+          <property name="acceptDrops">
+           <bool>true</bool>
+          </property>
+          <property name="autoFillBackground">
+           <bool>true</bool>
+          </property>
+          <property name="frameShape">
+           <enum>QFrame::Box</enum>
+          </property>
+          <property name="frameShadow">
+           <enum>QFrame::Raised</enum>
+          </property>
+          <property name="text">
+           <string>Déposer votre fichier ici</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignCenter</set>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="verticalSpacer">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>40</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout_2">
+          <property name="leftMargin">
+           <number>10</number>
+          </property>
+          <property name="rightMargin">
+           <number>10</number>
+          </property>
+          <item>
+           <widget class="QLabel" name="label_2">
+            <property name="font">
+             <font>
+              <italic>true</italic>
+             </font>
+            </property>
+            <property name="text">
+             <string>Ou:</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="btnRun">
+            <property name="minimumSize">
+             <size>
+              <width>250</width>
+              <height>41</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>1000</width>
+              <height>41</height>
+             </size>
+            </property>
+            <property name="font">
+             <font>
+              <family>Verdana</family>
+              <pointsize>9</pointsize>
+              <weight>75</weight>
+              <bold>true</bold>
+             </font>
+            </property>
+            <property name="text">
+             <string>Sélectionnez le fichier à traiter</string>
+            </property>
+            <property name="autoDefault">
+             <bool>false</bool>
+            </property>
+            <property name="default">
+             <bool>true</bool>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+        <item>
+         <spacer name="verticalSpacer_3">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>40</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <spacer name="verticalSpacer_2">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>40</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout">
+          <item>
+           <spacer name="horizontalSpacer">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>40</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item>
+           <widget class="QPushButton" name="btnHelp">
+            <property name="minimumSize">
+             <size>
+              <width>121</width>
+              <height>31</height>
+             </size>
+            </property>
+            <property name="text">
+             <string> Aide</string>
+            </property>
+            <property name="icon">
+             <iconset resource="pardit.qrc">
+              <normaloff>:/img/rsc/question.png</normaloff>:/img/rsc/question.png</iconset>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="btnSettings">
+            <property name="minimumSize">
+             <size>
+              <width>121</width>
+              <height>31</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>121</width>
+              <height>31</height>
+             </size>
+            </property>
+            <property name="font">
+             <font>
+              <family>Verdana</family>
+              <pointsize>8</pointsize>
+             </font>
+            </property>
+            <property name="text">
+             <string> Configuration</string>
+            </property>
+            <property name="icon">
+             <iconset resource="pardit.qrc">
+              <normaloff>:/img/rsc/settings.png</normaloff>:/img/rsc/settings.png</iconset>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="page1">
+       <layout class="QVBoxLayout" name="verticalLayout_3">
+        <item>
+         <widget class="QLabel" name="lblWait">
+          <property name="font">
+           <font>
+            <family>Verdana</family>
+            <pointsize>11</pointsize>
+           </font>
+          </property>
+          <property name="text">
+           <string>Veuillez patienter...</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignCenter</set>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout_3">
+          <item>
+           <widget class="QLabel" name="imgHourglass">
+            <property name="minimumSize">
+             <size>
+              <width>61</width>
+              <height>81</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>61</width>
+              <height>81</height>
+             </size>
+            </property>
+            <property name="text">
+             <string/>
+            </property>
+            <property name="pixmap">
+             <pixmap resource="pardit.qrc">:/img/rsc/hourglass.png</pixmap>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="page2">
+       <layout class="QVBoxLayout" name="verticalLayout_4">
+        <item>
+         <layout class="QVBoxLayout" name="verticalLayout_6" stretch="5,0,5,1">
+          <property name="bottomMargin">
+           <number>0</number>
+          </property>
+          <item>
+           <layout class="QHBoxLayout" name="horizontalLayout_4">
+            <property name="leftMargin">
+             <number>6</number>
+            </property>
+            <property name="rightMargin">
+             <number>6</number>
+            </property>
+            <item>
+             <widget class="QLabel" name="lblFilenameTitle">
+              <property name="font">
+               <font>
+                <pointsize>9</pointsize>
+                <weight>75</weight>
+                <bold>true</bold>
+               </font>
+              </property>
+              <property name="text">
+               <string>Opération réussie</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <spacer name="horizontalSpacer_4">
+              <property name="orientation">
+               <enum>Qt::Horizontal</enum>
+              </property>
+              <property name="sizeHint" stdset="0">
+               <size>
+                <width>40</width>
+                <height>20</height>
+               </size>
+              </property>
+             </spacer>
+            </item>
+           </layout>
+          </item>
+          <item>
+           <layout class="QVBoxLayout" name="filenames_layout"/>
+          </item>
+          <item>
+           <layout class="QHBoxLayout" name="horizontalLayout_5">
+            <property name="spacing">
+             <number>15</number>
+            </property>
+            <property name="leftMargin">
+             <number>15</number>
+            </property>
+            <property name="rightMargin">
+             <number>15</number>
+            </property>
+            <item>
+             <widget class="QPushButton" name="btnOpen">
+              <property name="minimumSize">
+               <size>
+                <width>0</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="text">
+               <string> Voir</string>
+              </property>
+              <property name="icon">
+               <iconset resource="pardit.qrc">
+                <normaloff>:/img/rsc/pdf.png</normaloff>:/img/rsc/pdf.png</iconset>
+              </property>
+              <property name="iconSize">
+               <size>
+                <width>20</width>
+                <height>20</height>
+               </size>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QPushButton" name="btnDir">
+              <property name="minimumSize">
+               <size>
+                <width>0</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="text">
+               <string>Ouvrir le dossier</string>
+              </property>
+              <property name="icon">
+               <iconset resource="pardit.qrc">
+                <normaloff>:/img/rsc/folder.png</normaloff>:/img/rsc/folder.png</iconset>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QPushButton" name="btnMail">
+              <property name="minimumSize">
+               <size>
+                <width>0</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="text">
+               <string> Envoyer par mail</string>
+              </property>
+              <property name="icon">
+               <iconset resource="pardit.qrc">
+                <normaloff>:/img/rsc/email.png</normaloff>:/img/rsc/email.png</iconset>
+              </property>
+              <property name="iconSize">
+               <size>
+                <width>18</width>
+                <height>18</height>
+               </size>
+              </property>
+              <property name="shortcut">
+               <string>Ctrl+S</string>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
+          <item>
+           <layout class="QHBoxLayout" name="horizontalLayout_6">
+            <property name="sizeConstraint">
+             <enum>QLayout::SetMinimumSize</enum>
+            </property>
+            <item>
+             <widget class="QPushButton" name="btnCancel">
+              <property name="minimumSize">
+               <size>
+                <width>0</width>
+                <height>20</height>
+               </size>
+              </property>
+              <property name="maximumSize">
+               <size>
+                <width>16777215</width>
+                <height>20</height>
+               </size>
+              </property>
+              <property name="palette">
+               <palette>
+                <active>
+                 <colorrole role="ButtonText">
+                  <brush brushstyle="SolidPattern">
+                   <color alpha="255">
+                    <red>0</red>
+                    <green>0</green>
+                    <blue>127</blue>
+                   </color>
+                  </brush>
+                 </colorrole>
+                </active>
+                <inactive>
+                 <colorrole role="ButtonText">
+                  <brush brushstyle="SolidPattern">
+                   <color alpha="255">
+                    <red>0</red>
+                    <green>0</green>
+                    <blue>127</blue>
+                   </color>
+                  </brush>
+                 </colorrole>
+                </inactive>
+                <disabled>
+                 <colorrole role="ButtonText">
+                  <brush brushstyle="SolidPattern">
+                   <color alpha="255">
+                    <red>120</red>
+                    <green>120</green>
+                    <blue>120</blue>
+                   </color>
+                  </brush>
+                 </colorrole>
+                </disabled>
+               </palette>
+              </property>
+              <property name="font">
+               <font>
+                <underline>true</underline>
+               </font>
+              </property>
+              <property name="text">
+               <string>Retour</string>
+              </property>
+              <property name="flat">
+               <bool>false</bool>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <spacer name="horizontalSpacer_5">
+              <property name="orientation">
+               <enum>Qt::Horizontal</enum>
+              </property>
+              <property name="sizeType">
+               <enum>QSizePolicy::Expanding</enum>
+              </property>
+              <property name="sizeHint" stdset="0">
+               <size>
+                <width>40</width>
+                <height>0</height>
+               </size>
+              </property>
+             </spacer>
+            </item>
+           </layout>
+          </item>
+         </layout>
+        </item>
+       </layout>
+      </widget>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>DropLabel</class>
+   <extends>QLabel</extends>
+   <header>ui.widgets.DropLabel.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources>
+  <include location="pardit.qrc"/>
+ </resources>
+ <connections/>
+</ui>

+ 260 - 0
ui/qt/main_ui.py

@@ -0,0 +1,260 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'C:\dev\python\pardit\ui\qt\main.ui'
+#
+# Created by: PyQt5 UI code generator 5.8.2
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+class Ui_mainWindow(object):
+    def setupUi(self, mainWindow):
+        mainWindow.setObjectName("mainWindow")
+        mainWindow.resize(521, 292)
+        mainWindow.setMinimumSize(QtCore.QSize(521, 292))
+        mainWindow.setMaximumSize(QtCore.QSize(521, 300))
+        font = QtGui.QFont()
+        font.setFamily("Verdana")
+        font.setPointSize(8)
+        mainWindow.setFont(font)
+        icon = QtGui.QIcon()
+        icon.addPixmap(QtGui.QPixmap(":/img/rsc/cone.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+        mainWindow.setWindowIcon(icon)
+        self.centralwidget = QtWidgets.QWidget(mainWindow)
+        self.centralwidget.setObjectName("centralwidget")
+        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
+        self.verticalLayout.setContentsMargins(3, 3, 3, 3)
+        self.verticalLayout.setSpacing(3)
+        self.verticalLayout.setObjectName("verticalLayout")
+        self.mainStack = QtWidgets.QStackedWidget(self.centralwidget)
+        self.mainStack.setObjectName("mainStack")
+        self.page0 = QtWidgets.QWidget()
+        self.page0.setObjectName("page0")
+        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.page0)
+        self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
+        self.verticalLayout_2.setObjectName("verticalLayout_2")
+        self.lblDropzone = DropLabel(self.page0)
+        self.lblDropzone.setMinimumSize(QtCore.QSize(0, 150))
+        palette = QtGui.QPalette()
+        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255, 110))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush)
+        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255, 110))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Window, brush)
+        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255, 110))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255, 110))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush)
+        self.lblDropzone.setPalette(palette)
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(True)
+        font.setWeight(75)
+        self.lblDropzone.setFont(font)
+        self.lblDropzone.setAcceptDrops(True)
+        self.lblDropzone.setAutoFillBackground(True)
+        self.lblDropzone.setFrameShape(QtWidgets.QFrame.Box)
+        self.lblDropzone.setFrameShadow(QtWidgets.QFrame.Raised)
+        self.lblDropzone.setAlignment(QtCore.Qt.AlignCenter)
+        self.lblDropzone.setObjectName("lblDropzone")
+        self.verticalLayout_2.addWidget(self.lblDropzone)
+        spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+        self.verticalLayout_2.addItem(spacerItem)
+        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_2.setContentsMargins(10, -1, 10, -1)
+        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+        self.label_2 = QtWidgets.QLabel(self.page0)
+        font = QtGui.QFont()
+        font.setItalic(True)
+        self.label_2.setFont(font)
+        self.label_2.setObjectName("label_2")
+        self.horizontalLayout_2.addWidget(self.label_2)
+        self.btnRun = QtWidgets.QPushButton(self.page0)
+        self.btnRun.setMinimumSize(QtCore.QSize(250, 41))
+        self.btnRun.setMaximumSize(QtCore.QSize(1000, 41))
+        font = QtGui.QFont()
+        font.setFamily("Verdana")
+        font.setPointSize(9)
+        font.setBold(True)
+        font.setWeight(75)
+        self.btnRun.setFont(font)
+        self.btnRun.setAutoDefault(False)
+        self.btnRun.setDefault(True)
+        self.btnRun.setObjectName("btnRun")
+        self.horizontalLayout_2.addWidget(self.btnRun)
+        self.verticalLayout_2.addLayout(self.horizontalLayout_2)
+        spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+        self.verticalLayout_2.addItem(spacerItem1)
+        spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+        self.verticalLayout_2.addItem(spacerItem2)
+        self.horizontalLayout = QtWidgets.QHBoxLayout()
+        self.horizontalLayout.setObjectName("horizontalLayout")
+        spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+        self.horizontalLayout.addItem(spacerItem3)
+        self.btnHelp = QtWidgets.QPushButton(self.page0)
+        self.btnHelp.setMinimumSize(QtCore.QSize(121, 31))
+        icon1 = QtGui.QIcon()
+        icon1.addPixmap(QtGui.QPixmap(":/img/rsc/question.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+        self.btnHelp.setIcon(icon1)
+        self.btnHelp.setObjectName("btnHelp")
+        self.horizontalLayout.addWidget(self.btnHelp)
+        self.btnSettings = QtWidgets.QPushButton(self.page0)
+        self.btnSettings.setMinimumSize(QtCore.QSize(121, 31))
+        self.btnSettings.setMaximumSize(QtCore.QSize(121, 31))
+        font = QtGui.QFont()
+        font.setFamily("Verdana")
+        font.setPointSize(8)
+        self.btnSettings.setFont(font)
+        icon2 = QtGui.QIcon()
+        icon2.addPixmap(QtGui.QPixmap(":/img/rsc/settings.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+        self.btnSettings.setIcon(icon2)
+        self.btnSettings.setObjectName("btnSettings")
+        self.horizontalLayout.addWidget(self.btnSettings)
+        self.verticalLayout_2.addLayout(self.horizontalLayout)
+        self.mainStack.addWidget(self.page0)
+        self.page1 = QtWidgets.QWidget()
+        self.page1.setObjectName("page1")
+        self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.page1)
+        self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
+        self.verticalLayout_3.setObjectName("verticalLayout_3")
+        self.lblWait = QtWidgets.QLabel(self.page1)
+        font = QtGui.QFont()
+        font.setFamily("Verdana")
+        font.setPointSize(11)
+        self.lblWait.setFont(font)
+        self.lblWait.setAlignment(QtCore.Qt.AlignCenter)
+        self.lblWait.setObjectName("lblWait")
+        self.verticalLayout_3.addWidget(self.lblWait)
+        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
+        self.imgHourglass = QtWidgets.QLabel(self.page1)
+        self.imgHourglass.setMinimumSize(QtCore.QSize(61, 81))
+        self.imgHourglass.setMaximumSize(QtCore.QSize(61, 81))
+        self.imgHourglass.setText("")
+        self.imgHourglass.setPixmap(QtGui.QPixmap(":/img/rsc/hourglass.png"))
+        self.imgHourglass.setObjectName("imgHourglass")
+        self.horizontalLayout_3.addWidget(self.imgHourglass)
+        self.verticalLayout_3.addLayout(self.horizontalLayout_3)
+        self.mainStack.addWidget(self.page1)
+        self.page2 = QtWidgets.QWidget()
+        self.page2.setObjectName("page2")
+        self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.page2)
+        self.verticalLayout_4.setContentsMargins(0, 0, 0, 0)
+        self.verticalLayout_4.setObjectName("verticalLayout_4")
+        self.verticalLayout_6 = QtWidgets.QVBoxLayout()
+        self.verticalLayout_6.setContentsMargins(-1, -1, -1, 0)
+        self.verticalLayout_6.setObjectName("verticalLayout_6")
+        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_4.setContentsMargins(6, -1, 6, -1)
+        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
+        self.lblFilenameTitle = QtWidgets.QLabel(self.page2)
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(True)
+        font.setWeight(75)
+        self.lblFilenameTitle.setFont(font)
+        self.lblFilenameTitle.setObjectName("lblFilenameTitle")
+        self.horizontalLayout_4.addWidget(self.lblFilenameTitle)
+        spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+        self.horizontalLayout_4.addItem(spacerItem4)
+        self.verticalLayout_6.addLayout(self.horizontalLayout_4)
+        self.filenames_layout = QtWidgets.QVBoxLayout()
+        self.filenames_layout.setObjectName("filenames_layout")
+        self.verticalLayout_6.addLayout(self.filenames_layout)
+        self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_5.setContentsMargins(15, -1, 15, -1)
+        self.horizontalLayout_5.setSpacing(15)
+        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
+        self.btnOpen = QtWidgets.QPushButton(self.page2)
+        self.btnOpen.setMinimumSize(QtCore.QSize(0, 32))
+        icon3 = QtGui.QIcon()
+        icon3.addPixmap(QtGui.QPixmap(":/img/rsc/pdf.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+        self.btnOpen.setIcon(icon3)
+        self.btnOpen.setIconSize(QtCore.QSize(20, 20))
+        self.btnOpen.setObjectName("btnOpen")
+        self.horizontalLayout_5.addWidget(self.btnOpen)
+        self.btnDir = QtWidgets.QPushButton(self.page2)
+        self.btnDir.setMinimumSize(QtCore.QSize(0, 32))
+        icon4 = QtGui.QIcon()
+        icon4.addPixmap(QtGui.QPixmap(":/img/rsc/folder.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+        self.btnDir.setIcon(icon4)
+        self.btnDir.setObjectName("btnDir")
+        self.horizontalLayout_5.addWidget(self.btnDir)
+        self.btnMail = QtWidgets.QPushButton(self.page2)
+        self.btnMail.setMinimumSize(QtCore.QSize(0, 32))
+        icon5 = QtGui.QIcon()
+        icon5.addPixmap(QtGui.QPixmap(":/img/rsc/email.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+        self.btnMail.setIcon(icon5)
+        self.btnMail.setIconSize(QtCore.QSize(18, 18))
+        self.btnMail.setObjectName("btnMail")
+        self.horizontalLayout_5.addWidget(self.btnMail)
+        self.verticalLayout_6.addLayout(self.horizontalLayout_5)
+        self.horizontalLayout_6 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_6.setSizeConstraint(QtWidgets.QLayout.SetMinimumSize)
+        self.horizontalLayout_6.setObjectName("horizontalLayout_6")
+        self.btnCancel = QtWidgets.QPushButton(self.page2)
+        self.btnCancel.setMinimumSize(QtCore.QSize(0, 20))
+        self.btnCancel.setMaximumSize(QtCore.QSize(16777215, 20))
+        palette = QtGui.QPalette()
+        brush = QtGui.QBrush(QtGui.QColor(0, 0, 127))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ButtonText, brush)
+        brush = QtGui.QBrush(QtGui.QColor(0, 0, 127))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ButtonText, brush)
+        brush = QtGui.QBrush(QtGui.QColor(120, 120, 120))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ButtonText, brush)
+        self.btnCancel.setPalette(palette)
+        font = QtGui.QFont()
+        font.setUnderline(True)
+        self.btnCancel.setFont(font)
+        self.btnCancel.setFlat(False)
+        self.btnCancel.setObjectName("btnCancel")
+        self.horizontalLayout_6.addWidget(self.btnCancel)
+        spacerItem5 = QtWidgets.QSpacerItem(40, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+        self.horizontalLayout_6.addItem(spacerItem5)
+        self.verticalLayout_6.addLayout(self.horizontalLayout_6)
+        self.verticalLayout_6.setStretch(0, 5)
+        self.verticalLayout_6.setStretch(2, 5)
+        self.verticalLayout_6.setStretch(3, 1)
+        self.verticalLayout_4.addLayout(self.verticalLayout_6)
+        self.mainStack.addWidget(self.page2)
+        self.verticalLayout.addWidget(self.mainStack)
+        mainWindow.setCentralWidget(self.centralwidget)
+        self.statusbar = QtWidgets.QStatusBar(mainWindow)
+        self.statusbar.setObjectName("statusbar")
+        mainWindow.setStatusBar(self.statusbar)
+
+        self.retranslateUi(mainWindow)
+        self.mainStack.setCurrentIndex(0)
+        QtCore.QMetaObject.connectSlotsByName(mainWindow)
+
+    def retranslateUi(self, mainWindow):
+        _translate = QtCore.QCoreApplication.translate
+        mainWindow.setWindowTitle(_translate("mainWindow", "Pardit"))
+        self.lblDropzone.setText(_translate("mainWindow", "Déposer votre fichier ici"))
+        self.label_2.setText(_translate("mainWindow", "Ou:"))
+        self.btnRun.setText(_translate("mainWindow", "Sélectionnez le fichier à traiter"))
+        self.btnHelp.setText(_translate("mainWindow", " Aide"))
+        self.btnSettings.setText(_translate("mainWindow", " Configuration"))
+        self.lblWait.setText(_translate("mainWindow", "Veuillez patienter..."))
+        self.lblFilenameTitle.setText(_translate("mainWindow", "Opération réussie"))
+        self.btnOpen.setText(_translate("mainWindow", " Voir"))
+        self.btnDir.setText(_translate("mainWindow", "Ouvrir le dossier"))
+        self.btnMail.setText(_translate("mainWindow", " Envoyer par mail"))
+        self.btnMail.setShortcut(_translate("mainWindow", "Ctrl+S"))
+        self.btnCancel.setText(_translate("mainWindow", "Retour"))
+
+from ui.widgets.DropLabel import DropLabel
+from . import pardit_rc

+ 13 - 0
ui/qt/pardit.qrc

@@ -0,0 +1,13 @@
+<RCC>
+  <qresource prefix="img">
+    <file>../rsc/folder.png</file>
+    <file>../rsc/settings.png</file>
+    <file>../rsc/question.png</file>
+    <file>../rsc/save.png</file>
+    <file>../rsc/email.png</file>
+    <file>../rsc/pdf.png</file>
+    <file>../rsc/barrier.png</file>
+    <file>../rsc/cone.png</file>
+    <file>../rsc/hourglass.png</file>
+  </qresource>
+</RCC>

+ 966 - 0
ui/qt/pardit_rc.py

@@ -0,0 +1,966 @@
+# -*- coding: utf-8 -*-
+
+# Resource object code
+#
+# Created by: The Resource Compiler for PyQt5 (Qt v5.8.0)
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore
+
+qt_resource_data = b"\
+\x00\x00\x05\xc0\
+\x89\
+\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
+\x00\x00\x40\x00\x00\x00\x40\x08\x03\x00\x00\x00\x9d\xb7\x81\xec\
+\x00\x00\x00\x03\x73\x42\x49\x54\x08\x08\x08\xdb\xe1\x4f\xe0\x00\
+\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0f\xd1\x00\x00\x0f\xd1\x01\
+\x56\x30\x1a\xa4\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\
+\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\
+\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x02\x85\x50\x4c\x54\
+\x45\xff\xff\xff\xe3\xe3\xe3\xde\xab\xa3\xe6\xe2\xd9\xe9\xe9\xe1\
+\xe1\xe1\xd5\xe1\xdf\xd5\xdf\xdf\xd3\xe2\xdf\xd5\xdf\xdf\xd3\xe0\
+\xe0\xd4\xe8\xe8\xe0\xe9\xe9\xe0\xea\xea\xdf\xe0\xb0\xaa\xe9\xe9\
+\xe1\xd6\x88\x84\xd5\x7b\x79\xe7\xe7\xdd\xd3\x6c\x6b\xde\xdc\xd1\
+\xda\xd8\xcc\xcc\x4b\x4c\xcc\x4c\x4d\xcc\x4d\x4e\xcd\x4d\x4e\xcd\
+\x4e\x4f\xcd\x4f\x50\xcd\x51\x51\xcd\x51\x52\xcd\x52\x52\xcd\x52\
+\x53\xcd\x53\x54\xce\x51\x52\xce\x54\x54\xce\x55\x55\xce\x56\x56\
+\xce\x57\x58\xce\x58\x58\xcf\x56\x57\xcf\x59\x59\xcf\x5b\x5b\xcf\
+\x5c\x5c\xcf\x5d\x5d\xcf\x5e\x5d\xd0\x58\x59\xd0\x5e\x5e\xd0\x5f\
+\x5f\xd0\x63\x63\xd1\x5c\x5d\xd1\x65\x64\xd1\x67\x66\xd1\x68\x67\
+\xd1\x69\x68\xd2\x69\x68\xd2\x6a\x69\xd2\x6c\x6b\xd2\x6d\x6c\xd2\
+\x6e\x6d\xd3\x65\x66\xd3\x6f\x6e\xd3\x70\x6e\xd3\x71\x70\xd3\x73\
+\x72\xd4\x67\x68\xd4\x68\x69\xd4\x76\x74\xd4\x77\x75\xd4\x78\x76\
+\xd5\x6b\x6c\xd5\x79\x78\xd5\x7a\x78\xd5\x7b\x79\xd5\x7d\x7b\xd5\
+\x7e\x7c\xd6\x80\x7d\xd6\x82\x7f\xd6\x83\x80\xd6\x83\x81\xd7\x72\
+\x73\xd7\x85\x83\xd7\x86\x83\xd7\x86\x84\xd7\x87\x84\xd7\x88\x85\
+\xd8\x74\x75\xd8\x76\x77\xd8\x8b\x88\xd8\x8e\x8b\xd8\x8f\x8b\xd9\
+\x77\x78\xd9\x78\x79\xd9\x79\x7a\xd9\x7a\x7a\xd9\x7a\x7b\xd9\x90\
+\x8d\xd9\x91\x8e\xd9\x92\x8e\xd9\x92\x8f\xd9\xd7\xca\xda\x7c\x7c\
+\xda\x95\x92\xda\x97\x93\xda\x99\x95\xda\x9a\x96\xdb\x81\x81\xdb\
+\x9a\x96\xdb\x9d\x99\xdb\x9e\x9a\xdc\xa2\x9e\xdc\xa4\x9f\xdd\xa9\
+\xa4\xdd\xdc\xd0\xde\x8b\x8b\xde\xab\xa6\xde\xac\xa7\xde\xad\xa8\
+\xdf\x8d\x8d\xdf\x8f\x8f\xdf\xb1\xac\xdf\xb2\xad\xdf\xb3\xae\xdf\
+\xb4\xae\xdf\xb5\xaf\xe0\x91\x91\xe0\x92\x92\xe0\xb6\xb0\xe0\xb8\
+\xb2\xe0\xba\xb4\xe1\x94\x95\xe1\x95\x96\xe1\xbc\xb6\xe1\xbe\xb8\
+\xe1\xbf\xb9\xe1\xc0\xba\xe2\x99\x99\xe2\x9a\x9b\xe2\xc1\xbb\xe3\
+\x9b\x9c\xe3\xc6\xbf\xe3\xc8\xc1\xe3\xc9\xc2\xe4\xa0\xa0\xe4\xcb\
+\xc4\xe4\xcc\xc5\xe4\xce\xc6\xe4\xd0\xc9\xe5\xa3\xa4\xe5\xa4\xa4\
+\xe5\xd2\xcb\xe5\xd3\xcb\xe5\xd3\xcc\xe6\xa7\xa8\xe6\xd6\xcf\xe6\
+\xd8\xd0\xe6\xd9\xd1\xe6\xda\xd2\xe6\xdb\xd3\xe6\xe6\xdd\xe7\xaa\
+\xaa\xe7\xaa\xab\xe7\xdd\xd4\xe7\xdf\xd7\xe7\xe0\xd7\xe7\xe0\xd8\
+\xe7\xe7\xde\xe8\xe2\xd9\xe8\xe3\xdb\xe8\xe4\xdb\xe8\xe5\xdc\xe8\
+\xe5\xdd\xe8\xe6\xdd\xe9\xb0\xb0\xe9\xb1\xb1\xe9\xe7\xde\xe9\xe8\
+\xdf\xe9\xe9\xe0\xea\xb3\xb4\xea\xb4\xb5\xeb\xb8\xb8\xec\xbb\xbc\
+\xed\xbe\xbe\xed\xbf\xbf\xed\xc0\xc1\xee\xc2\xc3\xef\xc7\xc7\xf0\
+\xc9\xc9\xf0\xc9\xca\xf0\xca\xca\xf2\xd1\xd1\xf3\xd4\xd4\xf3\xd5\
+\xd6\xf4\xd7\xd7\xf4\xd9\xd9\xf4\xda\xda\xf5\xdb\xdb\xf5\xdc\xdd\
+\xf6\xde\xde\xf6\xe0\xe0\xf7\xe1\xe2\xf7\xe3\xe4\xf8\xe6\xe6\xf9\
+\xe9\xe9\xf9\xeb\xeb\xfa\xed\xed\xfa\xef\xef\xfb\xf2\xf2\xfc\xf4\
+\xf4\xfc\xf6\xf6\xfd\xf9\xf9\xfe\xfa\xfa\xfe\xfb\xfb\xfe\xfd\xfd\
+\xff\xfe\xfe\xff\xff\xff\x04\x4a\x1d\x54\x00\x00\x00\x16\x74\x52\
+\x4e\x53\x00\x12\x3d\x3d\x5d\x66\x67\x68\x68\x69\x6a\x7b\x8e\x90\
+\xab\xb8\xc3\xcf\xe7\xf1\xfb\xfe\x6b\x8f\xc5\x1b\x00\x00\x02\x8b\
+\x49\x44\x41\x54\x58\xc3\xed\xd5\xe7\x5b\xd3\x40\x1c\x07\xf0\x8a\
+\x7b\x80\x20\xe6\x9b\xda\x88\x22\xe0\x40\x94\x3a\x90\xba\x71\xef\
+\x59\xf7\x1e\x45\x1c\x28\xee\x3d\x18\x2e\x54\xac\x15\x27\x60\x1d\
+\xa8\x38\xb0\xe1\xdc\x7b\x83\x5b\xab\xa2\xf7\xf7\x98\x3c\xa6\xda\
+\xa7\xa6\xe5\x92\x3c\xbe\xf1\xf1\xfb\x26\xbf\xcb\x3d\xf7\xc9\x5d\
+\x2e\xc3\x64\xfa\x99\x5a\x4d\x49\x4d\x69\x56\xd7\x14\x22\x75\x6a\
+\x1c\x4f\x4e\x73\xa1\x84\x26\x0c\x80\x83\xab\x17\x1c\x08\x67\x01\
+\x42\x09\x6c\x40\x08\x81\x11\x70\x70\xf5\x0d\x02\x41\x85\x60\x80\
+\x28\x06\x00\x0e\xae\x81\x16\x20\xcb\x62\x3d\x11\x00\x04\x11\xd4\
+\x81\x5d\x3c\x30\x2a\x10\x50\x17\xd4\x81\x0c\x2c\x8e\x8b\xad\x08\
+\x04\x1c\x5c\x43\x56\x60\x3a\x4a\x7a\xb7\xfb\x63\x06\xaa\x82\x3a\
+\xb0\x02\x07\x93\xfb\xa9\x00\x0e\xae\x11\x1b\x50\x80\x6e\xb0\xfb\
+\x1a\x17\x57\xf9\xa5\x79\x6d\xb6\x5d\xe8\x02\x2c\x57\xef\x69\xcc\
+\x06\x64\x02\x3b\xd4\x7b\xc2\xd9\x80\x22\x1e\x2e\x43\xc0\x79\x0b\
+\x32\x0d\x01\x9b\x81\x56\x25\x46\x80\xb1\x48\xc0\x04\x03\x80\x98\
+\xc0\x1f\xea\xc0\x17\xe8\x07\xf6\x21\x8d\x64\xa3\x97\xa8\x1b\x58\
+\x80\xb5\x84\x4c\xc4\x7c\xbd\x40\x45\xb2\x50\x4a\xc8\x85\x4e\xd8\
+\xa8\x13\xd8\x89\x91\xf2\x61\x0f\x1f\xe3\xd2\x07\x8c\x50\x1e\xc3\
+\x19\xb0\xce\x1b\xdd\xd7\x6a\x1b\x73\x58\x1b\x50\x6c\x8e\xbb\x4c\
+\x48\xd9\xd6\x71\xf1\x50\x12\xeb\xd6\x04\x2c\xc1\x24\xf7\x9a\x61\
+\x02\xc0\xdb\x7a\x02\xf6\x53\x85\x49\x7e\xcf\x35\x03\x20\x76\x44\
+\xa2\xf4\x49\x4b\x9a\xbc\xe9\x1c\x11\x17\xf1\x48\x6c\x0b\x9b\x96\
+\x25\x5c\x5a\x28\xcd\x39\x7e\xda\x01\xa5\x99\xd3\xdf\x8c\xd4\x62\
+\x0d\x40\xb6\x15\x18\xb4\xe5\x8a\xdf\x99\xd2\x22\x0d\xbb\x70\x6c\
+\x88\x74\xf9\x94\x8a\x10\xbf\x99\xd0\xc0\x3a\x01\x3d\x5a\x63\x37\
+\xd1\x0b\xe4\x98\xcd\xcb\x32\x30\x9c\xe8\x06\x52\xb0\xd2\x65\x31\
+\x17\xea\x06\xca\xf9\x98\xe3\xdd\x55\xdf\x20\xd6\x19\xa4\xc1\x82\
+\xc1\xe5\x06\x00\x77\x6a\x4b\x7b\x19\x31\x00\x10\x72\x95\x10\x63\
+\x00\xf9\x0f\xe8\x00\x22\xb2\x34\x26\x22\x00\x88\x82\xc6\x44\xfd\
+\xd3\x80\xd7\xeb\xfd\xf0\x78\xa9\x54\xe4\x4b\xd5\x9b\x7b\x7b\x05\
+\x28\xb5\x94\x47\x2c\x00\xf5\x3a\xcf\x54\xd2\xfd\x80\x93\xde\x3f\
+\x72\xfb\x35\xad\x1a\x08\xb9\x7e\xe8\x94\xb2\x9a\x09\x78\x07\x08\
+\xcf\xbf\xb5\x97\x06\xe5\x4a\xcd\xed\xd5\xaf\x04\x19\xc8\x67\x5e\
+\x82\x0c\xe0\x2c\x9d\xad\x00\xb8\x41\xf3\x74\x00\xb7\xe8\x00\x1f\
+\x30\x87\xde\xd1\x0e\x4c\xfd\x52\xd9\xc2\x07\x0c\xa5\xcf\x64\xe0\
+\xf3\x47\x29\x53\x98\x00\xfa\xb5\x9a\xbe\xec\x03\x1f\x30\x8b\x3e\
+\x90\xeb\xbb\x1b\xa4\x74\x65\x02\x3e\xe5\xae\x1f\xcf\xe3\x17\xb0\
+\x8d\x5e\xd7\x71\x0f\xf0\x1b\x78\x41\xd3\x8d\x00\x6d\x6e\xd2\xa7\
+\xd0\x0d\xbc\xaf\x7a\xfb\x9d\x3e\xe9\xac\x11\xf0\x1c\x55\x8a\xb9\
+\x1e\x8f\xe7\xda\xc9\x74\xa5\x9e\xf9\x97\x5f\xa6\x48\xad\x40\x64\
+\x00\x10\x16\xad\x6d\x7c\x74\x98\x32\xf0\x07\x89\xe6\xc6\xfb\xfa\
+\x59\x2e\xf7\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
+\x00\x00\x0a\x1d\
+\x89\
+\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
+\x00\x00\x40\x00\x00\x00\x40\x08\x06\x00\x00\x00\xaa\x69\x71\xde\
+\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\
+\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x01\xcf\x00\x00\x01\xcf\
+\x01\xe1\x0c\x10\xc7\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\
+\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\
+\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x09\x9a\x49\x44\
+\x41\x54\x78\xda\xe5\x5b\x67\x74\x55\x45\x10\x4e\x21\x24\x60\x30\
+\x05\xc1\x97\x08\x4a\x91\xae\x82\x52\x84\x08\x01\x84\x00\xa1\x04\
+\xb0\x20\x45\x82\x84\xde\x44\x25\x21\x80\x34\x43\x08\x81\x10\x3a\
+\x01\x12\x9a\x98\x08\x88\x1e\x3b\x16\x50\xb1\xa1\x72\x3c\x62\xd7\
+\x63\xc3\xa3\x58\x10\xd1\xa3\x62\x43\x65\x9d\xb9\xcc\xbe\x33\xd9\
+\xec\x7d\xf7\xde\xf7\x6e\xc8\x43\xef\x39\xdf\x8f\xbc\xbb\x3b\x3b\
+\xf3\xdd\xdd\xd9\x99\xd9\x4d\x88\x10\x22\xe4\x5c\x00\x3c\xcd\x01\
+\x2b\x01\x4f\x12\xca\x00\x29\x80\xd0\x80\xe4\x9e\x23\xc6\xb7\x07\
+\x08\x13\xcc\xfd\x3f\x10\xb0\x15\x8d\x8d\xaf\x5d\x5b\x74\x4a\xba\
+\xc6\xc0\x25\x97\x34\x90\x04\x7c\x09\x08\xff\xaf\x13\xf0\x26\x1a\
+\x9b\x36\x70\x90\xd8\xb9\xfb\x7e\x03\x33\x32\x67\xf2\x59\xe0\x39\
+\x67\x09\x80\x27\x1a\x30\x05\xf0\x12\x60\x21\x20\x91\xbd\x8b\x04\
+\xa4\x03\x4e\x58\x10\x90\x0b\xb8\x50\xe9\x37\x1a\xf0\x3c\x60\x19\
+\xa0\x61\x50\x12\x00\x4f\x6d\xc0\x61\x65\x4d\x1f\x03\xf4\x04\xe4\
+\x01\xbe\xe3\xef\x46\xa6\xdf\xe2\x25\x60\xd1\xe2\x25\xaa\x2f\xf8\
+\x93\x1c\x63\x37\xc0\x33\xca\xbb\x5f\x00\x9d\x83\x8a\x00\x78\x6a\
+\x01\xde\x92\x4a\x26\xc1\xba\x0e\x0f\x0f\xaf\xe0\xe4\x42\x43\x43\
+\x45\x93\xa6\x4d\x0d\xe3\x77\x94\xee\xf4\x12\x80\x98\x76\xeb\x6d\
+\xe2\x8a\xd6\x6d\x44\x44\x44\x84\xd6\x41\x76\xb8\xba\xa3\x88\x8a\
+\x8a\xe2\x24\xb4\x0f\x26\x02\xa6\x49\x45\xd3\x47\x9d\xf9\xb2\x77\
+\xcc\xc8\xf2\x92\x80\x46\x0d\x48\x1b\x24\x36\x16\x6f\x2e\x67\xb4\
+\x0e\xdb\xee\x2e\x15\xa3\x33\xc6\x8a\xd8\xd8\x58\xaf\xf1\xfd\xfa\
+\xa7\x19\xef\x16\xde\x95\xcb\x49\x78\x3c\x98\x08\xc0\x35\x2f\xba\
+\x76\xeb\x5e\xce\x98\x9c\x45\x79\x62\xe8\xb0\x11\x62\xfd\x86\x62\
+\x4b\xc3\x55\x6c\xdf\x51\x26\x32\xc6\x8c\x13\x13\x26\x4e\x2e\xf7\
+\xfb\xb8\xf1\x13\x25\x01\xff\x00\x62\x82\x85\x00\x74\x78\xa2\x7a\
+\xf5\xea\x62\xce\xdc\xf9\x8e\x8d\xb5\x8b\xf5\x45\x9b\x84\xc7\xe3\
+\x91\x04\xbc\x1a\x4c\x33\x20\x91\x1c\x9e\x31\xdd\x73\xf3\xf2\x5d\
+\x37\x1e\x67\x04\x33\xfe\x34\x60\x60\xb0\xed\x02\x3d\xe5\x9a\x1d\
+\x3a\x6c\xb8\xf5\xd7\x84\x65\x31\x23\x2b\x5b\x4c\x99\x36\x5d\x2c\
+\x5f\xb1\x4a\xdc\xbb\x6b\x8f\xcf\xf6\xb9\x8b\xf3\xb9\x53\x5c\x1b\
+\x8c\xdb\x60\x9e\x9c\x01\xeb\x8a\x36\x9a\x1a\x32\x61\xd2\x14\x11\
+\x1b\x17\x57\xc1\xcb\xa3\x73\xeb\x93\xda\xd7\xf8\xd2\xba\x7e\x48\
+\x50\x83\x06\x0d\x65\xfb\x77\x83\x6d\x1b\x8c\x94\xfb\x3c\x0f\x70\
+\x38\x8a\x37\x6f\x13\x57\x5d\xd5\x56\xb7\xc5\xfd\xc5\xff\xf6\x24\
+\x24\x98\x2e\xa1\xec\xd9\x77\xf2\x7e\xc9\xae\x13\x80\x5e\x15\xd0\
+\x16\x10\xe7\xb0\x1f\x46\x78\x22\x2c\x2c\xcc\x30\x54\xa7\xbc\x62\
+\xfc\x3e\x40\x0f\x40\x2c\x20\x0a\xd0\x01\xa7\x35\xad\x6d\x11\x13\
+\x13\x2b\x4a\x4c\xe4\xd4\xaf\x7f\xb1\x94\xb1\xd3\x35\x02\xe0\xb9\
+\x16\xf0\x00\xe0\x6f\xb6\xc5\x2c\xf7\x95\x9e\xc2\xd3\x1a\xb0\x99\
+\x62\x7b\x23\xbc\x6d\xd6\xac\xb9\xe9\xb4\x67\xc6\xcf\xf6\x21\xb3\
+\x1b\x45\x81\xa2\x63\xa7\x24\xad\xac\x81\x83\xae\xe3\x33\x07\xc7\
+\xde\x0b\x48\x03\x84\xf9\x9b\x97\xbf\xef\x23\x3d\x9d\x6c\xd2\xaf\
+\x89\xfc\x5a\x1c\x37\x8f\x4c\xd7\x2a\x1d\x17\x17\x2f\xdb\x3c\x65\
+\x43\xa7\x39\x52\xde\xb2\x82\x15\x15\x64\x2d\x5e\xb2\xd4\x4c\xd7\
+\xa9\xfe\x18\xff\x0d\x13\xf0\x39\x60\x16\xa0\x15\xe0\x39\x5f\xe9\
+\x29\xcd\x0e\xc3\xb0\x1e\x3d\x53\x0c\xdc\x70\xe3\x4d\x15\xc2\x5b\
+\xe9\xed\xd9\x18\x5d\x6c\xe8\x15\x01\xf8\x1d\xdb\x8f\x9f\x30\x49\
+\x3f\xa3\x20\x38\x92\xe3\x36\x6a\xd4\xd8\xeb\x18\x9d\x12\xb0\x8d\
+\x3a\x1e\x05\x0c\xc0\x29\xc4\xde\x25\x33\xa5\x07\x6b\xfa\x62\x15\
+\x47\x24\x77\xed\x66\xb9\xdd\x65\xc2\x56\xc7\x96\x55\xb4\x4d\xdd\
+\x5e\xc3\x3e\x29\xbd\x7a\x5b\xca\x9f\xc8\x97\x97\x43\x02\xb6\x53\
+\xc7\x22\x93\xf7\xef\xd0\xfb\xbd\x81\x10\x30\x65\xea\xad\x52\xc1\
+\xdf\xed\x16\x3b\xe0\x79\x1a\xfb\x74\xee\xdc\xa5\x52\x09\x28\xa2\
+\x8e\x5f\x01\xaa\x69\xde\xdf\x2c\x3d\xb6\xe6\xdd\x4e\xe9\xf4\xe6\
+\x2d\xb8\xcb\x40\xe1\xca\x35\x5a\x05\x0b\x0a\x57\xf1\x25\x70\x99\
+\x4d\xdd\xbe\x3f\xe3\x53\x46\x69\x65\x6e\xd8\xb4\xd9\x3b\x6e\xaf\
+\xde\x7d\xa4\xec\x13\x4e\x09\xe8\xca\x14\xbb\xde\xa4\x4d\x1b\xcc\
+\xf3\x35\xbf\xf7\xd2\x39\xa2\x99\xd9\xb3\xb5\x01\x4c\x64\x64\xa4\
+\x6c\x93\x6f\x43\xaf\x3e\x52\xde\xfc\x85\x39\x15\xe4\x6d\x2a\xd9\
+\x2a\x6a\xd4\xa8\xa1\x73\x82\x85\x4e\x09\x08\x63\x45\x8a\xbd\x0e\
+\xfb\x86\x02\xe6\x2b\x4e\x54\x5c\xdd\xb1\x93\xf6\x8b\x61\x84\x47\
+\x6d\x70\x9b\x4d\xf2\x21\x37\x9e\x1c\xaf\xb1\xdf\xdf\x53\xb6\xab\
+\x82\xac\x31\x63\xc7\xab\x86\x9f\x04\x94\x00\x12\x9c\x1a\xbf\x95\
+\x09\x79\xc4\xcf\xf8\x01\x3d\x76\x03\xc0\x52\x94\x83\x5f\x46\xa7\
+\xb4\x91\xc8\x40\x84\x47\x63\xfd\x06\x98\xce\x9d\x2e\xc9\xc2\xb2\
+\xf8\x17\xd8\x06\xeb\x08\x4b\x96\x16\x68\xc9\x6c\xd3\xe6\x4a\x29\
+\xe7\x20\xd6\x0f\x01\x35\x1d\x05\x42\x1a\xe3\x9f\x50\xf3\x6a\x3f\
+\x88\x48\x00\x9c\x42\x79\xe8\xf4\xb4\xc9\x0c\x84\xb7\x18\xe1\xb1\
+\x71\x7f\x02\x1c\x00\x3c\x06\xf8\x5a\xfe\x8e\xc6\x63\x41\x44\x27\
+\x63\xf5\xda\x22\x5e\x69\x1a\xe1\x38\x12\xd4\x18\xbf\x32\x90\x32\
+\xb4\x22\x7b\x17\xca\xac\x53\xa7\xae\x76\x16\x20\x30\xbc\xc5\x08\
+\xcf\x2c\xf0\xc2\x69\x6f\xf6\xe5\x11\xb8\x2b\x50\xdb\xe3\x98\x7f\
+\x98\x12\x40\x41\xce\x87\x80\x6f\x89\xdd\xed\x74\x20\xc1\x8d\xcf\
+\x72\x39\x21\xea\x2e\x65\xab\x55\x1c\x15\x4b\x0b\x0a\x8d\x20\xa7\
+\x67\x4a\x2f\xd1\xb9\x4b\xb2\x51\x23\x44\x87\x67\x46\x1c\x62\xed\
+\xba\x0d\x46\x4d\x51\x7e\x38\xd3\x6c\x10\x9e\x66\xaa\x73\xd2\x60\
+\x5b\x25\x64\x83\xfb\xa4\xfc\x49\x93\xa7\xba\x5e\x10\xc1\x14\xbb\
+\x5a\xb5\x6a\xbc\xda\xdc\xd4\x8c\x80\x87\xa9\x11\x7e\xfd\xc1\x80\
+\x45\x0a\x21\x07\x75\xd3\xc7\x86\x91\xe7\x99\xd5\xe4\xe1\xb9\x45\
+\xca\x4f\xed\xdb\xbf\xd2\x4a\x62\x78\x7e\xc0\x7c\xc0\x6e\x8d\x1e\
+\x21\xf5\x59\x46\x97\xad\x78\xeb\x1b\xf0\xec\x0d\x53\x50\x9b\x06\
+\x87\x03\x32\x68\xf9\xbc\x4b\xa1\x2c\xbe\x18\xa3\x69\x8b\xce\x4c\
+\xb4\x6b\xdf\xa1\x9c\xc2\xa5\xf7\xee\x16\x85\x2b\x56\xfb\x6d\x70\
+\xd1\xc6\x62\xb1\xa9\x78\x4b\xb9\xdf\xd2\x47\x8d\x96\x04\xa0\xd3\
+\x3d\x5f\x25\x20\x87\x5e\xfe\x01\xb8\x20\x80\x29\x8d\xcb\xe8\x15\
+\xcd\xd2\x41\x12\x86\x68\xda\xaf\xc0\xf7\xb5\x6a\xd5\x12\xf9\xcb\
+\x96\x7b\x95\x4f\x48\x48\x34\xfa\xb5\x68\xd1\x52\xe4\xe4\xe6\xd9\
+\x36\x1c\xd7\x3b\x86\xd9\xb8\xe6\x31\x88\x92\x85\xd6\x92\x2d\xdb\
+\x79\x55\xe8\x6d\xdd\x0c\x90\x59\xdc\x8e\x00\x8c\xbf\x9d\xf6\x6a\
+\x39\xd0\x2b\x94\xfd\x0d\xc5\x19\x66\xd2\xe7\x52\xc0\xaf\xd8\x3e\
+\x3a\x3a\xda\x38\x13\x48\x4c\x4c\xac\xe0\x7b\x90\x08\x4c\x99\x57\
+\xad\x59\xa7\xdd\x21\xd0\x79\xb6\x6d\xd7\xbe\xc2\xe1\x08\xfe\x8d\
+\x7e\x85\x19\x8f\x18\xa9\x23\xe0\x00\xbd\x5c\xe8\xa7\xf1\xa3\xd9\
+\x00\x3f\x00\x86\x3b\x0c\xad\x4f\x2a\x46\x9f\xa6\x28\xed\x63\xf5\
+\x84\xe8\x76\x20\x89\xa7\xcc\x9a\xf0\xf6\x38\x6d\xd3\xc7\x34\x33\
+\x71\x96\x89\x0e\x67\x92\x14\xaa\x96\x94\xfa\x0a\x3b\x4d\x4a\xdb\
+\x3f\x52\xff\xd7\xf8\xc1\xa6\x03\x19\x1d\x68\x37\x38\x4d\xd5\x9a\
+\x21\x2c\x74\xc6\xfc\xe1\x41\xe9\xa3\xb8\xb3\x9c\x3d\x67\xae\x50\
+\x9c\xf4\x08\xe9\xa8\xd1\xdb\x03\xee\xa7\x7e\x58\xbc\x49\xf7\x31\
+\xbe\x71\x46\x77\x50\x61\xeb\x0d\x8c\x0b\x6c\x28\xff\x28\x8b\xad\
+\x1b\x07\xb8\x2d\xd6\xb1\x3a\x1e\x4f\xed\xdb\xcf\x4b\xc0\xac\xf2\
+\xc5\x4e\x8f\x49\xbf\x0b\x6c\x1d\x8f\xa3\x67\x04\x14\xd0\x14\xf2\
+\x66\x4a\x16\x0a\x77\x61\x6d\xa7\x55\x72\x05\xf9\x29\x1c\xa7\x65\
+\xcb\x56\xc6\xb6\x86\xe8\xdb\xaf\x3f\xcf\x13\x6a\xba\x72\x3f\x80\
+\x82\x93\xef\x49\xf0\x22\x0b\xa5\xee\x60\x01\x46\x68\x25\x13\x30\
+\xc4\x47\x80\xb6\xd5\xd5\x2b\x32\x14\x0c\x99\x16\x37\x59\xbb\x1d\
+\x32\x31\x3a\x0b\x67\x08\x18\x93\x64\x03\x3e\x53\x12\xa3\xf5\x80\
+\x7a\x95\x45\xc0\x60\x0b\xa5\xde\xa6\x76\x79\x01\x1a\xd7\x9a\xc6\
+\x5c\x6e\xb3\xa6\x10\x45\x70\x27\x21\xf3\x41\x40\x1f\x0b\x65\x64\
+\xbb\xe9\x01\x12\x90\x4f\x72\xde\xab\x92\x13\x2a\x1f\x86\x8d\xb2\
+\x50\xfc\x49\x37\x92\x24\x59\xcc\xd4\x9d\xda\x54\x35\x01\xb3\x2c\
+\x14\xcf\x35\x0b\x2f\x1d\x12\x70\x5c\xcd\x43\x7c\xb4\xad\xeb\xd6\
+\xd4\xd7\xd5\x03\x6a\x93\x67\xff\xc3\x57\xfe\xcc\xda\x0f\x62\x35\
+\xbb\x46\x7e\x1a\xcf\xb7\xd2\xde\x36\x23\x4e\x2c\x81\xdd\xc9\x6f\
+\x85\x05\xf8\x01\x8c\x8a\xcf\x3c\x66\xb8\x30\xcb\xe0\x94\x8e\x71\
+\xec\xeb\xbd\xa8\xd6\xeb\x6c\xd6\x03\x3e\x60\x27\x4c\xe7\x59\xb4\
+\x1f\xae\xe8\x77\x4a\x57\xe2\xf2\x87\x80\x2c\x45\xe8\x7d\xba\x63\
+\x64\x93\xce\x37\xfa\x5b\x2d\x82\x67\x31\xeb\x9b\x62\xb3\x4f\x32\
+\xe9\x77\x8a\xcd\xbe\xe1\x81\x12\xf0\x29\x09\xdb\x8f\x85\x4a\x7f\
+\xeb\x7a\x94\xf6\x62\x8a\x5b\xc3\xc6\x71\xfa\x16\x66\x7c\x89\x9f\
+\x05\x55\xe9\x3c\x0f\x04\x4a\xc0\x09\x12\xb4\x20\x80\xcb\x8e\x3c\
+\x73\xfb\x08\x70\x9d\x1a\x9f\xc3\x73\x31\x9d\x1c\x7d\xc9\xda\x1e\
+\x56\x0b\x14\x0e\xc6\x5d\xe0\x16\x01\xb2\x1c\xf6\x89\xbf\x21\x2d\
+\xc6\xe2\x94\x86\xfe\xa3\xac\x53\x2c\xae\xbe\xa0\xde\xf8\xa4\xcc\
+\x13\xcb\x6e\x11\x7e\x8e\x17\x4a\xfa\xe2\x1f\x7b\x02\x25\xa0\x3f\
+\x53\x2c\x55\x53\xe2\x8a\x71\x20\x2c\x89\xdf\xfe\xd4\x00\x53\xde\
+\xd7\x01\xed\x1c\xde\x40\x09\x57\x7e\x4b\xb5\xbb\x7b\xd8\xdd\x05\
+\x3e\x27\x61\x4f\x13\xbb\x1e\xda\x19\x8e\x92\xa3\x19\xeb\x50\x68\
+\x3c\xdd\x00\xcb\xa6\x1b\x21\x59\x54\x02\x8f\x71\x28\x67\x2c\x8d\
+\x7f\x94\xf4\xf1\x90\x7e\x72\xfd\x7f\xec\xca\x3f\x4c\xc0\x93\xc9\
+\x18\x3d\xc2\xbc\x2c\x9f\xb2\x3d\xce\xf2\x25\xaa\x1e\xea\x65\x28\
+\xd2\xeb\x08\xbf\xe1\xe1\x4a\x20\x44\xd9\xd6\x01\xcd\x60\x7b\xd8\
+\xfa\xc5\x72\x57\x93\xb3\x64\x7c\x13\x1a\x4f\xd0\xf8\x0f\x68\xc8\
+\xd8\xef\x46\x54\xa8\x1e\x81\x0d\xa3\xfb\xf5\x13\x30\xec\xa4\xdf\
+\x2f\x67\x24\x1c\xb1\x7b\x5e\x1f\x80\xf1\x97\xb1\xaf\x7c\x4c\x8e\
+\x87\x69\x2f\xe0\x36\xc0\x1a\x3a\x53\xa8\x9c\x6c\xd0\x44\x29\x4e\
+\xc2\xcf\x78\x3d\xa6\x92\x8c\x1f\x40\xf2\xa5\xf1\xad\xce\x7a\x32\
+\x64\x93\x04\xdc\xee\x32\x5c\x36\x3e\x83\x6d\xa3\x98\x90\xb5\xac\
+\x92\x6c\xd0\x06\x09\x3f\x91\x92\x87\x5c\x26\xe0\x90\xf7\xda\x4a\
+\x48\x48\x8b\x2a\x4b\x87\x2d\x94\xf4\xb0\x1d\x22\xc7\x65\x02\x72\
+\x58\x91\x33\x3e\x58\x09\x98\xcf\x92\x90\x7a\x26\xa7\x3d\x87\xa8\
+\x8c\xfd\x38\xa0\x98\x2e\x44\x97\xd0\xed\x4c\x0c\x92\x5e\xd5\x95\
+\xd0\xc9\xc9\xc9\x33\xca\xcc\x60\x25\x40\x26\x3e\x0f\x99\xbc\x2f\
+\xb3\x38\x62\x97\x28\x33\xe9\xff\x10\xbd\x7f\x36\xd8\x09\x78\x54\
+\x8d\xc0\xa8\x5a\xf3\x27\xbd\x7f\x81\x4e\x88\x55\xbc\xcc\xfe\xc3\
+\xab\xae\xe6\x26\xca\x63\xf4\xfe\xf5\x60\x25\x60\x26\xfb\x8a\x98\
+\x8c\xcc\x90\xb7\xc4\x29\x54\x95\x01\x94\xd9\x49\x0d\x3f\x8a\x9f\
+\xc7\xc2\xe6\x4c\xa5\xe4\x9d\x13\x94\x04\x90\xc2\x4b\x94\xe9\xfc\
+\x1b\x45\x65\x32\x52\x2b\xb5\xe8\xbf\x87\x11\xb5\x4f\x39\x55\x16\
+\xe4\x3b\xa2\x82\x96\x00\x16\xb0\x3c\xa1\xb9\xfd\x7d\xcc\xea\x80\
+\x14\xcf\xeb\x94\xaf\x2d\xb3\x44\x94\x97\x56\xe5\x55\x61\x87\x44\
+\x34\xa4\x1b\x24\xf7\x91\xb7\xaf\x6b\xb3\xdf\x45\x54\x80\xdd\x45\
+\xfd\x1b\x56\xd5\x7f\xae\xfc\x0b\xa5\x19\xbe\x0f\xa6\xcc\xe6\x71\
+\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
+\x00\x00\x02\x25\
+\x89\
+\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
+\x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\
+\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\
+\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x07\xa3\x00\x00\x07\xa3\
+\x01\x30\x2f\xb2\xc5\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\
+\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\
+\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x01\xa2\x49\x44\
+\x41\x54\x58\x85\xed\x97\xcb\x4a\x42\x51\x14\x86\xff\xb5\xcf\x05\
+\x3d\x98\x19\xde\xb0\x8c\x1c\x34\x4b\xe8\x48\x2f\xe0\x24\xa1\x07\
+\xe9\x3d\xba\xbc\x43\x0f\x90\x45\x81\xa3\x1c\xd8\x6d\x10\x34\x96\
+\x70\x96\x44\x10\x41\x45\xa2\x54\x88\x60\xd0\xc9\xd5\xa0\x34\x3d\
+\x2a\x64\x1c\xf7\x69\xd0\x9a\xed\x1b\xdf\xc7\xde\x6b\x6f\xd6\x26\
+\x66\x86\x9b\x21\x5c\xa5\xff\x05\x01\xb5\x76\x1a\xc9\x03\x94\xf9\
+\xc9\x64\x02\x56\x83\xcb\x95\xac\x93\x02\x54\x3d\x89\x8c\x92\x04\
+\xf5\x77\x26\x33\x9a\x79\xbc\x71\x4a\x60\xd4\x23\xf0\xab\xc4\x3b\
+\xc8\x91\xe2\x94\xc0\xa8\x3b\xd0\x8e\x4d\xd6\x78\x6b\xd4\x45\x16\
+\x34\x2b\x96\xbe\xaf\x39\x21\xf0\xfb\x60\xac\x87\x32\x95\xb5\x76\
+\xd3\x8d\x5b\x60\x76\x37\x5c\xbf\x86\xae\x0b\xa8\xc3\x06\x08\xf4\
+\xc4\xc4\x4d\xc7\x89\x42\x6d\xbe\x94\x56\x12\x00\xd0\x68\x4e\x54\
+\x06\x27\x21\xe9\x45\x2d\x98\x4c\x32\x84\xc7\x71\x81\x6e\x0c\x50\
+\x1e\x78\x04\x8a\x7f\x56\x19\x37\x1c\x00\x18\x68\x0c\x12\x78\x20\
+\x6d\x6a\x71\xdc\xf0\xaf\xc8\xf6\x09\x90\x3e\x79\x05\x39\xc9\x69\
+\xa9\xe0\xbd\x3e\x90\xe2\x9d\x89\x4b\x80\x03\x8c\x63\x5f\xaa\x50\
+\xed\x15\x20\x71\x09\xcd\x98\x97\xc1\x27\x70\x16\xb0\x6d\x35\x79\
+\x42\x15\x19\x70\x00\xf5\xe7\x7a\xf3\xc0\x2e\x60\x29\xde\xd8\x82\
+\x24\x81\x5c\x22\x7d\xf6\xda\x23\x40\x8a\x7e\x01\xa1\x85\xe5\xf0\
+\xb9\x53\xd4\x74\x04\x84\x37\xfa\x26\x07\x8e\xdb\x40\xea\xf0\xdc\
+\x2e\x50\x27\x4f\x38\x25\x83\x4e\x4c\xbb\xc0\x77\x29\xfe\x29\xa0\
+\x1a\x25\x40\x18\x32\x04\x2c\x16\x3d\x35\xa5\x00\x00\xc5\x98\xf6\
+\xc9\x80\x03\x28\x06\x97\xf2\x65\xbb\xc0\x1d\xe9\x01\x73\xc8\x02\
+\x87\x83\xb6\xed\x3d\x82\xf4\x80\xc4\xa7\xb7\xb5\x6f\xef\x54\x15\
+\x23\x2e\xe7\xe9\x25\x1c\xf9\xcc\x42\xb5\x4f\x80\x54\xef\x35\x83\
+\xe7\xc6\x8c\xaf\x09\xb4\x36\x06\x7a\xfd\x7f\x4e\xdd\x16\xf8\x00\
+\x0c\x78\x6d\x84\xa1\xf9\xfb\x45\x00\x00\x00\x00\x49\x45\x4e\x44\
+\xae\x42\x60\x82\
+\x00\x00\x07\x58\
+\x89\
+\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
+\x00\x00\x40\x00\x00\x00\x40\x08\x06\x00\x00\x00\xaa\x69\x71\xde\
+\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\
+\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x01\xc2\x00\x00\x01\xc2\
+\x01\xe8\x3c\x7d\x54\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\
+\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\
+\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x06\xd5\x49\x44\
+\x41\x54\x78\xda\xdd\x9a\x6d\x4c\x5b\x55\x18\xc7\xd1\x45\xa3\x89\
+\x1a\xfd\xe2\x4b\x16\x3f\x98\xf8\xc9\x0f\x7e\x32\x7e\x35\x51\x3f\
+\x19\xa3\xc6\x41\x37\xe8\x6d\xa1\xed\x6d\x81\x96\x6c\x59\x32\xcd\
+\x4c\xd4\x6d\xea\xa2\xf3\x05\x37\x5f\xd8\xe2\x36\xb3\x45\xdc\xb2\
+\x0d\xb7\x39\x19\x41\x18\x63\xcb\x36\x06\x6c\xbc\x6d\xd0\xd2\xd2\
+\x96\xb7\x96\x42\xdf\x28\x50\xa0\x14\xda\xc7\xf3\x5c\x7a\xbb\xba\
+\xd1\xf6\xde\x4b\x29\xf7\xf6\x24\xff\xf4\xa6\xbd\x3d\xe7\xff\xfc\
+\xee\x39\xe7\xf6\x79\x7a\xf3\x00\x20\x2f\xdb\xb2\x94\x29\x3e\xee\
+\xa7\x29\x6f\x9f\xa6\x28\xda\xaf\xa5\xc2\xa3\x7a\xd5\x95\xf1\x0a\
+\xd5\x9b\xeb\xe1\x25\xfb\xc1\xeb\xa8\xab\xbd\x9a\x22\x40\xd9\x4a\
+\x95\x30\x66\x50\x27\x48\xf3\x49\x4e\x03\xb0\xea\x94\x9f\xb1\xc1\
+\x9b\x68\xf9\x7d\xc1\x2f\xcb\x61\xd0\xbc\x95\xb3\x00\xfa\x69\xb9\
+\x8f\x05\x30\x5c\x5e\xb2\x22\x80\x31\x83\xaa\x21\x27\x01\x0c\xe9\
+\xa8\x17\xd8\xe0\xc9\xda\x4f\x12\x3c\xa3\x45\x8f\x5a\xfd\x64\xce\
+\x01\xb0\x95\x2a\xf6\xb0\x00\xcc\x5a\x2a\x15\x00\x18\x37\xa8\xde\
+\xcd\x39\x00\x24\xe8\x2e\x16\x80\xbd\xac\x38\x25\x80\x31\xbd\x6a\
+\x7f\xce\x01\x30\xd2\x45\x21\x16\x00\xb9\xed\xa5\x06\x60\x50\xf5\
+\xe6\x14\x00\x3b\xad\x7c\x95\x0d\xde\x98\x64\xf7\xbf\x5f\x6e\x7d\
+\xc9\xf3\x39\x03\xc0\xa2\x53\x56\xb1\x00\x2c\x3a\x05\x27\x00\x63\
+\x7a\xb5\x3c\x67\x00\x78\x5a\x6f\xcc\x78\x4d\x7d\xe0\xbe\xd5\x0a\
+\xbe\xf3\x35\x30\x79\xec\x37\xf0\xfd\x52\x09\x9e\x6f\xf6\x30\xc2\
+\x63\x7c\x6f\xaa\xe6\x24\xcc\xd4\xd7\xc2\xec\xf5\x2b\x10\x6c\xaa\
+\x6f\xcb\x19\x00\x3e\x8f\x07\x3c\x31\x2d\x2d\x2d\x01\x97\x16\x09\
+\x4c\x2e\xe6\x04\x00\x5f\xed\x85\x1d\x6c\xf0\x7e\xbf\x1f\xf8\xb4\
+\x40\x7d\xed\xdb\x92\x07\xe0\xbd\xdd\x36\xc4\x02\x98\x99\x99\xe1\
+\x05\x60\xae\xe5\xda\x09\xc9\x03\xf0\x8f\x8c\x2c\xb1\x00\x42\xa1\
+\x10\x2f\x00\x21\xb3\xc9\x21\x6d\x00\xa7\x4f\x3f\xea\xf5\x7a\xe3\
+\xeb\x3f\x12\x89\xf0\x02\x10\x09\x06\xa3\xa4\x8f\x0d\x92\x05\x30\
+\xd1\x70\xf1\x20\x1b\xfc\xe4\xe4\x24\x08\x69\xc1\x86\x5a\x4a\xb2\
+\x00\xfc\x3d\x5d\x6e\x16\x40\x30\x18\x14\x04\x60\xfe\xd6\xcd\x3a\
+\xc9\x02\xf0\x39\x1d\x51\x16\xc0\xc2\xc2\x82\x20\x00\xe1\x41\xab\
+\x57\x92\x00\x46\x8f\x1f\xdf\x98\xb8\xfe\xa3\xd1\xa8\x20\x00\x51\
+\x02\xce\x57\x5d\xfd\x94\xe4\x00\x38\xaa\xf6\xff\xe8\x1d\xb4\x81\
+\xcf\xed\x86\x40\x40\xc0\xfa\x27\x1b\xe6\xa2\xd3\x01\x73\xed\x2d\
+\xe0\x3b\x58\x29\x93\x1c\x00\x8b\x96\xba\xc9\xfe\xfe\x1f\xdc\xaa\
+\x05\xcf\xbe\x3d\xe0\x3f\x52\x05\x81\x3f\x8f\xc1\xd4\xd9\x53\x30\
+\x53\xf7\x37\x04\x9b\x1b\x19\xe1\x31\xbe\x87\x9f\xe1\x39\x78\xae\
+\x6b\x9b\xee\x5e\x5e\x50\xa1\xfe\x5a\x72\x00\x4c\x34\x15\x64\x01\
+\x8c\x24\x2d\x7f\x71\xd6\x2d\x49\x01\xe8\xa7\xe9\x97\xe2\xe5\x2f\
+\x8e\xe9\x6f\x1a\x45\x86\xcb\xcb\x9f\x91\x0c\x00\x6b\xa9\xf2\x3b\
+\xde\xe9\x6f\x3a\x55\xa8\x37\x49\x06\x80\x59\xab\xe8\x8d\xaf\xff\
+\x74\xe5\x2f\xce\xd2\x54\x49\x06\x80\x91\x96\x87\xb9\x97\xbf\xd4\
+\x5c\x0b\x24\x16\x49\x00\x70\x5f\x3c\x57\xe2\x9b\x98\x00\x9f\xd5\
+\x02\x13\x97\x1b\xc0\xbb\x7f\x1f\x8c\xef\xa8\xe0\x1d\xf0\xf8\x47\
+\x15\xe0\x3d\xf0\x2d\x53\x24\x99\x6b\xbd\x01\x61\xc7\x08\x4c\xd5\
+\xff\xf3\xba\xe8\x01\x78\xda\x5b\xcd\xec\x8f\x9f\xe9\xe9\xe9\x7b\
+\x3f\x68\xe6\xe7\x60\x69\xd2\x0f\x8b\xae\x31\x08\x0f\xd9\x21\xd4\
+\x6f\x84\xf9\xee\x0e\x46\x78\x8c\xef\xe1\x67\x78\x0e\x9e\xbb\x52\
+\x9b\x6d\xb9\x7a\x44\xf4\x00\xfc\x43\xf6\x45\xa1\xe9\x6f\xba\x16\
+\x32\xf5\xd9\x45\x0f\x20\xb1\xfc\xc5\x37\xfd\x4d\xd7\x96\xa6\xa7\
+\x22\xa2\x06\xe0\xae\xaf\xdb\x2b\xb4\xfc\xc5\xb5\x4d\xd7\x5f\x7c\
+\x5f\xb4\x00\xbc\xdd\x1d\x4e\xa1\xe5\x2f\xae\x6d\xb6\xed\xfa\x59\
+\xd1\x02\xf0\x3b\x46\x23\xab\x4d\x7f\xd3\xb5\xb0\xd5\x32\x2e\x4a\
+\x00\x93\xcd\xe7\x9e\xce\x44\xfa\x9b\xae\x45\x43\xf3\x51\x68\x6e\
+\x7e\x4c\x74\x00\x3c\x97\x1b\xab\x57\x5b\xfe\xe2\xda\x66\x2e\x35\
+\x94\x8a\x0e\x80\xaf\xf7\x8e\x9f\x05\x30\x3b\x3b\xbb\xa6\x00\xe6\
+\x6f\xb7\x35\x89\x0e\x80\xdf\xe5\x8a\x97\xbf\xc2\xe1\xf0\x9a\x02\
+\x08\x0f\x0f\x05\x44\x05\xc0\x4e\xd3\xcf\x79\x4c\x46\xf0\x92\xe0\
+\x71\x1f\x58\xab\xf5\x8f\x6d\xd1\x3d\x01\xc1\xa6\x7f\x23\x6e\xbd\
+\xfe\x09\xd1\x00\x18\xd0\x51\xbb\x98\xdc\x9f\x64\x7e\x23\x87\x7e\
+\x82\xa9\x33\x27\x20\x64\xec\x85\x68\x06\x66\x42\x74\x21\x04\xa1\
+\xbb\xdd\x10\x38\x55\x0d\x13\xbb\x76\xc6\x73\x05\x97\xa1\xe4\x1d\
+\xd1\x00\xb0\xe8\xa8\x8e\xf8\xd3\x1f\x09\x8f\xbe\xb9\xb6\x97\x81\
+\xfb\xab\x4f\x99\x84\xc8\x7f\xf8\x57\x08\x9c\x3c\x0e\xd3\x17\xfe\
+\xc2\x2b\x08\x73\x6d\x2d\x10\xea\xbb\x03\xa1\xde\x1e\x26\xd9\x09\
+\x5e\xaa\x87\xe9\xf3\x67\x20\x50\xfd\x3b\xf8\x0f\x1d\x00\xef\xf7\
+\x7b\xc1\xbd\x7b\x27\xb8\xb6\xea\x92\xd4\x07\x34\x95\xa2\x01\x60\
+\xa2\xe5\xf3\x19\x4f\x7f\xd3\xc8\x65\x50\xf7\x88\x02\xc0\x70\xa9\
+\xfc\x15\xbe\x4f\x7f\x64\x48\xd1\xf1\x32\xc5\xb3\xeb\x0e\x60\x40\
+\xa7\xfc\x39\xe3\xe5\x2f\x8e\x72\xea\x55\x85\xeb\x07\x20\x2f\xef\
+\x21\xab\x86\x7a\xd9\xac\xa5\x9c\x99\x2f\x7f\x71\x93\xc3\xa0\x6a\
+\x42\x0f\xe8\x25\x6b\x00\x06\xb5\x85\x6f\xd8\xb5\x45\x35\x76\xad\
+\x7c\x8a\x88\x99\xf6\x2c\x00\x47\x96\xd6\x7f\xc2\x0c\x00\xf4\xb0\
+\xec\xa5\xa8\x06\xbd\xad\x09\x80\xd1\xed\x05\x8f\xdb\xe9\x22\x8d\
+\x5d\x4b\xf5\xc4\x06\x64\x64\xd3\x51\x90\xee\xd9\xdf\xb5\xd6\x20\
+\xf1\x90\xe8\x89\xf1\x48\xbc\xa2\xe7\xd5\x03\x28\x28\xd8\x40\x3a\
+\xfb\xc2\x4e\xcb\xbd\xff\x1f\x64\x59\x56\xed\x3d\x00\x03\x59\x5e\
+\xff\xac\x86\xc9\x6d\x77\x25\x6f\x8c\x67\xe2\x1d\x63\x10\x04\xe0\
+\xb6\x4e\xf7\x48\x6c\xaa\x43\x32\x0d\x24\xcc\x80\x07\x1f\x7d\xcf\
+\x8e\x46\xca\x94\x90\xca\x23\xc6\x80\xb1\xf0\x06\x40\xbe\xac\x4d\
+\xdd\x31\x11\x01\x60\x8a\xed\x01\xb8\x17\x8c\xae\xc3\x1e\xf0\xe0\
+\x12\x58\x51\x5a\xde\x00\x06\xe8\xa2\x36\x0e\x1d\xc7\x67\x02\x02\
+\xe8\x8b\xcd\x04\xe7\x1a\x83\xc0\xfe\xf1\xca\x0f\x72\xf5\x47\x62\
+\xe1\x0d\xc0\xa8\xde\x62\xe6\x0a\x20\x71\x4f\xe8\x8f\xdd\x19\xac\
+\x04\x04\xfe\x29\xea\xcc\xe4\x6d\x4f\x5f\x92\x7c\xcd\xa7\x10\xc6\
+\xc2\x1b\x40\x67\xb1\xec\xaa\x59\x53\xc8\x7b\xb0\xf8\x1d\x82\xc0\
+\x40\x20\x24\x4f\x60\x36\x48\xcc\x11\x86\x08\x10\x84\x82\x4b\x25\
+\xd9\x2c\x71\xc6\xae\x30\xde\x52\x47\xcb\x8b\x99\x80\x39\x4e\xf3\
+\x15\x85\x31\x60\x2c\xfc\x01\x28\x0b\xae\x10\x21\x3d\xb0\xd1\x72\
+\xc1\x06\x52\xed\x1f\xac\x56\x13\x60\xd2\x0b\x40\x33\x57\x1e\x30\
+\x06\x8c\x45\x30\x00\x54\x17\x51\xaf\x6a\x33\xae\xa5\xcc\x83\xc8\
+\xb0\xd0\x23\x7a\xed\x8a\x79\xcf\x08\x80\x44\xdd\x29\x91\x31\xd3\
+\xca\x26\xa2\xa0\x6d\xb1\xa9\x8e\xde\x56\xf2\x2c\x14\xc0\xf9\x24\
+\x9d\xc5\xd5\x5d\x2c\x83\xbb\x25\x9b\x99\xa9\x66\x41\x28\x74\x16\
+\x82\x25\x63\xe0\x58\x38\x26\x8e\x8d\x1e\xd2\xf9\xc4\x58\x04\x6c\
+\x82\xf9\x4a\x0e\x1d\x27\x85\xd2\xa7\xda\x02\x46\x22\x13\x31\xda\
+\xaf\x2e\x64\xae\x10\x1a\xc7\x29\x6a\x25\xb2\x25\x2c\x27\x5b\xec\
+\x3d\xfc\x0c\xcf\xc1\x73\xf1\x3b\xf8\x5d\xec\x03\xfb\xe2\x11\xec\
+\x83\x22\xb1\xf0\xff\x29\xbc\x7b\xf7\xc3\x9d\x4a\xd9\x61\x41\x03\
+\x8a\x4a\xb2\xc3\x18\x8b\xe0\x64\xa8\x43\x21\x33\x90\x8e\xec\x12\
+\x0c\xde\x8e\xde\x33\x93\x0e\x13\x82\x1d\x8a\xfc\x0f\xc9\xce\x7a\
+\x4d\xec\x81\xa3\x47\xf4\x9a\xea\xaa\xaf\xaa\x1e\xd0\xa9\xd8\xf4\
+\x5a\x97\x32\xff\x0f\x32\x98\x5b\x44\x81\xbb\x19\x4f\xc4\x5b\x56\
+\x4b\x62\xed\xaa\x2d\x2f\x76\x51\xb2\x0f\x3a\x15\xb2\x2f\x89\x89\
+\xba\xce\xe2\x82\xf1\x35\x0f\x76\x79\x8c\x3a\x1c\x13\xc7\x46\x0f\
+\xa2\xf8\x67\x88\x55\xb7\xb2\x60\x23\x31\xf9\x1e\x99\x8a\xdb\x3a\
+\x15\x05\x9f\x13\xb3\x3f\x74\x2a\xf3\x8f\x92\xe3\x1a\x72\xdc\x48\
+\x5e\xdb\xc9\xab\x99\x68\x82\x28\x14\x13\x1e\x5b\x62\x9f\x35\x2e\
+\x9f\x9b\x7f\xb4\x4b\x91\x5f\x89\x7d\x30\x7d\x91\x3e\xb1\xef\x4c\
+\xfb\xfd\x0f\x35\xe2\x68\x79\x76\x41\x87\xfb\x00\x00\x00\x00\x49\
+\x45\x4e\x44\xae\x42\x60\x82\
+\x00\x00\x02\xf0\
+\x89\
+\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
+\x00\x00\x40\x00\x00\x00\x40\x08\x03\x00\x00\x00\x9d\xb7\x81\xec\
+\x00\x00\x00\x03\x73\x42\x49\x54\x08\x08\x08\xdb\xe1\x4f\xe0\x00\
+\x00\x00\x09\x70\x48\x59\x73\x00\x00\x12\xd9\x00\x00\x12\xd9\x01\
+\x60\x4d\xdf\xec\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\
+\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\
+\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x01\x0e\x50\x4c\x54\
+\x45\xff\xff\xff\x40\x4d\x66\x3d\x49\x61\x46\x46\x5d\x43\x4e\x64\
+\x40\x4a\x60\x43\x49\x60\x42\x4a\x5f\x42\x4b\x60\x42\x4a\x60\x42\
+\x4a\x61\x42\x4a\x60\x42\x4a\x60\x46\x4e\x63\x4e\x56\x69\x4f\x57\
+\x6a\x4f\x57\x6b\x54\x5c\x6e\x59\x61\x72\x5a\x61\x73\x5b\x62\x73\
+\x65\x6c\x7b\x6b\x72\x80\x70\x76\x84\x74\x7a\x87\x86\x8c\x95\x88\
+\x8e\x97\x8a\x91\x9e\x8e\x86\x68\xa6\xaa\xad\xa9\xad\xb0\xaa\xae\
+\xb1\xab\x9f\x70\xb0\xb4\xb5\xb2\xb7\xb9\xb5\xa3\x62\xb9\xa6\x61\
+\xc3\xc6\xc4\xc3\xc9\xcf\xc7\xca\xc7\xce\xb4\x56\xce\xd1\xcf\xce\
+\xd2\xcf\xce\xd2\xd0\xda\xde\xe0\xda\xdf\xe0\xdb\xc0\x5e\xde\xe3\
+\xe2\xde\xe3\xe3\xe2\xbd\x3e\xe7\xec\xed\xea\xc5\x44\xeb\xba\x16\
+\xeb\xbb\x1b\xec\xbd\x20\xec\xbd\x21\xec\xbe\x22\xec\xbe\x24\xec\
+\xbe\x25\xed\xc0\x2a\xed\xc0\x2b\xed\xc2\x32\xef\xc6\x3f\xef\xc7\
+\x42\xef\xc9\x48\xef\xc9\x49\xf0\xca\x4d\xf0\xcb\x4f\xf1\xcd\x58\
+\xf1\xce\x5a\xf4\xd8\x7b\xf4\xda\x82\xf5\xdc\x8a\xf5\xdd\x8b\xf5\
+\xdd\x8d\xf6\xdf\x92\xf6\xe0\x97\xf7\xe4\xa5\xf8\xe5\xa8\xf8\xe6\
+\xaa\xf8\xe7\xaf\xf8\xe7\xb0\xfa\xef\xc8\xfc\xf4\xd9\xfd\xf7\xe3\
+\xfd\xf9\xea\xfe\xfb\xf2\xfe\xfc\xf4\xff\xfe\xfd\xff\xff\xff\xca\
+\xb1\x9f\xb6\x00\x00\x00\x0c\x74\x52\x4e\x53\x00\x14\x15\x16\x17\
+\x18\x50\xd3\xd4\xd5\xd6\xd7\xf2\xd6\xc5\xa6\x00\x00\x01\x3c\x49\
+\x44\x41\x54\x58\xc3\xed\xd3\xc7\x52\xc3\x30\x14\x85\xe1\x90\x40\
+\x12\xe0\x62\x9a\xe9\xbd\x04\xd3\x23\x84\xe9\x35\xf4\xde\x9b\xdf\
+\xff\x45\x58\x58\x8e\x6e\x12\xab\x58\x5e\x50\x46\xff\xd6\x33\xdf\
+\x1c\x8d\xa5\x4c\x1e\x78\xdd\x34\xaa\xec\x89\x1a\x00\x80\xf6\x96\
+\x0c\x2f\x1e\xa0\x0b\x32\x00\xda\x9a\x95\x40\x59\x0a\x60\x41\x00\
+\x08\x27\x84\x00\x12\x44\x00\x9e\xd0\xe3\x84\x8d\x73\x00\x5a\x73\
+\x0a\x80\x2e\x72\xc0\x61\xdf\xc7\x10\x50\x15\x84\x00\xc1\x40\x87\
+\xeb\x76\xd6\x01\x50\xcc\xc9\x01\x34\xc1\x01\xd7\xf3\x86\xeb\x01\
+\x26\x88\x01\xa2\x02\xa0\x98\x95\x02\x7c\x82\x08\x80\x42\x56\x0a\
+\x10\x25\x00\x85\x26\x19\x40\x97\x94\x00\xe4\xa5\x00\x49\x0b\x44\
+\x13\xcc\x01\x12\x01\xbd\xa5\xd2\x90\x09\xc0\x26\xc4\xde\x44\x3d\
+\x80\xa4\x05\xc2\x09\x83\xfd\x61\x53\x06\x00\x11\x3c\x67\x6d\xa0\
+\x7a\x17\x8c\x01\x92\x04\xe8\x5a\x69\x6c\x79\x7a\xa2\xa6\x3e\x19\
+\x60\x90\x05\x2c\x60\x81\x46\x60\x76\x5e\xb7\xd1\x78\x60\xcd\xd7\
+\x6d\xe6\x77\x03\xe7\x57\xd7\xac\xcb\x03\x13\xe0\x28\xe0\xbd\x98\
+\x00\xfb\x1f\x1c\xb8\x37\x3a\xc2\xd6\x71\x85\x75\xf8\x53\x7f\x61\
+\x67\x17\xb5\x99\x18\xd8\x7e\x0d\x70\x5f\x77\xfe\xe9\xfb\x63\x12\
+\xa0\x12\xd4\xf6\xe6\xdf\x04\x9f\x1b\x49\x8e\x70\xf1\xf4\x8c\x7a\
+\x38\xf1\xf7\x6e\xcf\xfe\xd8\x55\x4e\x01\xac\xae\xeb\x36\x19\x0f\
+\xcc\x51\xdd\x46\x2c\x60\x81\xff\x07\x7c\x03\xb8\xad\xd6\xb6\x7a\
+\xa4\x8c\xc5\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
+\x00\x00\x08\x05\
+\x89\
+\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
+\x00\x00\x40\x00\x00\x00\x40\x08\x06\x00\x00\x00\xaa\x69\x71\xde\
+\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\
+\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x01\xc4\x00\x00\x01\xc4\
+\x01\x68\x3f\x39\xcf\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\
+\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\
+\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x07\x82\x49\x44\
+\x41\x54\x78\xda\xed\x9a\xd9\x53\x53\x57\x1c\xc7\x99\x4e\x67\xfa\
+\xd2\x97\xbe\x75\xfa\xd4\x99\xfe\x0d\x7d\xe8\x4c\x67\x8c\x0f\x7d\
+\x60\xc6\xa5\x6a\x55\x82\xa0\x48\xc5\x62\xc0\xa9\xa2\x55\x8b\xca\
+\x32\x56\xec\xe0\xb8\x0f\xa5\x62\x11\xdc\xd7\xba\xb0\xc8\x22\x16\
+\x05\x85\x24\x98\x05\x44\x51\xf6\x35\x84\x2d\x2c\x61\xc9\xfe\xeb\
+\xf9\x9d\xcb\xcd\x42\x24\xe4\xde\xdc\x84\x04\x7d\xf8\x3e\x70\x39\
+\xf7\xde\xdf\xf7\x73\xcf\xf9\xfe\xce\x61\x08\x03\x80\xb0\x40\x2b\
+\x3c\x7c\xe7\x67\xcb\xc5\x89\xfb\x44\xe2\x04\xb5\x48\x2c\x69\x5e\
+\x2e\x4e\xc8\xf8\x3e\x72\xc7\x17\x8b\x51\x0b\xa7\xc1\x13\x13\x13\
+\xdf\xe9\xf5\xfa\x08\x5f\x24\x53\xbf\x4e\xca\xc8\xca\xeb\x3c\x7c\
+\x32\x07\x9c\x75\xe4\xec\xc5\xe1\xf2\x2a\x69\xba\xb7\xcf\xd1\xe9\
+\xc6\xc3\x03\x06\x60\x6c\x6c\xec\x1b\x62\xbe\x81\x08\x82\x45\x9a\
+\x81\x61\xdb\xdb\xf6\xbe\x87\x01\x01\x40\x88\x9f\x0a\x26\xf3\xa8\
+\x3e\xed\x30\x28\xde\x74\x42\x53\x7b\x5f\x41\x20\x00\x74\x05\x2b\
+\x80\x59\x08\x85\x7e\x05\x40\x5e\xa8\x0d\x66\x00\xa8\x77\x3c\x21\
+\x2c\x19\x00\x0c\x04\x4d\xd1\x07\x03\x80\x84\xa0\x1b\x00\x0a\xa1\
+\x43\x53\xfc\x41\x00\x18\x1d\x1b\x07\x65\x53\xe7\x7c\x10\x1e\x2d\
+\x79\x00\xec\x32\x68\x6c\xe9\x01\xd5\xdb\x2e\x37\xb5\x76\x6b\xef\
+\x2d\x79\x00\x0b\x48\xfb\x11\xc0\x47\x00\x41\x08\x60\xb2\xf9\x35\
+\x18\xef\x5d\x02\x73\x4e\x26\x58\x4e\x24\x83\xf5\xc8\xaf\x60\x39\
+\x75\x08\x4c\xb9\x27\x61\xa6\xa2\x00\xf4\x5a\xcd\xd2\x04\x30\xad\
+\xa8\x05\xeb\xd1\xdd\x00\xbb\x22\x3c\x6b\xcf\x26\x30\x5d\xcb\x06\
+\xfd\xf0\x50\x70\x00\x10\x89\xd2\x3e\x1d\x18\x1c\x9a\xe4\x5d\xc8\
+\xd8\x18\x18\xef\x5c\x04\xd8\x2d\xa6\x06\x6d\x87\xb6\x83\xf1\xfe\
+\x15\x98\x7a\xa5\x84\xc9\xee\x0e\x98\xd0\x8d\x80\xbe\xa7\x13\xa6\
+\x1a\x5e\x92\x19\x50\x08\xd6\xb4\x04\x3a\xce\x9a\xbe\x93\x5e\xe7\
+\xfb\x5e\xac\x19\x6b\xf7\x09\x80\x28\x22\xfe\x6b\x72\x66\xaf\xe9\
+\xee\xe5\x3f\x2d\xd1\x2c\xfd\xb2\x04\x80\xe1\xe1\x35\x98\x18\x1d\
+\xf5\x7c\x0f\x01\x62\x24\xe3\x70\xbc\xe5\xe4\x21\x0a\x90\xcf\x7b\
+\xb1\x66\xac\x1d\x3d\xf0\x02\xb0\x4c\x2c\x11\x2f\x13\x27\x8c\x93\
+\x87\x00\x5f\x00\x53\xf5\x75\xcc\x97\x27\x9a\x96\x3e\x75\xe4\x40\
+\x57\x3b\xcc\x3c\x2d\x01\xe3\xad\x0b\x30\xf3\xac\x84\x4e\xf7\xc9\
+\xd6\x26\x98\x7e\xf1\x84\x4a\xaf\xe9\x05\xe3\xed\x5c\x0a\x6e\xa6\
+\xb2\xd8\x17\x00\x80\x1e\xd0\x8b\xd7\x00\x44\xeb\x25\x9f\x93\x1b\
+\xf3\xf1\x66\x56\x7c\x01\x58\x33\xf6\x50\x13\xc6\xbb\x79\xf6\x6b\
+\x86\x47\x77\xdc\xd6\xbd\xe5\xf8\x7e\xb0\x9c\x4b\xb7\xff\x8c\x80\
+\x26\x46\x75\x34\x33\xf0\x77\xbe\x00\x70\x52\x3e\x7a\xf3\x08\x60\
+\xd9\x46\xc9\xb7\xa2\x88\x84\x96\x39\x37\xf2\x02\x30\xf5\x5a\xcd\
+\xac\xf9\x94\x78\x32\xad\x75\x8c\xf9\xa2\x9b\x0e\xd3\xa7\x0f\x93\
+\xaf\x5f\x0a\xa6\xfc\x33\xf6\x7c\xa0\xe3\x0f\xc6\x39\x96\xcf\xcd\
+\x1c\x7a\x4d\xdf\xdf\x27\x04\x00\x40\x6f\xe8\xd1\x0d\x40\x5a\x5a\
+\xda\x27\xa2\xc8\x84\xfd\x64\x90\xc9\xed\x26\x9e\x00\x4c\x57\xff\
+\x62\xbe\x3e\x99\xca\xec\xb4\x87\xa4\x48\xc6\x3c\xae\xed\xf1\x71\
+\xfb\x58\xfc\x99\x05\x60\xce\xce\xb0\x5f\x9f\xa9\x2a\xa3\xd7\xa6\
+\xde\xd4\x0b\x03\x80\x91\x09\xbd\xa2\x67\x0a\xe0\x87\x88\xc4\xaf\
+\xc8\x85\x8a\x79\x06\xf3\x06\x80\x3d\x9e\x16\xdf\xa0\x60\x80\xdc\
+\x38\x6f\x0f\x43\xdc\x0b\x38\x8f\xc5\x70\x64\x01\x18\x0a\x6e\x38\
+\x00\x3c\x29\x62\x9e\xa1\x92\x09\x09\x80\x11\xf1\x8c\xde\xc3\x52\
+\xd3\xe2\x5a\x3c\x0e\xe4\x09\xc0\x96\xb2\x83\x59\xcf\xd8\xea\x30\
+\x0f\x52\x25\x4c\x7b\xcb\x48\x72\xef\x14\x24\x23\x58\x00\xd3\x4a\
+\xa9\x63\x16\xe5\x9d\x76\x79\x86\xa0\x00\x88\xd0\x7b\x18\xd4\x47\
+\x19\xca\xae\xc5\x42\xf8\x16\x89\xa0\x00\x60\x6f\x14\x2d\x1e\xdb\
+\x1a\x06\x1a\xbb\xce\xcd\xb9\x27\xdc\xc6\x9a\xb3\x8e\xd8\x67\x87\
+\x7e\x50\xcb\x5c\x27\x4b\x04\xf7\x04\xb6\x7d\x5b\x5c\x96\x8b\x10\
+\x00\xd0\x2b\x7a\x46\xef\x14\x00\x11\xf4\x3e\xdd\x0c\xf1\x49\xf1\
+\x82\x01\x60\x37\x34\xd8\xd2\xf4\xda\x7e\xfb\x17\x36\x5d\x3a\xeb\
+\x32\x0e\xb7\xbe\xb6\xdf\x36\x33\xb3\xe3\x8f\x5d\x8e\x59\xf1\x6f\
+\xbe\x5b\x07\x11\x02\x00\x7a\x44\xaf\xe8\xd9\x05\x00\xca\xac\x8a\
+\x82\xf3\x67\xb6\xc1\xf2\x48\x01\x32\x80\xa4\x3c\x5d\xbf\x8d\x4a\
+\x66\x49\x90\x74\xa7\x26\xc9\x52\x70\x99\xfe\xe4\x5c\x60\x0f\xc0\
+\x0b\xc7\x99\xb5\x5f\x5d\xce\x74\x84\x03\xb1\xa0\x1f\xd0\x0a\x02\
+\x00\x3d\xa1\x37\xf4\xc8\xfa\x75\x03\xc0\x4a\x59\x10\x03\xeb\xe2\
+\x76\xf8\x04\xc0\x78\xef\xb2\xcb\x17\x34\xde\xfe\xc7\x31\x0b\xae\
+\x64\xd1\x70\xa4\x63\x9c\x5a\x20\xe6\x83\xf9\xef\x3f\x67\xcd\x6f\
+\xa5\x1b\x29\xbe\x3b\x50\x67\x00\xe8\x05\x3d\xcd\xf5\x39\x2f\x00\
+\xd4\xb8\x34\x1a\x92\x53\xb6\xf3\x06\x30\xd9\xd9\xca\x18\x49\xde\
+\x06\x13\x23\x23\x74\xb7\x67\xc9\xdc\xef\xbe\x09\x3a\x9d\xe2\x76\
+\x0d\xf7\x0e\x93\x2d\x4d\x3e\x1d\x86\x58\x00\xe8\x01\xbd\xbc\xcf\
+\xa3\x47\x00\xac\x1e\xe4\xc5\x42\x47\x77\x0f\xaf\x22\xcc\xd9\xc7\
+\x98\xa9\x4d\x8e\xbe\x34\xc8\x48\x18\x1a\xca\x1f\x80\xe9\xe2\x29\
+\x30\x5d\xcf\xa6\x27\x44\x66\x83\x74\x8b\x4e\x7f\x3c\x03\x60\x17\
+\xd0\x0f\x0d\x32\x27\xc8\xba\x6a\xba\x5d\x36\x94\xdc\xe5\xfc\x6e\
+\xac\x19\x6b\xf7\xe4\xcd\x2b\x00\xa8\xee\x9a\x03\xf0\xae\xa5\x99\
+\x73\x11\x34\xe0\x66\xdb\x1f\xb6\x34\xfd\xe0\x80\x77\xf7\x92\xce\
+\xe1\xbc\x6f\x98\x56\x49\x39\xbd\x17\x6b\xc5\x9a\x17\xf2\xe5\x35\
+\x00\x94\x51\xb9\x15\x64\xb5\x25\xdc\xb7\xc4\x6f\x5f\xd9\xf7\x04\
+\xb6\xc3\xbf\x30\x5f\x99\x1c\x8c\x26\xdb\x9b\x5d\x4e\x7a\xd8\xfe\
+\x70\xc7\x87\xbb\x3f\xeb\xb1\xbd\x8c\x79\xb2\x73\xe4\xfa\xf5\x65\
+\x35\xc5\x60\x52\xc5\x78\x63\x9e\x1b\x00\x56\xaf\x9e\x9d\x00\x4d\
+\x3f\xb7\x64\xc6\x2f\x6f\xba\x7c\xce\x25\xf0\xa8\xf6\x46\xd3\x03\
+\x13\xdb\x21\x9c\x65\x4d\x4f\xe4\x14\x82\xbd\x1a\x0d\x34\x56\x65\
+\x02\x17\x2f\xbc\x00\xa0\x46\xe4\x3b\xa1\xbe\x41\xc9\x7d\x49\xf4\
+\x75\xd3\x0c\xc0\xe0\xa3\xb3\x62\x4f\x94\x23\xf8\x7e\x8f\xa5\xa7\
+\x3f\x3c\x1c\x4d\xa9\xe5\x9c\x36\x3f\x2a\x75\x1d\xe8\xe4\x12\xae\
+\xe6\xf9\x03\x40\xd9\xd4\xd1\x20\xab\xbe\x0e\xa3\x0b\xfd\x81\x63\
+\xc1\xd9\xa1\xb5\x9f\x16\xb9\x6a\x84\xdc\x27\xaf\xba\x04\xb6\xfa\
+\x68\x3e\xe6\x7d\x03\xc0\xaa\xed\x79\x0a\xb4\x75\x74\xf8\x04\x81\
+\x8f\x9a\x5b\x5b\xa0\xeb\x45\x32\xf8\x52\xbb\x20\x00\x50\x53\x8a\
+\x38\xa8\x93\x57\x06\xcc\xbc\xac\xb6\x14\x0c\xca\x58\x5f\xcd\x0b\
+\x07\x80\x95\xea\x59\x16\x0c\x0c\x0d\xf9\xcd\x78\x5f\x7f\x3f\x0d\
+\x61\xa1\xea\x15\x1c\x00\x4a\x2b\x4d\x82\xc6\xa6\x46\xc1\xcd\xab\
+\xeb\x5f\xc2\x88\x2c\x51\x48\xf3\xfe\x01\x80\xb2\xa8\x37\x83\xec\
+\xf9\x7d\x18\xe7\x71\x8c\x9d\x2b\x9d\x6e\x94\x04\xdd\x55\x5f\x82\
+\x2e\xf0\x00\x58\x35\x55\x1d\x85\xae\x9e\x1e\xde\xe6\x5b\xda\xda\
+\xa0\xe3\xc5\x41\xf0\x57\x7d\x7e\x07\x40\x0f\x55\x75\xf1\xa0\x50\
+\xd6\x72\x36\x2f\x97\x96\x83\x41\xf1\xb3\x3f\xcd\x07\x06\x00\x95\
+\x7a\x13\xc8\x1e\xe7\xc0\x30\x39\x15\x2e\xf8\x9f\x1f\x5a\x2d\xa8\
+\xca\x32\xe9\x3d\x7e\xaf\x2b\x10\x00\x6c\xca\x48\x30\x3e\x5e\x0d\
+\x86\x47\x2b\xa0\xad\x30\x11\xde\x35\xcf\x7f\xa8\xaa\xaf\x57\x82\
+\xa6\x68\x2b\x1d\x8b\xf7\xe0\xbd\x21\x0d\xc0\xf6\x52\x0c\xc6\xb2\
+\x55\xd4\x10\xab\x89\xe2\xb5\x20\xad\x2a\x72\xfd\x77\x17\xb2\x9b\
+\xac\x7d\x7c\x19\x66\x8a\x57\xba\x8c\xc5\x7b\xf1\x19\x21\x09\xc0\
+\x2a\xdb\x48\x4e\x72\xae\x86\x9c\xd5\x51\x28\x81\xda\x8a\x2b\x20\
+\x2d\xcb\x05\x4d\x61\xcc\xbc\xe3\xf0\x19\xf8\xac\x90\x02\x60\xa9\
+\x59\x3f\xbf\x21\x9e\xc2\x67\x86\x04\x00\x73\xd5\x3a\xc1\xcd\xb3\
+\xc2\x67\x07\x2f\x00\x92\xda\xa6\xff\xd6\xf8\xcd\x3c\x2b\x7c\x87\
+\x80\x1d\x42\x18\x00\x34\xe9\x2b\x56\xfb\xdd\xbc\x3d\x1c\x2b\x04\
+\xeb\x10\xbe\x03\x78\x5f\xd2\x07\x04\x82\x30\x1d\xc2\x37\x00\x56\
+\x79\x84\xc7\xa4\xf7\xbb\xb0\x43\x90\x1a\x16\x05\x80\xa5\x66\xc3\
+\xe2\x19\x77\xeb\x10\x1b\x02\x0b\xc0\x9f\x49\x1f\xe0\x0e\xc1\x11\
+\x00\x26\x7d\xe5\x9a\xa0\x33\x6f\xef\x10\x95\x9c\x3b\x84\xf7\x00\
+\x6c\x2a\x62\xbe\xe2\xc7\xa0\x35\x6f\x87\x40\x6a\xc4\x5a\x05\x05\
+\x60\x53\x2c\x4e\xd2\xfb\xd4\x21\x14\x62\x61\x00\xd0\xa4\x2f\x5d\
+\x19\x32\xe6\xed\x2a\xf5\xaa\x43\x78\x06\x60\xa9\x25\x49\x5f\x12\
+\x62\xc6\x5d\xda\xe4\x0a\xea\x81\x17\x00\x73\xf5\x4f\xa1\x6b\x7c\
+\x6e\x87\x20\x5e\xbc\x07\xa0\x8e\x22\x69\xba\x76\xc9\x98\x77\x74\
+\x88\xb5\xd4\x9b\x47\x00\xa1\x92\xf4\x02\x76\x08\x0a\xa0\x8b\x49\
+\x7a\x72\xa0\x29\x0f\x9d\xa4\xe7\xdd\x21\xca\x57\x51\xaf\xb3\x00\
+\xba\x10\x40\x6a\xc8\x26\xbd\xef\x1d\x22\x35\x0c\xe4\x31\x5f\x92\
+\x33\xb6\xca\x58\xba\xca\xfa\xa1\x00\x40\xaf\xe8\x19\xbd\xff\x0f\
+\x04\x8a\x46\x5c\xf8\x16\xa5\x15\x00\x00\x00\x00\x49\x45\x4e\x44\
+\xae\x42\x60\x82\
+\x00\x00\x05\x2f\
+\x89\
+\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
+\x00\x00\x40\x00\x00\x00\x40\x08\x04\x00\x00\x00\x00\x60\xb9\x55\
+\x00\x00\x00\x04\x67\x41\x4d\x41\x00\x00\xb1\x8f\x0b\xfc\x61\x05\
+\x00\x00\x00\x20\x63\x48\x52\x4d\x00\x00\x7a\x26\x00\x00\x80\x84\
+\x00\x00\xfa\x00\x00\x00\x80\xe8\x00\x00\x75\x30\x00\x00\xea\x60\
+\x00\x00\x3a\x98\x00\x00\x17\x70\x9c\xba\x51\x3c\x00\x00\x00\x02\
+\x62\x4b\x47\x44\x00\x00\xaa\x8d\x23\x32\x00\x00\x00\x09\x70\x48\
+\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01\x42\x28\x9b\x78\x00\
+\x00\x00\x07\x74\x49\x4d\x45\x07\xe1\x09\x16\x09\x1f\x02\x45\x2b\
+\x5c\x88\x00\x00\x03\xfd\x49\x44\x41\x54\x68\xde\xed\xd9\x4b\x68\
+\x95\x47\x14\x07\xf0\xdf\xbd\x75\x61\x30\x60\xe2\xfb\x6e\x82\x46\
+\x89\x12\x24\x5a\x4b\xc5\x06\x83\x9b\x9a\xc6\x45\x8a\x4f\x90\x60\
+\xb7\xc1\x86\xb8\x10\x44\x24\xb8\x10\xb1\x20\x45\x97\x52\x2b\x64\
+\xe3\xa2\x2e\xa4\x50\x44\xb1\x55\x5c\x29\xad\x58\x6a\x7d\xa0\x8b\
+\xab\xd2\x50\x50\x6a\xc1\x68\x20\xba\x8a\x4e\x17\xb9\xb9\xaf\x24\
+\xf7\x8b\x37\xdf\xa7\x50\xfc\x7f\xab\x33\xf7\xcc\x9c\xff\x3d\x33\
+\x73\xe6\xcc\x19\xca\xb1\xdc\x45\xc3\x42\x02\xdf\xb0\x8b\x96\x8b\
+\x40\xbd\x27\x89\x18\x1f\xfb\x9e\xa8\x2f\x35\x38\xa3\x8c\xc0\x56\
+\x19\x7f\xdb\xe1\xdf\x28\xa6\x55\x60\x81\xb3\x1a\x6c\xd5\x5f\x89\
+\xc0\x5c\x64\xdd\x48\xc0\x3c\x03\xb2\x1a\xcc\xad\xec\x81\x2b\x82\
+\xcf\xdd\x4c\xc8\x03\x1f\x0b\xae\x44\xa9\x1d\x30\x92\xd8\x0a\x18\
+\x71\xa0\xdc\x5c\x6a\x02\x0a\x4b\x7d\xa6\x36\x2f\x7d\x87\x83\x9e\
+\x55\xf1\x8f\xe7\xf8\x06\x5f\xe7\xe5\x61\xbf\x79\xf4\xf6\xc3\x04\
+\xc1\xe2\xaa\x5c\xbe\x58\x10\xa2\x94\xd2\x55\x0d\x1d\x23\x3e\x10\
+\xf8\x40\x20\x9a\xc0\x3f\xc8\x54\x35\x76\x26\xd7\x7b\x9a\x04\x1e\
+\xa1\xa9\x2a\x02\x4d\xb9\xde\xd3\x24\xf0\x70\x5a\x04\x1e\xfe\x0f\
+\x3c\x90\x30\x81\x68\xac\x11\xbc\x52\x93\x97\x57\xb8\xa6\x63\x42\
+\xcd\x0e\xd7\xac\xc8\x4b\x35\x5e\x09\xd6\x4c\x9f\x00\xf7\x04\xbd\
+\x79\x69\xbb\xe0\xc8\x84\x7a\x47\x04\xdb\xf3\x52\xaf\xe0\x5e\x1c\
+\xe6\xd9\x2d\x18\x28\xca\x1c\x56\x9a\xed\xa4\x4d\x60\x9f\x7d\x60\
+\x93\x93\x66\x5b\x99\xd7\x99\x61\x40\xb0\x3b\x1e\x02\xb3\x3c\x17\
+\xec\x2a\x6a\x69\x15\x9c\x43\xda\x0b\x2f\xa4\x71\x4e\xd0\x5a\xa4\
+\xb1\x4b\xf0\xdc\xac\x78\x08\x70\x4c\x70\x37\x97\x3b\xd4\x39\x68\
+\x99\x0e\x19\x3d\xda\xad\xb6\x5a\xbb\x1e\x19\x1d\x96\x39\xa8\x0e\
+\xa4\xdc\x15\x1c\x8b\xcb\x3c\x4b\xbc\x16\x6c\x03\x5f\x09\x8e\x63\
+\x7e\x7e\x8e\xef\x09\xe6\xe3\xb8\xe0\x2b\xb0\x4d\xf0\xda\x92\xf8\
+\x08\x70\x58\x30\xa4\x05\xb5\x7a\x35\xd8\xa9\x51\x97\x56\x6d\xda\
+\xb4\xea\xd2\x68\xa7\x06\xbd\x6a\xd1\x62\x48\x70\x38\x4e\xf3\xa4\
+\x5d\x10\x3c\xd6\x00\xd6\x0b\xce\x23\x6d\xc8\x90\x34\xce\x0b\xd6\
+\x83\x06\x8f\x05\x17\xe2\x3f\xe6\xea\x3c\x10\xdc\x57\x8f\x1a\x47\
+\x6d\xd0\x22\xa3\x5b\xb7\x8c\x16\x1b\x1c\x55\x83\x7a\xf7\x05\x0f\
+\x72\x6b\x21\x66\xac\x34\x2c\xb8\x9a\x0b\x4a\xf3\x8c\xb8\x05\x6e\
+\x19\x31\x0f\xd4\xb8\x2a\x18\x2e\xda\x8e\x31\x63\xb3\x97\x82\xac\
+\x8d\x48\x39\x6d\x2f\xd8\xeb\xb4\x14\x36\xca\x0a\x5e\xda\x9c\x94\
+\x79\x68\x76\x47\x10\x9c\x29\xcb\x11\x32\xce\x08\x82\x3b\x9a\x93\
+\x34\x0f\x33\x9d\x10\x04\x43\xf6\xa8\xcb\x7d\x7b\x0c\x09\x82\x13\
+\x66\x26\x6d\x7e\x14\x5b\x0c\x8e\xbb\xf5\x0c\xda\x52\xcd\x50\xef\
+\x3d\x27\x7c\x7b\xbc\xe7\x29\x28\x5f\x84\xa7\x9c\xc2\x3b\x5b\x84\
+\xc5\xdb\x10\xd2\x9e\x7a\x9a\x9f\xc6\xc4\xb7\x61\x69\x20\x1a\xc5\
+\x22\x8b\x8a\xa4\x44\x03\x51\x71\x28\x2e\xa0\x5b\x77\x89\x9c\x58\
+\x28\x2e\x3d\x8c\x0a\xad\x63\x87\x51\x01\x09\x1d\x46\x85\xe3\xb8\
+\x14\x6d\xda\xc6\xb5\x25\x70\x1c\x17\x27\x24\xd1\x04\x12\x48\x48\
+\x8a\x53\xb2\x62\x4c\x34\x05\xc4\x9e\x92\x8d\x4f\x4a\x0b\x28\x5f\
+\x84\x63\x88\x35\x29\x2d\x4f\xcb\x8b\x51\xba\x0d\x0b\x88\x35\x2d\
+\x2f\xbd\x98\x14\xa3\x34\x10\x95\x22\xb6\x8b\x49\xf9\xd5\xac\x14\
+\x63\xa1\x78\x3c\x62\xbb\x9a\x75\x09\x6e\x4f\xfa\x6b\x6a\xc2\x4a\
+\xe3\x28\x6e\x0b\xba\xa2\x86\x8f\x0e\x17\x4b\x91\x9d\xd4\xfc\x75\
+\xd7\x27\xa5\x90\xcd\xf5\x4e\x90\x40\x65\x4c\x89\xc0\x8c\xc8\x61\
+\x96\x55\x20\x10\xac\x63\xd2\x6a\x68\x36\xd7\x7b\x9a\x04\x2a\x7b\
+\xe0\x7b\x26\x89\x04\x53\xf4\x40\x34\x2a\xd5\x8a\x2b\x6d\xc3\x44\
+\x6a\xc5\xcd\xfa\x35\xa2\x36\x57\x1f\x78\x63\x95\x55\xde\x18\xad\
+\x0f\xd4\xa2\x51\x7f\xdc\x39\x51\xb1\x07\xfa\x04\x3d\x0a\xf5\x81\
+\x02\xc6\xea\x03\x3d\x82\xbe\xb7\xf1\xc0\xd4\x09\x34\xeb\xb3\x40\
+\xa7\x85\x25\xf5\x01\x94\xd4\x07\x16\xea\xb4\x40\x9f\xe6\xf8\x09\
+\xf4\x0b\x3a\x4d\xa5\x3e\xd0\x29\xe8\x9f\x2a\x81\x54\x94\x82\x80\
+\x4d\x6a\xdd\xd4\xe1\x47\xed\x2e\xd9\xe1\x9c\x56\x37\xac\x33\xe0\
+\x23\xbc\xb6\xd8\x75\x6b\xfd\xea\x4b\x67\xb5\xbb\x64\x9b\x9f\xad\
+\x31\xec\x62\xb4\x85\xa9\x3d\xd9\x0c\x9a\xe3\x90\xa7\xbe\xb0\xd9\
+\x0f\xae\x5a\x62\xbf\xdb\x4e\x4a\x39\x86\x7d\x82\xdd\x56\xf9\xd6\
+\x5f\xda\x74\xf9\xc9\x2f\x16\x3a\x64\xd0\x1c\x55\x3c\xd9\xbc\xe7\
+\x47\xab\x4f\xfc\x2e\xe5\xcf\x04\x9f\xed\x3e\xf5\x47\x25\xa5\xfd\
+\x82\xcb\x09\x18\x1f\xc5\x65\xc1\xfe\xd2\xa6\xf2\x50\xfc\x0c\x4d\
+\xd6\x26\xe4\x81\xa6\x9c\x85\x0a\x78\xe7\x8f\xd7\xe3\xf1\x8e\x9f\
+\xef\xff\x03\x86\xf5\x7f\x55\x1a\x61\x3d\xe4\x00\x00\x00\x25\x74\
+\x45\x58\x74\x64\x61\x74\x65\x3a\x63\x72\x65\x61\x74\x65\x00\x32\
+\x30\x31\x37\x2d\x30\x39\x2d\x32\x32\x54\x30\x39\x3a\x33\x31\x3a\
+\x30\x32\x2b\x30\x32\x3a\x30\x30\x5e\x5c\x97\x83\x00\x00\x00\x25\
+\x74\x45\x58\x74\x64\x61\x74\x65\x3a\x6d\x6f\x64\x69\x66\x79\x00\
+\x32\x30\x31\x37\x2d\x30\x39\x2d\x32\x32\x54\x30\x39\x3a\x33\x31\
+\x3a\x30\x32\x2b\x30\x32\x3a\x30\x30\x2f\x01\x2f\x3f\x00\x00\x00\
+\x19\x74\x45\x58\x74\x53\x6f\x66\x74\x77\x61\x72\x65\x00\x77\x77\
+\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x9b\xee\
+\x3c\x1a\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
+\x00\x00\x05\x73\
+\x89\
+\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
+\x00\x00\x40\x00\x00\x00\x40\x08\x03\x00\x00\x00\x9d\xb7\x81\xec\
+\x00\x00\x00\x03\x73\x42\x49\x54\x08\x08\x08\xdb\xe1\x4f\xe0\x00\
+\x00\x00\x09\x70\x48\x59\x73\x00\x00\x01\xc9\x00\x00\x01\xc9\x01\
+\x61\x0f\x54\x5c\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\
+\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\
+\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x01\xc5\x50\x4c\x54\
+\x45\xff\xff\xff\x00\xaa\xaa\x1a\xb3\xcc\x2b\xbf\xd5\x26\xb3\xd0\
+\x21\xb5\xd6\x26\xb7\xd5\x25\xb9\xd3\x24\xb7\xd5\x24\xb6\xd3\x26\
+\xb8\xd4\x25\xb8\xd3\x24\xb6\xd4\x25\xb6\xd3\x25\xb7\xd3\x26\xb7\
+\xd2\x25\xb7\xd3\x26\xb7\xd4\x24\xb8\xd4\x26\xb7\xd3\x25\xb7\xd3\
+\x24\xb7\xd3\x25\xb7\xd3\x25\xb7\xd3\x25\xb7\xd2\x25\xb7\xd3\x25\
+\xb7\xd3\x25\xb7\xd3\x25\xb7\xd3\x25\xb7\xd3\x25\xb7\xd3\x26\xb7\
+\xd3\x27\xb8\xd3\x28\xb8\xd4\x29\xb8\xd4\x2b\xb9\xd4\x2d\xba\xd5\
+\x2e\xba\xd5\x2f\xba\xd5\x30\xbb\xd5\x31\xbb\xd5\x34\xbc\xd6\x37\
+\xbd\xd7\x39\xbd\xd7\x3b\xbe\xd7\x3c\xbf\xd8\x3d\xbf\xd8\x3e\xbf\
+\xd8\x3f\xbf\xd8\x43\xc1\xd9\x44\xc1\xd9\x45\xc1\xd9\x4a\xc3\xda\
+\x4b\xc3\xdb\x4c\xc4\xdb\x4d\xc4\xdb\x4f\xc5\xdb\x50\xc5\xdc\x51\
+\xc5\xdc\x52\xc6\xdc\x54\xc7\xdc\x58\xc8\xdd\x59\xc8\xde\x5a\xc9\
+\xde\x5b\xc9\xde\x5c\xc9\xde\x5d\xc9\xde\x5d\xca\xde\x5e\xca\xdf\
+\x5f\xca\xdf\x60\xca\xdf\x61\xcb\xdf\x63\xcc\xe0\x67\xcd\xe0\x69\
+\xcd\xe1\x6a\xce\xe1\x6b\xce\xe1\x6e\xcf\xe2\x70\xd0\xe2\x71\xd0\
+\xe2\x73\xd1\xe3\x75\xd1\xe3\x75\xd2\xe3\x76\xd2\xe3\x7b\xd4\xe4\
+\x7c\xd4\xe5\x7d\xd4\xe5\x7e\xd4\xe5\x80\xd5\xe5\x85\xd7\xe6\x89\
+\xd8\xe7\x8b\xd9\xe8\x8c\xd9\xe8\x8d\xd9\xe8\x91\xdb\xe9\x95\xdc\
+\xea\x97\xdd\xea\x9e\xdf\xec\x9f\xdf\xec\xa1\xe0\xec\xa2\xe0\xec\
+\xa6\xe2\xed\xa9\xe2\xee\xaa\xe3\xee\xab\xe3\xee\xac\xe4\xee\xaf\
+\xe5\xef\xb1\xe5\xef\xb2\xe6\xef\xb8\xe8\xf1\xbe\xea\xf2\xbf\xea\
+\xf2\xc1\xea\xf2\xc1\xeb\xf3\xc3\xeb\xf3\xc7\xec\xf4\xc7\xed\xf4\
+\xcb\xee\xf4\xcd\xee\xf5\xcf\xef\xf5\xd1\xf0\xf6\xd2\xf0\xf6\xd4\
+\xf1\xf6\xd7\xf2\xf7\xd8\xf2\xf7\xda\xf3\xf8\xdb\xf3\xf8\xdc\xf3\
+\xf8\xdd\xf4\xf8\xe3\xf6\xf9\xe4\xf6\xf9\xe4\xf6\xfa\xe6\xf7\xfa\
+\xe9\xf8\xfb\xea\xf8\xfb\xec\xf9\xfb\xed\xf9\xfb\xef\xfa\xfc\xf0\
+\xfa\xfc\xf2\xfb\xfc\xf4\xfb\xfd\xf5\xfc\xfd\xf7\xfc\xfd\xf8\xfd\
+\xfe\xf9\xfd\xfe\xfa\xfd\xfe\xfb\xfe\xfe\xfc\xfe\xfe\xfd\xfe\xff\
+\xfe\xff\xff\xff\xff\xff\x2f\xe4\x3e\x74\x00\x00\x00\x1e\x74\x52\
+\x4e\x53\x00\x03\x0a\x0c\x1b\x1f\x3c\x4c\x4e\x62\x64\x68\x70\x74\
+\x8a\x8e\xa4\xb0\xb6\xbe\xc0\xcb\xd5\xd8\xe5\xea\xf2\xf8\xf9\xfe\
+\x6d\xf3\x04\xea\x00\x00\x02\xf6\x49\x44\x41\x54\x58\xc3\xad\x57\
+\xe7\x5f\x13\x41\x10\xbd\x10\xd2\x2b\x29\x04\x92\xb0\x44\x12\xc5\
+\xa8\xd8\x0b\x16\x2c\xd8\x15\x2c\x80\x8a\x62\x03\x0b\x16\xec\xa8\
+\x51\x50\x34\x56\x40\x50\x88\xb9\xbf\xd7\xe4\x6e\xf7\xbc\x9b\x2d\
+\x77\xf9\x25\xef\x5b\x66\xdf\x9b\xec\xcd\xce\xcc\xce\x4a\x12\x07\
+\x76\xb7\x3f\x18\x8e\x26\x92\xc9\x44\x34\x1c\xf4\xbb\xed\x52\x4d\
+\x68\xf6\x45\x52\xc8\x80\x54\xc4\xd7\x6c\x55\xdd\x14\x88\x77\x20\
+\x06\x3a\xe2\x81\x26\x0b\x72\x9b\xb7\x0d\x71\xd1\xe6\xb5\x99\xe9\
+\x5d\xad\x48\x88\x56\x97\x50\xee\x88\x21\x53\xc4\x1c\x7c\xbd\xb3\
+\x1d\x59\x40\xbb\x93\xa7\xf7\xa4\x91\x25\xa4\x3d\xec\xe8\x85\x90\
+\x65\x84\x18\xb1\xb4\xb5\xa0\x1a\xd0\x42\x7b\x60\xfd\x7f\x6e\xc7\
+\xd1\xe1\xab\xe7\x0e\x6d\xeb\x62\xec\x81\xfa\x7e\x8a\xb2\x76\x68\
+\xba\x2c\xab\x58\x7c\x74\x3a\x0b\x97\x41\x1c\x9c\x30\x7e\xb9\x89\
+\x25\x59\x8f\x9f\x17\x60\x24\x0d\x67\xe1\x80\xe7\xd7\xfb\x49\x86\
+\x78\xb1\x05\x9c\xa6\x3e\x1f\x60\xfe\x0c\xad\xc8\x34\x3e\x6f\x04\
+\x19\xa5\xcb\x5f\xa0\x3f\xb2\x2a\xb3\xf0\xbe\xdb\x48\xd3\xb2\xda\
+\x06\xf2\x7f\xfb\x02\x91\xfc\x2a\x4c\xdd\x7d\xfe\x45\xf3\x30\x09\
+\xea\x82\x9c\xa5\x17\x6c\xe0\x19\x11\x3c\xcc\x2b\xbf\x2f\xfe\xc0\
+\xbf\x57\x37\x1b\x89\x5e\x5c\xff\xa0\x7e\xf7\x10\xfd\x18\xb1\x6c\
+\x22\x1e\xc6\x41\x75\xab\xfd\x21\x00\x36\xf0\x18\xb3\xa7\x33\x9a\
+\xe9\x24\x36\x7d\x04\xd4\x80\xe2\x20\x0e\xac\x45\xcc\xde\xad\xb3\
+\x7d\x53\x4d\xcb\x9d\x46\x6a\x5c\xe9\x7f\xa0\x7f\x65\xff\xaa\xe4\
+\xd7\xac\xb0\xf4\x80\x2e\x57\xed\x93\x3e\xb0\x81\x1e\xcc\x1d\xd4\
+\x1b\xdf\x62\x23\x48\x05\xe4\xab\x38\x88\xc0\x2c\xff\xae\x50\x0b\
+\xfa\xdd\xae\x2f\xa9\xfa\x52\x06\x70\x23\x95\xfe\x9f\x82\x0e\xce\
+\x54\xbf\xa1\x7c\x40\x6f\xba\x85\x37\xf0\x0e\x72\x53\x76\xc9\x4d\
+\x97\x6a\xdf\xcb\xe2\xe4\x41\xbd\xe1\x18\x0e\x8b\x7c\x99\xe2\xba\
+\x25\xbf\x79\xf7\x38\x41\x0a\xf3\x43\x8e\x5a\xf3\x4b\x41\x53\xfd\
+\x79\x52\x19\xcb\x3b\xe9\xc5\xa0\x14\x36\xd3\x8f\x92\xb6\x22\x5f\
+\x62\xac\x86\xa5\xa8\x89\xfe\x9a\x56\x4a\xe3\xac\xe5\xa8\x94\x10\
+\xeb\x6f\x6a\xfa\x1b\xcc\xf5\x84\x94\x14\xea\xc7\x88\xbc\x34\xc2\
+\x26\x24\xc5\x0e\x76\x91\xce\xf4\x67\x00\xf1\x1c\x88\x3e\x21\x53\
+\xc0\xfa\xa5\x7e\x1e\x25\x21\x0c\xe2\x30\xd1\xf7\x71\x29\x51\xe1\
+\x31\xde\x53\xf5\xe5\x53\x7c\x4a\x58\x98\x48\x6f\x54\x07\x0f\x04\
+\x94\xa0\x30\x95\x17\x55\x07\xfb\x05\x14\x3f\xab\x98\x08\x36\xe0\
+\x8b\x2d\x23\x70\xe0\x66\x94\xb3\x86\x35\xea\x21\x3e\x11\xe8\x2b\
+\xe5\x4c\x37\x94\xff\x78\xaa\x84\xb0\x57\xe0\x20\xc2\x68\x69\x3a\
+\x6c\x9d\x95\xe5\xdf\x13\xa2\x4c\xf3\x31\x9a\xaa\xe1\x23\x0e\x0f\
+\x74\x8b\xf4\x4a\x53\xa5\xda\x7a\x0d\x88\x33\x2f\x16\x03\x3a\x85\
+\x0e\x02\xcc\xab\x4d\xa7\x1e\x99\x59\x29\xde\x59\xc7\xd5\xe3\xab\
+\x8d\xba\x5c\x35\xdc\x57\x8e\x71\x36\xcb\x5b\xf7\x72\xae\x77\x82\
+\x7e\x5c\x4b\xd7\x39\x7a\xed\x7a\xa7\x06\x0c\x8c\xdb\xd8\xc1\x2b\
+\x8e\x03\x17\x7f\xc4\x31\x14\xa3\x3c\xc3\xd6\xc7\x44\x43\x96\x82\
+\x2b\xd8\xc1\x14\x53\x6f\x18\xb2\xe8\x31\xaf\x8a\xfc\x57\x75\x2e\
+\xd9\xc7\xd2\xa7\x9d\x66\x83\x66\x05\x7b\xe7\x2a\xfa\xf9\x41\xe6\
+\x06\x3c\x56\x46\x5d\xd4\x75\x7c\xf4\x6c\x9e\xa9\x0f\x35\x7e\xd8\
+\xae\x7b\xdc\xaf\xff\xc1\xd1\x80\x27\x4f\xfd\x8f\xae\xfa\x9f\x7d\
+\x0d\x78\x78\xd6\xff\xf4\x6d\xc0\xe3\xbb\xb6\xe7\xff\x3f\x12\x27\
+\x45\xc2\x0e\x8d\x6d\xe9\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\
+\x60\x82\
+\x00\x00\x06\xfb\
+\x89\
+\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
+\x00\x00\x80\x00\x00\x00\x80\x08\x03\x00\x00\x00\xf4\xe0\x91\xf9\
+\x00\x00\x00\x03\x73\x42\x49\x54\x08\x08\x08\xdb\xe1\x4f\xe0\x00\
+\x00\x00\x09\x70\x48\x59\x73\x00\x00\x03\x76\x00\x00\x03\x76\x01\
+\x7d\xd5\x82\xcc\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\
+\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\
+\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x02\x55\x50\x4c\x54\
+\x45\xff\xff\xff\xff\x00\x00\xff\x80\x80\xff\x55\x55\xd5\x55\x55\
+\xe3\x55\x55\xe8\x5d\x46\xe4\x51\x43\xdc\x51\x46\xdd\x55\x4d\xde\
+\x52\x4a\x68\x48\x40\xe2\x57\x49\xe4\x57\x4a\xb5\x54\x44\xe2\x57\
+\x48\x57\x60\x80\xe0\x58\x4b\x68\x67\x78\xe3\x55\x49\x74\x70\x6b\
+\x4a\x2b\x27\x55\x60\x80\xe0\x57\x49\x97\x87\x51\xe1\x56\x4a\xe2\
+\x55\x49\xe2\x57\x48\x55\x5f\x81\xe2\x57\x4a\xe0\x56\x49\x57\x60\
+\x80\xab\x93\x45\xe1\x55\x49\x74\x72\x6a\xe0\x56\x4a\x83\x7a\x62\
+\xe2\x56\x48\xa2\x88\x44\xa6\x92\x48\x65\x6a\x75\x55\x60\x80\xae\
+\x95\x42\xe0\x56\x49\x54\x60\x80\x55\x61\x7f\x57\x5d\x7a\xa8\x8e\
+\x42\xe0\x56\x4a\x64\x6a\x74\xe1\x56\x49\xe1\x56\x49\x77\x75\x67\
+\xbd\x52\x45\xe1\x56\x49\x61\x53\x5d\xe1\x56\x49\xe1\x56\x48\x6b\
+\x48\x41\x68\x45\x3d\x8d\x71\x43\xaf\x4f\x45\xe1\x56\x49\x54\x60\
+\x80\x9b\x4e\x45\xbc\x51\x46\xbc\x51\x47\x5c\x58\x6a\xae\x95\x42\
+\xe1\x56\x49\xc8\x53\x48\xe1\x56\x49\xe1\x56\x49\x8c\x4c\x43\xb9\
+\x9c\x39\x54\x60\x80\xbc\x9d\x38\xe2\x56\x49\x5f\x3d\x37\xba\x9c\
+\x39\x5f\x3d\x38\x64\x69\x74\xba\x9b\x38\x63\x50\x57\x65\x50\x56\
+\xe1\x56\x49\xd3\x55\x48\xe1\x55\x49\xe1\x57\x4a\xe1\x56\x49\xb5\
+\x96\x39\x5e\x55\x64\x8e\x72\x43\x91\x74\x41\x88\x69\x43\xb3\x93\
+\x39\x78\x49\x42\xe1\x56\x49\xe1\x56\x49\xe1\x56\x49\xe1\x56\x49\
+\xe1\x56\x49\xe1\x56\x49\xe1\x56\x49\xe0\x56\x49\x4c\x2c\x28\x55\
+\x60\x7f\x55\x60\x80\xe1\x56\x49\x88\x7e\x5c\x6f\x49\x41\xa6\x90\
+\x48\xe1\x56\x49\x70\x70\x6d\x86\x7e\x5d\xde\xb2\x20\xe1\x56\x49\
+\x4c\x2c\x28\x55\x60\x7f\x55\x60\x80\x55\x61\x7f\x55\x61\x80\x56\
+\x60\x7f\x56\x60\x80\x56\x61\x7f\x59\x62\x7e\x5c\x64\x7b\x6a\x6c\
+\x71\x6b\x48\x41\x70\x71\x6d\x71\x71\x6d\x72\x71\x6b\x72\x71\x6c\
+\x73\x72\x6b\x74\x72\x6a\x75\x73\x6a\x76\x74\x69\x77\x74\x68\x77\
+\x75\x67\x79\x75\x66\x79\x75\x67\x7a\x76\x66\x7c\x77\x65\x7d\x77\
+\x64\x7d\x78\x63\x7d\x79\x63\x7e\x79\x63\x80\x79\x62\x80\x7a\x61\
+\x80\x7a\x62\x81\x7a\x61\x81\x7b\x60\x81\x7b\x61\x82\x7a\x61\x82\
+\x7b\x60\x83\x7b\x5f\x87\x7d\x5d\x9f\x8c\x4b\xa0\x8c\x4b\xa1\x8e\
+\x4a\xa2\x8e\x49\xa3\x8e\x49\xa5\x8f\x48\xa5\x90\x48\xa6\x90\x47\
+\xa8\x91\x46\xa9\x92\x44\xa9\x93\x45\xaa\x93\x44\xab\x93\x44\xab\
+\x94\x44\xac\x94\x43\xad\x94\x43\xad\x95\x42\xad\x95\x43\xae\x95\
+\x42\xaf\x95\x42\xb0\x96\x41\xb1\x96\x40\xb2\x97\x40\xb2\x98\x3f\
+\xb4\x98\x3e\xb4\x9a\x3e\xb5\x99\x3d\xb6\x9b\x3c\xb7\x9b\x3c\xbe\
+\x9e\x36\xc8\xa5\x2f\xdb\xb1\x22\xe1\x56\x49\xe2\xb4\x1e\xe6\xb6\
+\x1a\xe8\xb8\x18\xe8\xb8\x19\xe9\xb9\x18\xea\xb9\x18\xeb\xb9\x17\
+\xeb\xba\x17\xec\xba\x16\x43\xd6\x4a\x1c\x00\x00\x00\x75\x74\x52\
+\x4e\x53\x00\x01\x02\x03\x06\x09\x0b\x13\x16\x1e\x1f\x20\x23\x26\
+\x2f\x35\x38\x3a\x3d\x3f\x42\x48\x48\x49\x55\x56\x57\x58\x5a\x61\
+\x62\x64\x64\x66\x69\x6b\x6e\x71\x73\x76\x78\x7c\x7c\x7d\x88\x88\
+\x88\x88\x8e\x8f\x8f\x92\x99\x9f\xa0\xa2\xa4\xa9\xb0\xb7\xb7\xb8\
+\xb8\xb9\xba\xba\xbb\xbc\xbc\xbd\xc0\xc1\xc4\xc5\xc5\xc7\xc7\xc7\
+\xc8\xc8\xc9\xca\xcb\xcc\xcc\xd3\xd4\xd4\xd7\xd8\xd9\xda\xda\xda\
+\xdd\xe2\xe7\xeb\xf0\xf1\xf2\xf3\xf4\xf6\xf7\xf8\xf8\xf8\xf9\xfa\
+\xfc\xfc\xfc\xfd\xfd\xfe\xfe\x80\x48\xe3\x89\x00\x00\x03\x97\x49\
+\x44\x41\x54\x78\xda\xed\x98\x67\x53\x53\x41\x18\x85\x57\x20\x48\
+\x57\xc4\x86\x08\x06\x15\x54\x40\x8d\x20\x48\xb7\x62\x2c\x80\xd8\
+\x40\xec\x74\x54\x44\x54\xcc\x22\x58\xb0\xf7\xde\xb1\xf7\x8a\x15\
+\xbb\x51\x6c\xf9\x5d\x8e\x26\x60\xee\x26\x77\xdf\x1d\xde\x2c\xe2\
+\xcc\x9e\x6f\x77\x66\xcf\x79\x9e\x4c\x66\x76\x72\x43\x88\x9b\x04\
+\xc4\xa4\x2e\x29\x35\x9b\xc2\xbd\x88\x47\xe2\x15\x6e\x32\x97\x16\
+\xa7\xc6\x04\x88\x16\xa2\x2b\xac\xf6\xcc\x0a\xf2\x04\x3f\x68\x96\
+\x63\xae\x22\x5a\xe8\xbc\x6f\xb6\xb5\x33\x95\x11\x78\x7e\x44\xe5\
+\xdf\xbd\x6c\x5f\x81\x42\x92\xd5\x29\x55\xc1\x58\x7e\x70\x95\xf3\
+\x5e\x12\x5c\x08\xab\x77\x2e\x58\xf3\xbc\x71\x7c\xef\x3c\xcd\x5c\
+\x7d\x18\xd8\x58\x6c\xd5\x26\x0a\x27\x10\xc5\xcc\x2d\x86\x0a\xbd\
+\x99\x82\x35\x05\x27\x90\xc2\xee\xf5\x06\x0a\x83\xd8\x42\x11\x4e\
+\xa0\x88\xdd\x1b\x04\x14\xe2\xd9\x42\x9d\x01\xc3\x37\xd4\xb1\x7b\
+\xf1\x40\x63\x04\x5b\x28\x47\xdd\x46\x5e\xe5\xec\xde\x08\xa0\xd1\
+\x87\x2d\x98\x71\x5f\x81\x99\xdd\xeb\x03\x14\x7c\x6a\x98\x82\x09\
+\x27\x60\x62\xe6\x6a\x7c\xa0\x46\x9a\xb6\x50\x1f\x8a\x13\x08\xd5\
+\x5e\x2b\xd6\x34\xb0\xe1\x57\xa2\x29\x24\x62\x6f\xc2\x44\xcd\x5c\
+\x89\x1f\xdc\x88\x70\x2e\x14\x1b\xb0\x02\x86\x62\xe7\xbd\x21\x22\
+\x95\xc8\xb2\xce\xf3\x39\xfe\x04\x1d\xff\x9c\xce\xb9\xb2\x48\xb1\
+\x4a\x48\xa1\xfd\x7c\x75\x72\x2f\xe2\x81\xf4\x4a\xae\xb6\xef\x15\
+\x86\x08\x36\x02\x9b\x57\x4f\x99\x3a\x33\x6b\x76\x6d\x3a\xf1\x48\
+\xd2\x6b\x67\x67\xcd\x9c\x36\x65\x75\x73\xa0\xb0\x80\x23\x9e\x12\
+\xe8\xd8\x53\x02\x4a\x40\x09\xf4\x4c\x81\x04\x26\x13\x73\x73\x17\
+\xac\x72\x64\x69\xae\x4b\xe6\x4c\x48\xe0\x65\xec\x0c\xd7\x4a\xee\
+\xd2\x8e\xbd\x05\xf3\xe6\xcf\x65\x32\x99\x50\x6d\x76\x7e\xb2\xf1\
+\xf2\xed\x0a\xe5\x65\xdb\x33\x6e\xfb\xfb\x2e\xd7\x0a\xe9\x4e\xfe\
+\x6e\x0a\x09\xc8\xe5\xef\xa5\x90\x00\x92\xdf\xca\x6d\xff\x74\xcb\
+\xd7\x08\xe0\xf8\x14\xe0\xef\xa3\x90\xc0\x3f\xe1\x3b\x09\x20\xf9\
+\x4f\xb8\xed\x1f\xfb\x29\x24\x20\x97\x7f\x80\x42\x02\x72\xf9\x07\
+\x29\x24\x20\x97\x7f\x88\x42\x02\x48\xfe\x63\x6e\xdb\x76\x98\x42\
+\x02\x72\xf9\x47\x29\x24\x20\x97\x7f\x84\x42\x02\x72\xf9\xc7\xf8\
+\xed\x3d\x04\xcb\x7f\x88\xe3\x7f\x26\x72\xf9\xc7\x21\xbe\x8d\x48\
+\xe5\x9f\x00\xf9\x36\x22\x93\x7f\x12\xe6\xf3\x05\x90\xfc\x53\x02\
+\x7c\xae\x00\x92\x7f\x5a\x84\xcf\x13\x40\xf2\xcf\x08\xf1\x39\x02\
+\x10\xff\x01\x9f\x7f\x51\x8c\xaf\x2f\xd0\x4d\x7c\x5d\x01\x24\xbf\
+\x45\x94\xaf\x27\x00\xf1\xef\xf1\xf9\x97\x85\xf9\x36\xd2\xee\x2e\
+\x5f\xd6\xaf\xfd\x93\x75\x3a\xd9\xd0\xce\xcd\x26\x2d\xcf\xd2\x19\
+\xfb\xf3\xc6\xcd\x4e\x67\xd5\xcb\xa9\x12\x50\x02\x4a\x80\xf4\x65\
+\xd2\xcf\x68\x8c\x5d\xe9\x48\xa6\xd1\x35\xfd\xfb\x72\x33\xd8\x4d\
+\x25\xb3\x63\x2f\xd6\x38\x7c\x18\x93\xa1\xec\x5f\x34\xdb\x3f\xf0\
+\x2f\xd9\xb6\x46\xee\x25\xdb\xd2\xce\x6d\x5f\xd5\x7d\x35\xeb\x1e\
+\xfe\x35\x0a\x09\xc8\xe5\x5f\xa7\x90\x80\x5c\xfe\x0d\x0b\x24\x80\
+\xe4\x5f\xe2\xf3\x6f\x5a\x28\x20\x20\x97\x7f\xcb\x42\x01\x01\xb9\
+\xfc\xdb\x7a\x3d\xd2\x3d\xfc\x3b\x14\x12\x90\xcb\xbf\x6b\x81\x04\
+\x90\xfc\x0b\x5d\xe6\x3b\x04\xe4\xf2\xef\xf3\xba\x44\x3e\xff\x21\
+\x85\x04\xe4\xf2\x1f\x35\x42\x02\x48\xfe\xd9\xaf\xdc\xf6\x63\xfe\
+\x2b\xc2\x0e\x22\x99\xff\x14\xe0\x7f\x24\x72\xf9\xad\x0d\x00\xdf\
+\x46\xa4\xf2\x9f\x83\x7c\xe0\x2f\x1a\x88\x7f\x9e\xcf\x7f\xd1\x04\
+\xf2\x01\x01\x1c\xff\xa5\x05\xe6\xf3\x05\x70\xfc\x57\x54\x80\xcf\
+\x15\xc0\xf1\xdb\x84\xf8\x3c\x01\x1c\xff\x75\xa3\x10\x9f\x23\x00\
+\xf0\xcf\xf1\xf9\x6f\xb6\x8a\xf1\xf5\x05\x70\xfc\xb7\x82\x9f\x5f\
+\x5f\x00\xc7\x7f\xd7\x24\xca\xd7\x13\xc0\xf1\xdf\x37\x08\xf3\x6d\
+\x24\xce\x35\xe3\x57\x2c\x5f\xb4\xf0\x77\x26\x0d\xd4\xc9\xa8\x38\
+\x6e\x46\x8f\xd1\x64\xfa\x32\x47\xc6\xd9\x9f\x47\x3a\x9f\x55\x6f\
+\xc7\x4a\x40\x09\x28\x01\x25\xa0\x04\x94\x00\x57\x20\x63\x80\x47\
+\x92\xd1\x65\x81\x82\x2d\x1e\x49\x81\x12\x50\x02\x4a\x40\x09\x28\
+\x81\xff\x57\x20\x7f\x8d\x47\x92\xaf\x7e\x0f\x28\x01\x25\xa0\x04\
+\x94\x40\x8f\x16\xf8\x05\xd1\x6b\x23\x5f\x22\x9c\xd5\x9c\x00\x00\
+\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
+"
+
+qt_resource_name = b"\
+\x00\x03\
+\x00\x00\x70\x37\
+\x00\x69\
+\x00\x6d\x00\x67\
+\x00\x03\
+\x00\x00\x79\x93\
+\x00\x72\
+\x00\x73\x00\x63\
+\x00\x07\
+\x06\xa9\x57\xa7\
+\x00\x70\
+\x00\x64\x00\x66\x00\x2e\x00\x70\x00\x6e\x00\x67\
+\x00\x0c\
+\x0b\xdf\x21\x47\
+\x00\x73\
+\x00\x65\x00\x74\x00\x74\x00\x69\x00\x6e\x00\x67\x00\x73\x00\x2e\x00\x70\x00\x6e\x00\x67\
+\x00\x0a\
+\x0a\xc8\xfb\x07\
+\x00\x66\
+\x00\x6f\x00\x6c\x00\x64\x00\x65\x00\x72\x00\x2e\x00\x70\x00\x6e\x00\x67\
+\x00\x08\
+\x06\x48\x5a\x07\
+\x00\x63\
+\x00\x6f\x00\x6e\x00\x65\x00\x2e\x00\x70\x00\x6e\x00\x67\
+\x00\x08\
+\x08\xc8\x58\x67\
+\x00\x73\
+\x00\x61\x00\x76\x00\x65\x00\x2e\x00\x70\x00\x6e\x00\x67\
+\x00\x09\
+\x07\xff\x8f\x27\
+\x00\x65\
+\x00\x6d\x00\x61\x00\x69\x00\x6c\x00\x2e\x00\x70\x00\x6e\x00\x67\
+\x00\x0d\
+\x06\x7f\x4a\xa7\
+\x00\x68\
+\x00\x6f\x00\x75\x00\x72\x00\x67\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x2e\x00\x70\x00\x6e\x00\x67\
+\x00\x0c\
+\x03\x76\xc2\x07\
+\x00\x71\
+\x00\x75\x00\x65\x00\x73\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\
+\x00\x0b\
+\x0f\x14\x44\x47\
+\x00\x62\
+\x00\x61\x00\x72\x00\x72\x00\x69\x00\x65\x00\x72\x00\x2e\x00\x70\x00\x6e\x00\x67\
+"
+
+qt_resource_struct = b"\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
+\x00\x00\x00\x0c\x00\x02\x00\x00\x00\x09\x00\x00\x00\x03\
+\x00\x00\x00\xc8\x00\x00\x00\x00\x00\x01\x00\x00\x29\x9a\
+\x00\x00\x00\x64\x00\x00\x00\x00\x00\x01\x00\x00\x12\x0e\
+\x00\x00\x00\xa8\x00\x00\x00\x00\x00\x01\x00\x00\x24\x67\
+\x00\x00\x00\x18\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
+\x00\x00\x00\x90\x00\x00\x00\x00\x00\x01\x00\x00\x1c\x5e\
+\x00\x00\x00\x7a\x00\x00\x00\x00\x00\x01\x00\x00\x19\x6a\
+\x00\x00\x00\x4a\x00\x00\x00\x00\x00\x01\x00\x00\x0f\xe5\
+\x00\x00\x00\x2c\x00\x00\x00\x00\x00\x01\x00\x00\x05\xc4\
+\x00\x00\x00\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x2f\x11\
+"
+
+def qInitResources():
+    QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+def qCleanupResources():
+    QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+qInitResources()

+ 696 - 0
ui/qt/settings.ui

@@ -0,0 +1,696 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>settings</class>
+ <widget class="QDialog" name="settings">
+  <property name="windowModality">
+   <enum>Qt::ApplicationModal</enum>
+  </property>
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>663</width>
+    <height>461</height>
+   </rect>
+  </property>
+  <property name="font">
+   <font>
+    <family>Verdana</family>
+    <pointsize>8</pointsize>
+   </font>
+  </property>
+  <property name="windowTitle">
+   <string>Pardit</string>
+  </property>
+  <property name="windowIcon">
+   <iconset resource="pardit.qrc">
+    <normaloff>:/img/rsc/cone.png</normaloff>:/img/rsc/cone.png</iconset>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QLabel" name="label">
+     <property name="font">
+      <font>
+       <pointsize>11</pointsize>
+      </font>
+     </property>
+     <property name="text">
+      <string>Options</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QTabWidget" name="tabWidget">
+     <property name="currentIndex">
+      <number>1</number>
+     </property>
+     <widget class="QWidget" name="tab_general">
+      <attribute name="title">
+       <string>General</string>
+      </attribute>
+      <widget class="QLineEdit" name="txt_repertoire_defaut">
+       <property name="geometry">
+        <rect>
+         <x>200</x>
+         <y>20</y>
+         <width>371</width>
+         <height>20</height>
+        </rect>
+       </property>
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
+      </widget>
+      <widget class="QLabel" name="lbl_repertoire_defaut">
+       <property name="geometry">
+        <rect>
+         <x>10</x>
+         <y>20</y>
+         <width>191</width>
+         <height>21</height>
+        </rect>
+       </property>
+       <property name="text">
+        <string>Répertoire par défaut des PDF</string>
+       </property>
+      </widget>
+      <widget class="QLabel" name="lbl_repertoire_sortie">
+       <property name="geometry">
+        <rect>
+         <x>10</x>
+         <y>50</y>
+         <width>191</width>
+         <height>21</height>
+        </rect>
+       </property>
+       <property name="text">
+        <string>Répertoire de sortie</string>
+       </property>
+      </widget>
+      <widget class="QLineEdit" name="txt_repertoire_sortie">
+       <property name="geometry">
+        <rect>
+         <x>200</x>
+         <y>50</y>
+         <width>371</width>
+         <height>20</height>
+        </rect>
+       </property>
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
+      </widget>
+      <widget class="QToolButton" name="btn_repertoire_defaut">
+       <property name="geometry">
+        <rect>
+         <x>580</x>
+         <y>20</y>
+         <width>25</width>
+         <height>19</height>
+        </rect>
+       </property>
+       <property name="text">
+        <string>...</string>
+       </property>
+       <property name="icon">
+        <iconset resource="pardit.qrc">
+         <normaloff>:/img/rsc/folder.png</normaloff>:/img/rsc/folder.png</iconset>
+       </property>
+      </widget>
+      <widget class="QToolButton" name="btn_repertoire_sortie">
+       <property name="geometry">
+        <rect>
+         <x>580</x>
+         <y>50</y>
+         <width>25</width>
+         <height>19</height>
+        </rect>
+       </property>
+       <property name="text">
+        <string>...</string>
+       </property>
+       <property name="icon">
+        <iconset resource="pardit.qrc">
+         <normaloff>:/img/rsc/folder.png</normaloff>:/img/rsc/folder.png</iconset>
+       </property>
+      </widget>
+     </widget>
+     <widget class="QWidget" name="tab_values">
+      <attribute name="title">
+       <string>Valeurs personnalisées</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_2">
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_3">
+         <property name="bottomMargin">
+          <number>0</number>
+         </property>
+         <item>
+          <widget class="QLabel" name="lblField">
+           <property name="minimumSize">
+            <size>
+             <width>171</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>171</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Raison Sociale</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="txt_RaisonSocialeExploitant">
+           <property name="minimumSize">
+            <size>
+             <width>221</width>
+             <height>0</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_4">
+         <property name="bottomMargin">
+          <number>0</number>
+         </property>
+         <item>
+          <widget class="QLabel" name="lblField_2">
+           <property name="minimumSize">
+            <size>
+             <width>171</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>171</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Contact</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="txt_ContactExploitant">
+           <property name="minimumSize">
+            <size>
+             <width>221</width>
+             <height>0</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_5">
+         <property name="bottomMargin">
+          <number>0</number>
+         </property>
+         <item>
+          <widget class="QLabel" name="lblField_3">
+           <property name="minimumSize">
+            <size>
+             <width>171</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>171</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>N° de voie</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="txt_NoVoieExploitant">
+           <property name="minimumSize">
+            <size>
+             <width>221</width>
+             <height>0</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_6">
+         <property name="bottomMargin">
+          <number>0</number>
+         </property>
+         <item>
+          <widget class="QLabel" name="lblField_4">
+           <property name="minimumSize">
+            <size>
+             <width>171</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>171</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Lieu-dit BP</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="txt_LieuditBPExploitant">
+           <property name="minimumSize">
+            <size>
+             <width>221</width>
+             <height>0</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_7">
+         <property name="bottomMargin">
+          <number>0</number>
+         </property>
+         <item>
+          <widget class="QLabel" name="lblField_5">
+           <property name="minimumSize">
+            <size>
+             <width>171</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>171</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Code Postal</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="txt_CodePostalExploitant">
+           <property name="minimumSize">
+            <size>
+             <width>221</width>
+             <height>0</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_16">
+         <property name="bottomMargin">
+          <number>0</number>
+         </property>
+         <item>
+          <widget class="QLabel" name="lblField_14">
+           <property name="minimumSize">
+            <size>
+             <width>171</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>171</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Commune</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="txt_CommuneExploitant">
+           <property name="minimumSize">
+            <size>
+             <width>221</width>
+             <height>0</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_8">
+         <property name="bottomMargin">
+          <number>0</number>
+         </property>
+         <item>
+          <widget class="QLabel" name="lblField_6">
+           <property name="minimumSize">
+            <size>
+             <width>171</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>171</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Tel.</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="txt_TelExploitant">
+           <property name="minimumSize">
+            <size>
+             <width>221</width>
+             <height>0</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_9">
+         <property name="bottomMargin">
+          <number>0</number>
+         </property>
+         <item>
+          <widget class="QLabel" name="lblField_7">
+           <property name="minimumSize">
+            <size>
+             <width>171</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>171</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Fax</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="txt_FaxExploitant">
+           <property name="minimumSize">
+            <size>
+             <width>221</width>
+             <height>0</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_11">
+         <property name="bottomMargin">
+          <number>0</number>
+         </property>
+         <item>
+          <widget class="QLabel" name="lblField_9">
+           <property name="minimumSize">
+            <size>
+             <width>171</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>171</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Service</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="txt_DesignationService">
+           <property name="minimumSize">
+            <size>
+             <width>221</width>
+             <height>0</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_13">
+         <property name="bottomMargin">
+          <number>0</number>
+         </property>
+         <item>
+          <widget class="QLabel" name="lblField_11">
+           <property name="minimumSize">
+            <size>
+             <width>171</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>171</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Responsable du dossier: Nom</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="txt_NomResponsableDossier">
+           <property name="minimumSize">
+            <size>
+             <width>221</width>
+             <height>0</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_10">
+         <property name="bottomMargin">
+          <number>0</number>
+         </property>
+         <item>
+          <widget class="QLabel" name="lblField_8">
+           <property name="minimumSize">
+            <size>
+             <width>171</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>171</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Responsable du dossier: Tel</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="txt_TelResponsableDossier">
+           <property name="minimumSize">
+            <size>
+             <width>221</width>
+             <height>0</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_14">
+         <property name="bottomMargin">
+          <number>0</number>
+         </property>
+         <item>
+          <widget class="QLabel" name="lblField_12">
+           <property name="minimumSize">
+            <size>
+             <width>171</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>171</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Endommagement: Tel</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="txt_TelEndommagement">
+           <property name="minimumSize">
+            <size>
+             <width>221</width>
+             <height>0</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_15">
+         <property name="bottomMargin">
+          <number>0</number>
+         </property>
+         <item>
+          <widget class="QLabel" name="lblField_13">
+           <property name="minimumSize">
+            <size>
+             <width>171</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>171</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Signataire</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="txt_NomSignataire">
+           <property name="minimumSize">
+            <size>
+             <width>221</width>
+             <height>0</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <spacer name="verticalSpacer">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QPushButton" name="btnCancel">
+       <property name="minimumSize">
+        <size>
+         <width>120</width>
+         <height>30</height>
+        </size>
+       </property>
+       <property name="font">
+        <font>
+         <pointsize>9</pointsize>
+        </font>
+       </property>
+       <property name="text">
+        <string>Annuler</string>
+       </property>
+       <property name="autoDefault">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="btnOk">
+       <property name="minimumSize">
+        <size>
+         <width>120</width>
+         <height>30</height>
+        </size>
+       </property>
+       <property name="font">
+        <font>
+         <pointsize>9</pointsize>
+        </font>
+       </property>
+       <property name="text">
+        <string>Enregistrer</string>
+       </property>
+       <property name="autoDefault">
+        <bool>false</bool>
+       </property>
+       <property name="default">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="pardit.qrc"/>
+ </resources>
+ <connections/>
+</ui>

+ 290 - 0
ui/qt/settings_ui.py

@@ -0,0 +1,290 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'C:\dev\python\pardit\ui\qt\settings.ui'
+#
+# Created by: PyQt5 UI code generator 5.8.2
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+class Ui_settings(object):
+    def setupUi(self, settings):
+        settings.setObjectName("settings")
+        settings.setWindowModality(QtCore.Qt.ApplicationModal)
+        settings.resize(663, 461)
+        font = QtGui.QFont()
+        font.setFamily("Verdana")
+        font.setPointSize(8)
+        settings.setFont(font)
+        icon = QtGui.QIcon()
+        icon.addPixmap(QtGui.QPixmap(":/img/rsc/cone.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+        settings.setWindowIcon(icon)
+        self.verticalLayout = QtWidgets.QVBoxLayout(settings)
+        self.verticalLayout.setObjectName("verticalLayout")
+        self.label = QtWidgets.QLabel(settings)
+        font = QtGui.QFont()
+        font.setPointSize(11)
+        self.label.setFont(font)
+        self.label.setObjectName("label")
+        self.verticalLayout.addWidget(self.label)
+        self.tabWidget = QtWidgets.QTabWidget(settings)
+        self.tabWidget.setObjectName("tabWidget")
+        self.tab_general = QtWidgets.QWidget()
+        self.tab_general.setObjectName("tab_general")
+        self.txt_repertoire_defaut = QtWidgets.QLineEdit(self.tab_general)
+        self.txt_repertoire_defaut.setGeometry(QtCore.QRect(200, 20, 371, 20))
+        self.txt_repertoire_defaut.setReadOnly(True)
+        self.txt_repertoire_defaut.setObjectName("txt_repertoire_defaut")
+        self.lbl_repertoire_defaut = QtWidgets.QLabel(self.tab_general)
+        self.lbl_repertoire_defaut.setGeometry(QtCore.QRect(10, 20, 191, 21))
+        self.lbl_repertoire_defaut.setObjectName("lbl_repertoire_defaut")
+        self.lbl_repertoire_sortie = QtWidgets.QLabel(self.tab_general)
+        self.lbl_repertoire_sortie.setGeometry(QtCore.QRect(10, 50, 191, 21))
+        self.lbl_repertoire_sortie.setObjectName("lbl_repertoire_sortie")
+        self.txt_repertoire_sortie = QtWidgets.QLineEdit(self.tab_general)
+        self.txt_repertoire_sortie.setGeometry(QtCore.QRect(200, 50, 371, 20))
+        self.txt_repertoire_sortie.setReadOnly(True)
+        self.txt_repertoire_sortie.setObjectName("txt_repertoire_sortie")
+        self.btn_repertoire_defaut = QtWidgets.QToolButton(self.tab_general)
+        self.btn_repertoire_defaut.setGeometry(QtCore.QRect(580, 20, 25, 19))
+        icon1 = QtGui.QIcon()
+        icon1.addPixmap(QtGui.QPixmap(":/img/rsc/folder.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+        self.btn_repertoire_defaut.setIcon(icon1)
+        self.btn_repertoire_defaut.setObjectName("btn_repertoire_defaut")
+        self.btn_repertoire_sortie = QtWidgets.QToolButton(self.tab_general)
+        self.btn_repertoire_sortie.setGeometry(QtCore.QRect(580, 50, 25, 19))
+        self.btn_repertoire_sortie.setIcon(icon1)
+        self.btn_repertoire_sortie.setObjectName("btn_repertoire_sortie")
+        self.tabWidget.addTab(self.tab_general, "")
+        self.tab_values = QtWidgets.QWidget()
+        self.tab_values.setObjectName("tab_values")
+        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.tab_values)
+        self.verticalLayout_2.setObjectName("verticalLayout_2")
+        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_3.setContentsMargins(-1, -1, -1, 0)
+        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
+        self.lblField = QtWidgets.QLabel(self.tab_values)
+        self.lblField.setMinimumSize(QtCore.QSize(171, 0))
+        self.lblField.setMaximumSize(QtCore.QSize(171, 16777215))
+        self.lblField.setObjectName("lblField")
+        self.horizontalLayout_3.addWidget(self.lblField)
+        self.txt_RaisonSocialeExploitant = QtWidgets.QLineEdit(self.tab_values)
+        self.txt_RaisonSocialeExploitant.setMinimumSize(QtCore.QSize(221, 0))
+        self.txt_RaisonSocialeExploitant.setObjectName("txt_RaisonSocialeExploitant")
+        self.horizontalLayout_3.addWidget(self.txt_RaisonSocialeExploitant)
+        self.verticalLayout_2.addLayout(self.horizontalLayout_3)
+        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_4.setContentsMargins(-1, -1, -1, 0)
+        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
+        self.lblField_2 = QtWidgets.QLabel(self.tab_values)
+        self.lblField_2.setMinimumSize(QtCore.QSize(171, 0))
+        self.lblField_2.setMaximumSize(QtCore.QSize(171, 16777215))
+        self.lblField_2.setObjectName("lblField_2")
+        self.horizontalLayout_4.addWidget(self.lblField_2)
+        self.txt_ContactExploitant = QtWidgets.QLineEdit(self.tab_values)
+        self.txt_ContactExploitant.setMinimumSize(QtCore.QSize(221, 0))
+        self.txt_ContactExploitant.setObjectName("txt_ContactExploitant")
+        self.horizontalLayout_4.addWidget(self.txt_ContactExploitant)
+        self.verticalLayout_2.addLayout(self.horizontalLayout_4)
+        self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_5.setContentsMargins(-1, -1, -1, 0)
+        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
+        self.lblField_3 = QtWidgets.QLabel(self.tab_values)
+        self.lblField_3.setMinimumSize(QtCore.QSize(171, 0))
+        self.lblField_3.setMaximumSize(QtCore.QSize(171, 16777215))
+        self.lblField_3.setObjectName("lblField_3")
+        self.horizontalLayout_5.addWidget(self.lblField_3)
+        self.txt_NoVoieExploitant = QtWidgets.QLineEdit(self.tab_values)
+        self.txt_NoVoieExploitant.setMinimumSize(QtCore.QSize(221, 0))
+        self.txt_NoVoieExploitant.setObjectName("txt_NoVoieExploitant")
+        self.horizontalLayout_5.addWidget(self.txt_NoVoieExploitant)
+        self.verticalLayout_2.addLayout(self.horizontalLayout_5)
+        self.horizontalLayout_6 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_6.setContentsMargins(-1, -1, -1, 0)
+        self.horizontalLayout_6.setObjectName("horizontalLayout_6")
+        self.lblField_4 = QtWidgets.QLabel(self.tab_values)
+        self.lblField_4.setMinimumSize(QtCore.QSize(171, 0))
+        self.lblField_4.setMaximumSize(QtCore.QSize(171, 16777215))
+        self.lblField_4.setObjectName("lblField_4")
+        self.horizontalLayout_6.addWidget(self.lblField_4)
+        self.txt_LieuditBPExploitant = QtWidgets.QLineEdit(self.tab_values)
+        self.txt_LieuditBPExploitant.setMinimumSize(QtCore.QSize(221, 0))
+        self.txt_LieuditBPExploitant.setObjectName("txt_LieuditBPExploitant")
+        self.horizontalLayout_6.addWidget(self.txt_LieuditBPExploitant)
+        self.verticalLayout_2.addLayout(self.horizontalLayout_6)
+        self.horizontalLayout_7 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_7.setContentsMargins(-1, -1, -1, 0)
+        self.horizontalLayout_7.setObjectName("horizontalLayout_7")
+        self.lblField_5 = QtWidgets.QLabel(self.tab_values)
+        self.lblField_5.setMinimumSize(QtCore.QSize(171, 0))
+        self.lblField_5.setMaximumSize(QtCore.QSize(171, 16777215))
+        self.lblField_5.setObjectName("lblField_5")
+        self.horizontalLayout_7.addWidget(self.lblField_5)
+        self.txt_CodePostalExploitant = QtWidgets.QLineEdit(self.tab_values)
+        self.txt_CodePostalExploitant.setMinimumSize(QtCore.QSize(221, 0))
+        self.txt_CodePostalExploitant.setObjectName("txt_CodePostalExploitant")
+        self.horizontalLayout_7.addWidget(self.txt_CodePostalExploitant)
+        self.verticalLayout_2.addLayout(self.horizontalLayout_7)
+        self.horizontalLayout_16 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_16.setContentsMargins(-1, -1, -1, 0)
+        self.horizontalLayout_16.setObjectName("horizontalLayout_16")
+        self.lblField_14 = QtWidgets.QLabel(self.tab_values)
+        self.lblField_14.setMinimumSize(QtCore.QSize(171, 0))
+        self.lblField_14.setMaximumSize(QtCore.QSize(171, 16777215))
+        self.lblField_14.setObjectName("lblField_14")
+        self.horizontalLayout_16.addWidget(self.lblField_14)
+        self.txt_CommuneExploitant = QtWidgets.QLineEdit(self.tab_values)
+        self.txt_CommuneExploitant.setMinimumSize(QtCore.QSize(221, 0))
+        self.txt_CommuneExploitant.setObjectName("txt_CommuneExploitant")
+        self.horizontalLayout_16.addWidget(self.txt_CommuneExploitant)
+        self.verticalLayout_2.addLayout(self.horizontalLayout_16)
+        self.horizontalLayout_8 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_8.setContentsMargins(-1, -1, -1, 0)
+        self.horizontalLayout_8.setObjectName("horizontalLayout_8")
+        self.lblField_6 = QtWidgets.QLabel(self.tab_values)
+        self.lblField_6.setMinimumSize(QtCore.QSize(171, 0))
+        self.lblField_6.setMaximumSize(QtCore.QSize(171, 16777215))
+        self.lblField_6.setObjectName("lblField_6")
+        self.horizontalLayout_8.addWidget(self.lblField_6)
+        self.txt_TelExploitant = QtWidgets.QLineEdit(self.tab_values)
+        self.txt_TelExploitant.setMinimumSize(QtCore.QSize(221, 0))
+        self.txt_TelExploitant.setObjectName("txt_TelExploitant")
+        self.horizontalLayout_8.addWidget(self.txt_TelExploitant)
+        self.verticalLayout_2.addLayout(self.horizontalLayout_8)
+        self.horizontalLayout_9 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_9.setContentsMargins(-1, -1, -1, 0)
+        self.horizontalLayout_9.setObjectName("horizontalLayout_9")
+        self.lblField_7 = QtWidgets.QLabel(self.tab_values)
+        self.lblField_7.setMinimumSize(QtCore.QSize(171, 0))
+        self.lblField_7.setMaximumSize(QtCore.QSize(171, 16777215))
+        self.lblField_7.setObjectName("lblField_7")
+        self.horizontalLayout_9.addWidget(self.lblField_7)
+        self.txt_FaxExploitant = QtWidgets.QLineEdit(self.tab_values)
+        self.txt_FaxExploitant.setMinimumSize(QtCore.QSize(221, 0))
+        self.txt_FaxExploitant.setObjectName("txt_FaxExploitant")
+        self.horizontalLayout_9.addWidget(self.txt_FaxExploitant)
+        self.verticalLayout_2.addLayout(self.horizontalLayout_9)
+        self.horizontalLayout_11 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_11.setContentsMargins(-1, -1, -1, 0)
+        self.horizontalLayout_11.setObjectName("horizontalLayout_11")
+        self.lblField_9 = QtWidgets.QLabel(self.tab_values)
+        self.lblField_9.setMinimumSize(QtCore.QSize(171, 0))
+        self.lblField_9.setMaximumSize(QtCore.QSize(171, 16777215))
+        self.lblField_9.setObjectName("lblField_9")
+        self.horizontalLayout_11.addWidget(self.lblField_9)
+        self.txt_DesignationService = QtWidgets.QLineEdit(self.tab_values)
+        self.txt_DesignationService.setMinimumSize(QtCore.QSize(221, 0))
+        self.txt_DesignationService.setObjectName("txt_DesignationService")
+        self.horizontalLayout_11.addWidget(self.txt_DesignationService)
+        self.verticalLayout_2.addLayout(self.horizontalLayout_11)
+        self.horizontalLayout_13 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_13.setContentsMargins(-1, -1, -1, 0)
+        self.horizontalLayout_13.setObjectName("horizontalLayout_13")
+        self.lblField_11 = QtWidgets.QLabel(self.tab_values)
+        self.lblField_11.setMinimumSize(QtCore.QSize(171, 0))
+        self.lblField_11.setMaximumSize(QtCore.QSize(171, 16777215))
+        self.lblField_11.setObjectName("lblField_11")
+        self.horizontalLayout_13.addWidget(self.lblField_11)
+        self.txt_NomResponsableDossier = QtWidgets.QLineEdit(self.tab_values)
+        self.txt_NomResponsableDossier.setMinimumSize(QtCore.QSize(221, 0))
+        self.txt_NomResponsableDossier.setObjectName("txt_NomResponsableDossier")
+        self.horizontalLayout_13.addWidget(self.txt_NomResponsableDossier)
+        self.verticalLayout_2.addLayout(self.horizontalLayout_13)
+        self.horizontalLayout_10 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_10.setContentsMargins(-1, -1, -1, 0)
+        self.horizontalLayout_10.setObjectName("horizontalLayout_10")
+        self.lblField_8 = QtWidgets.QLabel(self.tab_values)
+        self.lblField_8.setMinimumSize(QtCore.QSize(171, 0))
+        self.lblField_8.setMaximumSize(QtCore.QSize(171, 16777215))
+        self.lblField_8.setObjectName("lblField_8")
+        self.horizontalLayout_10.addWidget(self.lblField_8)
+        self.txt_TelResponsableDossier = QtWidgets.QLineEdit(self.tab_values)
+        self.txt_TelResponsableDossier.setMinimumSize(QtCore.QSize(221, 0))
+        self.txt_TelResponsableDossier.setObjectName("txt_TelResponsableDossier")
+        self.horizontalLayout_10.addWidget(self.txt_TelResponsableDossier)
+        self.verticalLayout_2.addLayout(self.horizontalLayout_10)
+        self.horizontalLayout_14 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_14.setContentsMargins(-1, -1, -1, 0)
+        self.horizontalLayout_14.setObjectName("horizontalLayout_14")
+        self.lblField_12 = QtWidgets.QLabel(self.tab_values)
+        self.lblField_12.setMinimumSize(QtCore.QSize(171, 0))
+        self.lblField_12.setMaximumSize(QtCore.QSize(171, 16777215))
+        self.lblField_12.setObjectName("lblField_12")
+        self.horizontalLayout_14.addWidget(self.lblField_12)
+        self.txt_TelEndommagement = QtWidgets.QLineEdit(self.tab_values)
+        self.txt_TelEndommagement.setMinimumSize(QtCore.QSize(221, 0))
+        self.txt_TelEndommagement.setObjectName("txt_TelEndommagement")
+        self.horizontalLayout_14.addWidget(self.txt_TelEndommagement)
+        self.verticalLayout_2.addLayout(self.horizontalLayout_14)
+        self.horizontalLayout_15 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_15.setContentsMargins(-1, -1, -1, 0)
+        self.horizontalLayout_15.setObjectName("horizontalLayout_15")
+        self.lblField_13 = QtWidgets.QLabel(self.tab_values)
+        self.lblField_13.setMinimumSize(QtCore.QSize(171, 0))
+        self.lblField_13.setMaximumSize(QtCore.QSize(171, 16777215))
+        self.lblField_13.setObjectName("lblField_13")
+        self.horizontalLayout_15.addWidget(self.lblField_13)
+        self.txt_NomSignataire = QtWidgets.QLineEdit(self.tab_values)
+        self.txt_NomSignataire.setMinimumSize(QtCore.QSize(221, 0))
+        self.txt_NomSignataire.setObjectName("txt_NomSignataire")
+        self.horizontalLayout_15.addWidget(self.txt_NomSignataire)
+        self.verticalLayout_2.addLayout(self.horizontalLayout_15)
+        spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+        self.verticalLayout_2.addItem(spacerItem)
+        self.tabWidget.addTab(self.tab_values, "")
+        self.verticalLayout.addWidget(self.tabWidget)
+        self.horizontalLayout = QtWidgets.QHBoxLayout()
+        self.horizontalLayout.setObjectName("horizontalLayout")
+        self.btnCancel = QtWidgets.QPushButton(settings)
+        self.btnCancel.setMinimumSize(QtCore.QSize(120, 30))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        self.btnCancel.setFont(font)
+        self.btnCancel.setAutoDefault(False)
+        self.btnCancel.setObjectName("btnCancel")
+        self.horizontalLayout.addWidget(self.btnCancel)
+        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+        self.horizontalLayout.addItem(spacerItem1)
+        self.btnOk = QtWidgets.QPushButton(settings)
+        self.btnOk.setMinimumSize(QtCore.QSize(120, 30))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        self.btnOk.setFont(font)
+        self.btnOk.setAutoDefault(False)
+        self.btnOk.setDefault(True)
+        self.btnOk.setObjectName("btnOk")
+        self.horizontalLayout.addWidget(self.btnOk)
+        self.verticalLayout.addLayout(self.horizontalLayout)
+
+        self.retranslateUi(settings)
+        self.tabWidget.setCurrentIndex(1)
+        QtCore.QMetaObject.connectSlotsByName(settings)
+
+    def retranslateUi(self, settings):
+        _translate = QtCore.QCoreApplication.translate
+        settings.setWindowTitle(_translate("settings", "Pardit"))
+        self.label.setText(_translate("settings", "Options"))
+        self.lbl_repertoire_defaut.setText(_translate("settings", "Répertoire par défaut des PDF"))
+        self.lbl_repertoire_sortie.setText(_translate("settings", "Répertoire de sortie"))
+        self.btn_repertoire_defaut.setText(_translate("settings", "..."))
+        self.btn_repertoire_sortie.setText(_translate("settings", "..."))
+        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_general), _translate("settings", "General"))
+        self.lblField.setText(_translate("settings", "Raison Sociale"))
+        self.lblField_2.setText(_translate("settings", "Contact"))
+        self.lblField_3.setText(_translate("settings", "N° de voie"))
+        self.lblField_4.setText(_translate("settings", "Lieu-dit BP"))
+        self.lblField_5.setText(_translate("settings", "Code Postal"))
+        self.lblField_14.setText(_translate("settings", "Commune"))
+        self.lblField_6.setText(_translate("settings", "Tel."))
+        self.lblField_7.setText(_translate("settings", "Fax"))
+        self.lblField_9.setText(_translate("settings", "Service"))
+        self.lblField_11.setText(_translate("settings", "Responsable du dossier: Nom"))
+        self.lblField_8.setText(_translate("settings", "Responsable du dossier: Tel"))
+        self.lblField_12.setText(_translate("settings", "Endommagement: Tel"))
+        self.lblField_13.setText(_translate("settings", "Signataire"))
+        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_values), _translate("settings", "Valeurs personnalisées"))
+        self.btnCancel.setText(_translate("settings", "Annuler"))
+        self.btnOk.setText(_translate("settings", "Enregistrer"))
+
+from . import pardit_rc

BIN
ui/rsc/barrier.png


BIN
ui/rsc/cone.png


BIN
ui/rsc/email.png


BIN
ui/rsc/folder.png


BIN
ui/rsc/hourglass.png


BIN
ui/rsc/pdf.png


BIN
ui/rsc/question.png


BIN
ui/rsc/save.png


BIN
ui/rsc/settings.png


+ 107 - 0
ui/settings.py

@@ -0,0 +1,107 @@
+'''
+Boite de dialogue d'édition des paramètres utilisateurs.
+
+@author: olivier.massot, sept. 2017
+'''
+from PyQt5.Qt import QFileDialog
+from PyQt5.QtWidgets import QDialog, QApplication
+import yaml
+
+from core import config
+from core.constants import USER_DATA_PATH
+from ui.qt.settings_ui import Ui_settings
+
+
+class SettingsDialog(QDialog):
+    def __init__(self):
+        super(SettingsDialog, self).__init__()
+        self.createWidgets()
+
+    def createWidgets(self):
+        self.ui = Ui_settings()
+        self.ui.setupUi(self)
+
+        self.ui.tabWidget.setCurrentIndex(0)
+
+        self.ui.btn_repertoire_defaut.clicked.connect(self.majRepInput)
+        self.ui.btn_repertoire_sortie.clicked.connect(self.majRepOutput)
+
+        self.ui.btnOk.clicked.connect(self.ok)
+        self.ui.btnCancel.clicked.connect(self.cancel)
+
+        self.load()
+
+
+    def load(self):
+        self.ui.txt_repertoire_defaut.setText(config.get("repertoire_defaut"))
+        self.ui.txt_repertoire_sortie.setText(config.get("repertoire_sortie"))
+
+        self.ui.txt_RaisonSocialeExploitant.setText(config.get("donnees", "commun", "RaisonSocialeExploitant"))
+        self.ui.txt_ContactExploitant.setText(config.get("donnees", "commun", "ContactExploitant"))
+        self.ui.txt_NoVoieExploitant.setText(config.get("donnees", "commun", "NoVoieExploitant"))
+        self.ui.txt_LieuditBPExploitant.setText(config.get("donnees", "commun", "LieuditBPExploitant"))
+        self.ui.txt_CodePostalExploitant.setText(config.get("donnees", "commun", "CodePostalExploitant"))
+        self.ui.txt_CommuneExploitant.setText(config.get("donnees", "commun", "CommuneExploitant"))
+        self.ui.txt_TelExploitant.setText(config.get("donnees", "commun", "TelExploitant"))
+        self.ui.txt_FaxExploitant.setText(config.get("donnees", "commun", "FaxExploitant"))
+        self.ui.txt_NomResponsableDossier.setText(config.get("donnees", "commun", "NomResponsableDossier"))
+        self.ui.txt_DesignationService.setText(config.get("donnees", "commun", "DésignationService"))
+        self.ui.txt_TelResponsableDossier.setText(config.get("donnees", "commun", "TelResponsableDossier"))
+        self.ui.txt_TelEndommagement.setText(config.get("donnees", "commun", "TelEndommagement"))
+        self.ui.txt_NomSignataire.setText(config.get("donnees", "commun", "NomSignataire"))
+
+
+    def majRepInput(self):
+        inputRep = QFileDialog.getExistingDirectory(self, "Répertoire d'entrée", "")
+        if inputRep :
+            self.ui.txt_repertoire_defaut.setText(inputRep)
+
+    def majRepOutput(self):
+        outputRep = QFileDialog.getExistingDirectory(self, "Répertoire de sortie", "")
+        if outputRep :
+            self.ui.txt_repertoire_sortie.setText(outputRep)
+
+    def save(self):
+
+        new_config = {}
+
+        new_config["repertoire_defaut"] = self.ui.txt_repertoire_defaut.text()
+        new_config["repertoire_sortie"] = self.ui.txt_repertoire_sortie.text()
+
+        new_config["donnees"] = {}
+        new_config["donnees"]["commun"] = {}
+        new_config["donnees"]["commun"]["RaisonSocialeExploitant"] = self.ui.txt_RaisonSocialeExploitant.text()
+        new_config["donnees"]["commun"]["ContactExploitant"] = self.ui.txt_ContactExploitant.text()
+        new_config["donnees"]["commun"]["NoVoieExploitant"] = self.ui.txt_NoVoieExploitant.text()
+        new_config["donnees"]["commun"]["LieuditBPExploitant"] = self.ui.txt_LieuditBPExploitant.text()
+        new_config["donnees"]["commun"]["CodePostalExploitant"] = self.ui.txt_CodePostalExploitant.text()
+        new_config["donnees"]["commun"]["CommuneExploitant"] = self.ui.txt_CommuneExploitant.text()
+        new_config["donnees"]["commun"]["TelExploitant"] = self.ui.txt_TelExploitant.text()
+        new_config["donnees"]["commun"]["FaxExploitant"] = self.ui.txt_FaxExploitant.text()
+        new_config["donnees"]["commun"]["NomResponsableDossier"] = self.ui.txt_NomResponsableDossier.text()
+        new_config["donnees"]["commun"]["DésignationService"] = self.ui.txt_DesignationService.text()
+        new_config["donnees"]["commun"]["TelResponsableDossier"] = self.ui.txt_TelResponsableDossier.text()
+        new_config["donnees"]["commun"]["TelEndommagement"] = self.ui.txt_TelEndommagement.text()
+        new_config["donnees"]["commun"]["NomSignataire"] = self.ui.txt_NomSignataire.text()
+
+        with open(USER_DATA_PATH, "w+") as f:
+            yaml.dump(new_config, f)
+
+        # recharge la configuration de l'appli
+        config.load()
+
+    def cancel(self):
+        self.done(0)
+
+    def ok(self):
+        self.save()
+        self.done(1)
+
+if __name__ == "__main__":
+    import sys
+    app = QApplication(sys.argv)
+    config.load()
+    dlg = SettingsDialog()
+    dlg.show()
+    dlg.exec_()
+    exit(0)

+ 67 - 0
ui/widgets/DropLabel.py

@@ -0,0 +1,67 @@
+'''
+Hérite de QLabel, accepte les drop de fichiers et lit leur
+
+@author: olivier.massot, nov. 2017
+'''
+import re
+
+from PyQt5.Qt import QLabel, Qt, pyqtSignal, QTextCodec
+from path import Path
+
+from core import constants
+
+
+class DropLabel(QLabel):
+    dropped = pyqtSignal()
+
+    def __init__(self, parent):
+        super(QLabel, self).__init__(parent)
+        self.setAcceptDrops(True)
+
+    def dragEnterEvent(self, event):
+        if event.mimeData().hasUrls:
+            event.accept()
+        else:
+            event.ignore()
+
+    def dragMoveEvent(self, event):
+        if event.mimeData().hasUrls:
+            event.setDropAction(Qt.CopyAction)
+            event.accept()
+        else:
+            event.ignore()
+
+    def dropEvent(self, event):
+        data = event.mimeData().data("FileGroupDescriptorW")
+        data = QTextCodec.codecForName("UTF-16").toUnicode(data)
+        data = re.findall(r"[\w\-. ]+", data)
+
+        if event.mimeData().hasFormat("FileGroupDescriptor"):
+            event.setDropAction(Qt.CopyAction)
+            event.accept()
+
+            # Get the file's name from mime data
+            data = event.mimeData().data("FileGroupDescriptorW")
+            data = QTextCodec.codecForName("UTF-16").toUnicode(data)
+            names = re.findall(r"[\w\-. ]+", data)
+            if len(names) > 1:
+                raise IOError("Vous ne pouvez pas traiter plus d'un fichier à la fois!")
+            filename = Path(names[0])
+            if not filename.ext == ".xml":
+                raise IOError("Le fichier doit être un fichier '.xml'.")
+
+            # Write the file in a temporary directory
+            with open(constants.TMPDIR / filename, 'wb') as f:
+                f.write(event.mimeData().data("FileContents"))
+            self.url = (constants.TMPDIR / filename)
+            self.dropped.emit()
+
+        elif event.mimeData().hasUrls:
+            event.setDropAction(Qt.CopyAction)
+            event.accept()
+            links = [url.toLocalFile() for url in event.mimeData().urls()]
+            self.url = links[0]
+            self.dropped.emit()
+
+        else:
+            event.ignore()

+ 0 - 0
ui/widgets/__init__.py


+ 26 - 0
ui/widgets/filenameLabel.py

@@ -0,0 +1,26 @@
+'''
+Label spécial pour l'affichage du ou des chemins d'accès aux fichiers générés
+
+@author: olivier.massot, sept. 2017
+'''
+from PyQt5.QtWidgets import QFrame
+from path import Path
+
+from ui.qt.filename_label_ui import Ui_Frame
+
+
+class FilenameLabel(QFrame):
+    def __init__(self, filename):
+        filename = Path(filename)
+        self._filename = filename
+
+        super(FilenameLabel, self).__init__()
+        self.createWidgets()
+        self.ui.txtFilename.setText("...\\" + filename.parent.name + "\\" + filename.name)
+
+    def createWidgets(self):
+        self.ui = Ui_Frame()
+        self.ui.setupUi(self)
+
+    def filename(self):
+        return self._filename