diff --git a/.github/workflows/build_and_deploy.yml b/.github/workflows/build_and_deploy.yml index e2eaaebb2..3e3b067db 100644 --- a/.github/workflows/build_and_deploy.yml +++ b/.github/workflows/build_and_deploy.yml @@ -98,6 +98,25 @@ jobs: needs: build runs-on: ubuntu-latest steps: + - name: Checkout Repo + if: ${{ inputs.noop != 'true' }} + uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref }} + - uses: actions/setup-node@v3 + if: ${{ inputs.noop != 'true' }} + with: + node-version-file: ".tool-versions" + - name: Install Dependencies for tools + if: ${{ inputs.noop != 'true' }} + working-directory: ./tools/fontlist + run: npm ci + - name: Upload font list + if: ${{ inputs.noop != 'true' }} + run: node ./tools/fontlist/upload.js + env: + DATABASE_GOOGLE_APPLICATION_CREDENTIALS_JSON: ${{ secrets.DATABASE_GOOGLE_APPLICATION_CREDENTIALS_JSON }} + FIREBASE_STORAGE_BUCKET: ${{ secrets.FIREBASE_STORAGE_BUCKET }} - name: Deploy backend to render.com if: ${{ inputs.noop != 'true' }} run: curl --silent --show-error --fail $RENDER_DEPLOY_HOOK_URL > /dev/null diff --git a/.gitignore b/.gitignore index c3a8bf08c..d5bb8d8e7 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,4 @@ cypress certs/* backend/tmp/ +data diff --git a/README.md b/README.md index 49ff2ae2d..d3c00bdee 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ TextUSM is a simple tool. Help you draw user story map using indented text. -![image](./img/textusm.gif) +![image](./assets/img/textusm.gif) ## Features @@ -54,7 +54,7 @@ TextUSM Press Shift + Tab to unindent lines: Online tool for Generate a User Story Mapping from indented text. ``` -![image](./img/usm.png) +![image](./assets/img/usm.png) ### Business Model Canvas @@ -79,7 +79,7 @@ TextUSM Customer Relationships ``` -![image](./img/bmc.png) +![image](./assets/img/bmc.png) ### Opportunity Canvas @@ -106,7 +106,7 @@ Budget Budget ``` -![image](./img/opc.png) +![image](./assets/img/opc.png) ### 4Ls Retrospective @@ -121,7 +121,7 @@ Longed for Longed for ``` -![image](./img/4ls.png) +![image](./assets/img/4ls.png) ### Start, Stop, Continue Retrospective @@ -134,7 +134,7 @@ Continue Continue ``` -![image](./img/ssc.png) +![image](./assets/img/ssc.png) ### KPT Retrospective @@ -147,7 +147,7 @@ Try Try ``` -![image](./img/kpt.png) +![image](./assets/img/kpt.png) ### MindMap @@ -163,7 +163,7 @@ TextUSM Share your diagrams online with your colleagues. ``` -![image](./img/mmp.png) +![image](./assets/img/mmp.png) ### Empathy Map @@ -175,7 +175,7 @@ DOES FEELS ``` -![image](./img/emm.png) +![image](./assets/img/emm.png) ### Table @@ -203,7 +203,7 @@ Row2 Column6 ``` -![image](./img/table.png) +![image](./assets/img/table.png) ### Site Map @@ -222,7 +222,7 @@ Home harehare1110@gmail.com ``` -![image](./img/smp.png) +![image](./assets/img/smp.png) ### Gantt Chart @@ -236,7 +236,7 @@ Home 2019-12-31 2020-01-04 ``` -![image](./img/gct.png) +![image](./assets/img/gct.png) ### Impact Map @@ -252,7 +252,7 @@ TextUSM Share your diagrams online with your colleagues. ``` -![image](./img/imm.png) +![image](./assets/img/imm.png) ### ER Diagram @@ -288,7 +288,7 @@ tables user_id int pk ``` -![image](./img/erd.png) +![image](./assets/img/erd.png) ### Kanban @@ -304,7 +304,7 @@ DONE task3 ``` -![image](./img/kanban.png) +![image](./assets/img/kanban.png) ### Sequence Diagram @@ -338,7 +338,7 @@ Par Sync Message ``` -![image](./img/sed.png) +![image](./assets//img/sed.png) ### Keyboard Layout @@ -412,7 +412,7 @@ r1 1.25u ``` -![image](./img/kbd60.png) +![image](./assets/img/kbd60.png) ## Developing diff --git a/assets/fontlist/all.txt b/assets/fontlist/all.txt new file mode 100644 index 000000000..19890f4ca --- /dev/null +++ b/assets/fontlist/all.txt @@ -0,0 +1,958 @@ +ABeeZee +Abel +Abhaya Libre +Abril Fatface +Aclonica +Acme +Actor +Adamina +Advent Pro +Aguafina Script +Akronim +Aladin +Aldrich +Alef +Alegreya +Alegreya Sans +Alegreya Sans SC +Alegreya SC +Aleo +Alex Brush +Alfa Slab One +Alice +Alike +Alike Angular +Allan +Allerta +Allerta Stencil +Allura +Almarai +Almendra +Almendra Display +Almendra SC +Amarante +Amaranth +Amatic SC +Amethysta +Amiko +Amiri +Amita +Anaheim +Andada +Andika +Angkor +Annie Use Your Telescope +Anonymous Pro +Antic +Antic Didone +Antic Slab +Anton +Arapey +Arbutus +Arbutus Slab +Architects Daughter +Archivo +Archivo Black +Archivo Narrow +Aref Ruqaa +Arima Madurai +Arimo +Arizonia +Armata +Arsenal +Artifika +Arvo +Arya +Asap +Asap Condensed +Asar +Asset +Assistant +Astloch +Asul +Athiti +Atma +Atomic Age +Aubrey +Audiowide +Autour One +Average +Average Sans +Averia Gruesa Libre +Averia Libre +Averia Sans Libre +Averia Serif Libre +B612 +B612 Mono +Bad Script +Bahiana +Bahianita +Bai Jamjuree +Baloo +Baloo Bhai +Baloo Bhaijaan +Baloo Bhaina +Baloo Chettan +Baloo Da +Baloo Paaji +Baloo Tamma +Baloo Tammudu +Baloo Thambi +Balthazar +Bangers +Barlow +Barlow Condensed +Barlow Semi Condensed +Barriecito +Barrio +Basic +Battambang +Baumans +Bayon +Be Vietnam +Belgrano +Bellefair +Belleza +BenchNine +Bentham +Berkshire Swash +Beth Ellen +Bevan +Big Shoulders Display +Big Shoulders Text +Bigelow Rules +Bigshot One +Bilbo +Bilbo Swash Caps +BioRhyme +BioRhyme Expanded +Biryani +Bitter +Black And White Picture +Black Han Sans +Black Ops One +Blinker +Bokor +Bonbon +Boogaloo +Bowlby One +Bowlby One SC +Brawler +Bree Serif +Bubblegum Sans +Bubbler One +Buda +Buenard +Bungee +Bungee Hairline +Bungee Inline +Bungee Outline +Bungee Shade +Butcherman +Butterfly Kids +Cabin +Cabin Condensed +Cabin Sketch +Caesar Dressing +Cagliostro +Cairo +Calligraffitti +Cambay +Cambo +Candal +Cantarell +Cantata One +Cantora One +Capriola +Cardo +Carme +Carrois Gothic +Carrois Gothic SC +Carter One +Catamaran +Caudex +Caveat +Caveat Brush +Cedarville Cursive +Ceviche One +Chakra Petch +Changa +Changa One +Chango +Charm +Charmonman +Chathura +Chau Philomene One +Chela One +Chelsea Market +Chenla +Cherry Cream Soda +Cherry Swash +Chewy +Chicle +Chilanka +Chivo +Chonburi +Cinzel +Cinzel Decorative +Clicker Script +Coda +Coda Caption +Codystar +Coiny +Combo +Comfortaa +Coming Soon +Concert One +Condiment +Content +Contrail One +Convergence +Cookie +Copse +Corben +Cormorant +Cormorant Garamond +Cormorant Infant +Cormorant SC +Cormorant Unicase +Cormorant Upright +Courgette +Cousine +Coustard +Covered By Your Grace +Crafty Girls +Creepster +Crete Round +Crimson Pro +Crimson Text +Croissant One +Crushed +Cuprum +Cute Font +Cutive +Cutive Mono +Damion +Dancing Script +Dangrek +Darker Grotesque +David Libre +Dawning of a New Day +Days One +Dekko +Delius +Delius Swash Caps +Delius Unicase +Della Respira +Denk One +Devonshire +Dhurjati +Didact Gothic +Diplomata +Diplomata SC +DM Sans +DM Serif Display +DM Serif Text +Do Hyeon +Dokdo +Domine +Donegal One +Doppio One +Dorsa +Dosis +Dr Sugiyama +Duru Sans +Dynalight +Eagle Lake +East Sea Dokdo +Eater +EB Garamond +Economica +Eczar +El Messiri +Electrolize +Elsie +Elsie Swash Caps +Emblema One +Emilys Candy +Encode Sans +Encode Sans Condensed +Encode Sans Expanded +Encode Sans Semi Condensed +Encode Sans Semi Expanded +Engagement +Englebert +Enriqueta +Erica One +Esteban +Euphoria Script +Ewert +Exo +Exo 2 +Expletus Sans +Fahkwang +Fanwood Text +Farro +Farsan +Fascinate +Fascinate Inline +Faster One +Fasthand +Fauna One +Faustina +Federant +Federo +Felipa +Fenix +Finger Paint +Fira Code +Fira Mono +Fira Sans +Fira Sans Condensed +Fira Sans Extra Condensed +Fjalla One +Fjord One +Flamenco +Flavors +Fondamento +Fontdiner Swanky +Forum +Francois One +Frank Ruhl Libre +Freckle Face +Fredericka the Great +Fredoka One +Freehand +Fresca +Frijole +Fruktur +Fugaz One +Gabriela +Gaegu +Gafata +Galada +Galdeano +Galindo +Gamja Flower +Gayathri +Gentium Basic +Gentium Book Basic +Geo +Geostar +Geostar Fill +Germania One +GFS Didot +GFS Neohellenic +Gidugu +Gilda Display +Give You Glory +Glass Antiqua +Glegoo +Gloria Hallelujah +Goblin One +Gochi Hand +Gorditas +Gothic A1 +Goudy Bookletter 1911 +Graduate +Grand Hotel +Gravitas One +Great Vibes +Grenze +Griffy +Gruppo +Gudea +Gugi +Gurajada +Habibi +Halant +Hammersmith One +Hanalei +Hanalei Fill +Handlee +Hanuman +Happy Monkey +Harmattan +Headland One +Heebo +Henny Penny +Hepta Slab +Herr Von Muellerhoff +Hi Melody +Hind +Hind Guntur +Hind Madurai +Hind Siliguri +Hind Vadodara +Holtwood One SC +Homemade Apple +Homenaje +IBM Plex Mono +IBM Plex Sans +IBM Plex Sans Condensed +IBM Plex Serif +Iceberg +Iceland +IM Fell Double Pica +IM Fell Double Pica SC +IM Fell DW Pica +IM Fell DW Pica SC +IM Fell English +IM Fell English SC +IM Fell French Canon +IM Fell French Canon SC +IM Fell Great Primer +IM Fell Great Primer SC +Imprima +Inconsolata +Inder +Indie Flower +Inika +Inknut Antiqua +Irish Grover +Istok Web +Italiana +Italianno +Itim +Jacques Francois +Jacques Francois Shadow +Jaldi +Jim Nightshade +Jockey One +Jolly Lodger +Jomhuria +Josefin Sans +Josefin Slab +Joti One +Jua +Judson +Julee +Julius Sans One +Junge +Jura +Just Another Hand +Just Me Again Down Here +K2D +Kadwa +Kalam +Kameron +Kanit +Kantumruy +Karla +Karma +Katibeh +Kaushan Script +Kavivanar +Kavoon +Kdam Thmor +Keania One +Kelly Slab +Kenia +Khand +Khmer +Khula +Kirang Haerang +Kite One +Knewave +Kodchasan +KoHo +Kosugi +Kosugi Maru +Kotta One +Koulen +Kranky +Kreon +Kristi +Krona One +Krub +Kumar One +Kumar One Outline +Kurale +La Belle Aurore +Lacquer +Laila +Lakki Reddy +Lalezar +Lancelot +Lateef +Lato +League Script +Leckerli One +Ledger +Lekton +Lemon +Lemonada +Lexend Deca +Lexend Exa +Lexend Giga +Lexend Mega +Lexend Peta +Lexend Tera +Lexend Zetta +Libre Barcode 128 +Libre Barcode 128 Text +Libre Barcode 39 +Libre Barcode 39 Extended +Libre Barcode 39 Extended Text +Libre Barcode 39 Text +Libre Baskerville +Libre Caslon Text +Libre Franklin +Life Savers +Lilita One +Lily Script One +Limelight +Linden Hill +Literata +Liu Jian Mao Cao +Livvic +Lobster +Lobster Two +Londrina Outline +Londrina Shadow +Londrina Sketch +Londrina Solid +Long Cang +Lora +Love Ya Like A Sister +Loved by the King +Lovers Quarrel +Luckiest Guy +Lusitana +Lustria +M PLUS 1p +M PLUS Rounded 1c +Ma Shan Zheng +Macondo +Macondo Swash Caps +Mada +Magra +Maiden Orange +Maitree +Major Mono Display +Mako +Mali +Mallanna +Mandali +Manjari +Mansalva +Manuale +Marcellus +Marcellus SC +Marck Script +Margarine +Markazi Text +Marko One +Marmelad +Martel +Martel Sans +Marvel +Mate +Mate SC +Maven Pro +McLaren +Meddon +MedievalSharp +Medula One +Meera Inimai +Megrim +Meie Script +Merienda +Merienda One +Merriweather +Merriweather Sans +Metal +Metal Mania +Metamorphous +Metrophobic +Michroma +Milonga +Miltonian +Miltonian Tattoo +Mina +Miniver +Miriam Libre +Mirza +Miss Fajardose +Mitr +Modak +Modern Antiqua +Mogra +Molengo +Molle +Monda +Monofett +Monoton +Monsieur La Doulaise +Montaga +Montez +Montserrat +Montserrat Alternates +Montserrat Subrayada +Moul +Moulpali +Mountains of Christmas +Mouse Memoirs +Mr Bedfort +Mr Dafoe +Mr De Haviland +Mrs Saint Delafield +Mrs Sheppards +Mukta +Mukta Mahee +Mukta Malar +Mukta Vaani +Muli +Mystery Quest +Nanum Brush Script +Nanum Gothic +Nanum Gothic Coding +Nanum Myeongjo +Nanum Pen Script +Neucha +Neuton +New Rocker +News Cycle +Niconne +Niramit +Nixie One +Nobile +Nokora +Norican +Nosifer +Notable +Nothing You Could Do +Noticia Text +Noto Sans +Noto Sans HK +Noto Sans JP +Noto Sans KR +Noto Sans SC +Noto Sans TC +Noto Serif +Noto Serif JP +Noto Serif KR +Noto Serif SC +Noto Serif TC +Nova Cut +Nova Flat +Nova Mono +Nova Oval +Nova Round +Nova Script +Nova Slim +Nova Square +NTR +Numans +Nunito +Nunito Sans +Odor Mean Chey +Offside +Old Standard TT +Oldenburg +Oleo Script +Oleo Script Swash Caps +Open Sans +Open Sans Condensed +Oranienbaum +Orbitron +Oregano +Orienta +Original Surfer +Oswald +Over the Rainbow +Overlock +Overlock SC +Overpass +Overpass Mono +Ovo +Oxygen +Oxygen Mono +Pacifico +Padauk +Palanquin +Palanquin Dark +Pangolin +Paprika +Parisienne +Passero One +Passion One +Pathway Gothic One +Patrick Hand +Patrick Hand SC +Pattaya +Patua One +Pavanam +Paytone One +Peddana +Peralta +Permanent Marker +Petit Formal Script +Petrona +Philosopher +Piedra +Pinyon Script +Pirata One +Plaster +Play +Playball +Playfair Display +Playfair Display SC +Podkova +Poiret One +Poller One +Poly +Pompiere +Pontano Sans +Poor Story +Poppins +Port Lligat Sans +Port Lligat Slab +Pragati Narrow +Prata +Preahvihear +Press Start 2P +Pridi +Princess Sofia +Prociono +Prompt +Prosto One +Proza Libre +PT Mono +PT Sans +PT Sans Caption +PT Sans Narrow +PT Serif +PT Serif Caption +Puritan +Purple Purse +Quando +Quantico +Quattrocento +Quattrocento Sans +Questrial +Quicksand +Quintessential +Qwigley +Racing Sans One +Radley +Rajdhani +Rakkas +Raleway +Raleway Dots +Ramabhadra +Ramaraja +Rambla +Rammetto One +Ranchers +Rancho +Ranga +Rasa +Rationale +Ravi Prakash +Red Hat Display +Red Hat Text +Redressed +Reem Kufi +Reenie Beanie +Revalia +Rhodium Libre +Ribeye +Ribeye Marrow +Righteous +Risque +Roboto +Roboto Condensed +Roboto Mono +Roboto Slab +Rochester +Rock Salt +Rokkitt +Romanesco +Ropa Sans +Rosario +Rosarivo +Rouge Script +Rozha One +Rubik +Rubik Mono One +Ruda +Rufina +Ruge Boogie +Ruluko +Rum Raisin +Ruslan Display +Russo One +Ruthie +Rye +Sacramento +Sahitya +Sail +Saira +Saira Condensed +Saira Extra Condensed +Saira Semi Condensed +Saira Stencil One +Salsa +Sanchez +Sancreek +Sansita +Sarabun +Sarala +Sarina +Sarpanch +Satisfy +Sawarabi Gothic +Sawarabi Mincho +Scada +Scheherazade +Schoolbell +Scope One +Seaweed Script +Secular One +Sedgwick Ave +Sedgwick Ave Display +Sevillana +Seymour One +Shadows Into Light +Shadows Into Light Two +Shanti +Share +Share Tech +Share Tech Mono +Shojumaru +Short Stack +Shrikhand +Siemreap +Sigmar One +Signika +Signika Negative +Simonetta +Single Day +Sintony +Sirin Stencil +Six Caps +Skranji +Slabo 13px +Slabo 27px +Slackey +Smokum +Smythe +Sniglet +Snippet +Snowburst One +Sofadi One +Sofia +Song Myung +Sonsie One +Sorts Mill Goudy +Source Code Pro +Source Sans Pro +Source Serif Pro +Space Mono +Special Elite +Spectral +Spectral SC +Spicy Rice +Spinnaker +Spirax +Squada One +Sree Krushnadevaraya +Sriracha +Srisakdi +Staatliches +Stalemate +Stalinist One +Stardos Stencil +Stint Ultra Condensed +Stint Ultra Expanded +Stoke +Strait +Stylish +Sue Ellen Francisco +Suez One +Sumana +Sunflower +Sunshiney +Supermercado One +Sura +Suranna +Suravaram +Suwannaphum +Swanky and Moo Moo +Syncopate +Tajawal +Tangerine +Taprom +Tauri +Taviraj +Teko +Telex +Tenali Ramakrishna +Tenor Sans +Text Me One +Thasadith +The Girl Next Door +Tienne +Tillana +Timmana +Tinos +Titan One +Titillium Web +Trade Winds +Trirong +Trocchi +Trochut +Trykker +Tulpen One +Turret Road +Ubuntu +Ubuntu Condensed +Ubuntu Mono +Ultra +Uncial Antiqua +Underdog +Unica One +UnifrakturCook +UnifrakturMaguntia +Unkempt +Unlock +Unna +Vampiro One +Varela +Varela Round +Vast Shadow +Vesper Libre +Vibes +Vibur +Vidaloka +Viga +Voces +Volkhov +Vollkorn +Vollkorn SC +Voltaire +VT323 +Waiting for the Sunrise +Wallpoet +Walter Turncoat +Warnes +Wellfleet +Wendy One +Wire One +Work Sans +Yanone Kaffeesatz +Yantramanav +Yatra One +Yellowtail +Yeon Sung +Yeseva One +Yesteryear +Yrsa +ZCOOL KuaiLe +ZCOOL QingKe HuangYou +ZCOOL XiaoWei +Zeyada +Zhi Mang Xing +Zilla Slab +Zilla Slab Highlight diff --git a/assets/fontlist/ja.txt b/assets/fontlist/ja.txt new file mode 100644 index 000000000..24a843f91 --- /dev/null +++ b/assets/fontlist/ja.txt @@ -0,0 +1,8 @@ +M PLUS 1p +M PLUS Rounded 1c +Hannari +Kokoro +Sawarabi Mincho +Nico Moji +Nikukyu +Noto Sans JP diff --git a/img/4ls.png b/assets/img/4ls.png similarity index 100% rename from img/4ls.png rename to assets/img/4ls.png diff --git a/img/bmc.png b/assets/img/bmc.png similarity index 100% rename from img/bmc.png rename to assets/img/bmc.png diff --git a/img/emm.png b/assets/img/emm.png similarity index 100% rename from img/emm.png rename to assets/img/emm.png diff --git a/img/erd.png b/assets/img/erd.png similarity index 100% rename from img/erd.png rename to assets/img/erd.png diff --git a/img/gct.png b/assets/img/gct.png similarity index 100% rename from img/gct.png rename to assets/img/gct.png diff --git a/img/imm.png b/assets/img/imm.png similarity index 100% rename from img/imm.png rename to assets/img/imm.png diff --git a/img/kanban.png b/assets/img/kanban.png similarity index 100% rename from img/kanban.png rename to assets/img/kanban.png diff --git a/img/kbd60.png b/assets/img/kbd60.png similarity index 100% rename from img/kbd60.png rename to assets/img/kbd60.png diff --git a/img/kpt.png b/assets/img/kpt.png similarity index 100% rename from img/kpt.png rename to assets/img/kpt.png diff --git a/img/mmp.png b/assets/img/mmp.png similarity index 100% rename from img/mmp.png rename to assets/img/mmp.png diff --git a/img/opc.png b/assets/img/opc.png similarity index 100% rename from img/opc.png rename to assets/img/opc.png diff --git a/img/persona.png b/assets/img/persona.png similarity index 100% rename from img/persona.png rename to assets/img/persona.png diff --git a/img/sed.png b/assets/img/sed.png similarity index 100% rename from img/sed.png rename to assets/img/sed.png diff --git a/img/smp.png b/assets/img/smp.png similarity index 100% rename from img/smp.png rename to assets/img/smp.png diff --git a/img/ssc.png b/assets/img/ssc.png similarity index 100% rename from img/ssc.png rename to assets/img/ssc.png diff --git a/img/table.png b/assets/img/table.png similarity index 100% rename from img/table.png rename to assets/img/table.png diff --git a/img/textusm.gif b/assets/img/textusm.gif similarity index 100% rename from img/textusm.gif rename to assets/img/textusm.gif diff --git a/img/usm.png b/assets/img/usm.png similarity index 100% rename from img/usm.png rename to assets/img/usm.png diff --git a/backend/compose.yaml b/backend/compose.yaml new file mode 100644 index 000000000..31d7dfc29 --- /dev/null +++ b/backend/compose.yaml @@ -0,0 +1,7 @@ +services: + redis: + image: "redis" + ports: + - "6379:6379" + volumes: + - "./data/redis:/data" diff --git a/backend/go.mod b/backend/go.mod index 033784934..a196bae80 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -10,6 +10,7 @@ require ( github.com/go-chi/cors v1.2.1 github.com/go-chi/httprate v0.7.4 github.com/kelseyhightower/envconfig v1.4.0 + github.com/redis/go-redis/v9 v9.3.0 github.com/samber/mo v1.11.0 github.com/satori/go.uuid v1.2.0 github.com/stretchr/testify v1.8.4 @@ -31,6 +32,7 @@ require ( github.com/agnivade/levenshtein v1.1.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect diff --git a/backend/go.sum b/backend/go.sum index 323f95f80..6fbee6862 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -26,6 +26,10 @@ github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNg github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= +github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -34,6 +38,8 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -100,6 +106,8 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/redis/go-redis/v9 v9.3.0 h1:RiVDjmig62jIWp7Kk4XVLs0hzV6pI3PyTnnL0cnn0u0= +github.com/redis/go-redis/v9 v9.3.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= github.com/samber/mo v1.11.0 h1:ZOiSkrGGpNhVv/1dxP02risztdMTIwE8KSW9OG4k5bY= github.com/samber/mo v1.11.0/go.mod h1:BfkrCPuYzVG3ZljnZB783WIJIGk1mcZr9c9CPf8tAxs= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= diff --git a/backend/internal/app/server.go b/backend/internal/app/server.go index 79df7cd10..53f96512a 100644 --- a/backend/internal/app/server.go +++ b/backend/internal/app/server.go @@ -15,6 +15,7 @@ import ( firebase "firebase.google.com/go/v4" "github.com/kelseyhightower/envconfig" + "github.com/redis/go-redis/v9" "github.com/harehare/textusm/internal/domain/service" itemRepo "github.com/harehare/textusm/internal/infra/firebase/item" @@ -49,6 +50,7 @@ type Env struct { GithubClientSecret string `envconfig:"GITHUB_CLIENT_SECRET" default:""` StorageBucketName string `required:"true" envconfig:"STORAGE_BUCKET_NAME"` GoEnv string `required:"true" envconfig:"GO_ENV"` + RedisUrl string `required:"false" envconfig:"REDIS_URL"` } var ( @@ -113,11 +115,23 @@ func Run() int { return 1 } + var rdb *redis.Client + + if env.RedisUrl != "" { + opts, err := redis.ParseURL(env.RedisUrl) + + if err != nil { + slog.Error("error initializing redis", "error", err) + return 1 + } + rdb = redis.NewClient(opts) + } + repo := itemRepo.NewFirestoreItemRepository(firestore, storage) shareRepo := shareRepo.NewFirestoreShareRepository(firestore, storage) userRepo := userRepo.NewFirebaseUserRepository(app) gistRepo := itemRepo.NewFirestoreGistItemRepository(firestore) - settingsRepo := settingsRepo.NewFirestoreSettingsRepository(firestore) + settingsRepo := settingsRepo.NewFirestoreSettingsRepository(firestore, storage, rdb) itemService := service.NewService(repo, shareRepo, userRepo) gistService := service.NewGistService(gistRepo, env.GithubClientID, env.GithubClientSecret) settingsService := service.NewSettingsService(settingsRepo, env.GithubClientID, env.GithubClientSecret) @@ -144,7 +158,7 @@ func Run() int { } }) - restApi := api.New(*gistService) + restApi := api.New(*gistService, *settingsService) r.Route("/api/v1", func(r chi.Router) { r.Use(chiMiddleware.AllowContentType("application/json")) diff --git a/backend/internal/domain/repository/settings/settings.go b/backend/internal/domain/repository/settings/settings.go index 3125dc86b..a2426a4ea 100644 --- a/backend/internal/domain/repository/settings/settings.go +++ b/backend/internal/domain/repository/settings/settings.go @@ -10,5 +10,6 @@ import ( type SettingsRepository interface { Find(ctx context.Context, userID string, diagram values.Diagram) mo.Result[*settings.Settings] + FindFontList(ctx context.Context, lang string) mo.Result[[]string] Save(ctx context.Context, userID string, diagram values.Diagram, settings settings.Settings) mo.Result[*settings.Settings] } diff --git a/backend/internal/domain/service/service_test.go b/backend/internal/domain/service/service_test.go index 75263f66c..dd326fb56 100644 --- a/backend/internal/domain/service/service_test.go +++ b/backend/internal/domain/service/service_test.go @@ -35,7 +35,7 @@ func (m *MockItemRepository) FindByID(ctx context.Context, userID string, itemID return ret.Get(0).(mo.Result[*diagramitem.DiagramItem]) } -func (m *MockItemRepository) Find(ctx context.Context, userID string, offset, limit int, isPublic bool, isBookmark bool) mo.Result[[]*diagramitem.DiagramItem] { +func (m *MockItemRepository) Find(ctx context.Context, userID string, offset, limit int, isPublic bool, isBookmark bool, shouldLoadText bool) mo.Result[[]*diagramitem.DiagramItem] { ret := m.Called(ctx, userID, offset, limit, isPublic) return ret.Get(0).(mo.Result[[]*diagramitem.DiagramItem]) } @@ -85,7 +85,7 @@ func TestFindDiagrams(t *testing.T) { i := diagramitem.New().WithID("id").WithPlainText(baseText).Build().OrEmpty() items := []*diagramitem.DiagramItem{i} - mockItemRepo.On("Find", ctx, "userID", 0, 10, false).Return(items, nil) + mockItemRepo.On("Find", ctx, "userID", 0, 10, false, false).Return(items, nil) service := NewService(mockItemRepo, mockShareRepo, mockUserRepo) fields := make(map[string]struct{}) diff --git a/backend/internal/domain/service/settingsservice.go b/backend/internal/domain/service/settingsservice.go index 751313973..723d7bf8b 100644 --- a/backend/internal/domain/service/settingsservice.go +++ b/backend/internal/domain/service/settingsservice.go @@ -39,3 +39,7 @@ func (s *SettingsService) Save(ctx context.Context, diagram v.Diagram, settings return s.repo.Save(ctx, values.GetUID(ctx).OrEmpty(), diagram, *settings) } + +func (s *SettingsService) FindFontList(ctx context.Context, lang string) mo.Result[[]string] { + return s.repo.FindFontList(ctx, lang) +} diff --git a/backend/internal/infra/firebase/settings/settings.go b/backend/internal/infra/firebase/settings/settings.go index 626582386..9c9db1ca7 100644 --- a/backend/internal/infra/firebase/settings/settings.go +++ b/backend/internal/infra/firebase/settings/settings.go @@ -2,13 +2,18 @@ package settings import ( "context" + "log/slog" + "strings" + "time" "cloud.google.com/go/firestore" + "firebase.google.com/go/v4/storage" "github.com/harehare/textusm/internal/domain/model/settings" - settingsModel "github.com/harehare/textusm/internal/domain/model/settings" settingsRepo "github.com/harehare/textusm/internal/domain/repository/settings" "github.com/harehare/textusm/internal/domain/values" e "github.com/harehare/textusm/internal/error" + "github.com/harehare/textusm/internal/infra/firebase" + "github.com/redis/go-redis/v9" "github.com/samber/mo" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -20,11 +25,13 @@ const ( ) type FirestoreSettingsRepository struct { - client *firestore.Client + client *firestore.Client + storage *storage.Client + redis *redis.Client } -func NewFirestoreSettingsRepository(client *firestore.Client) settingsRepo.SettingsRepository { - return &FirestoreSettingsRepository{client: client} +func NewFirestoreSettingsRepository(client *firestore.Client, storage *storage.Client, redis *redis.Client) settingsRepo.SettingsRepository { + return &FirestoreSettingsRepository{client: client, storage: storage, redis: redis} } func (r *FirestoreSettingsRepository) Find(ctx context.Context, userID string, diagram values.Diagram) mo.Result[*settings.Settings] { @@ -38,7 +45,7 @@ func (r *FirestoreSettingsRepository) Find(ctx context.Context, userID string, d return mo.Err[*settings.Settings](err) } - var s settingsModel.Settings + var s settings.Settings if err := fields.DataTo(&s); err != nil { return mo.Err[*settings.Settings](err) } @@ -46,6 +53,57 @@ func (r *FirestoreSettingsRepository) Find(ctx context.Context, userID string, d return mo.Ok(&s) } +func (r *FirestoreSettingsRepository) FindFontList(ctx context.Context, lang string) mo.Result[[]string] { + cacheKey := "fontlist_" + lang + + if r.redis != nil { + cachedFontList, err := r.redis.Get(ctx, cacheKey).Result() + + if err == nil && err != redis.Nil && cachedFontList != "" { + return mo.Ok(strings.Split(cachedFontList, "\n")) + } + } + + storage := firebase.NewCloudStorage(r.storage) + fontListResult := storage.Get(ctx, "fontlist", "all") + + if fontListResult.IsError() { + return mo.Err[[]string](fontListResult.Error()) + } + + langFontListResult := storage.Get(ctx, "fontlist", lang) + + if langFontListResult.IsError() { + return mo.Ok(strings.Split(fontListResult.OrEmpty(), "\n")) + } + + fontList := append(strings.Split(fontListResult.OrEmpty(), "\n"), strings.Split(langFontListResult.OrEmpty(), "\n")...) + + if r.redis != nil { + _, err := r.redis.Pipelined(ctx, func(pipe redis.Pipeliner) error { + err := pipe.Set(ctx, cacheKey, strings.Join(fontList, "\n"), 0).Err() + + if err != nil { + return err + } + + err = pipe.Expire(ctx, cacheKey, time.Hour).Err() + + if err != nil { + return err + } + + return nil + }) + + if err != nil { + slog.Error("Failed to cache font list", "error", err) + } + } + + return mo.Ok(append(strings.Split(fontListResult.OrEmpty(), "\n"), strings.Split(langFontListResult.OrEmpty(), "\n")...)) +} + func (r *FirestoreSettingsRepository) Save(ctx context.Context, userID string, diagram values.Diagram, s settings.Settings) mo.Result[*settings.Settings] { _, err := r.client.Collection(usersCollection).Doc(userID).Collection(settingsCollection).Doc(diagram.String()).Set(ctx, s) diff --git a/backend/internal/presentation/api/api.go b/backend/internal/presentation/api/api.go index 38973768a..6395c2f21 100644 --- a/backend/internal/presentation/api/api.go +++ b/backend/internal/presentation/api/api.go @@ -10,10 +10,11 @@ import ( type Api struct { gistService service.GistService + settingsService service.SettingsService } -func New(gistService service.GistService) *Api { - api := Api{gistService: gistService} +func New(gistService service.GistService, settingsService service.SettingsService) *Api { + api := Api{gistService: gistService, settingsService: settingsService} return &api } @@ -48,7 +49,14 @@ func (a *Api) RevokeGistToken(w http.ResponseWriter, r *http.Request) { } func (a *Api) UsableFontList(w http.ResponseWriter, r *http.Request) { - err := json.NewEncoder(w).Encode(GetFontList(r.URL.Query().Get("lang"))) + fontList := a.settingsService.FindFontList(r.Context(), r.URL.Query().Get("lang")) + + if fontList.IsError() { + w.WriteHeader(http.StatusInternalServerError) + return + } + + err := json.NewEncoder(w).Encode(fontList.OrElse([]string{})) if err != nil { w.WriteHeader(http.StatusInternalServerError) diff --git a/backend/internal/presentation/api/fontlist.go b/backend/internal/presentation/api/fontlist.go deleted file mode 100644 index dac873f0b..000000000 --- a/backend/internal/presentation/api/fontlist.go +++ /dev/null @@ -1,979 +0,0 @@ -package api - -var defaultFontList = []string{ - "ABeeZee", - "Abel", - "Abhaya Libre", - "Abril Fatface", - "Aclonica", - "Acme", - "Actor", - "Adamina", - "Advent Pro", - "Aguafina Script", - "Akronim", - "Aladin", - "Aldrich", - "Alef", - "Alegreya", - "Alegreya Sans", - "Alegreya Sans SC", - "Alegreya SC", - "Aleo", - "Alex Brush", - "Alfa Slab One", - "Alice", - "Alike", - "Alike Angular", - "Allan", - "Allerta", - "Allerta Stencil", - "Allura", - "Almarai", - "Almendra", - "Almendra Display", - "Almendra SC", - "Amarante", - "Amaranth", - "Amatic SC", - "Amethysta", - "Amiko", - "Amiri", - "Amita", - "Anaheim", - "Andada", - "Andika", - "Angkor", - "Annie Use Your Telescope", - "Anonymous Pro", - "Antic", - "Antic Didone", - "Antic Slab", - "Anton", - "Arapey", - "Arbutus", - "Arbutus Slab", - "Architects Daughter", - "Archivo", - "Archivo Black", - "Archivo Narrow", - "Aref Ruqaa", - "Arima Madurai", - "Arimo", - "Arizonia", - "Armata", - "Arsenal", - "Artifika", - "Arvo", - "Arya", - "Asap", - "Asap Condensed", - "Asar", - "Asset", - "Assistant", - "Astloch", - "Asul", - "Athiti", - "Atma", - "Atomic Age", - "Aubrey", - "Audiowide", - "Autour One", - "Average", - "Average Sans", - "Averia Gruesa Libre", - "Averia Libre", - "Averia Sans Libre", - "Averia Serif Libre", - "B612", - "B612 Mono", - "Bad Script", - "Bahiana", - "Bahianita", - "Bai Jamjuree", - "Baloo", - "Baloo Bhai", - "Baloo Bhaijaan", - "Baloo Bhaina", - "Baloo Chettan", - "Baloo Da", - "Baloo Paaji", - "Baloo Tamma", - "Baloo Tammudu", - "Baloo Thambi", - "Balthazar", - "Bangers", - "Barlow", - "Barlow Condensed", - "Barlow Semi Condensed", - "Barriecito", - "Barrio", - "Basic", - "Battambang", - "Baumans", - "Bayon", - "Be Vietnam", - "Belgrano", - "Bellefair", - "Belleza", - "BenchNine", - "Bentham", - "Berkshire Swash", - "Beth Ellen", - "Bevan", - "Big Shoulders Display", - "Big Shoulders Text", - "Bigelow Rules", - "Bigshot One", - "Bilbo", - "Bilbo Swash Caps", - "BioRhyme", - "BioRhyme Expanded", - "Biryani", - "Bitter", - "Black And White Picture", - "Black Han Sans", - "Black Ops One", - "Blinker", - "Bokor", - "Bonbon", - "Boogaloo", - "Bowlby One", - "Bowlby One SC", - "Brawler", - "Bree Serif", - "Bubblegum Sans", - "Bubbler One", - "Buda", - "Buenard", - "Bungee", - "Bungee Hairline", - "Bungee Inline", - "Bungee Outline", - "Bungee Shade", - "Butcherman", - "Butterfly Kids", - "Cabin", - "Cabin Condensed", - "Cabin Sketch", - "Caesar Dressing", - "Cagliostro", - "Cairo", - "Calligraffitti", - "Cambay", - "Cambo", - "Candal", - "Cantarell", - "Cantata One", - "Cantora One", - "Capriola", - "Cardo", - "Carme", - "Carrois Gothic", - "Carrois Gothic SC", - "Carter One", - "Catamaran", - "Caudex", - "Caveat", - "Caveat Brush", - "Cedarville Cursive", - "Ceviche One", - "Chakra Petch", - "Changa", - "Changa One", - "Chango", - "Charm", - "Charmonman", - "Chathura", - "Chau Philomene One", - "Chela One", - "Chelsea Market", - "Chenla", - "Cherry Cream Soda", - "Cherry Swash", - "Chewy", - "Chicle", - "Chilanka", - "Chivo", - "Chonburi", - "Cinzel", - "Cinzel Decorative", - "Clicker Script", - "Coda", - "Coda Caption", - "Codystar", - "Coiny", - "Combo", - "Comfortaa", - "Coming Soon", - "Concert One", - "Condiment", - "Content", - "Contrail One", - "Convergence", - "Cookie", - "Copse", - "Corben", - "Cormorant", - "Cormorant Garamond", - "Cormorant Infant", - "Cormorant SC", - "Cormorant Unicase", - "Cormorant Upright", - "Courgette", - "Cousine", - "Coustard", - "Covered By Your Grace", - "Crafty Girls", - "Creepster", - "Crete Round", - "Crimson Pro", - "Crimson Text", - "Croissant One", - "Crushed", - "Cuprum", - "Cute Font", - "Cutive", - "Cutive Mono", - "Damion", - "Dancing Script", - "Dangrek", - "Darker Grotesque", - "David Libre", - "Dawning of a New Day", - "Days One", - "Dekko", - "Delius", - "Delius Swash Caps", - "Delius Unicase", - "Della Respira", - "Denk One", - "Devonshire", - "Dhurjati", - "Didact Gothic", - "Diplomata", - "Diplomata SC", - "DM Sans", - "DM Serif Display", - "DM Serif Text", - "Do Hyeon", - "Dokdo", - "Domine", - "Donegal One", - "Doppio One", - "Dorsa", - "Dosis", - "Dr Sugiyama", - "Duru Sans", - "Dynalight", - "Eagle Lake", - "East Sea Dokdo", - "Eater", - "EB Garamond", - "Economica", - "Eczar", - "El Messiri", - "Electrolize", - "Elsie", - "Elsie Swash Caps", - "Emblema One", - "Emilys Candy", - "Encode Sans", - "Encode Sans Condensed", - "Encode Sans Expanded", - "Encode Sans Semi Condensed", - "Encode Sans Semi Expanded", - "Engagement", - "Englebert", - "Enriqueta", - "Erica One", - "Esteban", - "Euphoria Script", - "Ewert", - "Exo", - "Exo 2", - "Expletus Sans", - "Fahkwang", - "Fanwood Text", - "Farro", - "Farsan", - "Fascinate", - "Fascinate Inline", - "Faster One", - "Fasthand", - "Fauna One", - "Faustina", - "Federant", - "Federo", - "Felipa", - "Fenix", - "Finger Paint", - "Fira Code", - "Fira Mono", - "Fira Sans", - "Fira Sans Condensed", - "Fira Sans Extra Condensed", - "Fjalla One", - "Fjord One", - "Flamenco", - "Flavors", - "Fondamento", - "Fontdiner Swanky", - "Forum", - "Francois One", - "Frank Ruhl Libre", - "Freckle Face", - "Fredericka the Great", - "Fredoka One", - "Freehand", - "Fresca", - "Frijole", - "Fruktur", - "Fugaz One", - "Gabriela", - "Gaegu", - "Gafata", - "Galada", - "Galdeano", - "Galindo", - "Gamja Flower", - "Gayathri", - "Gentium Basic", - "Gentium Book Basic", - "Geo", - "Geostar", - "Geostar Fill", - "Germania One", - "GFS Didot", - "GFS Neohellenic", - "Gidugu", - "Gilda Display", - "Give You Glory", - "Glass Antiqua", - "Glegoo", - "Gloria Hallelujah", - "Goblin One", - "Gochi Hand", - "Gorditas", - "Gothic A1", - "Goudy Bookletter 1911", - "Graduate", - "Grand Hotel", - "Gravitas One", - "Great Vibes", - "Grenze", - "Griffy", - "Gruppo", - "Gudea", - "Gugi", - "Gurajada", - "Habibi", - "Halant", - "Hammersmith One", - "Hanalei", - "Hanalei Fill", - "Handlee", - "Hanuman", - "Happy Monkey", - "Harmattan", - "Headland One", - "Heebo", - "Henny Penny", - "Hepta Slab", - "Herr Von Muellerhoff", - "Hi Melody", - "Hind", - "Hind Guntur", - "Hind Madurai", - "Hind Siliguri", - "Hind Vadodara", - "Holtwood One SC", - "Homemade Apple", - "Homenaje", - "IBM Plex Mono", - "IBM Plex Sans", - "IBM Plex Sans Condensed", - "IBM Plex Serif", - "Iceberg", - "Iceland", - "IM Fell Double Pica", - "IM Fell Double Pica SC", - "IM Fell DW Pica", - "IM Fell DW Pica SC", - "IM Fell English", - "IM Fell English SC", - "IM Fell French Canon", - "IM Fell French Canon SC", - "IM Fell Great Primer", - "IM Fell Great Primer SC", - "Imprima", - "Inconsolata", - "Inder", - "Indie Flower", - "Inika", - "Inknut Antiqua", - "Irish Grover", - "Istok Web", - "Italiana", - "Italianno", - "Itim", - "Jacques Francois", - "Jacques Francois Shadow", - "Jaldi", - "Jim Nightshade", - "Jockey One", - "Jolly Lodger", - "Jomhuria", - "Josefin Sans", - "Josefin Slab", - "Joti One", - "Jua", - "Judson", - "Julee", - "Julius Sans One", - "Junge", - "Jura", - "Just Another Hand", - "Just Me Again Down Here", - "K2D", - "Kadwa", - "Kalam", - "Kameron", - "Kanit", - "Kantumruy", - "Karla", - "Karma", - "Katibeh", - "Kaushan Script", - "Kavivanar", - "Kavoon", - "Kdam Thmor", - "Keania One", - "Kelly Slab", - "Kenia", - "Khand", - "Khmer", - "Khula", - "Kirang Haerang", - "Kite One", - "Knewave", - "Kodchasan", - "KoHo", - "Kosugi", - "Kosugi Maru", - "Kotta One", - "Koulen", - "Kranky", - "Kreon", - "Kristi", - "Krona One", - "Krub", - "Kumar One", - "Kumar One Outline", - "Kurale", - "La Belle Aurore", - "Lacquer", - "Laila", - "Lakki Reddy", - "Lalezar", - "Lancelot", - "Lateef", - "Lato", - "League Script", - "Leckerli One", - "Ledger", - "Lekton", - "Lemon", - "Lemonada", - "Lexend Deca", - "Lexend Exa", - "Lexend Giga", - "Lexend Mega", - "Lexend Peta", - "Lexend Tera", - "Lexend Zetta", - "Libre Barcode 128", - "Libre Barcode 128 Text", - "Libre Barcode 39", - "Libre Barcode 39 Extended", - "Libre Barcode 39 Extended Text", - "Libre Barcode 39 Text", - "Libre Baskerville", - "Libre Caslon Text", - "Libre Franklin", - "Life Savers", - "Lilita One", - "Lily Script One", - "Limelight", - "Linden Hill", - "Literata", - "Liu Jian Mao Cao", - "Livvic", - "Lobster", - "Lobster Two", - "Londrina Outline", - "Londrina Shadow", - "Londrina Sketch", - "Londrina Solid", - "Long Cang", - "Lora", - "Love Ya Like A Sister", - "Loved by the King", - "Lovers Quarrel", - "Luckiest Guy", - "Lusitana", - "Lustria", - "M PLUS 1p", - "M PLUS Rounded 1c", - "Ma Shan Zheng", - "Macondo", - "Macondo Swash Caps", - "Mada", - "Magra", - "Maiden Orange", - "Maitree", - "Major Mono Display", - "Mako", - "Mali", - "Mallanna", - "Mandali", - "Manjari", - "Mansalva", - "Manuale", - "Marcellus", - "Marcellus SC", - "Marck Script", - "Margarine", - "Markazi Text", - "Marko One", - "Marmelad", - "Martel", - "Martel Sans", - "Marvel", - "Mate", - "Mate SC", - "Maven Pro", - "McLaren", - "Meddon", - "MedievalSharp", - "Medula One", - "Meera Inimai", - "Megrim", - "Meie Script", - "Merienda", - "Merienda One", - "Merriweather", - "Merriweather Sans", - "Metal", - "Metal Mania", - "Metamorphous", - "Metrophobic", - "Michroma", - "Milonga", - "Miltonian", - "Miltonian Tattoo", - "Mina", - "Miniver", - "Miriam Libre", - "Mirza", - "Miss Fajardose", - "Mitr", - "Modak", - "Modern Antiqua", - "Mogra", - "Molengo", - "Molle", - "Monda", - "Monofett", - "Monoton", - "Monsieur La Doulaise", - "Montaga", - "Montez", - "Montserrat", - "Montserrat Alternates", - "Montserrat Subrayada", - "Moul", - "Moulpali", - "Mountains of Christmas", - "Mouse Memoirs", - "Mr Bedfort", - "Mr Dafoe", - "Mr De Haviland", - "Mrs Saint Delafield", - "Mrs Sheppards", - "Mukta", - "Mukta Mahee", - "Mukta Malar", - "Mukta Vaani", - "Muli", - "Mystery Quest", - "Nanum Brush Script", - "Nanum Gothic", - "Nanum Gothic Coding", - "Nanum Myeongjo", - "Nanum Pen Script", - "Neucha", - "Neuton", - "New Rocker", - "News Cycle", - "Niconne", - "Niramit", - "Nixie One", - "Nobile", - "Nokora", - "Norican", - "Nosifer", - "Notable", - "Nothing You Could Do", - "Noticia Text", - "Noto Sans", - "Noto Sans HK", - "Noto Sans JP", - "Noto Sans KR", - "Noto Sans SC", - "Noto Sans TC", - "Noto Serif", - "Noto Serif JP", - "Noto Serif KR", - "Noto Serif SC", - "Noto Serif TC", - "Nova Cut", - "Nova Flat", - "Nova Mono", - "Nova Oval", - "Nova Round", - "Nova Script", - "Nova Slim", - "Nova Square", - "NTR", - "Numans", - "Nunito", - "Nunito Sans", - "Odor Mean Chey", - "Offside", - "Old Standard TT", - "Oldenburg", - "Oleo Script", - "Oleo Script Swash Caps", - "Open Sans", - "Open Sans Condensed", - "Oranienbaum", - "Orbitron", - "Oregano", - "Orienta", - "Original Surfer", - "Oswald", - "Over the Rainbow", - "Overlock", - "Overlock SC", - "Overpass", - "Overpass Mono", - "Ovo", - "Oxygen", - "Oxygen Mono", - "Pacifico", - "Padauk", - "Palanquin", - "Palanquin Dark", - "Pangolin", - "Paprika", - "Parisienne", - "Passero One", - "Passion One", - "Pathway Gothic One", - "Patrick Hand", - "Patrick Hand SC", - "Pattaya", - "Patua One", - "Pavanam", - "Paytone One", - "Peddana", - "Peralta", - "Permanent Marker", - "Petit Formal Script", - "Petrona", - "Philosopher", - "Piedra", - "Pinyon Script", - "Pirata One", - "Plaster", - "Play", - "Playball", - "Playfair Display", - "Playfair Display SC", - "Podkova", - "Poiret One", - "Poller One", - "Poly", - "Pompiere", - "Pontano Sans", - "Poor Story", - "Poppins", - "Port Lligat Sans", - "Port Lligat Slab", - "Pragati Narrow", - "Prata", - "Preahvihear", - "Press Start 2P", - "Pridi", - "Princess Sofia", - "Prociono", - "Prompt", - "Prosto One", - "Proza Libre", - "PT Mono", - "PT Sans", - "PT Sans Caption", - "PT Sans Narrow", - "PT Serif", - "PT Serif Caption", - "Puritan", - "Purple Purse", - "Quando", - "Quantico", - "Quattrocento", - "Quattrocento Sans", - "Questrial", - "Quicksand", - "Quintessential", - "Qwigley", - "Racing Sans One", - "Radley", - "Rajdhani", - "Rakkas", - "Raleway", - "Raleway Dots", - "Ramabhadra", - "Ramaraja", - "Rambla", - "Rammetto One", - "Ranchers", - "Rancho", - "Ranga", - "Rasa", - "Rationale", - "Ravi Prakash", - "Red Hat Display", - "Red Hat Text", - "Redressed", - "Reem Kufi", - "Reenie Beanie", - "Revalia", - "Rhodium Libre", - "Ribeye", - "Ribeye Marrow", - "Righteous", - "Risque", - "Roboto", - "Roboto Condensed", - "Roboto Mono", - "Roboto Slab", - "Rochester", - "Rock Salt", - "Rokkitt", - "Romanesco", - "Ropa Sans", - "Rosario", - "Rosarivo", - "Rouge Script", - "Rozha One", - "Rubik", - "Rubik Mono One", - "Ruda", - "Rufina", - "Ruge Boogie", - "Ruluko", - "Rum Raisin", - "Ruslan Display", - "Russo One", - "Ruthie", - "Rye", - "Sacramento", - "Sahitya", - "Sail", - "Saira", - "Saira Condensed", - "Saira Extra Condensed", - "Saira Semi Condensed", - "Saira Stencil One", - "Salsa", - "Sanchez", - "Sancreek", - "Sansita", - "Sarabun", - "Sarala", - "Sarina", - "Sarpanch", - "Satisfy", - "Sawarabi Gothic", - "Sawarabi Mincho", - "Scada", - "Scheherazade", - "Schoolbell", - "Scope One", - "Seaweed Script", - "Secular One", - "Sedgwick Ave", - "Sedgwick Ave Display", - "Sevillana", - "Seymour One", - "Shadows Into Light", - "Shadows Into Light Two", - "Shanti", - "Share", - "Share Tech", - "Share Tech Mono", - "Shojumaru", - "Short Stack", - "Shrikhand", - "Siemreap", - "Sigmar One", - "Signika", - "Signika Negative", - "Simonetta", - "Single Day", - "Sintony", - "Sirin Stencil", - "Six Caps", - "Skranji", - "Slabo 13px", - "Slabo 27px", - "Slackey", - "Smokum", - "Smythe", - "Sniglet", - "Snippet", - "Snowburst One", - "Sofadi One", - "Sofia", - "Song Myung", - "Sonsie One", - "Sorts Mill Goudy", - "Source Code Pro", - "Source Sans Pro", - "Source Serif Pro", - "Space Mono", - "Special Elite", - "Spectral", - "Spectral SC", - "Spicy Rice", - "Spinnaker", - "Spirax", - "Squada One", - "Sree Krushnadevaraya", - "Sriracha", - "Srisakdi", - "Staatliches", - "Stalemate", - "Stalinist One", - "Stardos Stencil", - "Stint Ultra Condensed", - "Stint Ultra Expanded", - "Stoke", - "Strait", - "Stylish", - "Sue Ellen Francisco", - "Suez One", - "Sumana", - "Sunflower", - "Sunshiney", - "Supermercado One", - "Sura", - "Suranna", - "Suravaram", - "Suwannaphum", - "Swanky and Moo Moo", - "Syncopate", - "Tajawal", - "Tangerine", - "Taprom", - "Tauri", - "Taviraj", - "Teko", - "Telex", - "Tenali Ramakrishna", - "Tenor Sans", - "Text Me One", - "Thasadith", - "The Girl Next Door", - "Tienne", - "Tillana", - "Timmana", - "Tinos", - "Titan One", - "Titillium Web", - "Trade Winds", - "Trirong", - "Trocchi", - "Trochut", - "Trykker", - "Tulpen One", - "Turret Road", - "Ubuntu", - "Ubuntu Condensed", - "Ubuntu Mono", - "Ultra", - "Uncial Antiqua", - "Underdog", - "Unica One", - "UnifrakturCook", - "UnifrakturMaguntia", - "Unkempt", - "Unlock", - "Unna", - "Vampiro One", - "Varela", - "Varela Round", - "Vast Shadow", - "Vesper Libre", - "Vibes", - "Vibur", - "Vidaloka", - "Viga", - "Voces", - "Volkhov", - "Vollkorn", - "Vollkorn SC", - "Voltaire", - "VT323", - "Waiting for the Sunrise", - "Wallpoet", - "Walter Turncoat", - "Warnes", - "Wellfleet", - "Wendy One", - "Wire One", - "Work Sans", - "Yanone Kaffeesatz", - "Yantramanav", - "Yatra One", - "Yellowtail", - "Yeon Sung", - "Yeseva One", - "Yesteryear", - "Yrsa", - "ZCOOL KuaiLe", - "ZCOOL QingKe HuangYou", - "ZCOOL XiaoWei", - "Zeyada", - "Zhi Mang Xing", - "Zilla Slab", - "Zilla Slab Highlight"} - -var extendFontList = map[string][]string{"ja": { - "M PLUS 1p", - "M PLUS Rounded 1c", - "Hannari", - "Kokoro", - "Sawarabi Mincho", - "Nico Moji", - "Nikukyu", - "Noto Sans JP", -}} - -func GetFontList(lang string) []string { - if ja, ok := extendFontList[lang]; ok { - return append(ja, defaultFontList...) - } - return defaultFontList -} diff --git a/backend/justfile b/backend/justfile index 8721ea954..b0494056e 100644 --- a/backend/justfile +++ b/backend/justfile @@ -12,6 +12,17 @@ setup: go install golang.org/x/tools/go/analysis/passes/fieldalignment/cmd/fieldalignment@latest go install github.com/cosmtrek/air@latest +docker-up: + #!/usr/bin/env bash + type docker &>/dev/null + docker_exist=$? + docker ps &>/dev/null + docker_startd=$? + + if [ $docker_exist -eq 0 ] && [ $docker_startd -eq 0 ]; then + docker compose up -d + fi + run: go run {{ main }} diff --git a/cli/README.md b/cli/README.md index f57e687d5..43078170e 100644 --- a/cli/README.md +++ b/cli/README.md @@ -74,7 +74,7 @@ TextUSM Press Shift + Tab to unindent lines: Note ``` -![image](./img/usm.png) +![image](./assets/img/usm.png) ### Business Model Canvas @@ -99,7 +99,7 @@ TextUSM Customer Relationships ``` -![image](./img/bmc.png) +![image](./assets/img/bmc.png) ### Opportunity Canvas @@ -126,7 +126,7 @@ Budget Budget ``` -![image](./img/opc.png) +![image](./assets/img/opc.png) ### 4Ls Retrospective @@ -141,7 +141,7 @@ Longed For longedFor ``` -![image](./img/4ls.png) +![image](./assets/img/4ls.png) ### Start, Stop, Continue Retrospective @@ -154,7 +154,7 @@ Continue continue ``` -![image](./img/ssc.png) +![image](./assets/img/ssc.png) ### KPT Retrospective @@ -167,7 +167,7 @@ Try try ``` -![image](./img/kpt.png) +![image](./assets/img/kpt.png) ### MindMap @@ -183,7 +183,7 @@ TextUSM Share your diagrams online with your colleagues. ``` -![image](./img/mmp.png) +![image](./assets/img/mmp.png) ### Empathy Map @@ -195,7 +195,7 @@ DOES FEELS ``` -![image](./img/emm.png) +![image](./assets/img/emm.png) ### Table @@ -223,7 +223,7 @@ Row2 Column6 ``` -![image](./img/table.png) +![image](./assets/img/table.png) ### Site Map @@ -242,7 +242,7 @@ Home harehare1110@gmail.com ``` -![image](./img/smp.png) +![image](./assets/img/smp.png) ### Gantt Chart @@ -253,7 +253,7 @@ Home 2019-12-31, 2020-01-04: task2 ``` -![image](./img/gct.png) +![image](./assets/img/gct.png) ### Impact Map @@ -269,7 +269,7 @@ TextUSM Share your diagrams online with your colleagues. ``` -![image](./img/imm.png) +![image](./assets/img/imm.png) ### ER Diagram @@ -305,7 +305,7 @@ tables user_id int pk ``` -![image](./img/erd.png) +![image](./assets/img/erd.png) ### Kanban @@ -321,7 +321,7 @@ DONE task3 ``` -![image](./img/kanban.png) +![image](./assets/img/kanban.png) ### Sequence Diagram @@ -355,7 +355,7 @@ Par Sync Message ``` -![image](./img/sed.png) +![image](./assets/img/sed.png) ### Keyboard Layout @@ -429,7 +429,7 @@ r1 1.25u ``` -![image](./img/kbd60.png) +![image](./assets/img/kbd60.png) ## Installation diff --git a/extension/lib/README.md b/extension/lib/README.md index ea6e959d6..aaa0ea434 100644 --- a/extension/lib/README.md +++ b/extension/lib/README.md @@ -78,7 +78,7 @@ TextUSM Press Shift + Tab to unindent lines: Note ``` -![image](./img/usm.png) +![image](./assets/img/usm.png) ### Business Model Canvas @@ -103,7 +103,7 @@ TextUSM Customer Relationships ``` -![image](./img/bmc.png) +![image](./assets/img/bmc.png) ### Opportunity Canvas @@ -130,7 +130,7 @@ Budget Budget ``` -![image](./img/opc.png) +![image](./assets/img/opc.png) ### 4Ls Retrospective @@ -145,7 +145,7 @@ Longed For longedFor ``` -![image](./img/4ls.png) +![image](./assets/img/4ls.png) ### Start, Stop, Continue Retrospective @@ -158,7 +158,7 @@ Continue continue ``` -![image](./img/ssc.png) +![image](./assets/img/ssc.png) ### KPT Retrospective @@ -171,7 +171,7 @@ Try try ``` -![image](./img/kpt.png) +![image](./assets/img/kpt.png) ### MindMap @@ -187,7 +187,7 @@ TextUSM Share your diagrams online with your colleagues. ``` -![image](./img/mmp.png) +![image](./assets/img/mmp.png) ### Empathy Map @@ -199,7 +199,7 @@ DOES FEELS ``` -![image](./img/emm.png) +![image](./assets/img/emm.png) ### Table @@ -227,7 +227,7 @@ Row2 Column6 ``` -![image](./img/table.png) +![image](./assets/img/table.png) ### Site Map @@ -246,7 +246,7 @@ Home harehare1110@gmail.com ``` -![image](./img/smp.png) +![image](./assets/img/smp.png) ### Gantt Chart @@ -257,7 +257,7 @@ Home 2019-12-31, 2020-01-04: task2 ``` -![image](./img/gct.png) +![image](./assets/img/gct.png) ### Impact Map @@ -273,7 +273,7 @@ TextUSM Share your diagrams online with your colleagues. ``` -![image](./img/imm.png) +![image](./assets/img/imm.png) ### ER Diagram @@ -309,7 +309,7 @@ tables user_id int pk ``` -![image](./img/erd.png) +![image](./assets/img/erd.png) ### Kanban @@ -325,7 +325,7 @@ DONE task3 ``` -![image](./img/kanban.png) +![image](./assets/img/kanban.png) ### Sequence Diagram @@ -359,7 +359,7 @@ Par Sync Message ``` -![image](./img/sed.png) +![image](./assets/img/sed.png) ### Keyboard Layout @@ -433,7 +433,7 @@ r1 1.25u ``` -![image](./img/kbd60.png) +![image](./assets/img/kbd60.png) ### Configuration diff --git a/extension/vscode/README.md b/extension/vscode/README.md index 3683b7d0c..f1d73135a 100644 --- a/extension/vscode/README.md +++ b/extension/vscode/README.md @@ -22,7 +22,7 @@ TextISM is a simple tool. Help you draw user story map using indented text. - Sequence Diagram - Keyboard Layout -![image](./img/textusm.gif) +![image](./assets/img/textusm.gif) https://textusm.com @@ -50,7 +50,7 @@ TextUSM Press Shift + Tab to unindent lines: Online tool for Generate a User Story Mapping from indented text. ``` -![image](./img/usm.png) +![image](./assets/img/usm.png) ## Business Model Canvas @@ -75,7 +75,7 @@ TextUSM Customer Relationships ``` -![image](./img/bmc.png) +![image](./assets/img/bmc.png) ## Opportunity Canvas @@ -102,7 +102,7 @@ Budget Budget ``` -![image](./img/opc.png) +![image](./assets/img/opc.png) ### 4Ls Retrospective @@ -117,7 +117,7 @@ Longed For longedFor ``` -![image](./img/4ls.png) +![image](./assets/img/4ls.png) ### Start, Stop, Continue Retrospective @@ -130,7 +130,7 @@ Continue continue ``` -![image](./img/ssc.png) +![image](./assets/img/ssc.png) ### KPT Retrospective @@ -143,7 +143,7 @@ Try try ``` -![image](./img/kpt.png) +![image](./assets/img/kpt.png) ### MindMap @@ -159,7 +159,7 @@ TextUSM Share your diagrams online with your colleagues. ``` -![image](./img/mmp.png) +![image](./assets/img/mmp.png) ### Empathy Map @@ -171,7 +171,7 @@ DOES FEELS ``` -![image](./img/emm.png) +![image](./assets/img/emm.png) ### Table @@ -199,7 +199,7 @@ Row2 Column6 ``` -![image](./img/table.png) +![image](./assets/img/table.png) ### Site Map @@ -218,7 +218,7 @@ Home harehare1110@gmail.com ``` -![image](./img/smp.png) +![image](./assets/img/smp.png) ### Gantt Chart @@ -229,7 +229,7 @@ Home 2019-12-31, 2020-01-04: task2 ``` -![image](./img/gct.png) +![image](./assets/img/gct.png) ### Impact Map @@ -245,7 +245,7 @@ TextUSM Share your diagrams online with your colleagues. ``` -![image](./img/imm.png) +![image](./assets/img/imm.png) ### ER Diagram @@ -281,7 +281,7 @@ tables user_id int pk ``` -![image](./img/erd.png) +![image](./assets/img/erd.png) ### Kanban @@ -297,7 +297,7 @@ DONE task3 ``` -![image](./img/kanban.png) +![image](./assets/img/kanban.png) ### Sequence Diagram @@ -331,7 +331,7 @@ Par Sync Message ``` -![image](./img/sed.png) +![image](./assets/img/sed.png) ### Keyboard Layout @@ -405,7 +405,7 @@ r1 1.25u ``` -![image](./img/kbd60.png) +![image](./assets/img/kbd60.png) ## Options diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 691f044fe..cdbaaeb9d 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "textusm", - "version": "0.14.3", + "version": "0.14.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "textusm", - "version": "0.14.3", + "version": "0.14.4", "license": "MIT", "dependencies": { "@sentry/browser": "^7.83.0", @@ -5001,17 +5001,6 @@ "@types/json-schema": "*" } }, - "node_modules/@types/eslint-scope": { - "version": "3.7.5", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.5.tgz", - "integrity": "sha512-JNvhIEyxVW6EoMIFIvj93ZOywYFatlpu9deeH6eSx6PE3WHYvHaQtmHmQeNw7aA81bYGBPPQqdtBm6b1SsQMmA==", - "dev": true, - "peer": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "node_modules/@types/estree": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", @@ -5529,181 +5518,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@webassemblyjs/ast": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true, - "peer": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true, - "peer": true - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", - "dev": true, - "peer": true - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true, - "peer": true - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "dev": true, - "peer": true, - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "dev": true, - "peer": true, - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true, - "peer": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true, - "peer": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true, - "peer": true - }, "node_modules/@zkochan/retry": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@zkochan/retry/-/retry-0.2.0.tgz", @@ -5777,16 +5591,6 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "dev": true, - "peer": true, - "peerDependencies": { - "acorn": "^8" - } - }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -6860,16 +6664,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6.0" - } - }, "node_modules/ci-info": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", @@ -9810,20 +9604,6 @@ "node": ">=4.0.0" } }, - "node_modules/enhanced-resolve": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", - "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", - "dev": true, - "peer": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -9920,13 +9700,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-module-lexer": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.1.tgz", - "integrity": "sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==", - "dev": true, - "peer": true - }, "node_modules/es-set-tostringtag": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", @@ -10801,20 +10574,6 @@ "integrity": "sha512-+TQ+x4JdTnDoFEXXb3fDvfGOwnyNV7duH8fXWTPD1ieaBmB8omj7Gw/pMBBu4uI2uJCCU8APDaQJzWuXnTsH4A==", "dev": true }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "peer": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/eslint-utils": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", @@ -11293,16 +11052,6 @@ "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", "dev": true }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.8.x" - } - }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -15051,13 +14800,6 @@ "node": ">= 6" } }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true, - "peer": true - }, "node_modules/global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -15285,16 +15027,6 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, - "node_modules/graphql": { - "version": "15.8.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", - "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 10.x" - } - }, "node_modules/graphql-request": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-3.4.0.tgz", @@ -17491,16 +17223,6 @@ "node": ">=8" } }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6.11.5" - } - }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -18530,13 +18252,6 @@ "node": ">= 0.6" } }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, - "peer": true - }, "node_modules/netmask": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", @@ -20878,59 +20593,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, - "peer": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/schema-utils/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "peer": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/schema-utils/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peer": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/schema-utils/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "peer": true - }, "node_modules/semver": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", @@ -22317,16 +21979,6 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, "node_modules/tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", @@ -22441,92 +22093,6 @@ "node": ">=10" } }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.9", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", - "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", - "dev": true, - "peer": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.17", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.16.8" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser-webpack-plugin/node_modules/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, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/terser-webpack-plugin/node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "peer": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", - "dev": true, - "peer": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -23485,20 +23051,6 @@ "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", "dev": true }, - "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", - "dev": true, - "peer": true, - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", @@ -23514,54 +23066,6 @@ "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", "dev": true }, - "node_modules/webpack": { - "version": "5.88.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", - "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", - "dev": true, - "peer": true, - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.15.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, "node_modules/webpack-sources": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", diff --git a/frontend/package.json b/frontend/package.json index 860c706a4..03f883d90 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "textusm", "description": "Online tool for Generate a User Story Mapping from indented text.", - "version": "0.14.3", + "version": "0.14.4", "author": "harehare", "bugs": { "url": "https://github.com/harehare/textusm/issues" @@ -67,8 +67,8 @@ "scripts": { "dev": "concurrently \"npm:dev:*\"", "dev:frontend": "vite", - "dev:backend": "cd ../backend/ && just watch", - "dev:emulators": "cd .. && firebase emulators:start --only firestore,auth,storage", + "dev:backend": "cd ../backend/ && just docker-up && just watch", + "dev:emulators": "cd .. && firebase emulators:exec --only storage 'node ./tools/fontlist/upload.js' --export-on-exit=data && firebase emulators:start --only firestore,auth,storage --import=data && npm run setup:fontlist", "dev:generate-elm-constants": "elm-constants --no-dotenv", "setup:emulators": "cd .. && firebase init emulators", "prod": "NODE_ENV=production NODE_OPTIONS='--max-old-space-size=4096' vite build", diff --git a/frontend/src/elm/Api/Graphql/Selection.elm b/frontend/src/elm/Api/Graphql/Selection.elm index 73f36c51f..0396c6327 100644 --- a/frontend/src/elm/Api/Graphql/Selection.elm +++ b/frontend/src/elm/Api/Graphql/Selection.elm @@ -15,9 +15,12 @@ import Graphql.Scalar import Graphql.SelectionSet as SelectionSet exposing (SelectionSet, hardcoded, with) import Graphql.Union import Graphql.Union.DiagramItem +import Models.Color as Color +import Models.Diagram.CardSize as CardSize import Models.Diagram.Id as DiagramId import Models.Diagram.Item as DiagramItem exposing (DiagramItem) import Models.Diagram.Location as DiagramLocation +import Models.Diagram.Scale as Scale import Models.Diagram.Settings as DiagramSettings import Models.Diagram.Type as DiagramType import Models.Text as Text @@ -89,24 +92,24 @@ settingsSelection : SelectionSet DiagramSettings.Settings Graphql.Object.Setting settingsSelection = SelectionSet.succeed DiagramSettings.Settings |> with Graphql.Object.Settings.font - |> with (SelectionSet.map2 (\w h -> { width = w, height = h }) Graphql.Object.Settings.width Graphql.Object.Settings.height) + |> with (SelectionSet.map2 (\w h -> { width = CardSize.fromInt w, height = CardSize.fromInt h }) Graphql.Object.Settings.width Graphql.Object.Settings.height) |> with (SelectionSet.succeed DiagramSettings.ColorSettings |> with (Graphql.Object.Settings.activityColor colorSelection) |> with (Graphql.Object.Settings.taskColor colorSelection) |> with (Graphql.Object.Settings.storyColor colorSelection) - |> with Graphql.Object.Settings.lineColor - |> with Graphql.Object.Settings.labelColor - |> with Graphql.Object.Settings.textColor + |> with (SelectionSet.map Color.fromString Graphql.Object.Settings.lineColor) + |> with (SelectionSet.map Color.fromString Graphql.Object.Settings.labelColor) + |> with (SelectionSet.map (Maybe.map Color.fromString) Graphql.Object.Settings.textColor) ) - |> with Graphql.Object.Settings.backgroundColor + |> with (SelectionSet.map Color.fromString Graphql.Object.Settings.backgroundColor) |> with Graphql.Object.Settings.zoomControl - |> with Graphql.Object.Settings.scale + |> with (SelectionSet.map (Maybe.map Scale.fromFloat) Graphql.Object.Settings.scale) |> with Graphql.Object.Settings.toolbar -colorSelection : SelectionSet DiagramSettings.Color Graphql.Object.Color +colorSelection : SelectionSet DiagramSettings.ColorSetting Graphql.Object.Color colorSelection = - SelectionSet.succeed DiagramSettings.Color - |> with Graphql.Object.Color.foregroundColor - |> with Graphql.Object.Color.backgroundColor + SelectionSet.succeed DiagramSettings.ColorSetting + |> with (SelectionSet.map Color.fromString Graphql.Object.Color.foregroundColor) + |> with (SelectionSet.map Color.fromString Graphql.Object.Color.backgroundColor) diff --git a/frontend/src/elm/Components/Diagram.elm b/frontend/src/elm/Components/Diagram.elm index ae63d3df2..32192f4c1 100644 --- a/frontend/src/elm/Components/Diagram.elm +++ b/frontend/src/elm/Components/Diagram.elm @@ -53,6 +53,7 @@ import Models.Color as Color import Models.Diagram as Diagram exposing (DragStatus(..), Model, Msg(..), SelectedItem, dragStart) import Models.Diagram.BackgroundImage as BackgroundImage import Models.Diagram.BusinessModelCanvas as BusinessModelCanvasModel +import Models.Diagram.CardSize as CardSize import Models.Diagram.Data as DiagramData import Models.Diagram.ER as ErDiagramModel import Models.Diagram.EmpathyMap as EmpathyMapModel @@ -122,7 +123,7 @@ init settings = , windowSize = Size.zero , diagram = { size = Size.zero - , scale = Scale.fromFloat <| Maybe.withDefault 1.0 settings.scale + , scale = Maybe.withDefault Scale.default settings.scale , position = ( 0, 20 ) , isFullscreen = False } @@ -1357,7 +1358,7 @@ svgView model centerPosition (( svgWidth, svgHeight ) as svgSize) mainSvg = , SvgAttr.y "8" , SvgAttr.fontSize "12" , SvgAttr.fontFamily <| DiagramSettings.fontStyle model.settings - , SvgAttr.fill (model.settings.color.text |> Maybe.withDefault model.settings.color.label) + , SvgAttr.fill <| Color.toString (model.settings.color.text |> Maybe.withDefault model.settings.color.label) ] [ Svg.text (Property.getTitle model.property |> Maybe.withDefault "") ] @@ -1376,7 +1377,7 @@ svgView model centerPosition (( svgWidth, svgHeight ) as svgSize) mainSvg = ++ String.fromFloat (model.diagram.scale |> Scale.toFloat) ++ ")" - , SvgAttr.fill model.settings.backgroundColor + , SvgAttr.fill <| Color.toString model.settings.backgroundColor , SvgAttr.style "will-change: transform;" ] [ mainSvg ] @@ -1406,7 +1407,7 @@ svgView model centerPosition (( svgWidth, svgHeight ) as svgSize) mainSvg = ) ( _, h ) = - Item.getSize item_ ( model.settings.size.width, model.settings.size.height ) + Item.getSize item_ ( CardSize.toInt model.settings.size.width, CardSize.toInt model.settings.size.height ) pos : Position pos = @@ -1701,33 +1702,25 @@ zoomControl isFullscreen scale = zoomIn : Scale -> Model -> Return Msg Model zoomIn step model = - if Scale.toFloat model.diagram.scale <= 10.0 then - Return.singleton - { model - | diagram = - { size = ( Size.getWidth model.diagram.size, Size.getHeight model.diagram.size ) - , scale = Scale.add model.diagram.scale step - , position = model.diagram.position - , isFullscreen = model.diagram.isFullscreen - } - } - - else - Return.singleton model + Return.singleton + { model + | diagram = + { size = ( Size.getWidth model.diagram.size, Size.getHeight model.diagram.size ) + , scale = Scale.add model.diagram.scale step + , position = model.diagram.position + , isFullscreen = model.diagram.isFullscreen + } + } zoomOut : Scale -> Model -> Return Msg Model zoomOut step model = - if Scale.toFloat model.diagram.scale > 0.03 then - Return.singleton - { model - | diagram = - { size = ( Size.getWidth model.diagram.size, Size.getHeight model.diagram.size ) - , scale = Scale.sub model.diagram.scale step - , position = model.diagram.position - , isFullscreen = model.diagram.isFullscreen - } - } - - else - Return.singleton model + Return.singleton + { model + | diagram = + { size = ( Size.getWidth model.diagram.size, Size.getHeight model.diagram.size ) + , scale = Scale.sub model.diagram.scale step + , position = model.diagram.position + , isFullscreen = model.diagram.isFullscreen + } + } diff --git a/frontend/src/elm/Effect/Diagram.elm b/frontend/src/elm/Effect/Diagram.elm index ab774dfe6..3eac7893d 100644 --- a/frontend/src/elm/Effect/Diagram.elm +++ b/frontend/src/elm/Effect/Diagram.elm @@ -18,9 +18,12 @@ module Effect.Diagram exposing import Api.Request as Request import Api.RequestError exposing (RequestError) import Graphql.OptionalArgument as OptionalArgument +import Models.Color as Color +import Models.Diagram.CardSize as CardSize import Models.Diagram.Id as DiagramId exposing (DiagramId) import Models.Diagram.Item as DiagramItem exposing (DiagramItem) import Models.Diagram.Location as DiagramLocation +import Models.Diagram.Scale as Scale import Models.Diagram.Settings as DiagramSettings import Models.Diagram.Type as DiagramType exposing (DiagramType) import Models.LoginProvider as LoginProvider @@ -158,7 +161,7 @@ loadFromShareWithoutPassword msg { session, token } = saveSettingsToLocal : Settings.Settings -> Return.ReturnF msg model saveSettingsToLocal settings = - Settings.settingsEncoder settings |> Ports.saveSettingsToLocal |> Return.command + Settings.encoder settings |> Ports.saveSettingsToLocal |> Return.command saveDiagramSettings : @@ -174,47 +177,47 @@ saveDiagramSettings msg { diagramType, session, settings } = Request.saveSettings (Session.getIdToken session) diagramType - { font = settings.storyMap.font - , width = settings.storyMap.size.width - , height = settings.storyMap.size.height - , backgroundColor = settings.storyMap.backgroundColor + { font = settings.diagramSettings.font + , width = CardSize.toInt settings.diagramSettings.size.width + , height = CardSize.toInt settings.diagramSettings.size.height + , backgroundColor = Color.toString settings.diagramSettings.backgroundColor , activityColor = - { foregroundColor = settings.storyMap.color.activity.color - , backgroundColor = settings.storyMap.color.activity.backgroundColor + { foregroundColor = Color.toString settings.diagramSettings.color.activity.color + , backgroundColor = Color.toString settings.diagramSettings.color.activity.backgroundColor } , taskColor = - { foregroundColor = settings.storyMap.color.task.color - , backgroundColor = settings.storyMap.color.task.backgroundColor + { foregroundColor = Color.toString settings.diagramSettings.color.task.color + , backgroundColor = Color.toString settings.diagramSettings.color.task.backgroundColor } , storyColor = - { foregroundColor = settings.storyMap.color.story.color - , backgroundColor = settings.storyMap.color.story.backgroundColor + { foregroundColor = Color.toString settings.diagramSettings.color.story.color + , backgroundColor = Color.toString settings.diagramSettings.color.story.backgroundColor } - , lineColor = settings.storyMap.color.line - , labelColor = settings.storyMap.color.label + , lineColor = Color.toString settings.diagramSettings.color.line + , labelColor = Color.toString settings.diagramSettings.color.label , textColor = - case settings.storyMap.color.text of + case settings.diagramSettings.color.text of Just c -> - OptionalArgument.Present c + OptionalArgument.Present <| Color.toString c Nothing -> OptionalArgument.Absent , zoomControl = - case settings.storyMap.zoomControl of + case settings.diagramSettings.zoomControl of Just z -> OptionalArgument.Present z Nothing -> OptionalArgument.Absent , scale = - case settings.storyMap.scale of + case settings.diagramSettings.scale of Just s -> - OptionalArgument.Present s + OptionalArgument.Present <| Scale.toFloat s Nothing -> OptionalArgument.Absent , toolbar = - case settings.storyMap.toolbar of + case settings.diagramSettings.toolbar of Just z -> OptionalArgument.Present z diff --git a/frontend/src/elm/Effect/Settings.elm b/frontend/src/elm/Effect/Settings.elm index a329ba911..630e77948 100644 --- a/frontend/src/elm/Effect/Settings.elm +++ b/frontend/src/elm/Effect/Settings.elm @@ -7,6 +7,9 @@ module Effect.Settings exposing import Api.Request as Request import Api.RequestError exposing (RequestError) import Graphql.OptionalArgument as OptionalArgument +import Models.Color as Color +import Models.Diagram.CardSize as CardSize +import Models.Diagram.Scale as Scale import Models.Diagram.Settings as DiagramSettings import Models.Diagram.Type as DiagramType exposing (DiagramType) import Models.Session as Session exposing (Session) @@ -50,7 +53,7 @@ load msg { cache, diagramType, session } = saveToLocal : Settings.Settings -> Return.ReturnF msg model saveToLocal settings = - Settings.settingsEncoder settings |> Ports.saveSettingsToLocal |> Return.command + Settings.encoder settings |> Ports.saveSettingsToLocal |> Return.command save : @@ -66,47 +69,47 @@ save msg { diagramType, session, settings } = Request.saveSettings (Session.getIdToken session) diagramType - { font = settings.storyMap.font - , width = settings.storyMap.size.width - , height = settings.storyMap.size.height - , backgroundColor = settings.storyMap.backgroundColor + { font = settings.diagramSettings.font + , width = CardSize.toInt settings.diagramSettings.size.width + , height = CardSize.toInt settings.diagramSettings.size.height + , backgroundColor = Color.toString settings.diagramSettings.backgroundColor , activityColor = - { foregroundColor = settings.storyMap.color.activity.color - , backgroundColor = settings.storyMap.color.activity.backgroundColor + { foregroundColor = Color.toString settings.diagramSettings.color.activity.color + , backgroundColor = Color.toString settings.diagramSettings.color.activity.backgroundColor } , taskColor = - { foregroundColor = settings.storyMap.color.task.color - , backgroundColor = settings.storyMap.color.task.backgroundColor + { foregroundColor = Color.toString settings.diagramSettings.color.task.color + , backgroundColor = Color.toString settings.diagramSettings.color.task.backgroundColor } , storyColor = - { foregroundColor = settings.storyMap.color.story.color - , backgroundColor = settings.storyMap.color.story.backgroundColor + { foregroundColor = Color.toString settings.diagramSettings.color.story.color + , backgroundColor = Color.toString settings.diagramSettings.color.story.backgroundColor } - , lineColor = settings.storyMap.color.line - , labelColor = settings.storyMap.color.label + , lineColor = Color.toString settings.diagramSettings.color.line + , labelColor = Color.toString settings.diagramSettings.color.label , textColor = - case settings.storyMap.color.text of + case settings.diagramSettings.color.text of Just c -> - OptionalArgument.Present c + OptionalArgument.Present <| Color.toString c Nothing -> OptionalArgument.Absent , zoomControl = - case settings.storyMap.zoomControl of + case settings.diagramSettings.zoomControl of Just z -> OptionalArgument.Present z Nothing -> OptionalArgument.Absent , scale = - case settings.storyMap.scale of + case settings.diagramSettings.scale of Just s -> - OptionalArgument.Present s + OptionalArgument.Present <| Scale.toFloat s Nothing -> OptionalArgument.Absent , toolbar = - case settings.storyMap.toolbar of + case settings.diagramSettings.toolbar of Just z -> OptionalArgument.Present z diff --git a/frontend/src/elm/Main.elm b/frontend/src/elm/Main.elm index 431e6ee68..7f4f74570 100644 --- a/frontend/src/elm/Main.elm +++ b/frontend/src/elm/Main.elm @@ -30,6 +30,7 @@ import Html.Styled.Events as E import Html.Styled.Lazy as Lazy import Json.Decode as D import Message exposing (Message) +import Models.Color as Color import Models.Diagram as DiagramModel import Models.Diagram.Id as DiagramId import Models.Diagram.Item as DiagramItem exposing (DiagramItem) @@ -38,7 +39,7 @@ import Models.Diagram.Scale as Scale import Models.Diagram.Settings as DiagramSettings import Models.Diagram.Type as DiagramType exposing (DiagramType(..)) import Models.Dialog as Dialog -import Models.Exporter as Exporter +import Models.Export.Diagram as ExportDiagram import Models.Hotkey as Hotkey import Models.IdToken as IdToken import Models.Jwt as Jwt @@ -52,7 +53,6 @@ import Models.Settings as Settings ( Settings , defaultEditorSettings , defaultSettings - , settingsDecoder ) import Models.SettingsCache as SettingsCache import Models.ShareState as ShareState @@ -320,11 +320,11 @@ init flags url key = DiagramList.init Session.guest lang Env.apiRoot flags.isOnline ( diagramModel, _ ) = - Diagram.init initSettings.storyMap + Diagram.init initSettings.diagramSettings initSettings : Settings initSettings = - D.decodeValue settingsDecoder flags.settings + D.decodeValue Settings.decoder flags.settings |> Result.withDefault (defaultSettings (Theme.System flags.isDarkMode)) lang : Message.Lang @@ -336,12 +336,12 @@ init flags url key = { key = key , url = url , page = Page.Main - , diagramModel = { diagramModel | text = Text.fromString (Maybe.withDefault "" initSettings.text) } + , diagramModel = { diagramModel | text = Maybe.withDefault Text.empty initSettings.text } , diagramListModel = diagramListModel , settingsModel = settingsModel , shareModel = shareModel , session = Session.guest - , currentDiagram = { currentDiagram | title = Title.fromString (Maybe.withDefault "" initSettings.title) } + , currentDiagram = { currentDiagram | title = Maybe.withDefault Title.untitled initSettings.title } , openMenu = Nothing , window = Window.init <| Maybe.withDefault 0 initSettings.position , progress = False @@ -611,7 +611,7 @@ setDiagramSettings settings = in { m | diagramModel = m.diagramModel |> DiagramModel.settings.set settings - , settingsModel = { newSettings | settings = m.settingsModel.settings |> Settings.storyMapOfSettings.set settings } + , settingsModel = { newSettings | settings = m.settingsModel.settings |> Settings.ofDiagramSettings.set settings } } ) >> setDiagramSettingsCache settings @@ -879,7 +879,7 @@ update model message = |> Return.mapBoth M.UpdateSettings (\model_ -> { m - | diagramModel = m.diagramModel |> DiagramModel.settings.set model_.settings.storyMap + | diagramModel = m.diagramModel |> DiagramModel.settings.set model_.settings.diagramSettings , page = Page.Settings , settingsModel = model_ } @@ -908,7 +908,7 @@ update model message = ( posX, posY ) = model.diagramModel.diagram.position in - Exporter.export + ExportDiagram.export exportDiagram { data = model.diagramModel.data , diagramType = model.diagramModel.diagramType @@ -1024,7 +1024,7 @@ update model message = , diagramType = diagramType , settings = model.settingsModel.settings } - >> setDiagramSettingsCache model.settingsModel.settings.storyMap + >> setDiagramSettingsCache model.settingsModel.settings.diagramSettings _ -> pushUrl (Url.toString url) @@ -1041,16 +1041,10 @@ update model message = newSettings = { position = Just model.window.position , font = model.settingsModel.settings.font - , diagramId = Maybe.map DiagramId.toString model.currentDiagram.id - , storyMap = - DiagramSettings.ofScale.set - (model.diagramModel.diagram.scale - |> Scale.toFloat - |> Just - ) - newStoryMap.storyMap - , text = Just (Text.toString model.diagramModel.text) - , title = Just <| Title.toString model.currentDiagram.title + , diagramId = model.currentDiagram.id + , diagramSettings = DiagramSettings.ofScale.set (Just model.diagramModel.diagram.scale) newStoryMap.diagramSettings + , text = Just model.diagramModel.text + , title = Just model.currentDiagram.title , editor = model.settingsModel.settings.editor , diagram = Just model.currentDiagram , location = model.settingsModel.settings.location @@ -1220,11 +1214,11 @@ update model message = setDiagramSettings settings >> stopProgress M.LoadSettings (Err _) -> - setDiagramSettings (.storyMap (defaultSettings (Theme.System model.browserStatus.isDarkMode))) + setDiagramSettings (.diagramSettings (defaultSettings (Theme.System model.browserStatus.isDarkMode))) >> stopProgress M.LoadSettingsFromLocal settingsJson -> - D.decodeValue settingsDecoder settingsJson + D.decodeValue Settings.decoder settingsJson |> Result.toMaybe |> Maybe.map (\settings -> @@ -1241,7 +1235,7 @@ update model message = , usableFontList = BoolEx.toMaybe m.settingsModel.usableFontList (Settings.isFetchedUsableFont m.settingsModel) } in - { m | settingsModel = newSettingsModel, diagramModel = DiagramModel.settings.set settings.storyMap m.diagramModel } + { m | settingsModel = newSettingsModel, diagramModel = DiagramModel.settings.set settings.diagramSettings m.diagramModel } ) ) |> Maybe.withDefault (showWarningMessage Message.messageFailedLoadSettings) @@ -1437,8 +1431,24 @@ updateSettings msg diagramType = , session = m.session , settings = m.settingsModel.settings } - |> setDiagramSettingsCache m.settingsModel.settings.storyMap + |> setDiagramSettingsCache m.settingsModel.settings.diagramSettings + ) + + Settings.LoadSettings (Ok settings) -> + Return.andThen + (\m -> + Return.singleton m + |> Effect.Settings.save M.SaveDiagramSettings + { diagramType = diagramType + , session = m.session + , settings = settings + } + |> setDiagramSettingsCache settings.diagramSettings ) + >> showInfoMessage Message.messageImportCompleted + + Settings.LoadSettings (Err _) -> + showErrorMessage Message.messagEerrorOccurred _ -> Return.zero @@ -1548,7 +1558,7 @@ mainView model = ] else - Html.div [ Attr.css [ Style.full, backgroundColor <| Css.hex model.settingsModel.settings.storyMap.backgroundColor ] ] + Html.div [ Attr.css [ Style.full, backgroundColor <| Css.hex <| Color.toString model.settingsModel.settings.diagramSettings.backgroundColor ] ] [ Lazy.lazy Diagram.view model.diagramModel |> Html.map M.UpdateDiagram ] @@ -1559,7 +1569,7 @@ mainView model = if Size.getWidth model.diagramModel.windowSize > 0 && Utils.isPhone (Size.getWidth model.diagramModel.windowSize) then Lazy.lazy3 SwitchWindow.view { onSwitchWindow = M.SwitchWindow - , bgColor = Css.hex model.diagramModel.settings.backgroundColor + , bgColor = Css.hex <| Color.toString model.diagramModel.settings.backgroundColor , window = model.window } (Html.div @@ -1581,7 +1591,7 @@ mainView model = else Lazy.lazy3 SplitWindow.view - { bgColor = Css.hex model.diagramModel.settings.backgroundColor + { bgColor = Css.hex <| Color.toString model.diagramModel.settings.backgroundColor , window = model.window , onToggleEditor = M.ShowEditor , onResize = M.HandleStartWindowResize diff --git a/frontend/src/elm/Models/Color.elm b/frontend/src/elm/Models/Color.elm index 845af51b6..c77abd22c 100644 --- a/frontend/src/elm/Models/Color.elm +++ b/frontend/src/elm/Models/Color.elm @@ -10,6 +10,7 @@ module Models.Color exposing , darkIconColor , decoder , disabledIconColor + , encoder , fromString , gray , green @@ -36,6 +37,7 @@ module Models.Color exposing ) import Json.Decode as D +import Json.Encode as E import Regex @@ -112,6 +114,11 @@ decoder = D.map fromString D.string +encoder : Color -> E.Value +encoder color = + E.string <| toString color + + disabledIconColor : Color disabledIconColor = Color "Disabled icon color" "#848A90" diff --git a/frontend/src/elm/Models/Diagram/CardSize.elm b/frontend/src/elm/Models/Diagram/CardSize.elm new file mode 100644 index 000000000..9fd10d473 --- /dev/null +++ b/frontend/src/elm/Models/Diagram/CardSize.elm @@ -0,0 +1,45 @@ +module Models.Diagram.CardSize exposing (CardSize, decoder, encoder, fromInt, max, min, toInt) + +import Json.Decode as D exposing (Decoder) +import Json.Encode as E + + +type CardSize + = CardSize Int + + +max : Int +max = + 600 + + +min : Int +min = + 50 + + +fromInt : Int -> CardSize +fromInt width = + if width > max then + CardSize max + + else if width < min then + CardSize min + + else + CardSize width + + +toInt : CardSize -> Int +toInt (CardSize w) = + w + + +decoder : Decoder CardSize +decoder = + D.map fromInt D.int + + +encoder : CardSize -> E.Value +encoder width = + E.int <| toInt width diff --git a/frontend/src/elm/Models/Diagram/FreeForm.elm b/frontend/src/elm/Models/Diagram/FreeForm.elm index 7c9e0a570..f09b4489b 100644 --- a/frontend/src/elm/Models/Diagram/FreeForm.elm +++ b/frontend/src/elm/Models/Diagram/FreeForm.elm @@ -7,6 +7,7 @@ module Models.Diagram.FreeForm exposing , size ) +import Models.Diagram.CardSize as CardSize import Models.Diagram.Settings as DiagramSettings import Models.Item as Item exposing (Item, Items) import Models.Item.Settings as ItemSettings @@ -83,8 +84,8 @@ size settings freeForm = ( offsetX, offsetY ) = Item.getOffset item_ in - ( 16 + (modBy 4 i + 1) * (settings.size.width + 32) - , (i // 4 + 1) * (settings.size.height + 32) + ( 16 + (modBy 4 i + 1) * (CardSize.toInt settings.size.width + 32) + , (i // 4 + 1) * (CardSize.toInt settings.size.height + 32) ) |> Tuple.mapBoth (\x -> x + offsetX) (\y -> y + offsetY) ) diff --git a/frontend/src/elm/Models/Diagram/Id.elm b/frontend/src/elm/Models/Diagram/Id.elm index 551ea2232..f23bad75a 100644 --- a/frontend/src/elm/Models/Diagram/Id.elm +++ b/frontend/src/elm/Models/Diagram/Id.elm @@ -1,6 +1,7 @@ -module Models.Diagram.Id exposing (DiagramId, decoder, fromString, isGithubId, toString) +module Models.Diagram.Id exposing (DiagramId, decoder, encoder, fromString, isGithubId, toString) import Json.Decode as D exposing (Decoder) +import Json.Encode as E type DiagramId @@ -12,6 +13,11 @@ decoder = D.map DiagramId D.string +encoder : DiagramId -> E.Value +encoder id_ = + E.string <| toString id_ + + fromString : String -> DiagramId fromString id = DiagramId id diff --git a/frontend/src/elm/Models/Diagram/ImpactMap.elm b/frontend/src/elm/Models/Diagram/ImpactMap.elm index bcc59b469..6e347a5f9 100644 --- a/frontend/src/elm/Models/Diagram/ImpactMap.elm +++ b/frontend/src/elm/Models/Diagram/ImpactMap.elm @@ -1,5 +1,6 @@ module Models.Diagram.ImpactMap exposing (size) +import Models.Diagram.CardSize as CardSize import Models.Diagram.Settings as DiagramSettings import Models.Item as Item exposing (Items) import Models.Size exposing (Size) @@ -7,10 +8,10 @@ import Models.Size exposing (Size) size : DiagramSettings.Settings -> Items -> Int -> Size size settings items hierarchy = - ( (settings.size.width + 24) * ((hierarchy + 1) * 2) + 100 + ( (CardSize.toInt settings.size.width + 24) * ((hierarchy + 1) * 2) + 100 , case Item.head items of Just head -> - Item.getLeafCount head * (settings.size.height + 24) * 2 + Item.getLeafCount head * (CardSize.toInt settings.size.height + 24) * 2 Nothing -> 0 diff --git a/frontend/src/elm/Models/Diagram/Kanban.elm b/frontend/src/elm/Models/Diagram/Kanban.elm index 2d7408d05..51841ce60 100644 --- a/frontend/src/elm/Models/Diagram/Kanban.elm +++ b/frontend/src/elm/Models/Diagram/Kanban.elm @@ -9,6 +9,7 @@ module Models.Diagram.Kanban exposing ) import Constants +import Models.Diagram.CardSize as CardSize import Models.Diagram.Settings as DiagramSettings import Models.Item as Item exposing (Item, Items) import Models.Size exposing (Size) @@ -45,8 +46,8 @@ getCardCount (Kanban lists) = size : DiagramSettings.Settings -> Kanban -> Size size settings kanban = - ( getListCount kanban * (settings.size.width + Constants.itemMargin * 3) - , getCardCount kanban * (settings.size.height + Constants.itemMargin) + Constants.itemMargin * 2 + ( getListCount kanban * (CardSize.toInt settings.size.width + Constants.itemMargin * 3) + , getCardCount kanban * (CardSize.toInt settings.size.height + Constants.itemMargin) + Constants.itemMargin * 2 ) diff --git a/frontend/src/elm/Models/Diagram/MindMap.elm b/frontend/src/elm/Models/Diagram/MindMap.elm index d668bf4e6..0fde33f38 100644 --- a/frontend/src/elm/Models/Diagram/MindMap.elm +++ b/frontend/src/elm/Models/Diagram/MindMap.elm @@ -1,5 +1,6 @@ module Models.Diagram.MindMap exposing (size) +import Models.Diagram.CardSize as CardSize import Models.Diagram.Settings as DiagramSettings import Models.Item as Item exposing (Items) import Models.Size exposing (Size) @@ -7,10 +8,10 @@ import Models.Size exposing (Size) size : DiagramSettings.Settings -> Items -> Int -> Size size settings items hierarchy = - ( (settings.size.width * 2) * (hierarchy * 2) + (settings.size.width * 2) + ( (CardSize.toInt settings.size.width * 2) * (hierarchy * 2) + (CardSize.toInt settings.size.width * 2) , case Item.head items of Just head -> - Item.getLeafCount head * (settings.size.height + 24) + Item.getLeafCount head * (CardSize.toInt settings.size.height + 24) Nothing -> 0 diff --git a/frontend/src/elm/Models/Diagram/Scale.elm b/frontend/src/elm/Models/Diagram/Scale.elm index 368b57b62..2c1e8ca37 100644 --- a/frontend/src/elm/Models/Diagram/Scale.elm +++ b/frontend/src/elm/Models/Diagram/Scale.elm @@ -1,7 +1,9 @@ module Models.Diagram.Scale exposing ( Scale , add + , decoder , default + , encoder , fromFloat , max , min @@ -10,6 +12,9 @@ module Models.Diagram.Scale exposing , toFloat ) +import Json.Decode as D exposing (Decoder) +import Json.Encode as E + type Scale = Scale Float @@ -66,3 +71,13 @@ sub (Scale a) (Scale b) = toFloat : Scale -> Float toFloat (Scale s) = s + + +decoder : Decoder Scale +decoder = + D.map fromFloat D.float + + +encoder : Scale -> E.Value +encoder scale = + E.float <| toFloat scale diff --git a/frontend/src/elm/Models/Diagram/SequenceDiagram.elm b/frontend/src/elm/Models/Diagram/SequenceDiagram.elm index 56c930b07..b56ea91fa 100644 --- a/frontend/src/elm/Models/Diagram/SequenceDiagram.elm +++ b/frontend/src/elm/Models/Diagram/SequenceDiagram.elm @@ -21,6 +21,7 @@ module Models.Diagram.SequenceDiagram exposing import Bool.Extra as BoolEx import Constants import Dict exposing (Dict) +import Models.Diagram.CardSize as CardSize import Models.Diagram.Settings as DiagramSettings import Models.Item as Item exposing (Item, Items) import Models.Size exposing (Size) @@ -186,14 +187,14 @@ size settings sequenceDiagram = diagramHeight = messageCountAll sequenceDiagram * Constants.messageMargin - + settings.size.height + + CardSize.toInt settings.size.height * 4 + Constants.messageMargin + 8 diagramWidth : Int diagramWidth = - participantCount sequenceDiagram * (settings.size.width + Constants.participantMargin) + 8 + participantCount sequenceDiagram * (CardSize.toInt settings.size.width + Constants.participantMargin) + 8 in ( diagramWidth, diagramHeight ) diff --git a/frontend/src/elm/Models/Diagram/Settings.elm b/frontend/src/elm/Models/Diagram/Settings.elm index 697669fa0..d4ed5c3e9 100644 --- a/frontend/src/elm/Models/Diagram/Settings.elm +++ b/frontend/src/elm/Models/Diagram/Settings.elm @@ -1,5 +1,5 @@ module Models.Diagram.Settings exposing - ( Color + ( ColorSetting , ColorSettings , Settings , Size @@ -34,26 +34,28 @@ module Models.Diagram.Settings exposing ) import Css exposing (fontFamilies) -import Models.Color as Color +import Models.Color as Color exposing (Color) +import Models.Diagram.CardSize as CardSize exposing (CardSize) +import Models.Diagram.Scale as Scale exposing (Scale) import Models.Property as Property exposing (Property) import Monocle.Compose as Compose import Monocle.Lens exposing (Lens) import Monocle.Optional exposing (Optional) -type alias Color = - { color : String - , backgroundColor : String +type alias ColorSetting = + { color : Color + , backgroundColor : Color } type alias ColorSettings = - { activity : Color - , task : Color - , story : Color - , line : String - , label : String - , text : Maybe String + { activity : ColorSetting + , task : ColorSetting + , story : ColorSetting + , line : Color + , label : Color + , text : Maybe Color } @@ -61,44 +63,44 @@ type alias Settings = { font : String , size : Size , color : ColorSettings - , backgroundColor : String + , backgroundColor : Color , zoomControl : Maybe Bool - , scale : Maybe Float + , scale : Maybe Scale , toolbar : Maybe Bool } type alias Size = - { width : Int - , height : Int + { width : CardSize + , height : CardSize } default : Settings default = { font = "Nunito Sans" - , size = { width = 140, height = 65 } + , size = { width = CardSize.fromInt 140, height = CardSize.fromInt 65 } , color = { activity = - { color = Color.toString Color.white - , backgroundColor = Color.toString Color.background1Defalut + { color = Color.white + , backgroundColor = Color.background1Defalut } , task = - { color = Color.toString Color.white - , backgroundColor = Color.toString Color.background2Defalut + { color = Color.white + , backgroundColor = Color.background2Defalut } , story = - { color = Color.toString Color.gray - , backgroundColor = Color.toString Color.white + { color = Color.gray + , backgroundColor = Color.white } - , line = Color.toString Color.lineDefalut - , label = Color.toString Color.labelDefalut - , text = Just <| Color.toString Color.textDefalut + , line = Color.lineDefalut + , label = Color.labelDefalut + , text = Just <| Color.textDefalut } , backgroundColor = - Color.toString Color.backgroundDarkDefalut + Color.backgroundDarkDefalut , zoomControl = Just True - , scale = Just 1.0 + , scale = Just Scale.default , toolbar = Nothing } @@ -128,49 +130,49 @@ fontStyle settings = getBackgroundColor : Settings -> Property -> Color.Color getBackgroundColor settings property = Property.getBackgroundColor property - |> Maybe.withDefault (settings.backgroundColor |> Color.fromString) + |> Maybe.withDefault settings.backgroundColor getCardBackgroundColor1 : Settings -> Property -> Color.Color getCardBackgroundColor1 settings property = Property.getCardBackgroundColor1 property - |> Maybe.withDefault (settings.color.activity.backgroundColor |> Color.fromString) + |> Maybe.withDefault settings.color.activity.backgroundColor getCardBackgroundColor2 : Settings -> Property -> Color.Color getCardBackgroundColor2 settings property = Property.getCardBackgroundColor2 property - |> Maybe.withDefault (settings.color.task.backgroundColor |> Color.fromString) + |> Maybe.withDefault settings.color.task.backgroundColor getCardBackgroundColor3 : Settings -> Property -> Color.Color getCardBackgroundColor3 settings property = Property.getCardBackgroundColor3 property - |> Maybe.withDefault (settings.color.story.backgroundColor |> Color.fromString) + |> Maybe.withDefault settings.color.story.backgroundColor getCardForegroundColor1 : Settings -> Property -> Color.Color getCardForegroundColor1 settings property = Property.getCardForegroundColor1 property - |> Maybe.withDefault (settings.color.activity.color |> Color.fromString) + |> Maybe.withDefault settings.color.activity.color getCardForegroundColor2 : Settings -> Property -> Color.Color getCardForegroundColor2 settings property = Property.getCardForegroundColor2 property - |> Maybe.withDefault (settings.color.task.color |> Color.fromString) + |> Maybe.withDefault settings.color.task.color getCardForegroundColor3 : Settings -> Property -> Color.Color getCardForegroundColor3 settings property = Property.getCardForegroundColor3 property - |> Maybe.withDefault (settings.color.story.color |> Color.fromString) + |> Maybe.withDefault settings.color.story.color getLineColor : Settings -> Property -> Color.Color getLineColor settings property = Property.getLineColor property - |> Maybe.withDefault (settings.color.line |> Color.fromString) + |> Maybe.withDefault settings.color.line getTextColor : Settings -> Property -> Color.Color @@ -179,28 +181,25 @@ getTextColor settings property = |> Maybe.withDefault (settings.color.text |> Maybe.withDefault - (Color.textDefalut - |> Color.toString - ) - |> Color.fromString + Color.textDefalut ) -ofActivityBackgroundColor : Lens Settings String +ofActivityBackgroundColor : Lens Settings Color ofActivityBackgroundColor = ofColor |> Compose.lensWithLens colorSettingsOfActivity |> Compose.lensWithLens colorOfBackgroundColor -ofActivityColor : Lens Settings String +ofActivityColor : Lens Settings Color ofActivityColor = ofColor |> Compose.lensWithLens colorSettingsOfActivity |> Compose.lensWithLens colorOfColor -ofBackgroundColor : Lens Settings String +ofBackgroundColor : Lens Settings Color ofBackgroundColor = Lens .backgroundColor (\b a -> { a | backgroundColor = b }) @@ -210,57 +209,57 @@ ofFont = Lens .font (\b a -> { a | font = b }) -ofHeight : Lens Settings Int +ofHeight : Lens Settings CardSize ofHeight = Compose.lensWithLens sizeOfHeight ofSize -ofLabelColor : Lens Settings String +ofLabelColor : Lens Settings Color ofLabelColor = ofColor |> Compose.lensWithLens colorSettingsOfLabel -ofLineColor : Lens Settings String +ofLineColor : Lens Settings Color ofLineColor = ofColor |> Compose.lensWithLens colorSettingsOfLine -ofScale : Lens Settings (Maybe Float) +ofScale : Lens Settings (Maybe Scale) ofScale = Lens .scale (\b a -> { a | scale = b }) -ofStoryBackgroundColor : Lens Settings String +ofStoryBackgroundColor : Lens Settings Color ofStoryBackgroundColor = ofColor |> Compose.lensWithLens colorSettingsOfStory |> Compose.lensWithLens colorOfBackgroundColor -ofStoryColor : Lens Settings String +ofStoryColor : Lens Settings Color ofStoryColor = ofColor |> Compose.lensWithLens colorSettingsOfStory |> Compose.lensWithLens colorOfColor -ofTaskBackgroundColor : Lens Settings String +ofTaskBackgroundColor : Lens Settings Color ofTaskBackgroundColor = ofColor |> Compose.lensWithLens colorSettingsOfTask |> Compose.lensWithLens colorOfBackgroundColor -ofTaskColor : Lens Settings String +ofTaskColor : Lens Settings Color ofTaskColor = ofColor |> Compose.lensWithLens colorSettingsOfTask |> Compose.lensWithLens colorOfColor -ofTextColor : Optional Settings String +ofTextColor : Optional Settings Color ofTextColor = ofColor |> Compose.lensWithOptional colorSettingsOfText @@ -271,7 +270,7 @@ ofToolbar = Lens .toolbar (\b a -> { a | toolbar = b }) -ofWidth : Lens Settings Int +ofWidth : Lens Settings CardSize ofWidth = Compose.lensWithLens sizeOfWidth ofSize @@ -281,42 +280,42 @@ ofZoomControl = Lens .zoomControl (\b a -> { a | zoomControl = b }) -colorOfBackgroundColor : Lens Color String +colorOfBackgroundColor : Lens ColorSetting Color colorOfBackgroundColor = Lens .backgroundColor (\b a -> { a | backgroundColor = b }) -colorOfColor : Lens Color String +colorOfColor : Lens ColorSetting Color colorOfColor = Lens .color (\b a -> { a | color = b }) -colorSettingsOfActivity : Lens ColorSettings Color +colorSettingsOfActivity : Lens ColorSettings ColorSetting colorSettingsOfActivity = Lens .activity (\b a -> { a | activity = b }) -colorSettingsOfLabel : Lens ColorSettings String +colorSettingsOfLabel : Lens ColorSettings Color colorSettingsOfLabel = Lens .label (\b a -> { a | label = b }) -colorSettingsOfLine : Lens ColorSettings String +colorSettingsOfLine : Lens ColorSettings Color colorSettingsOfLine = Lens .line (\b a -> { a | line = b }) -colorSettingsOfStory : Lens ColorSettings Color +colorSettingsOfStory : Lens ColorSettings ColorSetting colorSettingsOfStory = Lens .story (\b a -> { a | story = b }) -colorSettingsOfTask : Lens ColorSettings Color +colorSettingsOfTask : Lens ColorSettings ColorSetting colorSettingsOfTask = Lens .task (\b a -> { a | task = b }) -colorSettingsOfText : Optional ColorSettings String +colorSettingsOfText : Optional ColorSettings Color colorSettingsOfText = Optional .text (\b a -> { a | text = Just b }) @@ -331,11 +330,11 @@ ofSize = Lens .size (\b a -> { a | size = b }) -sizeOfHeight : Lens Size Int +sizeOfHeight : Lens Size CardSize sizeOfHeight = Lens .height (\b a -> { a | height = b }) -sizeOfWidth : Lens Size Int +sizeOfWidth : Lens Size CardSize sizeOfWidth = Lens .width (\b a -> { a | width = b }) diff --git a/frontend/src/elm/Models/Diagram/SiteMap.elm b/frontend/src/elm/Models/Diagram/SiteMap.elm index ef659c1d3..e9849f98b 100644 --- a/frontend/src/elm/Models/Diagram/SiteMap.elm +++ b/frontend/src/elm/Models/Diagram/SiteMap.elm @@ -1,6 +1,7 @@ module Models.Diagram.SiteMap exposing (size) import Constants +import Models.Diagram.CardSize as CardSize import Models.Diagram.Settings as DiagramSettings import Models.Item as Item exposing (Items) import Models.Size exposing (Size) @@ -33,7 +34,7 @@ size settings siteMapitems hierarchy = svgHeight : Int svgHeight = - (settings.size.height + (CardSize.toInt settings.size.height + Constants.itemSpan ) * (maxChildrenCount @@ -42,7 +43,7 @@ size settings siteMapitems hierarchy = svgWidth : Int svgWidth = - (settings.size.width + (CardSize.toInt settings.size.width + Constants.itemSpan ) * Item.length items diff --git a/frontend/src/elm/Models/Diagram/Table.elm b/frontend/src/elm/Models/Diagram/Table.elm index 536fb7127..dd789f0e6 100644 --- a/frontend/src/elm/Models/Diagram/Table.elm +++ b/frontend/src/elm/Models/Diagram/Table.elm @@ -8,6 +8,7 @@ module Models.Diagram.Table exposing ) import Constants +import Models.Diagram.CardSize as CardSize import Models.Diagram.Settings as DiagramSettings import Models.Item as Item exposing (Item, Items) import Models.Size exposing (Size) @@ -43,8 +44,8 @@ from items = size : DiagramSettings.Settings -> Items -> Size size settings items = - ( settings.size.width * ((items |> Item.head |> Maybe.withDefault Item.new |> Item.getChildren |> Item.unwrapChildren |> Item.length) + 1) - , settings.size.height * Item.length items + Constants.itemMargin + ( CardSize.toInt settings.size.width * ((items |> Item.head |> Maybe.withDefault Item.new |> Item.getChildren |> Item.unwrapChildren |> Item.length) + 1) + , CardSize.toInt settings.size.height * Item.length items + Constants.itemMargin ) diff --git a/frontend/src/elm/Models/Diagram/UserStoryMap.elm b/frontend/src/elm/Models/Diagram/UserStoryMap.elm index f7aa12935..be93f5158 100644 --- a/frontend/src/elm/Models/Diagram/UserStoryMap.elm +++ b/frontend/src/elm/Models/Diagram/UserStoryMap.elm @@ -14,6 +14,7 @@ import Bool.Extra as BoolEx import Constants import Dict import List.Extra exposing (scanl) +import Models.Diagram.CardSize as CardSize import Models.Diagram.Settings as DiagramSettings import Models.Item as Item exposing (Items) import Models.Property as Property exposing (Property) @@ -72,8 +73,8 @@ getItems (UserStoryMap userStoryMap) = size : DiagramSettings.Settings -> UserStoryMap -> Size size settings userStoryMap = - ( Constants.leftMargin + (settings.size.width + Constants.itemMargin * 2) * (taskCount userStoryMap + 1) - , (settings.size.height + Constants.itemMargin) * (storyCount userStoryMap + 2) + ( Constants.leftMargin + (CardSize.toInt settings.size.width + Constants.itemMargin * 2) * (taskCount userStoryMap + 1) + , (CardSize.toInt settings.size.height + Constants.itemMargin) * (storyCount userStoryMap + 2) ) diff --git a/frontend/src/elm/Models/Exporter.elm b/frontend/src/elm/Models/Export/Diagram.elm similarity index 98% rename from frontend/src/elm/Models/Exporter.elm rename to frontend/src/elm/Models/Export/Diagram.elm index fb1edbb2f..34999531c 100644 --- a/frontend/src/elm/Models/Exporter.elm +++ b/frontend/src/elm/Models/Export/Diagram.elm @@ -1,4 +1,4 @@ -port module Models.Exporter exposing (Export(..), ExportInfo, copyable, downloadable, export) +port module Models.Export.Diagram exposing (Export(..), ExportInfo, copyable, downloadable, export) import File.Download as Download import Models.Diagram.Data as DiagramData diff --git a/frontend/src/elm/Models/Model.elm b/frontend/src/elm/Models/Model.elm index 7a2c43d65..d867c669f 100644 --- a/frontend/src/elm/Models/Model.elm +++ b/frontend/src/elm/Models/Model.elm @@ -19,7 +19,7 @@ import Models.Diagram.Item exposing (DiagramItem) import Models.Diagram.Settings as DiagramSettings import Models.Diagram.Type exposing (DiagramType) import Models.Dialog exposing (ConfirmDialog) -import Models.Exporter exposing (Export) +import Models.Export.Diagram exposing (Export) import Models.Hotkey exposing (Hotkey) import Models.LoginProvider exposing (LoginProvider) import Models.Notification exposing (Notification) diff --git a/frontend/src/elm/Models/Settings.elm b/frontend/src/elm/Models/Settings.elm index 67dde2e49..92e7b8673 100644 --- a/frontend/src/elm/Models/Settings.elm +++ b/frontend/src/elm/Models/Settings.elm @@ -4,19 +4,22 @@ module Models.Settings exposing , activityBackgroundColor , activityColor , backgroundColor + , decoder , defaultEditorSettings , defaultSettings + , encoder + , exportEncoder , font , fontSize , height + , importDecoder , labelColor + , legacyEncoder , lineColor - , settingsDecoder - , settingsEncoder + , ofDiagramSettings , showLineNumber , storyBackgroundColor , storyColor - , storyMapOfSettings , taskBackgroundColor , taskColor , textColor @@ -27,14 +30,19 @@ module Models.Settings exposing ) import Json.Decode as D -import Json.Decode.Pipeline exposing (optional, required) +import Json.Decode.Pipeline exposing (custom, hardcoded, optional, required) import Json.Encode as E import Json.Encode.Extra exposing (maybe) -import Models.Color as Color +import Models.Color as Color exposing (Color) +import Models.Diagram.CardSize as CardSize exposing (CardSize) +import Models.Diagram.Id as DiagramId exposing (DiagramId) import Models.Diagram.Item as DiagramItem exposing (DiagramItem) import Models.Diagram.Location as DiagramLocation exposing (Location) +import Models.Diagram.Scale as Scale import Models.Diagram.Settings as DiagramSettings +import Models.Text as Text exposing (Text) import Models.Theme as Theme exposing (Theme) +import Models.Title as Title exposing (Title) import Monocle.Compose as Compose import Monocle.Lens exposing (Lens) import Monocle.Optional exposing (Optional) @@ -50,10 +58,10 @@ type alias EditorSettings = type alias Settings = { position : Maybe Int , font : String - , diagramId : Maybe String - , storyMap : DiagramSettings.Settings - , text : Maybe String - , title : Maybe String + , diagramId : Maybe DiagramId + , diagramSettings : DiagramSettings.Settings + , text : Maybe Text + , title : Maybe Title , editor : Maybe EditorSettings , diagram : Maybe DiagramItem , location : Maybe Location @@ -76,41 +84,41 @@ defaultSettings theme = { position = Just -10 , font = "Nunito Sans" , diagramId = Nothing - , storyMap = + , diagramSettings = { font = "Nunito Sans" - , size = { width = 140, height = 65 } + , size = { width = CardSize.fromInt 140, height = CardSize.fromInt 65 } , color = { activity = - { color = Color.toString Color.white - , backgroundColor = Color.toString Color.background1Defalut + { color = Color.white + , backgroundColor = Color.background1Defalut } , task = - { color = Color.toString Color.white - , backgroundColor = Color.toString Color.background2Defalut + { color = Color.white + , backgroundColor = Color.background2Defalut } , story = - { color = Color.toString Color.gray - , backgroundColor = Color.toString Color.white + { color = Color.gray + , backgroundColor = Color.white } - , line = Color.toString Color.lineDefalut - , label = Color.toString Color.labelDefalut - , text = Just <| Color.toString Color.textDefalut + , line = Color.lineDefalut + , label = Color.labelDefalut + , text = Just <| Color.textDefalut } , backgroundColor = case theme of Theme.System True -> - Color.toString Color.backgroundDarkDefalut + Color.backgroundDarkDefalut Theme.System False -> - Color.toString Color.backgroundDefalut + Color.backgroundDefalut Theme.Dark -> - Color.toString Color.backgroundDarkDefalut + Color.backgroundDarkDefalut Theme.Light -> - Color.toString Color.backgroundDefalut + Color.backgroundDefalut , zoomControl = Just True - , scale = Just 1.0 + , scale = Just Scale.default , toolbar = Nothing } , text = Nothing @@ -122,24 +130,24 @@ defaultSettings theme = } -activityBackgroundColor : Lens Settings String +activityBackgroundColor : Lens Settings Color activityBackgroundColor = - Compose.lensWithLens DiagramSettings.ofActivityBackgroundColor storyMapOfSettings + Compose.lensWithLens DiagramSettings.ofActivityBackgroundColor ofDiagramSettings -activityColor : Lens Settings String +activityColor : Lens Settings Color activityColor = - Compose.lensWithLens DiagramSettings.ofActivityColor storyMapOfSettings + Compose.lensWithLens DiagramSettings.ofActivityColor ofDiagramSettings -backgroundColor : Lens Settings String +backgroundColor : Lens Settings Color backgroundColor = - Compose.lensWithLens DiagramSettings.ofBackgroundColor storyMapOfSettings + Compose.lensWithLens DiagramSettings.ofBackgroundColor ofDiagramSettings font : Lens Settings String font = - Compose.lensWithLens DiagramSettings.ofFont storyMapOfSettings + Compose.lensWithLens DiagramSettings.ofFont ofDiagramSettings fontSize : Optional Settings Int @@ -147,19 +155,19 @@ fontSize = Compose.optionalWithLens editorOfFontSize editorOfSettings -height : Lens Settings Int +height : Lens Settings CardSize height = - Compose.lensWithLens DiagramSettings.ofHeight storyMapOfSettings + Compose.lensWithLens DiagramSettings.ofHeight ofDiagramSettings -labelColor : Lens Settings String +labelColor : Lens Settings Color labelColor = - Compose.lensWithLens DiagramSettings.ofLabelColor storyMapOfSettings + Compose.lensWithLens DiagramSettings.ofLabelColor ofDiagramSettings -lineColor : Lens Settings String +lineColor : Lens Settings Color lineColor = - Compose.lensWithLens DiagramSettings.ofLineColor storyMapOfSettings + Compose.lensWithLens DiagramSettings.ofLineColor ofDiagramSettings showLineNumber : Optional Settings Bool @@ -167,39 +175,39 @@ showLineNumber = Compose.optionalWithLens editorOfShowLineNumber editorOfSettings -storyBackgroundColor : Lens Settings String +storyBackgroundColor : Lens Settings Color storyBackgroundColor = - Compose.lensWithLens DiagramSettings.ofStoryBackgroundColor storyMapOfSettings + Compose.lensWithLens DiagramSettings.ofStoryBackgroundColor ofDiagramSettings -storyColor : Lens Settings String +storyColor : Lens Settings Color storyColor = - Compose.lensWithLens DiagramSettings.ofStoryColor storyMapOfSettings + Compose.lensWithLens DiagramSettings.ofStoryColor ofDiagramSettings -taskBackgroundColor : Lens Settings String +taskBackgroundColor : Lens Settings Color taskBackgroundColor = - Compose.lensWithLens DiagramSettings.ofTaskBackgroundColor storyMapOfSettings + Compose.lensWithLens DiagramSettings.ofTaskBackgroundColor ofDiagramSettings -taskColor : Lens Settings String +taskColor : Lens Settings Color taskColor = - Compose.lensWithLens DiagramSettings.ofTaskColor storyMapOfSettings + Compose.lensWithLens DiagramSettings.ofTaskColor ofDiagramSettings -textColor : Optional Settings String +textColor : Optional Settings Color textColor = - Compose.lensWithOptional DiagramSettings.ofTextColor storyMapOfSettings + Compose.lensWithOptional DiagramSettings.ofTextColor ofDiagramSettings toolbar : Lens Settings (Maybe Bool) toolbar = - Compose.lensWithLens DiagramSettings.ofToolbar storyMapOfSettings + Compose.lensWithLens DiagramSettings.ofToolbar ofDiagramSettings -width : Lens Settings Int +width : Lens Settings CardSize width = - Compose.lensWithLens DiagramSettings.ofWidth storyMapOfSettings + Compose.lensWithLens DiagramSettings.ofWidth ofDiagramSettings wordWrap : Optional Settings Bool @@ -209,33 +217,33 @@ wordWrap = zoomControl : Lens Settings (Maybe Bool) zoomControl = - Compose.lensWithLens DiagramSettings.ofZoomControl storyMapOfSettings + Compose.lensWithLens DiagramSettings.ofZoomControl ofDiagramSettings -settingsDecoder : D.Decoder Settings -settingsDecoder = +decoder : D.Decoder Settings +decoder = D.succeed Settings |> optional "position" (D.map Just D.int) Nothing |> required "font" D.string - |> optional "diagramId" (D.map Just D.string) Nothing - |> required "storyMap" diagramDecoder - |> optional "text" (D.map Just D.string) Nothing - |> optional "title" (D.map Just D.string) Nothing + |> optional "diagramId" (D.map Just DiagramId.decoder) Nothing + |> custom (D.oneOf [ D.field "storyMap" diagramDecoder, D.field "diagramSettings" diagramDecoder ]) + |> optional "text" (D.map Just Text.decoder) Nothing + |> optional "title" (D.map Just Title.decoder) Nothing |> optional "editor" (D.map Just editorSettingsDecoder) Nothing |> optional "diagram" (D.map Just DiagramItem.decoder) Nothing - |> optional "location" (D.map Just DiagramLocation.decoder) (Just DiagramLocation.Remote) - |> optional "theme" (D.map Just Theme.decoder) (Just <| Theme.System False) + |> optional "location" (D.map Just DiagramLocation.decoder) Nothing + |> optional "theme" (D.map Just Theme.decoder) Nothing -settingsEncoder : Settings -> E.Value -settingsEncoder settings = +encoder : Settings -> E.Value +encoder settings = E.object [ ( "position", maybe E.int settings.position ) , ( "font", E.string settings.font ) - , ( "diagramId", maybe E.string settings.diagramId ) - , ( "storyMap", diagramEncoder settings.storyMap ) - , ( "text", maybe E.string settings.text ) - , ( "title", maybe E.string settings.title ) + , ( "diagramId", maybe DiagramId.encoder settings.diagramId ) + , ( "diagramSettings", diagramEncoder settings.diagramSettings ) + , ( "text", maybe Text.encoder settings.text ) + , ( "title", maybe Title.encoder settings.title ) , ( "editor", maybe editorSettingsEncoder settings.editor ) , ( "diagram", maybe DiagramItem.encoder settings.diagram ) , ( "location", maybe DiagramLocation.encoder settings.location ) @@ -243,23 +251,66 @@ settingsEncoder settings = ] -storyMapOfSettings : Lens Settings DiagramSettings.Settings -storyMapOfSettings = - Lens .storyMap (\b a -> { a | storyMap = b }) +legacyEncoder : Settings -> E.Value +legacyEncoder settings = + E.object + [ ( "position", maybe E.int settings.position ) + , ( "font", E.string settings.font ) + , ( "diagramId", maybe DiagramId.encoder settings.diagramId ) + , ( "storyMap", diagramEncoder settings.diagramSettings ) + , ( "text", maybe Text.encoder settings.text ) + , ( "title", maybe Title.encoder settings.title ) + , ( "editor", maybe editorSettingsEncoder settings.editor ) + , ( "diagram", maybe DiagramItem.encoder settings.diagram ) + , ( "location", maybe DiagramLocation.encoder settings.location ) + , ( "theme", maybe Theme.encoder settings.theme ) + ] + + +exportEncoder : Settings -> E.Value +exportEncoder settings = + E.object + [ ( "position", maybe E.int settings.position ) + , ( "font", E.string settings.font ) + , ( "diagramSettings", diagramEncoder settings.diagramSettings ) + , ( "editor", maybe editorSettingsEncoder settings.editor ) + , ( "location", maybe DiagramLocation.encoder settings.location ) + , ( "theme", maybe Theme.encoder settings.theme ) + ] + + +importDecoder : Settings -> D.Decoder Settings +importDecoder settings = + D.succeed Settings + |> optional "position" (D.map Just D.int) Nothing + |> required "font" D.string + |> hardcoded settings.diagramId + |> custom (D.oneOf [ D.field "storyMap" diagramDecoder, D.field "diagramSettings" diagramDecoder ]) + |> hardcoded settings.text + |> hardcoded settings.title + |> optional "editor" (D.map Just editorSettingsDecoder) Nothing + |> hardcoded settings.diagram + |> optional "location" (D.map Just DiagramLocation.decoder) (Just DiagramLocation.Remote) + |> optional "theme" (D.map Just Theme.decoder) (Just <| Theme.System False) + + +ofDiagramSettings : Lens Settings DiagramSettings.Settings +ofDiagramSettings = + Lens .diagramSettings (\b a -> { a | diagramSettings = b }) -colorDecoder : D.Decoder DiagramSettings.Color +colorDecoder : D.Decoder DiagramSettings.ColorSetting colorDecoder = - D.succeed DiagramSettings.Color - |> required "color" D.string - |> required "backgroundColor" D.string + D.succeed DiagramSettings.ColorSetting + |> required "color" Color.decoder + |> required "backgroundColor" Color.decoder -colorEncoder : DiagramSettings.Color -> E.Value +colorEncoder : DiagramSettings.ColorSetting -> E.Value colorEncoder color = E.object - [ ( "color", E.string color.color ) - , ( "backgroundColor", E.string color.backgroundColor ) + [ ( "color", Color.encoder color.color ) + , ( "backgroundColor", Color.encoder color.backgroundColor ) ] @@ -269,9 +320,9 @@ colorSettingsDecoder = |> required "activity" colorDecoder |> required "task" colorDecoder |> required "story" colorDecoder - |> required "line" D.string - |> required "label" D.string - |> optional "text" (D.map Just D.string) Nothing + |> required "line" Color.decoder + |> required "label" Color.decoder + |> optional "text" (D.map Just Color.decoder) Nothing colorSettingsEncoder : DiagramSettings.ColorSettings -> E.Value @@ -280,9 +331,9 @@ colorSettingsEncoder colorSettings = [ ( "activity", colorEncoder colorSettings.activity ) , ( "task", colorEncoder colorSettings.task ) , ( "story", colorEncoder colorSettings.story ) - , ( "line", E.string colorSettings.line ) - , ( "label", E.string colorSettings.label ) - , ( "text", maybe E.string colorSettings.text ) + , ( "line", Color.encoder colorSettings.line ) + , ( "label", Color.encoder colorSettings.label ) + , ( "text", maybe Color.encoder colorSettings.text ) ] @@ -292,9 +343,9 @@ diagramDecoder = |> required "font" D.string |> required "size" sizeDecoder |> required "color" colorSettingsDecoder - |> required "backgroundColor" D.string + |> required "backgroundColor" Color.decoder |> optional "zoomControl" (D.map Just D.bool) Nothing - |> optional "scale" (D.map Just D.float) Nothing + |> optional "scale" (D.map Just Scale.decoder) Nothing |> optional "toolbar" (D.map Just D.bool) Nothing @@ -304,9 +355,9 @@ diagramEncoder settings = [ ( "font", E.string settings.font ) , ( "size", sizeEncoder settings.size ) , ( "color", colorSettingsEncoder settings.color ) - , ( "backgroundColor", E.string settings.backgroundColor ) + , ( "backgroundColor", Color.encoder settings.backgroundColor ) , ( "zoomControl", maybe E.bool settings.zoomControl ) - , ( "scale", maybe E.float settings.scale ) + , ( "scale", maybe Scale.encoder settings.scale ) , ( "toolbar", maybe E.bool settings.toolbar ) ] @@ -351,13 +402,13 @@ editorSettingsEncoder editorSettings = sizeDecoder : D.Decoder DiagramSettings.Size sizeDecoder = D.succeed DiagramSettings.Size - |> required "width" D.int - |> required "height" D.int + |> required "width" CardSize.decoder + |> required "height" CardSize.decoder sizeEncoder : DiagramSettings.Size -> E.Value sizeEncoder size = E.object - [ ( "width", E.int size.width ) - , ( "height", E.int size.height ) + [ ( "width", CardSize.encoder size.width ) + , ( "height", CardSize.encoder size.height ) ] diff --git a/frontend/src/elm/Models/Text.elm b/frontend/src/elm/Models/Text.elm index 2221622b4..7f9ffadea 100644 --- a/frontend/src/elm/Models/Text.elm +++ b/frontend/src/elm/Models/Text.elm @@ -4,6 +4,7 @@ module Models.Text exposing , decoder , edit , empty + , encoder , fromString , getLine , isChanged @@ -14,6 +15,7 @@ module Models.Text exposing ) import Json.Decode as D exposing (Decoder) +import Json.Encode as E import List.Extra exposing (getAt) @@ -38,15 +40,12 @@ change text = decoder : Decoder Text decoder = - D.map - (\t -> - if t == "" then - Empty + D.map fromString D.string - else - Saved t - ) - D.string + +encoder : Text -> E.Value +encoder text = + E.string <| toString text edit : Text -> String -> Text diff --git a/frontend/src/elm/Models/Title.elm b/frontend/src/elm/Models/Title.elm index 06a3fed01..f05655185 100644 --- a/frontend/src/elm/Models/Title.elm +++ b/frontend/src/elm/Models/Title.elm @@ -1,4 +1,20 @@ -module Models.Title exposing (Title, edit, fromString, isEdit, isUntitled, isView, map, toString, untitled, view) +module Models.Title exposing + ( Title + , decoder + , edit + , encoder + , fromString + , isEdit + , isUntitled + , isView + , map + , toString + , untitled + , view + ) + +import Json.Decode as D exposing (Decoder) +import Json.Encode as E type Title @@ -122,3 +138,13 @@ view title = View t -> View t + + +decoder : Decoder Title +decoder = + D.map fromString D.string + + +encoder : Title -> E.Value +encoder text = + E.string <| toString text diff --git a/frontend/src/elm/Page/Embed.elm b/frontend/src/elm/Page/Embed.elm index 1104db95a..e74b6dfc0 100644 --- a/frontend/src/elm/Page/Embed.elm +++ b/frontend/src/elm/Page/Embed.elm @@ -17,6 +17,7 @@ import Css import Html.Styled as Html exposing (Html, div) import Html.Styled.Attributes as Attr import Html.Styled.Lazy as Lazy +import Models.Color as Color import Models.Model exposing (Model, Msg(..)) import Style.Color as Color import Style.Style as Style @@ -28,7 +29,7 @@ view model = div [ Attr.css [ border3 (px 1) solid Color.darkTextColor - , backgroundColor <| hex model.settingsModel.settings.storyMap.backgroundColor + , backgroundColor <| hex <| Color.toString model.settingsModel.settings.diagramSettings.backgroundColor , Style.full , position relative ] diff --git a/frontend/src/elm/Page/Settings.elm b/frontend/src/elm/Page/Settings.elm index 2247494a2..5fb56f61f 100644 --- a/frontend/src/elm/Page/Settings.elm +++ b/frontend/src/elm/Page/Settings.elm @@ -35,14 +35,20 @@ import Css , wrap , zero ) -import Html.Styled as Html exposing (Html) +import File exposing (File) +import File.Download as Download +import File.Select as Select +import Html.Styled as Html exposing (Html, i) import Html.Styled.Attributes as Attr import Html.Styled.Events exposing (onClick) +import Json.Decode as D +import Json.Encode as E import Maybe.Extra exposing (isNothing) import Message exposing (Lang) import Models.Color as Color exposing (colors) +import Models.Diagram.CardSize as CardSize import Models.Diagram.Location as DiagramLocation -import Models.Diagram.Type exposing (DiagramType) +import Models.Diagram.Type as DiagramType exposing (DiagramType) import Models.FontSize as FontSize import Models.Session as Session exposing (Session) import Models.Settings as Settings exposing (Settings) @@ -55,6 +61,7 @@ import Style.Style as Style import Style.Text as Text import Task import Views.DropDownList as DropDownList exposing (DropDownValue) +import Views.Icon as Icon import Views.Switch as Switch @@ -79,6 +86,10 @@ type Msg | ToggleDropDownList String | DropDownClose | UpdateUsableFontList (Result RequestError FontList) + | ImportFile File + | Import + | Export + | LoadSettings (Result String Settings) loadUsableFontList : @@ -108,7 +119,7 @@ init { canUseNativeFileSystem, diagramType, session, settings, lang, usableFontL , settings = settings , session = session , canUseNativeFileSystem = canUseNativeFileSystem - , usableFontList = usableFontList |> Maybe.withDefault [ settings.storyMap.font ] + , usableFontList = usableFontList |> Maybe.withDefault [ settings.diagramSettings.font ] , lang = lang , isLoading = False } @@ -125,12 +136,18 @@ load { diagramType, session } = update : Msg -> Return.ReturnF Msg Model update msg = case msg of + LoadSettings (Ok settings) -> + Return.map <| \m -> { m | settings = settings } + + LoadSettings (Err _) -> + Return.zero + UpdateSettings getSetting value -> - Return.map (\m -> { m | dropDownIndex = Nothing, settings = getSetting value }) + Return.map <| \m -> { m | dropDownIndex = Nothing, settings = getSetting value } ToggleDropDownList id -> - Return.map - (\m -> + Return.map <| + \m -> { m | dropDownIndex = if (m.dropDownIndex |> Maybe.withDefault "") == id then @@ -139,16 +156,41 @@ update msg = else Just id } - ) DropDownClose -> - Return.map (\m -> { m | dropDownIndex = Nothing }) + Return.map <| \m -> { m | dropDownIndex = Nothing } UpdateUsableFontList (Ok fontList) -> - Return.map (\m -> { m | usableFontList = fontList, isLoading = False }) + Return.map <| \m -> { m | usableFontList = fontList, isLoading = False } UpdateUsableFontList (Err _) -> - Return.map (\m -> { m | usableFontList = [], isLoading = False }) + Return.map <| \m -> { m | usableFontList = [], isLoading = False } + + Export -> + Return.andThen <| + \m -> + Return.singleton m + |> Return.command + (Download.string ((m.diagramType |> DiagramType.toTypeString |> String.toLower) ++ "_settings.json") + "application/json" + (E.encode + 2 + (Settings.exportEncoder m.settings) + ) + ) + + Import -> + Return.command <| Select.file [ "application/json" ] ImportFile + + ImportFile file -> + Return.andThen <| + \m -> + Return.singleton m + |> (File.toString file + |> Task.map (\s -> D.decodeString (Settings.importDecoder m.settings) s |> Result.mapError D.errorToString) + |> Task.perform LoadSettings + |> Return.command + ) isFetchedUsableFont : Model -> Bool @@ -165,6 +207,7 @@ view model = , session = model.session , usableFontList = model.usableFontList , isLoading = model.isLoading + , lang = model.lang } @@ -273,9 +316,10 @@ view_ : , session : Session , usableFontList : FontList , isLoading : Bool + , lang : Lang } -> Html Msg -view_ { dropDownIndex, canUseNativeFileSystem, settings, session, usableFontList, isLoading } = +view_ { dropDownIndex, canUseNativeFileSystem, settings, session, usableFontList, isLoading, lang } = Html.div [ Attr.css [ Breakpoint.style @@ -325,11 +369,11 @@ view_ { dropDownIndex, canUseNativeFileSystem, settings, session, usableFontList dropDownIndex (UpdateSettings (\x -> - Settings.backgroundColor.set x settings + Settings.backgroundColor.set (Color.fromString x) settings ) ) baseColorItems - settings.storyMap.backgroundColor + (settings.diagramSettings.backgroundColor |> Color.toString) ] ] , conrtolView @@ -381,7 +425,7 @@ view_ { dropDownIndex, canUseNativeFileSystem, settings, session, usableFontList ] , conrtolRowView [ nameView [ Html.text "Zoom Control" ] - , Switch.view (Maybe.withDefault True settings.storyMap.zoomControl) + , Switch.view (Maybe.withDefault True settings.diagramSettings.zoomControl) (\v -> UpdateSettings (\_ -> settings |> Settings.zoomControl.set (Just v)) @@ -390,7 +434,7 @@ view_ { dropDownIndex, canUseNativeFileSystem, settings, session, usableFontList ] , conrtolRowView [ nameView [ Html.text "Toolbar" ] - , Switch.view (Maybe.withDefault True settings.storyMap.toolbar) + , Switch.view (Maybe.withDefault True settings.diagramSettings.toolbar) (\v -> UpdateSettings (\_ -> Settings.toolbar.set (Just v) settings) @@ -450,11 +494,11 @@ view_ { dropDownIndex, canUseNativeFileSystem, settings, session, usableFontList dropDownIndex (UpdateSettings (\x -> - Settings.width.set (String.toInt x |> Maybe.withDefault 150) settings + Settings.width.set (String.toInt x |> Maybe.withDefault 150 |> CardSize.fromInt) settings ) ) baseSizeItems - (String.fromInt settings.storyMap.size.width) + (String.fromInt <| CardSize.toInt settings.diagramSettings.size.width) ] ] , conrtolView @@ -465,11 +509,11 @@ view_ { dropDownIndex, canUseNativeFileSystem, settings, session, usableFontList dropDownIndex (UpdateSettings (\x -> - settings |> Settings.height.set (String.toInt x |> Maybe.withDefault 45) + settings |> Settings.height.set (String.toInt x |> Maybe.withDefault 45 |> CardSize.fromInt) ) ) baseSizeItems - (String.fromInt settings.storyMap.size.height) + (String.fromInt <| CardSize.toInt settings.diagramSettings.size.height) ] ] ] @@ -485,11 +529,11 @@ view_ { dropDownIndex, canUseNativeFileSystem, settings, session, usableFontList dropDownIndex (UpdateSettings (\x -> - Settings.activityBackgroundColor.set x settings + Settings.activityBackgroundColor.set (Color.fromString x) settings ) ) baseColorItems - settings.storyMap.color.activity.backgroundColor + (settings.diagramSettings.color.activity.backgroundColor |> Color.toString) ] ] , conrtolView @@ -500,11 +544,11 @@ view_ { dropDownIndex, canUseNativeFileSystem, settings, session, usableFontList dropDownIndex (UpdateSettings (\x -> - Settings.activityColor.set x settings + Settings.activityColor.set (Color.fromString x) settings ) ) baseColorItems - settings.storyMap.color.activity.color + (settings.diagramSettings.color.activity.color |> Color.toString) ] ] ] @@ -518,11 +562,11 @@ view_ { dropDownIndex, canUseNativeFileSystem, settings, session, usableFontList dropDownIndex (UpdateSettings (\x -> - Settings.taskBackgroundColor.set x settings + Settings.taskBackgroundColor.set (Color.fromString x) settings ) ) baseColorItems - settings.storyMap.color.task.backgroundColor + (settings.diagramSettings.color.task.backgroundColor |> Color.toString) ] ] , conrtolView @@ -533,11 +577,11 @@ view_ { dropDownIndex, canUseNativeFileSystem, settings, session, usableFontList dropDownIndex (UpdateSettings (\x -> - settings |> Settings.taskColor.set x + settings |> Settings.taskColor.set (Color.fromString x) ) ) baseColorItems - settings.storyMap.color.task.color + (settings.diagramSettings.color.task.color |> Color.toString) ] ] ] @@ -551,11 +595,11 @@ view_ { dropDownIndex, canUseNativeFileSystem, settings, session, usableFontList dropDownIndex (UpdateSettings (\x -> - Settings.storyBackgroundColor.set x settings + Settings.storyBackgroundColor.set (Color.fromString x) settings ) ) baseColorItems - settings.storyMap.color.story.backgroundColor + (settings.diagramSettings.color.story.backgroundColor |> Color.toString) ] ] , conrtolView @@ -566,11 +610,11 @@ view_ { dropDownIndex, canUseNativeFileSystem, settings, session, usableFontList dropDownIndex (UpdateSettings (\x -> - Settings.storyColor.set x settings + Settings.storyColor.set (Color.fromString x) settings ) ) baseColorItems - settings.storyMap.color.story.color + (settings.diagramSettings.color.story.color |> Color.toString) ] ] ] @@ -585,11 +629,11 @@ view_ { dropDownIndex, canUseNativeFileSystem, settings, session, usableFontList dropDownIndex (UpdateSettings (\x -> - Settings.lineColor.set x settings + Settings.lineColor.set (Color.fromString x) settings ) ) baseColorItems - settings.storyMap.color.line + (settings.diagramSettings.color.line |> Color.toString) ] ] , conrtolView @@ -600,11 +644,11 @@ view_ { dropDownIndex, canUseNativeFileSystem, settings, session, usableFontList dropDownIndex (UpdateSettings (\x -> - Settings.labelColor.set x settings + Settings.labelColor.set (Color.fromString x) settings ) ) baseColorItems - settings.storyMap.color.label + (settings.diagramSettings.color.label |> Color.toString) ] ] , conrtolView @@ -615,13 +659,33 @@ view_ { dropDownIndex, canUseNativeFileSystem, settings, session, usableFontList dropDownIndex (UpdateSettings (\x -> - Settings.textColor.set x settings + Settings.textColor.set (Color.fromString x) settings ) ) baseColorItems - (settings.storyMap.color.text |> Maybe.withDefault (Color.toString Color.textDefalut)) + (settings.diagramSettings.color.text |> Maybe.withDefault Color.textDefalut |> Color.toString) ] ] ] ] + , Html.div + [ Attr.css [ Style.button, Css.position Css.absolute, Css.right <| Css.px 48, Css.top <| Css.px 8 ] + , onClick Import + ] + [ Icon.cloudUpload Color.white 24 + , Html.span [ Attr.class "bottom-tooltip" ] + [ Html.span [ Attr.class "text" ] [ Html.text <| Message.toolTipImport lang ] ] + ] + , Html.div + [ Attr.css [ Style.button, Css.position Css.absolute, Css.right <| Css.px 8, Css.top <| Css.px 8 ] + , onClick Export + ] + [ Icon.cloudDownload Color.white 24 + , Html.span + [ Attr.class "bottom-tooltip" + ] + [ Html.span [ Attr.class "text" ] + [ Html.text <| Message.toolTipExport lang ] + ] + ] ] diff --git a/frontend/src/elm/Ports.elm b/frontend/src/elm/Ports.elm index d647d29ae..ca0c4d82f 100644 --- a/frontend/src/elm/Ports.elm +++ b/frontend/src/elm/Ports.elm @@ -5,7 +5,6 @@ port module Ports exposing , closeLocalFile , copyText , downloadCompleted - , reload , focusEditor , fullscreen , getDiagram @@ -28,8 +27,9 @@ port module Ports exposing , openedLocalFile , progress , refreshToken - , removedLocalDiagram + , reload , removeRemoteDiagram + , removedLocalDiagram , saveDiagram , saveLocalFile , saveSettingsToLocal @@ -131,6 +131,7 @@ port refreshToken : () -> Cmd msg port removedLocalDiagram : (String -> msg) -> Sub msg + port reload : (String -> msg) -> Sub msg diff --git a/frontend/src/elm/Utils/Utils.elm b/frontend/src/elm/Utils/Utils.elm index 021596824..340c64e24 100644 --- a/frontend/src/elm/Utils/Utils.elm +++ b/frontend/src/elm/Utils/Utils.elm @@ -8,6 +8,7 @@ module Utils.Utils exposing import Constants import Http exposing (Error(..)) +import Models.Diagram.CardSize as CardSize exposing (CardSize) import Models.Diagram.Settings as DiagramSettings import Models.Item as Item exposing (Items) import Process @@ -54,4 +55,4 @@ getCanvasHeight settings items = Item.map (\i -> Item.getChildren i |> Item.unwrapChildren |> Item.length) items |> List.maximum in - (settings.size.height + Constants.itemMargin) * (taskCount |> Maybe.withDefault 1) + 50 + (CardSize.toInt settings.size.height + Constants.itemMargin) * (taskCount |> Maybe.withDefault 1) + 50 diff --git a/frontend/src/elm/Views/Diagram/Canvas.elm b/frontend/src/elm/Views/Diagram/Canvas.elm index 21b9da045..faa2f45e3 100644 --- a/frontend/src/elm/Views/Diagram/Canvas.elm +++ b/frontend/src/elm/Views/Diagram/Canvas.elm @@ -4,6 +4,7 @@ import Constants import Events import Models.Color as Color exposing (Color) import Models.Diagram as Diagram exposing (ResizeDirection(..), SelectedItem, SelectedItemInfo) +import Models.Diagram.CardSize as CardSize import Models.Diagram.Settings as DiagramSettings import Models.FontSize as FontSize import Models.Item as Item exposing (Item, Items) @@ -195,12 +196,8 @@ canvasBase { settings, property, isTitleBottom, size, position, selectedItem, it 6 ) ) - , size = ( Size.getWidth selectedItemSize, settings.size.height ) - , color = - Item.getForegroundColor item - |> Maybe.map Color.toString - |> Maybe.withDefault settings.color.label - |> Color.fromString + , size = ( Size.getWidth selectedItemSize, CardSize.toInt settings.size.height ) + , color = Item.getForegroundColor item |> Maybe.withDefault settings.color.label , item = item_ , onEditSelectedItem = onEditSelectedItem , onEndEditSelectedItem = onEndEditSelectedItem @@ -278,7 +275,7 @@ canvasBase { settings, property, isTitleBottom, size, position, selectedItem, it Nothing -> Svg.g - [ Events.onClickStopPropagation <| onSelect <| Just { item = item, position = ( posX, posY + settings.size.height ), displayAllMenu = True } ] + [ Events.onClickStopPropagation <| onSelect <| Just { item = item, position = ( posX, posY + CardSize.toInt settings.size.height ), displayAllMenu = True } ] [ canvasRect colors property ( posX, posY ) ( svgWidth, svgHeight ) , title { settings = settings @@ -371,7 +368,7 @@ text { settings, property, svgWidth, position, selectedItem, items, onEditSelect let newSettings : DiagramSettings.Settings newSettings = - settings |> DiagramSettings.ofWidth.set (svgWidth - Constants.itemMargin * 2) + settings |> DiagramSettings.ofWidth.set (CardSize.fromInt <| svgWidth - Constants.itemMargin * 2) ( posX, posY ) = position @@ -382,7 +379,7 @@ text { settings, property, svgWidth, position, selectedItem, items, onEditSelect Card.viewWithDefaultColor { settings = newSettings , property = property - , position = ( posX + 16, posY + i * (settings.size.height + Constants.itemMargin) + Constants.itemMargin + 35 ) + , position = ( posX + 16, posY + i * (CardSize.toInt settings.size.height + Constants.itemMargin) + Constants.itemMargin + 35 ) , selectedItem = selectedItem , item = item , canMove = False @@ -402,11 +399,11 @@ title { settings, position, item, onSelect } = [ SvgAttr.x <| String.fromInt <| Position.getX position , SvgAttr.y <| String.fromInt <| Position.getY position + 14 , SvgAttr.fontFamily <| DiagramSettings.fontStyle settings - , SvgAttr.fill - (Item.getForegroundColor item - |> Maybe.map Color.toString - |> Maybe.withDefault settings.color.label - ) + , SvgAttr.fill <| + Color.toString + (Item.getForegroundColor item + |> Maybe.withDefault settings.color.label + ) , FontSize.svgStyledFontSize (Item.getFontSize item |> Maybe.withDefault FontSize.lg) , SvgAttr.fontWeight "bold" , SvgAttr.class "ts-title" @@ -414,7 +411,7 @@ title { settings, position, item, onSelect } = onSelect <| Just { item = item - , position = Tuple.mapSecond (\y -> y + settings.size.height) position + , position = Tuple.mapSecond (\y -> y + CardSize.toInt settings.size.height) position , displayAllMenu = True } ] diff --git a/frontend/src/elm/Views/Diagram/Card.elm b/frontend/src/elm/Views/Diagram/Card.elm index 70e3552f6..f52015f21 100644 --- a/frontend/src/elm/Views/Diagram/Card.elm +++ b/frontend/src/elm/Views/Diagram/Card.elm @@ -11,6 +11,7 @@ import Html.Styled.Attributes exposing (css) import Markdown import Models.Color as Color exposing (Color) import Models.Diagram as Diagram exposing (ResizeDirection(..), SelectedItem, SelectedItemInfo) +import Models.Diagram.CardSize as CardSize import Models.Diagram.Settings as DiagramSettings import Models.FontSize as FontSize exposing (FontSize) import Models.Item as Item exposing (Item) @@ -93,8 +94,8 @@ view { settings, property, position, selectedItem, item, canMove, defaultForeCol ( width, height ) = ( Property.getCardWidth property, Property.getCardHeight property ) |> Tuple.mapBoth - (\w -> Maybe.withDefault settings.size.width w) - (\h -> Maybe.withDefault (settings.size.height - 1) h) + (\w -> Maybe.withDefault (CardSize.toInt settings.size.width) w) + (\h -> Maybe.withDefault (CardSize.toInt settings.size.height - 1) h) |> Tuple.mapBoth (\w -> w + offsetWidth) (\h -> h + offsetHeight) @@ -151,7 +152,7 @@ view { settings, property, position, selectedItem, item, canMove, defaultForeCol selectedItemSize : Size selectedItemSize = - ( settings.size.width, settings.size.height - 1 ) + ( CardSize.toInt settings.size.width, CardSize.toInt settings.size.height - 1 ) |> Tuple.mapBoth (\w -> max 0 (w + Size.getWidth selectedItemOffsetSize)) (\h -> max 0 (h + Size.getHeight selectedItemOffsetSize)) diff --git a/frontend/src/elm/Views/Diagram/ER.elm b/frontend/src/elm/Views/Diagram/ER.elm index 9f80cacc6..3c7e5b9cd 100644 --- a/frontend/src/elm/Views/Diagram/ER.elm +++ b/frontend/src/elm/Views/Diagram/ER.elm @@ -24,6 +24,7 @@ import Html.Styled.Attributes exposing (css) import Html.Styled.Lazy as Lazy import List.Extra as ListEx import Maybe.Extra as MaybeEx +import Models.Color as Color import Models.Diagram as Diagram import Models.Diagram.Data as DiagramData import Models.Diagram.ER as ER exposing (Attribute(..), Column(..), Relationship(..), Table(..)) @@ -307,10 +308,10 @@ columnView settings columnWidth ( posX, posY ) (Column name_ type_ attrs) = style : Css.Style style = if isPrimaryKey then - Css.batch [ Css.fontWeight <| int 600, color <| hex settings.color.story.color ] + Css.batch [ Css.fontWeight <| int 600, color <| hex <| Color.toString settings.color.story.color ] else - Css.batch [ Css.fontWeight <| int 400, color <| hex settings.color.label ] + Css.batch [ Css.fontWeight <| int 400, color <| hex <| Color.toString settings.color.label ] in Svg.g [] [ Svg.rect @@ -318,7 +319,7 @@ columnView settings columnWidth ( posX, posY ) (Column name_ type_ attrs) = , SvgAttr.height <| String.fromInt Constants.tableRowHeight , SvgAttr.x colX , SvgAttr.y colY - , SvgAttr.fill settings.color.story.backgroundColor + , SvgAttr.fill <| Color.toString settings.color.story.backgroundColor ] [] , Svg.foreignObject @@ -335,7 +336,7 @@ columnView settings columnWidth ( posX, posY ) (Column name_ type_ attrs) = , alignItems center , justifyContent spaceBetween , Css.fontSize <| rem 0.9 - , color <| hex settings.color.story.color + , color <| hex <| Color.toString settings.color.story.color , style ] ] @@ -346,12 +347,12 @@ columnView settings columnWidth ( posX, posY ) (Column name_ type_ attrs) = [ css [ marginRight <| px 8, displayFlex, alignItems center, Css.fontSize <| rem 0.8 ] ] [ if isPrimaryKey then Html.div [ css [ marginRight <| px 8 ] ] - [ Icon.key settings.color.story.color 12 ] + [ Icon.key (Color.toString settings.color.story.color) 12 ] else if ListEx.find (\i -> i == Index) attrs |> MaybeEx.isJust then Html.div [ css [ marginRight <| px 8, marginTop <| px 5 ] ] - [ Icon.search settings.color.story.color 16 ] + [ Icon.search (Color.toString settings.color.story.color) 16 ] else Empty.view @@ -433,7 +434,7 @@ relationLabelView settings table1 table2 label = [ SvgAttr.x <| String.fromInt <| tableX1 + getWidth table1.size // 2 + 10 , SvgAttr.y <| String.fromInt <| tableY1 + getHeight table1.size + 15 , SvgAttr.fontFamily (DiagramSettings.fontStyle settings) - , SvgAttr.fill settings.color.label + , SvgAttr.fill <| Color.toString settings.color.label , SvgAttr.fontSize "14" , SvgAttr.fontWeight "bold" ] @@ -444,7 +445,7 @@ relationLabelView settings table1 table2 label = [ SvgAttr.x <| String.fromInt <| tableX1 + getWidth table1.size // 2 + 10 , SvgAttr.y <| String.fromInt <| tableY1 - 15 , SvgAttr.fontFamily (DiagramSettings.fontStyle settings) - , SvgAttr.fill settings.color.label + , SvgAttr.fill <| Color.toString settings.color.label , SvgAttr.fontSize "14" , SvgAttr.fontWeight "bold" ] @@ -455,7 +456,7 @@ relationLabelView settings table1 table2 label = [ SvgAttr.x <| String.fromInt <| tableX1 + getWidth table1.size + 10 , SvgAttr.y <| String.fromInt <| tableY1 + getHeight table1.size // 2 - 15 , SvgAttr.fontFamily (DiagramSettings.fontStyle settings) - , SvgAttr.fill settings.color.label + , SvgAttr.fill <| Color.toString settings.color.label , SvgAttr.fontSize "14" , SvgAttr.fontWeight "bold" ] @@ -466,7 +467,7 @@ relationLabelView settings table1 table2 label = [ SvgAttr.x <| String.fromInt <| tableX1 - 15 , SvgAttr.y <| String.fromInt <| tableY1 + getHeight table1.size // 2 + 15 , SvgAttr.fontFamily (DiagramSettings.fontStyle settings) - , SvgAttr.fill settings.color.label + , SvgAttr.fill <| Color.toString settings.color.label , SvgAttr.fontSize "14" , SvgAttr.fontWeight "bold" ] @@ -477,7 +478,7 @@ relationLabelView settings table1 table2 label = [ SvgAttr.x <| String.fromInt <| tableX1 + getWidth table1.size + 10 , SvgAttr.y <| String.fromInt <| tableY1 + getHeight table1.size // 2 + 15 , SvgAttr.fontFamily (DiagramSettings.fontStyle settings) - , SvgAttr.fill settings.color.label + , SvgAttr.fill <| Color.toString settings.color.label , SvgAttr.fontSize "14" , SvgAttr.fontWeight "bold" ] @@ -488,7 +489,7 @@ relationLabelView settings table1 table2 label = [ SvgAttr.x <| String.fromInt <| tableX1 - 15 , SvgAttr.y <| String.fromInt <| tableY1 + getHeight table1.size // 2 - 10 , SvgAttr.fontFamily (DiagramSettings.fontStyle settings) - , SvgAttr.fill settings.color.label + , SvgAttr.fill <| Color.toString settings.color.label , SvgAttr.fontSize "14" , SvgAttr.fontWeight "bold" ] @@ -557,14 +558,14 @@ tableHeaderView settings headerText headerWidth ( posX, posY ) = , SvgAttr.height <| String.fromInt Constants.tableRowHeight , SvgAttr.x (String.fromInt posX) , SvgAttr.y (String.fromInt posY) - , SvgAttr.fill settings.color.activity.backgroundColor + , SvgAttr.fill <| Color.toString settings.color.activity.backgroundColor ] [] , Svg.text_ [ SvgAttr.x <| String.fromInt <| posX + 8 , SvgAttr.y <| String.fromInt <| posY + 24 , SvgAttr.fontFamily (DiagramSettings.fontStyle settings) - , SvgAttr.fill settings.color.activity.color + , SvgAttr.fill <| Color.toString settings.color.activity.color , SvgAttr.fontSize "16" , SvgAttr.fontWeight "bold" ] @@ -602,7 +603,7 @@ tableView { settings, svgSize, pos, tableSize, table, dragStart } = , SvgAttr.x (String.fromInt tableX) , SvgAttr.y (String.fromInt tableY) , SvgAttr.strokeWidth "1" - , SvgAttr.stroke settings.color.activity.backgroundColor + , SvgAttr.stroke <| Color.toString settings.color.activity.backgroundColor ] [] :: tableHeaderView settings tableName (getWidth tableSize) ( tableX, tableY ) diff --git a/frontend/src/elm/Views/Diagram/FreeForm.elm b/frontend/src/elm/Views/Diagram/FreeForm.elm index 77938938e..4202f797f 100644 --- a/frontend/src/elm/Views/Diagram/FreeForm.elm +++ b/frontend/src/elm/Views/Diagram/FreeForm.elm @@ -4,6 +4,7 @@ import Constants import ElmBook.Actions as Actions import ElmBook.Chapter as Chapter exposing (Chapter) import Models.Diagram as Diagram exposing (MoveState, SelectedItem, SelectedItemInfo) +import Models.Diagram.CardSize as CardSize import Models.Diagram.Data as DiagramData import Models.Diagram.FreeForm as FreeForm exposing (FreeFormItem) import Models.Diagram.Settings as DiagramSettings @@ -92,8 +93,8 @@ formView { property, moveState, settings, selectedItem, onEditSelectedItem, onEn Line.horizontal { settings = settings , position = - ( 16 + modBy 4 i * (settings.size.width + 16) - , (i // 4) * (settings.size.height + 16) + ( 16 + modBy 4 i * (CardSize.toInt settings.size.width + 16) + , (i // 4) * (CardSize.toInt settings.size.height + 16) ) , selectedItem = selectedItem , item = @@ -116,8 +117,8 @@ formView { property, moveState, settings, selectedItem, onEditSelectedItem, onEn Line.vertical { settings = settings , position = - ( 16 + modBy 4 i * (settings.size.width + 16) - , (i // 4) * (settings.size.height + 16) + ( 16 + modBy 4 i * (CardSize.toInt settings.size.width + 16) + , (i // 4) * (CardSize.toInt settings.size.height + 16) ) , selectedItem = selectedItem , item = @@ -155,8 +156,8 @@ formView { property, moveState, settings, selectedItem, onEditSelectedItem, onEn { settings = settings , property = property , position = - ( 16 + modBy 4 i * (settings.size.width + 16) - , (i // 4) * (settings.size.height + 16) + ( 16 + modBy 4 i * (CardSize.toInt settings.size.width + 16) + , (i // 4) * (CardSize.toInt settings.size.height + 16) ) , selectedItem = selectedItem , item = @@ -213,8 +214,8 @@ cardView { selectedItem, settings, property, moveState, i, item_, onEditSelected { settings = settings , property = property , position = - ( 16 + modBy 4 i * (settings.size.width + 16) - , (i // 4) * (settings.size.height + 16) + ( 16 + modBy 4 i * (CardSize.toInt settings.size.width + 16) + , (i // 4) * (CardSize.toInt settings.size.height + 16) ) , selectedItem = selectedItem , item = @@ -241,8 +242,8 @@ cardView { selectedItem, settings, property, moveState, i, item_, onEditSelected { settings = settings , property = property , position = - ( 16 + modBy 4 i * (settings.size.width + 16) - , (i + i_ + 1) * (settings.size.height + 16) + ( 16 + modBy 4 i * (CardSize.toInt settings.size.width + 16) + , (i + i_ + 1) * (CardSize.toInt settings.size.height + 16) ) , selectedItem = selectedItem , item = diff --git a/frontend/src/elm/Views/Diagram/GanttChart.elm b/frontend/src/elm/Views/Diagram/GanttChart.elm index 8e7909a48..52eb32d92 100644 --- a/frontend/src/elm/Views/Diagram/GanttChart.elm +++ b/frontend/src/elm/Views/Diagram/GanttChart.elm @@ -5,7 +5,7 @@ import ElmBook.Chapter as Chapter exposing (Chapter) import Html.Styled as Html import Html.Styled.Attributes as Attr import List.Extra as ListEx -import Models.Color as Color +import Models.Color as Color exposing (Color) import Models.Diagram.Data as DiagramData import Models.Diagram.GanttChart as GanttChart exposing (GanttChart(..), Schedule(..), Section(..), Task(..)) import Models.Diagram.Settings as DiagramSettings @@ -152,7 +152,7 @@ daysView settings svgHeight ( from, to ) = [ Html.div [ Attr.style "font-family" (DiagramSettings.fontStyle settings) , Attr.style "word-wrap" "break-word" - , Attr.style "color" settings.color.label + , Attr.style "color" <| Color.toString settings.color.label ] [ Html.text <| String.fromInt day ] ] @@ -161,7 +161,7 @@ daysView settings svgHeight ( from, to ) = , SvgAttr.y1 <| String.fromInt <| Constants.ganttItemSize , SvgAttr.x2 <| String.fromInt posX , SvgAttr.y2 <| String.fromInt <| Constants.ganttItemSize + svgHeight - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "0.3" ] [] @@ -172,7 +172,7 @@ daysView settings svgHeight ( from, to ) = ) -headerItemView : DiagramSettings.Settings -> ( String, String ) -> Position -> Posix -> String -> Schedule -> Svg msg +headerItemView : DiagramSettings.Settings -> ( Color, Color ) -> Position -> Posix -> String -> Schedule -> Svg msg headerItemView settings colour ( posX, posY ) baseFrom text (Schedule from to _) = let interval : Int @@ -194,7 +194,7 @@ headerSectionView settings ( sectionWidth, sectionHeight ) ( posX, posY ) from s , SvgAttr.y1 <| String.fromInt <| posY , SvgAttr.x2 <| String.fromInt <| posX + sectionWidth + sectionMargin + Constants.ganttItemSize , SvgAttr.y2 <| String.fromInt <| posY - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "0.3" ] [] @@ -208,7 +208,7 @@ headerSectionView settings ( sectionWidth, sectionHeight ) ( posX, posY ) from s [ Attr.style "font-family" (DiagramSettings.fontStyle settings) , Attr.style "word-wrap" "break-word" , Attr.style "padding" "8px" - , Attr.style "color" settings.color.label + , Attr.style "color" <| Color.toString settings.color.label , Attr.style "font-size" "11px" , Attr.style "font-weight" "bold" ] @@ -228,7 +228,7 @@ headerSectionView settings ( sectionWidth, sectionHeight ) ( posX, posY ) from s ] -headerTaskView : DiagramSettings.Settings -> ( String, String ) -> Position -> Posix -> Posix -> String -> Svg msg +headerTaskView : DiagramSettings.Settings -> ( Color, Color ) -> Position -> Posix -> Posix -> String -> Svg msg headerTaskView settings ( backgroundColor, colour ) ( posX, posY ) from to text = let fromPolygon : String @@ -288,24 +288,24 @@ headerTaskView settings ( backgroundColor, colour ) ( posX, posY ) from to text , SvgAttr.height <| String.fromInt <| Constants.ganttItemSize // 2 - 8 , SvgAttr.x "0" , SvgAttr.y <| String.fromInt <| Constants.ganttItemSize // 4 - , SvgAttr.fill backgroundColor + , SvgAttr.fill <| Color.toString backgroundColor ] [] , Svg.polygon [ SvgAttr.points fromPolygon - , SvgAttr.fill backgroundColor + , SvgAttr.fill <| Color.toString backgroundColor ] [] , Svg.polygon [ SvgAttr.points toPolygon - , SvgAttr.fill backgroundColor + , SvgAttr.fill <| Color.toString backgroundColor ] [] , Views.plainText { settings = settings , position = ( svgWidth, -3 ) , size = ( textWidth, Constants.ganttItemSize ) - , foreColor = Color.fromString colour + , foreColor = colour , fontSize = FontSize.default , text = text , isHighlight = False @@ -313,7 +313,7 @@ headerTaskView settings ( backgroundColor, colour ) ( posX, posY ) from to text ] -itemView : DiagramSettings.Settings -> ( String, String ) -> Position -> Posix -> String -> Schedule -> Svg msg +itemView : DiagramSettings.Settings -> ( Color, Color ) -> Position -> Posix -> String -> Schedule -> Svg msg itemView settings colour ( posX, posY ) baseFrom text (Schedule from to _) = let interval : Int @@ -336,7 +336,7 @@ sectionView settings ( sectionWidth, sectionHeight ) ( posX, posY ) from (Task t , SvgAttr.y1 <| String.fromInt <| posY , SvgAttr.x2 <| String.fromInt <| posX + sectionWidth + sectionMargin - posX + Constants.ganttItemSize , SvgAttr.y2 <| String.fromInt <| posY - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "0.3" ] [] @@ -350,7 +350,7 @@ sectionView settings ( sectionWidth, sectionHeight ) ( posX, posY ) from (Task t [ Attr.style "font-family" (DiagramSettings.fontStyle settings) , Attr.style "word-wrap" "break-word" , Attr.style "padding" "8px" - , Attr.style "color" settings.color.label + , Attr.style "color" <| Color.toString settings.color.label , Attr.style "font-size" "11px" , Attr.style "font-weight" "bold" ] @@ -369,7 +369,7 @@ sectionView settings ( sectionWidth, sectionHeight ) ( posX, posY ) from (Task t ] -taskView : DiagramSettings.Settings -> ( String, String ) -> Position -> Posix -> Posix -> String -> Svg msg +taskView : DiagramSettings.Settings -> ( Color, Color ) -> Position -> Posix -> Posix -> String -> Svg msg taskView settings ( backgroundColor, colour ) ( posX, posY ) from to text = let interval : Int @@ -395,7 +395,7 @@ taskView settings ( backgroundColor, colour ) ( posX, posY ) from to text = , SvgAttr.height <| String.fromInt <| Constants.ganttItemSize - 6 , SvgAttr.x "0" , SvgAttr.y "3" - , SvgAttr.fill backgroundColor + , SvgAttr.fill <| Color.toString backgroundColor , SvgAttr.rx "3" , SvgAttr.ry "3" ] @@ -404,7 +404,7 @@ taskView settings ( backgroundColor, colour ) ( posX, posY ) from to text = { settings = settings , position = ( svgWidth, -3 ) , size = ( textWidth, Constants.ganttItemSize ) - , foreColor = Color.fromString colour + , foreColor = colour , fontSize = FontSize.default , text = text , isHighlight = False @@ -440,7 +440,7 @@ weekView settings ( from, to ) = [ Html.div [ Attr.style "font-family" (DiagramSettings.fontStyle settings) , Attr.style "word-wrap" "break-word" - , Attr.style "color" settings.color.label + , Attr.style "color" <| Color.toString settings.color.label , Attr.style "font-size" "11px" , Attr.style "font-weight" "bold" ] diff --git a/frontend/src/elm/Views/Diagram/Grid.elm b/frontend/src/elm/Views/Diagram/Grid.elm index 050e415ce..9236ef243 100644 --- a/frontend/src/elm/Views/Diagram/Grid.elm +++ b/frontend/src/elm/Views/Diagram/Grid.elm @@ -4,6 +4,7 @@ import Css exposing (backgroundColor) import Events import Models.Color as Color import Models.Diagram exposing (SelectedItem, SelectedItemInfo) +import Models.Diagram.CardSize as CardSize import Models.Diagram.Settings as DiagramSettings import Models.FontSize as FontSize import Models.Item as Item exposing (Item) @@ -42,24 +43,24 @@ view { settings, property, position, selectedItem, item, onEditSelectedItem, onE onSelect <| Just { item = item - , position = ( posX, posY + settings.size.height ) + , position = ( posX, posY + CardSize.toInt settings.size.height ) , displayAllMenu = True } ] [ Svg.rect - [ SvgAttr.width <| String.fromInt settings.size.width - , SvgAttr.height <| String.fromInt <| settings.size.height - 1 + [ SvgAttr.width <| String.fromInt <| CardSize.toInt settings.size.width + , SvgAttr.height <| String.fromInt <| CardSize.toInt settings.size.height - 1 , SvgAttr.x (String.fromInt posX) , SvgAttr.y (String.fromInt posY) , SvgAttr.fill <| Color.toString backgroundColor - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "1" ] [] , Card.text { settings = settings , position = ( posX, posY ) - , size = ( settings.size.width, settings.size.height ) + , size = ( CardSize.toInt settings.size.width, CardSize.toInt settings.size.height ) , color = forgroundColor , fontSize = Item.getFontSize item |> Maybe.withDefault FontSize.default , item = item @@ -71,13 +72,13 @@ view { settings, property, position, selectedItem, item, onEditSelectedItem, onE if Item.eq item_ item then Svg.g [] [ Svg.rect - [ SvgAttr.width <| String.fromInt settings.size.width - , SvgAttr.height <| String.fromInt <| settings.size.height - 1 + [ SvgAttr.width <| String.fromInt <| CardSize.toInt settings.size.width + , SvgAttr.height <| String.fromInt <| CardSize.toInt settings.size.height - 1 , SvgAttr.x (String.fromInt posX) , SvgAttr.y (String.fromInt posY) , SvgAttr.stroke "rgba(0, 0, 0, 0.1)" , SvgAttr.fill <| Color.toString backgroundColor - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "1" , SvgAttr.class "ts-grid" ] @@ -88,7 +89,7 @@ view { settings, property, position, selectedItem, item, onEditSelectedItem, onE , item = item_ , position = ( posX, posY ) , settings = settings - , size = ( settings.size.width, settings.size.height ) + , size = ( CardSize.toInt settings.size.width, CardSize.toInt settings.size.height ) , onEditSelectedItem = onEditSelectedItem , onEndEditSelectedItem = onEndEditSelectedItem , onSelect = onSelect diff --git a/frontend/src/elm/Views/Diagram/Kanban.elm b/frontend/src/elm/Views/Diagram/Kanban.elm index 4df12144e..0a098d3c7 100644 --- a/frontend/src/elm/Views/Diagram/Kanban.elm +++ b/frontend/src/elm/Views/Diagram/Kanban.elm @@ -3,7 +3,9 @@ module Views.Diagram.Kanban exposing (docs, view) import Constants import ElmBook.Actions as Actions import ElmBook.Chapter as Chapter exposing (Chapter) +import Models.Color as Color import Models.Diagram exposing (SelectedItem, SelectedItemInfo) +import Models.Diagram.CardSize as CardSize import Models.Diagram.Data as DiagramData import Models.Diagram.Kanban as Kanban exposing (Card(..), Kanban(..), KanbanList(..)) import Models.Diagram.Settings as DiagramSettings @@ -72,11 +74,11 @@ kanbanView { settings, property, selectedItem, kanban, onEditSelectedItem, onEnd let height : Int height = - Kanban.getCardCount kanban * (settings.size.height + Constants.itemMargin) + Constants.itemMargin + Kanban.getCardCount kanban * (CardSize.toInt settings.size.height + Constants.itemMargin) + Constants.itemMargin listWidth : Int listWidth = - settings.size.width + Constants.itemMargin * 3 + CardSize.toInt settings.size.width + Constants.itemMargin * 3 (Kanban lists) = kanban @@ -127,17 +129,17 @@ listView { settings, property, height, position, selectedItem, kanban, onEditSel [ SvgAttr.x <| String.fromInt <| posX + 8 , SvgAttr.y <| String.fromInt <| posY + kanbanMargin , SvgAttr.fontFamily (DiagramSettings.fontStyle settings) - , SvgAttr.fill settings.color.label + , SvgAttr.fill <| Color.toString settings.color.label , SvgAttr.fontSize "16" , SvgAttr.fontWeight "bold" ] [ Svg.text name ] :: Svg.line - [ SvgAttr.x1 <| String.fromInt <| posX + settings.size.width + 8 + Constants.itemMargin + [ SvgAttr.x1 <| String.fromInt <| posX + CardSize.toInt settings.size.width + 8 + Constants.itemMargin , SvgAttr.y1 "0" - , SvgAttr.x2 <| String.fromInt <| posX + settings.size.width + 8 + Constants.itemMargin + , SvgAttr.x2 <| String.fromInt <| posX + CardSize.toInt settings.size.width + 8 + Constants.itemMargin , SvgAttr.y2 <| String.fromInt <| height + Constants.itemMargin - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "3" ] [] @@ -148,7 +150,7 @@ listView { settings, property, height, position, selectedItem, kanban, onEditSel , item = item , position = ( posX - , posY + kanbanMargin + Constants.itemMargin + (settings.size.height + Constants.itemMargin) * i + , posY + kanbanMargin + Constants.itemMargin + (CardSize.toInt settings.size.height + Constants.itemMargin) * i ) , property = property , selectedItem = selectedItem diff --git a/frontend/src/elm/Views/Diagram/KeyboardLayout.elm b/frontend/src/elm/Views/Diagram/KeyboardLayout.elm index 2e0e979f2..355eb9c43 100644 --- a/frontend/src/elm/Views/Diagram/KeyboardLayout.elm +++ b/frontend/src/elm/Views/Diagram/KeyboardLayout.elm @@ -176,7 +176,7 @@ keyView { key, position, settings, selectedItem, property, onSelect, onEditSelec Item.getSettings item |> Maybe.map (\_ -> Views.getItemColor settings property item) |> Maybe.withDefault - ( Color.fromString <| Maybe.withDefault settings.color.label <| settings.color.text + ( Maybe.withDefault settings.color.label <| settings.color.text , Color.fromString "#FEFEFE" ) diff --git a/frontend/src/elm/Views/Diagram/Line.elm b/frontend/src/elm/Views/Diagram/Line.elm index 050997c53..d4b36353e 100644 --- a/frontend/src/elm/Views/Diagram/Line.elm +++ b/frontend/src/elm/Views/Diagram/Line.elm @@ -3,6 +3,7 @@ module Views.Diagram.Line exposing (horizontal, vertical) import Events import Models.Color as Color exposing (Color) import Models.Diagram as Diagram exposing (ResizeDirection(..), SelectedItem, SelectedItemInfo) +import Models.Diagram.CardSize as CardSize exposing (CardSize) import Models.Diagram.Settings as DiagramSettings import Models.Item as Item exposing (Item) import Models.Item.Settings as ItemSettings @@ -47,7 +48,7 @@ horizontal { settings, position, selectedItem, item, onSelect, dragStart } = Svg.g [ Events.onClickStopPropagation <| onSelect <| - Just { item = item, position = Tuple.mapSecond (\y -> y - settings.size.width + offsetHeight + 72) position, displayAllMenu = False } + Just { item = item, position = Tuple.mapSecond (\y -> y - CardSize.toInt settings.size.width + offsetHeight + 72) position, displayAllMenu = False } ] [ Svg.line [ SvgAttr.x1 <| String.fromInt posX @@ -63,7 +64,7 @@ horizontal { settings, position, selectedItem, item, onSelect, dragStart } = width : Int width = - settings.size.width + offsetWidth + CardSize.toInt settings.size.width + offsetWidth in case selectedItem of Just item_ -> @@ -86,7 +87,7 @@ horizontal { settings, position, selectedItem, item, onSelect, dragStart } = selectedItemSize : Position selectedItemSize = - ( settings.size.width, settings.size.height - 1 ) + ( CardSize.toInt settings.size.width, CardSize.toInt settings.size.height - 1 ) |> Tuple.mapBoth (\w -> max 0 (w + Size.getWidth selectedItemOffsetSize)) (\h -> max 0 (h + Size.getHeight selectedItemOffsetSize)) @@ -146,7 +147,7 @@ vertical { settings, position, selectedItem, item, onSelect, dragStart } = height : Int height = - settings.size.height + offsetHeight + CardSize.toInt settings.size.height + offsetHeight ( _, offsetHeight ) = Item.getOffsetSize item @@ -194,7 +195,7 @@ vertical { settings, position, selectedItem, item, onSelect, dragStart } = selectedItemSize : Size selectedItemSize = - ( settings.size.width, settings.size.height - 1 ) + ( CardSize.toInt settings.size.width, CardSize.toInt settings.size.height - 1 ) |> Tuple.mapBoth (\w -> max 0 (w + Size.getWidth selectedItemOffsetSize)) (\h -> max 0 (h + Size.getHeight selectedItemOffsetSize)) @@ -241,4 +242,4 @@ getLineColor : DiagramSettings.Settings -> Item -> Color getLineColor settings item = item |> Item.getBackgroundColor - |> Maybe.withDefault (Color.fromString settings.color.line) + |> Maybe.withDefault settings.color.line diff --git a/frontend/src/elm/Views/Diagram/MindMap.elm b/frontend/src/elm/Views/Diagram/MindMap.elm index 98b0b26d5..10cc4a0cb 100644 --- a/frontend/src/elm/Views/Diagram/MindMap.elm +++ b/frontend/src/elm/Views/Diagram/MindMap.elm @@ -3,7 +3,9 @@ module Views.Diagram.MindMap exposing (ViewType(..), docs, view) import ElmBook.Actions as Actions import ElmBook.Chapter as Chapter exposing (Chapter) import List.Extra as ListEx +import Models.Color exposing (Color) import Models.Diagram as Diagram exposing (Diagram, MoveState, SelectedItem, SelectedItemInfo) +import Models.Diagram.CardSize as CardSize import Models.Diagram.Data as DiagramData import Models.Diagram.Scale as Scale import Models.Diagram.Settings as DiagramSettings @@ -170,7 +172,7 @@ view { data, settings, property, selectedItem, moveState, viewType, onEditSelect Empty.view -nodeLineView : Size -> String -> Position -> Position -> Svg msg +nodeLineView : Size -> Color -> Position -> Position -> Svg msg nodeLineView ( width, height ) colour fromBase toBase = let ( fromPoint, toPoint ) = @@ -222,11 +224,11 @@ nodesView { settings, property, hierarchy, position, direction, selectedItem, it svgHeight : Int svgHeight = - settings.size.height + CardSize.toInt settings.size.height svgWidth : Int svgWidth = - settings.size.width + CardSize.toInt settings.size.width tmpNodeCounts : List Int tmpNodeCounts = @@ -291,7 +293,7 @@ nodesView { settings, property, hierarchy, position, direction, selectedItem, it |> Maybe.withDefault Position.zero in [ Lazy.lazy4 nodeLineView - ( settings.size.width, settings.size.height ) + ( CardSize.toInt settings.size.width, CardSize.toInt settings.size.height ) settings.color.task.backgroundColor ( x, y ) ( itemX + Position.getX offset, itemY + Position.getY offset ) diff --git a/frontend/src/elm/Views/Diagram/Path.elm b/frontend/src/elm/Views/Diagram/Path.elm index 74e38d84e..59e378196 100644 --- a/frontend/src/elm/Views/Diagram/Path.elm +++ b/frontend/src/elm/Views/Diagram/Path.elm @@ -1,6 +1,7 @@ module Views.Diagram.Path exposing (Position, Size, docs, view) import ElmBook.Chapter as Chapter exposing (Chapter) +import Models.Color as Color exposing (Color) import Svg.Styled as Svg exposing (Svg) import Svg.Styled.Attributes as SvgAttr @@ -13,7 +14,7 @@ type alias Size = ( Float, Float ) -view : String -> ( Position, Size ) -> ( Position, Size ) -> Svg msg +view : Color -> ( Position, Size ) -> ( Position, Size ) -> Svg msg view colour ( ( fromX, fromY ), ( fromWidth, fromHeight ) ) ( ( toX, toY ), ( toWidth, toHeight ) ) = if fromX == toX && fromY < toY then draw @@ -80,11 +81,11 @@ cornerSize = 8.0 -draw : String -> List Path -> Svg msg +draw : Color -> List Path -> Svg msg draw colour pathList = Svg.path [ SvgAttr.strokeWidth "3" - , SvgAttr.stroke colour + , SvgAttr.stroke <| Color.toString colour , SvgAttr.d <| String.join " " pathList , SvgAttr.fill "transparent" ] @@ -167,6 +168,6 @@ docs = , SvgAttr.height "100%" , SvgAttr.viewBox "0 0 2048 2048" ] - [ view "#000000" ( ( 0, 0 ), ( 100, 100 ) ) ( ( 100, 100 ), ( 10, 10 ) ) ] + [ view (Color.fromString "#000000") ( ( 0, 0 ), ( 100, 100 ) ) ( ( 100, 100 ), ( 10, 10 ) ) ] |> Svg.toUnstyled ) diff --git a/frontend/src/elm/Views/Diagram/SequenceDiagram.elm b/frontend/src/elm/Views/Diagram/SequenceDiagram.elm index a289fb687..e31556ee0 100644 --- a/frontend/src/elm/Views/Diagram/SequenceDiagram.elm +++ b/frontend/src/elm/Views/Diagram/SequenceDiagram.elm @@ -6,6 +6,7 @@ import ElmBook.Chapter as Chapter exposing (Chapter) import List.Extra as ListEx import Models.Color as Color import Models.Diagram exposing (SelectedItem, SelectedItemInfo) +import Models.Diagram.CardSize as CardSize import Models.Diagram.Data as DiagramData import Models.Diagram.SequenceDiagram as SequenceDiagram exposing (Fragment(..), Message(..), MessageType(..), Participant(..), SequenceDiagram(..), SequenceItem(..)) import Models.Diagram.Settings as DiagramSettings @@ -48,7 +49,7 @@ view { data, settings, property, selectedItem, onEditSelectedItem, onEndEditSele (\item y -> y + List.length (SequenceDiagram.sequenceItemMessages item) * Constants.messageMargin ) - (settings.size.height + Constants.messageMargin) + (CardSize.toInt settings.size.height + Constants.messageMargin) items in Svg.g [] @@ -88,7 +89,7 @@ fragmentAndMessageView : DiagramSettings.Settings -> Property -> Int -> Int -> L fragmentAndMessageView settings property level y messages fragmentText fragment = let ( ( fromX, fromY ), ( toX, toY ) ) = - fragmentRect ( settings.size.width, settings.size.height ) y level messages + fragmentRect ( CardSize.toInt settings.size.width, CardSize.toInt settings.size.height ) y level messages in Svg.g [] [ mesageViewList settings property level y messages @@ -159,7 +160,7 @@ fragmentRectView settings ( fromX, fromY ) ( fragmentWidth, fragmentHeight ) bac , SvgAttr.y <| String.fromInt fromY , SvgAttr.width <| String.fromInt fragmentWidth , SvgAttr.height <| String.fromInt fragmentHeight - , SvgAttr.stroke settings.color.activity.backgroundColor + , SvgAttr.stroke <| Color.toString settings.color.activity.backgroundColor , SvgAttr.strokeWidth "2" , SvgAttr.fill backgroundColor ] @@ -169,7 +170,7 @@ fragmentRectView settings ( fromX, fromY ) ( fragmentWidth, fragmentHeight ) bac , SvgAttr.y <| String.fromInt fromY , SvgAttr.width <| String.fromInt <| max 44 (String.length label * 7 + 16) , SvgAttr.height "20" - , SvgAttr.fill settings.color.activity.backgroundColor + , SvgAttr.fill <| Color.toString settings.color.activity.backgroundColor , SvgAttr.strokeWidth "2" ] [] @@ -177,7 +178,7 @@ fragmentRectView settings ( fromX, fromY ) ( fragmentWidth, fragmentHeight ) bac [ SvgAttr.x <| String.fromInt <| fromX + 8 , SvgAttr.y <| String.fromInt <| fromY + 14 , SvgAttr.fontFamily (DiagramSettings.fontStyle settings) - , SvgAttr.fill settings.color.task.color + , SvgAttr.fill <| Color.toString settings.color.task.color , SvgAttr.fontSize Constants.fontSize , SvgAttr.fontWeight "bold" ] @@ -190,7 +191,7 @@ fragmentTextView settings property ( fromX, fromY ) fragmentText = let offset : Int offset = - settings.size.width + CardSize.toInt settings.size.width // 2 + 16 in @@ -226,7 +227,7 @@ lineView settings ( fromX, fromY ) ( toX, toY ) = , SvgAttr.y1 <| String.fromInt fromY , SvgAttr.x2 <| String.fromInt toX , SvgAttr.y2 <| String.fromInt toY - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "2" ] [] @@ -246,7 +247,7 @@ markerView settings = ] [ Svg.polygon [ SvgAttr.points "0,0 0,10 10,5" - , SvgAttr.fill settings.color.line + , SvgAttr.fill <| Color.toString settings.color.line ] [] ] @@ -262,7 +263,7 @@ markerView settings = [ Svg.polyline [ SvgAttr.points "0,0 10,5 0,10" , SvgAttr.fill "none" - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "2" ] [] @@ -280,7 +281,7 @@ markerView settings = [ SvgAttr.cx "10" , SvgAttr.cy "5" , SvgAttr.r "5" - , SvgAttr.fill settings.color.line + , SvgAttr.fill <| Color.toString settings.color.line ] [] ] @@ -296,7 +297,7 @@ markerView settings = [ Svg.polyline [ SvgAttr.points "0,0 10,5 0,10" , SvgAttr.fill "none" - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "2" ] [] @@ -304,7 +305,7 @@ markerView settings = [ SvgAttr.cx "12" , SvgAttr.cy "5" , SvgAttr.r "5" - , SvgAttr.fill settings.color.line + , SvgAttr.fill <| Color.toString settings.color.line ] [] ] @@ -324,10 +325,10 @@ mesageViewList settings property level y messages = case message of Message messageType (Participant _ order1) (Participant _ order2) -> if order1 == order2 then - selfMessageView settings property ( messageX settings.size.width order1, messageY ) messageType + selfMessageView settings property ( messageX (CardSize.toInt settings.size.width) order1, messageY ) messageType else - messageView settings property ( messageX settings.size.width order1, messageY ) ( messageX settings.size.width order2, messageY ) messageType + messageView settings property ( messageX (CardSize.toInt settings.size.width) order1, messageY ) ( messageX (CardSize.toInt settings.size.width) order2, messageY ) messageType SubMessage subItem -> sequenceItemView settings property (level + 1) messageY subItem @@ -381,7 +382,7 @@ messageView settings property ( fromX, fromY ) ( toX, toY ) messageType = , SvgAttr.y1 <| String.fromInt fromY , SvgAttr.x2 <| String.fromInt <| toX - toOffset , SvgAttr.y2 <| String.fromInt toY - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "2" , if isDot then SvgAttr.strokeDasharray "3" @@ -393,7 +394,7 @@ messageView settings property ( fromX, fromY ) ( toX, toY ) messageType = ] [] , if isReverse then - textView settings property ( fromX + 8 - settings.size.width - Constants.participantMargin, fromY - 16 ) ( toX - fromX, 8 ) (SequenceDiagram.unwrapMessageType messageType) + textView settings property ( fromX + 8 - CardSize.toInt settings.size.width - Constants.participantMargin, fromY - 16 ) ( toX - fromX, 8 ) (SequenceDiagram.unwrapMessageType messageType) else textView settings property ( fromX + 8 + fromOffset, fromY - 16 ) ( toX - fromX, 8 ) (SequenceDiagram.unwrapMessageType messageType) @@ -422,15 +423,15 @@ participantView { settings, property, selectedItem, position, participant, messa let fromY : Int fromY = - Position.getY position + settings.size.height + Position.getY position + CardSize.toInt settings.size.height lineX : Int lineX = - Position.getX position + settings.size.width // 2 + Position.getX position + CardSize.toInt settings.size.width // 2 toY : Int toY = - fromY + messageHeight + settings.size.height + Constants.messageMargin + fromY + messageHeight + CardSize.toInt settings.size.height + Constants.messageMargin (Participant item _) = participant @@ -466,7 +467,7 @@ participantView { settings, property, selectedItem, position, participant, messa participantX : DiagramSettings.Settings -> Int -> Int participantX settings order = - (settings.size.width + Constants.participantMargin) * order + 8 + (CardSize.toInt settings.size.width + Constants.participantMargin) * order + 8 selfMessageView : DiagramSettings.Settings -> Property -> Position -> MessageType -> Svg msg @@ -486,7 +487,7 @@ selfMessageView settings property ( posX, posY ) messageType = [ SvgAttr.points messagePoints , SvgAttr.markerEnd "url(#sync)" , SvgAttr.fill "none" - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "2" ] [] @@ -504,7 +505,7 @@ sequenceItemView settings property level y item = y + SequenceDiagram.messagesCount ifMessages * Constants.messageMargin - Constants.messageMargin + 16 ( ( fromX, fromY ), ( toX, toY ) ) = - fragmentRect ( settings.size.width, settings.size.height ) y level messages + fragmentRect ( CardSize.toInt settings.size.width, CardSize.toInt settings.size.height ) y level messages messages : List Message messages = @@ -518,7 +519,7 @@ sequenceItemView settings property level y item = , SvgAttr.y1 <| String.fromInt elseY , SvgAttr.x2 <| String.fromInt <| toX , SvgAttr.y2 <| String.fromInt elseY - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "2" , SvgAttr.strokeDasharray "3" ] @@ -533,7 +534,7 @@ sequenceItemView settings property level y item = Fragment (Par parMessages) -> let ( ( fromX, fromY ), ( toX, toY ) ) = - fragmentRect ( settings.size.width, settings.size.height ) y level messages + fragmentRect ( CardSize.toInt settings.size.width, CardSize.toInt settings.size.height ) y level messages lines : List (Svg msg) lines = @@ -547,7 +548,7 @@ sequenceItemView settings property level y item = , SvgAttr.y1 <| String.fromInt messageY , SvgAttr.x2 <| String.fromInt <| toX , SvgAttr.y2 <| String.fromInt messageY - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "2" , SvgAttr.strokeDasharray "3" ] diff --git a/frontend/src/elm/Views/Diagram/SiteMap.elm b/frontend/src/elm/Views/Diagram/SiteMap.elm index 9bb1b3509..66675b6da 100644 --- a/frontend/src/elm/Views/Diagram/SiteMap.elm +++ b/frontend/src/elm/Views/Diagram/SiteMap.elm @@ -4,7 +4,9 @@ import Constants import ElmBook.Actions as Actions import ElmBook.Chapter as Chapter exposing (Chapter) import List.Extra as ListEx +import Models.Color as Color import Models.Diagram exposing (Diagram, SelectedItem, SelectedItemInfo) +import Models.Diagram.CardSize as CardSize import Models.Diagram.Data as DiagramData import Models.Diagram.Scale as Scale import Models.Diagram.Settings as DiagramSettings @@ -50,7 +52,7 @@ view { items, settings, property, selectedItem, onEditSelectedItem, onEndEditSel [ siteView { settings = settings , property = property - , position = ( 0, Constants.itemSpan + settings.size.height ) + , position = ( 0, Constants.itemSpan + CardSize.toInt settings.size.height ) , selectedItem = selectedItem , items = rootItems , onEditSelectedItem = onEditSelectedItem @@ -81,7 +83,7 @@ siteLineView settings ( xx1, yy1 ) ( xx2, yy2 ) = let centerX : Int centerX = - settings.size.width // 2 + CardSize.toInt settings.size.width // 2 in if xx1 == xx2 then Svg.line @@ -89,7 +91,7 @@ siteLineView settings ( xx1, yy1 ) ( xx2, yy2 ) = , SvgAttr.y1 <| String.fromInt yy1 , SvgAttr.x2 <| String.fromInt <| xx2 + centerX , SvgAttr.y2 <| String.fromInt yy2 - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "1" ] [] @@ -98,19 +100,19 @@ siteLineView settings ( xx1, yy1 ) ( xx2, yy2 ) = Svg.g [] [ Svg.line [ SvgAttr.x1 <| String.fromInt <| xx1 + centerX - , SvgAttr.y1 <| String.fromInt <| yy1 + settings.size.height + Constants.itemSpan // 2 + , SvgAttr.y1 <| String.fromInt <| yy1 + CardSize.toInt settings.size.height + Constants.itemSpan // 2 , SvgAttr.x2 <| String.fromInt <| xx2 + centerX - , SvgAttr.y2 <| String.fromInt <| yy1 + settings.size.height + Constants.itemSpan // 2 - , SvgAttr.stroke settings.color.line + , SvgAttr.y2 <| String.fromInt <| yy1 + CardSize.toInt settings.size.height + Constants.itemSpan // 2 + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "1" ] [] , Svg.line [ SvgAttr.x1 <| String.fromInt <| xx2 + centerX - , SvgAttr.y1 <| String.fromInt <| yy1 + settings.size.height + Constants.itemSpan // 2 + , SvgAttr.y1 <| String.fromInt <| yy1 + CardSize.toInt settings.size.height + Constants.itemSpan // 2 , SvgAttr.x2 <| String.fromInt <| xx2 + centerX , SvgAttr.y2 <| String.fromInt <| yy2 - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "1" ] [] @@ -129,17 +131,17 @@ siteTreeLineView settings ( xx1, yy1 ) ( xx2, yy2 ) = [ SvgAttr.x1 <| String.fromInt <| xx1 + itemPadding , SvgAttr.y1 <| String.fromInt <| yy1 , SvgAttr.x2 <| String.fromInt <| xx1 + itemPadding - , SvgAttr.y2 <| String.fromInt <| yy2 + settings.size.height // 2 - , SvgAttr.stroke settings.color.line + , SvgAttr.y2 <| String.fromInt <| yy2 + CardSize.toInt settings.size.height // 2 + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "1" ] [] , Svg.line [ SvgAttr.x1 <| String.fromInt <| xx1 + itemPadding - , SvgAttr.y1 <| String.fromInt <| yy2 + settings.size.height // 2 - , SvgAttr.x2 <| String.fromInt <| xx2 + settings.size.width - , SvgAttr.y2 <| String.fromInt <| yy2 + settings.size.height // 2 - , SvgAttr.stroke settings.color.line + , SvgAttr.y1 <| String.fromInt <| yy2 + CardSize.toInt settings.size.height // 2 + , SvgAttr.x2 <| String.fromInt <| xx2 + CardSize.toInt settings.size.width + , SvgAttr.y2 <| String.fromInt <| yy2 + CardSize.toInt settings.size.height // 2 + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "1" ] [] @@ -190,7 +192,7 @@ siteTreeView { settings, property, position, selectedItem, items, onEditSelected y : Int y = - Position.getY position + i * (settings.size.height + Constants.itemSpan) + childrenCount * (settings.size.height + Constants.itemSpan) + Position.getY position + i * (CardSize.toInt settings.size.height + Constants.itemSpan) + childrenCount * (CardSize.toInt settings.size.height + Constants.itemSpan) in [ siteTreeLineView settings (Tuple.mapSecond (\y_ -> y_ - Constants.itemSpan) position) ( Position.getX position, y ) , Card.viewWithDefaultColor @@ -210,7 +212,7 @@ siteTreeView { settings, property, position, selectedItem, items, onEditSelected , property = property , position = ( x - , y + (settings.size.height + Constants.itemSpan) + , y + (CardSize.toInt settings.size.height + Constants.itemSpan) ) , selectedItem = selectedItem , items = children @@ -252,7 +254,7 @@ siteView { settings, property, position, selectedItem, items, onEditSelectedItem let cardWidth : Int cardWidth = - settings.size.width + Constants.itemSpan + CardSize.toInt settings.size.width + Constants.itemSpan children : Items children = @@ -284,7 +286,7 @@ siteView { settings, property, position, selectedItem, items, onEditSelectedItem , property = property , position = ( x - , Position.getY position + settings.size.height + Constants.itemSpan + , Position.getY position + CardSize.toInt settings.size.height + Constants.itemSpan ) , selectedItem = selectedItem , items = children diff --git a/frontend/src/elm/Views/Diagram/Table.elm b/frontend/src/elm/Views/Diagram/Table.elm index 4c0a36439..793c4ccc9 100644 --- a/frontend/src/elm/Views/Diagram/Table.elm +++ b/frontend/src/elm/Views/Diagram/Table.elm @@ -3,6 +3,7 @@ module Views.Diagram.Table exposing (docs, view) import ElmBook.Actions as Actions import ElmBook.Chapter as Chapter exposing (Chapter) import Models.Diagram exposing (SelectedItem, SelectedItemInfo) +import Models.Diagram.CardSize as CardSize exposing (CardSize) import Models.Diagram.Data as DiagramData import Models.Diagram.Settings as DiagramSettings import Models.Diagram.Table as Table exposing (Header(..), Row(..), Table(..)) @@ -87,7 +88,7 @@ headerView { settings, property, selectedItem, item, onEditSelectedItem, onEndEd Lazy.lazy Grid.view { settings = settings , property = property - , position = ( settings.size.width * i, 0 ) + , position = ( CardSize.toInt settings.size.width * i, 0 ) , selectedItem = selectedItem , item = ii , onEditSelectedItem = onEditSelectedItem @@ -117,7 +118,7 @@ rowView { settings, property, selectedItem, rowNo, item, onEditSelectedItem, onE , Lazy.lazy Grid.view { settings = settings , property = property - , position = ( 0, settings.size.height * rowNo ) + , position = ( 0, CardSize.toInt settings.size.height * rowNo ) , selectedItem = selectedItem , item = item , onEditSelectedItem = onEditSelectedItem @@ -131,7 +132,7 @@ rowView { settings, property, selectedItem, rowNo, item, onEditSelectedItem, onE , Lazy.lazy Grid.view { settings = settings , property = property - , position = ( settings.size.width * (i + 1), settings.size.height * rowNo ) + , position = ( CardSize.toInt settings.size.width * (i + 1), CardSize.toInt settings.size.height * rowNo ) , selectedItem = selectedItem , item = childItem , onEditSelectedItem = onEditSelectedItem diff --git a/frontend/src/elm/Views/Diagram/TextNode.elm b/frontend/src/elm/Views/Diagram/TextNode.elm index be0d4d323..7a41c567b 100644 --- a/frontend/src/elm/Views/Diagram/TextNode.elm +++ b/frontend/src/elm/Views/Diagram/TextNode.elm @@ -24,6 +24,7 @@ import Html.Styled.Attributes as Attr exposing (css) import Html.Styled.Events exposing (onBlur, onInput) import Models.Color as Color exposing (Color) import Models.Diagram as Diagram exposing (ResizeDirection(..), SelectedItem, SelectedItemInfo) +import Models.Diagram.CardSize as CardSize import Models.Diagram.Settings as DiagramSettings import Models.FontSize as FontSize import Models.Item as Item exposing (Item) @@ -55,8 +56,8 @@ view { settings, property, position, selectedItem, item, onEditSelectedItem, onE ( width, height ) = ( Property.getNodeWidth property, Property.getNodeHeight property ) |> Tuple.mapBoth - (\w -> Maybe.withDefault settings.size.width w) - (\h -> Maybe.withDefault (settings.size.height - 1) h) + (\w -> Maybe.withDefault (CardSize.toInt settings.size.width) w) + (\h -> Maybe.withDefault (CardSize.toInt settings.size.height - 1) h) |> Tuple.mapBoth (\w -> w + offsetWidth) (\h -> h + offsetHeight) @@ -68,7 +69,7 @@ view { settings, property, position, selectedItem, item, onEditSelectedItem, onE , SvgAttr.height <| String.fromInt <| height - 1 , SvgAttr.x <| String.fromInt posX , SvgAttr.y <| String.fromInt posY - , SvgAttr.fill settings.backgroundColor + , SvgAttr.fill <| Color.toString settings.backgroundColor ] [] , textNode settings property ( posX, posY ) ( width, height ) color item @@ -97,8 +98,8 @@ view { settings, property, position, selectedItem, item, onEditSelectedItem, onE selectedItemSize = ( Property.getNodeWidth property, Property.getNodeHeight property ) |> Tuple.mapBoth - (\w -> Maybe.withDefault settings.size.width w) - (\h -> Maybe.withDefault (settings.size.height - 1) h) + (\w -> Maybe.withDefault (CardSize.toInt settings.size.width) w) + (\h -> Maybe.withDefault (CardSize.toInt settings.size.height - 1) h) |> Tuple.mapBoth (\w -> max 0 (w + Size.getWidth selectedItemOffsetSize)) (\h -> max 0 (h + Size.getHeight selectedItemOffsetSize)) @@ -118,7 +119,7 @@ view { settings, property, position, selectedItem, item, onEditSelectedItem, onE , SvgAttr.y <| String.fromInt y_ , SvgAttr.strokeWidth "1" , SvgAttr.stroke "transparent" - , SvgAttr.fill settings.backgroundColor + , SvgAttr.fill <| Color.toString settings.backgroundColor , SvgAttr.class "ts-node" ] [] @@ -246,43 +247,40 @@ root { settings, property, position, selectedItem, item, onEditSelectedItem, onE ( posX, posY ) = position - borderColor : String + borderColor : Color borderColor = Item.getBackgroundColor item - |> Maybe.map Color.toString |> Maybe.withDefault settings.color.activity.backgroundColor textColor : Color textColor = Item.getForegroundColor item - |> Maybe.map Color.toString |> Maybe.withDefault settings.color.activity.color - |> Color.fromString ( width, height ) = ( Property.getNodeWidth property, Property.getNodeHeight property ) |> Tuple.mapBoth - (\w -> Maybe.withDefault settings.size.width w) - (\h -> Maybe.withDefault (settings.size.height - 1) h) + (\w -> Maybe.withDefault (CardSize.toInt settings.size.width) w) + (\h -> Maybe.withDefault (CardSize.toInt settings.size.height - 1) h) view_ : Svg msg view_ = Svg.g - [ Events.onClickStopPropagation <| onSelect <| Just { item = item, position = ( posX, posY + settings.size.height ), displayAllMenu = True } ] + [ Events.onClickStopPropagation <| onSelect <| Just { item = item, position = ( posX, posY + CardSize.toInt settings.size.height ), displayAllMenu = True } ] [ Svg.rect [ SvgAttr.width <| String.fromInt width , SvgAttr.height <| String.fromInt <| height , SvgAttr.x <| String.fromInt posX , SvgAttr.y <| String.fromInt posY , SvgAttr.strokeWidth "3" - , SvgAttr.stroke borderColor + , SvgAttr.stroke <| Color.toString borderColor , SvgAttr.rx "32" , SvgAttr.ry "32" - , SvgAttr.fill settings.backgroundColor + , SvgAttr.fill <| Color.toString settings.backgroundColor , SvgAttr.class "ts-node" ] [] - , textNode settings property ( posX, posY ) ( settings.size.width, settings.size.height ) textColor item + , textNode settings property ( posX, posY ) ( CardSize.toInt settings.size.width, CardSize.toInt settings.size.height ) textColor item ] in case selectedItem of @@ -290,22 +288,22 @@ root { settings, property, position, selectedItem, item, onEditSelectedItem, onE if Item.eq item_ item then Svg.g [] [ Svg.rect - [ SvgAttr.width <| String.fromInt settings.size.width - , SvgAttr.height <| String.fromInt <| settings.size.height - 1 + [ SvgAttr.width <| String.fromInt <| CardSize.toInt settings.size.width + , SvgAttr.height <| String.fromInt <| CardSize.toInt settings.size.height - 1 , SvgAttr.x <| String.fromInt posX , SvgAttr.y <| String.fromInt posY , SvgAttr.strokeWidth "3" - , SvgAttr.stroke borderColor + , SvgAttr.stroke <| Color.toString borderColor , SvgAttr.rx "32" , SvgAttr.ry "32" - , SvgAttr.fill settings.backgroundColor + , SvgAttr.fill <| Color.toString settings.backgroundColor , SvgAttr.class "ts-node" ] [] , textNodeInput { settings = settings , pos = ( posX, posY ) - , size = ( settings.size.width, settings.size.height ) + , size = ( CardSize.toInt settings.size.width, CardSize.toInt settings.size.height ) , item = item_ , onEditSelectedItem = onEditSelectedItem , onEndEditSelectedItem = onEndEditSelectedItem diff --git a/frontend/src/elm/Views/Diagram/UseCaseDiagram.elm b/frontend/src/elm/Views/Diagram/UseCaseDiagram.elm index ded2fd188..86d2b4d07 100644 --- a/frontend/src/elm/Views/Diagram/UseCaseDiagram.elm +++ b/frontend/src/elm/Views/Diagram/UseCaseDiagram.elm @@ -165,7 +165,7 @@ actorView settings property fontSize name ( x, y ) = [ SvgAttr.cx <| String.fromInt (x + actorBaseSize) , SvgAttr.cy <| String.fromInt (y + actorBaseSize) , SvgAttr.r "15" - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "1" ] [] @@ -176,7 +176,7 @@ actorView settings property fontSize name ( x, y ) = , SvgAttr.y1 <| String.fromInt (y + actorSize2 - 6) , SvgAttr.x2 <| String.fromInt (x + actorBaseSize) , SvgAttr.y2 <| String.fromInt (y + actorSize4) - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "1" ] [] @@ -187,7 +187,7 @@ actorView settings property fontSize name ( x, y ) = , SvgAttr.y1 <| String.fromInt (y + actorSize2 + actorHalfSize) , SvgAttr.x2 <| String.fromInt (x + actorSize3 - actorHalfSize) , SvgAttr.y2 <| String.fromInt (y + actorSize2 + actorHalfSize) - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "1" ] [] @@ -198,7 +198,7 @@ actorView settings property fontSize name ( x, y ) = , SvgAttr.y1 <| String.fromInt (y + actorSize4) , SvgAttr.x2 <| String.fromInt x , SvgAttr.y2 <| String.fromInt (y + actorSize6) - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "1" ] [] @@ -209,7 +209,7 @@ actorView settings property fontSize name ( x, y ) = , SvgAttr.y1 <| String.fromInt (y + actorSize4) , SvgAttr.x2 <| String.fromInt (x + actorSize2) , SvgAttr.y2 <| String.fromInt (y + actorSize6) - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "1" ] [] @@ -288,7 +288,7 @@ arrowView settings = ] [ Svg.polygon [ SvgAttr.points "0,0 0,10 10,5" - , SvgAttr.fill settings.color.line + , SvgAttr.fill <| Color.toString settings.color.line ] [] ] @@ -327,7 +327,7 @@ relationLineView { settings, property, from, to, relation, reverse } = , SvgAttr.y1 <| String.fromInt <| fromY , SvgAttr.x2 <| String.fromInt <| toX , SvgAttr.y2 <| String.fromInt <| toY - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "1" , SvgAttr.strokeDasharray "15 5" , if reverse then @@ -385,7 +385,7 @@ useCaseLineView { settings, from, to } = , SvgAttr.y1 <| String.fromInt <| Position.getY from , SvgAttr.x2 <| String.fromInt <| Position.getX to , SvgAttr.y2 <| String.fromInt <| Position.getY to + actorBaseSize - , SvgAttr.stroke settings.color.line + , SvgAttr.stroke <| Color.toString settings.color.line , SvgAttr.strokeWidth "1" ] [] diff --git a/frontend/src/elm/Views/Diagram/UserStoryMap.elm b/frontend/src/elm/Views/Diagram/UserStoryMap.elm index 5f35dfef7..f64596737 100644 --- a/frontend/src/elm/Views/Diagram/UserStoryMap.elm +++ b/frontend/src/elm/Views/Diagram/UserStoryMap.elm @@ -10,6 +10,7 @@ import List import List.Extra as ListEx import Models.Color as Color import Models.Diagram exposing (Diagram, SelectedItem, SelectedItemInfo) +import Models.Diagram.CardSize as CardSize import Models.Diagram.Data as DiagramData import Models.Diagram.Scale as Scale import Models.Diagram.Settings as DiagramSettings @@ -96,7 +97,7 @@ mainView { settings, property, selectedItem, items, countByTasks, countByRelease { settings = settings , property = property , verticalCount = List.drop 2 countByReleaseLevel - , position = ( Constants.leftMargin + count * (settings.size.width + Constants.itemMargin), 10 ) + , position = ( Constants.leftMargin + count * (CardSize.toInt settings.size.width + Constants.itemMargin), 10 ) , selectedItem = selectedItem , item = item , onEditSelectedItem = onEditSelectedItem @@ -134,9 +135,9 @@ labelView { settings, property, width, userStoryMap } = (([ BoolEx.ifElse (Svg.line [ SvgAttr.x1 <| String.fromInt posX - , SvgAttr.y1 <| String.fromInt (Constants.itemMargin // 2 + (settings.size.height + Constants.itemMargin) * 2) + , SvgAttr.y1 <| String.fromInt (Constants.itemMargin // 2 + (CardSize.toInt settings.size.height + Constants.itemMargin) * 2) , SvgAttr.x2 <| String.fromInt width - , SvgAttr.y2 <| String.fromInt (Constants.itemMargin // 2 + (settings.size.height + Constants.itemMargin) * 2) + , SvgAttr.y2 <| String.fromInt (Constants.itemMargin // 2 + (CardSize.toInt settings.size.height + Constants.itemMargin) * 2) , SvgAttr.stroke <| Color.toString <| DiagramSettings.getLineColor settings property , SvgAttr.strokeWidth "2" ] @@ -149,13 +150,13 @@ labelView { settings, property, width, userStoryMap } = (Svg.g [] []) (hierarchy > 0) , BoolEx.ifElse - (labelTextView settings ( posX, settings.size.height + 25 ) (Property.getUserTask property |> Maybe.withDefault "USER TASKS")) + (labelTextView settings ( posX, CardSize.toInt settings.size.height + 25 ) (Property.getUserTask property |> Maybe.withDefault "USER TASKS")) (Svg.g [] []) (hierarchy > 0) ] ++ BoolEx.ifElse - [ labelTextView settings ( posX, settings.size.height * 2 + 50 ) (Property.getUserStory property |> Maybe.withDefault "USER STORIES") - , labelTextView settings ( posX, settings.size.height * 2 + 80 ) (Property.getReleaseLevel 1 property |> Maybe.withDefault "RELEASE 1") + [ labelTextView settings ( posX, CardSize.toInt settings.size.height * 2 + 50 ) (Property.getUserStory property |> Maybe.withDefault "USER STORIES") + , labelTextView settings ( posX, CardSize.toInt settings.size.height * 2 + 80 ) (Property.getReleaseLevel 1 property |> Maybe.withDefault "RELEASE 1") ] [ Svg.g [] [] ] (hierarchy > 1) @@ -170,7 +171,7 @@ labelView { settings, property, width, userStoryMap } = Constants.itemMargin // 2 + Constants.itemMargin - + ((settings.size.height + Constants.itemMargin) + + ((CardSize.toInt settings.size.height + Constants.itemMargin) * (countPerReleaseLevel |> List.take (xx + 2) |> List.sum @@ -235,14 +236,14 @@ activityView { settings, property, verticalCount, position, selectedItem, item, , verticalCount = verticalCount , position = ( Position.getX position - + (i * settings.size.width) + + (i * CardSize.toInt settings.size.width) + (if i > 0 then i * Constants.itemMargin else 0 ) - , Position.getY position + Constants.itemMargin + settings.size.height + , Position.getY position + Constants.itemMargin + CardSize.toInt settings.size.height ) , selectedItem = selectedItem , item = it @@ -302,7 +303,7 @@ taskView { settings, property, verticalCount, position, selectedItem, item, onEd , position = ( Position.getX position , Position.getY position - + ((i + 1) * settings.size.height) + + ((i + 1) * CardSize.toInt settings.size.height) + (Constants.itemMargin * 2) + (if i > 0 then Constants.itemMargin * i @@ -367,7 +368,7 @@ storyView { settings, property, verticalCount, parentCount, position, selectedIt ( Position.getX position , Position.getY position + (Basics.max 1 (itemCount - parentCount + i + 1) - * (Constants.itemMargin + settings.size.height) + * (Constants.itemMargin + CardSize.toInt settings.size.height) ) + Constants.itemMargin ) @@ -404,7 +405,7 @@ labelTextView settings ( posX, posY ) t = , SvgAttr.y <| String.fromInt posY , SvgAttr.width "100" , SvgAttr.height "40" - , SvgAttr.color settings.color.label + , SvgAttr.color <| Color.toString settings.color.label , SvgAttr.fontSize "12" , SvgAttr.fontWeight "bold" ] diff --git a/frontend/src/elm/Views/DropDownList.elm b/frontend/src/elm/Views/DropDownList.elm index be3103492..192595ce5 100644 --- a/frontend/src/elm/Views/DropDownList.elm +++ b/frontend/src/elm/Views/DropDownList.elm @@ -86,7 +86,7 @@ view onToggleDropDownList dropDownId currentId onChange items selectedValue = selectedItem = items |> ListEx.find (\item -> unwrapValue item.value == selectedValue) - |> Maybe.withDefault { name = "", value = stringValue selectedValue } + |> Maybe.withDefault { name = selectedValue, value = stringValue selectedValue } in Html.div [ Attr.css diff --git a/frontend/src/elm/Views/Menu.elm b/frontend/src/elm/Views/Menu.elm index b64217edd..fd56ea095 100644 --- a/frontend/src/elm/Views/Menu.elm +++ b/frontend/src/elm/Views/Menu.elm @@ -61,7 +61,7 @@ import Models.Color as Color import Models.Diagram.Item as DiagramItem exposing (DiagramItem) import Models.Diagram.Location as DiagramLocation import Models.Diagram.Type exposing (DiagramType(..)) -import Models.Exporter as Exporter +import Models.Export.Diagram as ExportDiagram import Models.FileType as FileType import Models.Model exposing (BrowserStatus, Menu(..)) import Models.Page as Page @@ -102,7 +102,7 @@ type alias Props msg = , currentDiagram : DiagramItem , onOpenLocalFile : msg , onOpenMenu : Menu -> msg - , onDownload : Exporter.Export -> msg + , onDownload : ExportDiagram.Export -> msg , onSaveLocalFile : msg , onSave : msg , onOpenCurrentFile : msg @@ -158,6 +158,9 @@ editMenu { diagramItem, lang, route, onOpenCurrentFile } = Route.EditLocalFile _ _ -> Lazy.lazy newMenu lang + Route.NotFound -> + Lazy.lazy newMenu lang + _ -> case diagramItem.id of Just _ -> @@ -369,36 +372,36 @@ view { page, lang, width, route, text, openMenu, settings, browserStatus, curren ] -baseExportMenu : { browserStatus : BrowserStatus, onDownload : Exporter.Export -> msg } -> List (MenuItem msg) +baseExportMenu : { browserStatus : BrowserStatus, onDownload : ExportDiagram.Export -> msg } -> List (MenuItem msg) baseExportMenu { browserStatus, onDownload } = [ MenuItem - { e = Just <| onDownload <| Exporter.downloadable FileType.svg + { e = Just <| onDownload <| ExportDiagram.downloadable FileType.svg , title = FileType.toString FileType.svg } , MenuItem - { e = Just <| onDownload <| Exporter.downloadable FileType.png + { e = Just <| onDownload <| ExportDiagram.downloadable FileType.png , title = FileType.toString FileType.png } , MenuItem - { e = Just <| onDownload <| Exporter.downloadable FileType.pdf + { e = Just <| onDownload <| ExportDiagram.downloadable FileType.pdf , title = FileType.toString FileType.pdf } , MenuItem - { e = Just <| onDownload <| Exporter.downloadable FileType.plainText + { e = Just <| onDownload <| ExportDiagram.downloadable FileType.plainText , title = FileType.toString FileType.plainText } , MenuItem - { e = Just <| onDownload <| Exporter.downloadable FileType.html + { e = Just <| onDownload <| ExportDiagram.downloadable FileType.html , title = FileType.toString FileType.html } ] ++ (if browserStatus.canUseClipboardItem then [ MenuItem - { e = Just <| onDownload <| Exporter.copyable FileType.png + { e = Just <| onDownload <| ExportDiagram.copyable FileType.png , title = "Copy " ++ FileType.toString FileType.png } , MenuItem - { e = Just <| onDownload <| Exporter.copyable FileType.Base64 + { e = Just <| onDownload <| ExportDiagram.copyable FileType.Base64 , title = "Copy " ++ FileType.toString FileType.Base64 } ] @@ -408,69 +411,69 @@ baseExportMenu { browserStatus, onDownload } = ) -exportMenu : { route : Route, browserStatus : BrowserStatus, onDownload : Exporter.Export -> msg } -> List (MenuItem msg) +exportMenu : { route : Route, browserStatus : BrowserStatus, onDownload : ExportDiagram.Export -> msg } -> List (MenuItem msg) exportMenu { route, browserStatus, onDownload } = case route of Route.Edit GanttChart _ _ -> MenuItem - { e = Just <| onDownload <| Exporter.copyable FileType.mermaid + { e = Just <| onDownload <| ExportDiagram.copyable FileType.mermaid , title = "Mermaid" } :: baseExportMenu { browserStatus = browserStatus, onDownload = onDownload } Route.Edit ErDiagram _ _ -> MenuItem - { e = Just <| onDownload <| Exporter.copyable FileType.ddl + { e = Just <| onDownload <| ExportDiagram.copyable FileType.ddl , title = "DDL" } :: MenuItem - { e = Just <| onDownload <| Exporter.copyable FileType.mermaid + { e = Just <| onDownload <| ExportDiagram.copyable FileType.mermaid , title = "Mermaid" } :: baseExportMenu { browserStatus = browserStatus, onDownload = onDownload } Route.Edit Table _ _ -> MenuItem - { e = Just <| onDownload <| Exporter.copyable FileType.markdown + { e = Just <| onDownload <| ExportDiagram.copyable FileType.markdown , title = "Markdown" } :: baseExportMenu { browserStatus = browserStatus, onDownload = onDownload } Route.Edit SequenceDiagram _ _ -> MenuItem - { e = Just <| onDownload <| Exporter.copyable FileType.mermaid + { e = Just <| onDownload <| ExportDiagram.copyable FileType.mermaid , title = "Mermaid" } :: baseExportMenu { browserStatus = browserStatus, onDownload = onDownload } Route.EditFile GanttChart _ -> MenuItem - { e = Just <| onDownload <| Exporter.copyable FileType.mermaid + { e = Just <| onDownload <| ExportDiagram.copyable FileType.mermaid , title = "Mermaid" } :: baseExportMenu { browserStatus = browserStatus, onDownload = onDownload } Route.EditFile ErDiagram _ -> MenuItem - { e = Just <| onDownload <| Exporter.copyable FileType.ddl + { e = Just <| onDownload <| ExportDiagram.copyable FileType.ddl , title = "DDL" } :: MenuItem - { e = Just <| onDownload <| Exporter.copyable FileType.mermaid + { e = Just <| onDownload <| ExportDiagram.copyable FileType.mermaid , title = "Mermaid" } :: baseExportMenu { browserStatus = browserStatus, onDownload = onDownload } Route.EditFile Table _ -> MenuItem - { e = Just <| onDownload <| Exporter.copyable FileType.markdown + { e = Just <| onDownload <| ExportDiagram.copyable FileType.markdown , title = "Markdown" } :: baseExportMenu { browserStatus = browserStatus, onDownload = onDownload } Route.EditFile SequenceDiagram _ -> MenuItem - { e = Just <| onDownload <| Exporter.copyable FileType.mermaid + { e = Just <| onDownload <| ExportDiagram.copyable FileType.mermaid , title = "Mermaid" } :: baseExportMenu { browserStatus = browserStatus, onDownload = onDownload } diff --git a/frontend/src/ts/model.ts b/frontend/src/ts/model.ts index 51bf9522a..00c3fe0f9 100644 --- a/frontend/src/ts/model.ts +++ b/frontend/src/ts/model.ts @@ -62,7 +62,8 @@ export type Settings = { text: string; title: string | undefined; diagramId: string | undefined; - storyMap: DiagramSettings; + diagramSettings?: DiagramSettings; + storyMap?: DiagramSettings; diagram: Diagram | undefined; location: DiagramLocation | undefined; theme: Theme | undefined; diff --git a/frontend/src/ts/settings.ts b/frontend/src/ts/settings.ts index 43795576a..83d28ecbb 100644 --- a/frontend/src/ts/settings.ts +++ b/frontend/src/ts/settings.ts @@ -6,7 +6,7 @@ const getSettingsKey = (diagram: string) => `${settingsKey}:${diagram}`; const getDefaultSettings = (isDarkMode: boolean) => ({ font: 'Nunito Sans', - storyMap: { + diagramSettings: { font: 'Nunito Sans', size: { width: 140, @@ -58,20 +58,39 @@ export const loadSettings = (isDarkMode: boolean, diagram?: string): Settings => ? (JSON.parse(diagramSettingsString) as DiagramSettings) : { color: {} }; const settingsObject = JSON.parse(settingsString) as Settings; - return { - ...defaultSettings, - ...settingsObject, - storyMap: { - ...defaultSettings.storyMap, - ...settingsObject.storyMap, - ...diagramSettings, - color: { - ...defaultSettings.storyMap.color, - ...settingsObject.storyMap.color, - ...diagramSettings.color, + + if (settingsObject.storyMap) { + return { + ...defaultSettings, + ...settingsObject, + diagramSettings: { + ...defaultSettings.diagramSettings, + ...settingsObject.storyMap, + ...diagramSettings, + color: { + ...defaultSettings.diagramSettings.color, + ...settingsObject.storyMap.color, + ...diagramSettings.color, + }, }, - }, - }; + }; + } + + if (settingsObject.diagramSettings) + return { + ...defaultSettings, + ...settingsObject, + diagramSettings: { + ...defaultSettings.diagramSettings, + ...settingsObject.diagramSettings, + ...diagramSettings, + color: { + ...defaultSettings.diagramSettings.color, + ...settingsObject.diagramSettings.color, + ...diagramSettings.color, + }, + }, + }; } return defaultSettings; @@ -86,7 +105,7 @@ export const saveSettings = (settings: Settings): void => { text: settings.text, title: settings.title, diagramId: settings.diagramId, - storyMap: settings.storyMap, + diagramSettings: settings.diagramSettings, diagram: settings.diagram, location: settings.location, theme: settings.theme, @@ -94,6 +113,6 @@ export const saveSettings = (settings: Settings): void => { ); if (settings.diagram?.diagram) { - localStorage.setItem(getSettingsKey(settings.diagram?.diagram), JSON.stringify(settings.storyMap)); + localStorage.setItem(getSettingsKey(settings.diagram?.diagram), JSON.stringify(settings.diagramSettings)); } }; diff --git a/frontend/tests/DiagramTests.elm b/frontend/tests/DiagramTests.elm index 4c78864ce..0db347143 100644 --- a/frontend/tests/DiagramTests.elm +++ b/frontend/tests/DiagramTests.elm @@ -4,7 +4,10 @@ import Browser.Dom exposing (Viewport) import Components.Diagram exposing (init, update, view) import Expect import Html.Styled +import Models.Color as Color import Models.Diagram as Diagram exposing (Model, Msg(..)) +import Models.Diagram.CardSize as CardSize +import Models.Diagram.Scale as Scale import Models.Diagram.Settings as DiagramSettings import Models.Diagram.Type as DiagramType exposing (DiagramType(..)) import Models.Item as Item @@ -631,28 +634,28 @@ defaultSettings : DiagramSettings.Settings defaultSettings = { font = "apple-system, BlinkMacSystemFont, Helvetica Neue, Hiragino Kaku Gothic ProN, 游ゴシック Medium, YuGothic, YuGothicM, メイリオ, Meiryo, sans-serif" , size = - { width = 140 - , height = 65 + { width = CardSize.fromInt 140 + , height = CardSize.fromInt 65 } - , backgroundColor = "#F5F5F6" + , backgroundColor = Color.fromString "#F5F5F6" , zoomControl = Just True - , scale = Just 1.0 + , scale = Just Scale.default , color = { activity = - { color = "#FFFFFF" - , backgroundColor = "#266B9A" + { color = Color.fromString "#FFFFFF" + , backgroundColor = Color.fromString "#266B9A" } , task = - { color = "#FFFFFF" - , backgroundColor = "#3E9BCD" + { color = Color.fromString "#FFFFFF" + , backgroundColor = Color.fromString "#3E9BCD" } , story = - { color = "#000000" - , backgroundColor = "#FFFFFF" + { color = Color.fromString "#000000" + , backgroundColor = Color.fromString "#FFFFFF" } - , line = "#434343" - , label = "#8C9FAE" - , text = Just "#111111" + , line = Color.fromString "#434343" + , label = Color.fromString "#8C9FAE" + , text = Just <| Color.fromString "#111111" } , toolbar = Just True } diff --git a/frontend/tests/Models/Diagram/CardSizeTests.elm b/frontend/tests/Models/Diagram/CardSizeTests.elm new file mode 100644 index 000000000..1cf4db744 --- /dev/null +++ b/frontend/tests/Models/Diagram/CardSizeTests.elm @@ -0,0 +1,25 @@ +module Models.Diagram.CardSizeTests exposing (suite) + +import Expect +import Fuzz +import Models.Diagram.CardSize as CardSize +import Test exposing (Test, fuzz) + + +suite : Test +suite = + fuzz Fuzz.int "CardSize test" <| + \s -> + Expect.equal + (CardSize.fromInt s + |> CardSize.toInt + ) + (if CardSize.max < s then + CardSize.max + + else if s < CardSize.min then + CardSize.min + + else + s + ) diff --git a/frontend/tests/Models/Fuzzer.elm b/frontend/tests/Models/Fuzzer.elm index f3532d6ec..5cce16ca3 100644 --- a/frontend/tests/Models/Fuzzer.elm +++ b/frontend/tests/Models/Fuzzer.elm @@ -1,16 +1,21 @@ -module Models.Fuzzer exposing (colorFuzzer, diagramItemFuzzer, diagramTypeFuzzer, itemFuzzer, itemSettingsFuzzer) +module Models.Fuzzer exposing (colorFuzzer, diagramItemFuzzer, diagramTypeFuzzer, itemFuzzer, itemSettingsFuzzer, settingsFuzzer) import Fuzz exposing (Fuzzer) import Models.Color as Color exposing (Color) +import Models.Diagram.CardSize as CardSize exposing (CardSize) import Models.Diagram.Id as DiagramId exposing (DiagramId) import Models.Diagram.Item exposing (DiagramItem) import Models.Diagram.Location as DiagramLocation exposing (Location) +import Models.Diagram.Scale as Scale exposing (Scale) +import Models.Diagram.Settings exposing (ColorSetting, ColorSettings) import Models.Diagram.Type exposing (DiagramType(..)) import Models.FontSize as FontSize exposing (FontSize) import Models.Item as Item exposing (Children, Item) import Models.Item.Settings as ItemSettings import Models.Position exposing (Position) +import Models.Settings exposing (EditorSettings, Settings) import Models.Text as Text exposing (Text) +import Models.Theme as Theme exposing (Theme) import Models.Title as Title exposing (Title) import Time exposing (Posix) @@ -95,7 +100,7 @@ itemFuzzer = (Fuzz.map (\s -> let - tokens: List String + tokens : List String tokens = String.split "#" s in @@ -203,6 +208,15 @@ hexFuzzer = ] +themeFuzzer : Fuzzer Theme +themeFuzzer = + Fuzz.oneOf + [ Fuzz.constant Theme.Dark + , Fuzz.constant Theme.Light + , Fuzz.constant <| Theme.System True + ] + + positionFuzzer : Fuzzer Position positionFuzzer = Fuzz.pair @@ -237,3 +251,61 @@ textFuzzer = titleFuzzer : Fuzzer Title titleFuzzer = Fuzz.map Title.fromString Fuzz.string + + +colorSettingFuzzer : Fuzzer ColorSetting +colorSettingFuzzer = + Fuzz.map ColorSetting colorFuzzer + |> Fuzz.andMap colorFuzzer + + +scaleFuzzer : Fuzzer Scale +scaleFuzzer = + Fuzz.map Scale.fromFloat Fuzz.float + + +cardSizeFuzzer : Fuzzer CardSize +cardSizeFuzzer = + Fuzz.map CardSize.fromInt Fuzz.int + + +colorSettingsFuzzer : Fuzzer ColorSettings +colorSettingsFuzzer = + Fuzz.map ColorSettings colorSettingFuzzer + |> Fuzz.andMap colorSettingFuzzer + |> Fuzz.andMap colorSettingFuzzer + |> Fuzz.andMap colorFuzzer + |> Fuzz.andMap colorFuzzer + |> Fuzz.andMap (Fuzz.maybe colorFuzzer) + + +diagramSettingsFuzzer : Fuzzer Models.Diagram.Settings.Settings +diagramSettingsFuzzer = + Fuzz.map Models.Diagram.Settings.Settings Fuzz.string + |> Fuzz.andMap (Fuzz.map Models.Diagram.Settings.Size cardSizeFuzzer |> Fuzz.andMap cardSizeFuzzer) + |> Fuzz.andMap colorSettingsFuzzer + |> Fuzz.andMap colorFuzzer + |> Fuzz.andMap (Fuzz.maybe Fuzz.bool) + |> Fuzz.andMap (Fuzz.maybe scaleFuzzer) + |> Fuzz.andMap (Fuzz.maybe Fuzz.bool) + + +settingsFuzzer : Fuzzer Settings +settingsFuzzer = + Fuzz.map Settings (Fuzz.maybe Fuzz.int) + |> Fuzz.andMap Fuzz.string + |> Fuzz.andMap (Fuzz.maybe diagramIdFuzzer) + |> Fuzz.andMap diagramSettingsFuzzer + |> Fuzz.andMap (Fuzz.maybe textFuzzer) + |> Fuzz.andMap (Fuzz.maybe titleFuzzer) + |> Fuzz.andMap + (Fuzz.maybe <| + (Fuzz.map EditorSettings + Fuzz.int + |> Fuzz.andMap Fuzz.bool + |> Fuzz.andMap Fuzz.bool + ) + ) + |> Fuzz.andMap (Fuzz.maybe diagramItemFuzzer) + |> Fuzz.andMap (Fuzz.maybe diagramLocationFuzzer) + |> Fuzz.andMap (Fuzz.maybe themeFuzzer) diff --git a/frontend/tests/Models/SettingsTests.elm b/frontend/tests/Models/SettingsTests.elm new file mode 100644 index 000000000..c69e35d29 --- /dev/null +++ b/frontend/tests/Models/SettingsTests.elm @@ -0,0 +1,24 @@ +module Models.SettingsTests exposing (suite) + +import Expect +import Json.Decode as D +import Json.Encode as E +import Models.Fuzzer exposing (settingsFuzzer) +import Models.Settings as Settings +import Test exposing (Test, describe, fuzz) + + +suite : Test +suite = + describe "Settings test" + [ fuzz settingsFuzzer "Settings decode/legacyEncode test" <| + \s -> + E.encode 0 (Settings.legacyEncoder s) + |> D.decodeString Settings.decoder + |> Expect.equal (Ok s) + , fuzz settingsFuzzer "Settings decode/encode test" <| + \s -> + E.encode 0 (Settings.encoder s) + |> D.decodeString Settings.decoder + |> Expect.equal (Ok s) + ] diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 2d6717936..a0fada490 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -129,6 +129,6 @@ export default defineConfig(({ mode }) => ({ key: '../certs/localhost.key', cert: '../certs/localhost.cert', } - : false, + : undefined, }, })); diff --git a/tools/fontlist/package-lock.json b/tools/fontlist/package-lock.json new file mode 100644 index 000000000..bc35e74ca --- /dev/null +++ b/tools/fontlist/package-lock.json @@ -0,0 +1,2223 @@ +{ + "name": "fontlist", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "fontlist", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "firebase-admin": "^11.11.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.4.tgz", + "integrity": "sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==", + "optional": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@fastify/busboy": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-1.2.1.tgz", + "integrity": "sha512-7PQA7EH43S0CxcOa9OeAnaeA0oQ+e/DHNPZwSQM9CQHW76jle5+OvLdibRp/Aafs9KXbLhxyjOTkRjWUbQEd3Q==", + "dependencies": { + "text-decoding": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@firebase/app-types": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.0.tgz", + "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==" + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.1.tgz", + "integrity": "sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg==" + }, + "node_modules/@firebase/component": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.4.tgz", + "integrity": "sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA==", + "dependencies": { + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database": { + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.14.4.tgz", + "integrity": "sha512-+Ea/IKGwh42jwdjCyzTmeZeLM3oy1h0mFPsTy6OqCWzcu/KFqRAr5Tt1HRCOBlNOdbh84JPZC47WLU18n2VbxQ==", + "dependencies": { + "@firebase/auth-interop-types": "0.2.1", + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.3.4.tgz", + "integrity": "sha512-kuAW+l+sLMUKBThnvxvUZ+Q1ZrF/vFJ58iUY9kAcbX48U03nVzIF6Tmkf0p3WVQwMqiXguSgtOPIB6ZCeF+5Gg==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/database": "0.14.4", + "@firebase/database-types": "0.10.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database-types": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.10.4.tgz", + "integrity": "sha512-dPySn0vJ/89ZeBac70T+2tWWPiJXWbmRygYv0smT5TfE3hDrQ09eKMF3Y+vMlTdrMWq7mUdYW5REWPSGH4kAZQ==", + "dependencies": { + "@firebase/app-types": "0.9.0", + "@firebase/util": "1.9.3" + } + }, + "node_modules/@firebase/logger": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz", + "integrity": "sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/util": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.3.tgz", + "integrity": "sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@google-cloud/firestore": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-6.8.0.tgz", + "integrity": "sha512-JRpk06SmZXLGz0pNx1x7yU3YhkUXheKgH5hbDZ4kMsdhtfV5qPLJLRI4wv69K0cZorIk+zTMOwptue7hizo0eA==", + "optional": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "functional-red-black-tree": "^1.0.1", + "google-gax": "^3.5.7", + "protobufjs": "^7.2.5" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@google-cloud/paginator": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.7.tgz", + "integrity": "sha512-jJNutk0arIQhmpUUQJPJErsojqo834KcyB6X7a1mxuic8i1tKXxde8E69IZxNZawRIlZdIK2QY4WALvlK5MzYQ==", + "optional": true, + "dependencies": { + "arrify": "^2.0.0", + "extend": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@google-cloud/projectify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-3.0.0.tgz", + "integrity": "sha512-HRkZsNmjScY6Li8/kb70wjGlDDyLkVk3KvoEo9uIoxSjYLJasGiCch9+PqRVDOCGUFvEIqyogl+BeqILL4OJHA==", + "optional": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@google-cloud/promisify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-3.0.1.tgz", + "integrity": "sha512-z1CjRjtQyBOYL+5Qr9DdYIfrdLBe746jRTYfaYU6MeXkqp7UfYs/jX16lFFVzZ7PGEJvqZNqYUEtb1mvDww4pA==", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@google-cloud/storage": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-6.12.0.tgz", + "integrity": "sha512-78nNAY7iiZ4O/BouWMWTD/oSF2YtYgYB3GZirn0To6eBOugjXVoK+GXgUXOl+HlqbAOyHxAVXOlsj3snfbQ1dw==", + "optional": true, + "dependencies": { + "@google-cloud/paginator": "^3.0.7", + "@google-cloud/projectify": "^3.0.0", + "@google-cloud/promisify": "^3.0.0", + "abort-controller": "^3.0.0", + "async-retry": "^1.3.3", + "compressible": "^2.0.12", + "duplexify": "^4.0.0", + "ent": "^2.2.0", + "extend": "^3.0.2", + "fast-xml-parser": "^4.2.2", + "gaxios": "^5.0.0", + "google-auth-library": "^8.0.1", + "mime": "^3.0.0", + "mime-types": "^2.0.8", + "p-limit": "^3.0.1", + "retry-request": "^5.0.0", + "teeny-request": "^8.0.0", + "uuid": "^8.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@google-cloud/storage/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.8.21", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.21.tgz", + "integrity": "sha512-KeyQeZpxeEBSqFVTi3q2K7PiPXmgBfECc4updA1ejCLjYmoAlvvM3ZMp5ztTDUCUQmoY3CpDxvchjO1+rFkoHg==", + "optional": true, + "dependencies": { + "@grpc/proto-loader": "^0.7.0", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz", + "integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==", + "optional": true, + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.4", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@jsdoc/salty": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.6.tgz", + "integrity": "sha512-aA+awb5yoml8TQ3CzI5Ue7sM3VMRC4l1zJJW4fgZ8OCL1wshJZhNzaf0PL85DSnOUw6QuFgeHGD/eq/xwwAF2g==", + "optional": true, + "dependencies": { + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=v12.0.0" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "optional": true + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "optional": true + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "optional": true + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "optional": true + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "optional": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "optional": true + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "optional": true + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "optional": true + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "optional": true + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "optional": true + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "optional": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.41", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", + "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", + "optional": true, + "dependencies": { + "@types/minimatch": "^5.1.2", + "@types/node": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz", + "integrity": "sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/linkify-it": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz", + "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==", + "optional": true + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "optional": true + }, + "node_modules/@types/markdown-it": { + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", + "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "optional": true, + "dependencies": { + "@types/linkify-it": "*", + "@types/mdurl": "*" + } + }, + "node_modules/@types/mdurl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", + "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==", + "optional": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "optional": true + }, + "node_modules/@types/node": { + "version": "20.9.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.4.tgz", + "integrity": "sha512-wmyg8HUhcn6ACjsn8oKYjkN/zUzQeNtMy44weTJSM6p4MMzEOuKbA3OjJ267uPCOW7Xex9dyrNTful8XTQYoDA==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/qs": { + "version": "6.9.10", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", + "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "node_modules/@types/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-F3OznnSLAUxFrCEu/L5PY8+ny8DtcFRjx7fZZ9bycvXRi3KPTRS9HOitGZwvPg0juRhXFWIeKX58cnX5YqLohQ==", + "optional": true, + "dependencies": { + "@types/glob": "*", + "@types/node": "*" + } + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "optional": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "optional": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "optional": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "optional": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "optional": true + }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "optional": true, + "dependencies": { + "retry": "0.13.1" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "optional": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "optional": true + }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "optional": true + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "node_modules/catharsis": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", + "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", + "optional": true, + "dependencies": { + "lodash": "^4.17.15" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "optional": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "optional": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "optional": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "optional": true + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "optional": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "optional": true + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "optional": true + }, + "node_modules/duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "optional": true, + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "optional": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "optional": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", + "optional": true + }, + "node_modules/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "optional": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "optional": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "optional": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "optional": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "optional": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "optional": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "optional": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "optional": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "optional": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "optional": true + }, + "node_modules/fast-text-encoding": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz", + "integrity": "sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==", + "optional": true + }, + "node_modules/fast-xml-parser": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.2.tgz", + "integrity": "sha512-rmrXUXwbJedoXkStenj1kkljNF7ugn5ZjR9FJcwmCfcCbtOMDghPajbc+Tck6vE6F5XsDmx+Pr2le9fw8+pXBg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "optional": true, + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/firebase-admin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-11.11.0.tgz", + "integrity": "sha512-lp784gXFAJgUEtjSdYNZGTWZqltqjBkoaPSQhDKnmWXJP/MCbWdiDY1hsdkl/6O4O4KFovTjUDLu26sojwdQvw==", + "dependencies": { + "@fastify/busboy": "^1.2.1", + "@firebase/database-compat": "^0.3.4", + "@firebase/database-types": "^0.10.4", + "@types/node": ">=12.12.47", + "jsonwebtoken": "^9.0.0", + "jwks-rsa": "^3.0.1", + "node-forge": "^1.3.1", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "@google-cloud/firestore": "^6.6.0", + "@google-cloud/storage": "^6.9.5" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "optional": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "optional": true + }, + "node_modules/gaxios": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.1.3.tgz", + "integrity": "sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==", + "optional": true, + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/gcp-metadata": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.3.0.tgz", + "integrity": "sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==", + "optional": true, + "dependencies": { + "gaxios": "^5.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "optional": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "optional": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/google-auth-library": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-8.9.0.tgz", + "integrity": "sha512-f7aQCJODJFmYWN6PeNKzgvy9LI2tYmXnzpNDHEjG5sDNPgGb2FXQyTBnXeSH+PAtpKESFD+LmHw3Ox3mN7e1Fg==", + "optional": true, + "dependencies": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^5.0.0", + "gcp-metadata": "^5.3.0", + "gtoken": "^6.1.0", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/google-gax": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-3.6.1.tgz", + "integrity": "sha512-g/lcUjGcB6DSw2HxgEmCDOrI/CByOwqRvsuUvNalHUK2iPPPlmAIpbMbl62u0YufGMr8zgE3JL7th6dCb1Ry+w==", + "optional": true, + "dependencies": { + "@grpc/grpc-js": "~1.8.0", + "@grpc/proto-loader": "^0.7.0", + "@types/long": "^4.0.0", + "@types/rimraf": "^3.0.2", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "fast-text-encoding": "^1.0.3", + "google-auth-library": "^8.0.2", + "is-stream-ended": "^0.1.4", + "node-fetch": "^2.6.1", + "object-hash": "^3.0.0", + "proto3-json-serializer": "^1.0.0", + "protobufjs": "7.2.4", + "protobufjs-cli": "1.1.1", + "retry-request": "^5.0.0" + }, + "bin": { + "compileProtos": "build/tools/compileProtos.js", + "minifyProtoJson": "build/tools/minify.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/google-gax/node_modules/protobufjs": { + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.4.tgz", + "integrity": "sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/google-p12-pem": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-4.0.1.tgz", + "integrity": "sha512-WPkN4yGtz05WZ5EhtlxNDWPhC4JIic6G8ePitwUWy4l+XPVYec+a0j0Ts47PDtW59y3RwAhUd9/h9ZZ63px6RQ==", + "optional": true, + "dependencies": { + "node-forge": "^1.3.1" + }, + "bin": { + "gp12-pem": "build/src/bin/gp12-pem.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "optional": true + }, + "node_modules/gtoken": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-6.1.2.tgz", + "integrity": "sha512-4ccGpzz7YAr7lxrT2neugmXQ3hP9ho2gcaityLVkiUecAiwiy60Ii8gRbZeOsXV19fYaRjgBSshs8kXw+NKCPQ==", + "optional": true, + "dependencies": { + "gaxios": "^5.0.1", + "google-p12-pem": "^4.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "optional": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "optional": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "optional": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "optional": true + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-stream-ended": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", + "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==", + "optional": true + }, + "node_modules/jose": { + "version": "4.15.4", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz", + "integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js2xmlparser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", + "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", + "optional": true, + "dependencies": { + "xmlcreate": "^2.0.4" + } + }, + "node_modules/jsdoc": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.2.tgz", + "integrity": "sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==", + "optional": true, + "dependencies": { + "@babel/parser": "^7.20.15", + "@jsdoc/salty": "^0.2.1", + "@types/markdown-it": "^12.2.3", + "bluebird": "^3.7.2", + "catharsis": "^0.9.0", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.2", + "klaw": "^3.0.0", + "markdown-it": "^12.3.2", + "markdown-it-anchor": "^8.4.1", + "marked": "^4.0.10", + "mkdirp": "^1.0.4", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.1.0", + "underscore": "~1.13.2" + }, + "bin": { + "jsdoc": "jsdoc.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "optional": true, + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "optional": true, + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jwks-rsa": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.1.0.tgz", + "integrity": "sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg==", + "dependencies": { + "@types/express": "^4.17.17", + "@types/jsonwebtoken": "^9.0.2", + "debug": "^4.3.4", + "jose": "^4.14.6", + "limiter": "^1.1.5", + "lru-memoizer": "^2.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "optional": true, + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "optional": true, + "dependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "optional": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, + "node_modules/linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "optional": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "optional": true + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "optional": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", + "optional": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lru-memoizer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.2.0.tgz", + "integrity": "sha512-QfOZ6jNkxCcM/BkIPnFsqDhtrazLRsghi9mBwFAzol5GCvj4EkFT899Za3+QwikCg5sRX8JstioBDwOxEyzaNw==", + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "~4.0.0" + } + }, + "node_modules/lru-memoizer/node_modules/lru-cache": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", + "integrity": "sha512-uQw9OqphAGiZhkuPlpFGmdTU2tEuhxTourM/19qGJrxBPHAr/f8BT1a0i/lOclESnGatdJG/UCkP9kZB/Lh1iw==", + "dependencies": { + "pseudomap": "^1.0.1", + "yallist": "^2.0.0" + } + }, + "node_modules/lru-memoizer/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" + }, + "node_modules/markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "optional": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it-anchor": { + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", + "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", + "optional": true, + "peerDependencies": { + "@types/markdown-it": "*", + "markdown-it": "*" + } + }, + "node_modules/marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "optional": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "optional": true + }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "optional": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "optional": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "optional": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "optional": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "optional": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "optional": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "optional": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "optional": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "optional": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "optional": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/proto3-json-serializer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-1.1.1.tgz", + "integrity": "sha512-AwAuY4g9nxx0u52DnSMkqqgyLHaW/XaPLtaAo3y/ZCfeaQB/g4YDH4kb8Wc/mWzWvu0YjOznVnfn373MVZZrgw==", + "optional": true, + "dependencies": { + "protobufjs": "^7.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/protobufjs": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.5.tgz", + "integrity": "sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/protobufjs-cli": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/protobufjs-cli/-/protobufjs-cli-1.1.1.tgz", + "integrity": "sha512-VPWMgIcRNyQwWUv8OLPyGQ/0lQY/QTQAVN5fh+XzfDwsVw1FZ2L3DM/bcBf8WPiRz2tNpaov9lPZfNcmNo6LXA==", + "optional": true, + "dependencies": { + "chalk": "^4.0.0", + "escodegen": "^1.13.0", + "espree": "^9.0.0", + "estraverse": "^5.1.0", + "glob": "^8.0.0", + "jsdoc": "^4.0.0", + "minimist": "^1.2.0", + "semver": "^7.1.2", + "tmp": "^0.2.1", + "uglify-js": "^3.7.7" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "protobufjs": "^7.0.0" + } + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", + "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", + "optional": true, + "dependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "optional": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/retry-request": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-5.0.2.tgz", + "integrity": "sha512-wfI3pk7EE80lCIXprqh7ym48IHYdwmAAzESdbU8Q9l7pnRCk9LEhpbOTNKjz6FARLm/Bl5m+4F0ABxOkYUujSQ==", + "optional": true, + "dependencies": { + "debug": "^4.1.1", + "extend": "^3.0.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "optional": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "optional": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/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==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stream-events": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", + "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "optional": true, + "dependencies": { + "stubs": "^3.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "optional": true + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "optional": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "optional": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "optional": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "optional": true + }, + "node_modules/stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", + "optional": true + }, + "node_modules/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==", + "optional": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/teeny-request": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-8.0.3.tgz", + "integrity": "sha512-jJZpA5He2y52yUhA7pyAGZlgQpcB+xLjcN0eUFxr9c8hP/H7uOXbBNVo/O0C/xVfJLJs680jvkFgVJEEvk9+ww==", + "optional": true, + "dependencies": { + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.1", + "stream-events": "^1.0.5", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/text-decoding": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-decoding/-/text-decoding-1.0.0.tgz", + "integrity": "sha512-/0TJD42KDnVwKmDK6jj3xP7E2MG7SHAOG4tyTgyUCRPdHwvkquYNLEQltmdMa3owq3TkddCVcTsoctJI8VQNKA==" + }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "optional": true, + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "optional": true + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "optional": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "optional": true + }, + "node_modules/uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", + "optional": true + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "optional": true + }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "optional": true + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "optional": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "optional": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "optional": true + }, + "node_modules/xmlcreate": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", + "optional": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "optional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "optional": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/tools/fontlist/package.json b/tools/fontlist/package.json new file mode 100644 index 000000000..3e7d0eedb --- /dev/null +++ b/tools/fontlist/package.json @@ -0,0 +1,14 @@ +{ + "name": "fontlist", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "firebase-admin": "^11.11.0" + } +} diff --git a/tools/fontlist/upload.js b/tools/fontlist/upload.js new file mode 100644 index 000000000..8c4ba0f49 --- /dev/null +++ b/tools/fontlist/upload.js @@ -0,0 +1,39 @@ +const fs = require("fs"); +const zlib = require("zlib"); + +const { initializeApp, cert } = require("firebase-admin/app"); +const { getStorage } = require("firebase-admin/storage"); + +initializeApp({ + credential: cert( + JSON.parse( + Buffer.from( + process.env.DATABASE_GOOGLE_APPLICATION_CREDENTIALS_JSON, + "base64" + ).toString() + ) + ), + storageBucket: process.env.FIREBASE_STORAGE_BUCKET, +}); + +(async () => { + fs.readdir("./assets/fontlist/", (err, files) => { + files.forEach(async (file) => { + const uploadFile = `./assets/fontlist/${file}`; + fs.writeFileSync( + `${uploadFile}.gz`, + zlib.gzipSync(fs.readFileSync(`${uploadFile}`, "utf-8")) + ); + + await getStorage() + .bucket() + .upload(`${uploadFile}.gz`, { + destination: `fontlist/${file}.gz`, + }) + .catch((err) => console.log(err)); + + fs.unlinkSync(`${uploadFile}.gz`); + console.log(`upload ${file}`); + }); + }); +})();