commit 8d22ffe40c80e5de21baa8044b7eac9e2f40dfbd Author: emile.malcuit Date: Wed May 21 16:15:27 2025 +0200 initialisation diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c1429d5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,122 @@ +# Compiled class file +*.class + +# class diagram file +*.mdj + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.idea/ +*.iml +# CMake +cmake-build-debug/ + +# Mongo Explorer plugin: +.idea/**/mongoSettings.xml + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +nbproject/private/ +build/ + +# Mac OS metafiles +.DS_Store diff --git a/documents/CouleurWagon.png b/documents/CouleurWagon.png new file mode 100644 index 0000000..74824a1 Binary files /dev/null and b/documents/CouleurWagon.png differ diff --git a/documents/Les Aventuriers du Rail - Règles.pdf b/documents/Les Aventuriers du Rail - Règles.pdf new file mode 100644 index 0000000..9afc0d0 Binary files /dev/null and b/documents/Les Aventuriers du Rail - Règles.pdf differ diff --git a/documents/Ticket to Ride Europe - Rules.pdf b/documents/Ticket to Ride Europe - Rules.pdf new file mode 100644 index 0000000..be214a8 Binary files /dev/null and b/documents/Ticket to Ride Europe - Rules.pdf differ diff --git a/documents/diagramme-classes-plantuml.txt b/documents/diagramme-classes-plantuml.txt new file mode 100644 index 0000000..eab70cb --- /dev/null +++ b/documents/diagramme-classes-plantuml.txt @@ -0,0 +1,70 @@ +@startuml +skinparam nodesep 220 +skinparam ranksep 120 + +class Jeu { +- joueurCourant: Joueur + ++ defausserCarteWagon(CouleurWagon): void ++ piocherCarteWagon(): CouleurWagon ++ retirerCarteWagonVisible(CouleurWagon): void ++ piocherDestination(): Destination ++ remplirCartesWagonVisibles() : void + +} + +class Joueur { +- couleur : Couleur +- nom : String +- nbWagons : int +- nbGares : int +- score : int + ++ joueurTour() ++ choisirDestinations(List, int) +} + +enum CouleurWagon{ +} + + +class Route { +- nom : String +- longueur : int +- couleur : CouleurWagon +} + +class Tunnel { +} + +class Ferry { +} + +class Destination { +- ville1 : String +- ville2 : String +- valeur: int + +} + +class Ville { +- nom : String +} + + + +Route <|-- Tunnel +Route <|-- Ferry + +Joueur "joueurs 2..5 "--* Jeu +Joueur -left->"*" CouleurWagon +Joueur "0..1 propriétaire"--"* destinations" Destination +Joueur "0..1 proprietaire"<- Route +Ville "0..3"-right->"0..1 prorpietaire" Joueur + +Jeu -->"*" Destination +Jeu -right->"*" Route + +Route -right->"ville1" Ville +Route -right->"ville2" Ville +@enduml \ No newline at end of file diff --git a/documents/reseau_Europe.png b/documents/reseau_Europe.png new file mode 100644 index 0000000..bc2cf25 Binary files /dev/null and b/documents/reseau_Europe.png differ diff --git a/nbactions.xml b/nbactions.xml new file mode 100644 index 0000000..9d0cbd1 --- /dev/null +++ b/nbactions.xml @@ -0,0 +1,55 @@ + + + + run + + jar + + + process-classes + org.codehaus.mojo:exec-maven-plugin:3.1.0:exec + + + + ${exec.vmArgs} -classpath %classpath ${exec.mainClass} ${exec.appArgs} + + vue.GameServer + java + + + + debug + + jar + + + process-classes + org.codehaus.mojo:exec-maven-plugin:3.1.0:exec + + + -agentlib:jdwp=transport=dt_socket,server=n,address=${jpda.address} + ${exec.vmArgs} -classpath %classpath ${exec.mainClass} ${exec.appArgs} + + vue.GameServer + java + true + + + + profile + + jar + + + process-classes + org.codehaus.mojo:exec-maven-plugin:3.1.0:exec + + + + ${exec.vmArgs} -classpath %classpath ${exec.mainClass} ${exec.appArgs} + vue.GameServer + java + + + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..e506aab --- /dev/null +++ b/pom.xml @@ -0,0 +1,94 @@ + + + 4.0.0 + + SLAM + Aventuriers-du-Rail + 1.0-SNAPSHOT + + 1.17 + 1.17 + UTF-8 + + + + org.junit.jupiter + junit-jupiter-engine + 5.4.0-M1 + test + + + org.junit.vintage + junit-vintage-engine + 5.4.0-M1 + test + + + org.junit.jupiter + junit-jupiter-api + 5.4.0-M1 + + + org.reflections + reflections + 0.9.12 + test + + + org.hamcrest + hamcrest + 2.2 + test + + + org.mockito + mockito-core + 3.3.3 + test + + + javax.websocket + javax.websocket-api + 1.1 + + + org.glassfish.tyrus + tyrus-server + 1.1 + + + org.glassfish.tyrus + tyrus-container-grizzly + 1.1 + + + com.google.code.gson + gson + 2.9.0 + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.0 + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.22.0 + + + org.apache.maven.plugins + maven-compiler-plugin + + 17 + 17 + + + + + + diff --git a/ressources/images/cards/eu_WagonCard_back.png b/ressources/images/cards/eu_WagonCard_back.png new file mode 100644 index 0000000..48c8027 Binary files /dev/null and b/ressources/images/cards/eu_WagonCard_back.png differ diff --git a/ressources/images/cards/eu_WagonCard_black.png b/ressources/images/cards/eu_WagonCard_black.png new file mode 100644 index 0000000..1d02db8 Binary files /dev/null and b/ressources/images/cards/eu_WagonCard_black.png differ diff --git a/ressources/images/cards/eu_WagonCard_blue.png b/ressources/images/cards/eu_WagonCard_blue.png new file mode 100644 index 0000000..cedace0 Binary files /dev/null and b/ressources/images/cards/eu_WagonCard_blue.png differ diff --git a/ressources/images/cards/eu_WagonCard_brown.png b/ressources/images/cards/eu_WagonCard_brown.png new file mode 100644 index 0000000..3cf4e9e Binary files /dev/null and b/ressources/images/cards/eu_WagonCard_brown.png differ diff --git a/ressources/images/cards/eu_WagonCard_green.png b/ressources/images/cards/eu_WagonCard_green.png new file mode 100644 index 0000000..d4986a0 Binary files /dev/null and b/ressources/images/cards/eu_WagonCard_green.png differ diff --git a/ressources/images/cards/eu_WagonCard_loco.png b/ressources/images/cards/eu_WagonCard_loco.png new file mode 100644 index 0000000..1331edd Binary files /dev/null and b/ressources/images/cards/eu_WagonCard_loco.png differ diff --git a/ressources/images/cards/eu_WagonCard_purple.png b/ressources/images/cards/eu_WagonCard_purple.png new file mode 100644 index 0000000..b3d3999 Binary files /dev/null and b/ressources/images/cards/eu_WagonCard_purple.png differ diff --git a/ressources/images/cards/eu_WagonCard_red.png b/ressources/images/cards/eu_WagonCard_red.png new file mode 100644 index 0000000..077a588 Binary files /dev/null and b/ressources/images/cards/eu_WagonCard_red.png differ diff --git a/ressources/images/cards/eu_WagonCard_tunnel.png b/ressources/images/cards/eu_WagonCard_tunnel.png new file mode 100644 index 0000000..bd1b394 Binary files /dev/null and b/ressources/images/cards/eu_WagonCard_tunnel.png differ diff --git a/ressources/images/cards/eu_WagonCard_white.png b/ressources/images/cards/eu_WagonCard_white.png new file mode 100644 index 0000000..bf428e1 Binary files /dev/null and b/ressources/images/cards/eu_WagonCard_white.png differ diff --git a/ressources/images/cards/eu_WagonCard_yellow.png b/ressources/images/cards/eu_WagonCard_yellow.png new file mode 100644 index 0000000..94df7a0 Binary files /dev/null and b/ressources/images/cards/eu_WagonCard_yellow.png differ diff --git a/ressources/images/euMap.jpg b/ressources/images/euMap.jpg new file mode 100644 index 0000000..d56f21f Binary files /dev/null and b/ressources/images/euMap.jpg differ diff --git a/ressources/images/missions/eu-amsterdam-pamplona.png b/ressources/images/missions/eu-amsterdam-pamplona.png new file mode 100644 index 0000000..8c8f92a Binary files /dev/null and b/ressources/images/missions/eu-amsterdam-pamplona.png differ diff --git a/ressources/images/missions/eu-amsterdam-wilno.png b/ressources/images/missions/eu-amsterdam-wilno.png new file mode 100644 index 0000000..72f2da1 Binary files /dev/null and b/ressources/images/missions/eu-amsterdam-wilno.png differ diff --git a/ressources/images/missions/eu-angora-kharkov.png b/ressources/images/missions/eu-angora-kharkov.png new file mode 100644 index 0000000..369a125 Binary files /dev/null and b/ressources/images/missions/eu-angora-kharkov.png differ diff --git a/ressources/images/missions/eu-athina-angora.png b/ressources/images/missions/eu-athina-angora.png new file mode 100644 index 0000000..1d75ae1 Binary files /dev/null and b/ressources/images/missions/eu-athina-angora.png differ diff --git a/ressources/images/missions/eu-athina-wilno.png b/ressources/images/missions/eu-athina-wilno.png new file mode 100644 index 0000000..bd1d477 Binary files /dev/null and b/ressources/images/missions/eu-athina-wilno.png differ diff --git a/ressources/images/missions/eu-barcelona-bruxelles.png b/ressources/images/missions/eu-barcelona-bruxelles.png new file mode 100644 index 0000000..50a2978 Binary files /dev/null and b/ressources/images/missions/eu-barcelona-bruxelles.png differ diff --git a/ressources/images/missions/eu-barcelona-munchen.png b/ressources/images/missions/eu-barcelona-munchen.png new file mode 100644 index 0000000..7e94770 Binary files /dev/null and b/ressources/images/missions/eu-barcelona-munchen.png differ diff --git a/ressources/images/missions/eu-berlin-bucuresti.png b/ressources/images/missions/eu-berlin-bucuresti.png new file mode 100644 index 0000000..d4dc495 Binary files /dev/null and b/ressources/images/missions/eu-berlin-bucuresti.png differ diff --git a/ressources/images/missions/eu-berlin-moskva.png b/ressources/images/missions/eu-berlin-moskva.png new file mode 100644 index 0000000..6c9a69d Binary files /dev/null and b/ressources/images/missions/eu-berlin-moskva.png differ diff --git a/ressources/images/missions/eu-berlin-roma.png b/ressources/images/missions/eu-berlin-roma.png new file mode 100644 index 0000000..855e3d6 Binary files /dev/null and b/ressources/images/missions/eu-berlin-roma.png differ diff --git a/ressources/images/missions/eu-brest-marseille.png b/ressources/images/missions/eu-brest-marseille.png new file mode 100644 index 0000000..daf77a2 Binary files /dev/null and b/ressources/images/missions/eu-brest-marseille.png differ diff --git a/ressources/images/missions/eu-brest-petrograd.png b/ressources/images/missions/eu-brest-petrograd.png new file mode 100644 index 0000000..b270053 Binary files /dev/null and b/ressources/images/missions/eu-brest-petrograd.png differ diff --git a/ressources/images/missions/eu-brest-venezia.png b/ressources/images/missions/eu-brest-venezia.png new file mode 100644 index 0000000..c652760 Binary files /dev/null and b/ressources/images/missions/eu-brest-venezia.png differ diff --git a/ressources/images/missions/eu-bruxelles-danzig.png b/ressources/images/missions/eu-bruxelles-danzig.png new file mode 100644 index 0000000..0896c60 Binary files /dev/null and b/ressources/images/missions/eu-bruxelles-danzig.png differ diff --git a/ressources/images/missions/eu-budapest-sofia.png b/ressources/images/missions/eu-budapest-sofia.png new file mode 100644 index 0000000..b3bdb05 Binary files /dev/null and b/ressources/images/missions/eu-budapest-sofia.png differ diff --git a/ressources/images/missions/eu-cadiz-stockholm.png b/ressources/images/missions/eu-cadiz-stockholm.png new file mode 100644 index 0000000..157b3e6 Binary files /dev/null and b/ressources/images/missions/eu-cadiz-stockholm.png differ diff --git a/ressources/images/missions/eu-edinburgh-athina.png b/ressources/images/missions/eu-edinburgh-athina.png new file mode 100644 index 0000000..f1f1453 Binary files /dev/null and b/ressources/images/missions/eu-edinburgh-athina.png differ diff --git a/ressources/images/missions/eu-edinburgh-paris.png b/ressources/images/missions/eu-edinburgh-paris.png new file mode 100644 index 0000000..ebf0bc9 Binary files /dev/null and b/ressources/images/missions/eu-edinburgh-paris.png differ diff --git a/ressources/images/missions/eu-essen-kyiv.png b/ressources/images/missions/eu-essen-kyiv.png new file mode 100644 index 0000000..8c18374 Binary files /dev/null and b/ressources/images/missions/eu-essen-kyiv.png differ diff --git a/ressources/images/missions/eu-frankfurt-kobenhavn.png b/ressources/images/missions/eu-frankfurt-kobenhavn.png new file mode 100644 index 0000000..800d173 Binary files /dev/null and b/ressources/images/missions/eu-frankfurt-kobenhavn.png differ diff --git a/ressources/images/missions/eu-frankfurt-smolensk.png b/ressources/images/missions/eu-frankfurt-smolensk.png new file mode 100644 index 0000000..03aa0de Binary files /dev/null and b/ressources/images/missions/eu-frankfurt-smolensk.png differ diff --git a/ressources/images/missions/eu-kobenhavn-erzurum.png b/ressources/images/missions/eu-kobenhavn-erzurum.png new file mode 100644 index 0000000..88038c9 Binary files /dev/null and b/ressources/images/missions/eu-kobenhavn-erzurum.png differ diff --git a/ressources/images/missions/eu-kyiv-petrograd.png b/ressources/images/missions/eu-kyiv-petrograd.png new file mode 100644 index 0000000..9fb7d8c Binary files /dev/null and b/ressources/images/missions/eu-kyiv-petrograd.png differ diff --git a/ressources/images/missions/eu-kyiv-sochi.png b/ressources/images/missions/eu-kyiv-sochi.png new file mode 100644 index 0000000..8d2bafd Binary files /dev/null and b/ressources/images/missions/eu-kyiv-sochi.png differ diff --git a/ressources/images/missions/eu-lisboa-danzig.png b/ressources/images/missions/eu-lisboa-danzig.png new file mode 100644 index 0000000..ad1190b Binary files /dev/null and b/ressources/images/missions/eu-lisboa-danzig.png differ diff --git a/ressources/images/missions/eu-london-berlin.png b/ressources/images/missions/eu-london-berlin.png new file mode 100644 index 0000000..652fc6f Binary files /dev/null and b/ressources/images/missions/eu-london-berlin.png differ diff --git a/ressources/images/missions/eu-london-wien.png b/ressources/images/missions/eu-london-wien.png new file mode 100644 index 0000000..bd0dd98 Binary files /dev/null and b/ressources/images/missions/eu-london-wien.png differ diff --git a/ressources/images/missions/eu-madrid-dieppe.png b/ressources/images/missions/eu-madrid-dieppe.png new file mode 100644 index 0000000..70a20e9 Binary files /dev/null and b/ressources/images/missions/eu-madrid-dieppe.png differ diff --git a/ressources/images/missions/eu-madrid-zurich.png b/ressources/images/missions/eu-madrid-zurich.png new file mode 100644 index 0000000..49f8594 Binary files /dev/null and b/ressources/images/missions/eu-madrid-zurich.png differ diff --git a/ressources/images/missions/eu-marseille-essen.png b/ressources/images/missions/eu-marseille-essen.png new file mode 100644 index 0000000..dea731f Binary files /dev/null and b/ressources/images/missions/eu-marseille-essen.png differ diff --git a/ressources/images/missions/eu-palermo-constantinople.png b/ressources/images/missions/eu-palermo-constantinople.png new file mode 100644 index 0000000..129dfad Binary files /dev/null and b/ressources/images/missions/eu-palermo-constantinople.png differ diff --git a/ressources/images/missions/eu-palermo-moskva.png b/ressources/images/missions/eu-palermo-moskva.png new file mode 100644 index 0000000..bbf69b7 Binary files /dev/null and b/ressources/images/missions/eu-palermo-moskva.png differ diff --git a/ressources/images/missions/eu-paris-wien.png b/ressources/images/missions/eu-paris-wien.png new file mode 100644 index 0000000..2f1913c Binary files /dev/null and b/ressources/images/missions/eu-paris-wien.png differ diff --git a/ressources/images/missions/eu-paris-zagrab.png b/ressources/images/missions/eu-paris-zagrab.png new file mode 100644 index 0000000..328579b Binary files /dev/null and b/ressources/images/missions/eu-paris-zagrab.png differ diff --git a/ressources/images/missions/eu-riga-bucuresti.png b/ressources/images/missions/eu-riga-bucuresti.png new file mode 100644 index 0000000..1d73eef Binary files /dev/null and b/ressources/images/missions/eu-riga-bucuresti.png differ diff --git a/ressources/images/missions/eu-roma-smyrna.png b/ressources/images/missions/eu-roma-smyrna.png new file mode 100644 index 0000000..c679112 Binary files /dev/null and b/ressources/images/missions/eu-roma-smyrna.png differ diff --git a/ressources/images/missions/eu-rostov-erzurum.png b/ressources/images/missions/eu-rostov-erzurum.png new file mode 100644 index 0000000..bc2739b Binary files /dev/null and b/ressources/images/missions/eu-rostov-erzurum.png differ diff --git a/ressources/images/missions/eu-sarajevo-sevastopol.png b/ressources/images/missions/eu-sarajevo-sevastopol.png new file mode 100644 index 0000000..5d52dde Binary files /dev/null and b/ressources/images/missions/eu-sarajevo-sevastopol.png differ diff --git a/ressources/images/missions/eu-smolensk-rostov.png b/ressources/images/missions/eu-smolensk-rostov.png new file mode 100644 index 0000000..25a02d6 Binary files /dev/null and b/ressources/images/missions/eu-smolensk-rostov.png differ diff --git a/ressources/images/missions/eu-sofia-smyrna.png b/ressources/images/missions/eu-sofia-smyrna.png new file mode 100644 index 0000000..2a96201 Binary files /dev/null and b/ressources/images/missions/eu-sofia-smyrna.png differ diff --git a/ressources/images/missions/eu-stockholm-wien.png b/ressources/images/missions/eu-stockholm-wien.png new file mode 100644 index 0000000..0fa760e Binary files /dev/null and b/ressources/images/missions/eu-stockholm-wien.png differ diff --git a/ressources/images/missions/eu-venezia-constantinople.png b/ressources/images/missions/eu-venezia-constantinople.png new file mode 100644 index 0000000..01b00fd Binary files /dev/null and b/ressources/images/missions/eu-venezia-constantinople.png differ diff --git a/ressources/images/missions/eu-warszawa-smolensk.png b/ressources/images/missions/eu-warszawa-smolensk.png new file mode 100644 index 0000000..445b6c2 Binary files /dev/null and b/ressources/images/missions/eu-warszawa-smolensk.png differ diff --git a/ressources/images/missions/eu-zagrab-brindisi.png b/ressources/images/missions/eu-zagrab-brindisi.png new file mode 100644 index 0000000..0af0095 Binary files /dev/null and b/ressources/images/missions/eu-zagrab-brindisi.png differ diff --git a/ressources/images/missions/eu-zurich-brindisi.png b/ressources/images/missions/eu-zurich-brindisi.png new file mode 100644 index 0000000..858f291 Binary files /dev/null and b/ressources/images/missions/eu-zurich-brindisi.png differ diff --git a/ressources/images/missions/eu-zurich-budapest.png b/ressources/images/missions/eu-zurich-budapest.png new file mode 100644 index 0000000..a8a4afd Binary files /dev/null and b/ressources/images/missions/eu-zurich-budapest.png differ diff --git a/ressources/images/missions/eu_TicketBack.png b/ressources/images/missions/eu_TicketBack.png new file mode 100644 index 0000000..f17d34d Binary files /dev/null and b/ressources/images/missions/eu_TicketBack.png differ diff --git a/ressources/images/shop-boardgame-big-Europe.jpg b/ressources/images/shop-boardgame-big-Europe.jpg new file mode 100644 index 0000000..52c4939 Binary files /dev/null and b/ressources/images/shop-boardgame-big-Europe.jpg differ diff --git a/ressources/images/wagons/wagons-Blue.png b/ressources/images/wagons/wagons-Blue.png new file mode 100644 index 0000000..8f36b56 Binary files /dev/null and b/ressources/images/wagons/wagons-Blue.png differ diff --git a/ressources/images/wagons/wagons-Green.png b/ressources/images/wagons/wagons-Green.png new file mode 100644 index 0000000..01552ae Binary files /dev/null and b/ressources/images/wagons/wagons-Green.png differ diff --git a/ressources/images/wagons/wagons-Outline.png b/ressources/images/wagons/wagons-Outline.png new file mode 100644 index 0000000..6064649 Binary files /dev/null and b/ressources/images/wagons/wagons-Outline.png differ diff --git a/ressources/images/wagons/wagons-Purple.png b/ressources/images/wagons/wagons-Purple.png new file mode 100644 index 0000000..f775c5b Binary files /dev/null and b/ressources/images/wagons/wagons-Purple.png differ diff --git a/ressources/images/wagons/wagons-Red.png b/ressources/images/wagons/wagons-Red.png new file mode 100644 index 0000000..f5a439d Binary files /dev/null and b/ressources/images/wagons/wagons-Red.png differ diff --git a/ressources/images/wagons/wagons-Yellow.png b/ressources/images/wagons/wagons-Yellow.png new file mode 100644 index 0000000..e904174 Binary files /dev/null and b/ressources/images/wagons/wagons-Yellow.png differ diff --git a/ressources/images/wagons/wagons-shadows.png b/ressources/images/wagons/wagons-shadows.png new file mode 100644 index 0000000..e95ab17 Binary files /dev/null and b/ressources/images/wagons/wagons-shadows.png differ diff --git a/src/main/java/modele/CouleurWagon.java b/src/main/java/modele/CouleurWagon.java new file mode 100644 index 0000000..1f867d4 --- /dev/null +++ b/src/main/java/modele/CouleurWagon.java @@ -0,0 +1,77 @@ +package modele; + +import java.util.*; + +/** + * Représentation des couleurs du jeu utilisées pour les cartes wagon et les joueurs + */ +public enum CouleurWagon { + NOIR, BLANC, JAUNE, ROUGE, ORANGE, BLEU, VERT, ROSE, GRIS, LOCOMOTIVE; + + @Override + public String toString() { + return switch (this) { + case NOIR -> "Noir"; + case BLANC -> "Blanc"; + case JAUNE -> "Jaune"; + case ROUGE -> "Rouge"; + case ORANGE -> "Orange"; + case BLEU -> "Bleu"; + case VERT -> "Vert"; + case ROSE -> "Rose"; + case GRIS -> "Gris"; // représente une couleur indéterminée + case LOCOMOTIVE -> "Locomotive"; // peut remplacer n'importe quelle couleur + }; + } + + public String toLog() { + return String.format("%s", name(), name().toLowerCase(), this); + } + + /** + * Renvoie la liste des couleurs "simples" c'est-à-dire sans LOCOMOTIVE ni GRIS + */ + public static ArrayList getCouleursSimples() { + return new ArrayList<>(List.of(NOIR, BLANC, JAUNE, ROUGE, ORANGE, BLEU, VERT, ROSE)); + } + + /** + * Renvoie la représentation sous forme d'une chaîne de caractères d'une liste + * non ordonnée de couleurs. + * + * La chaîne est constituée du nom de chaque couleur qui apparaît dans la liste, + * suivie éventuellement d'une chaîne de la forme " x n" où n est le nombre de + * fois que la couleur apparaît dans la liste, si n > 1. Les couleurs sont + * séparées par des virgules. + * + * @param liste une liste de couleurs (considérée comme non ordonnée) + * @return une chaîne de caractères décrivant les éléments qui apparaissent dans + * la liste + */ + public static String listToString(List liste) { + StringJoiner joiner = new StringJoiner(", "); + for (CouleurWagon c : CouleurWagon.values()) { + int count = Collections.frequency(liste, c); + if (count == 1) { + joiner.add(c.toString()); + } else if (count > 1) { + joiner.add(c.toString() + " x" + count); + } + } + return joiner.toString(); + } + + public static String listToLog(List liste) { + StringJoiner joiner = new StringJoiner(", "); + for (CouleurWagon c : CouleurWagon.values()) { + int count = Collections.frequency(liste, c); + if (count == 1) { + joiner.add(c.toLog()); + } else if (count > 1) { + joiner.add(c.toLog() + " x" + count); + } + } + return joiner.toString(); + } + +} diff --git a/src/main/java/modele/Destination.java b/src/main/java/modele/Destination.java new file mode 100644 index 0000000..0accf53 --- /dev/null +++ b/src/main/java/modele/Destination.java @@ -0,0 +1,105 @@ +package modele; + +import java.util.ArrayList; +import java.util.HashMap; + +public class Destination { + /** + * Ville de départ + */ + private String ville1; + /** + * Ville d'arrivée + */ + private String ville2; + /** + * Nombre de points que vaut la destination + */ + private int valeur; + + public Destination(String ville1, String ville2, int valeur) { + this.ville1 = ville1; + this.ville2 = ville2; + this.valeur = valeur; + } + + + @Override + public String toString() { + return getNom(); + } + + public String getNom() { + return String.format("%s - %s (%d)", ville1, ville2, valeur); + } + + public Object asPOJO() { + HashMap data = new HashMap<>(); + data.put("ville1", ville1); + data.put("ville2", ville2); + data.put("valeur", valeur); + return data; + } + + /** + * @return une liste contenant toutes les destinations "normales" du jeu + */ + public static ArrayList makeDestinationsEurope() { + ArrayList destinations = new ArrayList<>(); + destinations.add(new Destination("Athina", "Angora", 5)); + destinations.add(new Destination("Budapest", "Sofia", 5)); + destinations.add(new Destination("Frankfurt", "Kobenhavn", 5)); + destinations.add(new Destination("Rostov", "Erzurum", 5)); + destinations.add(new Destination("Sofia", "Smyrna", 5)); + destinations.add(new Destination("Kyiv", "Petrograd", 6)); + destinations.add(new Destination("Zurich", "Brindisi", 6)); + destinations.add(new Destination("Zurich", "Budapest", 6)); + destinations.add(new Destination("Warszawa", "Smolensk", 6)); + destinations.add(new Destination("Zagrab", "Brindisi", 6)); + destinations.add(new Destination("Paris", "Zagrab", 7)); + destinations.add(new Destination("Brest", "Marseille", 7)); + destinations.add(new Destination("London", "Berlin", 7)); + destinations.add(new Destination("Edinburgh", "Paris", 7)); + destinations.add(new Destination("Amsterdam", "Pamplona", 7)); + destinations.add(new Destination("Roma", "Smyrna", 8)); + destinations.add(new Destination("Palermo", "Constantinople", 8)); + destinations.add(new Destination("Sarajevo", "Sevastopol", 8)); + destinations.add(new Destination("Madrid", "Dieppe", 8)); + destinations.add(new Destination("Barcelona", "Bruxelles", 8)); + destinations.add(new Destination("Paris", "Wien", 8)); + destinations.add(new Destination("Barcelona", "Munchen", 8)); + destinations.add(new Destination("Brest", "Venezia", 8)); + destinations.add(new Destination("Smolensk", "Rostov", 8)); + destinations.add(new Destination("Marseille", "Essen", 8)); + destinations.add(new Destination("Kyiv", "Sochi", 8)); + destinations.add(new Destination("Madrid", "Zurich", 8)); + destinations.add(new Destination("Berlin", "Bucuresti", 8)); + destinations.add(new Destination("Bruxelles", "Danzig", 9)); + destinations.add(new Destination("Berlin", "Roma", 9)); + destinations.add(new Destination("Angora", "Kharkov", 10)); + destinations.add(new Destination("Riga", "Bucuresti", 10)); + destinations.add(new Destination("Essen", "Kyiv", 10)); + destinations.add(new Destination("Venezia", "Constantinople", 10)); + destinations.add(new Destination("London", "Wien", 10)); + destinations.add(new Destination("Athina", "Wilno", 11)); + destinations.add(new Destination("Stockholm", "Wien", 11)); + destinations.add(new Destination("Berlin", "Moskva", 12)); + destinations.add(new Destination("Amsterdam", "Wilno", 12)); + destinations.add(new Destination("Frankfurt", "Smolensk", 13)); + return destinations; + } + + /** + * @return une liste contenant toutes les destinations "longues" du jeu + */ + public static ArrayList makeDestinationsLonguesEurope() { + ArrayList destinations = new ArrayList<>(); + destinations.add(new Destination("Lisboa", "Danzig", 20)); + destinations.add(new Destination("Brest", "Petrograd", 20)); + destinations.add(new Destination("Palermo", "Moskva", 20)); + destinations.add(new Destination("Kobenhavn", "Erzurum", 21)); + destinations.add(new Destination("Edinburgh", "Athina", 21)); + destinations.add(new Destination("Cadiz", "Stockholm", 21)); + return destinations; + } +} diff --git a/src/main/java/modele/Ferry.java b/src/main/java/modele/Ferry.java new file mode 100644 index 0000000..20c4ce7 --- /dev/null +++ b/src/main/java/modele/Ferry.java @@ -0,0 +1,20 @@ +package modele; + +public class Ferry extends Route { + /** + * Nombre de locomotives qu'un joueur doit payer pour capturer le ferry + */ + private int nbLocomotives; + + public Ferry(Ville ville1, Ville ville2, int longueur, CouleurWagon couleur, int nbLocomotives) { + super(ville1, ville2, longueur, couleur); + this.nbLocomotives = nbLocomotives; + } + + @Override + public String toString() { + return String.format("[%s - %s (%d, %s, %d)]", getVille1(), getVille2(), getLongueur(), getCouleur(), + nbLocomotives); + } + +} diff --git a/src/main/java/modele/Jeu.java b/src/main/java/modele/Jeu.java new file mode 100644 index 0000000..6413dee --- /dev/null +++ b/src/main/java/modele/Jeu.java @@ -0,0 +1,309 @@ +package modele; + +import com.google.gson.Gson; +import vue.GameServer; + +import java.util.*; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.stream.Collectors; + +public class Jeu implements Runnable { + /** + * Liste des joueurs + */ + private List joueurs; + + /** + * Le joueur dont c'est le tour + */ + private Joueur joueurCourant; + /** + * Liste des villes représentées sur le plateau de jeu + */ + private List villes; + /** + * Liste des routes du plateau de jeu + */ + private List routes; + /** + * Pile de pioche (face cachée) + */ + private List pileCartesWagon; + /** + * Cartes de la pioche face visible (normalement il y a 5 cartes face visible) + */ + private List cartesWagonVisibles; + /** + * Pile de cartes qui ont été défaussée au cours de la partie + */ + private List defausseCartesWagon; + /** + * Pile des cartes "Destination" (uniquement les destinations "courtes", les + * destinations "longues" sont distribuées au début de la partie et ne peuvent + * plus être piochées après) + */ + private List pileDestinations; + /** + * File d'attente des instructions recues par le serveur + */ + private BlockingQueue inputQueue; + /** + * Messages d'information du jeu + */ + private List log; + + public Jeu(String[] nomJoueurs) { + /* + * ATTENTION : Cette méthode est à réécrire. + * + * Le code indiqué ici est un squelette minimum pour que le jeu se lance et que + * l'interface graphique fonctionne. + * Vous devez modifier ce code pour que les différents éléments du jeu soient + * correctement initialisés. + */ + + // initialisation des entrées/sorties + inputQueue = new LinkedBlockingQueue<>(); + log = new ArrayList<>(); + + // création des cartes + pileCartesWagon = new ArrayList<>(); + cartesWagonVisibles = new ArrayList<>(); + defausseCartesWagon = new ArrayList<>(); + pileDestinations = new ArrayList<>(); + + // création des joueurs + ArrayList couleurs = new ArrayList<>(Arrays.asList(Joueur.Couleur.values())); + Collections.shuffle(couleurs); + joueurs = new ArrayList<>(); + for (String nom : nomJoueurs) { + Joueur joueur = new Joueur(nom, this, couleurs.remove(0)); + joueurs.add(joueur); + } + joueurCourant = joueurs.get(0); + + // création des villes et des routes + Plateau plateau = Plateau.makePlateauEurope(); + villes = plateau.getVilles(); + routes = plateau.getRoutes(); + } + + public List getPileCartesWagon() { + return pileCartesWagon; + } + + public List getCartesWagonVisibles() { + return cartesWagonVisibles; + } + + public List getVilles() { + return villes; + } + + public List getRoutes() { + return routes; + } + + public Joueur getJoueurCourant() { + return joueurCourant; + } + + /** + * Exécute la partie + */ + public void run() { + /* + * ATTENTION : Cette méthode est à réécrire. + * + * Cette méthode doit : + * - faire choisir à chaque joueur les destinations initiales qu'il souhaite + * garder : on pioche 3 destinations "courtes" et 1 destination "longue", puis + * le + * joueur peut choisir des destinations à défausser ou passer s'il ne veut plus + * en défausser. Il doit en garder au moins 2. + * - exécuter la boucle principale du jeu qui fait jouer le tour de chaque + * joueur à tour de rôle jusqu'à ce qu'un des joueurs n'ait plus que 2 wagons ou + * moins + * - exécuter encore un dernier tour de jeu pour chaque joueur après + */ + + /** + * Le code proposé ici n'est qu'un exemple d'utilisation des méthodes pour + * interagir avec l'utilisateur, il n'a rien à voir avec le code de la partie et + * doit donc être entièrement réécrit. + */ + + // Exemple d'utilisation + while (true) { + // le joueur doit choisir une valeur parmi "1", "2", "3", "4", "6" ou "8" + // les choix possibles sont présentés sous forme de boutons cliquables + String choix = joueurCourant.choisir( + "Choisissez une taille de route.", // instruction + new ArrayList<>(), // choix (hors boutons, ici aucun) + new ArrayList<>(Arrays.asList("1", "2", "3", "4", "6", "8")), // boutons + false); // le joueur ne peut pas passer (il doit faire un choix) + + // une fois la longueur choisie, on filtre les routes pour ne garder que les + // routes de la longueur choisie + int longueurRoute = Integer.parseInt(choix); + ArrayList routesPossibles = new ArrayList<>(); + for (Route route : routes) { + if (route.getLongueur() == longueurRoute) { + routesPossibles.add(route.getNom()); + } + } + + // le joueur doit maintenant choisir une route de la longueur choisie (les + // autres ne sont pas acceptées). Le joueur peut choisir de passer (aucun choix) + String choixRoute = joueurCourant.choisir( + "Choisissez une route de longueur " + longueurRoute, // instruction + routesPossibles, // choix (pas des boutons, il faut cliquer sur la carte) + new ArrayList<>(), // boutons (ici aucun bouton créé) + true); // le joueur peut passer sans faire de choix + if (choixRoute.equals("")) { + // le joueur n'a pas fait de choix (cliqué sur le bouton "passer") + log("Auncune route n'a été choisie"); + } else { + // le joueur a choisi une route + log("Vous avez choisi la route " + choixRoute); + } + } + } + + /** + * Ajoute une carte dans la pile de défausse. + * Dans le cas peu probable, où il y a moins de 5 cartes wagon face visibles + * (parce que la pioche + * et la défausse sont vides), alors il faut immédiatement rendre cette carte + * face visible. + * + * @param c carte à défausser + */ + public void defausserCarteWagon(CouleurWagon c) { + throw new RuntimeException("Méthode non implémentée !"); + } + + /** + * Pioche une carte de la pile de pioche + * Si la pile est vide, les cartes de la défausse sont replacées dans la pioche + * puis mélangées avant de piocher une carte + * + * @return la carte qui a été piochée (ou null si aucune carte disponible) + */ + public CouleurWagon piocherCarteWagon() { + throw new RuntimeException("Méthode non implémentée !"); + } + + /** + * Retire une carte wagon de la pile des cartes wagon visibles. + * Si une carte a été retirée, la pile de cartes wagons visibles est recomplétée + * (remise à 5, éventuellement remélangée si 3 locomotives visibles) + */ + public void retirerCarteWagonVisible(CouleurWagon c) { + throw new RuntimeException("Méthode non implémentée !"); + } + + /** + * Pioche et renvoie la destination du dessus de la pile de destinations. + * + * @return la destination qui a été piochée (ou `null` si aucune destination + * disponible) + */ + public Destination piocherDestination() { + throw new RuntimeException("Méthode non implémentée !"); + } + + public List getJoueurs() { + return joueurs; + } + + @Override + public String toString() { + StringJoiner joiner = new StringJoiner("\n"); + for (Joueur j : joueurs) { + joiner.add(j.toString()); + } + return joiner.toString(); + } + + /** + * Ajoute un message au log du jeu + */ + public void log(String message) { + log.add(message); + } + + /** + * Ajoute un message à la file d'entrées + */ + public void addInput(String message) { + inputQueue.add(message); + } + + /** + * Lit une ligne de l'entrée standard + * C'est cette méthode qui doit être appelée à chaque fois qu'on veut lire + * l'entrée clavier de l'utilisateur (par exemple dans {@code Player.choisir}) + * + * @return une chaîne de caractères correspondant à l'entrée suivante dans la + * file + */ + public String lireLigne() { + try { + return inputQueue.take(); + } catch (InterruptedException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Envoie l'état de la partie pour affichage aux joueurs avant de faire un choix + * + * @param instruction l'instruction qui est donnée au joueur + * @param boutons labels des choix proposés s'il y en a + * @param peutPasser indique si le joueur peut passer sans faire de choix + */ + public void prompt(String instruction, Collection boutons, boolean peutPasser) { + System.out.println(); + System.out.println(this); + if (boutons.isEmpty()) { + System.out.printf(">>> %s: %s <<<%n", joueurCourant.getNom(), instruction); + } else { + StringJoiner joiner = new StringJoiner(" / "); + for (String bouton : boutons) { + joiner.add(bouton); + } + System.out.printf(">>> %s: %s [%s] <<<%n", joueurCourant.getNom(), instruction, joiner); + } + + Map data = Map.ofEntries( + new AbstractMap.SimpleEntry("prompt", Map.ofEntries( + new AbstractMap.SimpleEntry("instruction", instruction), + new AbstractMap.SimpleEntry("boutons", boutons), + new AbstractMap.SimpleEntry("nomJoueurCourant", getJoueurCourant().getNom()), + new AbstractMap.SimpleEntry("peutPasser", peutPasser))), + new AbstractMap.SimpleEntry<>("villes", + villes.stream().map(Ville::asPOJO).collect(Collectors.toList())), + new AbstractMap.SimpleEntry<>("routes", + routes.stream().map(Route::asPOJO).collect(Collectors.toList())), + new AbstractMap.SimpleEntry("joueurs", + joueurs.stream().map(Joueur::asPOJO).collect(Collectors.toList())), + new AbstractMap.SimpleEntry("piles", Map.ofEntries( + new AbstractMap.SimpleEntry("pileCartesWagon", pileCartesWagon.size()), + new AbstractMap.SimpleEntry("pileDestinations", pileDestinations.size()), + new AbstractMap.SimpleEntry("defausseCartesWagon", defausseCartesWagon), + new AbstractMap.SimpleEntry("cartesWagonVisibles", cartesWagonVisibles))), + new AbstractMap.SimpleEntry("log", log)); + GameServer.setEtatJeu(new Gson().toJson(data)); + } + + public List getDefausseCartesWagon() { + return defausseCartesWagon; + } + + public List getPileDestinations() { + return null; + } +} diff --git a/src/main/java/modele/Joueur.java b/src/main/java/modele/Joueur.java new file mode 100644 index 0000000..9ab923d --- /dev/null +++ b/src/main/java/modele/Joueur.java @@ -0,0 +1,269 @@ +package modele; + +import java.util.*; +import java.util.stream.Collectors; + +public class Joueur { + + public int getNbGares() { + return 0; + } + + public int getScore() { + return 0; + } + + /** + * Les couleurs possibles pour les joueurs (pour l'interface graphique) + */ + public static enum Couleur { + JAUNE, ROUGE, BLEU, VERT, ROSE; + } + + /** + * Jeu auquel le joueur est rattaché + */ + private Jeu jeu; + /** + * Nom du joueur + */ + private String nom; + /** + * CouleurWagon du joueur (pour représentation sur le plateau) + */ + private Couleur couleur; + /** + * Nombre de gares que le joueur peut encore poser sur le plateau + */ + private int nbGares; + /** + * Nombre de wagons que le joueur peut encore poser sur le plateau + */ + private int nbWagons; + /** + * Liste des missions à réaliser pendant la partie + */ + private List destinations; + /** + * Liste des cartes que le joueur a en main + */ + private List cartesWagon; + /** + * Liste temporaire de cartes wagon que le joueur est en train de jouer pour + * payer la capture d'une route ou la construction d'une gare + */ + private List cartesWagonPosees; + /** + * Score courant du joueur (somme des valeurs des routes capturées) + */ + private int score; + + public Joueur(String nom, Jeu jeu, Joueur.Couleur couleur) { + this.nom = nom; + this.jeu = jeu; + this.couleur = couleur; + nbGares = 3; + nbWagons = 45; + cartesWagon = new ArrayList<>(); + cartesWagonPosees = new ArrayList<>(); + destinations = new ArrayList<>(); + score = 12; // chaque gare non utilisée vaut 4 points + } + + public String getNom() { + return nom; + } + + public Couleur getCouleur() { + return couleur; + } + + public int getNbWagons() { + return nbWagons; + } + + public Jeu getJeu() { + return jeu; + } + + public List getCartesWagonPosees() { + return cartesWagonPosees; + } + + public List getCartesWagon() { + return cartesWagon; + } + + public List getDestinations() { + return destinations; + } + + /** + * Attend une entrée de la part du joueur (au clavier ou sur la websocket) et + * renvoie le choix du joueur. + *

+ * Cette méthode lit les entrées du jeu ({@code Jeu.lireligne()}) jusqu'à ce + * qu'un choix valide (un élément de {@code choix} ou de {@code boutons} ou + * éventuellement la chaîne vide si l'utilisateur est autorisé à passer) soit + * reçu. + * Lorsqu'un choix valide est obtenu, il est renvoyé par la fonction. + *

+ * Si l'ensemble des choix valides ({@code choix} + {@code boutons}) ne comporte + * qu'un seul élément et que {@code canPass} est faux, l'unique choix valide est + * automatiquement renvoyé sans lire l'entrée de l'utilisateur. + *

+ * Si l'ensemble des choix est vide, la chaîne vide ("") est automatiquement + * renvoyée par la méthode (indépendamment de la valeur de {@code canPass}). + *

+ * Exemple d'utilisation pour demander à un joueur de répondre à une question + * par "oui" ou "non" : + *

+ * {@code + * List choix = Arrays.asList("Oui", "Non"); + * String input = choisir("Voulez vous faire ceci ?", choix, new ArrayList<>(), false); + * } + *

+ *

+ * Si par contre on voulait proposer les réponses à l'aide de boutons, on + * pourrait utiliser : + *

+ * {@code + * List boutons = Arrays.asList("1", "2", "3"); + * String input = choisir("Choisissez un nombre.", new ArrayList<>(), boutons, false); + * } + * + * @param instruction message à afficher à l'écran pour indiquer au joueur la + * nature du choix qui est attendu + * @param choix une collection de chaînes de caractères correspondant aux + * choix valides attendus du joueur + * @param boutons une collection de chaînes de caractères correspondant aux + * choix valides attendus du joueur qui doivent être + * représentés par des boutons sur l'interface graphique. + * @param peutPasser booléen indiquant si le joueur a le droit de passer sans + * faire de choix. S'il est autorisé à passer, c'est la + * chaîne de caractères vide ("") qui signifie qu'il désire + * passer. + * @return le choix de l'utilisateur (un élément de {@code choix}, ou de + * {@code boutons} ou la chaîne vide) + */ + public String choisir(String instruction, Collection choix, Collection boutons, + boolean peutPasser) { + // on retire les doublons de la liste des choix + HashSet choixDistincts = new HashSet<>(); + choixDistincts.addAll(choix); + choixDistincts.addAll(boutons); + + // Aucun choix disponible + if (choixDistincts.isEmpty()) { + return ""; + } else { + // Un seul choix possible (renvoyer cet unique élément) + if (choixDistincts.size() == 1 && !peutPasser) + return choixDistincts.iterator().next(); + else { + String entree; + // Lit l'entrée de l'utilisateur jusqu'à obtenir un choix valide + while (true) { + jeu.prompt(instruction, boutons, peutPasser); + entree = jeu.lireLigne(); + // si une réponse valide est obtenue, elle est renvoyée + if (choixDistincts.contains(entree) || (peutPasser && entree.equals(""))) + return entree; + } + } + } + } + + /** + * Affiche un message dans le log du jeu (visible sur l'interface graphique) + * + * @param message le message à afficher (peut contenir des balises html pour la + * mise en forme) + */ + public void log(String message) { + jeu.log(message); + } + + @Override + public String toString() { + StringJoiner joiner = new StringJoiner("\n"); + joiner.add(String.format("=== %s (%d pts) ===", nom, score)); + joiner.add(String.format(" Gares: %d, Wagons: %d", nbGares, nbWagons)); + joiner.add(" Destinations: " + + destinations.stream().map(Destination::toString).collect(Collectors.joining(", "))); + joiner.add(" Cartes wagon: " + CouleurWagon.listToString(cartesWagon)); + return joiner.toString(); + } + + /** + * @return une chaîne de caractères contenant le nom du joueur, avec des balises + * HTML pour être mis en forme dans le log + */ + public String toLog() { + return String.format("%s", nom); + } + + /** + * Renvoie une représentation du joueur sous la forme d'un objet Java simple + * (POJO) + */ + public Object asPOJO() { + HashMap data = new HashMap<>(); + data.put("nom", nom); + data.put("couleur", couleur); + data.put("score", score); + data.put("nbGares", nbGares); + data.put("nbWagons", nbWagons); + data.put("estJoueurCourant", this == jeu.getJoueurCourant()); + data.put("destinations", destinations.stream().map(Destination::asPOJO).collect(Collectors.toList())); + data.put("cartesWagon", cartesWagon.stream().sorted().map(CouleurWagon::name).collect(Collectors.toList())); + data.put("cartesWagonPosees", + cartesWagonPosees.stream().sorted().map(CouleurWagon::name).collect(Collectors.toList())); + return data; + } + + /** + * Propose une liste de cartes destinations, parmi lesquelles le joueur doit en + * garder un nombre minimum n. + *

+ * Tant que le nombre de destinations proposées est strictement supérieur à n, + * le joueur peut choisir une des destinations qu'il retire de la liste des + * choix, ou passer (en renvoyant la chaîne de caractères vide). + *

+ * Les destinations qui ne sont pas écartées sont ajoutées à la liste des + * destinations du joueur. Les destinations écartées sont renvoyées par la + * fonction. + * + * @param destinationsPossibles liste de destinations proposées parmi lesquelles + * le joueur peut choisir d'en écarter certaines + * @param n nombre minimum de destinations que le joueur + * doit garder + * @return liste des destinations qui n'ont pas été gardées par le joueur + */ + public List choisirDestinations(List destinationsPossibles, int n) { + throw new RuntimeException("Méthode non implémentée !"); + } + + /** + * Exécute un tour de jeu du joueur. + *

+ * Cette méthode attend que le joueur choisisse une des options suivantes : + * - le nom d'une carte wagon face visible à prendre ; + * - le nom "GRIS" pour piocher une carte wagon face cachée s'il reste des + * cartes à piocher dans la pile de pioche ou dans la pile de défausse ; + * - la chaîne "destinations" pour piocher des cartes destination ; + * - le nom d'une ville sur laquelle il peut construire une gare (ville non + * prise par un autre joueur, le joueur a encore des gares en réserve et assez + * de cartes wagon pour construire la gare) ; + * - le nom d'une route que le joueur peut capturer (pas déjà capturée, assez de + * wagons et assez de cartes wagon) ; + * - la chaîne de caractères vide pour passer son tour + *

+ * Lorsqu'un choix valide est reçu, l'action est exécutée (il est possible que + * l'action nécessite d'autres choix de la part de l'utilisateur, comme "choisir les cartes wagon à défausser pour capturer une route" ou + * "construire une gare", "choisir les destinations à défausser", etc.) + */ + public void jouerTour() { + throw new RuntimeException("Méthode non implémentée !"); + } +} diff --git a/src/main/java/modele/Plateau.java b/src/main/java/modele/Plateau.java new file mode 100644 index 0000000..0d04d8f --- /dev/null +++ b/src/main/java/modele/Plateau.java @@ -0,0 +1,197 @@ +package modele; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Plateau { + /** + * Liste des villes + */ + private final List villes; + /** + * Liste des routes + */ + private final List routes; + + public Plateau(List villes, List routes) { + this.villes = villes; + this.routes = routes; + } + + public List getVilles() { + return villes; + } + + public List getRoutes() { + return routes; + } + + static public Plateau makePlateauEurope() { + Map villes = new HashMap<>(); + villes.put("amsterdam", new Ville("Amsterdam")); + villes.put("angora", new Ville("Angora")); + villes.put("athina", new Ville("Athina")); + villes.put("barcelona", new Ville("Barcelona")); + villes.put("berlin", new Ville("Berlin")); + villes.put("brest", new Ville("Brest")); + villes.put("brindisi", new Ville("Brindisi")); + villes.put("bruxelles", new Ville("Bruxelles")); + villes.put("bucuresti", new Ville("Bucuresti")); + villes.put("budapest", new Ville("Budapest")); + villes.put("cadiz", new Ville("Cadiz")); + villes.put("constantinople", new Ville("Constantinople")); + villes.put("danzig", new Ville("Danzig")); + villes.put("dieppe", new Ville("Dieppe")); + villes.put("edinburgh", new Ville("Edinburgh")); + villes.put("erzurum", new Ville("Erzurum")); + villes.put("essen", new Ville("Essen")); + villes.put("frankfurt", new Ville("Frankfurt")); + villes.put("kharkov", new Ville("Kharkov")); + villes.put("kobenhavn", new Ville("Kobenhavn")); + villes.put("kyiv", new Ville("Kyiv")); + villes.put("lisboa", new Ville("Lisboa")); + villes.put("london", new Ville("London")); + villes.put("madrid", new Ville("Madrid")); + villes.put("marseille", new Ville("Marseille")); + villes.put("moskva", new Ville("Moskva")); + villes.put("munchen", new Ville("Munchen")); + villes.put("palermo", new Ville("Palermo")); + villes.put("pamplona", new Ville("Pamplona")); + villes.put("paris", new Ville("Paris")); + villes.put("petrograd", new Ville("Petrograd")); + villes.put("riga", new Ville("Riga")); + villes.put("roma", new Ville("Roma")); + villes.put("rostov", new Ville("Rostov")); + villes.put("sarajevo", new Ville("Sarajevo")); + villes.put("sevastopol", new Ville("Sevastopol")); + villes.put("smolensk", new Ville("Smolensk")); + villes.put("smyrna", new Ville("Smyrna")); + villes.put("sochi", new Ville("Sochi")); + villes.put("sofia", new Ville("Sofia")); + villes.put("stockholm", new Ville("Stockholm")); + villes.put("venezia", new Ville("Venezia")); + villes.put("warszawa", new Ville("Warszawa")); + villes.put("wien", new Ville("Wien")); + villes.put("wilno", new Ville("Wilno")); + villes.put("zagrab", new Ville("Zagrab")); + villes.put("zurich", new Ville("Zurich")); + + ArrayList routes = new ArrayList<>(); + routes.add(new Route(villes.get("amsterdam"), villes.get("bruxelles"), 1, CouleurWagon.NOIR)); + routes.add(new Route(villes.get("amsterdam"), villes.get("essen"), 3, CouleurWagon.JAUNE)); + routes.add(new Route(villes.get("amsterdam"), villes.get("frankfurt"), 2, CouleurWagon.BLANC)); + routes.add(new Ferry(villes.get("amsterdam"), villes.get("london"), 2, CouleurWagon.GRIS, 2)); + routes.add(new Tunnel(villes.get("angora"), villes.get("constantinople"), 2, CouleurWagon.GRIS)); + routes.add(new Route(villes.get("angora"), villes.get("erzurum"), 3, CouleurWagon.NOIR)); + routes.add(new Tunnel(villes.get("angora"), villes.get("smyrna"), 3, CouleurWagon.ORANGE)); + routes.add(new Ferry(villes.get("athina"), villes.get("brindisi"), 4, CouleurWagon.GRIS, 1)); + routes.add(new Route(villes.get("athina"), villes.get("sarajevo"), 4, CouleurWagon.VERT)); + routes.add(new Ferry(villes.get("athina"), villes.get("smyrna"), 2, CouleurWagon.GRIS, 1)); + routes.add(new Route(villes.get("athina"), villes.get("sofia"), 3, CouleurWagon.ROSE)); + routes.add(new Route(villes.get("barcelona"), villes.get("madrid"), 2, CouleurWagon.JAUNE)); + routes.add(new Route(villes.get("barcelona"), villes.get("marseille"), 4, CouleurWagon.GRIS)); + routes.add(new Tunnel(villes.get("barcelona"), villes.get("pamplona"), 2, CouleurWagon.GRIS)); + routes.add(new Route(villes.get("berlin"), villes.get("danzig"), 4, CouleurWagon.GRIS)); + routes.add(new Route(villes.get("berlin"), villes.get("essen"), 2, CouleurWagon.BLEU)); + routes.add(new Route(villes.get("berlin"), villes.get("frankfurt"), 3, CouleurWagon.ROUGE)); + routes.add(new Route(villes.get("berlin"), villes.get("frankfurt"), 3, CouleurWagon.NOIR)); + routes.add(new Route(villes.get("berlin"), villes.get("warszawa"), 4, CouleurWagon.JAUNE)); + routes.add(new Route(villes.get("berlin"), villes.get("warszawa"), 4, CouleurWagon.ROSE)); + routes.add(new Route(villes.get("berlin"), villes.get("wien"), 3, CouleurWagon.VERT)); + routes.add(new Route(villes.get("brest"), villes.get("dieppe"), 2, CouleurWagon.ORANGE)); + routes.add(new Route(villes.get("brest"), villes.get("pamplona"), 4, CouleurWagon.ROSE)); + routes.add(new Route(villes.get("brest"), villes.get("paris"), 3, CouleurWagon.NOIR)); + routes.add(new Ferry(villes.get("brindisi"), villes.get("palermo"), 3, CouleurWagon.GRIS, 1)); + routes.add(new Route(villes.get("brindisi"), villes.get("roma"), 2, CouleurWagon.BLANC)); + routes.add(new Route(villes.get("bruxelles"), villes.get("dieppe"), 2, CouleurWagon.VERT)); + routes.add(new Route(villes.get("bruxelles"), villes.get("frankfurt"), 2, CouleurWagon.BLEU)); + routes.add(new Route(villes.get("bruxelles"), villes.get("paris"), 2, CouleurWagon.JAUNE)); + routes.add(new Route(villes.get("bruxelles"), villes.get("paris"), 2, CouleurWagon.ROUGE)); + routes.add(new Tunnel(villes.get("bucuresti"), villes.get("budapest"), 4, CouleurWagon.GRIS)); + routes.add(new Route(villes.get("bucuresti"), villes.get("constantinople"), 3, CouleurWagon.JAUNE)); + routes.add(new Route(villes.get("bucuresti"), villes.get("kyiv"), 4, CouleurWagon.GRIS)); + routes.add(new Route(villes.get("bucuresti"), villes.get("sevastopol"), 4, CouleurWagon.BLANC)); + routes.add(new Tunnel(villes.get("bucuresti"), villes.get("sofia"), 2, CouleurWagon.GRIS)); + routes.add(new Tunnel(villes.get("budapest"), villes.get("kyiv"), 6, CouleurWagon.GRIS)); + routes.add(new Route(villes.get("budapest"), villes.get("sarajevo"), 3, CouleurWagon.ROSE)); + routes.add(new Route(villes.get("budapest"), villes.get("wien"), 1, CouleurWagon.ROUGE)); + routes.add(new Route(villes.get("budapest"), villes.get("wien"), 1, CouleurWagon.BLANC)); + routes.add(new Route(villes.get("budapest"), villes.get("zagrab"), 2, CouleurWagon.ORANGE)); + routes.add(new Route(villes.get("cadiz"), villes.get("lisboa"), 2, CouleurWagon.BLEU)); + routes.add(new Route(villes.get("cadiz"), villes.get("madrid"), 3, CouleurWagon.ORANGE)); + routes.add(new Ferry(villes.get("constantinople"), villes.get("sevastopol"), 4, CouleurWagon.GRIS, 2)); + routes.add(new Tunnel(villes.get("constantinople"), villes.get("smyrna"), 2, CouleurWagon.GRIS)); + routes.add(new Route(villes.get("constantinople"), villes.get("sofia"), 3, CouleurWagon.BLEU)); + routes.add(new Route(villes.get("danzig"), villes.get("riga"), 3, CouleurWagon.NOIR)); + routes.add(new Route(villes.get("danzig"), villes.get("warszawa"), 2, CouleurWagon.GRIS)); + routes.add(new Ferry(villes.get("dieppe"), villes.get("london"), 2, CouleurWagon.GRIS, 1)); + routes.add(new Ferry(villes.get("dieppe"), villes.get("london"), 2, CouleurWagon.GRIS, 1)); + routes.add(new Route(villes.get("dieppe"), villes.get("paris"), 1, CouleurWagon.ROSE)); + routes.add(new Route(villes.get("edinburgh"), villes.get("london"), 4, CouleurWagon.ORANGE)); + routes.add(new Route(villes.get("edinburgh"), villes.get("london"), 4, CouleurWagon.NOIR)); + routes.add(new Ferry(villes.get("erzurum"), villes.get("sevastopol"), 4, CouleurWagon.GRIS, 2)); + routes.add(new Tunnel(villes.get("erzurum"), villes.get("sochi"), 3, CouleurWagon.ROUGE)); + routes.add(new Route(villes.get("essen"), villes.get("frankfurt"), 2, CouleurWagon.VERT)); + routes.add(new Ferry(villes.get("essen"), villes.get("kobenhavn"), 3, CouleurWagon.GRIS, 1)); + routes.add(new Ferry(villes.get("essen"), villes.get("kobenhavn"), 3, CouleurWagon.GRIS, 1)); + routes.add(new Route(villes.get("frankfurt"), villes.get("munchen"), 2, CouleurWagon.ROSE)); + routes.add(new Route(villes.get("frankfurt"), villes.get("paris"), 3, CouleurWagon.ORANGE)); + routes.add(new Route(villes.get("frankfurt"), villes.get("paris"), 3, CouleurWagon.BLANC)); + routes.add(new Route(villes.get("kharkov"), villes.get("kyiv"), 4, CouleurWagon.GRIS)); + routes.add(new Route(villes.get("kharkov"), villes.get("moskva"), 4, CouleurWagon.GRIS)); + routes.add(new Route(villes.get("kharkov"), villes.get("rostov"), 2, CouleurWagon.VERT)); + routes.add(new Route(villes.get("kobenhavn"), villes.get("stockholm"), 3, CouleurWagon.JAUNE)); + routes.add(new Route(villes.get("kobenhavn"), villes.get("stockholm"), 3, CouleurWagon.BLANC)); + routes.add(new Route(villes.get("kyiv"), villes.get("smolensk"), 3, CouleurWagon.ROUGE)); + routes.add(new Route(villes.get("kyiv"), villes.get("warszawa"), 4, CouleurWagon.GRIS)); + routes.add(new Route(villes.get("kyiv"), villes.get("wilno"), 2, CouleurWagon.GRIS)); + routes.add(new Route(villes.get("lisboa"), villes.get("madrid"), 3, CouleurWagon.ROSE)); + routes.add(new Tunnel(villes.get("madrid"), villes.get("pamplona"), 3, CouleurWagon.BLANC)); + routes.add(new Tunnel(villes.get("madrid"), villes.get("pamplona"), 3, CouleurWagon.NOIR)); + routes.add(new Route(villes.get("marseille"), villes.get("pamplona"), 4, CouleurWagon.ROUGE)); + routes.add(new Route(villes.get("marseille"), villes.get("paris"), 4, CouleurWagon.GRIS)); + routes.add(new Tunnel(villes.get("marseille"), villes.get("roma"), 4, CouleurWagon.GRIS)); + routes.add(new Tunnel(villes.get("marseille"), villes.get("zurich"), 2, CouleurWagon.ROSE)); + routes.add(new Route(villes.get("moskva"), villes.get("petrograd"), 4, CouleurWagon.BLANC)); + routes.add(new Route(villes.get("moskva"), villes.get("smolensk"), 2, CouleurWagon.ORANGE)); + routes.add(new Tunnel(villes.get("munchen"), villes.get("venezia"), 2, CouleurWagon.BLEU)); + routes.add(new Route(villes.get("munchen"), villes.get("wien"), 3, CouleurWagon.ORANGE)); + routes.add(new Tunnel(villes.get("munchen"), villes.get("zurich"), 2, CouleurWagon.JAUNE)); + routes.add(new Ferry(villes.get("palermo"), villes.get("roma"), 4, CouleurWagon.GRIS, 1)); + routes.add(new Ferry(villes.get("palermo"), villes.get("smyrna"), 6, CouleurWagon.GRIS, 2)); + routes.add(new Route(villes.get("pamplona"), villes.get("paris"), 4, CouleurWagon.BLEU)); + routes.add(new Route(villes.get("pamplona"), villes.get("paris"), 4, CouleurWagon.VERT)); + routes.add(new Tunnel(villes.get("paris"), villes.get("zurich"), 3, CouleurWagon.GRIS)); + routes.add(new Route(villes.get("petrograd"), villes.get("riga"), 4, CouleurWagon.GRIS)); + routes.add(new Tunnel(villes.get("petrograd"), villes.get("stockholm"), 8, CouleurWagon.GRIS)); + routes.add(new Route(villes.get("petrograd"), villes.get("wilno"), 4, CouleurWagon.BLEU)); + routes.add(new Route(villes.get("riga"), villes.get("wilno"), 4, CouleurWagon.VERT)); + routes.add(new Route(villes.get("roma"), villes.get("venezia"), 2, CouleurWagon.NOIR)); + routes.add(new Route(villes.get("rostov"), villes.get("sevastopol"), 4, CouleurWagon.GRIS)); + routes.add(new Route(villes.get("rostov"), villes.get("sochi"), 2, CouleurWagon.GRIS)); + routes.add(new Tunnel(villes.get("sarajevo"), villes.get("sofia"), 2, CouleurWagon.GRIS)); + routes.add(new Route(villes.get("sarajevo"), villes.get("zagrab"), 3, CouleurWagon.ROUGE)); + routes.add(new Ferry(villes.get("sevastopol"), villes.get("sochi"), 2, CouleurWagon.GRIS, 1)); + routes.add(new Route(villes.get("smolensk"), villes.get("wilno"), 3, CouleurWagon.JAUNE)); + routes.add(new Route(villes.get("venezia"), villes.get("zagrab"), 2, CouleurWagon.GRIS)); + routes.add(new Tunnel(villes.get("venezia"), villes.get("zurich"), 2, CouleurWagon.VERT)); + routes.add(new Route(villes.get("warszawa"), villes.get("wien"), 4, CouleurWagon.BLEU)); + routes.add(new Route(villes.get("warszawa"), villes.get("wilno"), 3, CouleurWagon.ROUGE)); + routes.add(new Route(villes.get("wien"), villes.get("zagrab"), 2, CouleurWagon.GRIS)); + + // Correction du nom pour les routes doubles + for (int i = 0; i < routes.size(); i++) { + Route r1 = routes.get(i); + if (i < routes.size() - 1) { + Route r2 = routes.get(i + 1); + if (r1.getNom().equals(r2.getNom())) { + r1.setNom(r1.getNom() + "(1)"); + r2.setNom(r2.getNom() + "(2)"); + } + } + } + return new Plateau(new ArrayList<>(villes.values()), routes); + } +} diff --git a/src/main/java/modele/Route.java b/src/main/java/modele/Route.java new file mode 100644 index 0000000..6a02c51 --- /dev/null +++ b/src/main/java/modele/Route.java @@ -0,0 +1,93 @@ +package modele; + +import java.util.HashMap; + +public class Route { + /** + * Première extrémité + */ + private Ville ville1; + /** + * Deuxième extrémité + */ + private Ville ville2; + /** + * Nombre de segments + */ + private int longueur; + /** + * CouleurWagon pour capturer la route (éventuellement GRIS, mais pas LOCOMOTIVE) + */ + private CouleurWagon couleur; + /** + * Joueur qui a capturé la route (`null` si la route est encore à prendre) + */ + private Joueur proprietaire; + /** + * Nom unique de la route. Ce nom est nécessaire pour résoudre l'ambiguïté entre les routes doubles + * (voir la classe Plateau pour plus de clarté) + */ + private String nom; + + public Route(Ville ville1, Ville ville2, int longueur, CouleurWagon couleur) { + this.ville1 = ville1; + this.ville2 = ville2; + this.longueur = longueur; + this.couleur = couleur; + nom = ville1.getNom() + " - " + ville2.getNom(); + proprietaire = null; + } + + public Ville getVille1() { + return ville1; + } + + public Ville getVille2() { + return ville2; + } + + public int getLongueur() { + return longueur; + } + + public CouleurWagon getCouleur() { + return couleur; + } + + public Joueur getProprietaire() { + return proprietaire; + } + + public void setProprietaire(Joueur proprietaire) { + this.proprietaire = proprietaire; + } + + public String getNom() { + return nom; + } + + public void setNom(String nom) { + this.nom = nom; + } + + public String toLog() { + return String.format("%s - %s", ville1.getNom(), ville2.getNom()); + } + + @Override + public String toString() { + return String.format("[%s - %s (%d, %s)]", ville1, ville2, longueur, couleur); + } + + /** + * @return un objet simple représentant les informations de la route + */ + public Object asPOJO() { + HashMap data = new HashMap<>(); + data.put("nom", getNom()); + if (proprietaire != null) { + data.put("proprietaire", proprietaire.getCouleur()); + } + return data; + } +} diff --git a/src/main/java/modele/Tunnel.java b/src/main/java/modele/Tunnel.java new file mode 100644 index 0000000..619c829 --- /dev/null +++ b/src/main/java/modele/Tunnel.java @@ -0,0 +1,13 @@ +package modele; + +public class Tunnel extends Route { + public Tunnel(Ville ville1, Ville ville2, int longueur, CouleurWagon couleur) { + super(ville1, ville2, longueur, couleur); + } + + @Override + public String toString() { + return "[" + super.toString() + "]"; + } + +} diff --git a/src/main/java/modele/Ville.java b/src/main/java/modele/Ville.java new file mode 100644 index 0000000..6788359 --- /dev/null +++ b/src/main/java/modele/Ville.java @@ -0,0 +1,48 @@ +package modele; + +import java.util.HashMap; + +public class Ville { + /** + * Nom complet de la ville + */ + private String nom; + /** + * Joueur qui a construit une gare sur la ville (ou `null` si pas de gare) + */ + private Joueur proprietaire; + + public Ville(String nom) { + this.nom = nom; + } + + public String getNom() { + return nom; + } + + public Joueur getProprietaire() { + return proprietaire; + } + + public void setProprietaire(Joueur proprietaire) { + this.proprietaire = proprietaire; + } + + @Override + public String toString() { + return nom; + } + + public String toLog() { + return String.format("%s", nom); + } + + public Object asPOJO() { + HashMap data = new HashMap<>(); + data.put("nom", nom); + if (proprietaire != null) { + data.put("proprietaire", proprietaire.getCouleur()); + } + return data; + } +} diff --git a/src/main/java/vue/GameServer.java b/src/main/java/vue/GameServer.java new file mode 100644 index 0000000..c5d7dcf --- /dev/null +++ b/src/main/java/vue/GameServer.java @@ -0,0 +1,98 @@ +package vue; + +import modele.Jeu; +import org.glassfish.tyrus.server.Server; + +import javax.websocket.DeploymentException; +import javax.websocket.Session; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Scanner; + +public class GameServer { + /** + * Liste des clients connectés au serveur + */ + private static ArrayList clients = new ArrayList<>(); + /** + * Description de l'état du jeu, envoyé aux clients pour la mise à jour de l'interface graphique + */ + private static String etatJeu = ""; + /** + * Instance de jeu exécutée par le serveur + */ + private static Jeu jeu; + + public static void main(String[] args) { + // Lancement de la partie + jeu = new Jeu(new String[]{"Guybrush", "Largo", "LeChuck", "Elaine"}); + + // Prépare le serveur websocket + Server server = new Server("localhost", 3232, "/", WebSocketClient.class); + + try (Scanner scanner = new Scanner(System.in)) { + server.start(); // lance le serveur + new Thread(jeu).start(); // démarre le jeu (exécute la méthode Jeu.run() dans un nouveau thread) + + while (true) { + jeu.addInput(scanner.nextLine()); + } + } catch (DeploymentException e) { + throw new RuntimeException(e); + } finally { + server.stop(); + } + } + + /** + * Ajoute une nouvelle instruction à la file d'instructions + * (cette méthode est appelée lorsqu'un message est reçue sur la websocket) + * + * @param message l'instruction à ajouter + */ + public static void addInput(String message) { + jeu.addInput(message); + } + + /** + * Met à jour l'état de la partie, et envoie le nouvel état à tous les clients connectés + * + * @param etatJeu l'état de la partie + */ + public static void setEtatJeu(String etatJeu) { + GameServer.etatJeu = etatJeu; + // Envoie l'état de la partie à tous les clients + try { + for (Session session : clients) { + session.getBasicRemote().sendText(etatJeu); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Ajoute un nouveau client à la liste, et lui transmet l'état actuel de la partie + * (cette méthode est appelée lorsqu'une nouvelle connexion est établie) + * + * @param session la session du nouveau client + */ + public static void addClient(Session session) { + GameServer.clients.add(session); + try { + session.getBasicRemote().sendText(etatJeu); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Retire un client de la liste + * (cette méthode est appelée lorsqu'une connexion est fermée) + * + * @param session la session du client à retirer + */ + public static void removeClient(Session session) { + GameServer.clients.remove(session); + } +} diff --git a/src/main/java/vue/WebSocketClient.java b/src/main/java/vue/WebSocketClient.java new file mode 100644 index 0000000..defe15e --- /dev/null +++ b/src/main/java/vue/WebSocketClient.java @@ -0,0 +1,28 @@ +package vue; + +import javax.websocket.*; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/") +public class WebSocketClient { + @OnOpen + public void onOpen(Session session) { + GameServer.addClient(session); + } + + @OnMessage + public void onMessage(String message, Session session) { + GameServer.addInput(message); + } + + @OnClose + public void onClose(Session session) { + GameServer.removeClient(session); + } + + @OnError + public void onError(Throwable exception, Session session) { + exception.printStackTrace(); + System.err.println("Error for client: " + session.getId()); + } +} \ No newline at end of file diff --git a/src/test/java/modele/IOJeu.java b/src/test/java/modele/IOJeu.java new file mode 100644 index 0000000..9ef5666 --- /dev/null +++ b/src/test/java/modele/IOJeu.java @@ -0,0 +1,38 @@ +package modele; + +import modele.Jeu; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class IOJeu extends Jeu { + /** + * Liste contenant les instructions à lire (qui remplacent les entrées au clavier) + */ + private List instructions; + + /** + * Constructeur, qui reprend exactement le constructeur de Game + */ + public IOJeu(String[] nomJoueurs) { + super(nomJoueurs); + this.instructions = new ArrayList<>(); + } + + /** + * Lit et renvoie une instruction dans la liste + */ + public String lireLigne() { + return instructions.remove(0); + } + + /** + * Fixe la liste d'instructions du jeu. + * + * @param args liste de chaînes de caractères. Chaque élément est une instruction (sans '\n' à la fin) + */ + public void setInput(String... args) { + instructions.clear(); + Collections.addAll(instructions, args); + } +} diff --git a/src/test/java/modele/JeuProfTest.java b/src/test/java/modele/JeuProfTest.java new file mode 100644 index 0000000..6d3e1d9 --- /dev/null +++ b/src/test/java/modele/JeuProfTest.java @@ -0,0 +1,95 @@ +package modele; + +import modele.CouleurWagon; +import modele.Destination; +import modele.Joueur; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class JeuProfTest { + private IOJeu jeu; + + @BeforeEach + public void setUp() { + jeu = new IOJeu(new String[] { "Guybrush", "Largo", "LeChuck", "Elaine" }); + } + + @Test + void testCartesWagon() { + // regrouper toutes les cartes wagon du jeu + List cartes = new ArrayList<>(); + cartes.addAll(jeu.getPileCartesWagon()); + cartes.addAll(jeu.getCartesWagonVisibles()); + cartes.addAll(jeu.getDefausseCartesWagon()); + for (Joueur j : jeu.getJoueurs()) { + cartes.addAll(j.getCartesWagon()); + } + + // compter le nombre de chaque couleur + HashMap compteur = new HashMap<>(); + for (CouleurWagon c : cartes) { + if (compteur.containsKey(c)) { + compteur.put(c, compteur.get(c) + 1); + } else { + compteur.put(c, 1); + } + } + + // varifier le nombre d'exemplaires de chaque couleur + assertEquals(110, cartes.size()); + assertEquals(12, compteur.get(CouleurWagon.NOIR)); + assertEquals(12, compteur.get(CouleurWagon.BLANC)); + assertEquals(12, compteur.get(CouleurWagon.JAUNE)); + assertEquals(12, compteur.get(CouleurWagon.ROUGE)); + assertEquals(12, compteur.get(CouleurWagon.ORANGE)); + assertEquals(12, compteur.get(CouleurWagon.BLEU)); + assertEquals(12, compteur.get(CouleurWagon.VERT)); + assertEquals(12, compteur.get(CouleurWagon.ROSE)); + assertEquals(14, compteur.get(CouleurWagon.LOCOMOTIVE)); + } + + @Test + void testInitialisationCartesVisibles() { + // vérifie que les cartes wagon face visible sont bien distribuées dans le + // constructeur du jeu + assertEquals(5, jeu.getCartesWagonVisibles().size()); + } + + @Test + void testDestinationsInitialesTousLesJoueursPassent() { + jeu.setInput("", "", "", ""); + try { + jeu.run(); + } catch (IndexOutOfBoundsException e) { + // on vérifie que chaque joueur a 3 destinations normales et 1 destination + // longue + List nomsDestinations = new ArrayList<>(); + for (Destination d : Destination.makeDestinationsEurope()) { + nomsDestinations.add(d.getNom()); + } + List nomsDestinationsLongues = new ArrayList<>(); + for (Destination d : Destination.makeDestinationsLonguesEurope()) { + nomsDestinationsLongues.add(d.getNom()); + } + for (Joueur j : jeu.getJoueurs()) { + int nbDestinations = 0; + int nbDestinationsLongues = 0; + for (Destination d : j.getDestinations()) { + if (nomsDestinations.contains(d.getNom())) { + nbDestinations += 1; + } else if (nomsDestinationsLongues.contains(d.getNom())) { + nbDestinationsLongues += 1; + } + } + assertEquals(3, nbDestinations); + assertEquals(1, nbDestinationsLongues); + } + } + } +} diff --git a/src/test/java/modele/JoueurProfTest.java b/src/test/java/modele/JoueurProfTest.java new file mode 100644 index 0000000..996a130 --- /dev/null +++ b/src/test/java/modele/JoueurProfTest.java @@ -0,0 +1,438 @@ +package modele; + +import modele.CouleurWagon; +import modele.Destination; +import modele.Ville; +import modele.Route; +import modele.Joueur; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class JoueurProfTest { + private IOJeu jeu; + private Joueur joueur1; + private Joueur joueur2; + private Joueur joueur3; + private Joueur joueur4; + + /** + * Renvoie la route du jeu dont le nom est passé en argument + * + * @param nom le nom de la route + * @return la route du jeu dont le nom est passé en argument (ou null si aucune + * route ne correspond) + */ + public Route getRouteParNom(String nom) { + for (Route route : jeu.getRoutes()) { + if (route.getNom().equals(nom)) { + return route; + } + } + return null; + } + + /** + * Renvoie la ville du jeu dont le nom est passé en argument + * + * @param nom le nom de la ville + * @return la ville du jeu dont le nom est passé en argument (ou null si aucune + * ville ne correspond) + */ + public Ville getVilleParNom(String nom) { + for (Ville ville : jeu.getVilles()) { + if (ville.getNom().equals(nom)) { + return ville; + } + } + return null; + } + + @BeforeEach + void init() { + jeu = new IOJeu(new String[] { "Guybrush", "Largo", "LeChuck", "Elaine" }); + List joueurs = jeu.getJoueurs(); + joueur1 = joueurs.get(0); + joueur2 = joueurs.get(1); + joueur3 = joueurs.get(2); + joueur4 = joueurs.get(3); + } + + /** + * Place 5 cartes ROUGE dans les cartes visibles, vide la pioche, la défausse et + * les mains des joueurs + */ + void clear() { + List cartesVisibles = jeu.getCartesWagonVisibles(); + cartesVisibles.clear(); + cartesVisibles.add(CouleurWagon.ROUGE); + cartesVisibles.add(CouleurWagon.ROUGE); + cartesVisibles.add(CouleurWagon.ROUGE); + cartesVisibles.add(CouleurWagon.ROUGE); + cartesVisibles.add(CouleurWagon.ROUGE); + jeu.getPileCartesWagon().clear(); + jeu.getDefausseCartesWagon().clear(); + + joueur1.getCartesWagon().clear(); + joueur2.getCartesWagon().clear(); + joueur3.getCartesWagon().clear(); + joueur4.getCartesWagon().clear(); + } + + @Test + void testInitialisation() { + for (Joueur joueur : jeu.getJoueurs()) { + assertEquals(3, joueur.getNbGares()); + assertEquals(4, joueur.getCartesWagon().size()); + assertEquals(45, joueur.getNbWagons()); + } + } + + @Test + void testChoisirDestinations() { + clear(); + + jeu.setInput("Athina - Angora (5)", "Frankfurt - Kobenhavn (5)"); + ArrayList destinationsPossibles = new ArrayList<>(); + Destination d1 = new Destination("Athina", "Angora", 5); + Destination d2 = new Destination("Budapest", "Sofia", 5); + Destination d3 = new Destination("Frankfurt", "Kobenhavn", 5); + Destination d4 = new Destination("Rostov", "Erzurum", 5); + destinationsPossibles.add(d1); + destinationsPossibles.add(d2); + destinationsPossibles.add(d3); + destinationsPossibles.add(d4); + + List destinationsDefaussees = joueur1.choisirDestinations(destinationsPossibles, 2); + assertEquals(2, joueur1.getDestinations().size()); + assertEquals(2, destinationsDefaussees.size()); + assertTrue(destinationsDefaussees.contains(d1)); + assertTrue(destinationsDefaussees.contains(d3)); + assertTrue(joueur1.getDestinations().contains(d2)); + assertTrue(joueur1.getDestinations().contains(d4)); + } + + @Test + void testJouerTourPrendreCartesWagon() { + clear(); + + List cartesWagonVisibles = jeu.getCartesWagonVisibles(); + + // On met VERT x3, BLEU, LOCOMOTIVE (haut de pile) dans la pile de cartes wagon + List pileCartesWagon = jeu.getPileCartesWagon(); + pileCartesWagon.add(0, CouleurWagon.VERT); + pileCartesWagon.add(0, CouleurWagon.VERT); + pileCartesWagon.add(0, CouleurWagon.VERT); + pileCartesWagon.add(0, CouleurWagon.BLEU); + pileCartesWagon.add(0, CouleurWagon.LOCOMOTIVE); + + jeu.setInput( + "JAUNE", // non valide (il n'y a que du ROUGE dans les cartes visibles) + "GRIS", // ok, pioche une LOCOMOTIVE sur le haut de la pile + "ROUGE"); // ok, prend dans les cartes visibles (remplacée par BLEU) + + joueur1.jouerTour(); + // le joueur devrait piocher la LOCOMOTIVE, prendre une carte ROUGE + // puis le jeu devrait remettre une carte visible BLEU + + assertTrue(TestUtils.contientExactement( + joueur1.getCartesWagon(), + CouleurWagon.ROUGE, + CouleurWagon.LOCOMOTIVE)); + assertTrue(TestUtils.contientExactement( + cartesWagonVisibles, + CouleurWagon.BLEU, + CouleurWagon.ROUGE, + CouleurWagon.ROUGE, + CouleurWagon.ROUGE, + CouleurWagon.ROUGE)); + assertTrue(TestUtils.contientExactement( + jeu.getPileCartesWagon(), + CouleurWagon.VERT, + CouleurWagon.VERT, + CouleurWagon.VERT)); + } + + @Test + void testJouerTourPiocherDestinations() { + clear(); + + Destination d1 = new Destination("Brest", "Marseille", 7); + Destination d2 = new Destination("London", "Berlin", 7); + Destination d3 = new Destination("Edinburgh", "Paris", 7); + Destination d4 = new Destination("Amsterdam", "Pamplona", 7); + Destination d5 = new Destination("Roma", "Smyrna", 8); + + // le joueur choisir de piocher des destinations, pioche les destinations d1, + // d2, d3, choisit + // de défausser d3 et passe (il garde donc d1 et d2) + jeu.setInput("destinations", d3.getNom(), ""); + List pileDestinations = jeu.getPileDestinations(); + pileDestinations.clear(); + pileDestinations.add(d1); // début de la liste : haut de la pile + pileDestinations.add(d2); + pileDestinations.add(d3); + pileDestinations.add(d4); + pileDestinations.add(d5); // fin de la liste : fond de la pile + + joueur1.jouerTour(); + assertEquals(d4, pileDestinations.get(0)); + assertEquals(d5, pileDestinations.get(1)); + assertEquals(d3, pileDestinations.get(2)); // d3 est remise en fond de pile + assertEquals(2, joueur1.getDestinations().size()); + assertTrue(joueur1.getDestinations().contains(d1)); + assertTrue(joueur1.getDestinations().contains(d2)); + } + + @Test + void testJouerTourCapturerRoute() { + clear(); + + List cartesWagon = joueur2.getCartesWagon(); + cartesWagon.add(CouleurWagon.BLEU); + cartesWagon.add(CouleurWagon.BLEU); + cartesWagon.add(CouleurWagon.ROUGE); + cartesWagon.add(CouleurWagon.ROUGE); + cartesWagon.add(CouleurWagon.LOCOMOTIVE); + + jeu.setInput( + "Brest - Pamplona", // coûte 4 ROSE (ne peut pas capturer) + "Bruxelles - Frankfurt", // coûte 2 BLEU + "BLEU", // ok + "ROUGE", // ne convient pas pour une route de 2 BLEU + "LOCOMOTIVE" // ok + ); + + joueur2.jouerTour(); + assertEquals(null, getRouteParNom("Brest - Pamplona").getProprietaire()); + assertEquals(joueur2, getRouteParNom("Bruxelles - Frankfurt").getProprietaire()); + assertTrue(TestUtils.contientExactement( + joueur2.getCartesWagon(), + CouleurWagon.BLEU, CouleurWagon.ROUGE, CouleurWagon.ROUGE)); + assertTrue(TestUtils.contientExactement( + jeu.getDefausseCartesWagon(), + CouleurWagon.BLEU, + CouleurWagon.LOCOMOTIVE)); + assertEquals(14, joueur2.getScore()); + } + + @Test + void testJouerTourCapturerRoutePlusieursCouleursPossibles() { + clear(); + + List cartesWagon = joueur2.getCartesWagon(); + cartesWagon.add(CouleurWagon.VERT); + cartesWagon.add(CouleurWagon.BLEU); + cartesWagon.add(CouleurWagon.BLEU); + cartesWagon.add(CouleurWagon.BLEU); + cartesWagon.add(CouleurWagon.ROUGE); + cartesWagon.add(CouleurWagon.ROUGE); + cartesWagon.add(CouleurWagon.ROUGE); + cartesWagon.add(CouleurWagon.LOCOMOTIVE); + cartesWagon.add(CouleurWagon.LOCOMOTIVE); + + jeu.setInput( + "Marseille - Paris", // coûte 4 GRIS + "VERT", // ne convient pas (impossible de payer en VERT) + "LOCOMOTIVE", // ok + "BLEU", // ok (paye tout le reste en BLEU ou LOCOMOTIVE) + "ROUGE", // ne convient pas car déjà payé BLEU + "BLEU", // ok + "LOCOMOTIVE" // ok + ); + + joueur2.jouerTour(); + assertEquals(joueur2, getRouteParNom("Marseille - Paris").getProprietaire()); + assertTrue(TestUtils.contientExactement( + joueur2.getCartesWagon(), + CouleurWagon.VERT, + CouleurWagon.BLEU, + CouleurWagon.ROUGE, CouleurWagon.ROUGE, CouleurWagon.ROUGE)); + assertTrue(TestUtils.contientExactement( + jeu.getDefausseCartesWagon(), + CouleurWagon.BLEU, + CouleurWagon.BLEU, + CouleurWagon.LOCOMOTIVE, + CouleurWagon.LOCOMOTIVE)); + assertEquals(19, joueur2.getScore()); + } + + @Test + void testJouerTourCapturerTunnelOK() { + clear(); + + List cartesWagon = joueur2.getCartesWagon(); + cartesWagon.add(CouleurWagon.ROSE); + cartesWagon.add(CouleurWagon.ROSE); + cartesWagon.add(CouleurWagon.ROUGE); + cartesWagon.add(CouleurWagon.ROUGE); + cartesWagon.add(CouleurWagon.LOCOMOTIVE); + + // cartes qui seront piochées après avoir payé le prix initial du tunnel + jeu.getPileCartesWagon().add(0, CouleurWagon.BLEU); + jeu.getPileCartesWagon().add(0, CouleurWagon.ROSE); + jeu.getPileCartesWagon().add(0, CouleurWagon.JAUNE); + + jeu.setInput( + "Marseille - Zurich", // coûte 2 ROSE (tunnel) + "ROSE", // ok + "LOCOMOTIVE", // ok + "ROSE" // coût supplémentaire du tunnel + ); + + joueur2.jouerTour(); + assertEquals(joueur2, getRouteParNom("Marseille - Zurich").getProprietaire()); + assertTrue(TestUtils.contientExactement( + joueur2.getCartesWagon(), + CouleurWagon.ROUGE, CouleurWagon.ROUGE)); + assertTrue(TestUtils.contientExactement( + jeu.getDefausseCartesWagon(), + CouleurWagon.ROSE, + CouleurWagon.ROSE, + CouleurWagon.LOCOMOTIVE, + CouleurWagon.BLEU, + CouleurWagon.ROSE, + CouleurWagon.JAUNE)); + assertEquals(14, joueur2.getScore()); + } + + @Test + void testJouerTourCapturerTunnelImpossible() { + clear(); + + List cartesWagon = joueur2.getCartesWagon(); + cartesWagon.add(CouleurWagon.ROSE); + cartesWagon.add(CouleurWagon.ROUGE); + cartesWagon.add(CouleurWagon.ROUGE); + cartesWagon.add(CouleurWagon.LOCOMOTIVE); + + // cartes qui seront piochées après avoir payé le prix initial du tunnel + jeu.getPileCartesWagon().add(0, CouleurWagon.ROSE); + jeu.getPileCartesWagon().add(0, CouleurWagon.BLEU); + jeu.getPileCartesWagon().add(0, CouleurWagon.JAUNE); + + jeu.setInput( + "Marseille - Zurich", // coûte 2 ROSE (tunnel) + "ROSE", // ok + "LOCOMOTIVE" // ok, mais le joueur ne peut pas payer le coût supplémentaire + ); + + joueur2.jouerTour(); + assertEquals(null, getRouteParNom("Marseille - Zurich").getProprietaire()); + assertTrue(TestUtils.contientExactement( + joueur2.getCartesWagon(), + CouleurWagon.ROSE, CouleurWagon.ROUGE, CouleurWagon.ROUGE, CouleurWagon.LOCOMOTIVE)); + assertTrue(TestUtils.contientExactement( + jeu.getDefausseCartesWagon(), + CouleurWagon.ROSE, + CouleurWagon.BLEU, + CouleurWagon.JAUNE)); + assertEquals(12, joueur2.getScore()); + } + + @Test + void testJouerTourCapturerTunnelAbandonne() { + clear(); + + List cartesWagon = joueur2.getCartesWagon(); + cartesWagon.add(CouleurWagon.ROSE); + cartesWagon.add(CouleurWagon.ROSE); + cartesWagon.add(CouleurWagon.ROUGE); + cartesWagon.add(CouleurWagon.ROUGE); + cartesWagon.add(CouleurWagon.LOCOMOTIVE); + + // cartes qui seront piochées après avoir payé le prix initial du tunnel + jeu.getPileCartesWagon().add(0, CouleurWagon.BLEU); + jeu.getPileCartesWagon().add(0, CouleurWagon.JAUNE); + jeu.getPileCartesWagon().add(0, CouleurWagon.ROSE); + + jeu.setInput( + "Marseille - Zurich", // coûte 2 ROSE (tunnel) + "ROSE", // ok + "LOCOMOTIVE", // ok + "" // le joueur pourrait payer mais choisit d'abandonner la capture + ); + + joueur2.jouerTour(); + assertEquals(null, getRouteParNom("Marseille - Zurich").getProprietaire()); + assertTrue(TestUtils.contientExactement( + joueur2.getCartesWagon(), + CouleurWagon.ROSE, CouleurWagon.ROSE, CouleurWagon.ROUGE, CouleurWagon.ROUGE, + CouleurWagon.LOCOMOTIVE)); + assertTrue(TestUtils.contientExactement( + jeu.getDefausseCartesWagon(), + CouleurWagon.ROSE, + CouleurWagon.BLEU, + CouleurWagon.JAUNE)); + assertEquals(12, joueur2.getScore()); + } + + @Test + void testJouerTourCapturerFerry() { + clear(); + + List cartesWagon = joueur3.getCartesWagon(); + cartesWagon.add(CouleurWagon.ROSE); + cartesWagon.add(CouleurWagon.JAUNE); + cartesWagon.add(CouleurWagon.JAUNE); + cartesWagon.add(CouleurWagon.JAUNE); + cartesWagon.add(CouleurWagon.LOCOMOTIVE); + + // Remarque: + // Il est possible de faire en sorte que la locomotive imposée par le ferry soit + // immédiatement payée par le joueur sans demander d'input (l'utilisateur doit + // alors choisir les cartes restantes pour payer) ou bien de demander à + // l'utilisateur de choisir toutes les cartes pour payer (y compris la + // locomotive imposée). Le test devrait fonctionner dans les deux cas. + jeu.setInput( + "Constantinople - Sevastopol", // (ferry) coûte 4 GRIS dont 2 LOCOMOTIVE (ne peut pas acheter) + "Palermo - Roma", // (ferry) coûte 4 GRIS dont 1 LOCOMOTIVE (peut acheter) + "ROSE", // non valide (ne peut pas couvrir le coût) + "JAUNE", // OK + "JAUNE", // OK + "JAUNE", // OK + "LOCOMOTIVE" // OK + ); + joueur3.jouerTour(); + + assertEquals(joueur3, getRouteParNom("Palermo - Roma").getProprietaire()); + assertTrue(TestUtils.contientExactement( + joueur3.getCartesWagon(), + CouleurWagon.ROSE)); + assertTrue(TestUtils.contientExactement( + jeu.getDefausseCartesWagon(), + CouleurWagon.JAUNE, CouleurWagon.JAUNE, CouleurWagon.JAUNE, + CouleurWagon.LOCOMOTIVE)); + assertEquals(null, getRouteParNom("Constantinople - Sevastopol").getProprietaire()); + assertEquals(19, joueur3.getScore()); + } + + @Test + void testJouerTourConstruireUneGare() { + clear(); + + List cartesWagon = joueur3.getCartesWagon(); + cartesWagon.add(CouleurWagon.VERT); + cartesWagon.add(CouleurWagon.BLEU); + cartesWagon.add(CouleurWagon.BLEU); + cartesWagon.add(CouleurWagon.ROUGE); + cartesWagon.add(CouleurWagon.ROUGE); + + jeu.setInput("Paris", "ROUGE"); + joueur3.jouerTour(); + + assertEquals(joueur3, getVilleParNom("Paris").getProprietaire()); + assertTrue(TestUtils.contientExactement( + joueur3.getCartesWagon(), + CouleurWagon.VERT, CouleurWagon.BLEU, CouleurWagon.BLEU, CouleurWagon.ROUGE)); + assertTrue(TestUtils.contientExactement( + jeu.getDefausseCartesWagon(), + CouleurWagon.ROUGE)); + assertEquals(2, joueur3.getNbGares()); + } +} diff --git a/src/test/java/modele/JoueurTest.java b/src/test/java/modele/JoueurTest.java new file mode 100644 index 0000000..e68730a --- /dev/null +++ b/src/test/java/modele/JoueurTest.java @@ -0,0 +1,96 @@ +package modele; + +import modele.CouleurWagon; +import modele.Destination; +import modele.Joueur; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class JoueurTest { + private IOJeu jeu; + private Joueur joueur1; + private Joueur joueur2; + private Joueur joueur3; + private Joueur joueur4; + + @BeforeEach + void init() { + jeu = new IOJeu(new String[] { "Guybrush", "Largo", "LeChuck", "Elaine" }); + List joueurs = jeu.getJoueurs(); + joueur1 = joueurs.get(0); + joueur2 = joueurs.get(1); + joueur3 = joueurs.get(2); + joueur4 = joueurs.get(3); + joueur1.getCartesWagon().clear(); + joueur2.getCartesWagon().clear(); + joueur3.getCartesWagon().clear(); + joueur4.getCartesWagon().clear(); + } + + + @Test + void testChoisirDestinations() { + jeu.setInput("Athina - Angora (5)", "Frankfurt - Kobenhavn (5)"); + ArrayList destinationsPossibles = new ArrayList<>(); + Destination d1 = new Destination("Athina", "Angora", 5); + Destination d2 = new Destination("Budapest", "Sofia", 5); + Destination d3 = new Destination("Frankfurt", "Kobenhavn", 5); + Destination d4 = new Destination("Rostov", "Erzurum", 5); + destinationsPossibles.add(d1); + destinationsPossibles.add(d2); + destinationsPossibles.add(d3); + destinationsPossibles.add(d4); + + List destinationsDefaussees = joueur1.choisirDestinations(destinationsPossibles, 2); + assertEquals(2, joueur1.getDestinations().size()); + assertEquals(2, destinationsDefaussees.size()); + assertTrue(destinationsDefaussees.contains(d1)); + assertTrue(destinationsDefaussees.contains(d3)); + assertTrue(joueur1.getDestinations().contains(d2)); + assertTrue(joueur1.getDestinations().contains(d4)); + } + + @Test + void testJouerTourPrendreCartesWagon() { + jeu.setInput("GRIS", "ROUGE"); + + // On met 5 cartes ROUGE dans les cartes wagon visibles + List cartesWagonVisibles = jeu.getCartesWagonVisibles(); + cartesWagonVisibles.clear(); + cartesWagonVisibles.add(CouleurWagon.ROUGE); + cartesWagonVisibles.add(CouleurWagon.ROUGE); + cartesWagonVisibles.add(CouleurWagon.ROUGE); + cartesWagonVisibles.add(CouleurWagon.ROUGE); + cartesWagonVisibles.add(CouleurWagon.ROUGE); + + // On met VERT, BLEU, LOCOMOTIVE (haut de pile) dans la pile de cartes wagon + List pileCartesWagon = jeu.getPileCartesWagon(); + pileCartesWagon.add(0, CouleurWagon.BLEU); + pileCartesWagon.add(0, CouleurWagon.LOCOMOTIVE); + int nbCartesWagon = pileCartesWagon.size(); + + joueur1.jouerTour(); + + // le joueur devrait piocher la LOCOMOTIVE, prendre une carte ROUGE + // puis le jeu devrait remettre une carte visible BLEU + + assertTrue(TestUtils.contientExactement( + joueur1.getCartesWagon(), + CouleurWagon.ROUGE, + CouleurWagon.LOCOMOTIVE)); + assertTrue(TestUtils.contientExactement( + cartesWagonVisibles, + CouleurWagon.BLEU, + CouleurWagon.ROUGE, + CouleurWagon.ROUGE, + CouleurWagon.ROUGE, + CouleurWagon.ROUGE)); + assertEquals(nbCartesWagon - 2, pileCartesWagon.size()); + } +} diff --git a/src/test/java/modele/TestUtils.java b/src/test/java/modele/TestUtils.java new file mode 100644 index 0000000..ade453a --- /dev/null +++ b/src/test/java/modele/TestUtils.java @@ -0,0 +1,76 @@ +package modele; + +import modele.CouleurWagon; +import modele.Joueur; +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class TestUtils { + /** + * Renvoie un attribut d'un objet à partir de son nom. + * La méthode cherche s'il existe un champ déclaré dans la classe de l'objet et + * si ce n'est pas le cas remonte dans la hiérarchie des classes jusqu'à trouver + * un champ avec le nom voulu ou renvoie null. + * + * @param obj objet dont on cherche le champ + * @param name nom du champ + * @return le champ de l'objet, avec un type statique Object + */ + public static Object getAttribute(Object obj, String name) { + Class c = obj.getClass(); + while (c != null) { + try { + Field field = c.getDeclaredField(name); + field.setAccessible(true); + return field.get(obj); + } catch (NoSuchFieldException e) { + c = c.getSuperclass(); + continue; + } catch (IllegalAccessException e) { + e.printStackTrace(); + return null; + } + } + return null; + } + + /** + * Met les cartes wagon passées en argument dans la main d'un joueur (la main + * est vidée avant, pour contenir exactement les cartes indiquées) + * + * @param joueur le joueur dont on fixe les cartes en main + */ + public static void setCartesWagon(Joueur joueur, CouleurWagon... cartesWagon) { + while (!joueur.getCartesWagon().isEmpty()) { + joueur.getCartesWagon().remove(0); + } + Collections.addAll(joueur.getCartesWagon(), cartesWagon); + } + + /** + * Teste si la liste de CouleurWagon passée en premier argument contient + * exactement les couleurs indiquées, indépendamment de leur ordre + * + * @param liste la liste de CouleurWagon à tester + * @param couleurs les couleurs que la liste devrait contenir (avec leur + * multiplicité) + * @return true si la liste contient exactement les couleurs indiquées, avec + * leur multiplicité, false sinon + */ + public static boolean contientExactement(List liste, CouleurWagon... couleurs) { + if (liste.size() != couleurs.length) { + return false; + } + Arrays.sort(couleurs); + Collections.sort(liste); + + for (int i = 0; i < couleurs.length; i++) { + if (couleurs[i] != liste.get(i)) { + return false; + } + } + return true; + } +} diff --git a/svelte/.gitignore b/svelte/.gitignore new file mode 100644 index 0000000..0fa49e9 --- /dev/null +++ b/svelte/.gitignore @@ -0,0 +1,3 @@ +/node_modules/ + +.DS_Store diff --git a/svelte/README.md b/svelte/README.md new file mode 100644 index 0000000..8ca4fca --- /dev/null +++ b/svelte/README.md @@ -0,0 +1,109 @@ +*Psst — looking for a more complete solution? Check out [SvelteKit](https://kit.svelte.dev), the official framework for building web applications of all sizes, with a beautiful development experience and flexible filesystem-based routing.* + +*Looking for a shareable component template instead? You can [use SvelteKit for that as well](https://kit.svelte.dev/docs#packaging) or the older [sveltejs/component-template](https://github.com/sveltejs/component-template)* + +--- + +# svelte app + +This is a project template for [Svelte](https://svelte.dev) apps. It lives at https://github.com/sveltejs/template. + +To create a new project based on this template using [degit](https://github.com/Rich-Harris/degit): + +```bash +npx degit sveltejs/template svelte-app +cd svelte-app +``` + +*Note that you will need to have [Node.js](https://nodejs.org) installed.* + + +## Get started + +Install the dependencies... + +```bash +cd svelte-app +npm install +``` + +...then start [Rollup](https://rollupjs.org): + +```bash +npm run dev +``` + +Navigate to [localhost:8080](http://localhost:8080). You should see your app running. Edit a component file in `src`, save it, and reload the page to see your changes. + +By default, the server will only respond to requests from localhost. To allow connections from other computers, edit the `sirv` commands in package.json to include the option `--host 0.0.0.0`. + +If you're using [Visual Studio Code](https://code.visualstudio.com/) we recommend installing the official extension [Svelte for VS Code](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). If you are using other editors you may need to install a plugin in order to get syntax highlighting and intellisense. + +## Building and running in production mode + +To create an optimised version of the app: + +```bash +npm run build +``` + +You can run the newly built app with `npm run start`. This uses [sirv](https://github.com/lukeed/sirv), which is included in your package.json's `dependencies` so that the app will work when you deploy to platforms like [Heroku](https://heroku.com). + + +## Single-page app mode + +By default, sirv will only respond to requests that match files in `public`. This is to maximise compatibility with static fileservers, allowing you to deploy your app anywhere. + +If you're building a single-page app (SPA) with multiple routes, sirv needs to be able to respond to requests for *any* path. You can make it so by editing the `"start"` command in package.json: + +```js +"start": "sirv public --single" +``` + +## Using TypeScript + +This template comes with a script to set up a TypeScript development environment, you can run it immediately after cloning the template with: + +```bash +node scripts/setupTypeScript.js +``` + +Or remove the script via: + +```bash +rm scripts/setupTypeScript.js +``` + +If you want to use `baseUrl` or `path` aliases within your `tsconfig`, you need to set up `@rollup/plugin-alias` to tell Rollup to resolve the aliases. For more info, see [this StackOverflow question](https://stackoverflow.com/questions/63427935/setup-tsconfig-path-in-svelte). + +## Deploying to the web + +### With [Vercel](https://vercel.com) + +Install `vercel` if you haven't already: + +```bash +npm install -g vercel +``` + +Then, from within your project folder: + +```bash +cd public +vercel deploy --name my-project +``` + +### With [surge](https://surge.sh/) + +Install `surge` if you haven't already: + +```bash +npm install -g surge +``` + +Then, from within your project folder: + +```bash +npm run build +surge public my-project.surge.sh +``` diff --git a/svelte/package-lock.json b/svelte/package-lock.json new file mode 100644 index 0000000..a48321f --- /dev/null +++ b/svelte/package-lock.json @@ -0,0 +1,788 @@ +{ + "name": "svelte-app", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.16.7" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@polka/url": { + "version": "1.0.0-next.21", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", + "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==" + }, + "@rollup/plugin-commonjs": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-17.1.0.tgz", + "integrity": "sha512-PoMdXCw0ZyvjpCMT5aV4nkL0QywxP29sODQsSGeDpr/oI49Qq9tRtAsb/LbYbDzFlOydVEqHmmZWFtXJEAX9ew==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "commondir": "^1.0.1", + "estree-walker": "^2.0.1", + "glob": "^7.1.6", + "is-reference": "^1.2.1", + "magic-string": "^0.25.7", + "resolve": "^1.17.0" + } + }, + "@rollup/plugin-node-resolve": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + } + }, + "@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "requires": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "dependencies": { + "estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + } + } + }, + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "@types/node": { + "version": "17.0.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.18.tgz", + "integrity": "sha512-eKj4f/BsN/qcculZiRSujogjvp5O/k4lOW5m35NopjZM/QwLOR075a8pJW5hD+Rtdm2DaCVPENS6KtSQnUD6BA==", + "dev": true + }, + "@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "console-clear": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/console-clear/-/console-clear-1.1.1.tgz", + "integrity": "sha512-pMD+MVR538ipqkG5JXeOEbKWS5um1H4LUUccUQG68qpeqBYbzYy79Gh55jkd2TtPdRfUaLWdv6LPP//5Zt0aPQ==" + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=" + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "requires": { + "@types/estree": "*" + } + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "kleur": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.4.tgz", + "integrity": "sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==" + }, + "livereload": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/livereload/-/livereload-0.9.3.tgz", + "integrity": "sha512-q7Z71n3i4X0R9xthAryBdNGVGAO2R5X+/xXpmKeuPMrteg+W2U8VusTKV3YiJbXZwKsOlFlHe+go6uSNjfxrZw==", + "dev": true, + "requires": { + "chokidar": "^3.5.0", + "livereload-js": "^3.3.1", + "opts": ">= 1.2.0", + "ws": "^7.4.3" + } + }, + "livereload-js": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-3.3.3.tgz", + "integrity": "sha512-a7Jipme3XIBIryJluWP5LQrEAvhobDPyScBe+q+MYwxBiMT2Ck7msy4tAdF8TAa33FMdJqX4guP81Yhiu6BkmQ==", + "dev": true + }, + "local-access": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/local-access/-/local-access-1.1.0.tgz", + "integrity": "sha512-XfegD5pyTAfb+GY6chk283Ox5z8WexG56OvM06RWLpAc/UHozO8X6xAxEkIitZOtsSMM1Yr3DkHgW5W+onLhCw==" + }, + "magic-string": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.4" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==" + }, + "mrmime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz", + "integrity": "sha512-a70zx7zFfVO7XpnQ2IX1Myh9yY4UYvfld/dikWRnsXxbyvMcfz+u6UfgNAtH+k2QqtJuzVpv6eLTx1G2+WKZbQ==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "opts": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opts/-/opts-2.0.2.tgz", + "integrity": "sha512-k41FwbcLnlgnFh69f4qdUfvDQ+5vaSDnVPFI/y5XuhKRq97EnVVneO9F1ESVCdiVu4fCS2L8usX3mU331hB7pg==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "require-relative": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz", + "integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=", + "dev": true + }, + "resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "requires": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "rollup": { + "version": "2.67.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.67.2.tgz", + "integrity": "sha512-hoEiBWwZtf1QdK3jZIq59L0FJj4Fiv4RplCO4pvCRC86qsoFurWB4hKQIjoRf3WvJmk5UZ9b0y5ton+62fC7Tw==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "rollup-plugin-css-only": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-css-only/-/rollup-plugin-css-only-3.1.0.tgz", + "integrity": "sha512-TYMOE5uoD76vpj+RTkQLzC9cQtbnJNktHPB507FzRWBVaofg7KhIqq1kGbcVOadARSozWF883Ho9KpSPKH8gqA==", + "dev": true, + "requires": { + "@rollup/pluginutils": "4" + }, + "dependencies": { + "@rollup/pluginutils": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.1.2.tgz", + "integrity": "sha512-ROn4qvkxP9SyPeHaf7uQC/GPFY6L/OWy9+bd9AwcjOAWQwxRscoEyAUD8qCY5o5iL4jqQwoLk2kaTKJPb/HwzQ==", + "dev": true, + "requires": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + } + } + } + }, + "rollup-plugin-livereload": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/rollup-plugin-livereload/-/rollup-plugin-livereload-2.0.5.tgz", + "integrity": "sha512-vqQZ/UQowTW7VoiKEM5ouNW90wE5/GZLfdWuR0ELxyKOJUIaj+uismPZZaICU4DnWPVjnpCDDxEqwU7pcKY/PA==", + "dev": true, + "requires": { + "livereload": "^0.9.1" + } + }, + "rollup-plugin-svelte": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-7.1.0.tgz", + "integrity": "sha512-vopCUq3G+25sKjwF5VilIbiY6KCuMNHP1PFvx2Vr3REBNMDllKHFZN2B9jwwC+MqNc3UPKkjXnceLPEjTjXGXg==", + "dev": true, + "requires": { + "require-relative": "^0.8.7", + "rollup-pluginutils": "^2.8.2" + } + }, + "rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + } + }, + "rollup-pluginutils": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", + "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", + "dev": true, + "requires": { + "estree-walker": "^0.6.1" + }, + "dependencies": { + "estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "dev": true + } + } + }, + "sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "requires": { + "mri": "^1.1.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "semiver": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semiver/-/semiver-1.1.0.tgz", + "integrity": "sha512-QNI2ChmuioGC1/xjyYwyZYADILWyW6AmS1UH6gDj/SFUUUS4MBAWs/7mxnkRPc/F4iHezDP+O8t0dO8WHiEOdg==" + }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "sirv": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.2.tgz", + "integrity": "sha512-4Qog6aE29nIjAOKe/wowFTxOdmbEZKb+3tsLljaBRzJwtqto0BChD2zzH0LhgCSXiI+V7X+Y45v14wBZQ1TK3w==", + "requires": { + "@polka/url": "^1.0.0-next.20", + "mrmime": "^1.0.0", + "totalist": "^3.0.0" + } + }, + "sirv-cli": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/sirv-cli/-/sirv-cli-2.0.2.tgz", + "integrity": "sha512-OtSJDwxsF1NWHc7ps3Sa0s+dPtP15iQNJzfKVz+MxkEo3z72mCD+yu30ct79rPr0CaV1HXSOBp+MIY5uIhHZ1A==", + "requires": { + "console-clear": "^1.1.0", + "get-port": "^3.2.0", + "kleur": "^4.1.4", + "local-access": "^1.0.1", + "sade": "^1.6.0", + "semiver": "^1.0.0", + "sirv": "^2.0.0", + "tinydate": "^1.0.0" + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "svelte": { + "version": "3.46.4", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.46.4.tgz", + "integrity": "sha512-qKJzw6DpA33CIa+C/rGp4AUdSfii0DOTCzj/2YpSKKayw5WGSS624Et9L1nU1k2OVRS9vaENQXp2CVZNU+xvIg==", + "dev": true + }, + "terser": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz", + "integrity": "sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.20" + } + }, + "tinydate": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.3.0.tgz", + "integrity": "sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "totalist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.0.tgz", + "integrity": "sha512-eM+pCBxXO/njtF7vdFsHuqb+ElbxqtI4r5EAvk6grfAFyJ6IvWlSkfZ5T9ozC6xWw3Fj1fGoSmrl0gUs46JVIw==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "ws": { + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", + "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", + "dev": true + } + } +} diff --git a/svelte/package.json b/svelte/package.json new file mode 100644 index 0000000..1fbd8f5 --- /dev/null +++ b/svelte/package.json @@ -0,0 +1,23 @@ +{ + "name": "svelte-app", + "version": "1.0.0", + "private": true, + "scripts": { + "build": "rollup -c", + "dev": "rollup -c -w", + "start": "sirv public --no-clear" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^17.0.0", + "@rollup/plugin-node-resolve": "^11.0.0", + "rollup": "^2.3.4", + "rollup-plugin-css-only": "^3.1.0", + "rollup-plugin-livereload": "^2.0.0", + "rollup-plugin-svelte": "^7.0.0", + "rollup-plugin-terser": "^7.0.0", + "svelte": "^3.0.0" + }, + "dependencies": { + "sirv-cli": "^2.0.0" + } +} diff --git a/svelte/public/bundle.css b/svelte/public/bundle.css new file mode 100644 index 0000000..c2e54b9 --- /dev/null +++ b/svelte/public/bundle.css @@ -0,0 +1 @@ +main.svelte-urompm{display:flex;flex-direction:row}.joueurs.svelte-urompm{float:right}#board.svelte-1s8m8k5{background:url(images/euMap.jpg);background-size:contain;width:850px;height:548px;border:1px var(--col-dark) solid;border-radius:8px;box-shadow:2px 2px 2px var(--col-dark)}.ville.svelte-1s8m8k5{stroke:none;fill:#0000}.route.svelte-1s8m8k5{stroke:none;fill:#0000}.no-pointer.svelte-1s8m8k5{pointer-events:none}.joueur.svelte-vqlws6.svelte-vqlws6{color:var(--col-dark);border:1px solid var(--col-dark);border-radius:8px;width:280px;padding:4px;margin-left:4px;margin-bottom:4px;box-shadow:2px 2px 2px var(--col-dark)}.joueur.BLEU.svelte-vqlws6.svelte-vqlws6{background:var(--col-light-BLEU)}.joueur.VERT.svelte-vqlws6.svelte-vqlws6{background:var(--col-light-VERT)}.joueur.ROSE.svelte-vqlws6.svelte-vqlws6{background:var(--col-light-ROSE)}.joueur.ROUGE.svelte-vqlws6.svelte-vqlws6{background:var(--col-light-ROUGE)}.joueur.JAUNE.svelte-vqlws6.svelte-vqlws6{background:var(--col-light-JAUNE)}.header.svelte-vqlws6.svelte-vqlws6{display:flex;flex-direction:row;justify-content:space-between;margin-bottom:4px}.info.svelte-vqlws6.svelte-vqlws6{width:100%}.nom.svelte-vqlws6.svelte-vqlws6{width:100%;text-align:center;font-size:1.5em;font-weight:bold}.avatar.svelte-vqlws6.svelte-vqlws6{height:84px;width:66px}.secret.svelte-vqlws6.svelte-vqlws6{display:none}.joueur.svelte-vqlws6:hover .secret.svelte-vqlws6,.joueur.actif.svelte-vqlws6 .secret.svelte-vqlws6{display:block}.destinations.svelte-vqlws6.svelte-vqlws6{align-content:right}.cartes-wagon.svelte-vqlws6.svelte-vqlws6{display:flex;flex-wrap:wrap;flex-direction:row;width:250px}.carte-wagon.svelte-vqlws6.svelte-vqlws6{border:1px solid var(--col-dark);border-radius:4px;overflow:hidden;position:relative;width:calc(248px * 0.3);height:calc(160px * 0.3);padding:0;margin-right:-42px}.carte-wagon.svelte-vqlws6 .overlay.svelte-vqlws6{position:absolute;top:0;left:0;width:100%;height:100%;background:var(--col-dark);opacity:0.5}.image-wagon.svelte-vqlws6.svelte-vqlws6{width:100%;height:100%;background-size:cover}.nom-joueur.svelte-19y2w7e{font-weight:bold}#piles.svelte-1eir9gx.svelte-1eir9gx{justify-content:space-around}.carte.svelte-1eir9gx.svelte-1eir9gx{width:100px;font-size:0.8em;text-align:center}.carte-stub.svelte-1eir9gx.svelte-1eir9gx{width:100px;height:67px;margin-bottom:5px}.carte.svelte-1eir9gx img.svelte-1eir9gx{margin-bottom:5px;border-radius:4px;border:1px var(--col-dark) solid;box-shadow:2px 2px 2px var(--col-dark)}#cartes-visibles.svelte-1eir9gx.svelte-1eir9gx{width:500px;height:89px;flex-direction:row-reverse}#defausse-cartes-wagon.svelte-1eir9gx.svelte-1eir9gx{flex-direction:column-reverse}#defausse-cartes-wagon.svelte-1eir9gx img.svelte-1eir9gx{margin-top:-55px;display:none}#defausse-cartes-wagon.svelte-1eir9gx:hover img.svelte-1eir9gx{display:block}#defausse-cartes-wagon.svelte-1eir9gx img.svelte-1eir9gx:last-child{margin-top:0;display:block}#pile-destinations.svelte-1eir9gx.svelte-1eir9gx,#pile-cartes-wagon.svelte-1eir9gx.svelte-1eir9gx{margin-left:10px}#log.svelte-1r9y78z{margin:5px 0;padding:10px 30px 12px 26px;width:408px;height:263px;font-family:monospace;background:url(images/dialogue-box_Big.png);background-size:cover}#inner-log.svelte-1r9y78z{padding:0px;height:100%;overflow:overlay}.svelte-1r9y78z::-webkit-scrollbar{background-color:transparent} \ No newline at end of file diff --git a/svelte/public/bundle.js b/svelte/public/bundle.js new file mode 100644 index 0000000..823a574 --- /dev/null +++ b/svelte/public/bundle.js @@ -0,0 +1,3672 @@ + +(function(l, r) { if (!l || l.getElementById('livereloadscript')) return; r = l.createElement('script'); r.async = 1; r.src = '//' + (self.location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1'; r.id = 'livereloadscript'; l.getElementsByTagName('head')[0].appendChild(r) })(self.document); +var app = (function () { + 'use strict'; + + function noop() { } + function add_location(element, file, line, column, char) { + element.__svelte_meta = { + loc: { file, line, column, char } + }; + } + function run(fn) { + return fn(); + } + function blank_object() { + return Object.create(null); + } + function run_all(fns) { + fns.forEach(run); + } + function is_function(thing) { + return typeof thing === 'function'; + } + function safe_not_equal(a, b) { + return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + } + let src_url_equal_anchor; + function src_url_equal(element_src, url) { + if (!src_url_equal_anchor) { + src_url_equal_anchor = document.createElement('a'); + } + src_url_equal_anchor.href = url; + return element_src === src_url_equal_anchor.href; + } + function is_empty(obj) { + return Object.keys(obj).length === 0; + } + function validate_store(store, name) { + if (store != null && typeof store.subscribe !== 'function') { + throw new Error(`'${name}' is not a store with a 'subscribe' method`); + } + } + function subscribe(store, ...callbacks) { + if (store == null) { + return noop; + } + const unsub = store.subscribe(...callbacks); + return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub; + } + function component_subscribe(component, store, callback) { + component.$$.on_destroy.push(subscribe(store, callback)); + } + function set_store_value(store, ret, value) { + store.set(value); + return ret; + } + function append(target, node) { + target.appendChild(node); + } + function insert(target, node, anchor) { + target.insertBefore(node, anchor || null); + } + function detach(node) { + node.parentNode.removeChild(node); + } + function destroy_each(iterations, detaching) { + for (let i = 0; i < iterations.length; i += 1) { + if (iterations[i]) + iterations[i].d(detaching); + } + } + function element(name) { + return document.createElement(name); + } + function svg_element(name) { + return document.createElementNS('http://www.w3.org/2000/svg', name); + } + function text(data) { + return document.createTextNode(data); + } + function space() { + return text(' '); + } + function empty() { + return text(''); + } + function listen(node, event, handler, options) { + node.addEventListener(event, handler, options); + return () => node.removeEventListener(event, handler, options); + } + function attr(node, attribute, value) { + if (value == null) + node.removeAttribute(attribute); + else if (node.getAttribute(attribute) !== value) + node.setAttribute(attribute, value); + } + function xlink_attr(node, attribute, value) { + node.setAttributeNS('http://www.w3.org/1999/xlink', attribute, value); + } + function children(element) { + return Array.from(element.childNodes); + } + function set_style(node, key, value, important) { + if (value === null) { + node.style.removeProperty(key); + } + else { + node.style.setProperty(key, value, important ? 'important' : ''); + } + } + function custom_event(type, detail, bubbles = false) { + const e = document.createEvent('CustomEvent'); + e.initCustomEvent(type, bubbles, false, detail); + return e; + } + + let current_component; + function set_current_component(component) { + current_component = component; + } + function get_current_component() { + if (!current_component) + throw new Error('Function called outside component initialization'); + return current_component; + } + function beforeUpdate(fn) { + get_current_component().$$.before_update.push(fn); + } + function afterUpdate(fn) { + get_current_component().$$.after_update.push(fn); + } + + const dirty_components = []; + const binding_callbacks = []; + const render_callbacks = []; + const flush_callbacks = []; + const resolved_promise = Promise.resolve(); + let update_scheduled = false; + function schedule_update() { + if (!update_scheduled) { + update_scheduled = true; + resolved_promise.then(flush); + } + } + function add_render_callback(fn) { + render_callbacks.push(fn); + } + // flush() calls callbacks in this order: + // 1. All beforeUpdate callbacks, in order: parents before children + // 2. All bind:this callbacks, in reverse order: children before parents. + // 3. All afterUpdate callbacks, in order: parents before children. EXCEPT + // for afterUpdates called during the initial onMount, which are called in + // reverse order: children before parents. + // Since callbacks might update component values, which could trigger another + // call to flush(), the following steps guard against this: + // 1. During beforeUpdate, any updated components will be added to the + // dirty_components array and will cause a reentrant call to flush(). Because + // the flush index is kept outside the function, the reentrant call will pick + // up where the earlier call left off and go through all dirty components. The + // current_component value is saved and restored so that the reentrant call will + // not interfere with the "parent" flush() call. + // 2. bind:this callbacks cannot trigger new flush() calls. + // 3. During afterUpdate, any updated components will NOT have their afterUpdate + // callback called a second time; the seen_callbacks set, outside the flush() + // function, guarantees this behavior. + const seen_callbacks = new Set(); + let flushidx = 0; // Do *not* move this inside the flush() function + function flush() { + const saved_component = current_component; + do { + // first, call beforeUpdate functions + // and update components + while (flushidx < dirty_components.length) { + const component = dirty_components[flushidx]; + flushidx++; + set_current_component(component); + update(component.$$); + } + set_current_component(null); + dirty_components.length = 0; + flushidx = 0; + while (binding_callbacks.length) + binding_callbacks.pop()(); + // then, once components are updated, call + // afterUpdate functions. This may cause + // subsequent updates... + for (let i = 0; i < render_callbacks.length; i += 1) { + const callback = render_callbacks[i]; + if (!seen_callbacks.has(callback)) { + // ...so guard against infinite loops + seen_callbacks.add(callback); + callback(); + } + } + render_callbacks.length = 0; + } while (dirty_components.length); + while (flush_callbacks.length) { + flush_callbacks.pop()(); + } + update_scheduled = false; + seen_callbacks.clear(); + set_current_component(saved_component); + } + function update($$) { + if ($$.fragment !== null) { + $$.update(); + run_all($$.before_update); + const dirty = $$.dirty; + $$.dirty = [-1]; + $$.fragment && $$.fragment.p($$.ctx, dirty); + $$.after_update.forEach(add_render_callback); + } + } + const outroing = new Set(); + let outros; + function group_outros() { + outros = { + r: 0, + c: [], + p: outros // parent group + }; + } + function check_outros() { + if (!outros.r) { + run_all(outros.c); + } + outros = outros.p; + } + function transition_in(block, local) { + if (block && block.i) { + outroing.delete(block); + block.i(local); + } + } + function transition_out(block, local, detach, callback) { + if (block && block.o) { + if (outroing.has(block)) + return; + outroing.add(block); + outros.c.push(() => { + outroing.delete(block); + if (callback) { + if (detach) + block.d(1); + callback(); + } + }); + block.o(local); + } + } + + const globals = (typeof window !== 'undefined' + ? window + : typeof globalThis !== 'undefined' + ? globalThis + : global); + function create_component(block) { + block && block.c(); + } + function mount_component(component, target, anchor, customElement) { + const { fragment, on_mount, on_destroy, after_update } = component.$$; + fragment && fragment.m(target, anchor); + if (!customElement) { + // onMount happens before the initial afterUpdate + add_render_callback(() => { + const new_on_destroy = on_mount.map(run).filter(is_function); + if (on_destroy) { + on_destroy.push(...new_on_destroy); + } + else { + // Edge case - component was destroyed immediately, + // most likely as a result of a binding initialising + run_all(new_on_destroy); + } + component.$$.on_mount = []; + }); + } + after_update.forEach(add_render_callback); + } + function destroy_component(component, detaching) { + const $$ = component.$$; + if ($$.fragment !== null) { + run_all($$.on_destroy); + $$.fragment && $$.fragment.d(detaching); + // TODO null out other refs, including component.$$ (but need to + // preserve final state?) + $$.on_destroy = $$.fragment = null; + $$.ctx = []; + } + } + function make_dirty(component, i) { + if (component.$$.dirty[0] === -1) { + dirty_components.push(component); + schedule_update(); + component.$$.dirty.fill(0); + } + component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31)); + } + function init(component, options, instance, create_fragment, not_equal, props, append_styles, dirty = [-1]) { + const parent_component = current_component; + set_current_component(component); + const $$ = component.$$ = { + fragment: null, + ctx: null, + // state + props, + update: noop, + not_equal, + bound: blank_object(), + // lifecycle + on_mount: [], + on_destroy: [], + on_disconnect: [], + before_update: [], + after_update: [], + context: new Map(options.context || (parent_component ? parent_component.$$.context : [])), + // everything else + callbacks: blank_object(), + dirty, + skip_bound: false, + root: options.target || parent_component.$$.root + }; + append_styles && append_styles($$.root); + let ready = false; + $$.ctx = instance + ? instance(component, options.props || {}, (i, ret, ...rest) => { + const value = rest.length ? rest[0] : ret; + if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) { + if (!$$.skip_bound && $$.bound[i]) + $$.bound[i](value); + if (ready) + make_dirty(component, i); + } + return ret; + }) + : []; + $$.update(); + ready = true; + run_all($$.before_update); + // `false` as a special case of no DOM component + $$.fragment = create_fragment ? create_fragment($$.ctx) : false; + if (options.target) { + if (options.hydrate) { + const nodes = children(options.target); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + $$.fragment && $$.fragment.l(nodes); + nodes.forEach(detach); + } + else { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + $$.fragment && $$.fragment.c(); + } + if (options.intro) + transition_in(component.$$.fragment); + mount_component(component, options.target, options.anchor, options.customElement); + flush(); + } + set_current_component(parent_component); + } + /** + * Base class for Svelte components. Used when dev=false. + */ + class SvelteComponent { + $destroy() { + destroy_component(this, 1); + this.$destroy = noop; + } + $on(type, callback) { + const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = [])); + callbacks.push(callback); + return () => { + const index = callbacks.indexOf(callback); + if (index !== -1) + callbacks.splice(index, 1); + }; + } + $set($$props) { + if (this.$$set && !is_empty($$props)) { + this.$$.skip_bound = true; + this.$$set($$props); + this.$$.skip_bound = false; + } + } + } + + function dispatch_dev(type, detail) { + document.dispatchEvent(custom_event(type, Object.assign({ version: '3.46.4' }, detail), true)); + } + function append_dev(target, node) { + dispatch_dev('SvelteDOMInsert', { target, node }); + append(target, node); + } + function insert_dev(target, node, anchor) { + dispatch_dev('SvelteDOMInsert', { target, node, anchor }); + insert(target, node, anchor); + } + function detach_dev(node) { + dispatch_dev('SvelteDOMRemove', { node }); + detach(node); + } + function listen_dev(node, event, handler, options, has_prevent_default, has_stop_propagation) { + const modifiers = options === true ? ['capture'] : options ? Array.from(Object.keys(options)) : []; + if (has_prevent_default) + modifiers.push('preventDefault'); + if (has_stop_propagation) + modifiers.push('stopPropagation'); + dispatch_dev('SvelteDOMAddEventListener', { node, event, handler, modifiers }); + const dispose = listen(node, event, handler, options); + return () => { + dispatch_dev('SvelteDOMRemoveEventListener', { node, event, handler, modifiers }); + dispose(); + }; + } + function attr_dev(node, attribute, value) { + attr(node, attribute, value); + if (value == null) + dispatch_dev('SvelteDOMRemoveAttribute', { node, attribute }); + else + dispatch_dev('SvelteDOMSetAttribute', { node, attribute, value }); + } + function set_data_dev(text, data) { + data = '' + data; + if (text.wholeText === data) + return; + dispatch_dev('SvelteDOMSetData', { node: text, data }); + text.data = data; + } + function validate_each_argument(arg) { + if (typeof arg !== 'string' && !(arg && typeof arg === 'object' && 'length' in arg)) { + let msg = '{#each} only iterates over array-like objects.'; + if (typeof Symbol === 'function' && arg && Symbol.iterator in arg) { + msg += ' You can use a spread to convert this iterable into an array.'; + } + throw new Error(msg); + } + } + function validate_slots(name, slot, keys) { + for (const slot_key of Object.keys(slot)) { + if (!~keys.indexOf(slot_key)) { + console.warn(`<${name}> received an unexpected slot "${slot_key}".`); + } + } + } + /** + * Base class for Svelte components with some minor dev-enhancements. Used when dev=true. + */ + class SvelteComponentDev extends SvelteComponent { + constructor(options) { + if (!options || (!options.target && !options.$$inline)) { + throw new Error("'target' is a required option"); + } + super(); + } + $destroy() { + super.$destroy(); + this.$destroy = () => { + console.warn('Component was already destroyed'); // eslint-disable-line no-console + }; + } + $capture_state() { } + $inject_state() { } + } + + const villesData = { + "Cadiz": { "x": 144, "y": 1072, "nom": "Cadiz" }, + "Madrid": { "x": 147, "y": 946, "nom": "Madrid" }, + "Barcelona": { "x": 336, "y": 961, "nom": "Barcelona" }, + "Lisboa": { "x": 32, "y": 981, "nom": "Lisboa" }, + "Pamplona": { "x": 318, "y": 805, "nom": "Pamplona" }, + "Paris": { "x": 425, "y": 544, "nom": "Paris" }, + "Dieppe": { "x": 341, "y": 467, "nom": "Dieppe" }, + "Brest": { "x": 188, "y": 516, "nom": "Brest" }, + "London": { "x": 358, "y": 313, "nom": "London" }, + "Amsterdam": { "x": 524, "y": 319, "nom": "Amsterdam" }, + "Bruxelles": { "x": 485, "y": 399, "nom": "Bruxelles" }, + "Edinburgh": { "x": 245, "y": 56, "nom": "Edinburgh" }, + "Zurich": { "x": 622, "y": 638, "nom": "Zurich" }, + "Marseille": { "x": 575, "y": 797, "nom": "Marseille" }, + "Frankfurt": { "x": 638, "y": 454, "nom": "Frankfurt" }, + "Munchen": { "x": 737, "y": 530, "nom": "Munchen" }, + "Wien": { "x": 930, "y": 559, "nom": "Wien" }, + "Venezia": { "x": 763, "y": 694, "nom": "Venezia" }, + "Roma": { "x": 779, "y": 849, "nom": "Roma" }, + "Brindisi": { "x": 925, "y": 892, "nom": "Brindisi" }, + "Palermo": { "x": 841, "y": 1072, "nom": "Palermo" }, + "Athina": { "x": 1136, "y": 1024, "nom": "Athina" }, + "Sofia": { "x": 1167, "y": 830, "nom": "Sofia" }, + "Sarajevo": { "x": 1053, "y": 815, "nom": "Sarajevo" }, + "Zagrab": { "x": 908, "y": 714, "nom": "Zagrab" }, + "Budapest": { "x": 1014, "y": 602, "nom": "Budapest" }, + "Kyiv": { "x": 1370, "y": 438, "nom": "Kyiv" }, + "Warszawa": { "x": 1113, "y": 345, "nom": "Warszawa" }, + "Wilno": { "x": 1302, "y": 303, "nom": "Wilno" }, + "Smolensk": { "x": 1479, "y": 310, "nom": "Smolensk" }, + "Moskva": { "x": 1625, "y": 269, "nom": "Moskva" }, + "Kharkov": { "x": 1600, "y": 528, "nom": "Kharkov" }, + "Rostov": { "x": 1671, "y": 618, "nom": "Rostov" }, + "Sochi": { "x": 1660, "y": 770, "nom": "Sochi" }, + "Erzurum": { "x": 1628, "y": 986, "nom": "Erzurum" }, + "Constantinople": { "x": 1358, "y": 932, "nom": "Constantinople" }, + "Angora": { "x": 1492, "y": 1026, "nom": "Angora" }, + "Smyrna": { "x": 1282, "y": 1068, "nom": "Smyrna" }, + "Essen": { "x": 663, "y": 335, "nom": "Essen" }, + "Berlin": { "x": 834, "y": 359, "nom": "Berlin" }, + "Kobenhavn": { "x": 784, "y": 155, "nom": "Kobenhavn" }, + "Stockholm": { "x": 963, "y": 22, "nom": "Stockholm" }, + "Riga": { "x": 1169, "y": 71, "nom": "Riga" }, + "Petrograd": { "x": 1458, "y": 64, "nom": "Petrograd" }, + "Danzig": { "x": 1028, "y": 226, "nom": "Danzig" }, + "Bucuresti": { "x": 1271, "y": 721, "nom": "Bucuresti" }, + "Sevastopol": { "x": 1508, "y": 746, "nom": "Sevastopol" } + }; + + const routesData = [ + { "ville1": "Amsterdam", "ville2": "Bruxelles", "longueur": 1, "couleur": "NOIR", "isTunnel": false, "ferry": 0, "segments": [{ "x": 504.5, "y": 361.5, "dx": -0.42661867571297646, "dy": 0.9044315925115101 }] }, + { "ville1": "Amsterdam", "ville2": "Essen", "longueur": 3, "couleur": "JAUNE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 528.5, "y": 276, "dx": 0.21871145691738075, "dy": -0.9757895770160064 }, { "x": 574, "y": 265, "dx": 0.9778024140774094, "dy": 0.20952908873087345 }, { "x": 629, "y": 300, "dx": 0.6368814469962913, "dy": 0.7709617516270895 }] }, + { "ville1": "Amsterdam", "ville2": "Frankfurt", "longueur": 2, "couleur": "BLANC", "isTunnel": false, "ferry": 0, "segments": [{ "x": 562, "y": 358.5, "dx": 0.6983238520753277, "dy": 0.7157819483772108 }, { "x": 606, "y": 403, "dx": 0.7249994335944138, "dy": 0.688749461914693 }] }, + { "ville1": "Amsterdam", "ville2": "London", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 2, "segments": [{ "x": 405, "y": 312, "dx": 1, "dy": 0 }, { "x": 469, "y": 314.5, "dx": 0.9998514005489976, "dy": 0.017238817250844786 }] }, + { "ville1": "Angora", "ville2": "Constantinople", "longueur": 2, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 1399, "y": 959, "dx": 0.8209052017854871, "dy": 0.5710644881985998 }, { "x": 1452, "y": 998, "dx": 0.8041761414663255, "dy": 0.5943910610838058 }] }, + { "ville1": "Angora", "ville2": "Erzurum", "longueur": 3, "couleur": "NOIR", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1533.5, "y": 1046, "dx": 0.8765785507795943, "dy": 0.48125881219271843 }, { "x": 1597, "y": 1059.5, "dx": 0.9812488205210874, "dy": -0.19274530403092788 }, { "x": 1635.5, "y": 1031.5, "dx": -0.16148856811054085, "dy": -0.9868745828977495 }] }, + { "ville1": "Angora", "ville2": "Smyrna", "longueur": 3, "couleur": "ORANGE", "isTunnel": true, "ferry": 0, "segments": [{ "x": 1329.5, "y": 1072.5, "dx": 0.9998347517133227, "dy": 0.01817881366751496 }, { "x": 1392.5, "y": 1072, "dx": 0.9895864392845114, "dy": -0.14393984571411075 }, { "x": 1455.5, "y": 1054, "dx": 0.8765785507795943, "dy": -0.48125881219271843 }] }, + { "ville1": "Athina", "ville2": "Brindisi", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 1, "segments": [{ "x": 957, "y": 928, "dx": 0.389639990836698, "dy": 0.9209672510685588 }, { "x": 982, "y": 986.5, "dx": 0.38337767164151665, "dy": 0.9235916635000174 }, { "x": 1027.5, "y": 1030.5, "dx": 0.9554026409829016, "dy": 0.2953062708492605 }, { "x": 1093.5, "y": 1036, "dx": 0.9838699100999074, "dy": -0.17888543819998318 }] }, + { "ville1": "Athina", "ville2": "Sarajevo", "longueur": 4, "couleur": "VERT", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1052.5, "y": 859, "dx": -0.053494721371611896, "dy": 0.9985681322700888 }, { "x": 1049, "y": 922.5, "dx": -0.035066140133044446, "dy": 0.9993849937917667 }, { "x": 1045.5, "y": 986.5, "dx": -0.08444307668618062, "dy": 0.9964283048969312 }, { "x": 1087.5, "y": 1007, "dx": 0.9994259471398348, "dy": 0.033878845665757114 }] }, + { "ville1": "Athina", "ville2": "Smyrna", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 1, "segments": [{ "x": 1180.5, "y": 1022, "dx": 0.9994259471398348, "dy": -0.033878845665757114 }, { "x": 1244.5, "y": 1036.5, "dx": 0.9044315925115101, "dy": 0.42661867571297646 }] }, + { "ville1": "Athina", "ville2": "Sofia", "longueur": 3, "couleur": "ROSE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1136, "y": 861, "dx": -0.6709133239691262, "dy": 0.7415357791237711 }, { "x": 1109.5, "y": 921, "dx": -0.11982016019085814, "dy": 0.9927956130099675 }, { "x": 1123, "y": 983, "dx": 0.52999894000318, "dy": 0.847998304005088 }] }, + { "ville1": "Barcelona", "ville2": "Madrid", "longueur": 2, "couleur": "JAUNE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 221.5, "y": 954.5, "dx": 0.9998563940539735, "dy": 0.016946718543287685 }, { "x": 285.5, "y": 956.5, "dx": 0.9986178293325098, "dy": 0.052558833122763673 }] }, + { "ville1": "Barcelona", "ville2": "Marseille", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 370.5, "y": 926, "dx": 0.6610305430689966, "dy": -0.7503589948350772 }, { "x": 415.5, "y": 881.5, "dx": 0.7407190347407712, "dy": -0.6718149384858157 }, { "x": 467.5, "y": 843.5, "dx": 0.8692901189279536, "dy": -0.4943022244884442 }, { "x": 525, "y": 818, "dx": 0.9377487607237036, "dy": -0.34731435582359393 }] }, + { "ville1": "Barcelona", "ville2": "Pamplona", "longueur": 2, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 322.5, "y": 852.5, "dx": 0.09053574604251853, "dy": 0.9958932064677039 }, { "x": 329.5, "y": 917.5, "dx": 0.11781773987828967, "dy": 0.9930352361170129 }] }, + { "ville1": "Berlin", "ville2": "Danzig", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 842.5, "y": 306.5, "dx": 0.1559625734730109, "dy": -0.987762965329069 }, { "x": 867.5, "y": 246.5, "dx": 0.5746304214759497, "dy": -0.8184130245263527 }, { "x": 922.5, "y": 210, "dx": 0.978549784986749, "dy": -0.2060104810498419 }, { "x": 987, "y": 210, "dx": 0.9778024140774094, "dy": 0.20952908873087345 }] }, + { "ville1": "Berlin", "ville2": "Essen", "longueur": 2, "couleur": "BLEU", "isTunnel": false, "ferry": 0, "segments": [{ "x": 726.5, "y": 331.5, "dx": 0.9925434552766405, "dy": 0.12189130152520146 }, { "x": 789.5, "y": 339, "dx": 0.9945054529214061, "dy": 0.10468478451804275 }] }, + { "ville1": "Berlin", "ville2": "Frankfurt", "longueur": 3, "couleur": "ROUGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 686.5, "y": 452.5, "dx": 0.9173450110960782, "dy": -0.3980931180228264 }, { "x": 743, "y": 424.5, "dx": 0.9012524245251862, "dy": -0.43329443486787794 }, { "x": 800, "y": 397.5, "dx": 0.9012524245251862, "dy": -0.43329443486787794 }] }, + { "ville1": "Berlin", "ville2": "Frankfurt", "longueur": 3, "couleur": "NOIR", "isTunnel": false, "ferry": 0, "segments": [{ "x": 676, "y": 432.5, "dx": 0.9012524245251862, "dy": -0.43329443486787794 }, { "x": 734, "y": 405.5, "dx": 0.9084904526785746, "dy": -0.41790560823214434 }, { "x": 790.5, "y": 378, "dx": 0.8909061469019802, "dy": -0.4541874474402252 }] }, + { "ville1": "Berlin", "ville2": "Warszawa", "longueur": 4, "couleur": "JAUNE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 877, "y": 365.5, "dx": 0.9469787003150827, "dy": -0.3212963447497602 }, { "x": 940, "y": 350.5, "dx": 0.988173903359179, "dy": -0.15333732983159673 }, { "x": 1003, "y": 347, "dx": 0.9993628543475496, "dy": -0.03569153051241249 }, { "x": 1065.5, "y": 350.5, "dx": 0.987762965329069, "dy": 0.1559625734730109 }] }, + { "ville1": "Berlin", "ville2": "Warszawa", "longueur": 4, "couleur": "ROSE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 875.5, "y": 341.5, "dx": 0.9486832980505138, "dy": -0.31622776601683794 }, { "x": 939.5, "y": 326.5, "dx": 0.9925434552766405, "dy": -0.12189130152520146 }, { "x": 1002, "y": 322, "dx": 0.9994059993535875, "dy": -0.03446227583977888 }, { "x": 1067, "y": 327, "dx": 0.9906211292434748, "dy": 0.13663739713703102 }] }, + { "ville1": "Berlin", "ville2": "Wien", "longueur": 3, "couleur": "VERT", "isTunnel": false, "ferry": 0, "segments": [{ "x": 847, "y": 408.5, "dx": 0.2890045919356118, "dy": 0.9573277107867141 }, { "x": 870.5, "y": 467, "dx": 0.47514891473488396, "dy": 0.8799053976571926 }, { "x": 906, "y": 520.5, "dx": 0.6246950475544243, "dy": 0.7808688094430304 }] }, + { "ville1": "Brest", "ville2": "Dieppe", "longueur": 2, "couleur": "ORANGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 225, "y": 482.5, "dx": 0.8650311892618034, "dy": -0.501718089771846 }, { "x": 287.5, "y": 464, "dx": 0.9977097021176764, "dy": -0.06764133573679162 }] }, + { "ville1": "Brest", "ville2": "Pamplona", "longueur": 4, "couleur": "ROSE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 229.5, "y": 549.5, "dx": 0.9342183861793726, "dy": 0.3567015656321241 }, { "x": 280, "y": 591, "dx": 0.5547001962252291, "dy": 0.8320502943378437 }, { "x": 302, "y": 652, "dx": 0.1414213562373095, "dy": 0.9899494936611665 }, { "x": 306, "y": 716, "dx": 0, "dy": 1 }] }, + { "ville1": "Brest", "ville2": "Paris", "longueur": 3, "couleur": "NOIR", "isTunnel": false, "ferry": 0, "segments": [{ "x": 235, "y": 521, "dx": 0.9946917938265513, "dy": 0.1028991510855053 }, { "x": 298.5, "y": 529, "dx": 0.9945054529214061, "dy": 0.10468478451804275 }, { "x": 360.5, "y": 536.5, "dx": 0.9964283048969312, "dy": 0.08444307668618062 }] }, + { "ville1": "Brindisi", "ville2": "Palermo", "longueur": 3, "couleur": "GRIS", "isTunnel": false, "ferry": 1, "segments": [{ "x": 880.5, "y": 1047.5, "dx": 0.6139406135149205, "dy": -0.7893522173763263 }, { "x": 923, "y": 998.5, "dx": 0.7327934916262993, "dy": -0.6804510993672779 }, { "x": 936.5, "y": 937, "dx": -0.40450601477770304, "dy": -0.9145353377582851 }] }, + { "ville1": "Brindisi", "ville2": "Roma", "longueur": 2, "couleur": "BLANC", "isTunnel": false, "ferry": 0, "segments": [{ "x": 832.5, "y": 833, "dx": 0.9902939771518443, "dy": -0.13898862837218867 }, { "x": 892.5, "y": 856, "dx": 0.6610305430689966, "dy": 0.7503589948350772 }] }, + { "ville1": "Bruxelles", "ville2": "Dieppe", "longueur": 2, "couleur": "VERT", "isTunnel": false, "ferry": 0, "segments": [{ "x": 387, "y": 447.5, "dx": 0.8346094065617252, "dy": -0.5508422083307386 }, { "x": 440, "y": 411, "dx": 0.8041761414663255, "dy": -0.5943910610838058 }] }, + { "ville1": "Bruxelles", "ville2": "Frankfurt", "longueur": 2, "couleur": "BLEU", "isTunnel": false, "ferry": 0, "segments": [{ "x": 528.5, "y": 403, "dx": 0.9690971739229421, "dy": -0.24667928063493072 }, { "x": 590.5, "y": 420, "dx": 0.7321867381630838, "dy": 0.6811039424772872 }] }, + { "ville1": "Bruxelles", "ville2": "Paris", "longueur": 2, "couleur": "JAUNE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 432.5, "y": 495, "dx": 0.47312663795681303, "dy": -0.8809944292988933 }, { "x": 462.5, "y": 439, "dx": 0.43329443486787794, "dy": -0.9012524245251862 }] }, + { "ville1": "Bruxelles", "ville2": "Paris", "longueur": 2, "couleur": "ROUGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 452.5, "y": 505.5, "dx": 0.4678877204190327, "dy": -0.8837879163470618 }, { "x": 482.5, "y": 449.5, "dx": 0.4678877204190327, "dy": -0.8837879163470618 }] }, + { "ville1": "Bucuresti", "ville2": "Budapest", "longueur": 4, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 1058, "y": 613.5, "dx": 0.8944271909999159, "dy": 0.4472135954999579 }, { "x": 1114.5, "y": 644, "dx": 0.8833490206949295, "dy": 0.46871580689935033 }, { "x": 1170, "y": 674, "dx": 0.8872168012345951, "dy": 0.46135273664198945 }, { "x": 1227, "y": 703.5, "dx": 0.8944271909999159, "dy": 0.4472135954999579 }] }, + { "ville1": "Bucuresti", "ville2": "Constantinople", "longueur": 3, "couleur": "JAUNE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1289.5, "y": 766, "dx": 0.40450601477770304, "dy": 0.9145353377582851 }, { "x": 1314.5, "y": 824, "dx": 0.39186206512519167, "dy": 0.9200239789895804 }, { "x": 1339, "y": 882, "dx": 0.4061384660534476, "dy": 0.9138115486202572 }] }, + { "ville1": "Bucuresti", "ville2": "Kyiv", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1337, "y": 492, "dx": -0.284088329691374, "dy": 0.9587981127083872 }, { "x": 1317.5, "y": 552, "dx": -0.343192952923539, "dy": 0.9392649237907383 }, { "x": 1298, "y": 612.5, "dx": -0.3215824263578902, "dy": 0.9468815887204546 }, { "x": 1278, "y": 672, "dx": -0.3271105638831663, "dy": 0.9449860734402582 }] }, + { "ville1": "Bucuresti", "ville2": "Sevastopol", "longueur": 4, "couleur": "BLANC", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1307.5, "y": 690.5, "dx": 0.7071067811865476, "dy": -0.7071067811865476 }, { "x": 1365, "y": 657.5, "dx": 0.965948051503245, "dy": -0.2587360852240835 }, { "x": 1430.5, "y": 665, "dx": 0.9040722665053037, "dy": 0.4273796168934163 }, { "x": 1480.5, "y": 705, "dx": 0.6055218324832624, "dy": 0.7958286941208591 }] }, + { "ville1": "Bucuresti", "ville2": "Sofia", "longueur": 2, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 1209.5, "y": 809.5, "dx": 0.9582877607731983, "dy": -0.28580512163411176 }, { "x": 1250, "y": 762.5, "dx": 0.13436367297357807, "dy": -0.9909320881801382 }] }, + { "ville1": "Budapest", "ville2": "Kyiv", "longueur": 6, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 1037.5, "y": 561, "dx": 0.6633075143158518, "dy": -0.7483469392281404 }, { "x": 1084, "y": 518, "dx": 0.8209052017854871, "dy": -0.5710644881985998 }, { "x": 1139, "y": 483.5, "dx": 0.8799053976571926, "dy": -0.47514891473488396 }, { "x": 1197.5, "y": 459, "dx": 0.9468815887204546, "dy": -0.3215824263578902 }, { "x": 1260, "y": 446, "dx": 0.9974586998307351, "dy": -0.07124704998790965 }, { "x": 1324, "y": 446.5, "dx": 0.9998405993454448, "dy": 0.017854296416882943 }] }, + { "ville1": "Budapest", "ville2": "Sarajevo", "longueur": 3, "couleur": "ROSE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1026, "y": 646.5, "dx": 0.14393984571411075, "dy": 0.9895864392845114 }, { "x": 1035, "y": 709, "dx": 0.1757906384836575, "dy": 0.984427575508482 }, { "x": 1044.5, "y": 772, "dx": 0.12403473458920845, "dy": 0.9922778767136676 }] }, + { "ville1": "Budapest", "ville2": "Wien", "longueur": 1, "couleur": "ROUGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 973.5, "y": 578, "dx": 0.8528513040762654, "dy": 0.5221538596385299 }] }, + { "ville1": "Budapest", "ville2": "Wien", "longueur": 1, "couleur": "BLANC", "isTunnel": false, "ferry": 0, "segments": [{ "x": 962, "y": 596, "dx": 0.8574929257125442, "dy": 0.5144957554275266 }] }, + { "ville1": "Budapest", "ville2": "Zagrab", "longueur": 2, "couleur": "ORANGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 987.5, "y": 639, "dx": -0.501718089771846, "dy": 0.8650311892618034 }, { "x": 946.5, "y": 689.5, "dx": -0.7724254859909581, "dy": 0.6351053995925655 }] }, + { "ville1": "Cadiz", "ville2": "Lisboa", "longueur": 2, "couleur": "BLEU", "isTunnel": false, "ferry": 0, "segments": [{ "x": 50, "y": 1025.5, "dx": 0.4125075533080444, "dy": 0.9109541802219313 }, { "x": 100, "y": 1063.5, "dx": 0.9812488205210874, "dy": 0.19274530403092788 }] }, + { "ville1": "Cadiz", "ville2": "Madrid", "longueur": 3, "couleur": "ORANGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 189, "y": 1062, "dx": 0.9377487607237036, "dy": -0.34731435582359393 }, { "x": 222.5, "y": 1027.5, "dx": -0.3265202527980472, "dy": -0.9451902054680315 }, { "x": 184.5, "y": 976, "dx": -0.7493290854811462, "dy": -0.6621977964717106 }] }, + { "ville1": "Constantinople", "ville2": "Sevastopol", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 2, "segments": [{ "x": 1490.5, "y": 791.5, "dx": -0.017541160386140585, "dy": 0.9998461420100133 }, { "x": 1471, "y": 852.5, "dx": -0.5795237863600037, "dy": 0.8149553245687551 }, { "x": 1428.5, "y": 874, "dx": -0.7938781460016401, "dy": -0.6080768777884903 }, { "x": 1386.5, "y": 896.5, "dx": -0.6139406135149205, "dy": 0.7893522173763263 }] }, + { "ville1": "Constantinople", "ville2": "Smyrna", "longueur": 2, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 1301.5, "y": 1026.5, "dx": 0.42661867571297646, "dy": -0.9044315925115101 }, { "x": 1330.5, "y": 968.5, "dx": 0.41110775310681835, "dy": -0.911586756889032 }] }, + { "ville1": "Constantinople", "ville2": "Sofia", "longueur": 3, "couleur": "BLEU", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1206, "y": 853, "dx": 0.8725060159497201, "dy": 0.48860336893184325 }, { "x": 1262, "y": 883, "dx": 0.879291966536774, "dy": 0.4762831485407526 }, { "x": 1317, "y": 913.5, "dx": 0.8650311892618034, "dy": 0.501718089771846 }] }, + { "ville1": "Danzig", "ville2": "Riga", "longueur": 3, "couleur": "NOIR", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1041.5, "y": 182.5, "dx": 0.27232246579934893, "dy": -0.9622060458243663 }, { "x": 1071, "y": 125.5, "dx": 0.6028330891856919, "dy": -0.7978673239222394 }, { "x": 1123.5, "y": 89, "dx": 0.9503971290446889, "dy": -0.3110390604146254 }] }, + { "ville1": "Danzig", "ville2": "Warszawa", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1068, "y": 247, "dx": 0.847998304005088, "dy": 0.52999894000318 }, { "x": 1103.5, "y": 299, "dx": 0.22612970719934952, "dy": 0.9740972002433518 }] }, + { + "ville1": "Dieppe", "ville2": "London", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 1, "segments": [ + { "x": 330.5, "y": 419.5, "dx": -0.08738374771484403, "dy": 0.9961747239492219 }, + { "x": 336.5, "y": 358, "dx": -0.08588834215301201, "dy": 0.9963047689749394 }, + ] + }, + { "ville1": "Dieppe", "ville2": "London", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 1, "segments": [{ "x": 354.5, "y": 422.5, "dx": 0.08444307668618062, "dy": -0.9964283048969312 }, { "x": 360, "y": 359.5, "dx": 0.10468478451804275, "dy": -0.9945054529214061 }] }, + { "ville1": "Dieppe", "ville2": "Paris", "longueur": 1, "couleur": "ROSE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 379.5, "y": 500.5, "dx": 0.7071067811865475, "dy": 0.7071067811865475 }] }, + { "ville1": "Edinburgh", "ville2": "London", "longueur": 4, "couleur": "ORANGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 276.5, "y": 96, "dx": 0.42012356811103757, "dy": 0.9074669071198412 }, { "x": 301, "y": 154.5, "dx": 0.38337767164151665, "dy": 0.9235916635000174 }, { "x": 325, "y": 212, "dx": 0.389639990836698, "dy": 0.9209672510685588 }, { "x": 349.5, "y": 269.5, "dx": 0.3980931180228264, "dy": 0.9173450110960782 }] }, + { "ville1": "Edinburgh", "ville2": "London", "longueur": 4, "couleur": "NOIR", "isTunnel": false, "ferry": 0, "segments": [{ "x": 255.5, "y": 105.5, "dx": 0.41110775310681835, "dy": 0.911586756889032 }, { "x": 280.5, "y": 163.5, "dx": 0.3980931180228264, "dy": 0.9173450110960782 }, { "x": 305, "y": 220, "dx": 0.40273861426601687, "dy": 0.9153150324227656 }, { "x": 329, "y": 277.5, "dx": 0.3960911114346502, "dy": 0.9182112128712345 }] }, + { "ville1": "Erzurum", "ville2": "Sevastopol", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 2, "segments": [{ "x": 1514, "y": 792, "dx": 0, "dy": 1 }, { "x": 1518.5, "y": 854, "dx": 0.15867809538375516, "dy": 0.9873303712766988 }, { "x": 1542, "y": 914, "dx": 0.5710644881985998, "dy": 0.8209052017854871 }, { "x": 1588.5, "y": 960, "dx": 0.8372705045624257, "dy": 0.546788900938727 }] }, + { "ville1": "Erzurum", "ville2": "Sochi", "longueur": 3, "couleur": "ROUGE", "isTunnel": true, "ferry": 0, "segments": [{ "x": 1653.5, "y": 817, "dx": -0.12403473458920845, "dy": 0.9922778767136676 }, { "x": 1644.5, "y": 880, "dx": -0.15867809538375516, "dy": 0.9873303712766988 }, { "x": 1635.5, "y": 942.5, "dx": -0.12625427967391514, "dy": 0.9919979117236188 }] }, + { "ville1": "Essen", "ville2": "Frankfurt", "longueur": 2, "couleur": "VERT", "isTunnel": false, "ferry": 0, "segments": [{ "x": 666, "y": 412, "dx": 0.8944271909999159, "dy": -0.4472135954999579 }, { "x": 698, "y": 374.5, "dx": -0.4541874474402252, "dy": -0.8909061469019802 }] }, + { "ville1": "Essen", "ville2": "Kobenhavn", "longueur": 3, "couleur": "GRIS", "isTunnel": false, "ferry": 1, "segments": [{ "x": 677, "y": 288, "dx": 0.5390536964233673, "dy": -0.8422714006615114 }, { "x": 713, "y": 235, "dx": 0.5547001962252291, "dy": -0.8320502943378437 }, { "x": 748, "y": 182, "dx": 0.5547001962252291, "dy": -0.8320502943378437 }] }, + { "ville1": "Essen", "ville2": "Kobenhavn", "longueur": 3, "couleur": "GRIS", "isTunnel": false, "ferry": 1, "segments": [{ "x": 695.5, "y": 300, "dx": 0.5665288228870652, "dy": -0.8240419241993676 }, { "x": 731, "y": 246, "dx": 0.5462677805469223, "dy": -0.8376105968386142 }, { "x": 765.5, "y": 196, "dx": 0.5665288228870652, "dy": -0.8240419241993676 }] }, + { "ville1": "Frankfurt", "ville2": "Munchen", "longueur": 2, "couleur": "ROSE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 654, "y": 500, "dx": 0.31622776601683794, "dy": 0.9486832980505138 }, { "x": 684.5, "y": 534.5, "dx": 0.9582877607731983, "dy": -0.28580512163411176 }] }, + { "ville1": "Frankfurt", "ville2": "Paris", "longueur": 3, "couleur": "ORANGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 494, "y": 553.5, "dx": 0.9568805766427723, "dy": -0.29048160362369874 }, { "x": 552, "y": 527, "dx": 0.8422714006615114, "dy": -0.5390536964233673 }, { "x": 605.5, "y": 491.5, "dx": 0.8137334712067349, "dy": -0.5812381937190964 }] }, + { "ville1": "Frankfurt", "ville2": "Paris", "longueur": 3, "couleur": "BLANC", "isTunnel": false, "ferry": 0, "segments": [{ "x": 482.5, "y": 533, "dx": 0.939793423488437, "dy": -0.3417430630867044 }, { "x": 541, "y": 506.5, "dx": 0.8400393777687709, "dy": -0.5425254314756646 }, { "x": 594, "y": 471.5, "dx": 0.8240419241993676, "dy": -0.5665288228870652 }] }, + { "ville1": "Kharkov", "ville2": "Kyiv", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1386, "y": 482, "dx": 0.34731435582359393, "dy": 0.9377487607237036 }, { "x": 1428, "y": 531, "dx": 0.8804710999221753, "dy": 0.47409982303501746 }, { "x": 1490.5, "y": 547.5, "dx": 0.9986178293325098, "dy": 0.052558833122763673 }, { "x": 1554, "y": 540, "dx": 0.9486832980505138, "dy": -0.31622776601683794 }] }, + { "ville1": "Kharkov", "ville2": "Moskva", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1628.5, "y": 491, "dx": 0.6985367247883851, "dy": -0.7155742058807848 }, { "x": 1661.5, "y": 437, "dx": 0.2676438637860946, "dy": -0.9635179096299405 }, { "x": 1666, "y": 372, "dx": -0.1414213562373095, "dy": -0.9899494936611665 }, { "x": 1647, "y": 309.5, "dx": -0.4541874474402252, "dy": -0.8909061469019802 }] }, + { "ville1": "Kharkov", "ville2": "Rostov", "longueur": 2, "couleur": "VERT", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1651, "y": 528, "dx": 1, "dy": 0 }, { "x": 1670.5, "y": 573.5, "dx": 0.017541160386140585, "dy": 0.9998461420100133 }] }, + { "ville1": "Kobenhavn", "ville2": "Stockholm", "longueur": 3, "couleur": "JAUNE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 808.5, "y": 114, "dx": 0.6804510993672779, "dy": -0.7327934916262993 }, { "x": 855, "y": 70.5, "dx": 0.7483469392281404, "dy": -0.6633075143158518 }, { "x": 908, "y": 34, "dx": 0.8804710999221753, "dy": -0.47409982303501746 }] }, + { "ville1": "Kobenhavn", "ville2": "Stockholm", "longueur": 3, "couleur": "BLANC", "isTunnel": false, "ferry": 0, "segments": [{ "x": 825, "y": 132, "dx": 0.6896551724137931, "dy": -0.7241379310344828 }, { "x": 870, "y": 87.5, "dx": 0.7503589948350772, "dy": -0.6610305430689966 }, { "x": 923.5, "y": 50.5, "dx": 0.8837879163470618, "dy": -0.4678877204190327 }] }, + { "ville1": "Kyiv", "ville2": "Smolensk", "longueur": 3, "couleur": "ROUGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1418.5, "y": 440.5, "dx": 0.9986178293325098, "dy": 0.052558833122763673 }, { "x": 1477.5, "y": 417, "dx": 0.7157819483772108, "dy": -0.6983238520753277 }, { "x": 1492, "y": 355.5, "dx": -0.2890045919356118, "dy": -0.9573277107867141 }] }, + { "ville1": "Kyiv", "ville2": "Warszawa", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1143.5, "y": 376.5, "dx": 0.689213765997513, "dy": 0.7245580616896932 }, { "x": 1196, "y": 413, "dx": 0.9377487607237036, "dy": 0.34731435582359393 }, { "x": 1258.5, "y": 422.5, "dx": 0.9986178293325098, "dy": -0.052558833122763673 }, { "x": 1322.5, "y": 423.5, "dx": 0.9986178293325098, "dy": 0.052558833122763673 }] }, + { "ville1": "Kyiv", "ville2": "Wilno", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1344, "y": 330.5, "dx": 0.8400393777687709, "dy": 0.5425254314756646 }, { "x": 1372, "y": 389.5, "dx": 0, "dy": 1 }] }, + { "ville1": "Lisboa", "ville2": "Madrid", "longueur": 3, "couleur": "ROSE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 30, "y": 940, "dx": 0, "dy": -1 }, { "x": 49.5, "y": 896, "dx": 0.9994259471398348, "dy": 0.033878845665757114 }, { "x": 111, "y": 917.5, "dx": 0.8080075302163774, "dy": 0.5891721574494418 }] }, + { "ville1": "Madrid", "ville2": "Pamplona", "longueur": 3, "couleur": "BLANC", "isTunnel": true, "ferry": 0, "segments": [{ "x": 186, "y": 920.5, "dx": 0.6419366564593427, "dy": -0.7667576729931038 }, { "x": 229, "y": 874, "dx": 0.7071067811865475, "dy": -0.7071067811865475 }, { "x": 278.5, "y": 833, "dx": 0.8372705045624257, "dy": -0.546788900938727 }] }, + { "ville1": "Madrid", "ville2": "Pamplona", "longueur": 3, "couleur": "NOIR", "isTunnel": true, "ferry": 0, "segments": [{ "x": 171, "y": 905, "dx": 0.6536198703460924, "dy": -0.7568230077691596 }, { "x": 212.5, "y": 857, "dx": 0.6804510993672779, "dy": -0.7327934916262993 }, { "x": 261, "y": 817, "dx": 0.8422714006615114, "dy": -0.5390536964233673 }] }, + { "ville1": "Marseille", "ville2": "Pamplona", "longueur": 4, "couleur": "ROUGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 367.5, "y": 823, "dx": 0.9503971290446889, "dy": 0.3110390604146254 }, { "x": 401, "y": 790.5, "dx": 0.35305725243424235, "dy": -0.9356017189507422 }, { "x": 452.5, "y": 753.5, "dx": 0.9998461420100133, "dy": -0.017541160386140585 }, { "x": 516.5, "y": 770.5, "dx": 0.8979207227269799, "dy": 0.44015721702302935 }] }, + { "ville1": "Marseille", "ville2": "Paris", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 553, "y": 756, "dx": -0.5547001962252291, "dy": -0.8320502943378437 }, { "x": 505.5, "y": 713.5, "dx": -0.8837879163470618, "dy": -0.4678877204190327 }, { "x": 457, "y": 670.5, "dx": -0.5700815482062942, "dy": -0.821588113591424 }, { "x": 436.5, "y": 608.5, "dx": -0.054464493159869794, "dy": -0.9985157079309461 }] }, + { "ville1": "Marseille", "ville2": "Roma", "longueur": 4, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 620, "y": 778, "dx": 0.8041761414663255, "dy": -0.5943910610838058 }, { "x": 671, "y": 741.5, "dx": 0.8, "dy": -0.6 }, { "x": 712, "y": 762.5, "dx": 0.6028330891856919, "dy": 0.7978673239222394 }, { "x": 750, "y": 813.5, "dx": 0.6028330891856919, "dy": 0.7978673239222394 }] }, + { "ville1": "Marseille", "ville2": "Zurich", "longueur": 2, "couleur": "ROSE", "isTunnel": true, "ferry": 0, "segments": [{ "x": 615, "y": 683.5, "dx": -0.2553911228370322, "dy": 0.9668378221687647 }, { "x": 599, "y": 746.5, "dx": -0.2890045919356118, "dy": 0.9573277107867141 }] }, + { "ville1": "Moskva", "ville2": "Petrograd", "longueur": 4, "couleur": "BLANC", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1504, "y": 79.5, "dx": 0.9538492507391959, "dy": 0.30028587523270983 }, { "x": 1561, "y": 110, "dx": 0.8041761414663255, "dy": 0.5943910610838058 }, { "x": 1600, "y": 161, "dx": 0.4472135954999579, "dy": 0.8944271909999159 }, { "x": 1617, "y": 222, "dx": 0.07124704998790965, "dy": 0.9974586998307351 }] }, + { "ville1": "Moskva", "ville2": "Smolensk", "longueur": 2, "couleur": "ORANGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1526, "y": 314, "dx": 0.994309153919809, "dy": 0.10653312363426524 }, { "x": 1587, "y": 295.5, "dx": 0.8080075302163774, "dy": -0.5891721574494418 }] }, + { "ville1": "Munchen", "ville2": "Venezia", "longueur": 2, "couleur": "BLEU", "isTunnel": true, "ferry": 0, "segments": [{ "x": 742, "y": 587, "dx": 0.18208926018230742, "dy": 0.9832820049844601 }, { "x": 754, "y": 651, "dx": 0.20952908873087345, "dy": 0.9778024140774094 }] }, + { "ville1": "Munchen", "ville2": "Wien", "longueur": 3, "couleur": "ORANGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 768.5, "y": 566, "dx": 0.6055218324832624, "dy": 0.7958286941208591 }, { "x": 826, "y": 594.5, "dx": 0.9986649849421085, "dy": 0.0516550854280401 }, { "x": 887, "y": 574.5, "dx": 0.7792134503124135, "dy": -0.6267586448165066 }] }, + { "ville1": "Munchen", "ville2": "Zurich", "longueur": 2, "couleur": "JAUNE", "isTunnel": true, "ferry": 0, "segments": [{ "x": 656.5, "y": 609.5, "dx": 0.7407190347407712, "dy": -0.6718149384858157 }, { "x": 702.5, "y": 564, "dx": 0.7321867381630838, "dy": -0.6811039424772872 }] }, + { + "ville1": "Palermo", "ville2": "Roma", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 1, "segments": [ + { "x": 864, "y": 1032, "dx": -0.5943910610838058, "dy": 0.8041761414663255 }, + { "x": 884.5, "y": 972, "dx": -0.017238817250844786, "dy": 0.9998514005489976 }, + { "x": 866, "y": 911, "dx": 0.6163082616581107, "dy": 0.7875050010075858 }, + { "x": 818, "y": 867.5, "dx": 0.8799053976571926, "dy": 0.47514891473488396 }, + ] + }, + { + "ville1": "Palermo", "ville2": "Smyrna", "longueur": 6, "couleur": "GRIS", "isTunnel": false, "ferry": 2, "segments": [ + { "x": 1236.5, "y": 1069, "dx": 1, "dy": 0 }, + { "x": 1172.5, "y": 1069, "dx": 1, "dy": 0 }, + { "x": 1110.5, "y": 1069, "dx": 1, "dy": 0 }, + { "x": 1048.5, "y": 1069, "dx": 1, "dy": 0 }, + { "x": 984, "y": 1069, "dx": 1, "dy": 0 }, + { "x": 920, "y": 1069, "dx": 1, "dy": 0 }, + ] + }, + { "ville1": "Pamplona", "ville2": "Paris", "longueur": 4, "couleur": "BLEU", "isTunnel": false, "ferry": 0, "segments": [{ "x": 321.5, "y": 763, "dx": 0.5891721574494418, "dy": -0.8080075302163774 }, { "x": 353.5, "y": 706.5, "dx": 0.34570535882735637, "dy": -0.9383431168171101 }, { "x": 374, "y": 647, "dx": 0.24253562503633297, "dy": -0.9701425001453319 }, { "x": 387.5, "y": 584, "dx": 0.15333732983159673, "dy": -0.988173903359179 }] }, + { "ville1": "Pamplona", "ville2": "Paris", "longueur": 4, "couleur": "VERT", "isTunnel": false, "ferry": 0, "segments": [{ "x": 343.5, "y": 770.5, "dx": 0.597266145998167, "dy": -0.8020431103403957 }, { "x": 376, "y": 713, "dx": 0.37729688731351946, "dy": -0.9260923597695477 }, { "x": 397, "y": 654, "dx": 0.27472112789737807, "dy": -0.9615239476408232 }, { "x": 410.5, "y": 592, "dx": 0.11982016019085814, "dy": -0.9927956130099675 }] }, + { "ville1": "Paris", "ville2": "Zurich", "longueur": 3, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 468.5, "y": 594, "dx": 0.5171156399255817, "dy": 0.8559155419457903 }, { "x": 515.5, "y": 636.5, "dx": 0.9052369440730288, "dy": 0.4249071370138707 }, { "x": 578.5, "y": 650, "dx": 1, "dy": 0 }] }, + { "ville1": "Petrograd", "ville2": "Riga", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1216.5, "y": 73, "dx": 1, "dy": 0 }, { "x": 1281, "y": 74, "dx": 0.9993628543475496, "dy": -0.03569153051241249 }, { "x": 1344, "y": 72, "dx": 0.9993148337667671, "dy": -0.037011660509880265 }, { "x": 1407, "y": 71.5, "dx": 0.9985681322700888, "dy": -0.053494721371611896 }] }, + { "ville1": "Petrograd", "ville2": "Stockholm", "longueur": 8, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 994, "y": 57, "dx": 0.6332377902572627, "dy": 0.773957299203321 }, { "x": 1040, "y": 48, "dx": 0.8041761414663255, "dy": -0.5943910610838058 }, { "x": 1099.5, "y": 26.5, "dx": 0.9998347517133227, "dy": 0.01817881366751496 }, { "x": 1163, "y": 26.5, "dx": 0.9998405993454448, "dy": 0.017854296416882943 }, { "x": 1226.5, "y": 25.5, "dx": 0.9998461420100133, "dy": -0.017541160386140585 }, { "x": 1289.5, "y": 26, "dx": 1, "dy": 0 }, { "x": 1352.5, "y": 26.5, "dx": 0.9998347517133227, "dy": -0.01817881366751496 }, { "x": 1416.5, "y": 39, "dx": 0.9165393783696333, "dy": 0.39994445601584 }] }, + { "ville1": "Petrograd", "ville2": "Wilno", "longueur": 4, "couleur": "BLEU", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1326, "y": 261, "dx": 0.5943910610838058, "dy": -0.8041761414663255 }, { "x": 1364, "y": 209.5, "dx": 0.5627909770820216, "dy": -0.8265992475892192 }, { "x": 1400.5, "y": 158, "dx": 0.5829078754517308, "dy": -0.8125382506296854 }, { "x": 1437, "y": 107.5, "dx": 0.5861197865287227, "dy": -0.8102244107897049 }] }, + { "ville1": "Riga", "ville2": "Wilno", "longueur": 4, "couleur": "VERT", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1167, "y": 119, "dx": -0.16990691650764622, "dy": 0.985460115744348 }, { "x": 1175, "y": 182, "dx": 0.4190581774617469, "dy": 0.9079593845004517 }, { "x": 1216, "y": 230.5, "dx": 0.8559155419457903, "dy": 0.5171156399255817 }, { "x": 1270, "y": 264.5, "dx": 0.8400393777687709, "dy": 0.5425254314756646 }] }, + { "ville1": "Roma", "ville2": "Venezia", "longueur": 2, "couleur": "NOIR", "isTunnel": false, "ferry": 0, "segments": [{ "x": 772.5, "y": 740, "dx": 0.19274530403092788, "dy": 0.9812488205210874 }, { "x": 784, "y": 803.5, "dx": 0.17888543819998318, "dy": 0.9838699100999074 }] }, + { "ville1": "Rostov", "ville2": "Sevastopol", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1526, "y": 703, "dx": 0.13663739713703102, "dy": -0.9906211292434748 }, { "x": 1534.5, "y": 640, "dx": 0.15867809538375516, "dy": -0.9873303712766988 }, { "x": 1561, "y": 598, "dx": 0.9906211292434748, "dy": 0.13663739713703102 }, { "x": 1623.5, "y": 609, "dx": 0.9849570246463139, "dy": 0.17279947800812523 }] }, + { "ville1": "Rostov", "ville2": "Sochi", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1667.5, "y": 663, "dx": -0.053494721371611896, "dy": 0.9985681322700888 }, { "x": 1664, "y": 726.5, "dx": -0.07000328148073091, "dy": 0.9975467611004155 }] }, + { "ville1": "Sarajevo", "ville2": "Sofia", "longueur": 2, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 1096, "y": 793, "dx": 0.9079593845004517, "dy": -0.4190581774617469 }, { "x": 1143.5, "y": 792, "dx": 0.47514891473488396, "dy": 0.8799053976571926 }] }, + { "ville1": "Sarajevo", "ville2": "Zagrab", "longueur": 3, "couleur": "ROUGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 913.5, "y": 761.5, "dx": 0.12189130152520146, "dy": 0.9925434552766405 }, { "x": 946, "y": 815.5, "dx": 0.8125382506296854, "dy": 0.5829078754517308 }, { "x": 1010, "y": 825.5, "dx": 0.9433123908373908, "dy": -0.3319062115909338 }] }, + { "ville1": "Sevastopol", "ville2": "Sochi", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 1, "segments": [{ "x": 1554, "y": 753, "dx": 0.9899494936611665, "dy": 0.1414213562373095 }, { "x": 1616, "y": 763, "dx": 0.9899494936611665, "dy": 0.1414213562373095 }] }, + { "ville1": "Smolensk", "ville2": "Wilno", "longueur": 3, "couleur": "JAUNE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1344.5, "y": 274.5, "dx": 0.5812381937190964, "dy": -0.8137334712067349 }, { "x": 1386, "y": 251, "dx": 0.8160244811016552, "dy": 0.5780173407803391 }, { "x": 1438, "y": 289, "dx": 0.8160244811016552, "dy": 0.5780173407803391 }] }, + { "ville1": "Venezia", "ville2": "Zagrab", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 808, "y": 680.5, "dx": 0.965948051503245, "dy": -0.2587360852240835 }, { "x": 870.5, "y": 691.5, "dx": 0.8450788360522153, "dy": 0.5346417126044628 }] }, + { "ville1": "Venezia", "ville2": "Zurich", "longueur": 2, "couleur": "VERT", "isTunnel": true, "ferry": 0, "segments": [{ "x": 664.5, "y": 659.5, "dx": 0.8837879163470618, "dy": 0.4678877204190327 }, { "x": 721.5, "y": 689, "dx": 0.8765785507795943, "dy": 0.48125881219271843 }] }, + { "ville1": "Warszawa", "ville2": "Wien", "longueur": 4, "couleur": "BLEU", "isTunnel": false, "ferry": 0, "segments": [{ "x": 966.5, "y": 531.5, "dx": 0.860576682823999, "dy": -0.5093208939162444 }, { "x": 1016.5, "y": 493.5, "dx": 0.7423931175486519, "dy": -0.6699645207146371 }, { "x": 1059.5, "y": 446, "dx": 0.5891721574494418, "dy": -0.8080075302163774 }, { "x": 1094, "y": 392.5, "dx": 0.5221538596385299, "dy": -0.8528513040762654 }] }, + { "ville1": "Warszawa", "ville2": "Wilno", "longueur": 3, "couleur": "ROUGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1142.5, "y": 310.5, "dx": 0.4678877204190327, "dy": -0.8837879163470618 }, { "x": 1194, "y": 272, "dx": 0.9761870601839528, "dy": -0.21693045781865616 }, { "x": 1257, "y": 285, "dx": 0.847998304005088, "dy": 0.52999894000318 }] }, + { "ville1": "Wien", "ville2": "Zagrab", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 912.5, "y": 667, "dx": 0.08588834215301201, "dy": -0.9963047689749394 }, { "x": 916.5, "y": 604.5, "dx": 0.054464493159869794, "dy": -0.9985157079309461 }] } + ]; + + const subscriber_queue = []; + /** + * Create a `Writable` store that allows both updating and reading by subscription. + * @param {*=}value initial value + * @param {StartStopNotifier=}start start and stop notifications for subscriptions + */ + function writable(value, start = noop) { + let stop; + const subscribers = new Set(); + function set(new_value) { + if (safe_not_equal(value, new_value)) { + value = new_value; + if (stop) { // store is ready + const run_queue = !subscriber_queue.length; + for (const subscriber of subscribers) { + subscriber[1](); + subscriber_queue.push(subscriber, value); + } + if (run_queue) { + for (let i = 0; i < subscriber_queue.length; i += 2) { + subscriber_queue[i][0](subscriber_queue[i + 1]); + } + subscriber_queue.length = 0; + } + } + } + } + function update(fn) { + set(fn(value)); + } + function subscribe(run, invalidate = noop) { + const subscriber = [run, invalidate]; + subscribers.add(subscriber); + if (subscribers.size === 1) { + stop = start(set) || noop; + } + run(value); + return () => { + subscribers.delete(subscriber); + if (subscribers.size === 0) { + stop(); + stop = null; + } + }; + } + return { set, update, subscribe }; + } + + let hostname = window.location.hostname; + if (hostname === "") { + hostname = "localhost"; + } + + const ws = writable(new WebSocket(`ws://${hostname}:3232`)); + + /* src/Plateau.svelte generated by Svelte v3.46.4 */ + + const { Object: Object_1, console: console_1$4 } = globals; + const file$5 = "src/Plateau.svelte"; + + function get_each_context$5(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[9] = list[i]; + return child_ctx; + } + + function get_each_context_1$2(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[12] = list[i]; + return child_ctx; + } + + function get_each_context_2$1(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[15] = list[i]; + child_ctx[17] = i; + return child_ctx; + } + + function get_each_context_3(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[9] = list[i]; + return child_ctx; + } + + function get_each_context_4(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[12] = list[i]; + return child_ctx; + } + + function get_each_context_5(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[15] = list[i]; + child_ctx[17] = i; + return child_ctx; + } + + // (106:8) {#each route.segments as segment, i} + function create_each_block_5(ctx) { + let g; + let rect; + let g_transform_value; + + const block = { + c: function create() { + g = svg_element("g"); + rect = svg_element("rect"); + attr_dev(rect, "x", -LONGUEUR_SEGMENT / 2); + attr_dev(rect, "y", -LARGEUR_SEGMENT / 2); + attr_dev(rect, "width", LONGUEUR_SEGMENT); + attr_dev(rect, "height", LARGEUR_SEGMENT); + add_location(rect, file$5, 111, 12, 2930); + attr_dev(g, "class", "segment"); + attr_dev(g, "transform", g_transform_value = "translate(" + /*segment*/ ctx[15].x + ", " + /*segment*/ ctx[15].y + ")\n rotate(" + Math.atan2(/*segment*/ ctx[15].dy, /*segment*/ ctx[15].dx) * 180 / Math.PI + ")"); + add_location(g, file$5, 106, 10, 2740); + }, + m: function mount(target, anchor) { + insert_dev(target, g, anchor); + append_dev(g, rect); + }, + p: function update(ctx, dirty) { + if (dirty & /*routes*/ 2 && g_transform_value !== (g_transform_value = "translate(" + /*segment*/ ctx[15].x + ", " + /*segment*/ ctx[15].y + ")\n rotate(" + Math.atan2(/*segment*/ ctx[15].dy, /*segment*/ ctx[15].dx) * 180 / Math.PI + ")")) { + attr_dev(g, "transform", g_transform_value); + } + }, + d: function destroy(detaching) { + if (detaching) detach_dev(g); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_each_block_5.name, + type: "each", + source: "(106:8) {#each route.segments as segment, i}", + ctx + }); + + return block; + } + + // (101:4) {#each routes as route} + function create_each_block_4(ctx) { + let g; + let mounted; + let dispose; + let each_value_5 = /*route*/ ctx[12].segments; + validate_each_argument(each_value_5); + let each_blocks = []; + + for (let i = 0; i < each_value_5.length; i += 1) { + each_blocks[i] = create_each_block_5(get_each_context_5(ctx, each_value_5, i)); + } + + function click_handler() { + return /*click_handler*/ ctx[4](/*route*/ ctx[12]); + } + + const block = { + c: function create() { + g = svg_element("g"); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + attr_dev(g, "class", "route svelte-1s8m8k5"); + add_location(g, file$5, 101, 6, 2609); + }, + m: function mount(target, anchor) { + insert_dev(target, g, anchor); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(g, null); + } + + if (!mounted) { + dispose = listen_dev(g, "click", click_handler, false, false, false); + mounted = true; + } + }, + p: function update(new_ctx, dirty) { + ctx = new_ctx; + + if (dirty & /*routes, Math, LONGUEUR_SEGMENT, LARGEUR_SEGMENT*/ 2) { + each_value_5 = /*route*/ ctx[12].segments; + validate_each_argument(each_value_5); + let i; + + for (i = 0; i < each_value_5.length; i += 1) { + const child_ctx = get_each_context_5(ctx, each_value_5, i); + + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block_5(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(g, null); + } + } + + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } + + each_blocks.length = each_value_5.length; + } + }, + d: function destroy(detaching) { + if (detaching) detach_dev(g); + destroy_each(each_blocks, detaching); + mounted = false; + dispose(); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_each_block_4.name, + type: "each", + source: "(101:4) {#each routes as route}", + ctx + }); + + return block; + } + + // (124:4) {#each villes as ville} + function create_each_block_3(ctx) { + let g; + let circle; + let g_transform_value; + let mounted; + let dispose; + + function click_handler_1() { + return /*click_handler_1*/ ctx[5](/*ville*/ ctx[9]); + } + + const block = { + c: function create() { + g = svg_element("g"); + circle = svg_element("circle"); + attr_dev(circle, "cx", "0"); + attr_dev(circle, "cy", "0"); + attr_dev(circle, "r", RAYON_VILLE); + add_location(circle, file$5, 129, 8, 3376); + attr_dev(g, "class", "ville svelte-1s8m8k5"); + attr_dev(g, "transform", g_transform_value = "translate(" + /*ville*/ ctx[9].x + ", " + /*ville*/ ctx[9].y + ")"); + add_location(g, file$5, 124, 6, 3242); + }, + m: function mount(target, anchor) { + insert_dev(target, g, anchor); + append_dev(g, circle); + + if (!mounted) { + dispose = listen_dev(g, "click", click_handler_1, false, false, false); + mounted = true; + } + }, + p: function update(new_ctx, dirty) { + ctx = new_ctx; + + if (dirty & /*villes*/ 1 && g_transform_value !== (g_transform_value = "translate(" + /*ville*/ ctx[9].x + ", " + /*ville*/ ctx[9].y + ")")) { + attr_dev(g, "transform", g_transform_value); + } + }, + d: function destroy(detaching) { + if (detaching) detach_dev(g); + mounted = false; + dispose(); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_each_block_3.name, + type: "each", + source: "(124:4) {#each villes as ville}", + ctx + }); + + return block; + } + + // (150:10) {#if route.proprietaire !== undefined} + function create_if_block_1(ctx) { + let g; + let image; + let image_xlink_href_value; + let g_transform_value; + + const block = { + c: function create() { + g = svg_element("g"); + image = svg_element("image"); + xlink_attr(image, "xlink:href", image_xlink_href_value = "images/image-wagon-" + /*route*/ ctx[12].proprietaire + ".png"); + attr_dev(image, "width", TAILLE_WAGON); + attr_dev(image, "height", TAILLE_WAGON); + attr_dev(image, "transform", "translate(" + -TAILLE_WAGON * 0.55 + ", " + -TAILLE_WAGON / 2 + ")"); + add_location(image, file$5, 154, 14, 4066); + attr_dev(g, "transform", g_transform_value = "translate(" + /*segment*/ ctx[15].x + ", " + /*segment*/ ctx[15].y + ")\n rotate(" + Math.atan2(/*segment*/ ctx[15].dy, /*segment*/ ctx[15].dx) * 180 / Math.PI + ")"); + add_location(g, file$5, 150, 12, 3896); + }, + m: function mount(target, anchor) { + insert_dev(target, g, anchor); + append_dev(g, image); + }, + p: function update(ctx, dirty) { + if (dirty & /*routes*/ 2 && image_xlink_href_value !== (image_xlink_href_value = "images/image-wagon-" + /*route*/ ctx[12].proprietaire + ".png")) { + xlink_attr(image, "xlink:href", image_xlink_href_value); + } + + if (dirty & /*routes*/ 2 && g_transform_value !== (g_transform_value = "translate(" + /*segment*/ ctx[15].x + ", " + /*segment*/ ctx[15].y + ")\n rotate(" + Math.atan2(/*segment*/ ctx[15].dy, /*segment*/ ctx[15].dx) * 180 / Math.PI + ")")) { + attr_dev(g, "transform", g_transform_value); + } + }, + d: function destroy(detaching) { + if (detaching) detach_dev(g); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_if_block_1.name, + type: "if", + source: "(150:10) {#if route.proprietaire !== undefined}", + ctx + }); + + return block; + } + + // (149:8) {#each route.segments as segment, i} + function create_each_block_2$1(ctx) { + let if_block_anchor; + let if_block = /*route*/ ctx[12].proprietaire !== undefined && create_if_block_1(ctx); + + const block = { + c: function create() { + if (if_block) if_block.c(); + if_block_anchor = empty(); + }, + m: function mount(target, anchor) { + if (if_block) if_block.m(target, anchor); + insert_dev(target, if_block_anchor, anchor); + }, + p: function update(ctx, dirty) { + if (/*route*/ ctx[12].proprietaire !== undefined) { + if (if_block) { + if_block.p(ctx, dirty); + } else { + if_block = create_if_block_1(ctx); + if_block.c(); + if_block.m(if_block_anchor.parentNode, if_block_anchor); + } + } else if (if_block) { + if_block.d(1); + if_block = null; + } + }, + d: function destroy(detaching) { + if (if_block) if_block.d(detaching); + if (detaching) detach_dev(if_block_anchor); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_each_block_2$1.name, + type: "each", + source: "(149:8) {#each route.segments as segment, i}", + ctx + }); + + return block; + } + + // (147:4) {#each routes as route} + function create_each_block_1$2(ctx) { + let g; + let each_value_2 = /*route*/ ctx[12].segments; + validate_each_argument(each_value_2); + let each_blocks = []; + + for (let i = 0; i < each_value_2.length; i += 1) { + each_blocks[i] = create_each_block_2$1(get_each_context_2$1(ctx, each_value_2, i)); + } + + const block = { + c: function create() { + g = svg_element("g"); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + attr_dev(g, "class", "no-pointer svelte-1s8m8k5"); + add_location(g, file$5, 147, 6, 3767); + }, + m: function mount(target, anchor) { + insert_dev(target, g, anchor); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(g, null); + } + }, + p: function update(ctx, dirty) { + if (dirty & /*routes, Math, TAILLE_WAGON, undefined*/ 2) { + each_value_2 = /*route*/ ctx[12].segments; + validate_each_argument(each_value_2); + let i; + + for (i = 0; i < each_value_2.length; i += 1) { + const child_ctx = get_each_context_2$1(ctx, each_value_2, i); + + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block_2$1(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(g, null); + } + } + + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } + + each_blocks.length = each_value_2.length; + } + }, + d: function destroy(detaching) { + if (detaching) detach_dev(g); + destroy_each(each_blocks, detaching); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_each_block_1$2.name, + type: "each", + source: "(147:4) {#each routes as route}", + ctx + }); + + return block; + } + + // (169:6) {#if ville.proprietaire !== undefined} + function create_if_block$3(ctx) { + let g; + let image0; + let image1; + let image1_xlink_href_value; + let g_transform_value; + + const block = { + c: function create() { + g = svg_element("g"); + image0 = svg_element("image"); + image1 = svg_element("image"); + xlink_attr(image0, "xlink:href", "images/gare-shadow.png"); + attr_dev(image0, "width", TAILLE_GARE * 1.05); + attr_dev(image0, "height", TAILLE_GARE * 1.05); + attr_dev(image0, "transform", "translate(" + -TAILLE_GARE * 0.55 + ", " + -TAILLE_GARE * 0.75 + ")"); + add_location(image0, file$5, 170, 10, 4601); + xlink_attr(image1, "xlink:href", image1_xlink_href_value = "images/gare-" + /*ville*/ ctx[9].proprietaire + ".png"); + attr_dev(image1, "width", TAILLE_GARE); + attr_dev(image1, "height", TAILLE_GARE); + attr_dev(image1, "transform", "translate(" + -TAILLE_GARE * 0.6 + ", " + -TAILLE_GARE * 0.7 + ")"); + add_location(image1, file$5, 176, 10, 4838); + attr_dev(g, "class", "no-pointer svelte-1s8m8k5"); + attr_dev(g, "transform", g_transform_value = "translate(" + /*ville*/ ctx[9].x + ", " + /*ville*/ ctx[9].y + ")"); + add_location(g, file$5, 169, 8, 4524); + }, + m: function mount(target, anchor) { + insert_dev(target, g, anchor); + append_dev(g, image0); + append_dev(g, image1); + }, + p: function update(ctx, dirty) { + if (dirty & /*villes*/ 1 && image1_xlink_href_value !== (image1_xlink_href_value = "images/gare-" + /*ville*/ ctx[9].proprietaire + ".png")) { + xlink_attr(image1, "xlink:href", image1_xlink_href_value); + } + + if (dirty & /*villes*/ 1 && g_transform_value !== (g_transform_value = "translate(" + /*ville*/ ctx[9].x + ", " + /*ville*/ ctx[9].y + ")")) { + attr_dev(g, "transform", g_transform_value); + } + }, + d: function destroy(detaching) { + if (detaching) detach_dev(g); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_if_block$3.name, + type: "if", + source: "(169:6) {#if ville.proprietaire !== undefined}", + ctx + }); + + return block; + } + + // (168:4) {#each villes as ville} + function create_each_block$5(ctx) { + let if_block_anchor; + let if_block = /*ville*/ ctx[9].proprietaire !== undefined && create_if_block$3(ctx); + + const block = { + c: function create() { + if (if_block) if_block.c(); + if_block_anchor = empty(); + }, + m: function mount(target, anchor) { + if (if_block) if_block.m(target, anchor); + insert_dev(target, if_block_anchor, anchor); + }, + p: function update(ctx, dirty) { + if (/*ville*/ ctx[9].proprietaire !== undefined) { + if (if_block) { + if_block.p(ctx, dirty); + } else { + if_block = create_if_block$3(ctx); + if_block.c(); + if_block.m(if_block_anchor.parentNode, if_block_anchor); + } + } else if (if_block) { + if_block.d(1); + if_block = null; + } + }, + d: function destroy(detaching) { + if (if_block) if_block.d(detaching); + if (detaching) detach_dev(if_block_anchor); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_each_block$5.name, + type: "each", + source: "(168:4) {#each villes as ville}", + ctx + }); + + return block; + } + + function create_fragment$5(ctx) { + let svg; + let each0_anchor; + let rect; + let each2_anchor; + let image; + let mounted; + let dispose; + let each_value_4 = /*routes*/ ctx[1]; + validate_each_argument(each_value_4); + let each_blocks_3 = []; + + for (let i = 0; i < each_value_4.length; i += 1) { + each_blocks_3[i] = create_each_block_4(get_each_context_4(ctx, each_value_4, i)); + } + + let each_value_3 = /*villes*/ ctx[0]; + validate_each_argument(each_value_3); + let each_blocks_2 = []; + + for (let i = 0; i < each_value_3.length; i += 1) { + each_blocks_2[i] = create_each_block_3(get_each_context_3(ctx, each_value_3, i)); + } + + let each_value_1 = /*routes*/ ctx[1]; + validate_each_argument(each_value_1); + let each_blocks_1 = []; + + for (let i = 0; i < each_value_1.length; i += 1) { + each_blocks_1[i] = create_each_block_1$2(get_each_context_1$2(ctx, each_value_1, i)); + } + + let each_value = /*villes*/ ctx[0]; + validate_each_argument(each_value); + let each_blocks = []; + + for (let i = 0; i < each_value.length; i += 1) { + each_blocks[i] = create_each_block$5(get_each_context$5(ctx, each_value, i)); + } + + const block = { + c: function create() { + svg = svg_element("svg"); + + for (let i = 0; i < each_blocks_3.length; i += 1) { + each_blocks_3[i].c(); + } + + each0_anchor = empty(); + + for (let i = 0; i < each_blocks_2.length; i += 1) { + each_blocks_2[i].c(); + } + + rect = svg_element("rect"); + + for (let i = 0; i < each_blocks_1.length; i += 1) { + each_blocks_1[i].c(); + } + + each2_anchor = empty(); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + image = svg_element("image"); + attr_dev(rect, "id", "cache"); + attr_dev(rect, "class", "no-pointer svelte-1s8m8k5"); + attr_dev(rect, "x", "0"); + attr_dev(rect, "y", "0"); + attr_dev(rect, "width", "1701"); + attr_dev(rect, "height", "1097"); + attr_dev(rect, "fill", "#fffc"); + set_style(rect, "visibility", "hidden"); + add_location(rect, file$5, 134, 4, 3514); + xlink_attr(image, "xlink:href", "images/toggle-button.png"); + attr_dev(image, "x", "0"); + attr_dev(image, "y", "0"); + attr_dev(image, "width", "80"); + attr_dev(image, "height", "80"); + add_location(image, file$5, 187, 4, 5153); + attr_dev(svg, "id", "board"); + attr_dev(svg, "xmlns", "http://www.w3.org/2000/svg"); + attr_dev(svg, "xmlns:xlink", "http://www.w3.org/1999/xlink"); + attr_dev(svg, "viewBox", "0 0 1701 1097"); + attr_dev(svg, "class", "svelte-1s8m8k5"); + add_location(svg, file$5, 93, 2, 2406); + }, + l: function claim(nodes) { + throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); + }, + m: function mount(target, anchor) { + insert_dev(target, svg, anchor); + + for (let i = 0; i < each_blocks_3.length; i += 1) { + each_blocks_3[i].m(svg, null); + } + + append_dev(svg, each0_anchor); + + for (let i = 0; i < each_blocks_2.length; i += 1) { + each_blocks_2[i].m(svg, null); + } + + append_dev(svg, rect); + + for (let i = 0; i < each_blocks_1.length; i += 1) { + each_blocks_1[i].m(svg, null); + } + + append_dev(svg, each2_anchor); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(svg, null); + } + + append_dev(svg, image); + + if (!mounted) { + dispose = listen_dev(image, "click", toggleTracks, false, false, false); + mounted = true; + } + }, + p: function update(ctx, [dirty]) { + if (dirty & /*send, routes, Math, LONGUEUR_SEGMENT, LARGEUR_SEGMENT*/ 6) { + each_value_4 = /*routes*/ ctx[1]; + validate_each_argument(each_value_4); + let i; + + for (i = 0; i < each_value_4.length; i += 1) { + const child_ctx = get_each_context_4(ctx, each_value_4, i); + + if (each_blocks_3[i]) { + each_blocks_3[i].p(child_ctx, dirty); + } else { + each_blocks_3[i] = create_each_block_4(child_ctx); + each_blocks_3[i].c(); + each_blocks_3[i].m(svg, each0_anchor); + } + } + + for (; i < each_blocks_3.length; i += 1) { + each_blocks_3[i].d(1); + } + + each_blocks_3.length = each_value_4.length; + } + + if (dirty & /*villes, send, RAYON_VILLE*/ 5) { + each_value_3 = /*villes*/ ctx[0]; + validate_each_argument(each_value_3); + let i; + + for (i = 0; i < each_value_3.length; i += 1) { + const child_ctx = get_each_context_3(ctx, each_value_3, i); + + if (each_blocks_2[i]) { + each_blocks_2[i].p(child_ctx, dirty); + } else { + each_blocks_2[i] = create_each_block_3(child_ctx); + each_blocks_2[i].c(); + each_blocks_2[i].m(svg, rect); + } + } + + for (; i < each_blocks_2.length; i += 1) { + each_blocks_2[i].d(1); + } + + each_blocks_2.length = each_value_3.length; + } + + if (dirty & /*routes, Math, TAILLE_WAGON, undefined*/ 2) { + each_value_1 = /*routes*/ ctx[1]; + validate_each_argument(each_value_1); + let i; + + for (i = 0; i < each_value_1.length; i += 1) { + const child_ctx = get_each_context_1$2(ctx, each_value_1, i); + + if (each_blocks_1[i]) { + each_blocks_1[i].p(child_ctx, dirty); + } else { + each_blocks_1[i] = create_each_block_1$2(child_ctx); + each_blocks_1[i].c(); + each_blocks_1[i].m(svg, each2_anchor); + } + } + + for (; i < each_blocks_1.length; i += 1) { + each_blocks_1[i].d(1); + } + + each_blocks_1.length = each_value_1.length; + } + + if (dirty & /*villes, TAILLE_GARE, undefined*/ 1) { + each_value = /*villes*/ ctx[0]; + validate_each_argument(each_value); + let i; + + for (i = 0; i < each_value.length; i += 1) { + const child_ctx = get_each_context$5(ctx, each_value, i); + + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block$5(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(svg, image); + } + } + + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } + + each_blocks.length = each_value.length; + } + }, + i: noop, + o: noop, + d: function destroy(detaching) { + if (detaching) detach_dev(svg); + destroy_each(each_blocks_3, detaching); + destroy_each(each_blocks_2, detaching); + destroy_each(each_blocks_1, detaching); + destroy_each(each_blocks, detaching); + mounted = false; + dispose(); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_fragment$5.name, + type: "component", + source: "", + ctx + }); + + return block; + } + + const LONGUEUR_SEGMENT = 60; + const LARGEUR_SEGMENT = 20; + const TAILLE_WAGON = 70; + const TAILLE_GARE = 50; + const RAYON_VILLE = 12; + + function toggleTracks() { + const cache = document.getElementById("cache"); + + if (cache.style.visibility === "hidden") { + cache.style.visibility = ""; + } else { + cache.style.visibility = "hidden"; + } + } + + function instance$5($$self, $$props, $$invalidate) { + let $ws; + validate_store(ws, 'ws'); + component_subscribe($$self, ws, $$value => $$invalidate(6, $ws = $$value)); + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots('Plateau', slots, []); + let { props } = $$props; + + function send(message) { + console.log(`Message: "${message}"`); + $ws.send(message); + } + + class Ville { + constructor(nom, x, y) { + this.nom = nom; + this.x = x; + this.y = y; + this.proprietaire = undefined; + } + } + + class Route { + constructor(ville1, ville2, longueur, couleur, isTunnel, ferry, segments) { + this.ville1 = ville1; + this.ville2 = ville2; + this.longueur = longueur; + this.couleur = couleur; + this.isTunnel = isTunnel; + this.ferry = ferry; + this.label = `${ville1} - ${ville2}`; + this.segments = segments; + this.proprietaire = undefined; + } + } + + const villes = Object.values(villesData).map(data => new Ville(data.nom, data.x, data.y)); + const routes = routesData.map(data => new Route(data.ville1, data.ville2, data.longueur, data.couleur, data.isTunnel, data.ferry, data.segments)); + + // Corriger les labels des routes multiples + for (let i = 0; i < routes.length - 1; i++) { + if (routes[i].label === routes[i + 1].label) { + routes[i].label += "(1)"; + routes[i + 1].label += "(2)"; + } + } + + beforeUpdate(() => { + for (const routeData of props.routes) { + if (routeData.proprietaire) { + routes.filter(r => r.label === routeData.nom)[0].proprietaire = routeData.proprietaire; + } + } + + for (const villeData of props.villes) { + if (villeData.proprietaire) { + villes.filter(v => v.nom === villeData.nom)[0].proprietaire = villeData.proprietaire; + } + } + + $$invalidate(1, routes); + $$invalidate(0, villes); + }); + + const writable_props = ['props']; + + Object_1.keys($$props).forEach(key => { + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== '$$' && key !== 'slot') console_1$4.warn(` was created with unknown prop '${key}'`); + }); + + const click_handler = route => send(route.label); + const click_handler_1 = ville => send(ville.nom); + + $$self.$$set = $$props => { + if ('props' in $$props) $$invalidate(3, props = $$props.props); + }; + + $$self.$capture_state = () => ({ + beforeUpdate, + villesData, + routesData, + ws, + props, + LONGUEUR_SEGMENT, + LARGEUR_SEGMENT, + TAILLE_WAGON, + TAILLE_GARE, + RAYON_VILLE, + toggleTracks, + send, + Ville, + Route, + villes, + routes, + $ws + }); + + $$self.$inject_state = $$props => { + if ('props' in $$props) $$invalidate(3, props = $$props.props); + }; + + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + + return [villes, routes, send, props, click_handler, click_handler_1]; + } + + class Plateau extends SvelteComponentDev { + constructor(options) { + super(options); + init(this, options, instance$5, create_fragment$5, safe_not_equal, { props: 3 }); + + dispatch_dev("SvelteRegisterComponent", { + component: this, + tagName: "Plateau", + options, + id: create_fragment$5.name + }); + + const { ctx } = this.$$; + const props = options.props || {}; + + if (/*props*/ ctx[3] === undefined && !('props' in props)) { + console_1$4.warn(" was created without expected prop 'props'"); + } + } + + get props() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set props(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + } + + /* src/Joueur.svelte generated by Svelte v3.46.4 */ + + const { console: console_1$3 } = globals; + const file$4 = "src/Joueur.svelte"; + + function get_each_context$4(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[5] = list[i]; + return child_ctx; + } + + function get_each_context_1$1(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[5] = list[i]; + return child_ctx; + } + + function get_each_context_2(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[10] = list[i]; + return child_ctx; + } + + // (27:12) {#each props.destinations as destination} + function create_each_block_2(ctx) { + let div; + let t0_value = /*destination*/ ctx[10].ville1 + ""; + let t0; + let t1; + let t2_value = /*destination*/ ctx[10].ville2 + ""; + let t2; + let t3; + let t4_value = /*destination*/ ctx[10].valeur + ""; + let t4; + let t5; + let mounted; + let dispose; + + function click_handler() { + return /*click_handler*/ ctx[2](/*destination*/ ctx[10]); + } + + const block = { + c: function create() { + div = element("div"); + t0 = text(t0_value); + t1 = text(" - "); + t2 = text(t2_value); + t3 = text(" ("); + t4 = text(t4_value); + t5 = text(")\n "); + attr_dev(div, "class", "destination"); + add_location(div, file$4, 27, 16, 866); + }, + m: function mount(target, anchor) { + insert_dev(target, div, anchor); + append_dev(div, t0); + append_dev(div, t1); + append_dev(div, t2); + append_dev(div, t3); + append_dev(div, t4); + append_dev(div, t5); + + if (!mounted) { + dispose = listen_dev(div, "click", click_handler, false, false, false); + mounted = true; + } + }, + p: function update(new_ctx, dirty) { + ctx = new_ctx; + if (dirty & /*props*/ 1 && t0_value !== (t0_value = /*destination*/ ctx[10].ville1 + "")) set_data_dev(t0, t0_value); + if (dirty & /*props*/ 1 && t2_value !== (t2_value = /*destination*/ ctx[10].ville2 + "")) set_data_dev(t2, t2_value); + if (dirty & /*props*/ 1 && t4_value !== (t4_value = /*destination*/ ctx[10].valeur + "")) set_data_dev(t4, t4_value); + }, + d: function destroy(detaching) { + if (detaching) detach_dev(div); + mounted = false; + dispose(); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_each_block_2.name, + type: "each", + source: "(27:12) {#each props.destinations as destination}", + ctx + }); + + return block; + } + + // (37:12) {#each props.cartesWagon as wagon} + function create_each_block_1$1(ctx) { + let div1; + let div0; + let t; + let div1_class_value; + let mounted; + let dispose; + + function click_handler_1() { + return /*click_handler_1*/ ctx[3](/*wagon*/ ctx[5]); + } + + const block = { + c: function create() { + div1 = element("div"); + div0 = element("div"); + t = space(); + attr_dev(div0, "class", "image-wagon svelte-vqlws6"); + set_style(div0, "background-image", "url(images/carte-wagon-" + /*wagon*/ ctx[5] + ".png"); + add_location(div0, file$4, 41, 20, 1371); + attr_dev(div1, "class", div1_class_value = "carte-wagon " + /*wagon*/ ctx[5] + " svelte-vqlws6"); + add_location(div1, file$4, 37, 16, 1231); + }, + m: function mount(target, anchor) { + insert_dev(target, div1, anchor); + append_dev(div1, div0); + append_dev(div1, t); + + if (!mounted) { + dispose = listen_dev(div1, "click", click_handler_1, false, false, false); + mounted = true; + } + }, + p: function update(new_ctx, dirty) { + ctx = new_ctx; + + if (dirty & /*props*/ 1) { + set_style(div0, "background-image", "url(images/carte-wagon-" + /*wagon*/ ctx[5] + ".png"); + } + + if (dirty & /*props*/ 1 && div1_class_value !== (div1_class_value = "carte-wagon " + /*wagon*/ ctx[5] + " svelte-vqlws6")) { + attr_dev(div1, "class", div1_class_value); + } + }, + d: function destroy(detaching) { + if (detaching) detach_dev(div1); + mounted = false; + dispose(); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_each_block_1$1.name, + type: "each", + source: "(37:12) {#each props.cartesWagon as wagon}", + ctx + }); + + return block; + } + + // (50:12) {#each props.cartesWagonPosees as wagon} + function create_each_block$4(ctx) { + let div2; + let div0; + let t0; + let div1; + let t1; + let div2_class_value; + + const block = { + c: function create() { + div2 = element("div"); + div0 = element("div"); + t0 = space(); + div1 = element("div"); + t1 = space(); + attr_dev(div0, "class", "image-wagon svelte-vqlws6"); + set_style(div0, "background-image", "url(images/carte-wagon-" + /*wagon*/ ctx[5] + ".png"); + add_location(div0, file$4, 51, 20, 1744); + attr_dev(div1, "class", "overlay svelte-vqlws6"); + add_location(div1, file$4, 55, 20, 1921); + attr_dev(div2, "class", div2_class_value = "carte-wagon " + /*wagon*/ ctx[5] + " svelte-vqlws6"); + add_location(div2, file$4, 50, 16, 1690); + }, + m: function mount(target, anchor) { + insert_dev(target, div2, anchor); + append_dev(div2, div0); + append_dev(div2, t0); + append_dev(div2, div1); + append_dev(div2, t1); + }, + p: function update(ctx, dirty) { + if (dirty & /*props*/ 1) { + set_style(div0, "background-image", "url(images/carte-wagon-" + /*wagon*/ ctx[5] + ".png"); + } + + if (dirty & /*props*/ 1 && div2_class_value !== (div2_class_value = "carte-wagon " + /*wagon*/ ctx[5] + " svelte-vqlws6")) { + attr_dev(div2, "class", div2_class_value); + } + }, + d: function destroy(detaching) { + if (detaching) detach_dev(div2); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_each_block$4.name, + type: "each", + source: "(50:12) {#each props.cartesWagonPosees as wagon}", + ctx + }); + + return block; + } + + function create_fragment$4(ctx) { + let div9; + let div4; + let img; + let img_alt_value; + let img_src_value; + let t0; + let div3; + let span; + let t1_value = /*props*/ ctx[0].nom + ""; + let t1; + let t2; + let div0; + let t3; + let t4_value = /*props*/ ctx[0].score + ""; + let t4; + let t5; + let div1; + let t6; + let t7_value = /*props*/ ctx[0].nbGares + ""; + let t7; + let t8; + let div2; + let t9; + let t10_value = /*props*/ ctx[0].nbWagons + ""; + let t10; + let t11; + let div8; + let div5; + let t12; + let div6; + let t13; + let div7; + let div9_class_value; + let each_value_2 = /*props*/ ctx[0].destinations; + validate_each_argument(each_value_2); + let each_blocks_2 = []; + + for (let i = 0; i < each_value_2.length; i += 1) { + each_blocks_2[i] = create_each_block_2(get_each_context_2(ctx, each_value_2, i)); + } + + let each_value_1 = /*props*/ ctx[0].cartesWagon; + validate_each_argument(each_value_1); + let each_blocks_1 = []; + + for (let i = 0; i < each_value_1.length; i += 1) { + each_blocks_1[i] = create_each_block_1$1(get_each_context_1$1(ctx, each_value_1, i)); + } + + let each_value = /*props*/ ctx[0].cartesWagonPosees; + validate_each_argument(each_value); + let each_blocks = []; + + for (let i = 0; i < each_value.length; i += 1) { + each_blocks[i] = create_each_block$4(get_each_context$4(ctx, each_value, i)); + } + + const block = { + c: function create() { + div9 = element("div"); + div4 = element("div"); + img = element("img"); + t0 = space(); + div3 = element("div"); + span = element("span"); + t1 = text(t1_value); + t2 = space(); + div0 = element("div"); + t3 = text("Score: "); + t4 = text(t4_value); + t5 = space(); + div1 = element("div"); + t6 = text("Gares: "); + t7 = text(t7_value); + t8 = space(); + div2 = element("div"); + t9 = text("Wagons: "); + t10 = text(t10_value); + t11 = space(); + div8 = element("div"); + div5 = element("div"); + + for (let i = 0; i < each_blocks_2.length; i += 1) { + each_blocks_2[i].c(); + } + + t12 = space(); + div6 = element("div"); + + for (let i = 0; i < each_blocks_1.length; i += 1) { + each_blocks_1[i].c(); + } + + t13 = space(); + div7 = element("div"); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + attr_dev(img, "class", "avatar svelte-vqlws6"); + attr_dev(img, "alt", img_alt_value = "avatar " + /*props*/ ctx[0].couleur); + if (!src_url_equal(img.src, img_src_value = "images/avatar-" + /*props*/ ctx[0].couleur + ".png")) attr_dev(img, "src", img_src_value); + add_location(img, file$4, 12, 8, 303); + attr_dev(span, "class", "nom svelte-vqlws6"); + add_location(span, file$4, 18, 12, 485); + attr_dev(div0, "class", "score"); + add_location(div0, file$4, 19, 12, 534); + attr_dev(div1, "class", "gares"); + add_location(div1, file$4, 20, 12, 592); + attr_dev(div2, "class", "wagons"); + add_location(div2, file$4, 21, 12, 652); + attr_dev(div3, "class", "info column svelte-vqlws6"); + add_location(div3, file$4, 17, 8, 447); + attr_dev(div4, "class", "header row svelte-vqlws6"); + add_location(div4, file$4, 11, 4, 270); + attr_dev(div5, "class", "destinations column svelte-vqlws6"); + add_location(div5, file$4, 25, 8, 762); + attr_dev(div6, "class", "cartes-wagon svelte-vqlws6"); + add_location(div6, file$4, 35, 8, 1141); + attr_dev(div7, "class", "cartes-wagon svelte-vqlws6"); + add_location(div7, file$4, 48, 8, 1594); + attr_dev(div8, "class", "secret svelte-vqlws6"); + add_location(div8, file$4, 24, 4, 733); + attr_dev(div9, "class", div9_class_value = "joueur " + /*props*/ ctx[0].couleur + " " + (/*props*/ ctx[0].estJoueurCourant ? 'actif' : '') + " svelte-vqlws6"); + add_location(div9, file$4, 10, 0, 189); + }, + l: function claim(nodes) { + throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); + }, + m: function mount(target, anchor) { + insert_dev(target, div9, anchor); + append_dev(div9, div4); + append_dev(div4, img); + append_dev(div4, t0); + append_dev(div4, div3); + append_dev(div3, span); + append_dev(span, t1); + append_dev(div3, t2); + append_dev(div3, div0); + append_dev(div0, t3); + append_dev(div0, t4); + append_dev(div3, t5); + append_dev(div3, div1); + append_dev(div1, t6); + append_dev(div1, t7); + append_dev(div3, t8); + append_dev(div3, div2); + append_dev(div2, t9); + append_dev(div2, t10); + append_dev(div9, t11); + append_dev(div9, div8); + append_dev(div8, div5); + + for (let i = 0; i < each_blocks_2.length; i += 1) { + each_blocks_2[i].m(div5, null); + } + + append_dev(div8, t12); + append_dev(div8, div6); + + for (let i = 0; i < each_blocks_1.length; i += 1) { + each_blocks_1[i].m(div6, null); + } + + append_dev(div8, t13); + append_dev(div8, div7); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(div7, null); + } + }, + p: function update(ctx, [dirty]) { + if (dirty & /*props*/ 1 && img_alt_value !== (img_alt_value = "avatar " + /*props*/ ctx[0].couleur)) { + attr_dev(img, "alt", img_alt_value); + } + + if (dirty & /*props*/ 1 && !src_url_equal(img.src, img_src_value = "images/avatar-" + /*props*/ ctx[0].couleur + ".png")) { + attr_dev(img, "src", img_src_value); + } + + if (dirty & /*props*/ 1 && t1_value !== (t1_value = /*props*/ ctx[0].nom + "")) set_data_dev(t1, t1_value); + if (dirty & /*props*/ 1 && t4_value !== (t4_value = /*props*/ ctx[0].score + "")) set_data_dev(t4, t4_value); + if (dirty & /*props*/ 1 && t7_value !== (t7_value = /*props*/ ctx[0].nbGares + "")) set_data_dev(t7, t7_value); + if (dirty & /*props*/ 1 && t10_value !== (t10_value = /*props*/ ctx[0].nbWagons + "")) set_data_dev(t10, t10_value); + + if (dirty & /*send, props*/ 3) { + each_value_2 = /*props*/ ctx[0].destinations; + validate_each_argument(each_value_2); + let i; + + for (i = 0; i < each_value_2.length; i += 1) { + const child_ctx = get_each_context_2(ctx, each_value_2, i); + + if (each_blocks_2[i]) { + each_blocks_2[i].p(child_ctx, dirty); + } else { + each_blocks_2[i] = create_each_block_2(child_ctx); + each_blocks_2[i].c(); + each_blocks_2[i].m(div5, null); + } + } + + for (; i < each_blocks_2.length; i += 1) { + each_blocks_2[i].d(1); + } + + each_blocks_2.length = each_value_2.length; + } + + if (dirty & /*props, send*/ 3) { + each_value_1 = /*props*/ ctx[0].cartesWagon; + validate_each_argument(each_value_1); + let i; + + for (i = 0; i < each_value_1.length; i += 1) { + const child_ctx = get_each_context_1$1(ctx, each_value_1, i); + + if (each_blocks_1[i]) { + each_blocks_1[i].p(child_ctx, dirty); + } else { + each_blocks_1[i] = create_each_block_1$1(child_ctx); + each_blocks_1[i].c(); + each_blocks_1[i].m(div6, null); + } + } + + for (; i < each_blocks_1.length; i += 1) { + each_blocks_1[i].d(1); + } + + each_blocks_1.length = each_value_1.length; + } + + if (dirty & /*props*/ 1) { + each_value = /*props*/ ctx[0].cartesWagonPosees; + validate_each_argument(each_value); + let i; + + for (i = 0; i < each_value.length; i += 1) { + const child_ctx = get_each_context$4(ctx, each_value, i); + + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block$4(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(div7, null); + } + } + + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } + + each_blocks.length = each_value.length; + } + + if (dirty & /*props*/ 1 && div9_class_value !== (div9_class_value = "joueur " + /*props*/ ctx[0].couleur + " " + (/*props*/ ctx[0].estJoueurCourant ? 'actif' : '') + " svelte-vqlws6")) { + attr_dev(div9, "class", div9_class_value); + } + }, + i: noop, + o: noop, + d: function destroy(detaching) { + if (detaching) detach_dev(div9); + destroy_each(each_blocks_2, detaching); + destroy_each(each_blocks_1, detaching); + destroy_each(each_blocks, detaching); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_fragment$4.name, + type: "component", + source: "", + ctx + }); + + return block; + } + + function instance$4($$self, $$props, $$invalidate) { + let $ws; + validate_store(ws, 'ws'); + component_subscribe($$self, ws, $$value => $$invalidate(4, $ws = $$value)); + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots('Joueur', slots, []); + let { props } = $$props; + + function send(message) { + console.log(`Message: "${message}"`); + $ws.send(message); + } + + const writable_props = ['props']; + + Object.keys($$props).forEach(key => { + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== '$$' && key !== 'slot') console_1$3.warn(` was created with unknown prop '${key}'`); + }); + + const click_handler = destination => send(destination.nom); + const click_handler_1 = wagon => send(wagon); + + $$self.$$set = $$props => { + if ('props' in $$props) $$invalidate(0, props = $$props.props); + }; + + $$self.$capture_state = () => ({ ws, props, send, $ws }); + + $$self.$inject_state = $$props => { + if ('props' in $$props) $$invalidate(0, props = $$props.props); + }; + + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + + return [props, send, click_handler, click_handler_1]; + } + + class Joueur extends SvelteComponentDev { + constructor(options) { + super(options); + init(this, options, instance$4, create_fragment$4, safe_not_equal, { props: 0 }); + + dispatch_dev("SvelteRegisterComponent", { + component: this, + tagName: "Joueur", + options, + id: create_fragment$4.name + }); + + const { ctx } = this.$$; + const props = options.props || {}; + + if (/*props*/ ctx[0] === undefined && !('props' in props)) { + console_1$3.warn(" was created without expected prop 'props'"); + } + } + + get props() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set props(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + } + + /* src/Prompt.svelte generated by Svelte v3.46.4 */ + + const { console: console_1$2 } = globals; + const file$3 = "src/Prompt.svelte"; + + function get_each_context$3(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[5] = list[i]; + return child_ctx; + } + + // (17:8) {#each props.boutons as bouton} + function create_each_block$3(ctx) { + let button; + let t_value = /*bouton*/ ctx[5] + ""; + let t; + let mounted; + let dispose; + + function click_handler() { + return /*click_handler*/ ctx[2](/*bouton*/ ctx[5]); + } + + const block = { + c: function create() { + button = element("button"); + t = text(t_value); + attr_dev(button, "class", "btn btn-primary"); + add_location(button, file$3, 17, 12, 415); + }, + m: function mount(target, anchor) { + insert_dev(target, button, anchor); + append_dev(button, t); + + if (!mounted) { + dispose = listen_dev(button, "click", click_handler, false, false, false); + mounted = true; + } + }, + p: function update(new_ctx, dirty) { + ctx = new_ctx; + if (dirty & /*props*/ 1 && t_value !== (t_value = /*bouton*/ ctx[5] + "")) set_data_dev(t, t_value); + }, + d: function destroy(detaching) { + if (detaching) detach_dev(button); + mounted = false; + dispose(); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_each_block$3.name, + type: "each", + source: "(17:8) {#each props.boutons as bouton}", + ctx + }); + + return block; + } + + // (26:8) {:else} + function create_else_block$2(ctx) { + let button; + + const block = { + c: function create() { + button = element("button"); + button.textContent = "Passer"; + button.disabled = true; + add_location(button, file$3, 26, 12, 694); + }, + m: function mount(target, anchor) { + insert_dev(target, button, anchor); + }, + p: noop, + d: function destroy(detaching) { + if (detaching) detach_dev(button); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_else_block$2.name, + type: "else", + source: "(26:8) {:else}", + ctx + }); + + return block; + } + + // (24:8) {#if props.peutPasser} + function create_if_block$2(ctx) { + let button; + let mounted; + let dispose; + + const block = { + c: function create() { + button = element("button"); + button.textContent = "Passer"; + add_location(button, file$3, 24, 12, 616); + }, + m: function mount(target, anchor) { + insert_dev(target, button, anchor); + + if (!mounted) { + dispose = listen_dev(button, "click", /*click_handler_1*/ ctx[3], false, false, false); + mounted = true; + } + }, + p: noop, + d: function destroy(detaching) { + if (detaching) detach_dev(button); + mounted = false; + dispose(); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_if_block$2.name, + type: "if", + source: "(24:8) {#if props.peutPasser}", + ctx + }); + + return block; + } + + function create_fragment$3(ctx) { + let div2; + let div0; + let span; + let t0_value = /*props*/ ctx[0].nomJoueurCourant + ""; + let t0; + let t1; + let t2; + let t3_value = /*props*/ ctx[0].instruction + ""; + let t3; + let t4; + let div1; + let t5; + let each_value = /*props*/ ctx[0].boutons; + validate_each_argument(each_value); + let each_blocks = []; + + for (let i = 0; i < each_value.length; i += 1) { + each_blocks[i] = create_each_block$3(get_each_context$3(ctx, each_value, i)); + } + + function select_block_type(ctx, dirty) { + if (/*props*/ ctx[0].peutPasser) return create_if_block$2; + return create_else_block$2; + } + + let current_block_type = select_block_type(ctx); + let if_block = current_block_type(ctx); + + const block = { + c: function create() { + div2 = element("div"); + div0 = element("div"); + span = element("span"); + t0 = text(t0_value); + t1 = text(":"); + t2 = space(); + t3 = text(t3_value); + t4 = space(); + div1 = element("div"); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + t5 = space(); + if_block.c(); + attr_dev(span, "class", "nom-joueur svelte-19y2w7e"); + add_location(span, file$3, 12, 4, 244); + attr_dev(div0, "class", "instruction"); + add_location(div0, file$3, 11, 4, 214); + attr_dev(div1, "class", "boutons"); + add_location(div1, file$3, 15, 4, 341); + attr_dev(div2, "class", "prompt"); + add_location(div2, file$3, 10, 0, 189); + }, + l: function claim(nodes) { + throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); + }, + m: function mount(target, anchor) { + insert_dev(target, div2, anchor); + append_dev(div2, div0); + append_dev(div0, span); + append_dev(span, t0); + append_dev(span, t1); + append_dev(div0, t2); + append_dev(div0, t3); + append_dev(div2, t4); + append_dev(div2, div1); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(div1, null); + } + + append_dev(div1, t5); + if_block.m(div1, null); + }, + p: function update(ctx, [dirty]) { + if (dirty & /*props*/ 1 && t0_value !== (t0_value = /*props*/ ctx[0].nomJoueurCourant + "")) set_data_dev(t0, t0_value); + if (dirty & /*props*/ 1 && t3_value !== (t3_value = /*props*/ ctx[0].instruction + "")) set_data_dev(t3, t3_value); + + if (dirty & /*send, props*/ 3) { + each_value = /*props*/ ctx[0].boutons; + validate_each_argument(each_value); + let i; + + for (i = 0; i < each_value.length; i += 1) { + const child_ctx = get_each_context$3(ctx, each_value, i); + + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block$3(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(div1, t5); + } + } + + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } + + each_blocks.length = each_value.length; + } + + if (current_block_type === (current_block_type = select_block_type(ctx)) && if_block) { + if_block.p(ctx, dirty); + } else { + if_block.d(1); + if_block = current_block_type(ctx); + + if (if_block) { + if_block.c(); + if_block.m(div1, null); + } + } + }, + i: noop, + o: noop, + d: function destroy(detaching) { + if (detaching) detach_dev(div2); + destroy_each(each_blocks, detaching); + if_block.d(); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_fragment$3.name, + type: "component", + source: "", + ctx + }); + + return block; + } + + function instance$3($$self, $$props, $$invalidate) { + let $ws; + validate_store(ws, 'ws'); + component_subscribe($$self, ws, $$value => $$invalidate(4, $ws = $$value)); + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots('Prompt', slots, []); + let { props } = $$props; + + function send(message) { + console.log(`Message: "${message}"`); + $ws.send(message); + } + + const writable_props = ['props']; + + Object.keys($$props).forEach(key => { + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== '$$' && key !== 'slot') console_1$2.warn(` was created with unknown prop '${key}'`); + }); + + const click_handler = bouton => send(bouton); + const click_handler_1 = () => send(""); + + $$self.$$set = $$props => { + if ('props' in $$props) $$invalidate(0, props = $$props.props); + }; + + $$self.$capture_state = () => ({ props, ws, send, $ws }); + + $$self.$inject_state = $$props => { + if ('props' in $$props) $$invalidate(0, props = $$props.props); + }; + + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + + return [props, send, click_handler, click_handler_1]; + } + + class Prompt extends SvelteComponentDev { + constructor(options) { + super(options); + init(this, options, instance$3, create_fragment$3, safe_not_equal, { props: 0 }); + + dispatch_dev("SvelteRegisterComponent", { + component: this, + tagName: "Prompt", + options, + id: create_fragment$3.name + }); + + const { ctx } = this.$$; + const props = options.props || {}; + + if (/*props*/ ctx[0] === undefined && !('props' in props)) { + console_1$2.warn(" was created without expected prop 'props'"); + } + } + + get props() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set props(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + } + + /* src/Log.svelte generated by Svelte v3.46.4 */ + const file$2 = "src/Log.svelte"; + + function get_each_context$2(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[1] = list[i]; + return child_ctx; + } + + // (15:8) {#each lines as line} + function create_each_block$2(ctx) { + let pre; + let raw_value = /*line*/ ctx[1] + ""; + + const block = { + c: function create() { + pre = element("pre"); + attr_dev(pre, "class", "svelte-1r9y78z"); + add_location(pre, file$2, 15, 12, 360); + }, + m: function mount(target, anchor) { + insert_dev(target, pre, anchor); + pre.innerHTML = raw_value; + }, + p: function update(ctx, dirty) { + if (dirty & /*lines*/ 1 && raw_value !== (raw_value = /*line*/ ctx[1] + "")) pre.innerHTML = raw_value; }, + d: function destroy(detaching) { + if (detaching) detach_dev(pre); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_each_block$2.name, + type: "each", + source: "(15:8) {#each lines as line}", + ctx + }); + + return block; + } + + function create_fragment$2(ctx) { + let div1; + let div0; + let each_value = /*lines*/ ctx[0]; + validate_each_argument(each_value); + let each_blocks = []; + + for (let i = 0; i < each_value.length; i += 1) { + each_blocks[i] = create_each_block$2(get_each_context$2(ctx, each_value, i)); + } + + const block = { + c: function create() { + div1 = element("div"); + div0 = element("div"); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + attr_dev(div0, "id", "inner-log"); + attr_dev(div0, "class", "svelte-1r9y78z"); + add_location(div0, file$2, 13, 4, 297); + attr_dev(div1, "id", "log"); + attr_dev(div1, "class", "svelte-1r9y78z"); + add_location(div1, file$2, 12, 0, 278); + }, + l: function claim(nodes) { + throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); + }, + m: function mount(target, anchor) { + insert_dev(target, div1, anchor); + append_dev(div1, div0); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(div0, null); + } + }, + p: function update(ctx, [dirty]) { + if (dirty & /*lines*/ 1) { + each_value = /*lines*/ ctx[0]; + validate_each_argument(each_value); + let i; + + for (i = 0; i < each_value.length; i += 1) { + const child_ctx = get_each_context$2(ctx, each_value, i); + + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block$2(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(div0, null); + } + } + + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } + + each_blocks.length = each_value.length; + } + }, + i: noop, + o: noop, + d: function destroy(detaching) { + if (detaching) detach_dev(div1); + destroy_each(each_blocks, detaching); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_fragment$2.name, + type: "component", + source: "", + ctx + }); + + return block; + } + + function scrollToBottom() { + const logElement = document.getElementById("inner-log"); + logElement.scrollTop = logElement.scrollHeight; + } + + function instance$2($$self, $$props, $$invalidate) { + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots('Log', slots, []); + let { lines } = $$props; + afterUpdate(scrollToBottom); + const writable_props = ['lines']; + + Object.keys($$props).forEach(key => { + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== '$$' && key !== 'slot') console.warn(` was created with unknown prop '${key}'`); + }); + + $$self.$$set = $$props => { + if ('lines' in $$props) $$invalidate(0, lines = $$props.lines); + }; + + $$self.$capture_state = () => ({ afterUpdate, lines, scrollToBottom }); + + $$self.$inject_state = $$props => { + if ('lines' in $$props) $$invalidate(0, lines = $$props.lines); + }; + + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + + return [lines]; + } + + class Log extends SvelteComponentDev { + constructor(options) { + super(options); + init(this, options, instance$2, create_fragment$2, safe_not_equal, { lines: 0 }); + + dispatch_dev("SvelteRegisterComponent", { + component: this, + tagName: "Log", + options, + id: create_fragment$2.name + }); + + const { ctx } = this.$$; + const props = options.props || {}; + + if (/*lines*/ ctx[0] === undefined && !('lines' in props)) { + console.warn(" was created without expected prop 'lines'"); + } + } + + get lines() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set lines(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + } + + /* src/Piles.svelte generated by Svelte v3.46.4 */ + + const { console: console_1$1 } = globals; + const file$1 = "src/Piles.svelte"; + + function get_each_context$1(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[7] = list[i]; + return child_ctx; + } + + function get_each_context_1(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[7] = list[i]; + return child_ctx; + } + + // (16:12) {#each props.cartesWagonVisibles as couleur} + function create_each_block_1(ctx) { + let div; + let img; + let img_alt_value; + let img_src_value; + let t0; + let span; + let t1_value = /*couleur*/ ctx[7][0] + /*couleur*/ ctx[7].slice(1).toLowerCase() + ""; + let t1; + let t2; + let mounted; + let dispose; + + function click_handler() { + return /*click_handler*/ ctx[3](/*couleur*/ ctx[7]); + } + + const block = { + c: function create() { + div = element("div"); + img = element("img"); + t0 = space(); + span = element("span"); + t1 = text(t1_value); + t2 = space(); + attr_dev(img, "class", "shadow svelte-1eir9gx"); + attr_dev(img, "alt", img_alt_value = /*couleur*/ ctx[7]); + if (!src_url_equal(img.src, img_src_value = "images/carte-wagon-" + /*couleur*/ ctx[7] + ".png")) attr_dev(img, "src", img_src_value); + add_location(img, file$1, 17, 20, 479); + add_location(span, file$1, 23, 20, 722); + attr_dev(div, "class", "carte visible column svelte-1eir9gx"); + add_location(div, file$1, 16, 16, 424); + }, + m: function mount(target, anchor) { + insert_dev(target, div, anchor); + append_dev(div, img); + append_dev(div, t0); + append_dev(div, span); + append_dev(span, t1); + append_dev(div, t2); + + if (!mounted) { + dispose = listen_dev(img, "click", click_handler, false, false, false); + mounted = true; + } + }, + p: function update(new_ctx, dirty) { + ctx = new_ctx; + + if (dirty & /*props*/ 1 && img_alt_value !== (img_alt_value = /*couleur*/ ctx[7])) { + attr_dev(img, "alt", img_alt_value); + } + + if (dirty & /*props*/ 1 && !src_url_equal(img.src, img_src_value = "images/carte-wagon-" + /*couleur*/ ctx[7] + ".png")) { + attr_dev(img, "src", img_src_value); + } + + if (dirty & /*props*/ 1 && t1_value !== (t1_value = /*couleur*/ ctx[7][0] + /*couleur*/ ctx[7].slice(1).toLowerCase() + "")) set_data_dev(t1, t1_value); + }, + d: function destroy(detaching) { + if (detaching) detach_dev(div); + mounted = false; + dispose(); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_each_block_1.name, + type: "each", + source: "(16:12) {#each props.cartesWagonVisibles as couleur}", + ctx + }); + + return block; + } + + // (42:8) {:else} + function create_else_block$1(ctx) { + let div; + let each_value = /*props*/ ctx[0].defausseCartesWagon.slice(-15); + validate_each_argument(each_value); + let each_blocks = []; + + for (let i = 0; i < each_value.length; i += 1) { + each_blocks[i] = create_each_block$1(get_each_context$1(ctx, each_value, i)); + } + + const block = { + c: function create() { + div = element("div"); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + attr_dev(div, "id", "defausse-cartes-wagon"); + attr_dev(div, "class", "carte column svelte-1eir9gx"); + add_location(div, file$1, 42, 12, 1317); + }, + m: function mount(target, anchor) { + insert_dev(target, div, anchor); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(div, null); + } + }, + p: function update(ctx, dirty) { + if (dirty & /*props*/ 1) { + each_value = /*props*/ ctx[0].defausseCartesWagon.slice(-15); + validate_each_argument(each_value); + let i; + + for (i = 0; i < each_value.length; i += 1) { + const child_ctx = get_each_context$1(ctx, each_value, i); + + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block$1(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(div, null); + } + } + + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } + + each_blocks.length = each_value.length; + } + }, + d: function destroy(detaching) { + if (detaching) detach_dev(div); + destroy_each(each_blocks, detaching); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_else_block$1.name, + type: "else", + source: "(42:8) {:else}", + ctx + }); + + return block; + } + + // (40:8) {#if props.defausseCartesWagon.length === 0} + function create_if_block$1(ctx) { + let div; + + const block = { + c: function create() { + div = element("div"); + attr_dev(div, "class", "carte-stub svelte-1eir9gx"); + add_location(div, file$1, 40, 12, 1262); + }, + m: function mount(target, anchor) { + insert_dev(target, div, anchor); + }, + p: noop, + d: function destroy(detaching) { + if (detaching) detach_dev(div); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_if_block$1.name, + type: "if", + source: "(40:8) {#if props.defausseCartesWagon.length === 0}", + ctx + }); + + return block; + } + + // (44:16) {#each props.defausseCartesWagon.slice(-15) as couleur} + function create_each_block$1(ctx) { + let img; + let img_alt_value; + let img_src_value; + + const block = { + c: function create() { + img = element("img"); + attr_dev(img, "class", "shadow svelte-1eir9gx"); + attr_dev(img, "alt", img_alt_value = /*couleur*/ ctx[7]); + if (!src_url_equal(img.src, img_src_value = "images/carte-wagon-" + /*couleur*/ ctx[7] + ".png")) attr_dev(img, "src", img_src_value); + add_location(img, file$1, 44, 20, 1463); + }, + m: function mount(target, anchor) { + insert_dev(target, img, anchor); + }, + p: function update(ctx, dirty) { + if (dirty & /*props*/ 1 && img_alt_value !== (img_alt_value = /*couleur*/ ctx[7])) { + attr_dev(img, "alt", img_alt_value); + } + + if (dirty & /*props*/ 1 && !src_url_equal(img.src, img_src_value = "images/carte-wagon-" + /*couleur*/ ctx[7] + ".png")) { + attr_dev(img, "src", img_src_value); + } + }, + d: function destroy(detaching) { + if (detaching) detach_dev(img); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_each_block$1.name, + type: "each", + source: "(44:16) {#each props.defausseCartesWagon.slice(-15) as couleur}", + ctx + }); + + return block; + } + + function create_fragment$1(ctx) { + let div5; + let div1; + let div0; + let t0; + let log; + let t1; + let div2; + let img0; + let img0_src_value; + let t2; + let span0; + let t3; + let t4_value = /*props*/ ctx[0].pileCartesWagon + ""; + let t4; + let t5; + let t6; + let div3; + let t7; + let span1; + let t8; + let t9_value = /*props*/ ctx[0].defausseCartesWagon.length + ""; + let t9; + let t10; + let t11; + let div4; + let img1; + let img1_src_value; + let t12; + let span2; + let t13; + let t14_value = /*props*/ ctx[0].pileDestinations + ""; + let t14; + let t15; + let current; + let mounted; + let dispose; + let each_value_1 = /*props*/ ctx[0].cartesWagonVisibles; + validate_each_argument(each_value_1); + let each_blocks = []; + + for (let i = 0; i < each_value_1.length; i += 1) { + each_blocks[i] = create_each_block_1(get_each_context_1(ctx, each_value_1, i)); + } + + log = new Log({ + props: { lines: /*logLines*/ ctx[1] }, + $$inline: true + }); + + function select_block_type(ctx, dirty) { + if (/*props*/ ctx[0].defausseCartesWagon.length === 0) return create_if_block$1; + return create_else_block$1; + } + + let current_block_type = select_block_type(ctx); + let if_block = current_block_type(ctx); + + const block = { + c: function create() { + div5 = element("div"); + div1 = element("div"); + div0 = element("div"); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + t0 = space(); + create_component(log.$$.fragment); + t1 = space(); + div2 = element("div"); + img0 = element("img"); + t2 = space(); + span0 = element("span"); + t3 = text("Cartes wagon ("); + t4 = text(t4_value); + t5 = text(")"); + t6 = space(); + div3 = element("div"); + if_block.c(); + t7 = space(); + span1 = element("span"); + t8 = text("Défausse ("); + t9 = text(t9_value); + t10 = text(")"); + t11 = space(); + div4 = element("div"); + img1 = element("img"); + t12 = space(); + span2 = element("span"); + t13 = text("Destinations ("); + t14 = text(t14_value); + t15 = text(")"); + attr_dev(div0, "id", "cartes-visibles"); + attr_dev(div0, "class", "row svelte-1eir9gx"); + add_location(div0, file$1, 14, 8, 312); + attr_dev(div1, "class", "column"); + add_location(div1, file$1, 13, 4, 283); + attr_dev(img0, "class", "shadow svelte-1eir9gx"); + attr_dev(img0, "alt", "wagon"); + if (!src_url_equal(img0.src, img0_src_value = "images/carte-wagon.png")) attr_dev(img0, "src", img0_src_value); + add_location(img0, file$1, 30, 8, 945); + add_location(span0, file$1, 36, 8, 1103); + attr_dev(div2, "id", "pile-cartes-wagon"); + attr_dev(div2, "class", "carte column svelte-1eir9gx"); + add_location(div2, file$1, 29, 4, 887); + add_location(span1, file$1, 52, 8, 1696); + attr_dev(div3, "class", "carte column svelte-1eir9gx"); + add_location(div3, file$1, 38, 4, 1170); + attr_dev(img1, "class", "shadow svelte-1eir9gx"); + attr_dev(img1, "alt", "destinations"); + if (!src_url_equal(img1.src, img1_src_value = "images/eu_TicketBack.png")) attr_dev(img1, "src", img1_src_value); + add_location(img1, file$1, 55, 8, 1828); + add_location(span2, file$1, 61, 8, 2003); + attr_dev(div4, "id", "pile-destinations"); + attr_dev(div4, "class", "carte column svelte-1eir9gx"); + add_location(div4, file$1, 54, 4, 1770); + attr_dev(div5, "id", "piles"); + attr_dev(div5, "class", "row svelte-1eir9gx"); + add_location(div5, file$1, 12, 0, 250); + }, + l: function claim(nodes) { + throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); + }, + m: function mount(target, anchor) { + insert_dev(target, div5, anchor); + append_dev(div5, div1); + append_dev(div1, div0); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(div0, null); + } + + append_dev(div1, t0); + mount_component(log, div1, null); + append_dev(div5, t1); + append_dev(div5, div2); + append_dev(div2, img0); + append_dev(div2, t2); + append_dev(div2, span0); + append_dev(span0, t3); + append_dev(span0, t4); + append_dev(span0, t5); + append_dev(div5, t6); + append_dev(div5, div3); + if_block.m(div3, null); + append_dev(div3, t7); + append_dev(div3, span1); + append_dev(span1, t8); + append_dev(span1, t9); + append_dev(span1, t10); + append_dev(div5, t11); + append_dev(div5, div4); + append_dev(div4, img1); + append_dev(div4, t12); + append_dev(div4, span2); + append_dev(span2, t13); + append_dev(span2, t14); + append_dev(span2, t15); + current = true; + + if (!mounted) { + dispose = [ + listen_dev(img0, "click", /*click_handler_1*/ ctx[4], false, false, false), + listen_dev(img1, "click", /*click_handler_2*/ ctx[5], false, false, false) + ]; + + mounted = true; + } + }, + p: function update(ctx, [dirty]) { + if (dirty & /*props, send*/ 5) { + each_value_1 = /*props*/ ctx[0].cartesWagonVisibles; + validate_each_argument(each_value_1); + let i; + + for (i = 0; i < each_value_1.length; i += 1) { + const child_ctx = get_each_context_1(ctx, each_value_1, i); + + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block_1(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(div0, null); + } + } + + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } + + each_blocks.length = each_value_1.length; + } + + const log_changes = {}; + if (dirty & /*logLines*/ 2) log_changes.lines = /*logLines*/ ctx[1]; + log.$set(log_changes); + if ((!current || dirty & /*props*/ 1) && t4_value !== (t4_value = /*props*/ ctx[0].pileCartesWagon + "")) set_data_dev(t4, t4_value); + + if (current_block_type === (current_block_type = select_block_type(ctx)) && if_block) { + if_block.p(ctx, dirty); + } else { + if_block.d(1); + if_block = current_block_type(ctx); + + if (if_block) { + if_block.c(); + if_block.m(div3, t7); + } + } + + if ((!current || dirty & /*props*/ 1) && t9_value !== (t9_value = /*props*/ ctx[0].defausseCartesWagon.length + "")) set_data_dev(t9, t9_value); + if ((!current || dirty & /*props*/ 1) && t14_value !== (t14_value = /*props*/ ctx[0].pileDestinations + "")) set_data_dev(t14, t14_value); + }, + i: function intro(local) { + if (current) return; + transition_in(log.$$.fragment, local); + current = true; + }, + o: function outro(local) { + transition_out(log.$$.fragment, local); + current = false; + }, + d: function destroy(detaching) { + if (detaching) detach_dev(div5); + destroy_each(each_blocks, detaching); + destroy_component(log); + if_block.d(); + mounted = false; + run_all(dispose); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_fragment$1.name, + type: "component", + source: "", + ctx + }); + + return block; + } + + function instance$1($$self, $$props, $$invalidate) { + let $ws; + validate_store(ws, 'ws'); + component_subscribe($$self, ws, $$value => $$invalidate(6, $ws = $$value)); + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots('Piles', slots, []); + let { props } = $$props; + let { logLines } = $$props; + + function send(message) { + console.log(`Message: "${message}"`); + $ws.send(message); + } + + const writable_props = ['props', 'logLines']; + + Object.keys($$props).forEach(key => { + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== '$$' && key !== 'slot') console_1$1.warn(` was created with unknown prop '${key}'`); + }); + + const click_handler = couleur => send(couleur); + const click_handler_1 = () => send("GRIS"); + const click_handler_2 = () => send("destinations"); + + $$self.$$set = $$props => { + if ('props' in $$props) $$invalidate(0, props = $$props.props); + if ('logLines' in $$props) $$invalidate(1, logLines = $$props.logLines); + }; + + $$self.$capture_state = () => ({ ws, Log, props, logLines, send, $ws }); + + $$self.$inject_state = $$props => { + if ('props' in $$props) $$invalidate(0, props = $$props.props); + if ('logLines' in $$props) $$invalidate(1, logLines = $$props.logLines); + }; + + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + + return [props, logLines, send, click_handler, click_handler_1, click_handler_2]; + } + + class Piles extends SvelteComponentDev { + constructor(options) { + super(options); + init(this, options, instance$1, create_fragment$1, safe_not_equal, { props: 0, logLines: 1 }); + + dispatch_dev("SvelteRegisterComponent", { + component: this, + tagName: "Piles", + options, + id: create_fragment$1.name + }); + + const { ctx } = this.$$; + const props = options.props || {}; + + if (/*props*/ ctx[0] === undefined && !('props' in props)) { + console_1$1.warn(" was created without expected prop 'props'"); + } + + if (/*logLines*/ ctx[1] === undefined && !('logLines' in props)) { + console_1$1.warn(" was created without expected prop 'logLines'"); + } + } + + get props() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set props(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + + get logLines() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set logLines(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + } + + /* src/App.svelte generated by Svelte v3.46.4 */ + + const { console: console_1 } = globals; + const file = "src/App.svelte"; + + function get_each_context(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[2] = list[i]; + return child_ctx; + } + + // (31:0) {:else} + function create_else_block(ctx) { + let p0; + let t1; + let p1; + + const block = { + c: function create() { + p0 = element("p"); + p0.textContent = "La connexion avec le serveur n'a pas pu être établie."; + t1 = space(); + p1 = element("p"); + p1.textContent = "Démarrez le serveur et rechargez la page."; + add_location(p0, file, 31, 2, 705); + add_location(p1, file, 32, 2, 768); + }, + m: function mount(target, anchor) { + insert_dev(target, p0, anchor); + insert_dev(target, t1, anchor); + insert_dev(target, p1, anchor); + }, + p: noop, + i: noop, + o: noop, + d: function destroy(detaching) { + if (detaching) detach_dev(p0); + if (detaching) detach_dev(t1); + if (detaching) detach_dev(p1); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_else_block.name, + type: "else", + source: "(31:0) {:else}", + ctx + }); + + return block; + } + + // (16:0) {#if data} + function create_if_block(ctx) { + let main; + let div1; + let plateau; + let t0; + let div0; + let prompt; + let t1; + let piles; + let t2; + let div2; + let current; + + plateau = new Plateau({ + props: { + props: { + villes: /*data*/ ctx[0].villes, + routes: /*data*/ ctx[0].routes + } + }, + $$inline: true + }); + + prompt = new Prompt({ + props: { props: /*data*/ ctx[0].prompt }, + $$inline: true + }); + + piles = new Piles({ + props: { + props: /*data*/ ctx[0].piles, + logLines: /*data*/ ctx[0].log + }, + $$inline: true + }); + + let each_value = /*data*/ ctx[0].joueurs; + validate_each_argument(each_value); + let each_blocks = []; + + for (let i = 0; i < each_value.length; i += 1) { + each_blocks[i] = create_each_block(get_each_context(ctx, each_value, i)); + } + + const out = i => transition_out(each_blocks[i], 1, 1, () => { + each_blocks[i] = null; + }); + + const block = { + c: function create() { + main = element("main"); + div1 = element("div"); + create_component(plateau.$$.fragment); + t0 = space(); + div0 = element("div"); + create_component(prompt.$$.fragment); + t1 = space(); + create_component(piles.$$.fragment); + t2 = space(); + div2 = element("div"); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + add_location(div0, file, 19, 6, 445); + attr_dev(div1, "id", "main"); + add_location(div1, file, 17, 4, 354); + attr_dev(div2, "class", "joueurs svelte-urompm"); + add_location(div2, file, 24, 4, 575); + attr_dev(main, "class", "svelte-urompm"); + add_location(main, file, 16, 2, 343); + }, + m: function mount(target, anchor) { + insert_dev(target, main, anchor); + append_dev(main, div1); + mount_component(plateau, div1, null); + append_dev(div1, t0); + append_dev(div1, div0); + mount_component(prompt, div0, null); + append_dev(div0, t1); + mount_component(piles, div0, null); + append_dev(main, t2); + append_dev(main, div2); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(div2, null); + } + + current = true; + }, + p: function update(ctx, dirty) { + const plateau_changes = {}; + + if (dirty & /*data*/ 1) plateau_changes.props = { + villes: /*data*/ ctx[0].villes, + routes: /*data*/ ctx[0].routes + }; + + plateau.$set(plateau_changes); + const prompt_changes = {}; + if (dirty & /*data*/ 1) prompt_changes.props = /*data*/ ctx[0].prompt; + prompt.$set(prompt_changes); + const piles_changes = {}; + if (dirty & /*data*/ 1) piles_changes.props = /*data*/ ctx[0].piles; + if (dirty & /*data*/ 1) piles_changes.logLines = /*data*/ ctx[0].log; + piles.$set(piles_changes); + + if (dirty & /*data*/ 1) { + each_value = /*data*/ ctx[0].joueurs; + validate_each_argument(each_value); + let i; + + for (i = 0; i < each_value.length; i += 1) { + const child_ctx = get_each_context(ctx, each_value, i); + + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + transition_in(each_blocks[i], 1); + } else { + each_blocks[i] = create_each_block(child_ctx); + each_blocks[i].c(); + transition_in(each_blocks[i], 1); + each_blocks[i].m(div2, null); + } + } + + group_outros(); + + for (i = each_value.length; i < each_blocks.length; i += 1) { + out(i); + } + + check_outros(); + } + }, + i: function intro(local) { + if (current) return; + transition_in(plateau.$$.fragment, local); + transition_in(prompt.$$.fragment, local); + transition_in(piles.$$.fragment, local); + + for (let i = 0; i < each_value.length; i += 1) { + transition_in(each_blocks[i]); + } + + current = true; + }, + o: function outro(local) { + transition_out(plateau.$$.fragment, local); + transition_out(prompt.$$.fragment, local); + transition_out(piles.$$.fragment, local); + each_blocks = each_blocks.filter(Boolean); + + for (let i = 0; i < each_blocks.length; i += 1) { + transition_out(each_blocks[i]); + } + + current = false; + }, + d: function destroy(detaching) { + if (detaching) detach_dev(main); + destroy_component(plateau); + destroy_component(prompt); + destroy_component(piles); + destroy_each(each_blocks, detaching); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_if_block.name, + type: "if", + source: "(16:0) {#if data}", + ctx + }); + + return block; + } + + // (26:6) {#each data.joueurs as props} + function create_each_block(ctx) { + let joueur; + let current; + + joueur = new Joueur({ + props: { props: /*props*/ ctx[2] }, + $$inline: true + }); + + const block = { + c: function create() { + create_component(joueur.$$.fragment); + }, + m: function mount(target, anchor) { + mount_component(joueur, target, anchor); + current = true; + }, + p: function update(ctx, dirty) { + const joueur_changes = {}; + if (dirty & /*data*/ 1) joueur_changes.props = /*props*/ ctx[2]; + joueur.$set(joueur_changes); + }, + i: function intro(local) { + if (current) return; + transition_in(joueur.$$.fragment, local); + current = true; + }, + o: function outro(local) { + transition_out(joueur.$$.fragment, local); + current = false; + }, + d: function destroy(detaching) { + destroy_component(joueur, detaching); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_each_block.name, + type: "each", + source: "(26:6) {#each data.joueurs as props}", + ctx + }); + + return block; + } + + function create_fragment(ctx) { + let current_block_type_index; + let if_block; + let if_block_anchor; + let current; + const if_block_creators = [create_if_block, create_else_block]; + const if_blocks = []; + + function select_block_type(ctx, dirty) { + if (/*data*/ ctx[0]) return 0; + return 1; + } + + current_block_type_index = select_block_type(ctx); + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); + + const block = { + c: function create() { + if_block.c(); + if_block_anchor = empty(); + }, + l: function claim(nodes) { + throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); + }, + m: function mount(target, anchor) { + if_blocks[current_block_type_index].m(target, anchor); + insert_dev(target, if_block_anchor, anchor); + current = true; + }, + p: function update(ctx, [dirty]) { + let previous_block_index = current_block_type_index; + current_block_type_index = select_block_type(ctx); + + if (current_block_type_index === previous_block_index) { + if_blocks[current_block_type_index].p(ctx, dirty); + } else { + group_outros(); + + transition_out(if_blocks[previous_block_index], 1, 1, () => { + if_blocks[previous_block_index] = null; + }); + + check_outros(); + if_block = if_blocks[current_block_type_index]; + + if (!if_block) { + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); + if_block.c(); + } else { + if_block.p(ctx, dirty); + } + + transition_in(if_block, 1); + if_block.m(if_block_anchor.parentNode, if_block_anchor); + } + }, + i: function intro(local) { + if (current) return; + transition_in(if_block); + current = true; + }, + o: function outro(local) { + transition_out(if_block); + current = false; + }, + d: function destroy(detaching) { + if_blocks[current_block_type_index].d(detaching); + if (detaching) detach_dev(if_block_anchor); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_fragment.name, + type: "component", + source: "", + ctx + }); + + return block; + } + + function instance($$self, $$props, $$invalidate) { + let $ws; + validate_store(ws, 'ws'); + component_subscribe($$self, ws, $$value => $$invalidate(1, $ws = $$value)); + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots('App', slots, []); + let data; + + set_store_value( + ws, + $ws.onmessage = function (event) { + $$invalidate(0, data = JSON.parse(event.data)); + console.log(data); + }, + $ws + ); + + const writable_props = []; + + Object.keys($$props).forEach(key => { + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== '$$' && key !== 'slot') console_1.warn(` was created with unknown prop '${key}'`); + }); + + $$self.$capture_state = () => ({ + Plateau, + Joueur, + Prompt, + Piles, + ws, + data, + $ws + }); + + $$self.$inject_state = $$props => { + if ('data' in $$props) $$invalidate(0, data = $$props.data); + }; + + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + + return [data]; + } + + class App extends SvelteComponentDev { + constructor(options) { + super(options); + init(this, options, instance, create_fragment, safe_not_equal, {}); + + dispatch_dev("SvelteRegisterComponent", { + component: this, + tagName: "App", + options, + id: create_fragment.name + }); + } + } + + const app = new App({ + target: document.body, + }); + + return app; + +})(); +//# sourceMappingURL=bundle.js.map diff --git a/svelte/public/bundle.js.map b/svelte/public/bundle.js.map new file mode 100644 index 0000000..5582c93 --- /dev/null +++ b/svelte/public/bundle.js.map @@ -0,0 +1 @@ +{"version":3,"file":"bundle.js","sources":["../node_modules/svelte/internal/index.mjs","../src/plateau_data.js","../node_modules/svelte/store/index.mjs","../src/stores.js","../src/Plateau.svelte","../src/Joueur.svelte","../src/Prompt.svelte","../src/Log.svelte","../src/Piles.svelte","../src/App.svelte","../src/main.js"],"sourcesContent":["function noop() { }\nconst identity = x => x;\nfunction assign(tar, src) {\n // @ts-ignore\n for (const k in src)\n tar[k] = src[k];\n return tar;\n}\nfunction is_promise(value) {\n return value && typeof value === 'object' && typeof value.then === 'function';\n}\nfunction add_location(element, file, line, column, char) {\n element.__svelte_meta = {\n loc: { file, line, column, char }\n };\n}\nfunction run(fn) {\n return fn();\n}\nfunction blank_object() {\n return Object.create(null);\n}\nfunction run_all(fns) {\n fns.forEach(run);\n}\nfunction is_function(thing) {\n return typeof thing === 'function';\n}\nfunction safe_not_equal(a, b) {\n return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');\n}\nlet src_url_equal_anchor;\nfunction src_url_equal(element_src, url) {\n if (!src_url_equal_anchor) {\n src_url_equal_anchor = document.createElement('a');\n }\n src_url_equal_anchor.href = url;\n return element_src === src_url_equal_anchor.href;\n}\nfunction not_equal(a, b) {\n return a != a ? b == b : a !== b;\n}\nfunction is_empty(obj) {\n return Object.keys(obj).length === 0;\n}\nfunction validate_store(store, name) {\n if (store != null && typeof store.subscribe !== 'function') {\n throw new Error(`'${name}' is not a store with a 'subscribe' method`);\n }\n}\nfunction subscribe(store, ...callbacks) {\n if (store == null) {\n return noop;\n }\n const unsub = store.subscribe(...callbacks);\n return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;\n}\nfunction get_store_value(store) {\n let value;\n subscribe(store, _ => value = _)();\n return value;\n}\nfunction component_subscribe(component, store, callback) {\n component.$$.on_destroy.push(subscribe(store, callback));\n}\nfunction create_slot(definition, ctx, $$scope, fn) {\n if (definition) {\n const slot_ctx = get_slot_context(definition, ctx, $$scope, fn);\n return definition[0](slot_ctx);\n }\n}\nfunction get_slot_context(definition, ctx, $$scope, fn) {\n return definition[1] && fn\n ? assign($$scope.ctx.slice(), definition[1](fn(ctx)))\n : $$scope.ctx;\n}\nfunction get_slot_changes(definition, $$scope, dirty, fn) {\n if (definition[2] && fn) {\n const lets = definition[2](fn(dirty));\n if ($$scope.dirty === undefined) {\n return lets;\n }\n if (typeof lets === 'object') {\n const merged = [];\n const len = Math.max($$scope.dirty.length, lets.length);\n for (let i = 0; i < len; i += 1) {\n merged[i] = $$scope.dirty[i] | lets[i];\n }\n return merged;\n }\n return $$scope.dirty | lets;\n }\n return $$scope.dirty;\n}\nfunction update_slot_base(slot, slot_definition, ctx, $$scope, slot_changes, get_slot_context_fn) {\n if (slot_changes) {\n const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn);\n slot.p(slot_context, slot_changes);\n }\n}\nfunction update_slot(slot, slot_definition, ctx, $$scope, dirty, get_slot_changes_fn, get_slot_context_fn) {\n const slot_changes = get_slot_changes(slot_definition, $$scope, dirty, get_slot_changes_fn);\n update_slot_base(slot, slot_definition, ctx, $$scope, slot_changes, get_slot_context_fn);\n}\nfunction get_all_dirty_from_scope($$scope) {\n if ($$scope.ctx.length > 32) {\n const dirty = [];\n const length = $$scope.ctx.length / 32;\n for (let i = 0; i < length; i++) {\n dirty[i] = -1;\n }\n return dirty;\n }\n return -1;\n}\nfunction exclude_internal_props(props) {\n const result = {};\n for (const k in props)\n if (k[0] !== '$')\n result[k] = props[k];\n return result;\n}\nfunction compute_rest_props(props, keys) {\n const rest = {};\n keys = new Set(keys);\n for (const k in props)\n if (!keys.has(k) && k[0] !== '$')\n rest[k] = props[k];\n return rest;\n}\nfunction compute_slots(slots) {\n const result = {};\n for (const key in slots) {\n result[key] = true;\n }\n return result;\n}\nfunction once(fn) {\n let ran = false;\n return function (...args) {\n if (ran)\n return;\n ran = true;\n fn.call(this, ...args);\n };\n}\nfunction null_to_empty(value) {\n return value == null ? '' : value;\n}\nfunction set_store_value(store, ret, value) {\n store.set(value);\n return ret;\n}\nconst has_prop = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);\nfunction action_destroyer(action_result) {\n return action_result && is_function(action_result.destroy) ? action_result.destroy : noop;\n}\n\nconst is_client = typeof window !== 'undefined';\nlet now = is_client\n ? () => window.performance.now()\n : () => Date.now();\nlet raf = is_client ? cb => requestAnimationFrame(cb) : noop;\n// used internally for testing\nfunction set_now(fn) {\n now = fn;\n}\nfunction set_raf(fn) {\n raf = fn;\n}\n\nconst tasks = new Set();\nfunction run_tasks(now) {\n tasks.forEach(task => {\n if (!task.c(now)) {\n tasks.delete(task);\n task.f();\n }\n });\n if (tasks.size !== 0)\n raf(run_tasks);\n}\n/**\n * For testing purposes only!\n */\nfunction clear_loops() {\n tasks.clear();\n}\n/**\n * Creates a new task that runs on each raf frame\n * until it returns a falsy value or is aborted\n */\nfunction loop(callback) {\n let task;\n if (tasks.size === 0)\n raf(run_tasks);\n return {\n promise: new Promise(fulfill => {\n tasks.add(task = { c: callback, f: fulfill });\n }),\n abort() {\n tasks.delete(task);\n }\n };\n}\n\n// Track which nodes are claimed during hydration. Unclaimed nodes can then be removed from the DOM\n// at the end of hydration without touching the remaining nodes.\nlet is_hydrating = false;\nfunction start_hydrating() {\n is_hydrating = true;\n}\nfunction end_hydrating() {\n is_hydrating = false;\n}\nfunction upper_bound(low, high, key, value) {\n // Return first index of value larger than input value in the range [low, high)\n while (low < high) {\n const mid = low + ((high - low) >> 1);\n if (key(mid) <= value) {\n low = mid + 1;\n }\n else {\n high = mid;\n }\n }\n return low;\n}\nfunction init_hydrate(target) {\n if (target.hydrate_init)\n return;\n target.hydrate_init = true;\n // We know that all children have claim_order values since the unclaimed have been detached if target is not \n let children = target.childNodes;\n // If target is , there may be children without claim_order\n if (target.nodeName === 'HEAD') {\n const myChildren = [];\n for (let i = 0; i < children.length; i++) {\n const node = children[i];\n if (node.claim_order !== undefined) {\n myChildren.push(node);\n }\n }\n children = myChildren;\n }\n /*\n * Reorder claimed children optimally.\n * We can reorder claimed children optimally by finding the longest subsequence of\n * nodes that are already claimed in order and only moving the rest. The longest\n * subsequence subsequence of nodes that are claimed in order can be found by\n * computing the longest increasing subsequence of .claim_order values.\n *\n * This algorithm is optimal in generating the least amount of reorder operations\n * possible.\n *\n * Proof:\n * We know that, given a set of reordering operations, the nodes that do not move\n * always form an increasing subsequence, since they do not move among each other\n * meaning that they must be already ordered among each other. Thus, the maximal\n * set of nodes that do not move form a longest increasing subsequence.\n */\n // Compute longest increasing subsequence\n // m: subsequence length j => index k of smallest value that ends an increasing subsequence of length j\n const m = new Int32Array(children.length + 1);\n // Predecessor indices + 1\n const p = new Int32Array(children.length);\n m[0] = -1;\n let longest = 0;\n for (let i = 0; i < children.length; i++) {\n const current = children[i].claim_order;\n // Find the largest subsequence length such that it ends in a value less than our current value\n // upper_bound returns first greater value, so we subtract one\n // with fast path for when we are on the current longest subsequence\n const seqLen = ((longest > 0 && children[m[longest]].claim_order <= current) ? longest + 1 : upper_bound(1, longest, idx => children[m[idx]].claim_order, current)) - 1;\n p[i] = m[seqLen] + 1;\n const newLen = seqLen + 1;\n // We can guarantee that current is the smallest value. Otherwise, we would have generated a longer sequence.\n m[newLen] = i;\n longest = Math.max(newLen, longest);\n }\n // The longest increasing subsequence of nodes (initially reversed)\n const lis = [];\n // The rest of the nodes, nodes that will be moved\n const toMove = [];\n let last = children.length - 1;\n for (let cur = m[longest] + 1; cur != 0; cur = p[cur - 1]) {\n lis.push(children[cur - 1]);\n for (; last >= cur; last--) {\n toMove.push(children[last]);\n }\n last--;\n }\n for (; last >= 0; last--) {\n toMove.push(children[last]);\n }\n lis.reverse();\n // We sort the nodes being moved to guarantee that their insertion order matches the claim order\n toMove.sort((a, b) => a.claim_order - b.claim_order);\n // Finally, we move the nodes\n for (let i = 0, j = 0; i < toMove.length; i++) {\n while (j < lis.length && toMove[i].claim_order >= lis[j].claim_order) {\n j++;\n }\n const anchor = j < lis.length ? lis[j] : null;\n target.insertBefore(toMove[i], anchor);\n }\n}\nfunction append(target, node) {\n target.appendChild(node);\n}\nfunction append_styles(target, style_sheet_id, styles) {\n const append_styles_to = get_root_for_style(target);\n if (!append_styles_to.getElementById(style_sheet_id)) {\n const style = element('style');\n style.id = style_sheet_id;\n style.textContent = styles;\n append_stylesheet(append_styles_to, style);\n }\n}\nfunction get_root_for_style(node) {\n if (!node)\n return document;\n const root = node.getRootNode ? node.getRootNode() : node.ownerDocument;\n if (root && root.host) {\n return root;\n }\n return node.ownerDocument;\n}\nfunction append_empty_stylesheet(node) {\n const style_element = element('style');\n append_stylesheet(get_root_for_style(node), style_element);\n return style_element.sheet;\n}\nfunction append_stylesheet(node, style) {\n append(node.head || node, style);\n}\nfunction append_hydration(target, node) {\n if (is_hydrating) {\n init_hydrate(target);\n if ((target.actual_end_child === undefined) || ((target.actual_end_child !== null) && (target.actual_end_child.parentElement !== target))) {\n target.actual_end_child = target.firstChild;\n }\n // Skip nodes of undefined ordering\n while ((target.actual_end_child !== null) && (target.actual_end_child.claim_order === undefined)) {\n target.actual_end_child = target.actual_end_child.nextSibling;\n }\n if (node !== target.actual_end_child) {\n // We only insert if the ordering of this node should be modified or the parent node is not target\n if (node.claim_order !== undefined || node.parentNode !== target) {\n target.insertBefore(node, target.actual_end_child);\n }\n }\n else {\n target.actual_end_child = node.nextSibling;\n }\n }\n else if (node.parentNode !== target || node.nextSibling !== null) {\n target.appendChild(node);\n }\n}\nfunction insert(target, node, anchor) {\n target.insertBefore(node, anchor || null);\n}\nfunction insert_hydration(target, node, anchor) {\n if (is_hydrating && !anchor) {\n append_hydration(target, node);\n }\n else if (node.parentNode !== target || node.nextSibling != anchor) {\n target.insertBefore(node, anchor || null);\n }\n}\nfunction detach(node) {\n node.parentNode.removeChild(node);\n}\nfunction destroy_each(iterations, detaching) {\n for (let i = 0; i < iterations.length; i += 1) {\n if (iterations[i])\n iterations[i].d(detaching);\n }\n}\nfunction element(name) {\n return document.createElement(name);\n}\nfunction element_is(name, is) {\n return document.createElement(name, { is });\n}\nfunction object_without_properties(obj, exclude) {\n const target = {};\n for (const k in obj) {\n if (has_prop(obj, k)\n // @ts-ignore\n && exclude.indexOf(k) === -1) {\n // @ts-ignore\n target[k] = obj[k];\n }\n }\n return target;\n}\nfunction svg_element(name) {\n return document.createElementNS('http://www.w3.org/2000/svg', name);\n}\nfunction text(data) {\n return document.createTextNode(data);\n}\nfunction space() {\n return text(' ');\n}\nfunction empty() {\n return text('');\n}\nfunction listen(node, event, handler, options) {\n node.addEventListener(event, handler, options);\n return () => node.removeEventListener(event, handler, options);\n}\nfunction prevent_default(fn) {\n return function (event) {\n event.preventDefault();\n // @ts-ignore\n return fn.call(this, event);\n };\n}\nfunction stop_propagation(fn) {\n return function (event) {\n event.stopPropagation();\n // @ts-ignore\n return fn.call(this, event);\n };\n}\nfunction self(fn) {\n return function (event) {\n // @ts-ignore\n if (event.target === this)\n fn.call(this, event);\n };\n}\nfunction trusted(fn) {\n return function (event) {\n // @ts-ignore\n if (event.isTrusted)\n fn.call(this, event);\n };\n}\nfunction attr(node, attribute, value) {\n if (value == null)\n node.removeAttribute(attribute);\n else if (node.getAttribute(attribute) !== value)\n node.setAttribute(attribute, value);\n}\nfunction set_attributes(node, attributes) {\n // @ts-ignore\n const descriptors = Object.getOwnPropertyDescriptors(node.__proto__);\n for (const key in attributes) {\n if (attributes[key] == null) {\n node.removeAttribute(key);\n }\n else if (key === 'style') {\n node.style.cssText = attributes[key];\n }\n else if (key === '__value') {\n node.value = node[key] = attributes[key];\n }\n else if (descriptors[key] && descriptors[key].set) {\n node[key] = attributes[key];\n }\n else {\n attr(node, key, attributes[key]);\n }\n }\n}\nfunction set_svg_attributes(node, attributes) {\n for (const key in attributes) {\n attr(node, key, attributes[key]);\n }\n}\nfunction set_custom_element_data(node, prop, value) {\n if (prop in node) {\n node[prop] = typeof node[prop] === 'boolean' && value === '' ? true : value;\n }\n else {\n attr(node, prop, value);\n }\n}\nfunction xlink_attr(node, attribute, value) {\n node.setAttributeNS('http://www.w3.org/1999/xlink', attribute, value);\n}\nfunction get_binding_group_value(group, __value, checked) {\n const value = new Set();\n for (let i = 0; i < group.length; i += 1) {\n if (group[i].checked)\n value.add(group[i].__value);\n }\n if (!checked) {\n value.delete(__value);\n }\n return Array.from(value);\n}\nfunction to_number(value) {\n return value === '' ? null : +value;\n}\nfunction time_ranges_to_array(ranges) {\n const array = [];\n for (let i = 0; i < ranges.length; i += 1) {\n array.push({ start: ranges.start(i), end: ranges.end(i) });\n }\n return array;\n}\nfunction children(element) {\n return Array.from(element.childNodes);\n}\nfunction init_claim_info(nodes) {\n if (nodes.claim_info === undefined) {\n nodes.claim_info = { last_index: 0, total_claimed: 0 };\n }\n}\nfunction claim_node(nodes, predicate, processNode, createNode, dontUpdateLastIndex = false) {\n // Try to find nodes in an order such that we lengthen the longest increasing subsequence\n init_claim_info(nodes);\n const resultNode = (() => {\n // We first try to find an element after the previous one\n for (let i = nodes.claim_info.last_index; i < nodes.length; i++) {\n const node = nodes[i];\n if (predicate(node)) {\n const replacement = processNode(node);\n if (replacement === undefined) {\n nodes.splice(i, 1);\n }\n else {\n nodes[i] = replacement;\n }\n if (!dontUpdateLastIndex) {\n nodes.claim_info.last_index = i;\n }\n return node;\n }\n }\n // Otherwise, we try to find one before\n // We iterate in reverse so that we don't go too far back\n for (let i = nodes.claim_info.last_index - 1; i >= 0; i--) {\n const node = nodes[i];\n if (predicate(node)) {\n const replacement = processNode(node);\n if (replacement === undefined) {\n nodes.splice(i, 1);\n }\n else {\n nodes[i] = replacement;\n }\n if (!dontUpdateLastIndex) {\n nodes.claim_info.last_index = i;\n }\n else if (replacement === undefined) {\n // Since we spliced before the last_index, we decrease it\n nodes.claim_info.last_index--;\n }\n return node;\n }\n }\n // If we can't find any matching node, we create a new one\n return createNode();\n })();\n resultNode.claim_order = nodes.claim_info.total_claimed;\n nodes.claim_info.total_claimed += 1;\n return resultNode;\n}\nfunction claim_element_base(nodes, name, attributes, create_element) {\n return claim_node(nodes, (node) => node.nodeName === name, (node) => {\n const remove = [];\n for (let j = 0; j < node.attributes.length; j++) {\n const attribute = node.attributes[j];\n if (!attributes[attribute.name]) {\n remove.push(attribute.name);\n }\n }\n remove.forEach(v => node.removeAttribute(v));\n return undefined;\n }, () => create_element(name));\n}\nfunction claim_element(nodes, name, attributes) {\n return claim_element_base(nodes, name, attributes, element);\n}\nfunction claim_svg_element(nodes, name, attributes) {\n return claim_element_base(nodes, name, attributes, svg_element);\n}\nfunction claim_text(nodes, data) {\n return claim_node(nodes, (node) => node.nodeType === 3, (node) => {\n const dataStr = '' + data;\n if (node.data.startsWith(dataStr)) {\n if (node.data.length !== dataStr.length) {\n return node.splitText(dataStr.length);\n }\n }\n else {\n node.data = dataStr;\n }\n }, () => text(data), true // Text nodes should not update last index since it is likely not worth it to eliminate an increasing subsequence of actual elements\n );\n}\nfunction claim_space(nodes) {\n return claim_text(nodes, ' ');\n}\nfunction find_comment(nodes, text, start) {\n for (let i = start; i < nodes.length; i += 1) {\n const node = nodes[i];\n if (node.nodeType === 8 /* comment node */ && node.textContent.trim() === text) {\n return i;\n }\n }\n return nodes.length;\n}\nfunction claim_html_tag(nodes) {\n // find html opening tag\n const start_index = find_comment(nodes, 'HTML_TAG_START', 0);\n const end_index = find_comment(nodes, 'HTML_TAG_END', start_index);\n if (start_index === end_index) {\n return new HtmlTagHydration();\n }\n init_claim_info(nodes);\n const html_tag_nodes = nodes.splice(start_index, end_index - start_index + 1);\n detach(html_tag_nodes[0]);\n detach(html_tag_nodes[html_tag_nodes.length - 1]);\n const claimed_nodes = html_tag_nodes.slice(1, html_tag_nodes.length - 1);\n for (const n of claimed_nodes) {\n n.claim_order = nodes.claim_info.total_claimed;\n nodes.claim_info.total_claimed += 1;\n }\n return new HtmlTagHydration(claimed_nodes);\n}\nfunction set_data(text, data) {\n data = '' + data;\n if (text.wholeText !== data)\n text.data = data;\n}\nfunction set_input_value(input, value) {\n input.value = value == null ? '' : value;\n}\nfunction set_input_type(input, type) {\n try {\n input.type = type;\n }\n catch (e) {\n // do nothing\n }\n}\nfunction set_style(node, key, value, important) {\n if (value === null) {\n node.style.removeProperty(key);\n }\n else {\n node.style.setProperty(key, value, important ? 'important' : '');\n }\n}\nfunction select_option(select, value) {\n for (let i = 0; i < select.options.length; i += 1) {\n const option = select.options[i];\n if (option.__value === value) {\n option.selected = true;\n return;\n }\n }\n select.selectedIndex = -1; // no option should be selected\n}\nfunction select_options(select, value) {\n for (let i = 0; i < select.options.length; i += 1) {\n const option = select.options[i];\n option.selected = ~value.indexOf(option.__value);\n }\n}\nfunction select_value(select) {\n const selected_option = select.querySelector(':checked') || select.options[0];\n return selected_option && selected_option.__value;\n}\nfunction select_multiple_value(select) {\n return [].map.call(select.querySelectorAll(':checked'), option => option.__value);\n}\n// unfortunately this can't be a constant as that wouldn't be tree-shakeable\n// so we cache the result instead\nlet crossorigin;\nfunction is_crossorigin() {\n if (crossorigin === undefined) {\n crossorigin = false;\n try {\n if (typeof window !== 'undefined' && window.parent) {\n void window.parent.document;\n }\n }\n catch (error) {\n crossorigin = true;\n }\n }\n return crossorigin;\n}\nfunction add_resize_listener(node, fn) {\n const computed_style = getComputedStyle(node);\n if (computed_style.position === 'static') {\n node.style.position = 'relative';\n }\n const iframe = element('iframe');\n iframe.setAttribute('style', 'display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; ' +\n 'overflow: hidden; border: 0; opacity: 0; pointer-events: none; z-index: -1;');\n iframe.setAttribute('aria-hidden', 'true');\n iframe.tabIndex = -1;\n const crossorigin = is_crossorigin();\n let unsubscribe;\n if (crossorigin) {\n iframe.src = \"data:text/html,\";\n unsubscribe = listen(window, 'message', (event) => {\n if (event.source === iframe.contentWindow)\n fn();\n });\n }\n else {\n iframe.src = 'about:blank';\n iframe.onload = () => {\n unsubscribe = listen(iframe.contentWindow, 'resize', fn);\n };\n }\n append(node, iframe);\n return () => {\n if (crossorigin) {\n unsubscribe();\n }\n else if (unsubscribe && iframe.contentWindow) {\n unsubscribe();\n }\n detach(iframe);\n };\n}\nfunction toggle_class(element, name, toggle) {\n element.classList[toggle ? 'add' : 'remove'](name);\n}\nfunction custom_event(type, detail, bubbles = false) {\n const e = document.createEvent('CustomEvent');\n e.initCustomEvent(type, bubbles, false, detail);\n return e;\n}\nfunction query_selector_all(selector, parent = document.body) {\n return Array.from(parent.querySelectorAll(selector));\n}\nclass HtmlTag {\n constructor() {\n this.e = this.n = null;\n }\n c(html) {\n this.h(html);\n }\n m(html, target, anchor = null) {\n if (!this.e) {\n this.e = element(target.nodeName);\n this.t = target;\n this.c(html);\n }\n this.i(anchor);\n }\n h(html) {\n this.e.innerHTML = html;\n this.n = Array.from(this.e.childNodes);\n }\n i(anchor) {\n for (let i = 0; i < this.n.length; i += 1) {\n insert(this.t, this.n[i], anchor);\n }\n }\n p(html) {\n this.d();\n this.h(html);\n this.i(this.a);\n }\n d() {\n this.n.forEach(detach);\n }\n}\nclass HtmlTagHydration extends HtmlTag {\n constructor(claimed_nodes) {\n super();\n this.e = this.n = null;\n this.l = claimed_nodes;\n }\n c(html) {\n if (this.l) {\n this.n = this.l;\n }\n else {\n super.c(html);\n }\n }\n i(anchor) {\n for (let i = 0; i < this.n.length; i += 1) {\n insert_hydration(this.t, this.n[i], anchor);\n }\n }\n}\nfunction attribute_to_object(attributes) {\n const result = {};\n for (const attribute of attributes) {\n result[attribute.name] = attribute.value;\n }\n return result;\n}\nfunction get_custom_elements_slots(element) {\n const result = {};\n element.childNodes.forEach((node) => {\n result[node.slot || 'default'] = true;\n });\n return result;\n}\n\n// we need to store the information for multiple documents because a Svelte application could also contain iframes\n// https://github.com/sveltejs/svelte/issues/3624\nconst managed_styles = new Map();\nlet active = 0;\n// https://github.com/darkskyapp/string-hash/blob/master/index.js\nfunction hash(str) {\n let hash = 5381;\n let i = str.length;\n while (i--)\n hash = ((hash << 5) - hash) ^ str.charCodeAt(i);\n return hash >>> 0;\n}\nfunction create_style_information(doc, node) {\n const info = { stylesheet: append_empty_stylesheet(node), rules: {} };\n managed_styles.set(doc, info);\n return info;\n}\nfunction create_rule(node, a, b, duration, delay, ease, fn, uid = 0) {\n const step = 16.666 / duration;\n let keyframes = '{\\n';\n for (let p = 0; p <= 1; p += step) {\n const t = a + (b - a) * ease(p);\n keyframes += p * 100 + `%{${fn(t, 1 - t)}}\\n`;\n }\n const rule = keyframes + `100% {${fn(b, 1 - b)}}\\n}`;\n const name = `__svelte_${hash(rule)}_${uid}`;\n const doc = get_root_for_style(node);\n const { stylesheet, rules } = managed_styles.get(doc) || create_style_information(doc, node);\n if (!rules[name]) {\n rules[name] = true;\n stylesheet.insertRule(`@keyframes ${name} ${rule}`, stylesheet.cssRules.length);\n }\n const animation = node.style.animation || '';\n node.style.animation = `${animation ? `${animation}, ` : ''}${name} ${duration}ms linear ${delay}ms 1 both`;\n active += 1;\n return name;\n}\nfunction delete_rule(node, name) {\n const previous = (node.style.animation || '').split(', ');\n const next = previous.filter(name\n ? anim => anim.indexOf(name) < 0 // remove specific animation\n : anim => anim.indexOf('__svelte') === -1 // remove all Svelte animations\n );\n const deleted = previous.length - next.length;\n if (deleted) {\n node.style.animation = next.join(', ');\n active -= deleted;\n if (!active)\n clear_rules();\n }\n}\nfunction clear_rules() {\n raf(() => {\n if (active)\n return;\n managed_styles.forEach(info => {\n const { stylesheet } = info;\n let i = stylesheet.cssRules.length;\n while (i--)\n stylesheet.deleteRule(i);\n info.rules = {};\n });\n managed_styles.clear();\n });\n}\n\nfunction create_animation(node, from, fn, params) {\n if (!from)\n return noop;\n const to = node.getBoundingClientRect();\n if (from.left === to.left && from.right === to.right && from.top === to.top && from.bottom === to.bottom)\n return noop;\n const { delay = 0, duration = 300, easing = identity, \n // @ts-ignore todo: should this be separated from destructuring? Or start/end added to public api and documentation?\n start: start_time = now() + delay, \n // @ts-ignore todo:\n end = start_time + duration, tick = noop, css } = fn(node, { from, to }, params);\n let running = true;\n let started = false;\n let name;\n function start() {\n if (css) {\n name = create_rule(node, 0, 1, duration, delay, easing, css);\n }\n if (!delay) {\n started = true;\n }\n }\n function stop() {\n if (css)\n delete_rule(node, name);\n running = false;\n }\n loop(now => {\n if (!started && now >= start_time) {\n started = true;\n }\n if (started && now >= end) {\n tick(1, 0);\n stop();\n }\n if (!running) {\n return false;\n }\n if (started) {\n const p = now - start_time;\n const t = 0 + 1 * easing(p / duration);\n tick(t, 1 - t);\n }\n return true;\n });\n start();\n tick(0, 1);\n return stop;\n}\nfunction fix_position(node) {\n const style = getComputedStyle(node);\n if (style.position !== 'absolute' && style.position !== 'fixed') {\n const { width, height } = style;\n const a = node.getBoundingClientRect();\n node.style.position = 'absolute';\n node.style.width = width;\n node.style.height = height;\n add_transform(node, a);\n }\n}\nfunction add_transform(node, a) {\n const b = node.getBoundingClientRect();\n if (a.left !== b.left || a.top !== b.top) {\n const style = getComputedStyle(node);\n const transform = style.transform === 'none' ? '' : style.transform;\n node.style.transform = `${transform} translate(${a.left - b.left}px, ${a.top - b.top}px)`;\n }\n}\n\nlet current_component;\nfunction set_current_component(component) {\n current_component = component;\n}\nfunction get_current_component() {\n if (!current_component)\n throw new Error('Function called outside component initialization');\n return current_component;\n}\nfunction beforeUpdate(fn) {\n get_current_component().$$.before_update.push(fn);\n}\nfunction onMount(fn) {\n get_current_component().$$.on_mount.push(fn);\n}\nfunction afterUpdate(fn) {\n get_current_component().$$.after_update.push(fn);\n}\nfunction onDestroy(fn) {\n get_current_component().$$.on_destroy.push(fn);\n}\nfunction createEventDispatcher() {\n const component = get_current_component();\n return (type, detail) => {\n const callbacks = component.$$.callbacks[type];\n if (callbacks) {\n // TODO are there situations where events could be dispatched\n // in a server (non-DOM) environment?\n const event = custom_event(type, detail);\n callbacks.slice().forEach(fn => {\n fn.call(component, event);\n });\n }\n };\n}\nfunction setContext(key, context) {\n get_current_component().$$.context.set(key, context);\n}\nfunction getContext(key) {\n return get_current_component().$$.context.get(key);\n}\nfunction getAllContexts() {\n return get_current_component().$$.context;\n}\nfunction hasContext(key) {\n return get_current_component().$$.context.has(key);\n}\n// TODO figure out if we still want to support\n// shorthand events, or if we want to implement\n// a real bubbling mechanism\nfunction bubble(component, event) {\n const callbacks = component.$$.callbacks[event.type];\n if (callbacks) {\n // @ts-ignore\n callbacks.slice().forEach(fn => fn.call(this, event));\n }\n}\n\nconst dirty_components = [];\nconst intros = { enabled: false };\nconst binding_callbacks = [];\nconst render_callbacks = [];\nconst flush_callbacks = [];\nconst resolved_promise = Promise.resolve();\nlet update_scheduled = false;\nfunction schedule_update() {\n if (!update_scheduled) {\n update_scheduled = true;\n resolved_promise.then(flush);\n }\n}\nfunction tick() {\n schedule_update();\n return resolved_promise;\n}\nfunction add_render_callback(fn) {\n render_callbacks.push(fn);\n}\nfunction add_flush_callback(fn) {\n flush_callbacks.push(fn);\n}\n// flush() calls callbacks in this order:\n// 1. All beforeUpdate callbacks, in order: parents before children\n// 2. All bind:this callbacks, in reverse order: children before parents.\n// 3. All afterUpdate callbacks, in order: parents before children. EXCEPT\n// for afterUpdates called during the initial onMount, which are called in\n// reverse order: children before parents.\n// Since callbacks might update component values, which could trigger another\n// call to flush(), the following steps guard against this:\n// 1. During beforeUpdate, any updated components will be added to the\n// dirty_components array and will cause a reentrant call to flush(). Because\n// the flush index is kept outside the function, the reentrant call will pick\n// up where the earlier call left off and go through all dirty components. The\n// current_component value is saved and restored so that the reentrant call will\n// not interfere with the \"parent\" flush() call.\n// 2. bind:this callbacks cannot trigger new flush() calls.\n// 3. During afterUpdate, any updated components will NOT have their afterUpdate\n// callback called a second time; the seen_callbacks set, outside the flush()\n// function, guarantees this behavior.\nconst seen_callbacks = new Set();\nlet flushidx = 0; // Do *not* move this inside the flush() function\nfunction flush() {\n const saved_component = current_component;\n do {\n // first, call beforeUpdate functions\n // and update components\n while (flushidx < dirty_components.length) {\n const component = dirty_components[flushidx];\n flushidx++;\n set_current_component(component);\n update(component.$$);\n }\n set_current_component(null);\n dirty_components.length = 0;\n flushidx = 0;\n while (binding_callbacks.length)\n binding_callbacks.pop()();\n // then, once components are updated, call\n // afterUpdate functions. This may cause\n // subsequent updates...\n for (let i = 0; i < render_callbacks.length; i += 1) {\n const callback = render_callbacks[i];\n if (!seen_callbacks.has(callback)) {\n // ...so guard against infinite loops\n seen_callbacks.add(callback);\n callback();\n }\n }\n render_callbacks.length = 0;\n } while (dirty_components.length);\n while (flush_callbacks.length) {\n flush_callbacks.pop()();\n }\n update_scheduled = false;\n seen_callbacks.clear();\n set_current_component(saved_component);\n}\nfunction update($$) {\n if ($$.fragment !== null) {\n $$.update();\n run_all($$.before_update);\n const dirty = $$.dirty;\n $$.dirty = [-1];\n $$.fragment && $$.fragment.p($$.ctx, dirty);\n $$.after_update.forEach(add_render_callback);\n }\n}\n\nlet promise;\nfunction wait() {\n if (!promise) {\n promise = Promise.resolve();\n promise.then(() => {\n promise = null;\n });\n }\n return promise;\n}\nfunction dispatch(node, direction, kind) {\n node.dispatchEvent(custom_event(`${direction ? 'intro' : 'outro'}${kind}`));\n}\nconst outroing = new Set();\nlet outros;\nfunction group_outros() {\n outros = {\n r: 0,\n c: [],\n p: outros // parent group\n };\n}\nfunction check_outros() {\n if (!outros.r) {\n run_all(outros.c);\n }\n outros = outros.p;\n}\nfunction transition_in(block, local) {\n if (block && block.i) {\n outroing.delete(block);\n block.i(local);\n }\n}\nfunction transition_out(block, local, detach, callback) {\n if (block && block.o) {\n if (outroing.has(block))\n return;\n outroing.add(block);\n outros.c.push(() => {\n outroing.delete(block);\n if (callback) {\n if (detach)\n block.d(1);\n callback();\n }\n });\n block.o(local);\n }\n}\nconst null_transition = { duration: 0 };\nfunction create_in_transition(node, fn, params) {\n let config = fn(node, params);\n let running = false;\n let animation_name;\n let task;\n let uid = 0;\n function cleanup() {\n if (animation_name)\n delete_rule(node, animation_name);\n }\n function go() {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n if (css)\n animation_name = create_rule(node, 0, 1, duration, delay, easing, css, uid++);\n tick(0, 1);\n const start_time = now() + delay;\n const end_time = start_time + duration;\n if (task)\n task.abort();\n running = true;\n add_render_callback(() => dispatch(node, true, 'start'));\n task = loop(now => {\n if (running) {\n if (now >= end_time) {\n tick(1, 0);\n dispatch(node, true, 'end');\n cleanup();\n return running = false;\n }\n if (now >= start_time) {\n const t = easing((now - start_time) / duration);\n tick(t, 1 - t);\n }\n }\n return running;\n });\n }\n let started = false;\n return {\n start() {\n if (started)\n return;\n started = true;\n delete_rule(node);\n if (is_function(config)) {\n config = config();\n wait().then(go);\n }\n else {\n go();\n }\n },\n invalidate() {\n started = false;\n },\n end() {\n if (running) {\n cleanup();\n running = false;\n }\n }\n };\n}\nfunction create_out_transition(node, fn, params) {\n let config = fn(node, params);\n let running = true;\n let animation_name;\n const group = outros;\n group.r += 1;\n function go() {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n if (css)\n animation_name = create_rule(node, 1, 0, duration, delay, easing, css);\n const start_time = now() + delay;\n const end_time = start_time + duration;\n add_render_callback(() => dispatch(node, false, 'start'));\n loop(now => {\n if (running) {\n if (now >= end_time) {\n tick(0, 1);\n dispatch(node, false, 'end');\n if (!--group.r) {\n // this will result in `end()` being called,\n // so we don't need to clean up here\n run_all(group.c);\n }\n return false;\n }\n if (now >= start_time) {\n const t = easing((now - start_time) / duration);\n tick(1 - t, t);\n }\n }\n return running;\n });\n }\n if (is_function(config)) {\n wait().then(() => {\n // @ts-ignore\n config = config();\n go();\n });\n }\n else {\n go();\n }\n return {\n end(reset) {\n if (reset && config.tick) {\n config.tick(1, 0);\n }\n if (running) {\n if (animation_name)\n delete_rule(node, animation_name);\n running = false;\n }\n }\n };\n}\nfunction create_bidirectional_transition(node, fn, params, intro) {\n let config = fn(node, params);\n let t = intro ? 0 : 1;\n let running_program = null;\n let pending_program = null;\n let animation_name = null;\n function clear_animation() {\n if (animation_name)\n delete_rule(node, animation_name);\n }\n function init(program, duration) {\n const d = (program.b - t);\n duration *= Math.abs(d);\n return {\n a: t,\n b: program.b,\n d,\n duration,\n start: program.start,\n end: program.start + duration,\n group: program.group\n };\n }\n function go(b) {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n const program = {\n start: now() + delay,\n b\n };\n if (!b) {\n // @ts-ignore todo: improve typings\n program.group = outros;\n outros.r += 1;\n }\n if (running_program || pending_program) {\n pending_program = program;\n }\n else {\n // if this is an intro, and there's a delay, we need to do\n // an initial tick and/or apply CSS animation immediately\n if (css) {\n clear_animation();\n animation_name = create_rule(node, t, b, duration, delay, easing, css);\n }\n if (b)\n tick(0, 1);\n running_program = init(program, duration);\n add_render_callback(() => dispatch(node, b, 'start'));\n loop(now => {\n if (pending_program && now > pending_program.start) {\n running_program = init(pending_program, duration);\n pending_program = null;\n dispatch(node, running_program.b, 'start');\n if (css) {\n clear_animation();\n animation_name = create_rule(node, t, running_program.b, running_program.duration, 0, easing, config.css);\n }\n }\n if (running_program) {\n if (now >= running_program.end) {\n tick(t = running_program.b, 1 - t);\n dispatch(node, running_program.b, 'end');\n if (!pending_program) {\n // we're done\n if (running_program.b) {\n // intro — we can tidy up immediately\n clear_animation();\n }\n else {\n // outro — needs to be coordinated\n if (!--running_program.group.r)\n run_all(running_program.group.c);\n }\n }\n running_program = null;\n }\n else if (now >= running_program.start) {\n const p = now - running_program.start;\n t = running_program.a + running_program.d * easing(p / running_program.duration);\n tick(t, 1 - t);\n }\n }\n return !!(running_program || pending_program);\n });\n }\n }\n return {\n run(b) {\n if (is_function(config)) {\n wait().then(() => {\n // @ts-ignore\n config = config();\n go(b);\n });\n }\n else {\n go(b);\n }\n },\n end() {\n clear_animation();\n running_program = pending_program = null;\n }\n };\n}\n\nfunction handle_promise(promise, info) {\n const token = info.token = {};\n function update(type, index, key, value) {\n if (info.token !== token)\n return;\n info.resolved = value;\n let child_ctx = info.ctx;\n if (key !== undefined) {\n child_ctx = child_ctx.slice();\n child_ctx[key] = value;\n }\n const block = type && (info.current = type)(child_ctx);\n let needs_flush = false;\n if (info.block) {\n if (info.blocks) {\n info.blocks.forEach((block, i) => {\n if (i !== index && block) {\n group_outros();\n transition_out(block, 1, 1, () => {\n if (info.blocks[i] === block) {\n info.blocks[i] = null;\n }\n });\n check_outros();\n }\n });\n }\n else {\n info.block.d(1);\n }\n block.c();\n transition_in(block, 1);\n block.m(info.mount(), info.anchor);\n needs_flush = true;\n }\n info.block = block;\n if (info.blocks)\n info.blocks[index] = block;\n if (needs_flush) {\n flush();\n }\n }\n if (is_promise(promise)) {\n const current_component = get_current_component();\n promise.then(value => {\n set_current_component(current_component);\n update(info.then, 1, info.value, value);\n set_current_component(null);\n }, error => {\n set_current_component(current_component);\n update(info.catch, 2, info.error, error);\n set_current_component(null);\n if (!info.hasCatch) {\n throw error;\n }\n });\n // if we previously had a then/catch block, destroy it\n if (info.current !== info.pending) {\n update(info.pending, 0);\n return true;\n }\n }\n else {\n if (info.current !== info.then) {\n update(info.then, 1, info.value, promise);\n return true;\n }\n info.resolved = promise;\n }\n}\nfunction update_await_block_branch(info, ctx, dirty) {\n const child_ctx = ctx.slice();\n const { resolved } = info;\n if (info.current === info.then) {\n child_ctx[info.value] = resolved;\n }\n if (info.current === info.catch) {\n child_ctx[info.error] = resolved;\n }\n info.block.p(child_ctx, dirty);\n}\n\nconst globals = (typeof window !== 'undefined'\n ? window\n : typeof globalThis !== 'undefined'\n ? globalThis\n : global);\n\nfunction destroy_block(block, lookup) {\n block.d(1);\n lookup.delete(block.key);\n}\nfunction outro_and_destroy_block(block, lookup) {\n transition_out(block, 1, 1, () => {\n lookup.delete(block.key);\n });\n}\nfunction fix_and_destroy_block(block, lookup) {\n block.f();\n destroy_block(block, lookup);\n}\nfunction fix_and_outro_and_destroy_block(block, lookup) {\n block.f();\n outro_and_destroy_block(block, lookup);\n}\nfunction update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block, next, get_context) {\n let o = old_blocks.length;\n let n = list.length;\n let i = o;\n const old_indexes = {};\n while (i--)\n old_indexes[old_blocks[i].key] = i;\n const new_blocks = [];\n const new_lookup = new Map();\n const deltas = new Map();\n i = n;\n while (i--) {\n const child_ctx = get_context(ctx, list, i);\n const key = get_key(child_ctx);\n let block = lookup.get(key);\n if (!block) {\n block = create_each_block(key, child_ctx);\n block.c();\n }\n else if (dynamic) {\n block.p(child_ctx, dirty);\n }\n new_lookup.set(key, new_blocks[i] = block);\n if (key in old_indexes)\n deltas.set(key, Math.abs(i - old_indexes[key]));\n }\n const will_move = new Set();\n const did_move = new Set();\n function insert(block) {\n transition_in(block, 1);\n block.m(node, next);\n lookup.set(block.key, block);\n next = block.first;\n n--;\n }\n while (o && n) {\n const new_block = new_blocks[n - 1];\n const old_block = old_blocks[o - 1];\n const new_key = new_block.key;\n const old_key = old_block.key;\n if (new_block === old_block) {\n // do nothing\n next = new_block.first;\n o--;\n n--;\n }\n else if (!new_lookup.has(old_key)) {\n // remove old block\n destroy(old_block, lookup);\n o--;\n }\n else if (!lookup.has(new_key) || will_move.has(new_key)) {\n insert(new_block);\n }\n else if (did_move.has(old_key)) {\n o--;\n }\n else if (deltas.get(new_key) > deltas.get(old_key)) {\n did_move.add(new_key);\n insert(new_block);\n }\n else {\n will_move.add(old_key);\n o--;\n }\n }\n while (o--) {\n const old_block = old_blocks[o];\n if (!new_lookup.has(old_block.key))\n destroy(old_block, lookup);\n }\n while (n)\n insert(new_blocks[n - 1]);\n return new_blocks;\n}\nfunction validate_each_keys(ctx, list, get_context, get_key) {\n const keys = new Set();\n for (let i = 0; i < list.length; i++) {\n const key = get_key(get_context(ctx, list, i));\n if (keys.has(key)) {\n throw new Error('Cannot have duplicate keys in a keyed each');\n }\n keys.add(key);\n }\n}\n\nfunction get_spread_update(levels, updates) {\n const update = {};\n const to_null_out = {};\n const accounted_for = { $$scope: 1 };\n let i = levels.length;\n while (i--) {\n const o = levels[i];\n const n = updates[i];\n if (n) {\n for (const key in o) {\n if (!(key in n))\n to_null_out[key] = 1;\n }\n for (const key in n) {\n if (!accounted_for[key]) {\n update[key] = n[key];\n accounted_for[key] = 1;\n }\n }\n levels[i] = n;\n }\n else {\n for (const key in o) {\n accounted_for[key] = 1;\n }\n }\n }\n for (const key in to_null_out) {\n if (!(key in update))\n update[key] = undefined;\n }\n return update;\n}\nfunction get_spread_object(spread_props) {\n return typeof spread_props === 'object' && spread_props !== null ? spread_props : {};\n}\n\n// source: https://html.spec.whatwg.org/multipage/indices.html\nconst boolean_attributes = new Set([\n 'allowfullscreen',\n 'allowpaymentrequest',\n 'async',\n 'autofocus',\n 'autoplay',\n 'checked',\n 'controls',\n 'default',\n 'defer',\n 'disabled',\n 'formnovalidate',\n 'hidden',\n 'ismap',\n 'loop',\n 'multiple',\n 'muted',\n 'nomodule',\n 'novalidate',\n 'open',\n 'playsinline',\n 'readonly',\n 'required',\n 'reversed',\n 'selected'\n]);\n\nconst invalid_attribute_name_character = /[\\s'\">/=\\u{FDD0}-\\u{FDEF}\\u{FFFE}\\u{FFFF}\\u{1FFFE}\\u{1FFFF}\\u{2FFFE}\\u{2FFFF}\\u{3FFFE}\\u{3FFFF}\\u{4FFFE}\\u{4FFFF}\\u{5FFFE}\\u{5FFFF}\\u{6FFFE}\\u{6FFFF}\\u{7FFFE}\\u{7FFFF}\\u{8FFFE}\\u{8FFFF}\\u{9FFFE}\\u{9FFFF}\\u{AFFFE}\\u{AFFFF}\\u{BFFFE}\\u{BFFFF}\\u{CFFFE}\\u{CFFFF}\\u{DFFFE}\\u{DFFFF}\\u{EFFFE}\\u{EFFFF}\\u{FFFFE}\\u{FFFFF}\\u{10FFFE}\\u{10FFFF}]/u;\n// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n// https://infra.spec.whatwg.org/#noncharacter\nfunction spread(args, attrs_to_add) {\n const attributes = Object.assign({}, ...args);\n if (attrs_to_add) {\n const classes_to_add = attrs_to_add.classes;\n const styles_to_add = attrs_to_add.styles;\n if (classes_to_add) {\n if (attributes.class == null) {\n attributes.class = classes_to_add;\n }\n else {\n attributes.class += ' ' + classes_to_add;\n }\n }\n if (styles_to_add) {\n if (attributes.style == null) {\n attributes.style = style_object_to_string(styles_to_add);\n }\n else {\n attributes.style = style_object_to_string(merge_ssr_styles(attributes.style, styles_to_add));\n }\n }\n }\n let str = '';\n Object.keys(attributes).forEach(name => {\n if (invalid_attribute_name_character.test(name))\n return;\n const value = attributes[name];\n if (value === true)\n str += ' ' + name;\n else if (boolean_attributes.has(name.toLowerCase())) {\n if (value)\n str += ' ' + name;\n }\n else if (value != null) {\n str += ` ${name}=\"${value}\"`;\n }\n });\n return str;\n}\nfunction merge_ssr_styles(style_attribute, style_directive) {\n const style_object = {};\n for (const individual_style of style_attribute.split(';')) {\n const colon_index = individual_style.indexOf(':');\n const name = individual_style.slice(0, colon_index).trim();\n const value = individual_style.slice(colon_index + 1).trim();\n if (!name)\n continue;\n style_object[name] = value;\n }\n for (const name in style_directive) {\n const value = style_directive[name];\n if (value) {\n style_object[name] = value;\n }\n else {\n delete style_object[name];\n }\n }\n return style_object;\n}\nconst escaped = {\n '\"': '"',\n \"'\": ''',\n '&': '&',\n '<': '<',\n '>': '>'\n};\nfunction escape(html) {\n return String(html).replace(/[\"'&<>]/g, match => escaped[match]);\n}\nfunction escape_attribute_value(value) {\n return typeof value === 'string' ? escape(value) : value;\n}\nfunction escape_object(obj) {\n const result = {};\n for (const key in obj) {\n result[key] = escape_attribute_value(obj[key]);\n }\n return result;\n}\nfunction each(items, fn) {\n let str = '';\n for (let i = 0; i < items.length; i += 1) {\n str += fn(items[i], i);\n }\n return str;\n}\nconst missing_component = {\n $$render: () => ''\n};\nfunction validate_component(component, name) {\n if (!component || !component.$$render) {\n if (name === 'svelte:component')\n name += ' this={...}';\n throw new Error(`<${name}> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules`);\n }\n return component;\n}\nfunction debug(file, line, column, values) {\n console.log(`{@debug} ${file ? file + ' ' : ''}(${line}:${column})`); // eslint-disable-line no-console\n console.log(values); // eslint-disable-line no-console\n return '';\n}\nlet on_destroy;\nfunction create_ssr_component(fn) {\n function $$render(result, props, bindings, slots, context) {\n const parent_component = current_component;\n const $$ = {\n on_destroy,\n context: new Map(context || (parent_component ? parent_component.$$.context : [])),\n // these will be immediately discarded\n on_mount: [],\n before_update: [],\n after_update: [],\n callbacks: blank_object()\n };\n set_current_component({ $$ });\n const html = fn(result, props, bindings, slots);\n set_current_component(parent_component);\n return html;\n }\n return {\n render: (props = {}, { $$slots = {}, context = new Map() } = {}) => {\n on_destroy = [];\n const result = { title: '', head: '', css: new Set() };\n const html = $$render(result, props, {}, $$slots, context);\n run_all(on_destroy);\n return {\n html,\n css: {\n code: Array.from(result.css).map(css => css.code).join('\\n'),\n map: null // TODO\n },\n head: result.title + result.head\n };\n },\n $$render\n };\n}\nfunction add_attribute(name, value, boolean) {\n if (value == null || (boolean && !value))\n return '';\n return ` ${name}${value === true && boolean_attributes.has(name) ? '' : `=${typeof value === 'string' ? JSON.stringify(escape(value)) : `\"${value}\"`}`}`;\n}\nfunction add_classes(classes) {\n return classes ? ` class=\"${classes}\"` : '';\n}\nfunction style_object_to_string(style_object) {\n return Object.keys(style_object)\n .filter(key => style_object[key])\n .map(key => `${key}: ${style_object[key]};`)\n .join(' ');\n}\nfunction add_styles(style_object) {\n const styles = style_object_to_string(style_object);\n return styles ? ` style=\"${styles}\"` : '';\n}\n\nfunction bind(component, name, callback) {\n const index = component.$$.props[name];\n if (index !== undefined) {\n component.$$.bound[index] = callback;\n callback(component.$$.ctx[index]);\n }\n}\nfunction create_component(block) {\n block && block.c();\n}\nfunction claim_component(block, parent_nodes) {\n block && block.l(parent_nodes);\n}\nfunction mount_component(component, target, anchor, customElement) {\n const { fragment, on_mount, on_destroy, after_update } = component.$$;\n fragment && fragment.m(target, anchor);\n if (!customElement) {\n // onMount happens before the initial afterUpdate\n add_render_callback(() => {\n const new_on_destroy = on_mount.map(run).filter(is_function);\n if (on_destroy) {\n on_destroy.push(...new_on_destroy);\n }\n else {\n // Edge case - component was destroyed immediately,\n // most likely as a result of a binding initialising\n run_all(new_on_destroy);\n }\n component.$$.on_mount = [];\n });\n }\n after_update.forEach(add_render_callback);\n}\nfunction destroy_component(component, detaching) {\n const $$ = component.$$;\n if ($$.fragment !== null) {\n run_all($$.on_destroy);\n $$.fragment && $$.fragment.d(detaching);\n // TODO null out other refs, including component.$$ (but need to\n // preserve final state?)\n $$.on_destroy = $$.fragment = null;\n $$.ctx = [];\n }\n}\nfunction make_dirty(component, i) {\n if (component.$$.dirty[0] === -1) {\n dirty_components.push(component);\n schedule_update();\n component.$$.dirty.fill(0);\n }\n component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));\n}\nfunction init(component, options, instance, create_fragment, not_equal, props, append_styles, dirty = [-1]) {\n const parent_component = current_component;\n set_current_component(component);\n const $$ = component.$$ = {\n fragment: null,\n ctx: null,\n // state\n props,\n update: noop,\n not_equal,\n bound: blank_object(),\n // lifecycle\n on_mount: [],\n on_destroy: [],\n on_disconnect: [],\n before_update: [],\n after_update: [],\n context: new Map(options.context || (parent_component ? parent_component.$$.context : [])),\n // everything else\n callbacks: blank_object(),\n dirty,\n skip_bound: false,\n root: options.target || parent_component.$$.root\n };\n append_styles && append_styles($$.root);\n let ready = false;\n $$.ctx = instance\n ? instance(component, options.props || {}, (i, ret, ...rest) => {\n const value = rest.length ? rest[0] : ret;\n if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {\n if (!$$.skip_bound && $$.bound[i])\n $$.bound[i](value);\n if (ready)\n make_dirty(component, i);\n }\n return ret;\n })\n : [];\n $$.update();\n ready = true;\n run_all($$.before_update);\n // `false` as a special case of no DOM component\n $$.fragment = create_fragment ? create_fragment($$.ctx) : false;\n if (options.target) {\n if (options.hydrate) {\n start_hydrating();\n const nodes = children(options.target);\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n $$.fragment && $$.fragment.l(nodes);\n nodes.forEach(detach);\n }\n else {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n $$.fragment && $$.fragment.c();\n }\n if (options.intro)\n transition_in(component.$$.fragment);\n mount_component(component, options.target, options.anchor, options.customElement);\n end_hydrating();\n flush();\n }\n set_current_component(parent_component);\n}\nlet SvelteElement;\nif (typeof HTMLElement === 'function') {\n SvelteElement = class extends HTMLElement {\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\n }\n connectedCallback() {\n const { on_mount } = this.$$;\n this.$$.on_disconnect = on_mount.map(run).filter(is_function);\n // @ts-ignore todo: improve typings\n for (const key in this.$$.slotted) {\n // @ts-ignore todo: improve typings\n this.appendChild(this.$$.slotted[key]);\n }\n }\n attributeChangedCallback(attr, _oldValue, newValue) {\n this[attr] = newValue;\n }\n disconnectedCallback() {\n run_all(this.$$.on_disconnect);\n }\n $destroy() {\n destroy_component(this, 1);\n this.$destroy = noop;\n }\n $on(type, callback) {\n // TODO should this delegate to addEventListener?\n const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));\n callbacks.push(callback);\n return () => {\n const index = callbacks.indexOf(callback);\n if (index !== -1)\n callbacks.splice(index, 1);\n };\n }\n $set($$props) {\n if (this.$$set && !is_empty($$props)) {\n this.$$.skip_bound = true;\n this.$$set($$props);\n this.$$.skip_bound = false;\n }\n }\n };\n}\n/**\n * Base class for Svelte components. Used when dev=false.\n */\nclass SvelteComponent {\n $destroy() {\n destroy_component(this, 1);\n this.$destroy = noop;\n }\n $on(type, callback) {\n const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));\n callbacks.push(callback);\n return () => {\n const index = callbacks.indexOf(callback);\n if (index !== -1)\n callbacks.splice(index, 1);\n };\n }\n $set($$props) {\n if (this.$$set && !is_empty($$props)) {\n this.$$.skip_bound = true;\n this.$$set($$props);\n this.$$.skip_bound = false;\n }\n }\n}\n\nfunction dispatch_dev(type, detail) {\n document.dispatchEvent(custom_event(type, Object.assign({ version: '3.46.4' }, detail), true));\n}\nfunction append_dev(target, node) {\n dispatch_dev('SvelteDOMInsert', { target, node });\n append(target, node);\n}\nfunction append_hydration_dev(target, node) {\n dispatch_dev('SvelteDOMInsert', { target, node });\n append_hydration(target, node);\n}\nfunction insert_dev(target, node, anchor) {\n dispatch_dev('SvelteDOMInsert', { target, node, anchor });\n insert(target, node, anchor);\n}\nfunction insert_hydration_dev(target, node, anchor) {\n dispatch_dev('SvelteDOMInsert', { target, node, anchor });\n insert_hydration(target, node, anchor);\n}\nfunction detach_dev(node) {\n dispatch_dev('SvelteDOMRemove', { node });\n detach(node);\n}\nfunction detach_between_dev(before, after) {\n while (before.nextSibling && before.nextSibling !== after) {\n detach_dev(before.nextSibling);\n }\n}\nfunction detach_before_dev(after) {\n while (after.previousSibling) {\n detach_dev(after.previousSibling);\n }\n}\nfunction detach_after_dev(before) {\n while (before.nextSibling) {\n detach_dev(before.nextSibling);\n }\n}\nfunction listen_dev(node, event, handler, options, has_prevent_default, has_stop_propagation) {\n const modifiers = options === true ? ['capture'] : options ? Array.from(Object.keys(options)) : [];\n if (has_prevent_default)\n modifiers.push('preventDefault');\n if (has_stop_propagation)\n modifiers.push('stopPropagation');\n dispatch_dev('SvelteDOMAddEventListener', { node, event, handler, modifiers });\n const dispose = listen(node, event, handler, options);\n return () => {\n dispatch_dev('SvelteDOMRemoveEventListener', { node, event, handler, modifiers });\n dispose();\n };\n}\nfunction attr_dev(node, attribute, value) {\n attr(node, attribute, value);\n if (value == null)\n dispatch_dev('SvelteDOMRemoveAttribute', { node, attribute });\n else\n dispatch_dev('SvelteDOMSetAttribute', { node, attribute, value });\n}\nfunction prop_dev(node, property, value) {\n node[property] = value;\n dispatch_dev('SvelteDOMSetProperty', { node, property, value });\n}\nfunction dataset_dev(node, property, value) {\n node.dataset[property] = value;\n dispatch_dev('SvelteDOMSetDataset', { node, property, value });\n}\nfunction set_data_dev(text, data) {\n data = '' + data;\n if (text.wholeText === data)\n return;\n dispatch_dev('SvelteDOMSetData', { node: text, data });\n text.data = data;\n}\nfunction validate_each_argument(arg) {\n if (typeof arg !== 'string' && !(arg && typeof arg === 'object' && 'length' in arg)) {\n let msg = '{#each} only iterates over array-like objects.';\n if (typeof Symbol === 'function' && arg && Symbol.iterator in arg) {\n msg += ' You can use a spread to convert this iterable into an array.';\n }\n throw new Error(msg);\n }\n}\nfunction validate_slots(name, slot, keys) {\n for (const slot_key of Object.keys(slot)) {\n if (!~keys.indexOf(slot_key)) {\n console.warn(`<${name}> received an unexpected slot \"${slot_key}\".`);\n }\n }\n}\n/**\n * Base class for Svelte components with some minor dev-enhancements. Used when dev=true.\n */\nclass SvelteComponentDev extends SvelteComponent {\n constructor(options) {\n if (!options || (!options.target && !options.$$inline)) {\n throw new Error(\"'target' is a required option\");\n }\n super();\n }\n $destroy() {\n super.$destroy();\n this.$destroy = () => {\n console.warn('Component was already destroyed'); // eslint-disable-line no-console\n };\n }\n $capture_state() { }\n $inject_state() { }\n}\n/**\n * Base class to create strongly typed Svelte components.\n * This only exists for typing purposes and should be used in `.d.ts` files.\n *\n * ### Example:\n *\n * You have component library on npm called `component-library`, from which\n * you export a component called `MyComponent`. For Svelte+TypeScript users,\n * you want to provide typings. Therefore you create a `index.d.ts`:\n * ```ts\n * import { SvelteComponentTyped } from \"svelte\";\n * export class MyComponent extends SvelteComponentTyped<{foo: string}> {}\n * ```\n * Typing this makes it possible for IDEs like VS Code with the Svelte extension\n * to provide intellisense and to use the component like this in a Svelte file\n * with TypeScript:\n * ```svelte\n * \n * \n * ```\n *\n * #### Why not make this part of `SvelteComponent(Dev)`?\n * Because\n * ```ts\n * class ASubclassOfSvelteComponent extends SvelteComponent<{foo: string}> {}\n * const component: typeof SvelteComponent = ASubclassOfSvelteComponent;\n * ```\n * will throw a type error, so we need to separate the more strictly typed class.\n */\nclass SvelteComponentTyped extends SvelteComponentDev {\n constructor(options) {\n super(options);\n }\n}\nfunction loop_guard(timeout) {\n const start = Date.now();\n return () => {\n if (Date.now() - start > timeout) {\n throw new Error('Infinite loop detected');\n }\n };\n}\n\nexport { HtmlTag, HtmlTagHydration, SvelteComponent, SvelteComponentDev, SvelteComponentTyped, SvelteElement, action_destroyer, add_attribute, add_classes, add_flush_callback, add_location, add_render_callback, add_resize_listener, add_styles, add_transform, afterUpdate, append, append_dev, append_empty_stylesheet, append_hydration, append_hydration_dev, append_styles, assign, attr, attr_dev, attribute_to_object, beforeUpdate, bind, binding_callbacks, blank_object, bubble, check_outros, children, claim_component, claim_element, claim_html_tag, claim_space, claim_svg_element, claim_text, clear_loops, component_subscribe, compute_rest_props, compute_slots, createEventDispatcher, create_animation, create_bidirectional_transition, create_component, create_in_transition, create_out_transition, create_slot, create_ssr_component, current_component, custom_event, dataset_dev, debug, destroy_block, destroy_component, destroy_each, detach, detach_after_dev, detach_before_dev, detach_between_dev, detach_dev, dirty_components, dispatch_dev, each, element, element_is, empty, end_hydrating, escape, escape_attribute_value, escape_object, escaped, exclude_internal_props, fix_and_destroy_block, fix_and_outro_and_destroy_block, fix_position, flush, getAllContexts, getContext, get_all_dirty_from_scope, get_binding_group_value, get_current_component, get_custom_elements_slots, get_root_for_style, get_slot_changes, get_spread_object, get_spread_update, get_store_value, globals, group_outros, handle_promise, hasContext, has_prop, identity, init, insert, insert_dev, insert_hydration, insert_hydration_dev, intros, invalid_attribute_name_character, is_client, is_crossorigin, is_empty, is_function, is_promise, listen, listen_dev, loop, loop_guard, merge_ssr_styles, missing_component, mount_component, noop, not_equal, now, null_to_empty, object_without_properties, onDestroy, onMount, once, outro_and_destroy_block, prevent_default, prop_dev, query_selector_all, raf, run, run_all, safe_not_equal, schedule_update, select_multiple_value, select_option, select_options, select_value, self, setContext, set_attributes, set_current_component, set_custom_element_data, set_data, set_data_dev, set_input_type, set_input_value, set_now, set_raf, set_store_value, set_style, set_svg_attributes, space, spread, src_url_equal, start_hydrating, stop_propagation, subscribe, svg_element, text, tick, time_ranges_to_array, to_number, toggle_class, transition_in, transition_out, trusted, update_await_block_branch, update_keyed_each, update_slot, update_slot_base, validate_component, validate_each_argument, validate_each_keys, validate_slots, validate_store, xlink_attr };\n","export const villesData = {\n \"Cadiz\": { \"x\": 144, \"y\": 1072, \"nom\": \"Cadiz\" },\n \"Madrid\": { \"x\": 147, \"y\": 946, \"nom\": \"Madrid\" },\n \"Barcelona\": { \"x\": 336, \"y\": 961, \"nom\": \"Barcelona\" },\n \"Lisboa\": { \"x\": 32, \"y\": 981, \"nom\": \"Lisboa\" },\n \"Pamplona\": { \"x\": 318, \"y\": 805, \"nom\": \"Pamplona\" },\n \"Paris\": { \"x\": 425, \"y\": 544, \"nom\": \"Paris\" },\n \"Dieppe\": { \"x\": 341, \"y\": 467, \"nom\": \"Dieppe\" },\n \"Brest\": { \"x\": 188, \"y\": 516, \"nom\": \"Brest\" },\n \"London\": { \"x\": 358, \"y\": 313, \"nom\": \"London\" },\n \"Amsterdam\": { \"x\": 524, \"y\": 319, \"nom\": \"Amsterdam\" },\n \"Bruxelles\": { \"x\": 485, \"y\": 399, \"nom\": \"Bruxelles\" },\n \"Edinburgh\": { \"x\": 245, \"y\": 56, \"nom\": \"Edinburgh\" },\n \"Zurich\": { \"x\": 622, \"y\": 638, \"nom\": \"Zurich\" },\n \"Marseille\": { \"x\": 575, \"y\": 797, \"nom\": \"Marseille\" },\n \"Frankfurt\": { \"x\": 638, \"y\": 454, \"nom\": \"Frankfurt\" },\n \"Munchen\": { \"x\": 737, \"y\": 530, \"nom\": \"Munchen\" },\n \"Wien\": { \"x\": 930, \"y\": 559, \"nom\": \"Wien\" },\n \"Venezia\": { \"x\": 763, \"y\": 694, \"nom\": \"Venezia\" },\n \"Roma\": { \"x\": 779, \"y\": 849, \"nom\": \"Roma\" },\n \"Brindisi\": { \"x\": 925, \"y\": 892, \"nom\": \"Brindisi\" },\n \"Palermo\": { \"x\": 841, \"y\": 1072, \"nom\": \"Palermo\" },\n \"Athina\": { \"x\": 1136, \"y\": 1024, \"nom\": \"Athina\" },\n \"Sofia\": { \"x\": 1167, \"y\": 830, \"nom\": \"Sofia\" },\n \"Sarajevo\": { \"x\": 1053, \"y\": 815, \"nom\": \"Sarajevo\" },\n \"Zagrab\": { \"x\": 908, \"y\": 714, \"nom\": \"Zagrab\" },\n \"Budapest\": { \"x\": 1014, \"y\": 602, \"nom\": \"Budapest\" },\n \"Kyiv\": { \"x\": 1370, \"y\": 438, \"nom\": \"Kyiv\" },\n \"Warszawa\": { \"x\": 1113, \"y\": 345, \"nom\": \"Warszawa\" },\n \"Wilno\": { \"x\": 1302, \"y\": 303, \"nom\": \"Wilno\" },\n \"Smolensk\": { \"x\": 1479, \"y\": 310, \"nom\": \"Smolensk\" },\n \"Moskva\": { \"x\": 1625, \"y\": 269, \"nom\": \"Moskva\" },\n \"Kharkov\": { \"x\": 1600, \"y\": 528, \"nom\": \"Kharkov\" },\n \"Rostov\": { \"x\": 1671, \"y\": 618, \"nom\": \"Rostov\" },\n \"Sochi\": { \"x\": 1660, \"y\": 770, \"nom\": \"Sochi\" },\n \"Erzurum\": { \"x\": 1628, \"y\": 986, \"nom\": \"Erzurum\" },\n \"Constantinople\": { \"x\": 1358, \"y\": 932, \"nom\": \"Constantinople\" },\n \"Angora\": { \"x\": 1492, \"y\": 1026, \"nom\": \"Angora\" },\n \"Smyrna\": { \"x\": 1282, \"y\": 1068, \"nom\": \"Smyrna\" },\n \"Essen\": { \"x\": 663, \"y\": 335, \"nom\": \"Essen\" },\n \"Berlin\": { \"x\": 834, \"y\": 359, \"nom\": \"Berlin\" },\n \"Kobenhavn\": { \"x\": 784, \"y\": 155, \"nom\": \"Kobenhavn\" },\n \"Stockholm\": { \"x\": 963, \"y\": 22, \"nom\": \"Stockholm\" },\n \"Riga\": { \"x\": 1169, \"y\": 71, \"nom\": \"Riga\" },\n \"Petrograd\": { \"x\": 1458, \"y\": 64, \"nom\": \"Petrograd\" },\n \"Danzig\": { \"x\": 1028, \"y\": 226, \"nom\": \"Danzig\" },\n \"Bucuresti\": { \"x\": 1271, \"y\": 721, \"nom\": \"Bucuresti\" },\n \"Sevastopol\": { \"x\": 1508, \"y\": 746, \"nom\": \"Sevastopol\" }\n};\n\nexport const routesData = [\n { \"ville1\": \"Amsterdam\", \"ville2\": \"Bruxelles\", \"longueur\": 1, \"couleur\": \"NOIR\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 504.5, \"y\": 361.5, \"dx\": -0.42661867571297646, \"dy\": 0.9044315925115101 }] },\n { \"ville1\": \"Amsterdam\", \"ville2\": \"Essen\", \"longueur\": 3, \"couleur\": \"JAUNE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 528.5, \"y\": 276, \"dx\": 0.21871145691738075, \"dy\": -0.9757895770160064 }, { \"x\": 574, \"y\": 265, \"dx\": 0.9778024140774094, \"dy\": 0.20952908873087345 }, { \"x\": 629, \"y\": 300, \"dx\": 0.6368814469962913, \"dy\": 0.7709617516270895 }] },\n { \"ville1\": \"Amsterdam\", \"ville2\": \"Frankfurt\", \"longueur\": 2, \"couleur\": \"BLANC\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 562, \"y\": 358.5, \"dx\": 0.6983238520753277, \"dy\": 0.7157819483772108 }, { \"x\": 606, \"y\": 403, \"dx\": 0.7249994335944138, \"dy\": 0.688749461914693 }] },\n { \"ville1\": \"Amsterdam\", \"ville2\": \"London\", \"longueur\": 2, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 2, \"segments\": [{ \"x\": 405, \"y\": 312, \"dx\": 1, \"dy\": 0 }, { \"x\": 469, \"y\": 314.5, \"dx\": 0.9998514005489976, \"dy\": 0.017238817250844786 }] },\n { \"ville1\": \"Angora\", \"ville2\": \"Constantinople\", \"longueur\": 2, \"couleur\": \"GRIS\", \"isTunnel\": true, \"ferry\": 0, \"segments\": [{ \"x\": 1399, \"y\": 959, \"dx\": 0.8209052017854871, \"dy\": 0.5710644881985998 }, { \"x\": 1452, \"y\": 998, \"dx\": 0.8041761414663255, \"dy\": 0.5943910610838058 }] },\n { \"ville1\": \"Angora\", \"ville2\": \"Erzurum\", \"longueur\": 3, \"couleur\": \"NOIR\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1533.5, \"y\": 1046, \"dx\": 0.8765785507795943, \"dy\": 0.48125881219271843 }, { \"x\": 1597, \"y\": 1059.5, \"dx\": 0.9812488205210874, \"dy\": -0.19274530403092788 }, { \"x\": 1635.5, \"y\": 1031.5, \"dx\": -0.16148856811054085, \"dy\": -0.9868745828977495 }] },\n { \"ville1\": \"Angora\", \"ville2\": \"Smyrna\", \"longueur\": 3, \"couleur\": \"ORANGE\", \"isTunnel\": true, \"ferry\": 0, \"segments\": [{ \"x\": 1329.5, \"y\": 1072.5, \"dx\": 0.9998347517133227, \"dy\": 0.01817881366751496 }, { \"x\": 1392.5, \"y\": 1072, \"dx\": 0.9895864392845114, \"dy\": -0.14393984571411075 }, { \"x\": 1455.5, \"y\": 1054, \"dx\": 0.8765785507795943, \"dy\": -0.48125881219271843 }] },\n { \"ville1\": \"Athina\", \"ville2\": \"Brindisi\", \"longueur\": 4, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 1, \"segments\": [{ \"x\": 957, \"y\": 928, \"dx\": 0.389639990836698, \"dy\": 0.9209672510685588 }, { \"x\": 982, \"y\": 986.5, \"dx\": 0.38337767164151665, \"dy\": 0.9235916635000174 }, { \"x\": 1027.5, \"y\": 1030.5, \"dx\": 0.9554026409829016, \"dy\": 0.2953062708492605 }, { \"x\": 1093.5, \"y\": 1036, \"dx\": 0.9838699100999074, \"dy\": -0.17888543819998318 }] },\n { \"ville1\": \"Athina\", \"ville2\": \"Sarajevo\", \"longueur\": 4, \"couleur\": \"VERT\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1052.5, \"y\": 859, \"dx\": -0.053494721371611896, \"dy\": 0.9985681322700888 }, { \"x\": 1049, \"y\": 922.5, \"dx\": -0.035066140133044446, \"dy\": 0.9993849937917667 }, { \"x\": 1045.5, \"y\": 986.5, \"dx\": -0.08444307668618062, \"dy\": 0.9964283048969312 }, { \"x\": 1087.5, \"y\": 1007, \"dx\": 0.9994259471398348, \"dy\": 0.033878845665757114 }] },\n { \"ville1\": \"Athina\", \"ville2\": \"Smyrna\", \"longueur\": 2, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 1, \"segments\": [{ \"x\": 1180.5, \"y\": 1022, \"dx\": 0.9994259471398348, \"dy\": -0.033878845665757114 }, { \"x\": 1244.5, \"y\": 1036.5, \"dx\": 0.9044315925115101, \"dy\": 0.42661867571297646 }] },\n { \"ville1\": \"Athina\", \"ville2\": \"Sofia\", \"longueur\": 3, \"couleur\": \"ROSE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1136, \"y\": 861, \"dx\": -0.6709133239691262, \"dy\": 0.7415357791237711 }, { \"x\": 1109.5, \"y\": 921, \"dx\": -0.11982016019085814, \"dy\": 0.9927956130099675 }, { \"x\": 1123, \"y\": 983, \"dx\": 0.52999894000318, \"dy\": 0.847998304005088 }] },\n { \"ville1\": \"Barcelona\", \"ville2\": \"Madrid\", \"longueur\": 2, \"couleur\": \"JAUNE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 221.5, \"y\": 954.5, \"dx\": 0.9998563940539735, \"dy\": 0.016946718543287685 }, { \"x\": 285.5, \"y\": 956.5, \"dx\": 0.9986178293325098, \"dy\": 0.052558833122763673 }] },\n { \"ville1\": \"Barcelona\", \"ville2\": \"Marseille\", \"longueur\": 4, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 370.5, \"y\": 926, \"dx\": 0.6610305430689966, \"dy\": -0.7503589948350772 }, { \"x\": 415.5, \"y\": 881.5, \"dx\": 0.7407190347407712, \"dy\": -0.6718149384858157 }, { \"x\": 467.5, \"y\": 843.5, \"dx\": 0.8692901189279536, \"dy\": -0.4943022244884442 }, { \"x\": 525, \"y\": 818, \"dx\": 0.9377487607237036, \"dy\": -0.34731435582359393 }] },\n { \"ville1\": \"Barcelona\", \"ville2\": \"Pamplona\", \"longueur\": 2, \"couleur\": \"GRIS\", \"isTunnel\": true, \"ferry\": 0, \"segments\": [{ \"x\": 322.5, \"y\": 852.5, \"dx\": 0.09053574604251853, \"dy\": 0.9958932064677039 }, { \"x\": 329.5, \"y\": 917.5, \"dx\": 0.11781773987828967, \"dy\": 0.9930352361170129 }] },\n { \"ville1\": \"Berlin\", \"ville2\": \"Danzig\", \"longueur\": 4, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 842.5, \"y\": 306.5, \"dx\": 0.1559625734730109, \"dy\": -0.987762965329069 }, { \"x\": 867.5, \"y\": 246.5, \"dx\": 0.5746304214759497, \"dy\": -0.8184130245263527 }, { \"x\": 922.5, \"y\": 210, \"dx\": 0.978549784986749, \"dy\": -0.2060104810498419 }, { \"x\": 987, \"y\": 210, \"dx\": 0.9778024140774094, \"dy\": 0.20952908873087345 }] },\n { \"ville1\": \"Berlin\", \"ville2\": \"Essen\", \"longueur\": 2, \"couleur\": \"BLEU\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 726.5, \"y\": 331.5, \"dx\": 0.9925434552766405, \"dy\": 0.12189130152520146 }, { \"x\": 789.5, \"y\": 339, \"dx\": 0.9945054529214061, \"dy\": 0.10468478451804275 }] },\n { \"ville1\": \"Berlin\", \"ville2\": \"Frankfurt\", \"longueur\": 3, \"couleur\": \"ROUGE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 686.5, \"y\": 452.5, \"dx\": 0.9173450110960782, \"dy\": -0.3980931180228264 }, { \"x\": 743, \"y\": 424.5, \"dx\": 0.9012524245251862, \"dy\": -0.43329443486787794 }, { \"x\": 800, \"y\": 397.5, \"dx\": 0.9012524245251862, \"dy\": -0.43329443486787794 }] },\n { \"ville1\": \"Berlin\", \"ville2\": \"Frankfurt\", \"longueur\": 3, \"couleur\": \"NOIR\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 676, \"y\": 432.5, \"dx\": 0.9012524245251862, \"dy\": -0.43329443486787794 }, { \"x\": 734, \"y\": 405.5, \"dx\": 0.9084904526785746, \"dy\": -0.41790560823214434 }, { \"x\": 790.5, \"y\": 378, \"dx\": 0.8909061469019802, \"dy\": -0.4541874474402252 }] },\n { \"ville1\": \"Berlin\", \"ville2\": \"Warszawa\", \"longueur\": 4, \"couleur\": \"JAUNE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 877, \"y\": 365.5, \"dx\": 0.9469787003150827, \"dy\": -0.3212963447497602 }, { \"x\": 940, \"y\": 350.5, \"dx\": 0.988173903359179, \"dy\": -0.15333732983159673 }, { \"x\": 1003, \"y\": 347, \"dx\": 0.9993628543475496, \"dy\": -0.03569153051241249 }, { \"x\": 1065.5, \"y\": 350.5, \"dx\": 0.987762965329069, \"dy\": 0.1559625734730109 }] },\n { \"ville1\": \"Berlin\", \"ville2\": \"Warszawa\", \"longueur\": 4, \"couleur\": \"ROSE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 875.5, \"y\": 341.5, \"dx\": 0.9486832980505138, \"dy\": -0.31622776601683794 }, { \"x\": 939.5, \"y\": 326.5, \"dx\": 0.9925434552766405, \"dy\": -0.12189130152520146 }, { \"x\": 1002, \"y\": 322, \"dx\": 0.9994059993535875, \"dy\": -0.03446227583977888 }, { \"x\": 1067, \"y\": 327, \"dx\": 0.9906211292434748, \"dy\": 0.13663739713703102 }] },\n { \"ville1\": \"Berlin\", \"ville2\": \"Wien\", \"longueur\": 3, \"couleur\": \"VERT\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 847, \"y\": 408.5, \"dx\": 0.2890045919356118, \"dy\": 0.9573277107867141 }, { \"x\": 870.5, \"y\": 467, \"dx\": 0.47514891473488396, \"dy\": 0.8799053976571926 }, { \"x\": 906, \"y\": 520.5, \"dx\": 0.6246950475544243, \"dy\": 0.7808688094430304 }] },\n { \"ville1\": \"Brest\", \"ville2\": \"Dieppe\", \"longueur\": 2, \"couleur\": \"ORANGE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 225, \"y\": 482.5, \"dx\": 0.8650311892618034, \"dy\": -0.501718089771846 }, { \"x\": 287.5, \"y\": 464, \"dx\": 0.9977097021176764, \"dy\": -0.06764133573679162 }] },\n { \"ville1\": \"Brest\", \"ville2\": \"Pamplona\", \"longueur\": 4, \"couleur\": \"ROSE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 229.5, \"y\": 549.5, \"dx\": 0.9342183861793726, \"dy\": 0.3567015656321241 }, { \"x\": 280, \"y\": 591, \"dx\": 0.5547001962252291, \"dy\": 0.8320502943378437 }, { \"x\": 302, \"y\": 652, \"dx\": 0.1414213562373095, \"dy\": 0.9899494936611665 }, { \"x\": 306, \"y\": 716, \"dx\": 0, \"dy\": 1 }] },\n { \"ville1\": \"Brest\", \"ville2\": \"Paris\", \"longueur\": 3, \"couleur\": \"NOIR\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 235, \"y\": 521, \"dx\": 0.9946917938265513, \"dy\": 0.1028991510855053 }, { \"x\": 298.5, \"y\": 529, \"dx\": 0.9945054529214061, \"dy\": 0.10468478451804275 }, { \"x\": 360.5, \"y\": 536.5, \"dx\": 0.9964283048969312, \"dy\": 0.08444307668618062 }] },\n { \"ville1\": \"Brindisi\", \"ville2\": \"Palermo\", \"longueur\": 3, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 1, \"segments\": [{ \"x\": 880.5, \"y\": 1047.5, \"dx\": 0.6139406135149205, \"dy\": -0.7893522173763263 }, { \"x\": 923, \"y\": 998.5, \"dx\": 0.7327934916262993, \"dy\": -0.6804510993672779 }, { \"x\": 936.5, \"y\": 937, \"dx\": -0.40450601477770304, \"dy\": -0.9145353377582851 }] },\n { \"ville1\": \"Brindisi\", \"ville2\": \"Roma\", \"longueur\": 2, \"couleur\": \"BLANC\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 832.5, \"y\": 833, \"dx\": 0.9902939771518443, \"dy\": -0.13898862837218867 }, { \"x\": 892.5, \"y\": 856, \"dx\": 0.6610305430689966, \"dy\": 0.7503589948350772 }] },\n { \"ville1\": \"Bruxelles\", \"ville2\": \"Dieppe\", \"longueur\": 2, \"couleur\": \"VERT\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 387, \"y\": 447.5, \"dx\": 0.8346094065617252, \"dy\": -0.5508422083307386 }, { \"x\": 440, \"y\": 411, \"dx\": 0.8041761414663255, \"dy\": -0.5943910610838058 }] },\n { \"ville1\": \"Bruxelles\", \"ville2\": \"Frankfurt\", \"longueur\": 2, \"couleur\": \"BLEU\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 528.5, \"y\": 403, \"dx\": 0.9690971739229421, \"dy\": -0.24667928063493072 }, { \"x\": 590.5, \"y\": 420, \"dx\": 0.7321867381630838, \"dy\": 0.6811039424772872 }] },\n { \"ville1\": \"Bruxelles\", \"ville2\": \"Paris\", \"longueur\": 2, \"couleur\": \"JAUNE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 432.5, \"y\": 495, \"dx\": 0.47312663795681303, \"dy\": -0.8809944292988933 }, { \"x\": 462.5, \"y\": 439, \"dx\": 0.43329443486787794, \"dy\": -0.9012524245251862 }] },\n { \"ville1\": \"Bruxelles\", \"ville2\": \"Paris\", \"longueur\": 2, \"couleur\": \"ROUGE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 452.5, \"y\": 505.5, \"dx\": 0.4678877204190327, \"dy\": -0.8837879163470618 }, { \"x\": 482.5, \"y\": 449.5, \"dx\": 0.4678877204190327, \"dy\": -0.8837879163470618 }] },\n { \"ville1\": \"Bucuresti\", \"ville2\": \"Budapest\", \"longueur\": 4, \"couleur\": \"GRIS\", \"isTunnel\": true, \"ferry\": 0, \"segments\": [{ \"x\": 1058, \"y\": 613.5, \"dx\": 0.8944271909999159, \"dy\": 0.4472135954999579 }, { \"x\": 1114.5, \"y\": 644, \"dx\": 0.8833490206949295, \"dy\": 0.46871580689935033 }, { \"x\": 1170, \"y\": 674, \"dx\": 0.8872168012345951, \"dy\": 0.46135273664198945 }, { \"x\": 1227, \"y\": 703.5, \"dx\": 0.8944271909999159, \"dy\": 0.4472135954999579 }] },\n { \"ville1\": \"Bucuresti\", \"ville2\": \"Constantinople\", \"longueur\": 3, \"couleur\": \"JAUNE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1289.5, \"y\": 766, \"dx\": 0.40450601477770304, \"dy\": 0.9145353377582851 }, { \"x\": 1314.5, \"y\": 824, \"dx\": 0.39186206512519167, \"dy\": 0.9200239789895804 }, { \"x\": 1339, \"y\": 882, \"dx\": 0.4061384660534476, \"dy\": 0.9138115486202572 }] },\n { \"ville1\": \"Bucuresti\", \"ville2\": \"Kyiv\", \"longueur\": 4, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1337, \"y\": 492, \"dx\": -0.284088329691374, \"dy\": 0.9587981127083872 }, { \"x\": 1317.5, \"y\": 552, \"dx\": -0.343192952923539, \"dy\": 0.9392649237907383 }, { \"x\": 1298, \"y\": 612.5, \"dx\": -0.3215824263578902, \"dy\": 0.9468815887204546 }, { \"x\": 1278, \"y\": 672, \"dx\": -0.3271105638831663, \"dy\": 0.9449860734402582 }] },\n { \"ville1\": \"Bucuresti\", \"ville2\": \"Sevastopol\", \"longueur\": 4, \"couleur\": \"BLANC\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1307.5, \"y\": 690.5, \"dx\": 0.7071067811865476, \"dy\": -0.7071067811865476 }, { \"x\": 1365, \"y\": 657.5, \"dx\": 0.965948051503245, \"dy\": -0.2587360852240835 }, { \"x\": 1430.5, \"y\": 665, \"dx\": 0.9040722665053037, \"dy\": 0.4273796168934163 }, { \"x\": 1480.5, \"y\": 705, \"dx\": 0.6055218324832624, \"dy\": 0.7958286941208591 }] },\n { \"ville1\": \"Bucuresti\", \"ville2\": \"Sofia\", \"longueur\": 2, \"couleur\": \"GRIS\", \"isTunnel\": true, \"ferry\": 0, \"segments\": [{ \"x\": 1209.5, \"y\": 809.5, \"dx\": 0.9582877607731983, \"dy\": -0.28580512163411176 }, { \"x\": 1250, \"y\": 762.5, \"dx\": 0.13436367297357807, \"dy\": -0.9909320881801382 }] },\n { \"ville1\": \"Budapest\", \"ville2\": \"Kyiv\", \"longueur\": 6, \"couleur\": \"GRIS\", \"isTunnel\": true, \"ferry\": 0, \"segments\": [{ \"x\": 1037.5, \"y\": 561, \"dx\": 0.6633075143158518, \"dy\": -0.7483469392281404 }, { \"x\": 1084, \"y\": 518, \"dx\": 0.8209052017854871, \"dy\": -0.5710644881985998 }, { \"x\": 1139, \"y\": 483.5, \"dx\": 0.8799053976571926, \"dy\": -0.47514891473488396 }, { \"x\": 1197.5, \"y\": 459, \"dx\": 0.9468815887204546, \"dy\": -0.3215824263578902 }, { \"x\": 1260, \"y\": 446, \"dx\": 0.9974586998307351, \"dy\": -0.07124704998790965 }, { \"x\": 1324, \"y\": 446.5, \"dx\": 0.9998405993454448, \"dy\": 0.017854296416882943 }] },\n { \"ville1\": \"Budapest\", \"ville2\": \"Sarajevo\", \"longueur\": 3, \"couleur\": \"ROSE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1026, \"y\": 646.5, \"dx\": 0.14393984571411075, \"dy\": 0.9895864392845114 }, { \"x\": 1035, \"y\": 709, \"dx\": 0.1757906384836575, \"dy\": 0.984427575508482 }, { \"x\": 1044.5, \"y\": 772, \"dx\": 0.12403473458920845, \"dy\": 0.9922778767136676 }] },\n { \"ville1\": \"Budapest\", \"ville2\": \"Wien\", \"longueur\": 1, \"couleur\": \"ROUGE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 973.5, \"y\": 578, \"dx\": 0.8528513040762654, \"dy\": 0.5221538596385299 }] },\n { \"ville1\": \"Budapest\", \"ville2\": \"Wien\", \"longueur\": 1, \"couleur\": \"BLANC\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 962, \"y\": 596, \"dx\": 0.8574929257125442, \"dy\": 0.5144957554275266 }] },\n { \"ville1\": \"Budapest\", \"ville2\": \"Zagrab\", \"longueur\": 2, \"couleur\": \"ORANGE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 987.5, \"y\": 639, \"dx\": -0.501718089771846, \"dy\": 0.8650311892618034 }, { \"x\": 946.5, \"y\": 689.5, \"dx\": -0.7724254859909581, \"dy\": 0.6351053995925655 }] },\n { \"ville1\": \"Cadiz\", \"ville2\": \"Lisboa\", \"longueur\": 2, \"couleur\": \"BLEU\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 50, \"y\": 1025.5, \"dx\": 0.4125075533080444, \"dy\": 0.9109541802219313 }, { \"x\": 100, \"y\": 1063.5, \"dx\": 0.9812488205210874, \"dy\": 0.19274530403092788 }] },\n { \"ville1\": \"Cadiz\", \"ville2\": \"Madrid\", \"longueur\": 3, \"couleur\": \"ORANGE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 189, \"y\": 1062, \"dx\": 0.9377487607237036, \"dy\": -0.34731435582359393 }, { \"x\": 222.5, \"y\": 1027.5, \"dx\": -0.3265202527980472, \"dy\": -0.9451902054680315 }, { \"x\": 184.5, \"y\": 976, \"dx\": -0.7493290854811462, \"dy\": -0.6621977964717106 }] },\n { \"ville1\": \"Constantinople\", \"ville2\": \"Sevastopol\", \"longueur\": 4, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 2, \"segments\": [{ \"x\": 1490.5, \"y\": 791.5, \"dx\": -0.017541160386140585, \"dy\": 0.9998461420100133 }, { \"x\": 1471, \"y\": 852.5, \"dx\": -0.5795237863600037, \"dy\": 0.8149553245687551 }, { \"x\": 1428.5, \"y\": 874, \"dx\": -0.7938781460016401, \"dy\": -0.6080768777884903 }, { \"x\": 1386.5, \"y\": 896.5, \"dx\": -0.6139406135149205, \"dy\": 0.7893522173763263 }] },\n { \"ville1\": \"Constantinople\", \"ville2\": \"Smyrna\", \"longueur\": 2, \"couleur\": \"GRIS\", \"isTunnel\": true, \"ferry\": 0, \"segments\": [{ \"x\": 1301.5, \"y\": 1026.5, \"dx\": 0.42661867571297646, \"dy\": -0.9044315925115101 }, { \"x\": 1330.5, \"y\": 968.5, \"dx\": 0.41110775310681835, \"dy\": -0.911586756889032 }] },\n { \"ville1\": \"Constantinople\", \"ville2\": \"Sofia\", \"longueur\": 3, \"couleur\": \"BLEU\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1206, \"y\": 853, \"dx\": 0.8725060159497201, \"dy\": 0.48860336893184325 }, { \"x\": 1262, \"y\": 883, \"dx\": 0.879291966536774, \"dy\": 0.4762831485407526 }, { \"x\": 1317, \"y\": 913.5, \"dx\": 0.8650311892618034, \"dy\": 0.501718089771846 }] },\n { \"ville1\": \"Danzig\", \"ville2\": \"Riga\", \"longueur\": 3, \"couleur\": \"NOIR\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1041.5, \"y\": 182.5, \"dx\": 0.27232246579934893, \"dy\": -0.9622060458243663 }, { \"x\": 1071, \"y\": 125.5, \"dx\": 0.6028330891856919, \"dy\": -0.7978673239222394 }, { \"x\": 1123.5, \"y\": 89, \"dx\": 0.9503971290446889, \"dy\": -0.3110390604146254 }] },\n { \"ville1\": \"Danzig\", \"ville2\": \"Warszawa\", \"longueur\": 2, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1068, \"y\": 247, \"dx\": 0.847998304005088, \"dy\": 0.52999894000318 }, { \"x\": 1103.5, \"y\": 299, \"dx\": 0.22612970719934952, \"dy\": 0.9740972002433518 }] },\n {\n \"ville1\": \"Dieppe\", \"ville2\": \"London\", \"longueur\": 2, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 1, \"segments\": [\n { \"x\": 330.5, \"y\": 419.5, \"dx\": -0.08738374771484403, \"dy\": 0.9961747239492219 },\n { \"x\": 336.5, \"y\": 358, \"dx\": -0.08588834215301201, \"dy\": 0.9963047689749394 }, \n ]\n },\n { \"ville1\": \"Dieppe\", \"ville2\": \"London\", \"longueur\": 2, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 1, \"segments\": [{ \"x\": 354.5, \"y\": 422.5, \"dx\": 0.08444307668618062, \"dy\": -0.9964283048969312 }, { \"x\": 360, \"y\": 359.5, \"dx\": 0.10468478451804275, \"dy\": -0.9945054529214061 }] },\n { \"ville1\": \"Dieppe\", \"ville2\": \"Paris\", \"longueur\": 1, \"couleur\": \"ROSE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 379.5, \"y\": 500.5, \"dx\": 0.7071067811865475, \"dy\": 0.7071067811865475 }] },\n { \"ville1\": \"Edinburgh\", \"ville2\": \"London\", \"longueur\": 4, \"couleur\": \"ORANGE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 276.5, \"y\": 96, \"dx\": 0.42012356811103757, \"dy\": 0.9074669071198412 }, { \"x\": 301, \"y\": 154.5, \"dx\": 0.38337767164151665, \"dy\": 0.9235916635000174 }, { \"x\": 325, \"y\": 212, \"dx\": 0.389639990836698, \"dy\": 0.9209672510685588 }, { \"x\": 349.5, \"y\": 269.5, \"dx\": 0.3980931180228264, \"dy\": 0.9173450110960782 }] },\n { \"ville1\": \"Edinburgh\", \"ville2\": \"London\", \"longueur\": 4, \"couleur\": \"NOIR\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 255.5, \"y\": 105.5, \"dx\": 0.41110775310681835, \"dy\": 0.911586756889032 }, { \"x\": 280.5, \"y\": 163.5, \"dx\": 0.3980931180228264, \"dy\": 0.9173450110960782 }, { \"x\": 305, \"y\": 220, \"dx\": 0.40273861426601687, \"dy\": 0.9153150324227656 }, { \"x\": 329, \"y\": 277.5, \"dx\": 0.3960911114346502, \"dy\": 0.9182112128712345 }] },\n { \"ville1\": \"Erzurum\", \"ville2\": \"Sevastopol\", \"longueur\": 4, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 2, \"segments\": [{ \"x\": 1514, \"y\": 792, \"dx\": 0, \"dy\": 1 }, { \"x\": 1518.5, \"y\": 854, \"dx\": 0.15867809538375516, \"dy\": 0.9873303712766988 }, { \"x\": 1542, \"y\": 914, \"dx\": 0.5710644881985998, \"dy\": 0.8209052017854871 }, { \"x\": 1588.5, \"y\": 960, \"dx\": 0.8372705045624257, \"dy\": 0.546788900938727 }] },\n { \"ville1\": \"Erzurum\", \"ville2\": \"Sochi\", \"longueur\": 3, \"couleur\": \"ROUGE\", \"isTunnel\": true, \"ferry\": 0, \"segments\": [{ \"x\": 1653.5, \"y\": 817, \"dx\": -0.12403473458920845, \"dy\": 0.9922778767136676 }, { \"x\": 1644.5, \"y\": 880, \"dx\": -0.15867809538375516, \"dy\": 0.9873303712766988 }, { \"x\": 1635.5, \"y\": 942.5, \"dx\": -0.12625427967391514, \"dy\": 0.9919979117236188 }] },\n { \"ville1\": \"Essen\", \"ville2\": \"Frankfurt\", \"longueur\": 2, \"couleur\": \"VERT\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 666, \"y\": 412, \"dx\": 0.8944271909999159, \"dy\": -0.4472135954999579 }, { \"x\": 698, \"y\": 374.5, \"dx\": -0.4541874474402252, \"dy\": -0.8909061469019802 }] },\n { \"ville1\": \"Essen\", \"ville2\": \"Kobenhavn\", \"longueur\": 3, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 1, \"segments\": [{ \"x\": 677, \"y\": 288, \"dx\": 0.5390536964233673, \"dy\": -0.8422714006615114 }, { \"x\": 713, \"y\": 235, \"dx\": 0.5547001962252291, \"dy\": -0.8320502943378437 }, { \"x\": 748, \"y\": 182, \"dx\": 0.5547001962252291, \"dy\": -0.8320502943378437 }] },\n { \"ville1\": \"Essen\", \"ville2\": \"Kobenhavn\", \"longueur\": 3, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 1, \"segments\": [{ \"x\": 695.5, \"y\": 300, \"dx\": 0.5665288228870652, \"dy\": -0.8240419241993676 }, { \"x\": 731, \"y\": 246, \"dx\": 0.5462677805469223, \"dy\": -0.8376105968386142 }, { \"x\": 765.5, \"y\": 196, \"dx\": 0.5665288228870652, \"dy\": -0.8240419241993676 }] },\n { \"ville1\": \"Frankfurt\", \"ville2\": \"Munchen\", \"longueur\": 2, \"couleur\": \"ROSE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 654, \"y\": 500, \"dx\": 0.31622776601683794, \"dy\": 0.9486832980505138 }, { \"x\": 684.5, \"y\": 534.5, \"dx\": 0.9582877607731983, \"dy\": -0.28580512163411176 }] },\n { \"ville1\": \"Frankfurt\", \"ville2\": \"Paris\", \"longueur\": 3, \"couleur\": \"ORANGE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 494, \"y\": 553.5, \"dx\": 0.9568805766427723, \"dy\": -0.29048160362369874 }, { \"x\": 552, \"y\": 527, \"dx\": 0.8422714006615114, \"dy\": -0.5390536964233673 }, { \"x\": 605.5, \"y\": 491.5, \"dx\": 0.8137334712067349, \"dy\": -0.5812381937190964 }] },\n { \"ville1\": \"Frankfurt\", \"ville2\": \"Paris\", \"longueur\": 3, \"couleur\": \"BLANC\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 482.5, \"y\": 533, \"dx\": 0.939793423488437, \"dy\": -0.3417430630867044 }, { \"x\": 541, \"y\": 506.5, \"dx\": 0.8400393777687709, \"dy\": -0.5425254314756646 }, { \"x\": 594, \"y\": 471.5, \"dx\": 0.8240419241993676, \"dy\": -0.5665288228870652 }] },\n { \"ville1\": \"Kharkov\", \"ville2\": \"Kyiv\", \"longueur\": 4, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1386, \"y\": 482, \"dx\": 0.34731435582359393, \"dy\": 0.9377487607237036 }, { \"x\": 1428, \"y\": 531, \"dx\": 0.8804710999221753, \"dy\": 0.47409982303501746 }, { \"x\": 1490.5, \"y\": 547.5, \"dx\": 0.9986178293325098, \"dy\": 0.052558833122763673 }, { \"x\": 1554, \"y\": 540, \"dx\": 0.9486832980505138, \"dy\": -0.31622776601683794 }] },\n { \"ville1\": \"Kharkov\", \"ville2\": \"Moskva\", \"longueur\": 4, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1628.5, \"y\": 491, \"dx\": 0.6985367247883851, \"dy\": -0.7155742058807848 }, { \"x\": 1661.5, \"y\": 437, \"dx\": 0.2676438637860946, \"dy\": -0.9635179096299405 }, { \"x\": 1666, \"y\": 372, \"dx\": -0.1414213562373095, \"dy\": -0.9899494936611665 }, { \"x\": 1647, \"y\": 309.5, \"dx\": -0.4541874474402252, \"dy\": -0.8909061469019802 }] },\n { \"ville1\": \"Kharkov\", \"ville2\": \"Rostov\", \"longueur\": 2, \"couleur\": \"VERT\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1651, \"y\": 528, \"dx\": 1, \"dy\": 0 }, { \"x\": 1670.5, \"y\": 573.5, \"dx\": 0.017541160386140585, \"dy\": 0.9998461420100133 }] },\n { \"ville1\": \"Kobenhavn\", \"ville2\": \"Stockholm\", \"longueur\": 3, \"couleur\": \"JAUNE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 808.5, \"y\": 114, \"dx\": 0.6804510993672779, \"dy\": -0.7327934916262993 }, { \"x\": 855, \"y\": 70.5, \"dx\": 0.7483469392281404, \"dy\": -0.6633075143158518 }, { \"x\": 908, \"y\": 34, \"dx\": 0.8804710999221753, \"dy\": -0.47409982303501746 }] },\n { \"ville1\": \"Kobenhavn\", \"ville2\": \"Stockholm\", \"longueur\": 3, \"couleur\": \"BLANC\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 825, \"y\": 132, \"dx\": 0.6896551724137931, \"dy\": -0.7241379310344828 }, { \"x\": 870, \"y\": 87.5, \"dx\": 0.7503589948350772, \"dy\": -0.6610305430689966 }, { \"x\": 923.5, \"y\": 50.5, \"dx\": 0.8837879163470618, \"dy\": -0.4678877204190327 }] },\n { \"ville1\": \"Kyiv\", \"ville2\": \"Smolensk\", \"longueur\": 3, \"couleur\": \"ROUGE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1418.5, \"y\": 440.5, \"dx\": 0.9986178293325098, \"dy\": 0.052558833122763673 }, { \"x\": 1477.5, \"y\": 417, \"dx\": 0.7157819483772108, \"dy\": -0.6983238520753277 }, { \"x\": 1492, \"y\": 355.5, \"dx\": -0.2890045919356118, \"dy\": -0.9573277107867141 }] },\n { \"ville1\": \"Kyiv\", \"ville2\": \"Warszawa\", \"longueur\": 4, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1143.5, \"y\": 376.5, \"dx\": 0.689213765997513, \"dy\": 0.7245580616896932 }, { \"x\": 1196, \"y\": 413, \"dx\": 0.9377487607237036, \"dy\": 0.34731435582359393 }, { \"x\": 1258.5, \"y\": 422.5, \"dx\": 0.9986178293325098, \"dy\": -0.052558833122763673 }, { \"x\": 1322.5, \"y\": 423.5, \"dx\": 0.9986178293325098, \"dy\": 0.052558833122763673 }] },\n { \"ville1\": \"Kyiv\", \"ville2\": \"Wilno\", \"longueur\": 2, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1344, \"y\": 330.5, \"dx\": 0.8400393777687709, \"dy\": 0.5425254314756646 }, { \"x\": 1372, \"y\": 389.5, \"dx\": 0, \"dy\": 1 }] },\n { \"ville1\": \"Lisboa\", \"ville2\": \"Madrid\", \"longueur\": 3, \"couleur\": \"ROSE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 30, \"y\": 940, \"dx\": 0, \"dy\": -1 }, { \"x\": 49.5, \"y\": 896, \"dx\": 0.9994259471398348, \"dy\": 0.033878845665757114 }, { \"x\": 111, \"y\": 917.5, \"dx\": 0.8080075302163774, \"dy\": 0.5891721574494418 }] },\n { \"ville1\": \"Madrid\", \"ville2\": \"Pamplona\", \"longueur\": 3, \"couleur\": \"BLANC\", \"isTunnel\": true, \"ferry\": 0, \"segments\": [{ \"x\": 186, \"y\": 920.5, \"dx\": 0.6419366564593427, \"dy\": -0.7667576729931038 }, { \"x\": 229, \"y\": 874, \"dx\": 0.7071067811865475, \"dy\": -0.7071067811865475 }, { \"x\": 278.5, \"y\": 833, \"dx\": 0.8372705045624257, \"dy\": -0.546788900938727 }] },\n { \"ville1\": \"Madrid\", \"ville2\": \"Pamplona\", \"longueur\": 3, \"couleur\": \"NOIR\", \"isTunnel\": true, \"ferry\": 0, \"segments\": [{ \"x\": 171, \"y\": 905, \"dx\": 0.6536198703460924, \"dy\": -0.7568230077691596 }, { \"x\": 212.5, \"y\": 857, \"dx\": 0.6804510993672779, \"dy\": -0.7327934916262993 }, { \"x\": 261, \"y\": 817, \"dx\": 0.8422714006615114, \"dy\": -0.5390536964233673 }] },\n { \"ville1\": \"Marseille\", \"ville2\": \"Pamplona\", \"longueur\": 4, \"couleur\": \"ROUGE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 367.5, \"y\": 823, \"dx\": 0.9503971290446889, \"dy\": 0.3110390604146254 }, { \"x\": 401, \"y\": 790.5, \"dx\": 0.35305725243424235, \"dy\": -0.9356017189507422 }, { \"x\": 452.5, \"y\": 753.5, \"dx\": 0.9998461420100133, \"dy\": -0.017541160386140585 }, { \"x\": 516.5, \"y\": 770.5, \"dx\": 0.8979207227269799, \"dy\": 0.44015721702302935 }] },\n { \"ville1\": \"Marseille\", \"ville2\": \"Paris\", \"longueur\": 4, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 553, \"y\": 756, \"dx\": -0.5547001962252291, \"dy\": -0.8320502943378437 }, { \"x\": 505.5, \"y\": 713.5, \"dx\": -0.8837879163470618, \"dy\": -0.4678877204190327 }, { \"x\": 457, \"y\": 670.5, \"dx\": -0.5700815482062942, \"dy\": -0.821588113591424 }, { \"x\": 436.5, \"y\": 608.5, \"dx\": -0.054464493159869794, \"dy\": -0.9985157079309461 }] },\n { \"ville1\": \"Marseille\", \"ville2\": \"Roma\", \"longueur\": 4, \"couleur\": \"GRIS\", \"isTunnel\": true, \"ferry\": 0, \"segments\": [{ \"x\": 620, \"y\": 778, \"dx\": 0.8041761414663255, \"dy\": -0.5943910610838058 }, { \"x\": 671, \"y\": 741.5, \"dx\": 0.8, \"dy\": -0.6 }, { \"x\": 712, \"y\": 762.5, \"dx\": 0.6028330891856919, \"dy\": 0.7978673239222394 }, { \"x\": 750, \"y\": 813.5, \"dx\": 0.6028330891856919, \"dy\": 0.7978673239222394 }] },\n { \"ville1\": \"Marseille\", \"ville2\": \"Zurich\", \"longueur\": 2, \"couleur\": \"ROSE\", \"isTunnel\": true, \"ferry\": 0, \"segments\": [{ \"x\": 615, \"y\": 683.5, \"dx\": -0.2553911228370322, \"dy\": 0.9668378221687647 }, { \"x\": 599, \"y\": 746.5, \"dx\": -0.2890045919356118, \"dy\": 0.9573277107867141 }] },\n { \"ville1\": \"Moskva\", \"ville2\": \"Petrograd\", \"longueur\": 4, \"couleur\": \"BLANC\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1504, \"y\": 79.5, \"dx\": 0.9538492507391959, \"dy\": 0.30028587523270983 }, { \"x\": 1561, \"y\": 110, \"dx\": 0.8041761414663255, \"dy\": 0.5943910610838058 }, { \"x\": 1600, \"y\": 161, \"dx\": 0.4472135954999579, \"dy\": 0.8944271909999159 }, { \"x\": 1617, \"y\": 222, \"dx\": 0.07124704998790965, \"dy\": 0.9974586998307351 }] },\n { \"ville1\": \"Moskva\", \"ville2\": \"Smolensk\", \"longueur\": 2, \"couleur\": \"ORANGE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1526, \"y\": 314, \"dx\": 0.994309153919809, \"dy\": 0.10653312363426524 }, { \"x\": 1587, \"y\": 295.5, \"dx\": 0.8080075302163774, \"dy\": -0.5891721574494418 }] },\n { \"ville1\": \"Munchen\", \"ville2\": \"Venezia\", \"longueur\": 2, \"couleur\": \"BLEU\", \"isTunnel\": true, \"ferry\": 0, \"segments\": [{ \"x\": 742, \"y\": 587, \"dx\": 0.18208926018230742, \"dy\": 0.9832820049844601 }, { \"x\": 754, \"y\": 651, \"dx\": 0.20952908873087345, \"dy\": 0.9778024140774094 }] },\n { \"ville1\": \"Munchen\", \"ville2\": \"Wien\", \"longueur\": 3, \"couleur\": \"ORANGE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 768.5, \"y\": 566, \"dx\": 0.6055218324832624, \"dy\": 0.7958286941208591 }, { \"x\": 826, \"y\": 594.5, \"dx\": 0.9986649849421085, \"dy\": 0.0516550854280401 }, { \"x\": 887, \"y\": 574.5, \"dx\": 0.7792134503124135, \"dy\": -0.6267586448165066 }] },\n { \"ville1\": \"Munchen\", \"ville2\": \"Zurich\", \"longueur\": 2, \"couleur\": \"JAUNE\", \"isTunnel\": true, \"ferry\": 0, \"segments\": [{ \"x\": 656.5, \"y\": 609.5, \"dx\": 0.7407190347407712, \"dy\": -0.6718149384858157 }, { \"x\": 702.5, \"y\": 564, \"dx\": 0.7321867381630838, \"dy\": -0.6811039424772872 }] },\n {\n \"ville1\": \"Palermo\", \"ville2\": \"Roma\", \"longueur\": 4, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 1, \"segments\": [\n { \"x\": 864, \"y\": 1032, \"dx\": -0.5943910610838058, \"dy\": 0.8041761414663255 },\n { \"x\": 884.5, \"y\": 972, \"dx\": -0.017238817250844786, \"dy\": 0.9998514005489976 },\n { \"x\": 866, \"y\": 911, \"dx\": 0.6163082616581107, \"dy\": 0.7875050010075858 },\n { \"x\": 818, \"y\": 867.5, \"dx\": 0.8799053976571926, \"dy\": 0.47514891473488396 },\n ]\n },\n {\n \"ville1\": \"Palermo\", \"ville2\": \"Smyrna\", \"longueur\": 6, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 2, \"segments\": [\n { \"x\": 1236.5, \"y\": 1069, \"dx\": 1, \"dy\": 0 },\n { \"x\": 1172.5, \"y\": 1069, \"dx\": 1, \"dy\": 0 },\n { \"x\": 1110.5, \"y\": 1069, \"dx\": 1, \"dy\": 0 },\n { \"x\": 1048.5, \"y\": 1069, \"dx\": 1, \"dy\": 0 },\n { \"x\": 984, \"y\": 1069, \"dx\": 1, \"dy\": 0 },\n { \"x\": 920, \"y\": 1069, \"dx\": 1, \"dy\": 0 },\n ]\n },\n { \"ville1\": \"Pamplona\", \"ville2\": \"Paris\", \"longueur\": 4, \"couleur\": \"BLEU\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 321.5, \"y\": 763, \"dx\": 0.5891721574494418, \"dy\": -0.8080075302163774 }, { \"x\": 353.5, \"y\": 706.5, \"dx\": 0.34570535882735637, \"dy\": -0.9383431168171101 }, { \"x\": 374, \"y\": 647, \"dx\": 0.24253562503633297, \"dy\": -0.9701425001453319 }, { \"x\": 387.5, \"y\": 584, \"dx\": 0.15333732983159673, \"dy\": -0.988173903359179 }] },\n { \"ville1\": \"Pamplona\", \"ville2\": \"Paris\", \"longueur\": 4, \"couleur\": \"VERT\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 343.5, \"y\": 770.5, \"dx\": 0.597266145998167, \"dy\": -0.8020431103403957 }, { \"x\": 376, \"y\": 713, \"dx\": 0.37729688731351946, \"dy\": -0.9260923597695477 }, { \"x\": 397, \"y\": 654, \"dx\": 0.27472112789737807, \"dy\": -0.9615239476408232 }, { \"x\": 410.5, \"y\": 592, \"dx\": 0.11982016019085814, \"dy\": -0.9927956130099675 }] },\n { \"ville1\": \"Paris\", \"ville2\": \"Zurich\", \"longueur\": 3, \"couleur\": \"GRIS\", \"isTunnel\": true, \"ferry\": 0, \"segments\": [{ \"x\": 468.5, \"y\": 594, \"dx\": 0.5171156399255817, \"dy\": 0.8559155419457903 }, { \"x\": 515.5, \"y\": 636.5, \"dx\": 0.9052369440730288, \"dy\": 0.4249071370138707 }, { \"x\": 578.5, \"y\": 650, \"dx\": 1, \"dy\": 0 }] },\n { \"ville1\": \"Petrograd\", \"ville2\": \"Riga\", \"longueur\": 4, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1216.5, \"y\": 73, \"dx\": 1, \"dy\": 0 }, { \"x\": 1281, \"y\": 74, \"dx\": 0.9993628543475496, \"dy\": -0.03569153051241249 }, { \"x\": 1344, \"y\": 72, \"dx\": 0.9993148337667671, \"dy\": -0.037011660509880265 }, { \"x\": 1407, \"y\": 71.5, \"dx\": 0.9985681322700888, \"dy\": -0.053494721371611896 }] },\n { \"ville1\": \"Petrograd\", \"ville2\": \"Stockholm\", \"longueur\": 8, \"couleur\": \"GRIS\", \"isTunnel\": true, \"ferry\": 0, \"segments\": [{ \"x\": 994, \"y\": 57, \"dx\": 0.6332377902572627, \"dy\": 0.773957299203321 }, { \"x\": 1040, \"y\": 48, \"dx\": 0.8041761414663255, \"dy\": -0.5943910610838058 }, { \"x\": 1099.5, \"y\": 26.5, \"dx\": 0.9998347517133227, \"dy\": 0.01817881366751496 }, { \"x\": 1163, \"y\": 26.5, \"dx\": 0.9998405993454448, \"dy\": 0.017854296416882943 }, { \"x\": 1226.5, \"y\": 25.5, \"dx\": 0.9998461420100133, \"dy\": -0.017541160386140585 }, { \"x\": 1289.5, \"y\": 26, \"dx\": 1, \"dy\": 0 }, { \"x\": 1352.5, \"y\": 26.5, \"dx\": 0.9998347517133227, \"dy\": -0.01817881366751496 }, { \"x\": 1416.5, \"y\": 39, \"dx\": 0.9165393783696333, \"dy\": 0.39994445601584 }] },\n { \"ville1\": \"Petrograd\", \"ville2\": \"Wilno\", \"longueur\": 4, \"couleur\": \"BLEU\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1326, \"y\": 261, \"dx\": 0.5943910610838058, \"dy\": -0.8041761414663255 }, { \"x\": 1364, \"y\": 209.5, \"dx\": 0.5627909770820216, \"dy\": -0.8265992475892192 }, { \"x\": 1400.5, \"y\": 158, \"dx\": 0.5829078754517308, \"dy\": -0.8125382506296854 }, { \"x\": 1437, \"y\": 107.5, \"dx\": 0.5861197865287227, \"dy\": -0.8102244107897049 }] },\n { \"ville1\": \"Riga\", \"ville2\": \"Wilno\", \"longueur\": 4, \"couleur\": \"VERT\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1167, \"y\": 119, \"dx\": -0.16990691650764622, \"dy\": 0.985460115744348 }, { \"x\": 1175, \"y\": 182, \"dx\": 0.4190581774617469, \"dy\": 0.9079593845004517 }, { \"x\": 1216, \"y\": 230.5, \"dx\": 0.8559155419457903, \"dy\": 0.5171156399255817 }, { \"x\": 1270, \"y\": 264.5, \"dx\": 0.8400393777687709, \"dy\": 0.5425254314756646 }] },\n { \"ville1\": \"Roma\", \"ville2\": \"Venezia\", \"longueur\": 2, \"couleur\": \"NOIR\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 772.5, \"y\": 740, \"dx\": 0.19274530403092788, \"dy\": 0.9812488205210874 }, { \"x\": 784, \"y\": 803.5, \"dx\": 0.17888543819998318, \"dy\": 0.9838699100999074 }] },\n { \"ville1\": \"Rostov\", \"ville2\": \"Sevastopol\", \"longueur\": 4, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1526, \"y\": 703, \"dx\": 0.13663739713703102, \"dy\": -0.9906211292434748 }, { \"x\": 1534.5, \"y\": 640, \"dx\": 0.15867809538375516, \"dy\": -0.9873303712766988 }, { \"x\": 1561, \"y\": 598, \"dx\": 0.9906211292434748, \"dy\": 0.13663739713703102 }, { \"x\": 1623.5, \"y\": 609, \"dx\": 0.9849570246463139, \"dy\": 0.17279947800812523 }] },\n { \"ville1\": \"Rostov\", \"ville2\": \"Sochi\", \"longueur\": 2, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1667.5, \"y\": 663, \"dx\": -0.053494721371611896, \"dy\": 0.9985681322700888 }, { \"x\": 1664, \"y\": 726.5, \"dx\": -0.07000328148073091, \"dy\": 0.9975467611004155 }] },\n { \"ville1\": \"Sarajevo\", \"ville2\": \"Sofia\", \"longueur\": 2, \"couleur\": \"GRIS\", \"isTunnel\": true, \"ferry\": 0, \"segments\": [{ \"x\": 1096, \"y\": 793, \"dx\": 0.9079593845004517, \"dy\": -0.4190581774617469 }, { \"x\": 1143.5, \"y\": 792, \"dx\": 0.47514891473488396, \"dy\": 0.8799053976571926 }] },\n { \"ville1\": \"Sarajevo\", \"ville2\": \"Zagrab\", \"longueur\": 3, \"couleur\": \"ROUGE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 913.5, \"y\": 761.5, \"dx\": 0.12189130152520146, \"dy\": 0.9925434552766405 }, { \"x\": 946, \"y\": 815.5, \"dx\": 0.8125382506296854, \"dy\": 0.5829078754517308 }, { \"x\": 1010, \"y\": 825.5, \"dx\": 0.9433123908373908, \"dy\": -0.3319062115909338 }] },\n { \"ville1\": \"Sevastopol\", \"ville2\": \"Sochi\", \"longueur\": 2, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 1, \"segments\": [{ \"x\": 1554, \"y\": 753, \"dx\": 0.9899494936611665, \"dy\": 0.1414213562373095 }, { \"x\": 1616, \"y\": 763, \"dx\": 0.9899494936611665, \"dy\": 0.1414213562373095 }] },\n { \"ville1\": \"Smolensk\", \"ville2\": \"Wilno\", \"longueur\": 3, \"couleur\": \"JAUNE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1344.5, \"y\": 274.5, \"dx\": 0.5812381937190964, \"dy\": -0.8137334712067349 }, { \"x\": 1386, \"y\": 251, \"dx\": 0.8160244811016552, \"dy\": 0.5780173407803391 }, { \"x\": 1438, \"y\": 289, \"dx\": 0.8160244811016552, \"dy\": 0.5780173407803391 }] },\n { \"ville1\": \"Venezia\", \"ville2\": \"Zagrab\", \"longueur\": 2, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 808, \"y\": 680.5, \"dx\": 0.965948051503245, \"dy\": -0.2587360852240835 }, { \"x\": 870.5, \"y\": 691.5, \"dx\": 0.8450788360522153, \"dy\": 0.5346417126044628 }] },\n { \"ville1\": \"Venezia\", \"ville2\": \"Zurich\", \"longueur\": 2, \"couleur\": \"VERT\", \"isTunnel\": true, \"ferry\": 0, \"segments\": [{ \"x\": 664.5, \"y\": 659.5, \"dx\": 0.8837879163470618, \"dy\": 0.4678877204190327 }, { \"x\": 721.5, \"y\": 689, \"dx\": 0.8765785507795943, \"dy\": 0.48125881219271843 }] },\n { \"ville1\": \"Warszawa\", \"ville2\": \"Wien\", \"longueur\": 4, \"couleur\": \"BLEU\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 966.5, \"y\": 531.5, \"dx\": 0.860576682823999, \"dy\": -0.5093208939162444 }, { \"x\": 1016.5, \"y\": 493.5, \"dx\": 0.7423931175486519, \"dy\": -0.6699645207146371 }, { \"x\": 1059.5, \"y\": 446, \"dx\": 0.5891721574494418, \"dy\": -0.8080075302163774 }, { \"x\": 1094, \"y\": 392.5, \"dx\": 0.5221538596385299, \"dy\": -0.8528513040762654 }] },\n { \"ville1\": \"Warszawa\", \"ville2\": \"Wilno\", \"longueur\": 3, \"couleur\": \"ROUGE\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 1142.5, \"y\": 310.5, \"dx\": 0.4678877204190327, \"dy\": -0.8837879163470618 }, { \"x\": 1194, \"y\": 272, \"dx\": 0.9761870601839528, \"dy\": -0.21693045781865616 }, { \"x\": 1257, \"y\": 285, \"dx\": 0.847998304005088, \"dy\": 0.52999894000318 }] },\n { \"ville1\": \"Wien\", \"ville2\": \"Zagrab\", \"longueur\": 2, \"couleur\": \"GRIS\", \"isTunnel\": false, \"ferry\": 0, \"segments\": [{ \"x\": 912.5, \"y\": 667, \"dx\": 0.08588834215301201, \"dy\": -0.9963047689749394 }, { \"x\": 916.5, \"y\": 604.5, \"dx\": 0.054464493159869794, \"dy\": -0.9985157079309461 }] }\n];","import { noop, safe_not_equal, subscribe, run_all, is_function } from '../internal/index.mjs';\nexport { get_store_value as get } from '../internal/index.mjs';\n\nconst subscriber_queue = [];\n/**\n * Creates a `Readable` store that allows reading by subscription.\n * @param value initial value\n * @param {StartStopNotifier}start start and stop notifications for subscriptions\n */\nfunction readable(value, start) {\n return {\n subscribe: writable(value, start).subscribe\n };\n}\n/**\n * Create a `Writable` store that allows both updating and reading by subscription.\n * @param {*=}value initial value\n * @param {StartStopNotifier=}start start and stop notifications for subscriptions\n */\nfunction writable(value, start = noop) {\n let stop;\n const subscribers = new Set();\n function set(new_value) {\n if (safe_not_equal(value, new_value)) {\n value = new_value;\n if (stop) { // store is ready\n const run_queue = !subscriber_queue.length;\n for (const subscriber of subscribers) {\n subscriber[1]();\n subscriber_queue.push(subscriber, value);\n }\n if (run_queue) {\n for (let i = 0; i < subscriber_queue.length; i += 2) {\n subscriber_queue[i][0](subscriber_queue[i + 1]);\n }\n subscriber_queue.length = 0;\n }\n }\n }\n }\n function update(fn) {\n set(fn(value));\n }\n function subscribe(run, invalidate = noop) {\n const subscriber = [run, invalidate];\n subscribers.add(subscriber);\n if (subscribers.size === 1) {\n stop = start(set) || noop;\n }\n run(value);\n return () => {\n subscribers.delete(subscriber);\n if (subscribers.size === 0) {\n stop();\n stop = null;\n }\n };\n }\n return { set, update, subscribe };\n}\nfunction derived(stores, fn, initial_value) {\n const single = !Array.isArray(stores);\n const stores_array = single\n ? [stores]\n : stores;\n const auto = fn.length < 2;\n return readable(initial_value, (set) => {\n let inited = false;\n const values = [];\n let pending = 0;\n let cleanup = noop;\n const sync = () => {\n if (pending) {\n return;\n }\n cleanup();\n const result = fn(single ? values[0] : values, set);\n if (auto) {\n set(result);\n }\n else {\n cleanup = is_function(result) ? result : noop;\n }\n };\n const unsubscribers = stores_array.map((store, i) => subscribe(store, (value) => {\n values[i] = value;\n pending &= ~(1 << i);\n if (inited) {\n sync();\n }\n }, () => {\n pending |= (1 << i);\n }));\n inited = true;\n sync();\n return function stop() {\n run_all(unsubscribers);\n cleanup();\n };\n });\n}\n\nexport { derived, readable, writable };\n","import { writable } from 'svelte/store';\nlet hostname = window.location.hostname;\nif (hostname === \"\") {\n hostname = \"localhost\";\n}\n\nexport const ws = writable(new WebSocket(`ws://${hostname}:3232`));\n","\n \n \n \n {#each routes as route}\n send(route.label)}\n >\n {#each route.segments as segment, i}\n \n \n \n {/each}\n \n {/each}\n \n \n {#each villes as ville}\n send(ville.nom)}\n >\n \n \n {/each}\n \n \n \n \n \n {#each routes as route}\n \n {#each route.segments as segment, i}\n {#if route.proprietaire !== undefined}\n \n \n \n {/if}\n {/each}\n \n {/each}\n \n \n {#each villes as ville}\n {#if ville.proprietaire !== undefined}\n \n \n \n \n {/if}\n {/each}\n \n \n \n \n \n \n ","\n\n

\n
\n \n
\n {props.nom}\n
Score: {props.score}
\n
Gares: {props.nbGares}
\n
Wagons: {props.nbWagons}
\n
\n
\n
\n
\n {#each props.destinations as destination}\n send(destination.nom)}\n >\n {destination.ville1} - {destination.ville2} ({destination.valeur})\n
\n {/each}\n
\n
\n {#each props.cartesWagon as wagon}\n send(wagon)}\n >\n \n
\n {/each}\n
\n
\n {#each props.cartesWagonPosees as wagon}\n
\n \n
\n
\n {/each}\n
\n
\n\n\n\n","\n\n
\n
\n {props.nomJoueurCourant}:\n {props.instruction}\n
\n
\n {#each props.boutons as bouton}\n send(bouton)}\n >{bouton}\n {/each}\n {#if props.peutPasser}\n \n {:else}\n \n {/if}\n
\n
\n\n\n","\n\n
\n
\n {#each lines as line}\n
{@html line}
\n {/each}\n
\n
\n\n\n","\n\n
\n
\n
\n {#each props.cartesWagonVisibles as couleur}\n
\n send(couleur)}\n />\n {couleur[0] + couleur.slice(1).toLowerCase()}\n
\n {/each}\n
\n \n
\n
\n send(\"GRIS\")}\n />\n Cartes wagon ({props.pileCartesWagon})\n
\n
\n {#if props.defausseCartesWagon.length === 0}\n
\n {:else}\n
\n {#each props.defausseCartesWagon.slice(-15) as couleur}\n \n {/each}\n
\n {/if}\n Défausse ({props.defausseCartesWagon.length})\n
\n
\n send(\"destinations\")}\n />\n Destinations ({props.pileDestinations})\n
\n
\n\n\n","\n\n{#if data}\n
\n
\n \n
\n \n \n
\n
\n
\n {#each data.joueurs as props}\n \n {/each}\n
\n
\n{:else}\n

La connexion avec le serveur n'a pas pu être établie.

\n

Démarrez le serveur et rechargez la page.

\n{/if}\n\n\n","import App from './App.svelte';\n\nconst app = new App({\n\ttarget: document.body,\n});\n\nexport default app;"],"names":[],"mappings":";;;;;IAAA,SAAS,IAAI,GAAG,GAAG;IAWnB,SAAS,YAAY,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;IACzD,IAAI,OAAO,CAAC,aAAa,GAAG;IAC5B,QAAQ,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;IACzC,KAAK,CAAC;IACN,CAAC;IACD,SAAS,GAAG,CAAC,EAAE,EAAE;IACjB,IAAI,OAAO,EAAE,EAAE,CAAC;IAChB,CAAC;IACD,SAAS,YAAY,GAAG;IACxB,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IACD,SAAS,OAAO,CAAC,GAAG,EAAE;IACtB,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,SAAS,WAAW,CAAC,KAAK,EAAE;IAC5B,IAAI,OAAO,OAAO,KAAK,KAAK,UAAU,CAAC;IACvC,CAAC;IACD,SAAS,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE;IAC9B,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,KAAK,OAAO,CAAC,KAAK,UAAU,CAAC,CAAC;IAClG,CAAC;IACD,IAAI,oBAAoB,CAAC;IACzB,SAAS,aAAa,CAAC,WAAW,EAAE,GAAG,EAAE;IACzC,IAAI,IAAI,CAAC,oBAAoB,EAAE;IAC/B,QAAQ,oBAAoB,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAC3D,KAAK;IACL,IAAI,oBAAoB,CAAC,IAAI,GAAG,GAAG,CAAC;IACpC,IAAI,OAAO,WAAW,KAAK,oBAAoB,CAAC,IAAI,CAAC;IACrD,CAAC;IAID,SAAS,QAAQ,CAAC,GAAG,EAAE;IACvB,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;IACzC,CAAC;IACD,SAAS,cAAc,CAAC,KAAK,EAAE,IAAI,EAAE;IACrC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,UAAU,EAAE;IAChE,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,0CAA0C,CAAC,CAAC,CAAC;IAC9E,KAAK;IACL,CAAC;IACD,SAAS,SAAS,CAAC,KAAK,EAAE,GAAG,SAAS,EAAE;IACxC,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE;IACvB,QAAQ,OAAO,IAAI,CAAC;IACpB,KAAK;IACL,IAAI,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC;IAChD,IAAI,OAAO,KAAK,CAAC,WAAW,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE,GAAG,KAAK,CAAC;IACjE,CAAC;IAMD,SAAS,mBAAmB,CAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE;IACzD,IAAI,SAAS,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7D,CAAC;IAqFD,SAAS,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE;IAC5C,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACrB,IAAI,OAAO,GAAG,CAAC;IACf,CAAC;IA2JD,SAAS,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE;IAC9B,IAAI,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAmDD,SAAS,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE;IACtC,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC;IAC9C,CAAC;IASD,SAAS,MAAM,CAAC,IAAI,EAAE;IACtB,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IACD,SAAS,YAAY,CAAC,UAAU,EAAE,SAAS,EAAE;IAC7C,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;IACnD,QAAQ,IAAI,UAAU,CAAC,CAAC,CAAC;IACzB,YAAY,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACvC,KAAK;IACL,CAAC;IACD,SAAS,OAAO,CAAC,IAAI,EAAE;IACvB,IAAI,OAAO,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAgBD,SAAS,WAAW,CAAC,IAAI,EAAE;IAC3B,IAAI,OAAO,QAAQ,CAAC,eAAe,CAAC,4BAA4B,EAAE,IAAI,CAAC,CAAC;IACxE,CAAC;IACD,SAAS,IAAI,CAAC,IAAI,EAAE;IACpB,IAAI,OAAO,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IACD,SAAS,KAAK,GAAG;IACjB,IAAI,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,SAAS,KAAK,GAAG;IACjB,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC;IACpB,CAAC;IACD,SAAS,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE;IAC/C,IAAI,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACnD,IAAI,OAAO,MAAM,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACnE,CAAC;IA6BD,SAAS,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE;IACtC,IAAI,IAAI,KAAK,IAAI,IAAI;IACrB,QAAQ,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;IACxC,SAAS,IAAI,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,KAAK,KAAK;IACnD,QAAQ,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC5C,CAAC;IAmCD,SAAS,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE;IAC5C,IAAI,IAAI,CAAC,cAAc,CAAC,8BAA8B,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAC1E,CAAC;IAsBD,SAAS,QAAQ,CAAC,OAAO,EAAE;IAC3B,IAAI,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC1C,CAAC;IAuID,SAAS,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE;IAChD,IAAI,IAAI,KAAK,KAAK,IAAI,EAAE;IACxB,QAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;IACvC,KAAK;IACL,SAAS;IACT,QAAQ,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,GAAG,WAAW,GAAG,EAAE,CAAC,CAAC;IACzE,KAAK;IACL,CAAC;IAgFD,SAAS,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAG,KAAK,EAAE;IACrD,IAAI,MAAM,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;IAClD,IAAI,CAAC,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACpD,IAAI,OAAO,CAAC,CAAC;IACb,CAAC;AA8MD;IACA,IAAI,iBAAiB,CAAC;IACtB,SAAS,qBAAqB,CAAC,SAAS,EAAE;IAC1C,IAAI,iBAAiB,GAAG,SAAS,CAAC;IAClC,CAAC;IACD,SAAS,qBAAqB,GAAG;IACjC,IAAI,IAAI,CAAC,iBAAiB;IAC1B,QAAQ,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IAC5E,IAAI,OAAO,iBAAiB,CAAC;IAC7B,CAAC;IACD,SAAS,YAAY,CAAC,EAAE,EAAE;IAC1B,IAAI,qBAAqB,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACtD,CAAC;IAID,SAAS,WAAW,CAAC,EAAE,EAAE;IACzB,IAAI,qBAAqB,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrD,CAAC;AAwCD;IACA,MAAM,gBAAgB,GAAG,EAAE,CAAC;IAE5B,MAAM,iBAAiB,GAAG,EAAE,CAAC;IAC7B,MAAM,gBAAgB,GAAG,EAAE,CAAC;IAC5B,MAAM,eAAe,GAAG,EAAE,CAAC;IAC3B,MAAM,gBAAgB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3C,IAAI,gBAAgB,GAAG,KAAK,CAAC;IAC7B,SAAS,eAAe,GAAG;IAC3B,IAAI,IAAI,CAAC,gBAAgB,EAAE;IAC3B,QAAQ,gBAAgB,GAAG,IAAI,CAAC;IAChC,QAAQ,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,KAAK;IACL,CAAC;IAKD,SAAS,mBAAmB,CAAC,EAAE,EAAE;IACjC,IAAI,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;IAID;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,MAAM,cAAc,GAAG,IAAI,GAAG,EAAE,CAAC;IACjC,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,SAAS,KAAK,GAAG;IACjB,IAAI,MAAM,eAAe,GAAG,iBAAiB,CAAC;IAC9C,IAAI,GAAG;IACP;IACA;IACA,QAAQ,OAAO,QAAQ,GAAG,gBAAgB,CAAC,MAAM,EAAE;IACnD,YAAY,MAAM,SAAS,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACzD,YAAY,QAAQ,EAAE,CAAC;IACvB,YAAY,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAC7C,YAAY,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACjC,SAAS;IACT,QAAQ,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACpC,QAAQ,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC;IACpC,QAAQ,QAAQ,GAAG,CAAC,CAAC;IACrB,QAAQ,OAAO,iBAAiB,CAAC,MAAM;IACvC,YAAY,iBAAiB,CAAC,GAAG,EAAE,EAAE,CAAC;IACtC;IACA;IACA;IACA,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,gBAAgB,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;IAC7D,YAAY,MAAM,QAAQ,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;IACjD,YAAY,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;IAC/C;IACA,gBAAgB,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7C,gBAAgB,QAAQ,EAAE,CAAC;IAC3B,aAAa;IACb,SAAS;IACT,QAAQ,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC;IACpC,KAAK,QAAQ,gBAAgB,CAAC,MAAM,EAAE;IACtC,IAAI,OAAO,eAAe,CAAC,MAAM,EAAE;IACnC,QAAQ,eAAe,CAAC,GAAG,EAAE,EAAE,CAAC;IAChC,KAAK;IACL,IAAI,gBAAgB,GAAG,KAAK,CAAC;IAC7B,IAAI,cAAc,CAAC,KAAK,EAAE,CAAC;IAC3B,IAAI,qBAAqB,CAAC,eAAe,CAAC,CAAC;IAC3C,CAAC;IACD,SAAS,MAAM,CAAC,EAAE,EAAE;IACpB,IAAI,IAAI,EAAE,CAAC,QAAQ,KAAK,IAAI,EAAE;IAC9B,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC;IACpB,QAAQ,OAAO,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC;IAClC,QAAQ,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC;IAC/B,QAAQ,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACxB,QAAQ,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACpD,QAAQ,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACrD,KAAK;IACL,CAAC;IAeD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAE,CAAC;IAC3B,IAAI,MAAM,CAAC;IACX,SAAS,YAAY,GAAG;IACxB,IAAI,MAAM,GAAG;IACb,QAAQ,CAAC,EAAE,CAAC;IACZ,QAAQ,CAAC,EAAE,EAAE;IACb,QAAQ,CAAC,EAAE,MAAM;IACjB,KAAK,CAAC;IACN,CAAC;IACD,SAAS,YAAY,GAAG;IACxB,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE;IACnB,QAAQ,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1B,KAAK;IACL,IAAI,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;IACtB,CAAC;IACD,SAAS,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE;IACrC,IAAI,IAAI,KAAK,IAAI,KAAK,CAAC,CAAC,EAAE;IAC1B,QAAQ,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACvB,KAAK;IACL,CAAC;IACD,SAAS,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE;IACxD,IAAI,IAAI,KAAK,IAAI,KAAK,CAAC,CAAC,EAAE;IAC1B,QAAQ,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;IAC/B,YAAY,OAAO;IACnB,QAAQ,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC5B,QAAQ,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM;IAC5B,YAAY,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACnC,YAAY,IAAI,QAAQ,EAAE;IAC1B,gBAAgB,IAAI,MAAM;IAC1B,oBAAoB,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,gBAAgB,QAAQ,EAAE,CAAC;IAC3B,aAAa;IACb,SAAS,CAAC,CAAC;IACX,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACvB,KAAK;IACL,CAAC;AAoTD;IACA,MAAM,OAAO,IAAI,OAAO,MAAM,KAAK,WAAW;IAC9C,MAAM,MAAM;IACZ,MAAM,OAAO,UAAU,KAAK,WAAW;IACvC,UAAU,UAAU;IACpB,UAAU,MAAM,CAAC,CAAC;IAkVlB,SAAS,gBAAgB,CAAC,KAAK,EAAE;IACjC,IAAI,KAAK,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC;IACvB,CAAC;IAID,SAAS,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE;IACnE,IAAI,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC;IAC1E,IAAI,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,IAAI,IAAI,CAAC,aAAa,EAAE;IACxB;IACA,QAAQ,mBAAmB,CAAC,MAAM;IAClC,YAAY,MAAM,cAAc,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACzE,YAAY,IAAI,UAAU,EAAE;IAC5B,gBAAgB,UAAU,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC;IACnD,aAAa;IACb,iBAAiB;IACjB;IACA;IACA,gBAAgB,OAAO,CAAC,cAAc,CAAC,CAAC;IACxC,aAAa;IACb,YAAY,SAAS,CAAC,EAAE,CAAC,QAAQ,GAAG,EAAE,CAAC;IACvC,SAAS,CAAC,CAAC;IACX,KAAK;IACL,IAAI,YAAY,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC9C,CAAC;IACD,SAAS,iBAAiB,CAAC,SAAS,EAAE,SAAS,EAAE;IACjD,IAAI,MAAM,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC;IAC5B,IAAI,IAAI,EAAE,CAAC,QAAQ,KAAK,IAAI,EAAE;IAC9B,QAAQ,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;IAC/B,QAAQ,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAChD;IACA;IACA,QAAQ,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC;IAC3C,QAAQ,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC;IACpB,KAAK;IACL,CAAC;IACD,SAAS,UAAU,CAAC,SAAS,EAAE,CAAC,EAAE;IAClC,IAAI,IAAI,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;IACtC,QAAQ,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzC,QAAQ,eAAe,EAAE,CAAC;IAC1B,QAAQ,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACnC,KAAK;IACL,IAAI,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACxD,CAAC;IACD,SAAS,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE;IAC5G,IAAI,MAAM,gBAAgB,GAAG,iBAAiB,CAAC;IAC/C,IAAI,qBAAqB,CAAC,SAAS,CAAC,CAAC;IACrC,IAAI,MAAM,EAAE,GAAG,SAAS,CAAC,EAAE,GAAG;IAC9B,QAAQ,QAAQ,EAAE,IAAI;IACtB,QAAQ,GAAG,EAAE,IAAI;IACjB;IACA,QAAQ,KAAK;IACb,QAAQ,MAAM,EAAE,IAAI;IACpB,QAAQ,SAAS;IACjB,QAAQ,KAAK,EAAE,YAAY,EAAE;IAC7B;IACA,QAAQ,QAAQ,EAAE,EAAE;IACpB,QAAQ,UAAU,EAAE,EAAE;IACtB,QAAQ,aAAa,EAAE,EAAE;IACzB,QAAQ,aAAa,EAAE,EAAE;IACzB,QAAQ,YAAY,EAAE,EAAE;IACxB,QAAQ,OAAO,EAAE,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,gBAAgB,GAAG,gBAAgB,CAAC,EAAE,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IAClG;IACA,QAAQ,SAAS,EAAE,YAAY,EAAE;IACjC,QAAQ,KAAK;IACb,QAAQ,UAAU,EAAE,KAAK;IACzB,QAAQ,IAAI,EAAE,OAAO,CAAC,MAAM,IAAI,gBAAgB,CAAC,EAAE,CAAC,IAAI;IACxD,KAAK,CAAC;IACN,IAAI,aAAa,IAAI,aAAa,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,IAAI,KAAK,GAAG,KAAK,CAAC;IACtB,IAAI,EAAE,CAAC,GAAG,GAAG,QAAQ;IACrB,UAAU,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI,KAAK;IACxE,YAAY,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IACtD,YAAY,IAAI,EAAE,CAAC,GAAG,IAAI,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE;IACnE,gBAAgB,IAAI,CAAC,EAAE,CAAC,UAAU,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IACjD,oBAAoB,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACvC,gBAAgB,IAAI,KAAK;IACzB,oBAAoB,UAAU,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IAC7C,aAAa;IACb,YAAY,OAAO,GAAG,CAAC;IACvB,SAAS,CAAC;IACV,UAAU,EAAE,CAAC;IACb,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC;IAChB,IAAI,KAAK,GAAG,IAAI,CAAC;IACjB,IAAI,OAAO,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC;IAC9B;IACA,IAAI,EAAE,CAAC,QAAQ,GAAG,eAAe,GAAG,eAAe,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACpE,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE;IACxB,QAAQ,IAAI,OAAO,CAAC,OAAO,EAAE;IAE7B,YAAY,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD;IACA,YAAY,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAChD,YAAY,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,SAAS;IACT,aAAa;IACb;IACA,YAAY,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;IAC3C,SAAS;IACT,QAAQ,IAAI,OAAO,CAAC,KAAK;IACzB,YAAY,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;IACjD,QAAQ,eAAe,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAE1F,QAAQ,KAAK,EAAE,CAAC;IAChB,KAAK;IACL,IAAI,qBAAqB,CAAC,gBAAgB,CAAC,CAAC;IAC5C,CAAC;IA8CD;IACA;IACA;IACA,MAAM,eAAe,CAAC;IACtB,IAAI,QAAQ,GAAG;IACf,QAAQ,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACnC,QAAQ,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IAC7B,KAAK;IACL,IAAI,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE;IACxB,QAAQ,MAAM,SAAS,IAAI,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACtF,QAAQ,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjC,QAAQ,OAAO,MAAM;IACrB,YAAY,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACtD,YAAY,IAAI,KAAK,KAAK,CAAC,CAAC;IAC5B,gBAAgB,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC3C,SAAS,CAAC;IACV,KAAK;IACL,IAAI,IAAI,CAAC,OAAO,EAAE;IAClB,QAAQ,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;IAC9C,YAAY,IAAI,CAAC,EAAE,CAAC,UAAU,GAAG,IAAI,CAAC;IACtC,YAAY,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChC,YAAY,IAAI,CAAC,EAAE,CAAC,UAAU,GAAG,KAAK,CAAC;IACvC,SAAS;IACT,KAAK;IACL,CAAC;AACD;IACA,SAAS,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE;IACpC,IAAI,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IACnG,CAAC;IACD,SAAS,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE;IAClC,IAAI,YAAY,CAAC,iBAAiB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACzB,CAAC;IAKD,SAAS,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE;IAC1C,IAAI,YAAY,CAAC,iBAAiB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9D,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACjC,CAAC;IAKD,SAAS,UAAU,CAAC,IAAI,EAAE;IAC1B,IAAI,YAAY,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC;IAgBD,SAAS,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE;IAC9F,IAAI,MAAM,SAAS,GAAG,OAAO,KAAK,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC;IACvG,IAAI,IAAI,mBAAmB;IAC3B,QAAQ,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACzC,IAAI,IAAI,oBAAoB;IAC5B,QAAQ,SAAS,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC1C,IAAI,YAAY,CAAC,2BAA2B,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;IACnF,IAAI,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1D,IAAI,OAAO,MAAM;IACjB,QAAQ,YAAY,CAAC,8BAA8B,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;IAC1F,QAAQ,OAAO,EAAE,CAAC;IAClB,KAAK,CAAC;IACN,CAAC;IACD,SAAS,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE;IAC1C,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IACjC,IAAI,IAAI,KAAK,IAAI,IAAI;IACrB,QAAQ,YAAY,CAAC,0BAA0B,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IACtE;IACA,QAAQ,YAAY,CAAC,uBAAuB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1E,CAAC;IASD,SAAS,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE;IAClC,IAAI,IAAI,GAAG,EAAE,GAAG,IAAI,CAAC;IACrB,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI;IAC/B,QAAQ,OAAO;IACf,IAAI,YAAY,CAAC,kBAAkB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACrB,CAAC;IACD,SAAS,sBAAsB,CAAC,GAAG,EAAE;IACrC,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,EAAE,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,QAAQ,IAAI,GAAG,CAAC,EAAE;IACzF,QAAQ,IAAI,GAAG,GAAG,gDAAgD,CAAC;IACnE,QAAQ,IAAI,OAAO,MAAM,KAAK,UAAU,IAAI,GAAG,IAAI,MAAM,CAAC,QAAQ,IAAI,GAAG,EAAE;IAC3E,YAAY,GAAG,IAAI,+DAA+D,CAAC;IACnF,SAAS;IACT,QAAQ,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,KAAK;IACL,CAAC;IACD,SAAS,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;IAC1C,IAAI,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;IAC9C,QAAQ,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;IACtC,YAAY,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,+BAA+B,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;IACjF,SAAS;IACT,KAAK;IACL,CAAC;IACD;IACA;IACA;IACA,MAAM,kBAAkB,SAAS,eAAe,CAAC;IACjD,IAAI,WAAW,CAAC,OAAO,EAAE;IACzB,QAAQ,IAAI,CAAC,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;IAChE,YAAY,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAC7D,SAAS;IACT,QAAQ,KAAK,EAAE,CAAC;IAChB,KAAK;IACL,IAAI,QAAQ,GAAG;IACf,QAAQ,KAAK,CAAC,QAAQ,EAAE,CAAC;IACzB,QAAQ,IAAI,CAAC,QAAQ,GAAG,MAAM;IAC9B,YAAY,OAAO,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IAC5D,SAAS,CAAC;IACV,KAAK;IACL,IAAI,cAAc,GAAG,GAAG;IACxB,IAAI,aAAa,GAAG,GAAG;IACvB;;IC3hEO,MAAM,UAAU,GAAG;IAC1B,IAAI,OAAO,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE;IACpD,IAAI,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;IACrD,IAAI,WAAW,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE;IAC3D,IAAI,QAAQ,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;IACpD,IAAI,UAAU,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE;IACzD,IAAI,OAAO,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE;IACnD,IAAI,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;IACrD,IAAI,OAAO,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE;IACnD,IAAI,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;IACrD,IAAI,WAAW,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE;IAC3D,IAAI,WAAW,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE;IAC3D,IAAI,WAAW,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE;IAC1D,IAAI,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;IACrD,IAAI,WAAW,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE;IAC3D,IAAI,WAAW,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE;IAC3D,IAAI,SAAS,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE;IACvD,IAAI,MAAM,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE;IACjD,IAAI,SAAS,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE;IACvD,IAAI,MAAM,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE;IACjD,IAAI,UAAU,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE;IACzD,IAAI,SAAS,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE;IACxD,IAAI,QAAQ,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE;IACvD,IAAI,OAAO,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE;IACpD,IAAI,UAAU,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE;IAC1D,IAAI,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;IACrD,IAAI,UAAU,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE;IAC1D,IAAI,MAAM,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE;IAClD,IAAI,UAAU,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE;IAC1D,IAAI,OAAO,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE;IACpD,IAAI,UAAU,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE;IAC1D,IAAI,QAAQ,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;IACtD,IAAI,SAAS,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE;IACxD,IAAI,QAAQ,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;IACtD,IAAI,OAAO,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE;IACpD,IAAI,SAAS,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE;IACxD,IAAI,gBAAgB,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,gBAAgB,EAAE;IACtE,IAAI,QAAQ,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE;IACvD,IAAI,QAAQ,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE;IACvD,IAAI,OAAO,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE;IACnD,IAAI,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;IACrD,IAAI,WAAW,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE;IAC3D,IAAI,WAAW,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE;IAC1D,IAAI,MAAM,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;IACjD,IAAI,WAAW,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE;IAC3D,IAAI,QAAQ,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;IACtD,IAAI,WAAW,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE;IAC5D,IAAI,YAAY,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE;IAC9D,CAAC,CAAC;AACF;IACO,MAAM,UAAU,GAAG;IAC1B,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IACrN,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IACzW,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,EAAE;IAC7R,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,EAAE;IAC1P,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAC9R,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IACtX,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,CAAC,EAAE;IACrX,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,CAAC,EAAE;IAC7b,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,oBAAoB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,oBAAoB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,EAAE;IACxc,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,oBAAoB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,EAAE;IACnS,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,EAAE;IACrW,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,EAAE;IACrS,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,CAAC,EAAE;IAClc,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IACnS,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,iBAAiB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,EAAE;IACzb,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,EAAE;IAC5R,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,CAAC,EAAE;IAClX,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAC/W,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAC7b,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,EAAE;IAChc,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IACtW,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,iBAAiB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,CAAC,EAAE;IAC5R,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE;IAChZ,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,EAAE;IACvW,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAClX,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAC5R,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAC5R,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IACjS,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAChS,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAClS,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAC7b,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IACtX,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,iBAAiB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,iBAAiB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IACxb,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IACpc,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAClS,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,EAAE;IAC3lB,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAC7W,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAC5M,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAC1M,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,iBAAiB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAChS,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,EAAE;IAC1R,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAChX,IAAI,EAAE,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,oBAAoB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAChd,IAAI,EAAE,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,iBAAiB,EAAE,CAAC,EAAE;IAC1S,IAAI,EAAE,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,EAAE;IAC5W,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAC7W,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IACzR,IAAI;IACJ,QAAQ,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE;IAC7H,YAAY,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE;IAC5F,YAAY,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE;IAC1F,SAAS;IACT,KAAK;IACL,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAC/R,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAC5M,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAC1b,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAC3b,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,EAAE;IACxZ,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAClX,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAC5R,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IACtW,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAC1W,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,CAAC,EAAE;IAChS,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAC/W,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAC5W,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,CAAC,EAAE;IAC1b,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAC9b,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAC5P,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,CAAC,EAAE;IAC9W,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAC/W,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAClX,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,oBAAoB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,EAAE;IAClc,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE;IACtP,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IACpU,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,iBAAiB,EAAE,CAAC,EAAE;IACzW,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IACvW,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,oBAAoB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,EAAE;IACrc,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC,iBAAiB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,oBAAoB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAClc,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IACvZ,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAC7R,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IACxb,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAC9R,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IACxR,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IACzW,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAC9R,IAAI;IACJ,QAAQ,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE;IAC5H,YAAY,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE;IACxF,YAAY,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,oBAAoB,EAAE,IAAI,EAAE,kBAAkB,EAAE;IAC3F,YAAY,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE;IACtF,YAAY,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE;IACzF,SAAS;IACT,KAAK;IACL,IAAI;IACJ,QAAQ,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE;IAC9H,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;IACxD,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;IACxD,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;IACxD,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;IACxD,YAAY,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;IACrD,YAAY,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;IACrD,SAAS;IACT,KAAK;IACL,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,iBAAiB,EAAE,CAAC,EAAE;IAC5b,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAC1b,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE;IACrU,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,oBAAoB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,oBAAoB,EAAE,CAAC,EAAE;IACxZ,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,oBAAoB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,EAAE;IACvtB,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAC7b,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IACnb,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAC1R,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,EAAE;IAC/b,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,oBAAoB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAC/R,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAC3R,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAC/W,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAC1R,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAC3W,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE;IAC5R,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,EAAE;IAC5R,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAC/b,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,EAAE;IAC1W,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAE;IAC9R,CAAC;;IC1KD,MAAM,gBAAgB,GAAG,EAAE,CAAC;IAW5B;IACA;IACA;IACA;IACA;IACA,SAAS,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE;IACvC,IAAI,IAAI,IAAI,CAAC;IACb,IAAI,MAAM,WAAW,GAAG,IAAI,GAAG,EAAE,CAAC;IAClC,IAAI,SAAS,GAAG,CAAC,SAAS,EAAE;IAC5B,QAAQ,IAAI,cAAc,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE;IAC9C,YAAY,KAAK,GAAG,SAAS,CAAC;IAC9B,YAAY,IAAI,IAAI,EAAE;IACtB,gBAAgB,MAAM,SAAS,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAAC;IAC3D,gBAAgB,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE;IACtD,oBAAoB,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IACpC,oBAAoB,gBAAgB,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC7D,iBAAiB;IACjB,gBAAgB,IAAI,SAAS,EAAE;IAC/B,oBAAoB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,gBAAgB,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;IACzE,wBAAwB,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACxE,qBAAqB;IACrB,oBAAoB,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC;IAChD,iBAAiB;IACjB,aAAa;IACb,SAAS;IACT,KAAK;IACL,IAAI,SAAS,MAAM,CAAC,EAAE,EAAE;IACxB,QAAQ,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IACvB,KAAK;IACL,IAAI,SAAS,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,EAAE;IAC/C,QAAQ,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAC7C,QAAQ,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACpC,QAAQ,IAAI,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE;IACpC,YAAY,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;IACtC,SAAS;IACT,QAAQ,GAAG,CAAC,KAAK,CAAC,CAAC;IACnB,QAAQ,OAAO,MAAM;IACrB,YAAY,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC3C,YAAY,IAAI,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE;IACxC,gBAAgB,IAAI,EAAE,CAAC;IACvB,gBAAgB,IAAI,GAAG,IAAI,CAAC;IAC5B,aAAa;IACb,SAAS,CAAC;IACV,KAAK;IACL,IAAI,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IACtC;;IC1DA,IAAI,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;IACxC,IAAI,QAAQ,KAAK,EAAE,EAAE;IACrB,IAAI,QAAQ,GAAG,WAAW,CAAC;IAC3B,CAAC;AACD;IACO,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,SAAS,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BC0GhD,gBAAgB,GAAG,CAAC;4BACpB,eAAe,GAAG,CAAC;+BAChB,gBAAgB;gCACf,eAAe;;;+EAPH,GAAO,KAAC,CAAC,sBAAI,GAAO,KAAC,CAAC,8BACnC,IAAI,CAAC,KAAK,aAAC,GAAO,KAAC,EAAE,cAAE,GAAO,KAAC,EAAE,IAAI,GAAG,GAAI,IAAI,CAAC,EAAE;;;;OAH9D,UAWI;OANF,UAKE;;;yGARoB,GAAO,KAAC,CAAC,sBAAI,GAAO,KAAC,CAAC,8BACnC,IAAI,CAAC,KAAK,aAAC,GAAO,KAAC,EAAE,cAAE,GAAO,KAAC,EAAE,IAAI,GAAG,GAAI,IAAI,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;kCAJzD,GAAK,KAAC,QAAQ;;;;sCAAnB,MAAI;;;;;;;;;;;;;;;;;;;;OAJR,UAkBI;;;;;;;;;;;;;;;iCAdK,GAAK,KAAC,QAAQ;;;;qCAAnB,MAAI;;;;;;;;;;;;;;;;0CAAJ,MAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAwBmB,WAAW;;;6EAHd,GAAK,IAAC,CAAC,oBAAI,GAAK,IAAC,CAAC;;;;OAF1C,UAMI;OADF,UAAwC;;;;;;;;;;uGAHlB,GAAK,IAAC,CAAC,oBAAI,GAAK,IAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kGA6BA,GAAK,KAAC,YAAY;gCAC3C,YAAY;iCACX,YAAY;oDACG,YAAY,GAAG,IAAI,WAAK,YAAY,GAAG,CAAC;;+EAP3C,GAAO,KAAC,CAAC,sBAAI,GAAO,KAAC,CAAC,gCACnC,IAAI,CAAC,KAAK,aAAC,GAAO,KAAC,EAAE,cAAE,GAAO,KAAC,EAAE,IAAI,GAAG,GAAI,IAAI,CAAC,EAAE;;;;OAF9D,UAUI;OANF,UAKE;;;0HAJgC,GAAK,KAAC,YAAY;;;;yGAJ9B,GAAO,KAAC,CAAC,sBAAI,GAAO,KAAC,CAAC,gCACnC,IAAI,CAAC,KAAK,aAAC,GAAO,KAAC,EAAE,cAAE,GAAO,KAAC,EAAE,IAAI,GAAG,GAAI,IAAI,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;8BAH3D,GAAK,KAAC,YAAY,KAAK,SAAS;;;;;;;;;;;;qBAAhC,GAAK,KAAC,YAAY,KAAK,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kCADhC,GAAK,KAAC,QAAQ;;;;sCAAnB,MAAI;;;;;;;;;;;;;;;;OADR,UAgBI;;;;;;;;iCAfK,GAAK,KAAC,QAAQ;;;;qCAAnB,MAAI;;;;;;;;;;;;;;;;0CAAJ,MAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCAwBK,WAAW,GAAG,IAAI;kCACjB,WAAW,GAAG,IAAI;qDACH,WAAW,GAAG,IAAI,WAAK,WAAW,GAAG,IAAI;;6FAGvC,GAAK,IAAC,YAAY;iCACpC,WAAW;kCACV,WAAW;qDACI,WAAW,GAAG,GAAG,WAAK,WAAW,GAAG,GAAG;;;6EAXtB,GAAK,IAAC,CAAC,oBAAI,GAAK,IAAC,CAAC;;;;OAA9D,UAaI;OAZF,UAKE;OACF,UAKE;;;qHAJyB,GAAK,IAAC,YAAY;;;;uGARH,GAAK,IAAC,CAAC,oBAAI,GAAK,IAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;8BAD3D,GAAK,IAAC,YAAY,KAAK,SAAS;;;;;;;;;;;;qBAAhC,GAAK,IAAC,YAAY,KAAK,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCApEhC,GAAM;;;;sCAAX,MAAI;;;;mCAuBC,GAAM;;;;sCAAX,MAAI;;;;mCAuBC,GAAM;;;;sCAAX,MAAI;;;;iCAqBC,GAAM;;;;oCAAX,MAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA1ER,UA+FM;;;;;;;;;;;;OAtDJ,UASE;;;;;;;;;;;;OA4CF,UAAuG;;;6CAAf,YAAY;;;;;;kCAvF7F,GAAM;;;;qCAAX,MAAI;;;;;;;;;;;;;;;;4CAAJ,MAAI;;;;kCAuBC,GAAM;;;;qCAAX,MAAI;;;;;;;;;;;;;;;;4CAAJ,MAAI;;;;kCAuBC,GAAM;;;;qCAAX,MAAI;;;;;;;;;;;;;;;;4CAAJ,MAAI;;;;gCAqBC,GAAM;;;;mCAAX,MAAI;;;;;;;;;;;;;;;;wCAAJ,MAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;UAhKA,gBAAgB,GAAG,EAAE;UACrB,eAAe,GAAG,EAAE;UACpB,YAAY,GAAG,EAAE;UACjB,WAAW,GAAG,EAAE;UAChB,WAAW,GAAG,EAAE;;aAEb,YAAY;WACb,KAAK,GAAG,QAAQ,CAAC,cAAc,CAAC,OAAO;;SACzC,KAAK,CAAC,KAAK,CAAC,UAAU,KAAK,QAAQ;MACrC,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE;;MAE3B,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,QAAQ;;;;;;;;;;WAb1B,KAAK;;cAiBP,IAAI,CAAC,OAAO;MACjB,OAAO,CAAC,GAAG,cAAc,OAAO;MAChC,GAAG,CAAC,IAAI,CAAC,OAAO;;;WAGd,KAAK;MACT,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;OACnB,IAAI,CAAC,GAAG,GAAG,GAAG;OACd,IAAI,CAAC,CAAC,GAAG,CAAC;OACV,IAAI,CAAC,CAAC,GAAG,CAAC;OACV,IAAI,CAAC,YAAY,GAAG,SAAS;;;;WAI3B,KAAK;MACT,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ;OACtE,IAAI,CAAC,MAAM,GAAG,MAAM;OACpB,IAAI,CAAC,MAAM,GAAG,MAAM;OACpB,IAAI,CAAC,QAAQ,GAAG,QAAQ;OACxB,IAAI,CAAC,OAAO,GAAG,OAAO;OACtB,IAAI,CAAC,QAAQ,GAAG,QAAQ;OACxB,IAAI,CAAC,KAAK,GAAG,KAAK;OAClB,IAAI,CAAC,KAAK,MAAM,MAAM,MAAM,MAAM;OAClC,IAAI,CAAC,QAAQ,GAAG,QAAQ;OACxB,IAAI,CAAC,YAAY,GAAG,SAAS;;;;WAI3B,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,CACzC,IAAI,QAAS,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;WAGxC,MAAM,GAAG,UAAU,CAAC,GAAG,CAC1B,IAAI,QACC,KAAK,CACP,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,QAAQ;;;cAKV,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;UAClC,MAAM,CAAC,CAAC,EAAE,KAAK,KAAK,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK;OACzC,MAAM,CAAC,CAAC,EAAE,KAAK,IAAI,KAAK;OACxB,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,IAAI,KAAK;;;;KAIhC,YAAY;iBACC,SAAS,IAAI,KAAK,CAAC,MAAM;WAC9B,SAAS,CAAC,YAAY;QACxB,MAAM,CAAC,MAAM,CAAE,CAAC,IAAK,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,GAAG,EAAE,CAAC,EAAE,YAAY,GAC7D,SAAS,CAAC,YAAY;;;;iBAGjB,SAAS,IAAI,KAAK,CAAC,MAAM;WAC9B,SAAS,CAAC,YAAY;QACxB,MAAM,CAAC,MAAM,CAAE,CAAC,IAAK,CAAC,CAAC,GAAG,KAAK,SAAS,CAAC,GAAG,EAAE,CAAC,EAAE,YAAY,GAC3D,SAAS,CAAC,YAAY;;;;;;;;;;;;;;oCAkBV,IAAI,CAAC,KAAK,CAAC,KAAK;sCAwBhB,IAAI,CAAC,KAAK,CAAC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oCChGjB,GAAW,KAAC,MAAM;;;oCAAK,GAAW,KAAC,MAAM;;;oCAAI,GAAW,KAAC,MAAM;;;;;;;;;;;;;;iBAA5C,KAAG;;iBAAoB,IAAE;;iBAAoB,qBACrE;;;;;OALA,UAKM;;;;;;;;;;;;;;;2EADD,GAAW,KAAC,MAAM;2EAAK,GAAW,KAAC,MAAM;2EAAI,GAAW,KAAC,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iFAYX,GAAK;;6EALtC,GAAK;;;;OAD7B,UAQM;OAJF,UAGE;;;;;;;;;;;;kFADmD,GAAK;;;sGALtC,GAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iFAe4B,GAAK;;;;6EAHrC,GAAK;;;;OAA9B,UAMM;OALF,UAGE;;OACF,UAAuB;;;;;kFAF8B,GAAK;;;sGAHrC,GAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAhCf,GAAK,IAAC,GAAG;;;;;8BACD,GAAK,IAAC,KAAK;;;;;8BACX,GAAK,IAAC,OAAO;;;;;+BACX,GAAK,IAAC,QAAQ;;;;;;;;;;kCAKpC,GAAK,IAAC,YAAY;;;;sCAAvB,MAAI;;;;kCAUC,GAAK,IAAC,WAAW;;;;sCAAtB,MAAI;;;;gCAaC,GAAK,IAAC,iBAAiB;;;;oCAA5B,MAAI;;;;;;;;;;;;;;;iBA9Ba,SAAO;;;;iBACP,SAAO;;;;iBACN,UAAQ;;;;;;;;;;;;;;;;;;;;;;;;;kEAPf,GAAK,IAAC,OAAO;gFACN,GAAK,IAAC,OAAO;;;;;;;;;;;;;;;;;;;;;;wEALzB,GAAK,IAAC,OAAO,oBAAG,GAAK,IAAC,gBAAgB,GAAG,OAAO,GAAG,EAAE;;;;;;;OAAzE,UAkDM;OAjDF,UAYM;OAXF,UAIE;;OACF,UAKM;OAJF,UAAoC;;;OACpC,UAA6C;;;;OAC7C,UAA+C;;;;OAC/C,UAAkD;;;;OAG1D,UAmCM;OAlCF,UASM;;;;;;;OACN,UAYM;;;;;;;OACN,UAUM;;;;;;;2FA5CW,GAAK,IAAC,OAAO;;;;uGACN,GAAK,IAAC,OAAO;;;;qEAGd,GAAK,IAAC,GAAG;qEACD,GAAK,IAAC,KAAK;qEACX,GAAK,IAAC,OAAO;uEACX,GAAK,IAAC,QAAQ;;;iCAKpC,GAAK,IAAC,YAAY;;;;qCAAvB,MAAI;;;;;;;;;;;;;;;;4CAAJ,MAAI;;;;iCAUC,GAAK,IAAC,WAAW;;;;qCAAtB,MAAI;;;;;;;;;;;;;;;;4CAAJ,MAAI;;;;+BAaC,GAAK,IAAC,iBAAiB;;;;mCAA5B,MAAI;;;;;;;;;;;;;;;;wCAAJ,MAAI;;;iGAvCE,GAAK,IAAC,OAAO,oBAAG,GAAK,IAAC,gBAAgB,GAAG,OAAO,GAAG,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAR1D,KAAK;;cAEP,IAAI,CAAC,OAAO;MACjB,OAAO,CAAC,GAAG,cAAc,OAAO;MAChC,GAAG,CAAC,IAAI,CAAC,OAAO;;;;;;;;;0CAuBY,IAAI,CAAC,WAAW,CAAC,GAAG;sCAUpB,IAAI,CAAC,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BCnB5B,GAAM;;;;;;;;;;;;;;;;;OAHZ,UAIC;;;;;;;;;;oEADK,GAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAMZ,UAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAFhC,UAAiD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAZ/B,GAAK,IAAC,gBAAgB;;;;8BAC/C,GAAK,IAAC,WAAW;;;;;gCAGP,GAAK,IAAC,OAAO;;;;oCAAlB,MAAI;;;;;oBAOD,GAAK,IAAC,UAAU;;;;;;;;;;;;;iBAXwB,GAAC;;;;;;;;;;;;;;;;;;;;;;;;;OAFtD,UAmBM;OAlBF,UAGM;OAFN,UAAyD;;;;;;OAGzD,UAaM;;;;;;;;;;qEAhBoB,GAAK,IAAC,gBAAgB;qEAC/C,GAAK,IAAC,WAAW;;;+BAGP,GAAK,IAAC,OAAO;;;;mCAAlB,MAAI;;;;;;;;;;;;;;;;wCAAJ,MAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAfC,KAAK;;cAGP,IAAI,CAAC,OAAO;MACjB,OAAO,CAAC,GAAG,cAAc,OAAO;MAChC,GAAG,CAAC,IAAI,CAAC,OAAO;;;;;;;;;qCAaQ,IAAI,CAAC,MAAM;mCAKP,IAAI,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BCTnB,GAAI;;;;;;;;;OAAhB,UAAuB;;;;sEAAX,GAAI;;;;;;;;;;;;;;;;;;;;gCADb,GAAK;;;;oCAAV,MAAI;;;;;;;;;;;;;;;;;;;;;;;;OAFd,UAMM;OALF,UAIM;;;;;;;;+BAHK,GAAK;;;;mCAAV,MAAI;;;;;;;;;;;;;;;;wCAAJ,MAAI;;;;;;;;;;;;;;;;;;;;;;aAVD,cAAc;WACb,UAAU,GAAG,QAAQ,CAAC,cAAc,CAAC,WAAW;KACtD,UAAU,CAAC,SAAS,GAAG,UAAU,CAAC,YAAY;;;;;;WAJvC,KAAK;KAOhB,WAAW,CAAC,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCCcH,GAAO,IAAC,CAAC,gBAAI,GAAO,IAAC,KAAK,CAAC,CAAC,EAAE,WAAW;;;;;;;;;;;;;;;;;;;wDAJvC,GAAO;uFACa,GAAO;;;;;;;OAJxC,UAQM;OAPF,UAKE;;OACF,UAA0D;;;;;;;;;;;;iFAJjD,GAAO;;;;8GACa,GAAO;;;;uEAG7B,GAAO,IAAC,CAAC,gBAAI,GAAO,IAAC,KAAK,CAAC,CAAC,EAAE,WAAW;;;;;;;;;;;;;;;;;;;;;;;gCAoB7C,GAAK,IAAC,mBAAmB,CAAC,KAAK,EAAE,EAAE;;;;oCAAxC,MAAI;;;;;;;;;;;;;;;;;OADV,UAQM;;;;;;;;+BAPK,GAAK,IAAC,mBAAmB,CAAC,KAAK,EAAE,EAAE;;;;mCAAxC,MAAI;;;;;;;;;;;;;;;;wCAAJ,MAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAHV,UAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wDAMT,GAAO;uFACa,GAAO;;;;OAHpC,UAIE;;;iFAFO,GAAO;;;;8GACa,GAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAX3B,GAAK,IAAC,eAAe;;;;;;;;8BAgBzB,GAAK,IAAC,mBAAmB,CAAC,MAAM;;;;;;;;;;+BAS5B,GAAK,IAAC,gBAAgB;;;;;;kCA9ChC,GAAK,IAAC,mBAAmB;;;;sCAA9B,MAAI;;;;;oCAYE,GAAQ;;;;;oBAYf,GAAK,IAAC,mBAAmB,CAAC,MAAM,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;iBAHrC,gBAAc;;iBAAuB,GAAC;;;;;;iBAgBtC,YAAU;;kBAAkC,GAAC;;;;;;kBAS7C,gBAAc;;kBAAwB,GAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAjDrD,UAmDM;OAlDF,UAeM;OAdF,UAYM;;;;;;;;;OAGV,UAQM;OAPF,UAKE;;OACF,UAAmD;;;;;OAEvD,UAeM;;;OADF,UAA0D;;;;;OAE9D,UAQM;OAPF,UAKE;;OACF,UAAoD;;;;;;;;;;;;;;;;;iCA9CzC,GAAK,IAAC,mBAAmB;;;;qCAA9B,MAAI;;;;;;;;;;;;;;;;0CAAJ,MAAI;;;;oEAYE,GAAQ;;mFASC,GAAK,IAAC,eAAe;;;;;;;;;;;;;;mFAgBzB,GAAK,IAAC,mBAAmB,CAAC,MAAM;qFAS5B,GAAK,IAAC,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA1DpC,KAAK;WACL,QAAQ;;cAEV,IAAI,CAAC,OAAO;MACjB,OAAO,CAAC,GAAG,cAAc,OAAO;MAChC,GAAG,CAAC,IAAI,CAAC,OAAO;;;;;;;;;sCAagB,IAAI,CAAC,OAAO;mCAaxB,IAAI,CAAC,MAAM;mCAyBX,IAAI,CAAC,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OC5B7C,UAA4D;;OAC5D,UAAgD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAd3B,MAAM,WAAE,GAAI,IAAC,MAAM;SAAE,MAAM,WAAE,GAAI,IAAC,MAAM;;;;;;;gCAExC,GAAI,IAAC,MAAM;;;;;;wBACZ,GAAI,IAAC,KAAK;2BAAY,GAAI,IAAC,GAAG;;;;;+BAIvC,GAAI,IAAC,OAAO;;;;oCAAjB,MAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OATV,UAaO;OAZL,UAMM;;;OAJJ,UAGM;;;;;OAER,UAIM;;;;;;;;;;;;QAVa,MAAM,WAAE,GAAI,IAAC,MAAM;QAAE,MAAM,WAAE,GAAI,IAAC,MAAM;;;;;+DAExC,GAAI,IAAC,MAAM;;;8DACZ,GAAI,IAAC,KAAK;iEAAY,GAAI,IAAC,GAAG;;;;8BAIvC,GAAI,IAAC,OAAO;;;;mCAAjB,MAAI;;;;;;;;;;;;;;;;4BAAJ,MAAI;;;;;;;;;;;;;sCAAJ,MAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAVP,GAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SARH,IAAI;;;;MAER,GAAG,CAAC,SAAS,aAAa,KAAK;uBAC7B,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI;OAC5B,OAAO,CAAC,GAAG,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACTf,UAAC,GAAG,GAAG,IAAI,GAAG,CAAC;IACpB,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI;IACtB,CAAC;;;;;;;;"} \ No newline at end of file diff --git a/svelte/public/favicon.png b/svelte/public/favicon.png new file mode 100644 index 0000000..7e6f5eb Binary files /dev/null and b/svelte/public/favicon.png differ diff --git a/svelte/public/global.css b/svelte/public/global.css new file mode 100644 index 0000000..9bcba14 --- /dev/null +++ b/svelte/public/global.css @@ -0,0 +1,157 @@ +@import url('https://fonts.googleapis.com/css2?family=IM+Fell+English+SC&display=swap'); + +* { + box-sizing: border-box; +} + +html { + --col-BLEU: #205099; + --col-light-BLEU: #87BDE1; + --col-ROUGE: #D64036; + --col-light-ROUGE: #CC916C; + --col-VERT: #65964C; + --col-light-VERT: #C6E370; + --col-JAUNE: #C69943; + --col-light-JAUNE: #F6E678; + --col-ROSE: #5E3182; + --col-light-ROSE: #D89FDB; + --col-dark: #373F3B; +} + +html, body { + position: relative; + width: 100%; + height: 100%; +} + +body { + color: var(--col-dark); + margin: 0; + padding: 8px; + box-sizing: border-box; + font-family: "IM Fell English SC", serif; + background: #E1E5E7; +} + +a { + color: rgb(0, 100, 200); + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +a:visited { + color: rgb(0, 80, 160); +} + +label { + display: block; +} + +input, button, select, textarea { + font-family: inherit; + font-size: inherit; + -webkit-padding: 0.4em 0; + padding: 0.4em; + margin: 0 0 0.5em 0; + box-sizing: border-box; + border: 1px solid #ccc; + border-radius: 2px; +} + +input:disabled { + color: #ccc; +} + +button { + color: #333; + background-color: #f4f4f4; + outline: none; +} + +button:disabled { + color: #999; +} + +button:not(:disabled):active { + background-color: #ddd; +} + +button:focus { + border-color: #666; +} + +.column { + display: flex; + flex-direction: column; +} + +.row { + display: flex; + flex-direction: row; +} + +#log .tour { + margin-left: 100px; + font-weight: bold; + text-decoration: underline; +} + +#log .joueur { + font-weight: bold; +} + +#log .ville, #log .route { + font-style: italic; + font-weight: bold; +} + +#log .couleur { + text-decoration: underline; + text-decoration-thickness: 2px; + font-weight: bold; +} + +#log .couleur.rouge { + text-decoration-color: #be3c33; +} + +#log .couleur.vert { + text-decoration-color: #96c156; +} + +#log .couleur.bleu { + text-decoration-color: #489fd9; +} + +#log .couleur.jaune { + text-decoration-color: #fbe969; +} + +#log .couleur.orange { + text-decoration-color: #d58b44; +} + +#log .couleur.noir { + text-decoration-color: #3a4f59; +} + +#log .couleur.blanc { + text-decoration-color: #e8e9ec; +} + +#log .couleur.rose { + text-decoration-color: #b991bb; +} + +#log .couleur.gris { + text-decoration-color: #969b9d; +} + +img.couleur { + width: 1.5em; + height: 1.5em; + margin-bottom: -0.5em; +} \ No newline at end of file diff --git a/svelte/public/images/avatar-BLEU.png b/svelte/public/images/avatar-BLEU.png new file mode 100644 index 0000000..7a632ac Binary files /dev/null and b/svelte/public/images/avatar-BLEU.png differ diff --git a/svelte/public/images/avatar-JAUNE.png b/svelte/public/images/avatar-JAUNE.png new file mode 100644 index 0000000..fd76700 Binary files /dev/null and b/svelte/public/images/avatar-JAUNE.png differ diff --git a/svelte/public/images/avatar-ROSE.png b/svelte/public/images/avatar-ROSE.png new file mode 100644 index 0000000..4e3beef Binary files /dev/null and b/svelte/public/images/avatar-ROSE.png differ diff --git a/svelte/public/images/avatar-ROUGE.png b/svelte/public/images/avatar-ROUGE.png new file mode 100644 index 0000000..f7f47d8 Binary files /dev/null and b/svelte/public/images/avatar-ROUGE.png differ diff --git a/svelte/public/images/avatar-VERT.png b/svelte/public/images/avatar-VERT.png new file mode 100644 index 0000000..a2c3abb Binary files /dev/null and b/svelte/public/images/avatar-VERT.png differ diff --git a/svelte/public/images/carte-wagon-BLANC.png b/svelte/public/images/carte-wagon-BLANC.png new file mode 100644 index 0000000..bf428e1 Binary files /dev/null and b/svelte/public/images/carte-wagon-BLANC.png differ diff --git a/svelte/public/images/carte-wagon-BLEU.png b/svelte/public/images/carte-wagon-BLEU.png new file mode 100644 index 0000000..cedace0 Binary files /dev/null and b/svelte/public/images/carte-wagon-BLEU.png differ diff --git a/svelte/public/images/carte-wagon-JAUNE.png b/svelte/public/images/carte-wagon-JAUNE.png new file mode 100644 index 0000000..94df7a0 Binary files /dev/null and b/svelte/public/images/carte-wagon-JAUNE.png differ diff --git a/svelte/public/images/carte-wagon-LOCOMOTIVE.png b/svelte/public/images/carte-wagon-LOCOMOTIVE.png new file mode 100644 index 0000000..1331edd Binary files /dev/null and b/svelte/public/images/carte-wagon-LOCOMOTIVE.png differ diff --git a/svelte/public/images/carte-wagon-NOIR.png b/svelte/public/images/carte-wagon-NOIR.png new file mode 100644 index 0000000..1d02db8 Binary files /dev/null and b/svelte/public/images/carte-wagon-NOIR.png differ diff --git a/svelte/public/images/carte-wagon-ORANGE.png b/svelte/public/images/carte-wagon-ORANGE.png new file mode 100644 index 0000000..3cf4e9e Binary files /dev/null and b/svelte/public/images/carte-wagon-ORANGE.png differ diff --git a/svelte/public/images/carte-wagon-ROSE.png b/svelte/public/images/carte-wagon-ROSE.png new file mode 100644 index 0000000..b3d3999 Binary files /dev/null and b/svelte/public/images/carte-wagon-ROSE.png differ diff --git a/svelte/public/images/carte-wagon-ROUGE.png b/svelte/public/images/carte-wagon-ROUGE.png new file mode 100644 index 0000000..077a588 Binary files /dev/null and b/svelte/public/images/carte-wagon-ROUGE.png differ diff --git a/svelte/public/images/carte-wagon-VERT.png b/svelte/public/images/carte-wagon-VERT.png new file mode 100644 index 0000000..d4986a0 Binary files /dev/null and b/svelte/public/images/carte-wagon-VERT.png differ diff --git a/svelte/public/images/carte-wagon.png b/svelte/public/images/carte-wagon.png new file mode 100644 index 0000000..48c8027 Binary files /dev/null and b/svelte/public/images/carte-wagon.png differ diff --git a/svelte/public/images/destination.jpg b/svelte/public/images/destination.jpg new file mode 100644 index 0000000..f423eec Binary files /dev/null and b/svelte/public/images/destination.jpg differ diff --git a/svelte/public/images/dialogue-box_Big.png b/svelte/public/images/dialogue-box_Big.png new file mode 100644 index 0000000..441e047 Binary files /dev/null and b/svelte/public/images/dialogue-box_Big.png differ diff --git a/svelte/public/images/euMap.jpg b/svelte/public/images/euMap.jpg new file mode 100644 index 0000000..d56f21f Binary files /dev/null and b/svelte/public/images/euMap.jpg differ diff --git a/svelte/public/images/eu_TicketBack.png b/svelte/public/images/eu_TicketBack.png new file mode 100644 index 0000000..f17d34d Binary files /dev/null and b/svelte/public/images/eu_TicketBack.png differ diff --git a/svelte/public/images/gare-BLEU.png b/svelte/public/images/gare-BLEU.png new file mode 100644 index 0000000..370502c Binary files /dev/null and b/svelte/public/images/gare-BLEU.png differ diff --git a/svelte/public/images/gare-JAUNE.png b/svelte/public/images/gare-JAUNE.png new file mode 100644 index 0000000..c0ad45e Binary files /dev/null and b/svelte/public/images/gare-JAUNE.png differ diff --git a/svelte/public/images/gare-ROSE.png b/svelte/public/images/gare-ROSE.png new file mode 100644 index 0000000..6300ac2 Binary files /dev/null and b/svelte/public/images/gare-ROSE.png differ diff --git a/svelte/public/images/gare-ROUGE.png b/svelte/public/images/gare-ROUGE.png new file mode 100644 index 0000000..5efac81 Binary files /dev/null and b/svelte/public/images/gare-ROUGE.png differ diff --git a/svelte/public/images/gare-VERT.png b/svelte/public/images/gare-VERT.png new file mode 100644 index 0000000..a227f6f Binary files /dev/null and b/svelte/public/images/gare-VERT.png differ diff --git a/svelte/public/images/gare-shadow.png b/svelte/public/images/gare-shadow.png new file mode 100644 index 0000000..82d3a85 Binary files /dev/null and b/svelte/public/images/gare-shadow.png differ diff --git a/svelte/public/images/image-wagon-BLEU.png b/svelte/public/images/image-wagon-BLEU.png new file mode 100644 index 0000000..ab13880 Binary files /dev/null and b/svelte/public/images/image-wagon-BLEU.png differ diff --git a/svelte/public/images/image-wagon-JAUNE.png b/svelte/public/images/image-wagon-JAUNE.png new file mode 100644 index 0000000..171920b Binary files /dev/null and b/svelte/public/images/image-wagon-JAUNE.png differ diff --git a/svelte/public/images/image-wagon-ROSE.png b/svelte/public/images/image-wagon-ROSE.png new file mode 100644 index 0000000..928ff68 Binary files /dev/null and b/svelte/public/images/image-wagon-ROSE.png differ diff --git a/svelte/public/images/image-wagon-ROUGE.png b/svelte/public/images/image-wagon-ROUGE.png new file mode 100644 index 0000000..79c6bc2 Binary files /dev/null and b/svelte/public/images/image-wagon-ROUGE.png differ diff --git a/svelte/public/images/image-wagon-VERT.png b/svelte/public/images/image-wagon-VERT.png new file mode 100644 index 0000000..e86de7f Binary files /dev/null and b/svelte/public/images/image-wagon-VERT.png differ diff --git a/svelte/public/images/symbole-BLANC.png b/svelte/public/images/symbole-BLANC.png new file mode 100644 index 0000000..cb9c59c Binary files /dev/null and b/svelte/public/images/symbole-BLANC.png differ diff --git a/svelte/public/images/symbole-BLEU.png b/svelte/public/images/symbole-BLEU.png new file mode 100644 index 0000000..8baadf8 Binary files /dev/null and b/svelte/public/images/symbole-BLEU.png differ diff --git a/svelte/public/images/symbole-JAUNE.png b/svelte/public/images/symbole-JAUNE.png new file mode 100644 index 0000000..2ae0758 Binary files /dev/null and b/svelte/public/images/symbole-JAUNE.png differ diff --git a/svelte/public/images/symbole-LOCOMOTIVE.png b/svelte/public/images/symbole-LOCOMOTIVE.png new file mode 100644 index 0000000..968e451 Binary files /dev/null and b/svelte/public/images/symbole-LOCOMOTIVE.png differ diff --git a/svelte/public/images/symbole-NOIR.png b/svelte/public/images/symbole-NOIR.png new file mode 100644 index 0000000..9ba9e97 Binary files /dev/null and b/svelte/public/images/symbole-NOIR.png differ diff --git a/svelte/public/images/symbole-ORANGE.png b/svelte/public/images/symbole-ORANGE.png new file mode 100644 index 0000000..fc535bc Binary files /dev/null and b/svelte/public/images/symbole-ORANGE.png differ diff --git a/svelte/public/images/symbole-ROSE.png b/svelte/public/images/symbole-ROSE.png new file mode 100644 index 0000000..55fd740 Binary files /dev/null and b/svelte/public/images/symbole-ROSE.png differ diff --git a/svelte/public/images/symbole-ROUGE.png b/svelte/public/images/symbole-ROUGE.png new file mode 100644 index 0000000..207f531 Binary files /dev/null and b/svelte/public/images/symbole-ROUGE.png differ diff --git a/svelte/public/images/symbole-VERT.png b/svelte/public/images/symbole-VERT.png new file mode 100644 index 0000000..1394fe9 Binary files /dev/null and b/svelte/public/images/symbole-VERT.png differ diff --git a/svelte/public/images/toggle-button.png b/svelte/public/images/toggle-button.png new file mode 100644 index 0000000..8a9248f Binary files /dev/null and b/svelte/public/images/toggle-button.png differ diff --git a/svelte/public/index.html b/svelte/public/index.html new file mode 100644 index 0000000..91ee6f2 --- /dev/null +++ b/svelte/public/index.html @@ -0,0 +1,18 @@ + + + + + + + Svelte app + + + + + + + + + + + diff --git a/svelte/rollup.config.js b/svelte/rollup.config.js new file mode 100644 index 0000000..12caf41 --- /dev/null +++ b/svelte/rollup.config.js @@ -0,0 +1,76 @@ +import svelte from 'rollup-plugin-svelte'; +import commonjs from '@rollup/plugin-commonjs'; +import resolve from '@rollup/plugin-node-resolve'; +import livereload from 'rollup-plugin-livereload'; +import { terser } from 'rollup-plugin-terser'; +import css from 'rollup-plugin-css-only'; + +const production = !process.env.ROLLUP_WATCH; + +function serve() { + let server; + + function toExit() { + if (server) server.kill(0); + } + + return { + writeBundle() { + if (server) return; + server = require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], { + stdio: ['ignore', 'inherit', 'inherit'], + shell: true + }); + + process.on('SIGTERM', toExit); + process.on('exit', toExit); + } + }; +} + +export default { + input: 'src/main.js', + output: { + sourcemap: true, + format: 'iife', + name: 'app', + file: 'public/bundle.js' + }, + plugins: [ + svelte({ + compilerOptions: { + // enable run-time checks when not in production + dev: !production + } + }), + // we'll extract any component CSS out into + // a separate file - better for performance + css({ output: 'bundle.css' }), + + // If you have external dependencies installed from + // npm, you'll most likely need these plugins. In + // some cases you'll need additional configuration - + // consult the documentation for details: + // https://github.com/rollup/plugins/tree/master/packages/commonjs + resolve({ + browser: true, + dedupe: ['svelte'] + }), + commonjs(), + + // In dev mode, call `npm run start` once + // the bundle has been generated + !production && serve(), + + // Watch the `public` directory and refresh the + // browser on changes when not in production + !production && livereload('public'), + + // If we're building for production (npm run build + // instead of npm run dev), minify + production && terser() + ], + watch: { + clearScreen: false + } +}; diff --git a/svelte/scripts/setupTypeScript.js b/svelte/scripts/setupTypeScript.js new file mode 100644 index 0000000..133658a --- /dev/null +++ b/svelte/scripts/setupTypeScript.js @@ -0,0 +1,121 @@ +// @ts-check + +/** This script modifies the project to support TS code in .svelte files like: + + + + As well as validating the code for CI. + */ + +/** To work on this script: + rm -rf test-template template && git clone sveltejs/template test-template && node scripts/setupTypeScript.js test-template +*/ + +const fs = require("fs") +const path = require("path") +const { argv } = require("process") + +const projectRoot = argv[2] || path.join(__dirname, "..") + +// Add deps to pkg.json +const packageJSON = JSON.parse(fs.readFileSync(path.join(projectRoot, "package.json"), "utf8")) +packageJSON.devDependencies = Object.assign(packageJSON.devDependencies, { + "svelte-check": "^2.0.0", + "svelte-preprocess": "^4.0.0", + "@rollup/plugin-typescript": "^8.0.0", + "typescript": "^4.0.0", + "tslib": "^2.0.0", + "@tsconfig/svelte": "^2.0.0" +}) + +// Add script for checking +packageJSON.scripts = Object.assign(packageJSON.scripts, { + "check": "svelte-check --tsconfig ./tsconfig.json" +}) + +// Write the package JSON +fs.writeFileSync(path.join(projectRoot, "package.json"), JSON.stringify(packageJSON, null, " ")) + +// mv src/main.js to main.ts - note, we need to edit rollup.config.js for this too +const beforeMainJSPath = path.join(projectRoot, "src", "main.js") +const afterMainTSPath = path.join(projectRoot, "src", "main.ts") +fs.renameSync(beforeMainJSPath, afterMainTSPath) + +// Switch the app.svelte file to use TS +const appSveltePath = path.join(projectRoot, "src", "App.svelte") +let appFile = fs.readFileSync(appSveltePath, "utf8") +appFile = appFile.replace(" + +{#if data} +
+
+ +
+ + +
+
+
+ {#each data.joueurs as props} + + {/each} +
+
+{:else} +

La connexion avec le serveur n'a pas pu être établie.

+

Démarrez le serveur et rechargez la page.

+{/if} + + diff --git a/svelte/src/Joueur.svelte b/svelte/src/Joueur.svelte new file mode 100644 index 0000000..42430b4 --- /dev/null +++ b/svelte/src/Joueur.svelte @@ -0,0 +1,148 @@ + + +
+
+ avatar {props.couleur} +
+ {props.nom} +
Score: {props.score}
+
Gares: {props.nbGares}
+
Wagons: {props.nbWagons}
+
+
+
+
+ {#each props.destinations as destination} +
send(destination.nom)} + > + {destination.ville1} - {destination.ville2} ({destination.valeur}) +
+ {/each} +
+
+ {#each props.cartesWagon as wagon} +
send(wagon)} + > +
+
+ {/each} +
+
+ {#each props.cartesWagonPosees as wagon} +
+
+
+
+ {/each} +
+
+
+ + diff --git a/svelte/src/Log.svelte b/svelte/src/Log.svelte new file mode 100644 index 0000000..c9850c9 --- /dev/null +++ b/svelte/src/Log.svelte @@ -0,0 +1,42 @@ + + +
+
+ {#each lines as line} +
{@html line}
+ {/each} +
+
+ + diff --git a/svelte/src/Piles.svelte b/svelte/src/Piles.svelte new file mode 100644 index 0000000..dab2d7c --- /dev/null +++ b/svelte/src/Piles.svelte @@ -0,0 +1,109 @@ + + +
+
+
+ {#each props.cartesWagonVisibles as couleur} +
+ {couleur} send(couleur)} + /> + {couleur[0] + couleur.slice(1).toLowerCase()} +
+ {/each} +
+ +
+
+ wagon send("GRIS")} + /> + Cartes wagon ({props.pileCartesWagon}) +
+
+ {#if props.defausseCartesWagon.length === 0} +
+ {:else} +
+ {#each props.defausseCartesWagon.slice(-15) as couleur} + {couleur} + {/each} +
+ {/if} + Défausse ({props.defausseCartesWagon.length}) +
+
+ destinations send("destinations")} + /> + Destinations ({props.pileDestinations}) +
+
+ + diff --git a/svelte/src/Plateau.svelte b/svelte/src/Plateau.svelte new file mode 100644 index 0000000..b5e6f4f --- /dev/null +++ b/svelte/src/Plateau.svelte @@ -0,0 +1,213 @@ + + + + + {#each routes as route} + send(route.label)} + > + {#each route.segments as segment, i} + + + + {/each} + + {/each} + + + {#each villes as ville} + send(ville.nom)} + > + + + {/each} + + + + + + {#each routes as route} + + {#each route.segments as segment, i} + {#if route.proprietaire !== undefined} + + + + {/if} + {/each} + + {/each} + + + {#each villes as ville} + {#if ville.proprietaire !== undefined} + + + + + {/if} + {/each} + + + + + + + \ No newline at end of file diff --git a/svelte/src/Prompt.svelte b/svelte/src/Prompt.svelte new file mode 100644 index 0000000..97dc334 --- /dev/null +++ b/svelte/src/Prompt.svelte @@ -0,0 +1,36 @@ + + +
+
+ {props.nomJoueurCourant}: + {props.instruction} +
+
+ {#each props.boutons as bouton} + + {/each} + {#if props.peutPasser} + + {:else} + + {/if} +
+
+ + diff --git a/svelte/src/main.js b/svelte/src/main.js new file mode 100644 index 0000000..d80e9a3 --- /dev/null +++ b/svelte/src/main.js @@ -0,0 +1,7 @@ +import App from './App.svelte'; + +const app = new App({ + target: document.body, +}); + +export default app; \ No newline at end of file diff --git a/svelte/src/plateau_data.js b/svelte/src/plateau_data.js new file mode 100644 index 0000000..cacfd8f --- /dev/null +++ b/svelte/src/plateau_data.js @@ -0,0 +1,153 @@ +export const villesData = { + "Cadiz": { "x": 144, "y": 1072, "nom": "Cadiz" }, + "Madrid": { "x": 147, "y": 946, "nom": "Madrid" }, + "Barcelona": { "x": 336, "y": 961, "nom": "Barcelona" }, + "Lisboa": { "x": 32, "y": 981, "nom": "Lisboa" }, + "Pamplona": { "x": 318, "y": 805, "nom": "Pamplona" }, + "Paris": { "x": 425, "y": 544, "nom": "Paris" }, + "Dieppe": { "x": 341, "y": 467, "nom": "Dieppe" }, + "Brest": { "x": 188, "y": 516, "nom": "Brest" }, + "London": { "x": 358, "y": 313, "nom": "London" }, + "Amsterdam": { "x": 524, "y": 319, "nom": "Amsterdam" }, + "Bruxelles": { "x": 485, "y": 399, "nom": "Bruxelles" }, + "Edinburgh": { "x": 245, "y": 56, "nom": "Edinburgh" }, + "Zurich": { "x": 622, "y": 638, "nom": "Zurich" }, + "Marseille": { "x": 575, "y": 797, "nom": "Marseille" }, + "Frankfurt": { "x": 638, "y": 454, "nom": "Frankfurt" }, + "Munchen": { "x": 737, "y": 530, "nom": "Munchen" }, + "Wien": { "x": 930, "y": 559, "nom": "Wien" }, + "Venezia": { "x": 763, "y": 694, "nom": "Venezia" }, + "Roma": { "x": 779, "y": 849, "nom": "Roma" }, + "Brindisi": { "x": 925, "y": 892, "nom": "Brindisi" }, + "Palermo": { "x": 841, "y": 1072, "nom": "Palermo" }, + "Athina": { "x": 1136, "y": 1024, "nom": "Athina" }, + "Sofia": { "x": 1167, "y": 830, "nom": "Sofia" }, + "Sarajevo": { "x": 1053, "y": 815, "nom": "Sarajevo" }, + "Zagrab": { "x": 908, "y": 714, "nom": "Zagrab" }, + "Budapest": { "x": 1014, "y": 602, "nom": "Budapest" }, + "Kyiv": { "x": 1370, "y": 438, "nom": "Kyiv" }, + "Warszawa": { "x": 1113, "y": 345, "nom": "Warszawa" }, + "Wilno": { "x": 1302, "y": 303, "nom": "Wilno" }, + "Smolensk": { "x": 1479, "y": 310, "nom": "Smolensk" }, + "Moskva": { "x": 1625, "y": 269, "nom": "Moskva" }, + "Kharkov": { "x": 1600, "y": 528, "nom": "Kharkov" }, + "Rostov": { "x": 1671, "y": 618, "nom": "Rostov" }, + "Sochi": { "x": 1660, "y": 770, "nom": "Sochi" }, + "Erzurum": { "x": 1628, "y": 986, "nom": "Erzurum" }, + "Constantinople": { "x": 1358, "y": 932, "nom": "Constantinople" }, + "Angora": { "x": 1492, "y": 1026, "nom": "Angora" }, + "Smyrna": { "x": 1282, "y": 1068, "nom": "Smyrna" }, + "Essen": { "x": 663, "y": 335, "nom": "Essen" }, + "Berlin": { "x": 834, "y": 359, "nom": "Berlin" }, + "Kobenhavn": { "x": 784, "y": 155, "nom": "Kobenhavn" }, + "Stockholm": { "x": 963, "y": 22, "nom": "Stockholm" }, + "Riga": { "x": 1169, "y": 71, "nom": "Riga" }, + "Petrograd": { "x": 1458, "y": 64, "nom": "Petrograd" }, + "Danzig": { "x": 1028, "y": 226, "nom": "Danzig" }, + "Bucuresti": { "x": 1271, "y": 721, "nom": "Bucuresti" }, + "Sevastopol": { "x": 1508, "y": 746, "nom": "Sevastopol" } +}; + +export const routesData = { + { "ville1": "Amsterdam", "ville2": "Bruxelles", "longueur": 1, "couleur": "NOIR", "isTunnel": false, "ferry": 0, "segments": [{ "x": 504.5, "y": 361.5, "dx": -0.42661867571297646, "dy": 0.9044315925115101 }] }, + { "ville1": "Amsterdam", "ville2": "Essen", "longueur": 3, "couleur": "JAUNE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 528.5, "y": 276, "dx": 0.21871145691738075, "dy": -0.9757895770160064 }, { "x": 574, "y": 265, "dx": 0.9778024140774094, "dy": 0.20952908873087345 }, { "x": 629, "y": 300, "dx": 0.6368814469962913, "dy": 0.7709617516270895 }] }, + { "ville1": "Amsterdam", "ville2": "Frankfurt", "longueur": 2, "couleur": "BLANC", "isTunnel": false, "ferry": 0, "segments": [{ "x": 562, "y": 358.5, "dx": 0.6983238520753277, "dy": 0.7157819483772108 }, { "x": 606, "y": 403, "dx": 0.7249994335944138, "dy": 0.688749461914693 }] }, + { "ville1": "Amsterdam", "ville2": "London", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 2, "segments": [{ "x": 405, "y": 312, "dx": 1, "dy": 0 }, { "x": 469, "y": 314.5, "dx": 0.9998514005489976, "dy": 0.017238817250844786 }] }, + { "ville1": "Angora", "ville2": "Constantinople", "longueur": 2, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 1399, "y": 959, "dx": 0.8209052017854871, "dy": 0.5710644881985998 }, { "x": 1452, "y": 998, "dx": 0.8041761414663255, "dy": 0.5943910610838058 }] }, + { "ville1": "Angora", "ville2": "Erzurum", "longueur": 3, "couleur": "NOIR", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1533.5, "y": 1046, "dx": 0.8765785507795943, "dy": 0.48125881219271843 }, { "x": 1597, "y": 1059.5, "dx": 0.9812488205210874, "dy": -0.19274530403092788 }, { "x": 1635.5, "y": 1031.5, "dx": -0.16148856811054085, "dy": -0.9868745828977495 }] }, + { "ville1": "Angora", "ville2": "Smyrna", "longueur": 3, "couleur": "ORANGE", "isTunnel": true, "ferry": 0, "segments": [{ "x": 1329.5, "y": 1072.5, "dx": 0.9998347517133227, "dy": 0.01817881366751496 }, { "x": 1392.5, "y": 1072, "dx": 0.9895864392845114, "dy": -0.14393984571411075 }, { "x": 1455.5, "y": 1054, "dx": 0.8765785507795943, "dy": -0.48125881219271843 }] }, + { "ville1": "Athina", "ville2": "Brindisi", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 1, "segments": [{ "x": 957, "y": 928, "dx": 0.389639990836698, "dy": 0.9209672510685588 }, { "x": 982, "y": 986.5, "dx": 0.38337767164151665, "dy": 0.9235916635000174 }, { "x": 1027.5, "y": 1030.5, "dx": 0.9554026409829016, "dy": 0.2953062708492605 }, { "x": 1093.5, "y": 1036, "dx": 0.9838699100999074, "dy": -0.17888543819998318 }] }, + { "ville1": "Athina", "ville2": "Sarajevo", "longueur": 4, "couleur": "VERT", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1052.5, "y": 859, "dx": -0.053494721371611896, "dy": 0.9985681322700888 }, { "x": 1049, "y": 922.5, "dx": -0.035066140133044446, "dy": 0.9993849937917667 }, { "x": 1045.5, "y": 986.5, "dx": -0.08444307668618062, "dy": 0.9964283048969312 }, { "x": 1087.5, "y": 1007, "dx": 0.9994259471398348, "dy": 0.033878845665757114 }] }, + { "ville1": "Athina", "ville2": "Smyrna", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 1, "segments": [{ "x": 1180.5, "y": 1022, "dx": 0.9994259471398348, "dy": -0.033878845665757114 }, { "x": 1244.5, "y": 1036.5, "dx": 0.9044315925115101, "dy": 0.42661867571297646 }] }, + { "ville1": "Athina", "ville2": "Sofia", "longueur": 3, "couleur": "ROSE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1136, "y": 861, "dx": -0.6709133239691262, "dy": 0.7415357791237711 }, { "x": 1109.5, "y": 921, "dx": -0.11982016019085814, "dy": 0.9927956130099675 }, { "x": 1123, "y": 983, "dx": 0.52999894000318, "dy": 0.847998304005088 }] }, + { "ville1": "Barcelona", "ville2": "Madrid", "longueur": 2, "couleur": "JAUNE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 221.5, "y": 954.5, "dx": 0.9998563940539735, "dy": 0.016946718543287685 }, { "x": 285.5, "y": 956.5, "dx": 0.9986178293325098, "dy": 0.052558833122763673 }] }, + { "ville1": "Barcelona", "ville2": "Marseille", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 370.5, "y": 926, "dx": 0.6610305430689966, "dy": -0.7503589948350772 }, { "x": 415.5, "y": 881.5, "dx": 0.7407190347407712, "dy": -0.6718149384858157 }, { "x": 467.5, "y": 843.5, "dx": 0.8692901189279536, "dy": -0.4943022244884442 }, { "x": 525, "y": 818, "dx": 0.9377487607237036, "dy": -0.34731435582359393 }] }, + { "ville1": "Barcelona", "ville2": "Pamplona", "longueur": 2, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 322.5, "y": 852.5, "dx": 0.09053574604251853, "dy": 0.9958932064677039 }, { "x": 329.5, "y": 917.5, "dx": 0.11781773987828967, "dy": 0.9930352361170129 }] }, + { "ville1": "Berlin", "ville2": "Danzig", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 842.5, "y": 306.5, "dx": 0.1559625734730109, "dy": -0.987762965329069 }, { "x": 867.5, "y": 246.5, "dx": 0.5746304214759497, "dy": -0.8184130245263527 }, { "x": 922.5, "y": 210, "dx": 0.978549784986749, "dy": -0.2060104810498419 }, { "x": 987, "y": 210, "dx": 0.9778024140774094, "dy": 0.20952908873087345 }] }, + { "ville1": "Berlin", "ville2": "Essen", "longueur": 2, "couleur": "BLEU", "isTunnel": false, "ferry": 0, "segments": [{ "x": 726.5, "y": 331.5, "dx": 0.9925434552766405, "dy": 0.12189130152520146 }, { "x": 789.5, "y": 339, "dx": 0.9945054529214061, "dy": 0.10468478451804275 }] }, + { "ville1": "Berlin", "ville2": "Frankfurt", "longueur": 3, "couleur": "ROUGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 686.5, "y": 452.5, "dx": 0.9173450110960782, "dy": -0.3980931180228264 }, { "x": 743, "y": 424.5, "dx": 0.9012524245251862, "dy": -0.43329443486787794 }, { "x": 800, "y": 397.5, "dx": 0.9012524245251862, "dy": -0.43329443486787794 }] }, + { "ville1": "Berlin", "ville2": "Frankfurt", "longueur": 3, "couleur": "NOIR", "isTunnel": false, "ferry": 0, "segments": [{ "x": 676, "y": 432.5, "dx": 0.9012524245251862, "dy": -0.43329443486787794 }, { "x": 734, "y": 405.5, "dx": 0.9084904526785746, "dy": -0.41790560823214434 }, { "x": 790.5, "y": 378, "dx": 0.8909061469019802, "dy": -0.4541874474402252 }] }, + { "ville1": "Berlin", "ville2": "Warszawa", "longueur": 4, "couleur": "JAUNE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 877, "y": 365.5, "dx": 0.9469787003150827, "dy": -0.3212963447497602 }, { "x": 940, "y": 350.5, "dx": 0.988173903359179, "dy": -0.15333732983159673 }, { "x": 1003, "y": 347, "dx": 0.9993628543475496, "dy": -0.03569153051241249 }, { "x": 1065.5, "y": 350.5, "dx": 0.987762965329069, "dy": 0.1559625734730109 }] }, + { "ville1": "Berlin", "ville2": "Warszawa", "longueur": 4, "couleur": "ROSE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 875.5, "y": 341.5, "dx": 0.9486832980505138, "dy": -0.31622776601683794 }, { "x": 939.5, "y": 326.5, "dx": 0.9925434552766405, "dy": -0.12189130152520146 }, { "x": 1002, "y": 322, "dx": 0.9994059993535875, "dy": -0.03446227583977888 }, { "x": 1067, "y": 327, "dx": 0.9906211292434748, "dy": 0.13663739713703102 }] }, + { "ville1": "Berlin", "ville2": "Wien", "longueur": 3, "couleur": "VERT", "isTunnel": false, "ferry": 0, "segments": [{ "x": 847, "y": 408.5, "dx": 0.2890045919356118, "dy": 0.9573277107867141 }, { "x": 870.5, "y": 467, "dx": 0.47514891473488396, "dy": 0.8799053976571926 }, { "x": 906, "y": 520.5, "dx": 0.6246950475544243, "dy": 0.7808688094430304 }] }, + { "ville1": "Brest", "ville2": "Dieppe", "longueur": 2, "couleur": "ORANGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 225, "y": 482.5, "dx": 0.8650311892618034, "dy": -0.501718089771846 }, { "x": 287.5, "y": 464, "dx": 0.9977097021176764, "dy": -0.06764133573679162 }] }, + { "ville1": "Brest", "ville2": "Pamplona", "longueur": 4, "couleur": "ROSE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 229.5, "y": 549.5, "dx": 0.9342183861793726, "dy": 0.3567015656321241 }, { "x": 280, "y": 591, "dx": 0.5547001962252291, "dy": 0.8320502943378437 }, { "x": 302, "y": 652, "dx": 0.1414213562373095, "dy": 0.9899494936611665 }, { "x": 306, "y": 716, "dx": 0, "dy": 1 }] }, + { "ville1": "Brest", "ville2": "Paris", "longueur": 3, "couleur": "NOIR", "isTunnel": false, "ferry": 0, "segments": [{ "x": 235, "y": 521, "dx": 0.9946917938265513, "dy": 0.1028991510855053 }, { "x": 298.5, "y": 529, "dx": 0.9945054529214061, "dy": 0.10468478451804275 }, { "x": 360.5, "y": 536.5, "dx": 0.9964283048969312, "dy": 0.08444307668618062 }] }, + { "ville1": "Brindisi", "ville2": "Palermo", "longueur": 3, "couleur": "GRIS", "isTunnel": false, "ferry": 1, "segments": [{ "x": 880.5, "y": 1047.5, "dx": 0.6139406135149205, "dy": -0.7893522173763263 }, { "x": 923, "y": 998.5, "dx": 0.7327934916262993, "dy": -0.6804510993672779 }, { "x": 936.5, "y": 937, "dx": -0.40450601477770304, "dy": -0.9145353377582851 }] }, + { "ville1": "Brindisi", "ville2": "Roma", "longueur": 2, "couleur": "BLANC", "isTunnel": false, "ferry": 0, "segments": [{ "x": 832.5, "y": 833, "dx": 0.9902939771518443, "dy": -0.13898862837218867 }, { "x": 892.5, "y": 856, "dx": 0.6610305430689966, "dy": 0.7503589948350772 }] }, + { "ville1": "Bruxelles", "ville2": "Dieppe", "longueur": 2, "couleur": "VERT", "isTunnel": false, "ferry": 0, "segments": [{ "x": 387, "y": 447.5, "dx": 0.8346094065617252, "dy": -0.5508422083307386 }, { "x": 440, "y": 411, "dx": 0.8041761414663255, "dy": -0.5943910610838058 }] }, + { "ville1": "Bruxelles", "ville2": "Frankfurt", "longueur": 2, "couleur": "BLEU", "isTunnel": false, "ferry": 0, "segments": [{ "x": 528.5, "y": 403, "dx": 0.9690971739229421, "dy": -0.24667928063493072 }, { "x": 590.5, "y": 420, "dx": 0.7321867381630838, "dy": 0.6811039424772872 }] }, + { "ville1": "Bruxelles", "ville2": "Paris", "longueur": 2, "couleur": "JAUNE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 432.5, "y": 495, "dx": 0.47312663795681303, "dy": -0.8809944292988933 }, { "x": 462.5, "y": 439, "dx": 0.43329443486787794, "dy": -0.9012524245251862 }] }, + { "ville1": "Bruxelles", "ville2": "Paris", "longueur": 2, "couleur": "ROUGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 452.5, "y": 505.5, "dx": 0.4678877204190327, "dy": -0.8837879163470618 }, { "x": 482.5, "y": 449.5, "dx": 0.4678877204190327, "dy": -0.8837879163470618 }] }, + { "ville1": "Bucuresti", "ville2": "Budapest", "longueur": 4, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 1058, "y": 613.5, "dx": 0.8944271909999159, "dy": 0.4472135954999579 }, { "x": 1114.5, "y": 644, "dx": 0.8833490206949295, "dy": 0.46871580689935033 }, { "x": 1170, "y": 674, "dx": 0.8872168012345951, "dy": 0.46135273664198945 }, { "x": 1227, "y": 703.5, "dx": 0.8944271909999159, "dy": 0.4472135954999579 }] }, + { "ville1": "Bucuresti", "ville2": "Constantinople", "longueur": 3, "couleur": "JAUNE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1289.5, "y": 766, "dx": 0.40450601477770304, "dy": 0.9145353377582851 }, { "x": 1314.5, "y": 824, "dx": 0.39186206512519167, "dy": 0.9200239789895804 }, { "x": 1339, "y": 882, "dx": 0.4061384660534476, "dy": 0.9138115486202572 }] }, + { "ville1": "Bucuresti", "ville2": "Kyiv", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1337, "y": 492, "dx": -0.284088329691374, "dy": 0.9587981127083872 }, { "x": 1317.5, "y": 552, "dx": -0.343192952923539, "dy": 0.9392649237907383 }, { "x": 1298, "y": 612.5, "dx": -0.3215824263578902, "dy": 0.9468815887204546 }, { "x": 1278, "y": 672, "dx": -0.3271105638831663, "dy": 0.9449860734402582 }] }, + { "ville1": "Bucuresti", "ville2": "Sevastopol", "longueur": 4, "couleur": "BLANC", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1307.5, "y": 690.5, "dx": 0.7071067811865476, "dy": -0.7071067811865476 }, { "x": 1365, "y": 657.5, "dx": 0.965948051503245, "dy": -0.2587360852240835 }, { "x": 1430.5, "y": 665, "dx": 0.9040722665053037, "dy": 0.4273796168934163 }, { "x": 1480.5, "y": 705, "dx": 0.6055218324832624, "dy": 0.7958286941208591 }] }, + { "ville1": "Bucuresti", "ville2": "Sofia", "longueur": 2, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 1209.5, "y": 809.5, "dx": 0.9582877607731983, "dy": -0.28580512163411176 }, { "x": 1250, "y": 762.5, "dx": 0.13436367297357807, "dy": -0.9909320881801382 }] }, + { "ville1": "Budapest", "ville2": "Kyiv", "longueur": 6, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 1037.5, "y": 561, "dx": 0.6633075143158518, "dy": -0.7483469392281404 }, { "x": 1084, "y": 518, "dx": 0.8209052017854871, "dy": -0.5710644881985998 }, { "x": 1139, "y": 483.5, "dx": 0.8799053976571926, "dy": -0.47514891473488396 }, { "x": 1197.5, "y": 459, "dx": 0.9468815887204546, "dy": -0.3215824263578902 }, { "x": 1260, "y": 446, "dx": 0.9974586998307351, "dy": -0.07124704998790965 }, { "x": 1324, "y": 446.5, "dx": 0.9998405993454448, "dy": 0.017854296416882943 }] }, + { "ville1": "Budapest", "ville2": "Sarajevo", "longueur": 3, "couleur": "ROSE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1026, "y": 646.5, "dx": 0.14393984571411075, "dy": 0.9895864392845114 }, { "x": 1035, "y": 709, "dx": 0.1757906384836575, "dy": 0.984427575508482 }, { "x": 1044.5, "y": 772, "dx": 0.12403473458920845, "dy": 0.9922778767136676 }] }, + { "ville1": "Budapest", "ville2": "Wien", "longueur": 1, "couleur": "ROUGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 973.5, "y": 578, "dx": 0.8528513040762654, "dy": 0.5221538596385299 }] }, + { "ville1": "Budapest", "ville2": "Wien", "longueur": 1, "couleur": "BLANC", "isTunnel": false, "ferry": 0, "segments": [{ "x": 962, "y": 596, "dx": 0.8574929257125442, "dy": 0.5144957554275266 }] }, + { "ville1": "Budapest", "ville2": "Zagrab", "longueur": 2, "couleur": "ORANGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 987.5, "y": 639, "dx": -0.501718089771846, "dy": 0.8650311892618034 }, { "x": 946.5, "y": 689.5, "dx": -0.7724254859909581, "dy": 0.6351053995925655 }] }, + { "ville1": "Cadiz", "ville2": "Lisboa", "longueur": 2, "couleur": "BLEU", "isTunnel": false, "ferry": 0, "segments": [{ "x": 50, "y": 1025.5, "dx": 0.4125075533080444, "dy": 0.9109541802219313 }, { "x": 100, "y": 1063.5, "dx": 0.9812488205210874, "dy": 0.19274530403092788 }] }, + { "ville1": "Cadiz", "ville2": "Madrid", "longueur": 3, "couleur": "ORANGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 189, "y": 1062, "dx": 0.9377487607237036, "dy": -0.34731435582359393 }, { "x": 222.5, "y": 1027.5, "dx": -0.3265202527980472, "dy": -0.9451902054680315 }, { "x": 184.5, "y": 976, "dx": -0.7493290854811462, "dy": -0.6621977964717106 }] }, + { "ville1": "Constantinople", "ville2": "Sevastopol", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 2, "segments": [{ "x": 1490.5, "y": 791.5, "dx": -0.017541160386140585, "dy": 0.9998461420100133 }, { "x": 1471, "y": 852.5, "dx": -0.5795237863600037, "dy": 0.8149553245687551 }, { "x": 1428.5, "y": 874, "dx": -0.7938781460016401, "dy": -0.6080768777884903 }, { "x": 1386.5, "y": 896.5, "dx": -0.6139406135149205, "dy": 0.7893522173763263 }] }, + { "ville1": "Constantinople", "ville2": "Smyrna", "longueur": 2, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 1301.5, "y": 1026.5, "dx": 0.42661867571297646, "dy": -0.9044315925115101 }, { "x": 1330.5, "y": 968.5, "dx": 0.41110775310681835, "dy": -0.911586756889032 }] }, + { "ville1": "Constantinople", "ville2": "Sofia", "longueur": 3, "couleur": "BLEU", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1206, "y": 853, "dx": 0.8725060159497201, "dy": 0.48860336893184325 }, { "x": 1262, "y": 883, "dx": 0.879291966536774, "dy": 0.4762831485407526 }, { "x": 1317, "y": 913.5, "dx": 0.8650311892618034, "dy": 0.501718089771846 }] }, + { "ville1": "Danzig", "ville2": "Riga", "longueur": 3, "couleur": "NOIR", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1041.5, "y": 182.5, "dx": 0.27232246579934893, "dy": -0.9622060458243663 }, { "x": 1071, "y": 125.5, "dx": 0.6028330891856919, "dy": -0.7978673239222394 }, { "x": 1123.5, "y": 89, "dx": 0.9503971290446889, "dy": -0.3110390604146254 }] }, + { "ville1": "Danzig", "ville2": "Warszawa", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1068, "y": 247, "dx": 0.847998304005088, "dy": 0.52999894000318 }, { "x": 1103.5, "y": 299, "dx": 0.22612970719934952, "dy": 0.9740972002433518 }] }, + { "ville1": "Dieppe", "ville2": "London", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 1, "segments": [{ "x": 330.5, "y": 419.5, "dx": -0.08738374771484403, "dy": 0.9961747239492219 }, { "x": 336.5, "y": 358, "dx": -0.08588834215301201, "dy": 0.9963047689749394 }] }, + { "ville1": "Dieppe", "ville2": "London", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 1, "segments": [{ "x": 354.5, "y": 422.5, "dx": 0.08444307668618062, "dy": -0.9964283048969312 }, { "x": 360, "y": 359.5, "dx": 0.10468478451804275, "dy": -0.9945054529214061 }] }, + { "ville1": "Dieppe", "ville2": "Paris", "longueur": 1, "couleur": "ROSE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 379.5, "y": 500.5, "dx": 0.7071067811865475, "dy": 0.7071067811865475 }] }, + { "ville1": "Edinburgh", "ville2": "London", "longueur": 4, "couleur": "ORANGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 276.5, "y": 96, "dx": 0.42012356811103757, "dy": 0.9074669071198412 }, { "x": 301, "y": 154.5, "dx": 0.38337767164151665, "dy": 0.9235916635000174 }, { "x": 325, "y": 212, "dx": 0.389639990836698, "dy": 0.9209672510685588 }, { "x": 349.5, "y": 269.5, "dx": 0.3980931180228264, "dy": 0.9173450110960782 }] }, + { "ville1": "Edinburgh", "ville2": "London", "longueur": 4, "couleur": "NOIR", "isTunnel": false, "ferry": 0, "segments": [{ "x": 255.5, "y": 105.5, "dx": 0.41110775310681835, "dy": 0.911586756889032 }, { "x": 280.5, "y": 163.5, "dx": 0.3980931180228264, "dy": 0.9173450110960782 }, { "x": 305, "y": 220, "dx": 0.40273861426601687, "dy": 0.9153150324227656 }, { "x": 329, "y": 277.5, "dx": 0.3960911114346502, "dy": 0.9182112128712345 }] }, + { "ville1": "Erzurum", "ville2": "Sevastopol", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 2, "segments": [{ "x": 1514, "y": 792, "dx": 0, "dy": 1 }, { "x": 1518.5, "y": 854, "dx": 0.15867809538375516, "dy": 0.9873303712766988 }, { "x": 1542, "y": 914, "dx": 0.5710644881985998, "dy": 0.8209052017854871 }, { "x": 1588.5, "y": 960, "dx": 0.8372705045624257, "dy": 0.546788900938727 }] }, + { "ville1": "Erzurum", "ville2": "Sochi", "longueur": 3, "couleur": "ROUGE", "isTunnel": true, "ferry": 0, "segments": [{ "x": 1653.5, "y": 817, "dx": -0.12403473458920845, "dy": 0.9922778767136676 }, { "x": 1644.5, "y": 880, "dx": -0.15867809538375516, "dy": 0.9873303712766988 }, { "x": 1635.5, "y": 942.5, "dx": -0.12625427967391514, "dy": 0.9919979117236188 }] }, + { "ville1": "Essen", "ville2": "Frankfurt", "longueur": 2, "couleur": "VERT", "isTunnel": false, "ferry": 0, "segments": [{ "x": 666, "y": 412, "dx": 0.8944271909999159, "dy": -0.4472135954999579 }, { "x": 698, "y": 374.5, "dx": -0.4541874474402252, "dy": -0.8909061469019802 }] }, + { "ville1": "Essen", "ville2": "Kobenhavn", "longueur": 3, "couleur": "GRIS", "isTunnel": false, "ferry": 1, "segments": [{ "x": 677, "y": 288, "dx": 0.5390536964233673, "dy": -0.8422714006615114 }, { "x": 713, "y": 235, "dx": 0.5547001962252291, "dy": -0.8320502943378437 }, { "x": 748, "y": 182, "dx": 0.5547001962252291, "dy": -0.8320502943378437 }] }, + { "ville1": "Essen", "ville2": "Kobenhavn", "longueur": 3, "couleur": "GRIS", "isTunnel": false, "ferry": 1, "segments": [{ "x": 695.5, "y": 300, "dx": 0.5665288228870652, "dy": -0.8240419241993676 }, { "x": 731, "y": 246, "dx": 0.5462677805469223, "dy": -0.8376105968386142 }, { "x": 765.5, "y": 196, "dx": 0.5665288228870652, "dy": -0.8240419241993676 }] }, + { "ville1": "Frankfurt", "ville2": "Munchen", "longueur": 2, "couleur": "ROSE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 654, "y": 500, "dx": 0.31622776601683794, "dy": 0.9486832980505138 }, { "x": 684.5, "y": 534.5, "dx": 0.9582877607731983, "dy": -0.28580512163411176 }] }, + { "ville1": "Frankfurt", "ville2": "Paris", "longueur": 3, "couleur": "ORANGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 494, "y": 553.5, "dx": 0.9568805766427723, "dy": -0.29048160362369874 }, { "x": 552, "y": 527, "dx": 0.8422714006615114, "dy": -0.5390536964233673 }, { "x": 605.5, "y": 491.5, "dx": 0.8137334712067349, "dy": -0.5812381937190964 }] }, + { "ville1": "Frankfurt", "ville2": "Paris", "longueur": 3, "couleur": "BLANC", "isTunnel": false, "ferry": 0, "segments": [{ "x": 482.5, "y": 533, "dx": 0.939793423488437, "dy": -0.3417430630867044 }, { "x": 541, "y": 506.5, "dx": 0.8400393777687709, "dy": -0.5425254314756646 }, { "x": 594, "y": 471.5, "dx": 0.8240419241993676, "dy": -0.5665288228870652 }] }, + { "ville1": "Kharkov", "ville2": "Kyiv", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1386, "y": 482, "dx": 0.34731435582359393, "dy": 0.9377487607237036 }, { "x": 1428, "y": 531, "dx": 0.8804710999221753, "dy": 0.47409982303501746 }, { "x": 1490.5, "y": 547.5, "dx": 0.9986178293325098, "dy": 0.052558833122763673 }, { "x": 1554, "y": 540, "dx": 0.9486832980505138, "dy": -0.31622776601683794 }] }, + { "ville1": "Kharkov", "ville2": "Moskva", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1628.5, "y": 491, "dx": 0.6985367247883851, "dy": -0.7155742058807848 }, { "x": 1661.5, "y": 437, "dx": 0.2676438637860946, "dy": -0.9635179096299405 }, { "x": 1666, "y": 372, "dx": -0.1414213562373095, "dy": -0.9899494936611665 }, { "x": 1647, "y": 309.5, "dx": -0.4541874474402252, "dy": -0.8909061469019802 }] }, + { "ville1": "Kharkov", "ville2": "Rostov", "longueur": 2, "couleur": "VERT", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1651, "y": 528, "dx": 1, "dy": 0 }, { "x": 1670.5, "y": 573.5, "dx": 0.017541160386140585, "dy": 0.9998461420100133 }] }, + { "ville1": "Kobenhavn", "ville2": "Stockholm", "longueur": 3, "couleur": "JAUNE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 808.5, "y": 114, "dx": 0.6804510993672779, "dy": -0.7327934916262993 }, { "x": 855, "y": 70.5, "dx": 0.7483469392281404, "dy": -0.6633075143158518 }, { "x": 908, "y": 34, "dx": 0.8804710999221753, "dy": -0.47409982303501746 }] }, + { "ville1": "Kobenhavn", "ville2": "Stockholm", "longueur": 3, "couleur": "BLANC", "isTunnel": false, "ferry": 0, "segments": [{ "x": 825, "y": 132, "dx": 0.6896551724137931, "dy": -0.7241379310344828 }, { "x": 870, "y": 87.5, "dx": 0.7503589948350772, "dy": -0.6610305430689966 }, { "x": 923.5, "y": 50.5, "dx": 0.8837879163470618, "dy": -0.4678877204190327 }] }, + { "ville1": "Kyiv", "ville2": "Smolensk", "longueur": 3, "couleur": "ROUGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1418.5, "y": 440.5, "dx": 0.9986178293325098, "dy": 0.052558833122763673 }, { "x": 1477.5, "y": 417, "dx": 0.7157819483772108, "dy": -0.6983238520753277 }, { "x": 1492, "y": 355.5, "dx": -0.2890045919356118, "dy": -0.9573277107867141 }] }, + { "ville1": "Kyiv", "ville2": "Warszawa", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1143.5, "y": 376.5, "dx": 0.689213765997513, "dy": 0.7245580616896932 }, { "x": 1196, "y": 413, "dx": 0.9377487607237036, "dy": 0.34731435582359393 }, { "x": 1258.5, "y": 422.5, "dx": 0.9986178293325098, "dy": -0.052558833122763673 }, { "x": 1322.5, "y": 423.5, "dx": 0.9986178293325098, "dy": 0.052558833122763673 }] }, + { "ville1": "Kyiv", "ville2": "Wilno", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1344, "y": 330.5, "dx": 0.8400393777687709, "dy": 0.5425254314756646 }, { "x": 1372, "y": 389.5, "dx": 0, "dy": 1 }] }, + { "ville1": "Lisboa", "ville2": "Madrid", "longueur": 3, "couleur": "ROSE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 30, "y": 940, "dx": 0, "dy": -1 }, { "x": 49.5, "y": 896, "dx": 0.9994259471398348, "dy": 0.033878845665757114 }, { "x": 111, "y": 917.5, "dx": 0.8080075302163774, "dy": 0.5891721574494418 }] }, + { "ville1": "Madrid", "ville2": "Pamplona", "longueur": 3, "couleur": "BLANC", "isTunnel": true, "ferry": 0, "segments": [{ "x": 186, "y": 920.5, "dx": 0.6419366564593427, "dy": -0.7667576729931038 }, { "x": 229, "y": 874, "dx": 0.7071067811865475, "dy": -0.7071067811865475 }, { "x": 278.5, "y": 833, "dx": 0.8372705045624257, "dy": -0.546788900938727 }] }, + { "ville1": "Madrid", "ville2": "Pamplona", "longueur": 3, "couleur": "NOIR", "isTunnel": true, "ferry": 0, "segments": [{ "x": 171, "y": 905, "dx": 0.6536198703460924, "dy": -0.7568230077691596 }, { "x": 212.5, "y": 857, "dx": 0.6804510993672779, "dy": -0.7327934916262993 }, { "x": 261, "y": 817, "dx": 0.8422714006615114, "dy": -0.5390536964233673 }] }, + { "ville1": "Marseille", "ville2": "Pamplona", "longueur": 4, "couleur": "ROUGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 367.5, "y": 823, "dx": 0.9503971290446889, "dy": 0.3110390604146254 }, { "x": 401, "y": 790.5, "dx": 0.35305725243424235, "dy": -0.9356017189507422 }, { "x": 452.5, "y": 753.5, "dx": 0.9998461420100133, "dy": -0.017541160386140585 }, { "x": 516.5, "y": 770.5, "dx": 0.8979207227269799, "dy": 0.44015721702302935 }] }, + { "ville1": "Marseille", "ville2": "Paris", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 553, "y": 756, "dx": -0.5547001962252291, "dy": -0.8320502943378437 }, { "x": 505.5, "y": 713.5, "dx": -0.8837879163470618, "dy": -0.4678877204190327 }, { "x": 457, "y": 670.5, "dx": -0.5700815482062942, "dy": -0.821588113591424 }, { "x": 436.5, "y": 608.5, "dx": -0.054464493159869794, "dy": -0.9985157079309461 }] }, + { "ville1": "Marseille", "ville2": "Roma", "longueur": 4, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 620, "y": 778, "dx": 0.8041761414663255, "dy": -0.5943910610838058 }, { "x": 671, "y": 741.5, "dx": 0.8, "dy": -0.6 }, { "x": 712, "y": 762.5, "dx": 0.6028330891856919, "dy": 0.7978673239222394 }, { "x": 750, "y": 813.5, "dx": 0.6028330891856919, "dy": 0.7978673239222394 }] }, + { "ville1": "Marseille", "ville2": "Zurich", "longueur": 2, "couleur": "ROSE", "isTunnel": true, "ferry": 0, "segments": [{ "x": 615, "y": 683.5, "dx": -0.2553911228370322, "dy": 0.9668378221687647 }, { "x": 599, "y": 746.5, "dx": -0.2890045919356118, "dy": 0.9573277107867141 }] }, + { "ville1": "Moskva", "ville2": "Petrograd", "longueur": 4, "couleur": "BLANC", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1504, "y": 79.5, "dx": 0.9538492507391959, "dy": 0.30028587523270983 }, { "x": 1561, "y": 110, "dx": 0.8041761414663255, "dy": 0.5943910610838058 }, { "x": 1600, "y": 161, "dx": 0.4472135954999579, "dy": 0.8944271909999159 }, { "x": 1617, "y": 222, "dx": 0.07124704998790965, "dy": 0.9974586998307351 }] }, + { "ville1": "Moskva", "ville2": "Smolensk", "longueur": 2, "couleur": "ORANGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1526, "y": 314, "dx": 0.994309153919809, "dy": 0.10653312363426524 }, { "x": 1587, "y": 295.5, "dx": 0.8080075302163774, "dy": -0.5891721574494418 }] }, + { "ville1": "Munchen", "ville2": "Venezia", "longueur": 2, "couleur": "BLEU", "isTunnel": true, "ferry": 0, "segments": [{ "x": 742, "y": 587, "dx": 0.18208926018230742, "dy": 0.9832820049844601 }, { "x": 754, "y": 651, "dx": 0.20952908873087345, "dy": 0.9778024140774094 }] }, + { "ville1": "Munchen", "ville2": "Wien", "longueur": 3, "couleur": "ORANGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 768.5, "y": 566, "dx": 0.6055218324832624, "dy": 0.7958286941208591 }, { "x": 826, "y": 594.5, "dx": 0.9986649849421085, "dy": 0.0516550854280401 }, { "x": 887, "y": 574.5, "dx": 0.7792134503124135, "dy": -0.6267586448165066 }] }, + { "ville1": "Munchen", "ville2": "Zurich", "longueur": 2, "couleur": "JAUNE", "isTunnel": true, "ferry": 0, "segments": [{ "x": 656.5, "y": 609.5, "dx": 0.7407190347407712, "dy": -0.6718149384858157 }, { "x": 702.5, "y": 564, "dx": 0.7321867381630838, "dy": -0.6811039424772872 }] }, + { "ville1": "Palermo", "ville2": "Roma", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 1, "segments": [{ "x": 864, "y": 1032, "dx": -0.5943910610838058, "dy": 0.8041761414663255 }, { "x": 884.5, "y": 972, "dx": -0.017238817250844786, "dy": 0.9998514005489976 }, { "x": 866, "y": 911, "dx": 0.6163082616581107, "dy": 0.7875050010075858 }, { "x": 818, "y": 867.5, "dx": 0.8799053976571926, "dy": 0.47514891473488396 }] }, + { "ville1": "Palermo", "ville2": "Smyrna", "longueur": 6, "couleur": "GRIS", "isTunnel": false, "ferry": 2, "segments": [{ "x": 1236.5, "y": 1069, "dx": 1, "dy": 0 }, { "x": 1172.5, "y": 1069, "dx": 1, "dy": 0 },{ "x": 1110.5, "y": 1069, "dx": 1, "dy": 0 }, { "x": 1048.5, "y": 1069, "dx": 1, "dy": 0 }, { "x": 984, "y": 1069, "dx": 1, "dy": 0 }, { "x": 920, "y": 1069, "dx": 1, "dy": 0 }] }, + { "ville1": "Pamplona", "ville2": "Paris", "longueur": 4, "couleur": "BLEU", "isTunnel": false, "ferry": 0, "segments": [{ "x": 321.5, "y": 763, "dx": 0.5891721574494418, "dy": -0.8080075302163774 }, { "x": 353.5, "y": 706.5, "dx": 0.34570535882735637, "dy": -0.9383431168171101 }, { "x": 374, "y": 647, "dx": 0.24253562503633297, "dy": -0.9701425001453319 }, { "x": 387.5, "y": 584, "dx": 0.15333732983159673, "dy": -0.988173903359179 }] }, + { "ville1": "Pamplona", "ville2": "Paris", "longueur": 4, "couleur": "VERT", "isTunnel": false, "ferry": 0, "segments": [{ "x": 343.5, "y": 770.5, "dx": 0.597266145998167, "dy": -0.8020431103403957 }, { "x": 376, "y": 713, "dx": 0.37729688731351946, "dy": -0.9260923597695477 }, { "x": 397, "y": 654, "dx": 0.27472112789737807, "dy": -0.9615239476408232 }, { "x": 410.5, "y": 592, "dx": 0.11982016019085814, "dy": -0.9927956130099675 }] }, + { "ville1": "Paris", "ville2": "Zurich", "longueur": 3, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 468.5, "y": 594, "dx": 0.5171156399255817, "dy": 0.8559155419457903 }, { "x": 515.5, "y": 636.5, "dx": 0.9052369440730288, "dy": 0.4249071370138707 }, { "x": 578.5, "y": 650, "dx": 1, "dy": 0 }] }, + { "ville1": "Petrograd", "ville2": "Riga", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1216.5, "y": 73, "dx": 1, "dy": 0 }, { "x": 1281, "y": 74, "dx": 0.9993628543475496, "dy": -0.03569153051241249 }, { "x": 1344, "y": 72, "dx": 0.9993148337667671, "dy": -0.037011660509880265 }, { "x": 1407, "y": 71.5, "dx": 0.9985681322700888, "dy": -0.053494721371611896 }] }, + { "ville1": "Petrograd", "ville2": "Stockholm", "longueur": 8, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 994, "y": 57, "dx": 0.6332377902572627, "dy": 0.773957299203321 }, { "x": 1040, "y": 48, "dx": 0.8041761414663255, "dy": -0.5943910610838058 }, { "x": 1099.5, "y": 26.5, "dx": 0.9998347517133227, "dy": 0.01817881366751496 }, { "x": 1163, "y": 26.5, "dx": 0.9998405993454448, "dy": 0.017854296416882943 }, { "x": 1226.5, "y": 25.5, "dx": 0.9998461420100133, "dy": -0.017541160386140585 }, { "x": 1289.5, "y": 26, "dx": 1, "dy": 0 }, { "x": 1352.5, "y": 26.5, "dx": 0.9998347517133227, "dy": -0.01817881366751496 }, { "x": 1416.5, "y": 39, "dx": 0.9165393783696333, "dy": 0.39994445601584 }] }, + { "ville1": "Petrograd", "ville2": "Wilno", "longueur": 4, "couleur": "BLEU", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1326, "y": 261, "dx": 0.5943910610838058, "dy": -0.8041761414663255 }, { "x": 1364, "y": 209.5, "dx": 0.5627909770820216, "dy": -0.8265992475892192 }, { "x": 1400.5, "y": 158, "dx": 0.5829078754517308, "dy": -0.8125382506296854 }, { "x": 1437, "y": 107.5, "dx": 0.5861197865287227, "dy": -0.8102244107897049 }] }, + { "ville1": "Riga", "ville2": "Wilno", "longueur": 4, "couleur": "VERT", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1167, "y": 119, "dx": -0.16990691650764622, "dy": 0.985460115744348 }, { "x": 1175, "y": 182, "dx": 0.4190581774617469, "dy": 0.9079593845004517 }, { "x": 1216, "y": 230.5, "dx": 0.8559155419457903, "dy": 0.5171156399255817 }, { "x": 1270, "y": 264.5, "dx": 0.8400393777687709, "dy": 0.5425254314756646 }] }, + { "ville1": "Roma", "ville2": "Venezia", "longueur": 2, "couleur": "NOIR", "isTunnel": false, "ferry": 0, "segments": [{ "x": 772.5, "y": 740, "dx": 0.19274530403092788, "dy": 0.9812488205210874 }, { "x": 784, "y": 803.5, "dx": 0.17888543819998318, "dy": 0.9838699100999074 }] }, + { "ville1": "Rostov", "ville2": "Sevastopol", "longueur": 4, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1526, "y": 703, "dx": 0.13663739713703102, "dy": -0.9906211292434748 }, { "x": 1534.5, "y": 640, "dx": 0.15867809538375516, "dy": -0.9873303712766988 }, { "x": 1561, "y": 598, "dx": 0.9906211292434748, "dy": 0.13663739713703102 }, { "x": 1623.5, "y": 609, "dx": 0.9849570246463139, "dy": 0.17279947800812523 }] }, + { "ville1": "Rostov", "ville2": "Sochi", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1667.5, "y": 663, "dx": -0.053494721371611896, "dy": 0.9985681322700888 }, { "x": 1664, "y": 726.5, "dx": -0.07000328148073091, "dy": 0.9975467611004155 }] }, + { "ville1": "Sarajevo", "ville2": "Sofia", "longueur": 2, "couleur": "GRIS", "isTunnel": true, "ferry": 0, "segments": [{ "x": 1096, "y": 793, "dx": 0.9079593845004517, "dy": -0.4190581774617469 }, { "x": 1143.5, "y": 792, "dx": 0.47514891473488396, "dy": 0.8799053976571926 }] }, + { "ville1": "Sarajevo", "ville2": "Zagrab", "longueur": 3, "couleur": "ROUGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 913.5, "y": 761.5, "dx": 0.12189130152520146, "dy": 0.9925434552766405 }, { "x": 946, "y": 815.5, "dx": 0.8125382506296854, "dy": 0.5829078754517308 }, { "x": 1010, "y": 825.5, "dx": 0.9433123908373908, "dy": -0.3319062115909338 }] }, + { "ville1": "Sevastopol", "ville2": "Sochi", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 1, "segments": [{ "x": 1554, "y": 753, "dx": 0.9899494936611665, "dy": 0.1414213562373095 }, { "x": 1616, "y": 763, "dx": 0.9899494936611665, "dy": 0.1414213562373095 }] }, + { "ville1": "Smolensk", "ville2": "Wilno", "longueur": 3, "couleur": "JAUNE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1344.5, "y": 274.5, "dx": 0.5812381937190964, "dy": -0.8137334712067349 }, { "x": 1386, "y": 251, "dx": 0.8160244811016552, "dy": 0.5780173407803391 }, { "x": 1438, "y": 289, "dx": 0.8160244811016552, "dy": 0.5780173407803391 }] }, + { "ville1": "Venezia", "ville2": "Zagrab", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 808, "y": 680.5, "dx": 0.965948051503245, "dy": -0.2587360852240835 }, { "x": 870.5, "y": 691.5, "dx": 0.8450788360522153, "dy": 0.5346417126044628 }] }, + { "ville1": "Venezia", "ville2": "Zurich", "longueur": 2, "couleur": "VERT", "isTunnel": true, "ferry": 0, "segments": [{ "x": 664.5, "y": 659.5, "dx": 0.8837879163470618, "dy": 0.4678877204190327 }, { "x": 721.5, "y": 689, "dx": 0.8765785507795943, "dy": 0.48125881219271843 }] }, + { "ville1": "Warszawa", "ville2": "Wien", "longueur": 4, "couleur": "BLEU", "isTunnel": false, "ferry": 0, "segments": [{ "x": 966.5, "y": 531.5, "dx": 0.860576682823999, "dy": -0.5093208939162444 }, { "x": 1016.5, "y": 493.5, "dx": 0.7423931175486519, "dy": -0.6699645207146371 }, { "x": 1059.5, "y": 446, "dx": 0.5891721574494418, "dy": -0.8080075302163774 }, { "x": 1094, "y": 392.5, "dx": 0.5221538596385299, "dy": -0.8528513040762654 }] }, + { "ville1": "Warszawa", "ville2": "Wilno", "longueur": 3, "couleur": "ROUGE", "isTunnel": false, "ferry": 0, "segments": [{ "x": 1142.5, "y": 310.5, "dx": 0.4678877204190327, "dy": -0.8837879163470618 }, { "x": 1194, "y": 272, "dx": 0.9761870601839528, "dy": -0.21693045781865616 }, { "x": 1257, "y": 285, "dx": 0.847998304005088, "dy": 0.52999894000318 }] }, + { "ville1": "Wien", "ville2": "Zagrab", "longueur": 2, "couleur": "GRIS", "isTunnel": false, "ferry": 0, "segments": [{ "x": 912.5, "y": 667, "dx": 0.08588834215301201, "dy": -0.9963047689749394 }, { "x": 916.5, "y": 604.5, "dx": 0.054464493159869794, "dy": -0.9985157079309461 }] } +}; \ No newline at end of file diff --git a/svelte/src/stores.js b/svelte/src/stores.js new file mode 100644 index 0000000..15d868e --- /dev/null +++ b/svelte/src/stores.js @@ -0,0 +1,7 @@ +import { writable } from 'svelte/store'; +let hostname = window.location.hostname; +if (hostname === "") { + hostname = "localhost"; +} + +export const ws = writable(new WebSocket(`ws://${hostname}:3232`)); diff --git a/tools/missions.py b/tools/missions.py new file mode 100644 index 0000000..57c8e39 --- /dev/null +++ b/tools/missions.py @@ -0,0 +1,52 @@ +data = """\ +Athina Angora 5 +Budapest Sofia 5 +Frankfurt Kobenhavn 5 +Rostov Erzurum 5 +Sofia Smyrna 5 +Kyiv Petrograd 6 +Zurich Brindisi 6 +Zurich Budapest 6 +Warszawa Smolensk 6 +Zagrab Brindisi 6 +Paris Zagreb 7 +Brest Marseille 7 +London Berlin 7 +Edinburgh Paris 7 +Amsterdam Pamplona 7 +Roma Smyrna 8 +Palermo Constantinople 8 +Sarajevo Sevastopol 8 +Madrid Dieppe 8 +Barcelona Bruxelles 8 +Paris Wien 8 +Barcelona Munchen 8 +Brest Venezia 8 +Smolensk Rostov 8 +Marseille Essen 8 +Kyiv Sochi 8 +Madrid Zurich 8 +Berlin Bucuresti 8 +Bruxelles Danzic 9 +Berlin Roma 9 +Angora Kharkov 10 +Riga Bucuresti 10 +Essen Kyiv 10 +Venizia Constantinople 10 +London Wien 10 +Athina Wilno 11 +Stockholm Wien 11 +Berlin Moskva 12 +Amsterdam Wilno 12 +Frankfurt Smolensk 13 +Lisboa Danzic 20 +Brest Petrograd 20 +Palermo Moskva 20 +Kobenhavn Erzurum 21 +Edinburgh Athina 21 +Cadiz Stockholm 21""" + +for line in data.split('\n'): + line = line.strip() + ville1, ville2, score = line.split(' ') + print(f'missions.add(new Mission("{ville1}", "{ville2}", {score}));') diff --git a/tools/network.py b/tools/network.py new file mode 100644 index 0000000..ebd9f73 --- /dev/null +++ b/tools/network.py @@ -0,0 +1,175 @@ +cities = [ + "Amsterdam", + "Angora", + "Athina", + "Barcelona", + "Berlin", + "Brest", + "Brindisi", + "Bruxelles", + "Bucuresti", + "Budapest", + "Cadiz", + "Constantinople", + "Danzig", + "Dieppe", + "Edinburgh", + "Erzurum", + "Essen", + "Frankfurt", + "Kharkov", + "København", + "Kyiv", + "Lisboa", + "London", + "Madrid", + "Marseille", + "Moskva", + "München", + "Palermo", + "Pamplona", + "Paris", + "Petrograd", + "Riga", + "Roma", + "Rostov", + "Sarajevo", + "Sevastopol", + "Smolensk", + "Smyrna", + "Sochi", + "Sofia", + "Stockholm", + "Venezia", + "Warszawa", + "Wien", + "Wilno", + "Zagrab", + "Zürich", +] + +GRIS = "GRIS" +NOIR = "NOIR" +BLANC = "BLANC" +JAUNE = "JAUNE" +ROUGE = "ROUGE" +ORANGE = "ORANGE" +BLEU = "BLEU" +VERT = "VERT" +ROSE = "ROSE" +LOCOMOTIVE = "LOCOMOTIVE" + +amsterdam = "amsterdam" +angora = "angora" +athina = "athina" +barcelona = "barcelona" +berlin = "berlin" +brest = "brest" +brindisi = "brindisi" +bruxelles = "bruxelles" +bucuresti = "bucuresti" +budapest = "budapest" +cadiz = "cadiz" +constantinople = "constantinople" +danzig = "danzig" +dieppe = "dieppe" +edinburgh = "edinburgh" +erzurum = "erzurum" +essen = "essen" +frankfurt = "frankfurt" +kharkov = "kharkov" +kobenhavn = "kobenhavn" +kyiv = "kyiv" +lisboa = "lisboa" +london = "london" +madrid = "madrid" +marseille = "marseille" +moskva = "moskva" +munchen = "munchen" +palermo = "palermo" +pamplona = "pamplona" +paris = "paris" +petrograd = "petrograd" +riga = "riga" +roma = "roma" +rostov = "rostov" +sarajevo = "sarajevo" +sevastopol = "sevastopol" +smolensk = "smolensk" +smyrna = "smyrna" +sochi = "sochi" +sofia = "sofia" +stockholm = "stockholm" +venezia = "venezia" +warszawa = "warszawa" +wien = "wien" +wilno = "wilno" +zagrab = "zagrab" +zurich = "zurich" + +routes = [ + (edinburgh, london, 4, NOIR), + (edinburgh, london, 4, ORANGE), + (london, amsterdam, 2, GRIS, 2), + (london, dieppe, 2, GRIS, 1), + (london, dieppe, 2, GRIS, 1), + (dieppe, brest, 2, ORANGE), + (dieppe, bruxelles, 2, VERT), + (dieppe, paris, 1, ROSE), + (brest, paris, 3, NOIR), + (brest, pamplona, 4, ROSE), + (paris, pamplona, 4, BLEU), + (paris, pamplona, 4, VERT), + (paris, marseille, 4, GRIS), + (paris, zurich, 3, GRIS, True), + (paris, frankfurt, 3, BLANC), + (paris, frankfurt, 3, ORANGE), + (paris, bruxelles, 2, JAUNE), + (paris, bruxelles, 2, ROUGE), + (pamplona, madrid, 3, BLANC), + (pamplona, madrid, 3, NOIR), + (pamplona, barcelona, 2, GRIS, True), + (pamplona, marseille, 4, ROUGE), + (madrid, lisboa, 3, ROSE), + (madrid, cadiz, 3, ORANGE), + (madrid, barcelona, 2, JAUNE), + (lisboa, cadiz, 2, BLEU), + (barcelona, marseille, 4, GRIS), + (zurich, marseille, 2, ROSE, True), + (zurich, munchen, 2, JAUNE, True), + (zurich, venezia, 2, VERT, True), + (marseille, roma, 4, GRIS, True), + (munchen, venezia, 2, BLEU, True), + (munchen, frankfurt, 2, ROSE), + (frankfurt, bruxelles, 2, BLEU), + (frankfurt, amsterdam, 2, BLANC), + (bruxelles, amsterdam, 1, NOIR), + (venezia, roma, 2, NOIR), +] + +var_names = [] +for city_name in cities: + tr = str.maketrans("øü", "ou") + var_name = city_name.lower().translate(tr) + var_names.append(var_name) + print(f'Ville {var_name} = new Ville("{city_name}");') + +# for var_name in var_names: +# print(f'{var_name} = "{var_name}"') + +for route in routes: + ville1, ville2, longueur, couleur = route[:4] + locomotives = 0 + tunnel = False + if len(route) == 5: + if route[4] is True: + tunnel = True + else: + locomotives = route[4] + if tunnel: + print(f'routes.add(new Tunnel({ville1}, {ville2}, {longueur}, Couleur.{couleur}));') + else: + print(f'routes.add(new Route({ville1}, {ville2}, {longueur}, Couleur.{couleur}, {locomotives}));') + + +# print(f'Ville[] villes = new Ville[] {{{", ".join(var_names)}}};')