├── dartclj.build_artifacts.txt ├── .clj-kondo └── config.edn ├── npm-test-app ├── deps.edn ├── .gitignore ├── shadow-cljs.edn ├── README.md ├── src │ └── converter │ │ └── core.cljs ├── package.json ├── assets │ └── index.html └── package-lock.json ├── images └── Screenshot 2022-05-28 at 20.11.09.png ├── .npmignore ├── doc └── intro.md ├── Dockerfile ├── shadow-cljs.edn ├── .github └── workflows │ ├── gitlab_sync.yml │ └── build-binaries.yml ├── src └── dumch │ ├── base64.cljs │ ├── util.cljc │ ├── convert.cljc │ ├── dartclojure.cljc │ ├── improve.cljc │ └── parse.cljc ├── compile.sh ├── .gitignore ├── CHANGELOG.md ├── package.json ├── project.clj ├── deps.edn ├── test └── dumch │ ├── improve_test.cljc │ ├── integration_test.cljc │ └── parse_test.cljc ├── pom.xml ├── resources └── widget-parser.bnf └── README.md /dartclj.build_artifacts.txt: -------------------------------------------------------------------------------- 1 | [EXECUTABLE] 2 | dartclojure 3 | 4 | -------------------------------------------------------------------------------- /.clj-kondo/config.edn: -------------------------------------------------------------------------------- 1 | {:lint-as {instaparse.core/defparser clojure.core/def}} 2 | -------------------------------------------------------------------------------- /npm-test-app/deps.edn: -------------------------------------------------------------------------------- 1 | {:deps {org.clojure/clojurescript {:mvn/version "1.11.54"}}} -------------------------------------------------------------------------------- /images/Screenshot 2022-05-28 at 20.11.09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D00mch/DartClojure/HEAD/images/Screenshot 2022-05-28 at 20.11.09.png -------------------------------------------------------------------------------- /npm-test-app/.gitignore: -------------------------------------------------------------------------------- 1 | # Lint 2 | .clj-kondo/* 3 | !.clj-kondo/config.edn 4 | .lsp/ 5 | 6 | # CLJS 7 | .cljs_node_repl/ 8 | cljs-test-runner-out/ 9 | .shadow-cljs/ 10 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Put everything on the blacklist by default 2 | * 3 | */** 4 | **/.DS_Store 5 | */**/.DS_Store 6 | 7 | # Whitelist 8 | !target/npm-app 9 | !target/npm-lib 10 | !package.json 11 | !README.md 12 | !CHANGELOG.md 13 | !LICENSE 14 | -------------------------------------------------------------------------------- /doc/intro.md: -------------------------------------------------------------------------------- 1 | # How to use 2 | 3 | Get jar and run it like: 4 | 5 | ```bash 6 | java -jar dartclojure.jar "Text('text')" 7 | ``` 8 | 9 | Or load a library in jvm repl and run like: 10 | 11 | ```clojure 12 | (dart->clojure "Text('text')") 13 | ``` 14 | -------------------------------------------------------------------------------- /npm-test-app/shadow-cljs.edn: -------------------------------------------------------------------------------- 1 | {:source-paths ["src"] 2 | :dependencies [] 3 | :dev-http {8080 "target/"} 4 | :builds {:app {:output-dir "target/" 5 | :asset-path "." 6 | :target :browser 7 | :modules {:main {:init-fn converter.core/main!}}}}} -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # build uberjar locally 2 | FROM ghcr.io/graalvm/graalvm-ce:ol8-java17 AS native 3 | WORKDIR /usr/src/app 4 | COPY . . 5 | RUN gu install native-image 6 | WORKDIR /usr/src/app 7 | COPY compile.sh . 8 | RUN chmod +x compile.sh 9 | RUN ./compile.sh 10 | CMD ["/usr/src/app/dartclojure", "Text(1)"] 11 | -------------------------------------------------------------------------------- /npm-test-app/README.md: -------------------------------------------------------------------------------- 1 | # DartCLojure NPM test app 2 | 3 | Testing that we can consume the npm package. 4 | 5 | Install the local npm package: 6 | 7 | ``` 8 | npm i .. 9 | ``` 10 | 11 | Start the REPL something like so: 12 | 13 | ```sh 14 | npx shadow-cljs -d cider/cider-nrepl:0.27.4 watch :app 15 | ``` 16 | 17 | Build the app for release: 18 | 19 | ```sh 20 | npm i dartclojure 21 | npm run release 22 | ``` 23 | -------------------------------------------------------------------------------- /shadow-cljs.edn: -------------------------------------------------------------------------------- 1 | {:deps {:aliases [:test-shadow-cljs]} 2 | :builds 3 | {:lib {:target :node-library 4 | :exports {:convert dumch.convert/convert} 5 | :output-to "target/npm-lib/index.js"} 6 | :app {:target :node-script 7 | :main dumch.dartclojure/node-main 8 | :output-to "target/npm-app/index.js" 9 | :devtools {:after-load dumch.dartclojure/shadow-cljs-reload}} 10 | :test {:target :node-test, :output-to "target/node-test/test.js" 11 | :autorun true}}} -------------------------------------------------------------------------------- /.github/workflows/gitlab_sync.yml: -------------------------------------------------------------------------------- 1 | name: GitlabSync 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | delete: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | sync: 13 | runs-on: ubuntu-latest 14 | name: Git Repo Sync 15 | steps: 16 | - uses: actions/checkout@v2 17 | with: 18 | fetch-depth: 0 19 | - uses: wangchucheng/git-repo-sync@v0.1.0 20 | with: 21 | target-url: ${{ secrets.TARGET_URL }} 22 | target-username: ${{ secrets.TARGET_USERNAME }} 23 | target-token: ${{ secrets.TARGET_TOKEN }} 24 | -------------------------------------------------------------------------------- /npm-test-app/src/converter/core.cljs: -------------------------------------------------------------------------------- 1 | (ns converter.core 2 | (:require ["dartclojure" :as dartclojure])) 3 | 4 | (println "Hello") 5 | 6 | (defn ^:export convert [] 7 | (try 8 | (let [dart-code (.-value (js/document.getElementById "dart")) 9 | clj-code (dartclojure/convert dart-code)] 10 | (set! (.-innerHTML (js/document.getElementById "clojure")) clj-code)) 11 | (catch :default e 12 | (js/alert e)))) 13 | 14 | (defn main! [] 15 | (println "Hello from main")) 16 | 17 | (defn ^:dev/after-load reload! [] 18 | (println "shadow-cljs reloaded")) -------------------------------------------------------------------------------- /src/dumch/base64.cljs: -------------------------------------------------------------------------------- 1 | (ns dumch.base64) 2 | 3 | ;; NB: These functions use deprecated js/escape and js/unescape functions 4 | ;; https://developer.mozilla.org/en-US/docs/Glossary/Base64 5 | 6 | (defn utf8_to_b64 7 | "Returns `str` encoded to base64. Unicode safe." 8 | [str] 9 | (-> str 10 | js/encodeURIComponent 11 | js/unescape 12 | js/btoa)) 13 | 14 | (defn b64_to_utf8 15 | "Returns `b64` decoded from base64. Unicode safe." 16 | [b64] 17 | (-> b64 18 | js/atob 19 | js/escape 20 | js/decodeURIComponent)) 21 | 22 | (comment 23 | (utf8_to_b64 "a") 24 | (utf8_to_b64 "✓ à la mode") 25 | (b64_to_utf8 "4pyTIMOgIGxhIG1vZGU=") 26 | ) -------------------------------------------------------------------------------- /npm-test-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "npm-test-app", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "main.js", 6 | "scripts": { 7 | "watch": "shadow-cljs watch app", 8 | "compile": "shadow-cljs compile app", 9 | "release": "shadow-cljs release app", 10 | "html": "mkdir -p target && cp assets/index.html target/", 11 | "serve": "npm run html && http-server target/", 12 | "del": "rm -r target/*", 13 | "build": "npm run release && npm rum html && npm run serve" 14 | }, 15 | "author": "", 16 | "license": "MIT", 17 | "devDependencies": { 18 | "http-server": "^14.1.1", 19 | "shadow-cljs": "^2.19.3" 20 | }, 21 | "dependencies": { 22 | "dartclojure": "file:.." 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /compile.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | mkdir -p META-INF/native-image 3 | 4 | echo '[ 5 | { 6 | "name": "java.lang.reflect.AccessibleObject", 7 | "methods" : [{"name":"canAccess"}] 8 | } 9 | ]' | tee META-INF/native-image/logging.json 10 | 11 | # remove -H:+StaticExecutableWithDynamicLibC for m1 builds 12 | 13 | native-image -jar dartclojure.jar --no-fallback \ 14 | -J-Dclojure.spec.skip.macros=true -J-Dclojure.compiler.direct-linking=true \ 15 | --verbose --no-server -J-Xmx3G \ 16 | --report-unsupported-elements-at-runtime --native-image-info \ 17 | -H:CCompilerOption=-pipe \ 18 | --features=clj_easy.graal_build_time.InitClojureClasses \ 19 | -H:ReflectionConfigurationFiles=META-INF/native-image/logging.json 20 | 21 | chmod +x dartclojure 22 | echo "Size of generated native-image `ls -sh dartclojure`" 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .calva/output-window/ 2 | .classpath 3 | .cpcache 4 | .DS_Store 5 | .eastwood 6 | .factorypath 7 | .hg/ 8 | .hgignore 9 | .java-version 10 | .lein-* 11 | .lsp/.cache 12 | .lsp/sqlite.db 13 | .nrepl-history 14 | .nrepl-port 15 | .portal 16 | .project 17 | .rebel_readline_history 18 | .settings 19 | .socket-repl-port 20 | .sw* 21 | .vscode 22 | *.class 23 | *.jar 24 | *.swp 25 | *~ 26 | /checkouts 27 | /classes 28 | /target 29 | 30 | # Native 31 | /META-INF 32 | /reports 33 | dartclojure-*-aarch64-darwin 34 | dartclojure-*-aarch64-linux 35 | 36 | # Lint 37 | .clj-kondo/* 38 | !.clj-kondo/config.edn 39 | .lsp/ 40 | 41 | # CLJS 42 | .cljs_node_repl/ 43 | cljs-test-runner-out/ 44 | .shadow-cljs/ 45 | 46 | # Node 47 | node_modules/ 48 | 49 | # NPM Example App 50 | npm-test-app/target 51 | 52 | # Idea 53 | DartClojure.iml 54 | .idea/ 55 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/). 3 | 4 | ## [Unreleased] 5 | ### Changed 6 | - Add a new arity to `make-widget-async` to provide a different widget shape. 7 | 8 | ## [0.1.1] - 2022-05-22 9 | ### Changed 10 | - Documentation on how to make the widgets. 11 | 12 | ### Removed 13 | - `make-widget-sync` - we're all async, all the time. 14 | 15 | ### Fixed 16 | - Fixed widget maker to keep working when daylight savings switches over. 17 | 18 | ## 0.1.0 - 2022-05-22 19 | ### Added 20 | - Files from the new template. 21 | - Widget maker public API - `make-widget-sync`. 22 | 23 | [Unreleased]: https://github.com/dumch/dartclojure/compare/0.1.1...HEAD 24 | [0.1.1]: https://github.com/dumch/dartclojure/compare/0.1.0...0.1.1 25 | -------------------------------------------------------------------------------- /src/dumch/util.cljc: -------------------------------------------------------------------------------- 1 | (ns dumch.util 2 | (:require [rewrite-clj.node :as n] 3 | #?(:clj [clojure.java.io :as io])) 4 | #?(:cljs (:require-macros [dumch.util]))) 5 | 6 | #?(:clj (set! *warn-on-reflection* true)) 7 | 8 | (def ws (n/spaces 1)) 9 | (defn spaces [sq] (interpose ws sq)) 10 | (defn lists* [& args] (spaces (apply list* args))) 11 | (defn maps [f sq] (spaces (map f sq))) 12 | (defn mapcats [f sq] (spaces (mapcat f sq))) 13 | 14 | (def nl (n/newlines 1)) 15 | (defn mapn [f sq] (interpose nl (map f sq))) 16 | (defn mapcatn [f sq] (interpose nl (mapcat f sq))) 17 | 18 | #?(:clj 19 | (defmacro inline-resource [resource-path] 20 | (slurp (clojure.java.io/resource resource-path)))) 21 | 22 | (defn upper-case? [s] 23 | #?(:clj (Character/isUpperCase ^Character s) 24 | :cljs (and (= s (.toUpperCase s)) 25 | (not= s (.toLowerCase s))))) 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dartclojure", 3 | "description": "Opinionated Dart to Clojure converter for Flutter widgets.", 4 | "version": "0.2.23", 5 | "publisher": "liverm0r", 6 | "author": { 7 | "name": "Artur Dumchev", 8 | "email": "arturdumchev@gmail.com" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/Liverm0r/DartClojure" 13 | }, 14 | "license": "Apache License, Version 2.0", 15 | "main": "target/npm-lib/index.js", 16 | "bin": "target/npm-app/index.js", 17 | "scripts": { 18 | "clean": "rimraf target/npm-*", 19 | "watch": "shadow-cljs watch :app :lib :test", 20 | "compile": "shadow-cljs compile :app :lib", 21 | "release": "shadow-cljs release :app :lib", 22 | "prepublish": "npm run clean && npm run release" 23 | }, 24 | "devDependencies": { 25 | "rimraf": "3.0.2", 26 | "shadow-cljs": "^2.19.3" 27 | }, 28 | "dependencies": { 29 | "dartclojure": "^0.2.23" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /project.clj: -------------------------------------------------------------------------------- 1 | (defproject dartclojure "0.2.23-SNAPSHOT" 2 | :license {:name "EPL-2.0" 3 | :url "https://www.eclipse.org/legal/epl-2.0/"} 4 | :dependencies [[org.clojure/clojure "1.10.3"] 5 | [better-cond/better-cond "2.1.4"] 6 | [com.github.clj-easy/graal-build-time "1.0.5"] 7 | [instaparse/instaparse "1.4.12"] 8 | [org.clojure/tools.cli "1.0.206"] 9 | [rewrite-clj/rewrite-clj "1.1.47"] 10 | [zprint/zprint "1.2.7"]] 11 | :main dumch.dartclojure 12 | :source-paths ["src"] 13 | :resource-paths ["resources"] 14 | :profiles {:dev {:dependencies [[org.clojure/test.check "1.1.1"] 15 | [io.github.cognitect-labs/test-runner "0.5.0"] 16 | [org.clojure/clojurescript "1.11.54"] 17 | [thheller/shadow-cljs "2.19.3"] 18 | [olical/cljs-test-runner "3.8.0"]] 19 | :plugins [[slipset/deps-deploy "0.2.1"]] 20 | :main cognitect.test-runner.api/test}}) 21 | -------------------------------------------------------------------------------- /npm-test-app/assets/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 50 | 51 |
52 |

DartClojure NPM test app

53 | 54 |

Dart code here:

55 | 56 | 57 |

Clojure code:

58 |

59 |
60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /src/dumch/convert.cljc: -------------------------------------------------------------------------------- 1 | (ns dumch.convert 2 | (:require [dumch.improve :as improve] 3 | [dumch.parse :as parse] 4 | [instaparse.core :as insta] 5 | [rewrite-clj.zip :as z] 6 | [zprint.core :as zpr])) 7 | 8 | #?(:clj (set! *warn-on-reflection* true)) 9 | 10 | (defn convert 11 | "get dart code, return clojure code 12 | pass keyword arguments, like: (convert code :format :sexpr, :material \"m\") 13 | :material — material alias name, default to \"m\"; 14 | :flutter — alias for ClojureDart helper macro, default to \"f\"; 15 | :format — or of :string (default), :sexpr, :zipper, :node; last 2 about rewrite-clj" 16 | [code & {m :material f :flutter frm :format :or {m "m", f "f"}}] 17 | (let [ast (parse/dart->ast code) 18 | bad? (insta/failure? ast)] 19 | (if bad? 20 | (str "Can't convert the code: " (:text ast)) 21 | (let [rslt (improve/simplify (parse/ast->clj ast) :flutter f :material m)] 22 | (case frm 23 | :zipper rslt 24 | :sexpr (z/sexpr rslt) 25 | :node (z/node rslt) 26 | (-> rslt z/string (zpr/zprint-str {:parse-string? true}))))))) 27 | 28 | (comment 29 | (-> 30 | " 31 | (context, index) { 32 | if (index == 0) { 33 | return const Padding( 34 | padding: EdgeInsets.only(left: 15, top: 16, bottom: 8), 35 | child: Text( 36 | 'Some $field and ${Factory.create()}:', 37 | style: TextStyle( 38 | fontSize: 16, 39 | fontWeight: FontWeight.w500, 40 | ), 41 | ), 42 | ); 43 | } 44 | return const SongPlaceholderTile(); 45 | }; 46 | " 47 | (convert :format :sexpr))) 48 | -------------------------------------------------------------------------------- /deps.edn: -------------------------------------------------------------------------------- 1 | {:paths ["src" "resources"] 2 | :deps {better-cond/better-cond {:mvn/version "2.1.4"} 3 | com.github.clj-easy/graal-build-time {:mvn/version "1.0.5"} 4 | instaparse/instaparse {:mvn/version "1.4.12"} 5 | org.clojure/clojure {:mvn/version "1.10.3"} 6 | org.clojure/tools.cli {:mvn/version "1.0.206"} 7 | rewrite-clj/rewrite-clj {:mvn/version "1.1.47"} 8 | zprint/zprint {:mvn/version "1.2.7"}} 9 | :aliases 10 | {:build 11 | ;; clj -T:build uber :version '"0.2.22"' 12 | {:extra-deps {io.github.clojure/tools.build 13 | {:git/url "https://github.com/clojure/tools.build" 14 | :git/sha "32d497f4f1ad07cb1dfa0855ada9e9cf17abff48"}} 15 | :ns-default build} 16 | :deploy {:extra-deps {slipset/deps-deploy {:mvn/version "0.2.1"}} 17 | :exec-fn deps-deploy.deps-deploy/deploy 18 | :exec-args {:installer :remote 19 | :artifact "dartclojure.jar"}} 20 | :test {:extra-paths ["test"] 21 | :extra-deps {org.clojure/test.check {:mvn/version "1.1.1"} 22 | io.github.cognitect-labs/test-runner 23 | {:git/tag "v0.5.0" :git/sha "48c3c67"}} 24 | :main-opts ["-m" "cognitect.test-runner"] 25 | :exec-fn cognitect.test-runner.api/test} 26 | :test-shadow-cljs {:extra-paths ["test"]} 27 | :cljs {:extra-deps {org.clojure/clojurescript {:mvn/version "1.11.54"}}} 28 | :shadow-cljs 29 | {:extra-deps {thheller/shadow-cljs {:mvn/version "2.19.3"}} 30 | :main-opts ["-m" "shadow.cljs.devtools.cli" "-d" "cider/cider-nrepl:0.28.3"]} 31 | :test-cljs 32 | {:extra-deps 33 | {olical/cljs-test-runner {:mvn/version "3.8.0"}} 34 | :extra-paths ["test"] 35 | :main-opts ["-m" "cljs-test-runner.main"]}}} 36 | -------------------------------------------------------------------------------- /test/dumch/improve_test.cljc: -------------------------------------------------------------------------------- 1 | (ns dumch.improve-test 2 | (:require [clojure.test :refer [deftest is testing]] 3 | [dumch.improve :refer [simplify wrap-nest]] 4 | [dumch.parse :refer [dart->clojure]] 5 | [rewrite-clj.zip :as z] 6 | [rewrite-clj.parser :as p])) 7 | 8 | (def ^:private simplify-clj-str (comp z/sexpr simplify p/parse-string)) 9 | 10 | (deftest nesting-test 11 | (testing "3 nested .child should be replaced with f/nest macro" 12 | (is 13 | (= '(f/widget (Container) (Box) (Padding) (Text "2")) 14 | (-> 15 | "(Container 16 | .child 17 | (Box .child (Padding .child (Text \"2\"))))" 18 | z/of-string 19 | wrap-nest 20 | z/sexpr)))) 21 | 22 | (testing "2- nested .child should be unchanged" 23 | (is 24 | (= '(Box .child (Padding .child (Text "2"))) 25 | (-> "(Box .child (Padding .child (Text \"2\")))" 26 | z/of-string 27 | wrap-nest 28 | z/sexpr))))) 29 | 30 | (deftest redundant-do 31 | (testing "fn with do body" 32 | (is (= '(fn [a] a b) 33 | (simplify-clj-str "(fn [a] (do a b))")))) 34 | (testing "defn with do body" 35 | (is (= '(defn main [a] a b) 36 | (simplify-clj-str "(defn main [a] (do a b))"))))) 37 | 38 | (deftest print-test 39 | (is (= '(fn [a b] (when a a) (dart:core/print 1) (when c c) b) 40 | (simplify-clj-str 41 | "(fn [a b] (do (when a a) (print 1) (when c c) b))")))) 42 | 43 | (deftest material-alias-test 44 | (testing "No alias on core" 45 | (is (= '(Duration .milliseconds 250) 46 | (simplify-clj-str "(Duration .milliseconds 250)")))) 47 | (testing "material alias with slash" 48 | (is (= '(m/MyDuration .milliseconds 250) 49 | (simplify-clj-str "(MyDuration .milliseconds 250)")))) 50 | (testing "material alias with dot" 51 | (is (= '(m.My/Duration .milliseconds 250) 52 | (simplify-clj-str "(My.Duration .milliseconds 250)"))))) 53 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | org.clojars.liverm0r 5 | dartclojure 6 | 0.2.23-SNAPSHOT 7 | dumch/dartclojure 8 | Opinionated Dart->Clojure translater 9 | https://github.com/Liverm0r/dartclojure 10 | 11 | 12 | Apache License, Version 2.0 13 | https://www.apache.org/licenses/LICENSE-2.0 14 | 15 | 16 | 17 | 18 | M1 19 | 20 | 21 | 22 | https://github.com/Liverm0r/dartclojure 23 | scm:git:git://github.com/Liverm0r/dartclojure.git 24 | scm:git:ssh://git@github.com/Liverm0r/dartclojure.git 25 | v0.2.23-SNAPSHOT 26 | 27 | 28 | 29 | org.clojure 30 | clojure 31 | 1.10.3 32 | 33 | 34 | better-cond 35 | better-cond 36 | 2.1.4 37 | 38 | 39 | com.github.clj-easy 40 | graal-build-time 41 | 0.1.4 42 | 43 | 44 | org.clojure 45 | tools.cli 46 | 1.0.206 47 | 48 | 49 | rewrite-clj 50 | rewrite-clj 51 | 1.1.47 52 | 53 | 54 | instaparse 55 | instaparse 56 | 1.4.12 57 | 58 | 59 | zprint 60 | zprint 61 | 1.2.7 62 | 63 | 64 | 65 | src 66 | 67 | 68 | 69 | clojars 70 | https://repo.clojars.org/ 71 | 72 | 73 | 74 | 75 | clojars 76 | Clojars repository 77 | https://clojars.org/repo 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /.github/workflows/build-binaries.yml: -------------------------------------------------------------------------------- 1 | name: GraalVM Native Image builds 2 | on: 3 | push: 4 | tags: 5 | - '*' 6 | 7 | jobs: 8 | create-release: 9 | name: Create release 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Create Release 13 | id: create_release 14 | uses: actions/create-release@v1 15 | env: 16 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 17 | with: 18 | tag_name: ${{ github.ref }} 19 | release_name: ${{ github.ref }} 20 | draft: false 21 | prerelease: false 22 | 23 | build-and-upload: 24 | needs: create-release 25 | name: Build and upload binaries with ${{ matrix.os }} 26 | runs-on: ${{ matrix.os.host }} 27 | strategy: 28 | matrix: 29 | os: 30 | - name: macos-latest 31 | architecture: x86-64 32 | host: macos-latest 33 | 34 | - name: macos-latest 35 | architecture: arm64 36 | host: macos-latest 37 | 38 | - name: openbsd 39 | architecture: arm64 40 | host: ubuntu-latest 41 | 42 | - name: netbsd 43 | architecture: x86-64 44 | host: ubuntu-latest 45 | 46 | steps: 47 | - name: Check for tag 48 | run: | 49 | if [[ "${{ github.ref }}" == refs/tags/* ]]; then 50 | echo "This is a tagged push." 51 | else 52 | echo "This is not a tagged push." 53 | exit 1 54 | fi 55 | 56 | - name: Check OS name 57 | run: | 58 | echo "os name is: ${{ matrix.os.architecture }} ${{ matrix.os.host }} " 59 | 60 | - id: get_version 61 | uses: battila7/get-version-action@v2 62 | 63 | - uses: actions/checkout@v4 64 | 65 | - uses: graalvm/setup-graalvm@v1 66 | with: 67 | java-version: '21' 68 | distribution: 'graalvm' 69 | github-token: ${{ secrets.GITHUB_TOKEN }} 70 | native-image-job-reports: 'true' 71 | 72 | - name: Prepare java 73 | uses: actions/setup-java@v3 74 | with: 75 | distribution: 'temurin' 76 | java-version: '17' 77 | 78 | - name: Install clojure tools 79 | uses: DeLaGuardo/setup-clojure@12.1 80 | with: 81 | cli: 1.11.1.1413 82 | # lein: 2.10.0 83 | 84 | - name: Build jar and native 85 | run: | 86 | clojure -T:build uber :version '"${{ steps.get_version.outputs.version-without-v }}"' 87 | cp target/dartclojure*.jar dartclojure.jar 88 | chmod +x compile.sh 89 | ./compile.sh 90 | mv dartclojure "dartclojure-${{ matrix.os.host }}-${{ matrix.os.architecture }}" 91 | 92 | - name: Attach binaries to release 93 | env: 94 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 95 | run: | 96 | set -x 97 | ls -l 98 | assets=() 99 | assets+=("-a" dartclojure*latest*) 100 | githubref=${{ steps.get_version.outputs.version-without-v }} 101 | hub release edit "${assets[@]}" -m $githubref $githubref 102 | -------------------------------------------------------------------------------- /test/dumch/integration_test.cljc: -------------------------------------------------------------------------------- 1 | (ns dumch.integration-test 2 | (:require #?(:cljs [clojure.edn :refer [read-string]]) 3 | [clojure.test :refer [deftest is testing]] 4 | [dumch.convert :refer [convert]] 5 | [dumch.improve :refer [simplify]] 6 | [dumch.parse :refer [dart->clojure widget-parser]] 7 | [instaparse.core :as insta])) 8 | 9 | (def ^:private code " 10 | AnimatedContainer( 11 | transformAlignment: Alignment.center, 12 | transform: Matrix4.diagonal3Values( 13 | _isOpened ? 0.7 : 1.0, 14 | _isOpened ? 0.7 : 1.0, 15 | 1.0, 16 | ), 17 | duration: const Duration(milliseconds: 250), 18 | curve: const Interval(0.0, 0.5, curve: Curves.easeOut), 19 | child: AnimatedRotation( 20 | turns: _isOpened ? -0.1 : 0, 21 | curve: const Interval(0.25, 1.0, curve: Curves.easeInOut), 22 | duration: const Duration(milliseconds: 250), 23 | child: FloatingActionButton( 24 | onPressed: () => widget.closeHint.value = !widget.closeHint.value, 25 | backgroundColor: _isOpened ? Colors.white : theme.primaryColor, 26 | child: Icon(Icons.add, color: _isOpened ? theme.primaryColor : Colors.white), 27 | ) 28 | ) 29 | ); 30 | ") 31 | 32 | (deftest complex-example-test 33 | (testing "no ambiguity" 34 | (is (= 1 (count (insta/parses widget-parser code))))) 35 | (testing "dart->clojure, using widget macro" 36 | (is 37 | (= 38 | (read-string (convert code)) 39 | '(f/widget 40 | (m/AnimatedContainer 41 | .transformAlignment (.-center m/Alignment) 42 | .transform (.diagonal3Values 43 | m/Matrix4 44 | (if _isOpened 0.7 1.0) 45 | (if _isOpened 0.7 1.0) 46 | 1.0) 47 | .duration (Duration .milliseconds 250) 48 | .curve (m/Interval 0.0 0.5 .curve (.-easeOut m/Curves))) 49 | (m/AnimatedRotation 50 | .turns (if _isOpened -0.1 0) 51 | .curve (m/Interval 0.25 1.0 .curve (.-easeInOut m/Curves)) 52 | .duration (Duration .milliseconds 250)) 53 | (m/FloatingActionButton 54 | .onPressed 55 | (fn [] :unidiomatic) 56 | .backgroundColor 57 | (if _isOpened (.-white m/Colors) (.-primaryColor theme))) 58 | (m/Icon 59 | (.-add m/Icons) 60 | .color (if _isOpened (.-primaryColor theme) (.-white m/Colors)))))))) 61 | 62 | (def code2 " 63 | Column( 64 | children: [ 65 | Question( 66 | questions[_questionIndex]['questionText'], 67 | ), 68 | (questions[_questionIndex]['answers'] as List) 69 | .map((answer) { 70 | return Answer(_answerQuestion, answer); 71 | }).toList(), 72 | Numb(sorted: (1 < 2 && 2 < 3 && 3 < a) && (a == b)), 73 | ], 74 | ), 75 | ") 76 | 77 | (deftest complex-example-test2 78 | (testing "no ambiguity" 79 | (is (= 1 (count (insta/parses widget-parser code2))))) 80 | (testing "Complex example with list, lambda, map, compare, named arg" 81 | (is 82 | (= 83 | (-> code2 convert read-string) 84 | '(m/Column 85 | .children 86 | [(m/Question (get (get questions _questionIndex) "questionText")) 87 | (-> 88 | (get (get questions _questionIndex) "answers") 89 | (.map (fn [answer] (m/Answer _answerQuestion answer))) 90 | .toList) 91 | (m/Numb .sorted (and (= a b) (< 1 2 3 a)))]))))) 92 | -------------------------------------------------------------------------------- /src/dumch/dartclojure.cljc: -------------------------------------------------------------------------------- 1 | (ns dumch.dartclojure 2 | (:require #?(:cljs ["readline" :as node-rl]) 3 | #?(:cljs [clojure.edn :refer [read-string]]) 4 | #?(:cljs ["fs" :as node-fs]) 5 | [clojure.pprint :refer [pprint]] 6 | [clojure.tools.cli :refer [parse-opts]] 7 | [clojure.string :as str] 8 | [dumch.convert :refer [convert]] 9 | [zprint.core :as zpr]) 10 | #?(:clj (:gen-class))) 11 | 12 | #?(:clj (set! *warn-on-reflection* true)) 13 | 14 | (def cli-options 15 | [["-r" "--repl REPL" "Mode: repl or single command, single by default" 16 | :default false 17 | :parse-fn #?(:clj #(Boolean/parseBoolean %) 18 | :cljs read-string) 19 | :validate [boolean? "Must be either true or false"]] 20 | ["-e" "--end TEXT" "Mode: text or symbol to show the end of code" 21 | :default "" 22 | :parse-fn str] 23 | ["-m" "--material MATERIAL" "material require alias, any string" 24 | :default "m" 25 | :parse-fn str 26 | :validate [#(re-matches #"^[A-Za-z][A-Za-z0-9]*$" %) 27 | "invalid require-alias for material"]] 28 | ["-f" "--flutter FLUTTER_MACRO_PACKAGE" "flutter-macro require alias, any string" 29 | :default "f" 30 | :parse-fn str 31 | :validate [#(re-matches #"^[A-Za-z][A-Za-z0-9]*$" %) 32 | "invalid require alias for flutter-materail"]] 33 | ["-c" "--colors BOOLEAN" "colorize output" 34 | :default false 35 | :parse-fn #?(:clj #(Boolean/parseBoolean %) 36 | :cljs read-string) 37 | :validate [boolean? "Must be either true or false"]] 38 | ["-p" "--path PATH TO FILE, OR URL" "url or path to dart file to translate" 39 | :parse-fn str] 40 | ["-h" "--help"]]) 41 | 42 | (defn show! [data & {:keys [colors] :or {colors false}}] 43 | (if colors 44 | (zpr/czprint data {:parse-string? true}) 45 | (println data))) 46 | 47 | (defn- print-repl-instructions [end] 48 | (println (str "Paste dart code below, press enter" 49 | (when (seq end) (str ", write '" end "',")) 50 | " and see the result:\n"))) 51 | 52 | #?(:clj 53 | (defn- stdin-loop! [& {:keys [material flutter end colors]}] 54 | (print-repl-instructions end) 55 | (loop [input (read-line) 56 | acc []] 57 | (if (= input end) 58 | (do 59 | (try 60 | (-> (convert (str/join "\n" acc) 61 | :material material 62 | :flutter flutter) 63 | (show! :colors colors)) 64 | (catch Exception e (println "Can't convert the code; e " e))) 65 | (println) 66 | (recur (read-line) [])) 67 | (recur (read-line) (conj acc input)))))) 68 | 69 | #?(:cljs 70 | ;; This could have been a lambda, but then we can't update it via the REPL 71 | (defn- process-node-repl-input! [input !code {:keys [material flutter end colors]}] 72 | (if (= input end) 73 | (do 74 | (try 75 | (-> (convert (str/join "\n" @!code) 76 | :material material 77 | :flutter flutter) 78 | (show! :colors colors)) 79 | (catch js/Error e (println "Can't convert the code; e " e))) 80 | (println) 81 | (reset! !code [])) 82 | (swap! !code conj input)))) 83 | 84 | #?(:cljs 85 | (defn- node-repl! [& {:keys [end] :as params}] 86 | (print-repl-instructions end) 87 | (let [!code (atom [])] 88 | (-> (.createInterface node-rl #js {:input js/process.stdin 89 | :output js/process.stdout 90 | :terminal false}) 91 | (.on "line" (fn [input] 92 | (process-node-repl-input! input !code params))))))) 93 | 94 | (defn -main [& args] 95 | (let [{{:keys [repl help path] :as params} :options, 96 | errors :errors, 97 | args :arguments :as m} 98 | (parse-opts args cli-options) 99 | params (mapcat identity params)] 100 | (cond 101 | help (println "here is the arguments\n" m) 102 | errors (println errors) 103 | repl #?(:clj (apply stdin-loop! params) 104 | :cljs (apply node-repl! params)) 105 | path (when-let [code (#?(:clj slurp 106 | :cljs #(node-fs/readFileSync % #js {:encoding "utf-8" :flag "r"})) path)] 107 | (apply show! 108 | (apply convert code params) 109 | params)) 110 | :else (if args 111 | (apply show! 112 | (apply convert (first args) params) 113 | params) 114 | (println "no arguments passed"))))) 115 | 116 | #?(:cljs 117 | (def node-main #'-main)) 118 | 119 | #?(:cljs 120 | (defn shadow-cljs-reload [] 121 | (println "shadow-cljs reloaded the code"))) 122 | -------------------------------------------------------------------------------- /src/dumch/improve.cljc: -------------------------------------------------------------------------------- 1 | (ns dumch.improve 2 | (:require 3 | [better-cond.core :as b] 4 | [clojure.string :as str] 5 | [dumch.util :refer [lists* upper-case?]] 6 | [rewrite-clj.node :as n] 7 | [rewrite-clj.paredit :as p] 8 | [rewrite-clj.zip :as z])) 9 | 10 | (defn- remove-child-named-arg [zloc] 11 | (-> zloc z/down (z/find-value z/right '.child) z/right z/remove z/remove* z/up)) 12 | 13 | (defn- nested-children? [zloc times] 14 | (let [zloc (-> zloc z/down (z/find-value z/right '.child))] 15 | (cond 16 | (not= '.child (z/sexpr zloc)) false 17 | (= 1 times) true 18 | :else (recur (-> zloc z/next) (dec times))))) 19 | 20 | (defn- nest-flatten [zloc & {fl :flutter :or {fl "f"}}] 21 | (loop [zloc zloc 22 | rslt []] 23 | (if-let [child (-> zloc z/down (z/find-value z/right '.child))] 24 | (recur (-> child z/right) (conj rslt (remove-child-named-arg zloc))) 25 | (z/of-node 26 | (n/list-node (lists* (n/token-node (symbol (str (when fl (str fl "/")) "widget"))) 27 | (map z/node (conj rslt zloc)))))))) 28 | 29 | (defn wrap-nest [zloc & {fl :flutter :or {fl "f"}}] 30 | (z/prewalk zloc 31 | #(and (z/list? %) (nested-children? % 3)) 32 | #(nest-flatten % :flutter fl))) 33 | 34 | (b/defnc- try-remove-redundant-do [zloc] 35 | :when-let [fn-node (-> zloc z/down)] 36 | :let [fn? (= (z/sexpr fn-node) 'fn) 37 | defn? (= (z/sexpr fn-node) 'defn)] 38 | 39 | :when-let [_ (or fn? defn?) 40 | fn-node (if defn? (z/right fn-node) fn-node) 41 | do-zloc (-> fn-node z/right z/right z/down)] 42 | 43 | (= (z/sexpr do-zloc) 'do) 44 | (-> do-zloc z/remove z/splice z/up)) 45 | 46 | (def ^:private core-vars 47 | #{'AbstractClassInstantiationError 'ArgumentError 'AssertionError 'BidirectionalIterator 48 | 'BigIntbool 'CastError 'Comparable 'Comparator 'ConcurrentModificationError 49 | 'CyclicInitializationError 'DateTime 'double 'Duration 'Error 'Exception 'Expando 50 | 'FallThroughError 'Finalizer 'FormatException 'Function 'IndexError 'IntegerDivisionByZeroException 51 | 'Invocation 'Iterable 'Iterator 'List 'Map 'MapEntry 'Match 'NoSuchMethodError 'Null 'NullThrownError 52 | 'Object 'OutOfMemoryError 'Pattern 'pragma 'RangeError 'RegExp 'RegExpMatch 'Runes 'RuneIterator 'Set 53 | 'Sink 'StackOverflowError 'StackTrace 'StateError 'Stopwatch 'String 'StringBuffer 'StringSink 54 | 'Symbol 'Type 'TypeError 'UnimplementedError 'UnsupportedError 'Uri 'WeakReference}) 55 | 56 | (b/defnc- insert-alias [symb m] 57 | :let [s (str symb)] 58 | (not (str/includes? s ".")) (symbol (str m "/" symb)) 59 | 60 | :let [parts (cons m (str/split s #"\."))] 61 | (symbol (str (str/join "." (butlast parts)) "/" (last parts)))) 62 | 63 | (defn simplify [node & {fl :flutter, m :material :or {fl "f", m "m"}}] 64 | (-> node 65 | z/of-node 66 | (z/postwalk 67 | (fn [zloc] 68 | (b/cond 69 | (and (z/list? zloc) (nested-children? zloc 3)) 70 | (nest-flatten zloc :flutter fl) 71 | 72 | :let [undo-node (try-remove-redundant-do zloc)] 73 | undo-node undo-node 74 | 75 | :let [expr (z/sexpr zloc)] 76 | (= expr 'print) (z/edit zloc #(symbol (str "dart:core/" %))) 77 | 78 | ;; require alias 79 | (and (symbol? expr) 80 | (upper-case? (first (str expr))) 81 | (not (core-vars expr))) 82 | (z/edit zloc #(insert-alias % m)) 83 | 84 | :else zloc))))) 85 | 86 | #_(-> "(Duration 39)" 87 | rewrite-clj.parser/parse-string 88 | simplify 89 | z/sexpr) 90 | 91 | (comment 92 | (def nested "(Container 93 | .child 94 | (Box .child (Padding .child (Text 1)) .a 1))") 95 | 96 | (-> nested z/of-string (nested-children? 3)) 97 | 98 | (-> nested z/of-string 99 | z/down 100 | (z/find-value '.child) 101 | z/right 102 | p/raise 103 | z/up 104 | z/string 105 | ) 106 | 107 | (def animation "(Column 108 | .children 109 | [(Text \"name\") 110 | (Icon m.Icons/widgets) 111 | (IgnorePointer. 112 | .ignoring (boolean @open) 113 | .child 114 | (AnimatedContainer. 115 | .transformAlignment m.Alignment/center 116 | .transform (m.Matrix4/diagonal3Values 117 | (if @open 0.7 1.0) 118 | (if @open 0.7 1.0) 119 | 1.0) 120 | .duration ^:const (Duration. .milliseconds 250) 121 | .curve ^:const (Interval. 0.0 0.5 .curve m.Curves/easeOut) 122 | .child 123 | (AnimatedOpacity. 124 | .opacity (if @open 0.0 (+ (+ 2.0 1.0) (+ -3.0) 1.0)) 125 | .curve ^:const (Interval. 0.25 1.0 .curve m.Curves/easeInOut) 126 | .duration ^:const (Duration. .milliseconds 250) 127 | .child 128 | (FloatingActionButton. 129 | .onPressed toggle 130 | .child 131 | (Icon. m.Icons/create)))))]) 132 | ") 133 | 134 | (z/sexpr (wrap-nest (z/of-string animation)))) 135 | -------------------------------------------------------------------------------- /resources/widget-parser.bnf: -------------------------------------------------------------------------------- 1 | s = file / code 2 | code = (expr )* 3 | 4 | metadata = ('@' qualified params? <';'>?)+ 5 | file = import-block? 6 | ( 7 | (method | var-declare <';'> | class | _typedef | for-in | 8 | _for | _while | _do-while | switch | try | enum | return))* 9 | = <'static'?> ? identifier lambda-args 10 | = (block | <'=>'> assign-val) <';'*> 11 | method = method-decl method-body 12 | 13 | import-block = (import <';'?>)+ 14 | = (import-full | import-as | import-hide | import-show | import-naked) 15 | import-naked = im-body 16 | import-full = im-body im-as-part (im-show-part | im-hide-part) 17 | import-as = im-body im-as-part 18 | import-show = im-body im-show-part 19 | import-hide = im-body im-hide-part 20 | = <'import'> string 21 | = (<'deferred'?> <'as'> identifier) 22 | = <'show'> identifier+ 23 | = <'hide'> identifier+ 24 | 25 | class = <'abstract'? 'class' #'[^{}]*' '{'> 26 | ( (method | method-decl <';'> | getter-decl | 27 | var-declare <';'> | ))* 28 | <'}'> 29 | construct-decl = 'const'? identifier ('.' identifier)? 30 | '(' ( 31 | (typed-arg '.')* typed-arg? 32 | (<','> (typed-arg '.')* typed-arg)* 33 | )? 34 | <','>? args-bloc? 35 | ')' 36 | ( (':' 'super' params)? ';' | ':' (identifier '=' expr (','|';'))* ) 37 | args-bloc = '{' #'[^{}]*' '}' 38 | _typedef = 'typedef' dtype <'='> (dtype | method) 39 | getter-decl = 'get' 40 | identifier (block | <'=>'> assign-val | <';'>) <';'*> 41 | 42 | enum = <'enum'> identifier 43 | <'{'> enum-entry (<','> enum-entry)* <','>? <'}'> 44 | enum-entry = identifier 45 | 46 | = <(';'|#'\n'+|','|#'$')> 47 | = var-declare | _for | for-in | _while | _do-while | switch | try 48 | return = <'return'> expr? <';'> 49 | 50 | if = <'if'> if-condition if-else-body 51 | = (block | return | expr ) 52 | ( (<'else'> | <'else if'> if-condition) if-else-body)* 53 | = <'('> expr <')'> 54 | 55 | var-declare = <'static'>? field-type var-init (<','> var-init)* 56 | var-init = identifier (<'='> expr)? 57 | 58 | for-in = <'for'> <'('> identifier <'in'> expr <')'> for-body 59 | _for = <'for'> <'('> for-init expr? <';'> expr-list? <')'> for-body 60 | for-init = var-declare <';'> EPSILON | expr? <';'> 61 | = (block | return | expr | statement) 62 | _while = <'while'> <'('> expr <')'> for-body 63 | _do-while = <'do'> for-body 'while' <'('> expr <')'> <';'> 64 | 65 | switch = <'switch'> <'('> expr <')'> <'{'> switch-case* default-case? <'}'> 66 | switch-case = (identifier <':'>)* cases for-body switch-exit? 67 | cases = (<'case'> expr <':'>)+ 68 | default-case = (identifier <':'>)* <'default'> <':'> for-body switch-exit? 69 | switch-exit = ('break' | 'continue' | 'continue' identifier) <';'> 70 | 71 | try = <'try'> block (try-on+ finally? | finally) 72 | try-on = on-part catch block 73 | on-part = <'on'> dtype | EPSILON 74 | catch = <'catch'> <'('> identifier (<','> identifier)? <')'> | EPSILON 75 | finally = <'finally'> block 76 | 77 | lambda-args = <'('> typed-arg? (<','> typed-arg)* <')'> <'async'?> 78 | = identifier 79 | block = <'{'> ( statement <';'> | expr | method )* return? <'}'> 80 | 81 | expr-list = expr (',' expr)* 82 | = lambda-val <'!'>? 83 | 84 | = await-val | lambda 85 | lambda = lambda-args block | lambda-args <'=>'> await-val 86 | = cascade-val | await 87 | await = <'await'> await-val 88 | = assign-val | cascade 89 | cascade = cascade-val <'..'> assign-val 90 | = ternary-val | _set 91 | _set = dot-val <_operator> ternary-val 92 | = ifnull-val | ternary 93 | ternary = ternary-val <'?'> expr <':'> expr 94 | = and-val | ifnull 95 | ifnull = ifnull-val '??' and-val 96 | = or-val | and 97 | and = and-val <'&&'> or-val 98 | = equality-val | or 99 | or = or-val <'||'> equality-val 100 | = compare-val | equality 101 | equality = equality-val ( '==' | '!=' ) compare-val 102 | = add-sub-val | compare 103 | compare = compare-val !type-args ( '<' | '>' | '<=' | '>=' | 'is') add-sub-val 104 | = mul-div-val | add | sub 105 | add = add-sub-val <'+'> mul-div-val 106 | sub = add-sub-val <'-'> mul-div-val 107 | = dot-val | mul | div 108 | mul = mul-div-val <'*'> dot-val 109 | div = mul-div-val ('/' | '%' | '~/') dot-val 110 | = term | dot | dot-op 111 | dot-op = dot-val <'?'> (invoke | field) 112 | dot = dot-val (invoke | field) 113 | = value | <'('> ternary-val <')'> 114 | 115 | = (number | string | !get identifier 116 | | constructor | invoke | typecasting | const 117 | | list | map | get | _spread | if 118 | | inc | _inc | dec | _dec | identifier | number 119 | | _tilda | neg | not) <';'?> 120 | 121 | typecasting = value 'as' dtype 122 | 123 | invoke = <'.'> typed-value params <';'?> 124 | field = <'.'> identifier <';'?> 125 | neg = !number <'-'> value 126 | not = <'!'> value 127 | dec = <'--'> value 128 | inc = <'++'> value 129 | _dec = value <'--'> 130 | _inc = value <'++'> 131 | _tilda = <'~'> value 132 | 133 | const = <'const'> (constructor | get | map | list | dot | dot-op) 134 | constructor = typed-value params <';'?> 135 | = identifier 136 | params = <'('> <')'> 137 | | (<'('> argument (<','> argument)* <','?> <')'>) 138 | argument = expr | (named-arg expr) 139 | named-arg = identifier <':'> 140 | 141 | list = 142 | <'['> (list-el (<','> list-el)* <','?> | EPSILON ) <']'> 143 | = _spread | expr 144 | _spread = '...' value 145 | map = 146 | <'{'> (expr <':'> expr 147 | (<','> (identifier|string|number) <':'> expr)* <','>? 148 | | EPSILON ) <'}'> 149 | get = (get | identifier | map | dot | dot-op) 150 | <'['> (identifier | string | number | dot | dot-op) <']'> 151 | 152 | _operator = '=' | '*=' | '/=' | '~/=' | '%=' | '+=' | '<<=' | '>>=' 153 | | '>>>=' | '&=' | '^=' | '|=' | '??=' | '-=' 154 | 155 | (* type without name *) 156 | = !'await' (modifier | !modifier | modifier) 157 | = 'final' | 'const' 158 | = qualified type-args? <'?'?> 159 | qualified = (identifier <'.'>)* identifier 160 | type-args = <'<'> type-list <'>'> 161 | type-list = dtype (',' dtype)* 162 | 163 | string = #'r?\'([^\']*)\'' 164 | identifier = !return #'[a-zA-Z_]+[a-zA-Z0-9!_]*' 165 | number = #'[+-]?[0-9]+(\.[0-9]+)?((e|E)[+-]?[0-9]+)?' | #'0x[0-9a-fA-F]+' 166 | 167 | = #'[0-9]' 168 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DartClojure 2 | 3 | [![Clojars Project](https://img.shields.io/clojars/v/org.clojars.liverm0r/dartclojure.svg)](https://clojars.org/org.clojars.liverm0r/dartclojure) 4 | 5 | Opinionated Dart to Clojure converter for Flutter widgets. 6 | It doesn't (and probably will not) convert classes, setters, or annotations—only the parts that can be reused after translation. 7 | 8 | alt text 9 | 10 | ## How to use 11 | 12 | There are 9 options now: 13 | 1. [Calva (VSCode);](https://github.com/d00mch/DartClojure/#api-from-calva) 14 | 2. [Intellij Idea;](https://github.com/d00mch/DartClojure/#api-from-intellij-idea) 15 | 3. [Jvm/Js REPL;](https://github.com/d00mch/DartClojure/#api-from-jvmjs-repl) 16 | 4. [Clojure Cli;](https://github.com/d00mch/DartClojure/#api-from-cli) 17 | 5. [Jar;](https://github.com/d00mch/DartClojure/#api-with-jar) 18 | 6. [Native image;](https://github.com/d00mch/DartClojure/#api-with-native-image) 19 | 7. [Native image, Emacs;](https://github.com/D00mch/DartClojure#api-with-native-image-via-emacs) 20 | 8. [NPM CLI;](https://github.com/d00mch/DartClojure/#api-with-npm-cli) 21 | 9. [NPM library;](https://github.com/d00mch/DartClojure/#api-with-npm-library) 22 | 23 | ## Why is it not a full dart->clojure converter? 24 | 25 | The converted code would not be idiomatic. Instead of using 26 | classes, there is a [widget][1] macro. 27 | 28 | Setters are also useless; there would be a `:state` atom 29 | and `swap!` or `reset!` functions for changing the state. 30 | 31 | So I see little value in converting everything. 32 | 33 | But rewriting widgets is routine and most of the time translates literally: 34 | 35 | ```dart 36 | Center( 37 | child: Text( 38 | _active ? 'Active' : 'Inactive', 39 | style: const TextStyle(fontSize: 32.0, color: Colors.white), 40 | ), 41 | ); 42 | ``` 43 | 44 | ```clojure 45 | (m/Center 46 | .child (m/Text 47 | (if _active "Active" "Inactive") 48 | .style (m/TextStyle .fontSize 32.0 .color m.Colors/white))) 49 | ``` 50 | 51 | Three more examples: 52 | 53 | ![Screen Recording](https://user-images.githubusercontent.com/14236531/170881526-82983262-fd41-45e4-a90d-270859431890.gif) 54 | 55 | 56 | ## Supported 57 | 58 | - constructor invocation; 59 | - static, factory methods invocation; 60 | - named arguments; 61 | - (typed) lists, maps, cascade operator (`..`); 62 | - math and logical expressions; 63 | - ternary operators; 64 | - lambdas; 65 | - comments (will be removed); 66 | - nesting children with the f/nest macro; 67 | - constants; 68 | - variables in strings with $; 69 | - raw (interpreted) strings like `r'some string $dollar'` 70 | - class/methods/fields declarations (not tested well, pre-alpha); 71 | - try-catch; 72 | - for in; 73 | - switch with breaks and returns; 74 | 75 | ## Not supported 76 | 77 | - bitwise operators; 78 | - proper aliases for everything, it's not possible to get this info generally; 79 | - enums; 80 | - external keyword; 81 | - yield; 82 | - exports; 83 | - switch with continue, without breaks or returns (considered unidiomatic); 84 | - for with declaration, condition and increment (considered unidiomatic) 85 | - while (considered unidiomatic) 86 | - early exits from lambdas (ignored); 87 | - `...` operator (ignored); 88 | - typedefs (ignored); 89 | - annotations (ignored); 90 | 91 | ## TODO: 92 | 93 | - [ ] test classes and methods extensively; 94 | - [ ] handle early exit from lambdas/if/for/methods with `return`; 95 | 96 | 97 | ## How to use 98 | 99 | ### API from Calva 100 | 101 | [Calva][6] (a VSCode Clojure extension) packs DartClojure conversion into a command. This makes it easy to paste some Dart code and convert it. 102 | 103 | 104 | 105 | See [Calva ClojureDart docs][5] for a little more on the subject. 106 | 107 | ### API from IntelliJ IDEA 108 | 109 | You can use the available [api](https://github.com/d00mch/DartClojure/#how-to-use) (4, 5, 6, 7) directly from IDEA with [External Tools][3]. 110 | 111 | Preferences —> Tools —> External Tools —> + 112 | 113 | `Program`: any terminal command. For example, if you have npm, install 114 | dartclojure globally and put `dartclojure` in the `Program` field. If you 115 | downloaded the native image, put the path to the native image here: 116 | `/Users/PcName/Downloads/dartclojure-aarch64-darwin` 117 | 118 | `Arguments`: `"$SelectedText$"` 119 | 120 | ![image](https://user-images.githubusercontent.com/14236531/175103257-cd2894ab-e20d-4990-9469-c4280ac228ed.png) 121 | 122 | That's it. Select code, press `Shift + Shift` (or `Cmd + Shift + A`), type `DartClojure` and press Enter (or set up a hotkey for it). Here's a little [video][7] showing how it looks. 123 | 124 | ### API from JVM/JS REPL 125 | 126 | [Clojars][2]. 127 | 128 | Add CLI/deps: 129 | ```clojure 130 | {:deps 131 | { 132 | org.clojars.liverm0r/dartclojure {:mvn/version "0.2.23-SNAPSHOT"} 133 | }} 134 | ``` 135 | 136 | Or Leiningen/Boot: 137 | ```clojure 138 | [org.clojars.liverm0r/dartclojure "0.2.23-SNAPSHOT"] 139 | ``` 140 | 141 | Convert Dart code (simplify and wrap-nest under the hood): 142 | ```clojure 143 | (require '[dumch.convert :refer [convert]]) 144 | 145 | (convert "1 + 1 + 2 * 1;" :format :sexpr) ; => (+ 1 1 (* 2 1)) 146 | ``` 147 | 148 | You may pass aliases for material and flutter-macro: 149 | ```clojure 150 | (convert "Text('1')" :material "m" :flutter "f") ; => "(m/Text "1")" 151 | ``` 152 | 153 | If you just need to wrap Clojure code with nest: 154 | ```clojure 155 | (require 156 | '[dumch.improve :as impr] 157 | '[rewrite-clj.zip :as z]) 158 | 159 | (-> "(Container .child (Box .child (Padding .child (:Text \"2\"))))" 160 | z/of-string 161 | impr/wrap-nest 162 | z/sexpr) 163 | ; => (f/nest (Container) (Box) (Padding) (:Text "2")) 164 | ``` 165 | 166 | ### API from CLI 167 | 168 | ```bash 169 | clojure -Sdeps \ 170 | '{:deps {org.clojars.liverm0r/dartclojure {:mvn/version "0.2.23-SNAPSHOT"}}}' \ 171 | -e "(require '[dumch.convert :refer [convert]]) (convert \"Text('1')\" :material \"m\" :flutter \"f\")" 172 | ``` 173 | 174 | ### API with Jar 175 | 176 | There are two ways to interact with the [jar][4]. The first is to run it each time: 177 | 178 | ``` 179 | $ java -jar dartclojure.jar "Divider( 180 | height: 0, 181 | color: Colors.grey, 182 | )" 183 | 184 | (m/Divider .height 0 .color m.Colors/grey) 185 | ``` 186 | 187 | The second is to run REPL-like console (and send code into it with your editor/IDE): 188 | ``` 189 | $ java -jar dartclojure.jar -r true -m "material" 190 | Paste dart code below, press Enter and see the result: 191 | 192 | Divider( 193 | height: 0, 194 | color: Colors.grey, 195 | ) 196 | 197 | (material/Divider .height 0 .color material.Colors/grey) 198 | ``` 199 | 200 | Colors are also supported: 201 | 202 | ![image](https://user-images.githubusercontent.com/14236531/172026319-0f770f8c-5a33-4703-91d0-37cbd3772700.png) 203 | 204 | For example, you may start the REPL-like console app with `-e` key: 205 | ``` 206 | $ java -jar dartclojure.jar -r true -e :end 207 | ``` 208 | 209 | For all the arguments, see: 210 | ```bash 211 | $ java -jar dartclojure.jar -h 212 | ``` 213 | 214 | ### API with native image: 215 | 216 | Same API as with the jar: 217 | 218 | ./dartclojure -h 219 | 220 | ./dartclojure "Text('a')" -m "m" 221 | 222 | ./dartclojure --path main.dart 223 | 224 | ./dartclojure -r true 225 | 226 | If there is no build for your architecture on [release page][4], 227 | see how to build it with graalvm below. 228 | 229 | ### API with native image via Emacs 230 | 231 | You can use the Emacs package from [dartclojure.el](https://github.com/burinc/dartclojure.el) via your favorite Emacs package manager. 232 | 233 | ### API with npm CLI 234 | 235 | Same API as with the jar and native image: 236 | 237 | ```sh 238 | npm i dartclojure 239 | 240 | npx dartclojure -h 241 | 242 | npx dartclojure "Text('a')" -m "m" 243 | ``` 244 | 245 | You can, of course, also install it globally: 246 | 247 | ```sh 248 | npm i -g dartclojure 249 | 250 | dartclojure -h 251 | 252 | dartclojure "Text('a')" -m "m" 253 | ``` 254 | 255 | ### API with npm library 256 | 257 | ```js 258 | const converter = require('dartclojure'); 259 | 260 | const clojureCode = converter.convert("Text('a')"); 261 | ``` 262 | 263 | ## Contribution 264 | 265 | Build the jar: 266 | 267 | $ clj -T:build uber :version '"0.2.22"' 268 | 269 | Run tests: 270 | 271 | $ clj -X:test ; clj -M:test-cljs 272 | 273 | Run Docker, build the GraalVM image: 274 | 275 | $ cp target/dartclojure*.jar dartclojure.jar 276 | $ docker build --pull --no-cache --tag dartclojure . 277 | $ docker run --name dc -it dartclojure ./dartclojure "Text('should work')" 278 | $ docker cp dc:/usr/src/app/dartclojure. 279 | 280 | Compile a native image with GraalVM locally: 281 | 282 | # install graalvm 283 | $ chmod +x compile.sh 284 | $ ./compile.sh 285 | 286 | Remember to comment out the line with `-H:+StaticExecutableWithDynamicLibC` for OSX M1 287 | builds. 288 | 289 | Start the shadow-cljs watcher and REPL: 290 | 291 | ``` 292 | clj -M:shadow-cljs watch :app :lib :test 293 | ``` 294 | 295 | (You can use this for developing both the Clojure and ClojureScript library, but the test watcher will only be watching and running the ClojureScript tests.) 296 | 297 | Install the local npm package: 298 | 299 | ``` 300 | npm link dartclojure 301 | ``` 302 | 303 | ## License 304 | 305 | Copyright © 2022 Artur Dumchev 306 | 307 | Licensed under the Apache License, Version 2.0 (the "License"); 308 | you may not use this file except in compliance with the License. 309 | You may obtain a copy of the License at 310 | 311 | http://www.apache.org/licenses/LICENSE-2.0 312 | 313 | Unless required by applicable law or agreed to in writing, software 314 | distributed under the License is distributed on an "AS IS" BASIS, 315 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 316 | See the License for the specific language governing permissions and 317 | limitations under the License. 318 | 319 | [1]: https://github.com/Tensegritics/ClojureDart/blob/main/doc/flutter-helpers.md#widget-macro 320 | [2]: https://clojars.org/org.clojars.liverm0r/dartclojure/versions/0.2.23-SNAPSHOT 321 | [3]: https://www.jetbrains.com/help/idea/configuring-third-party-tools.html 322 | [4]: https://github.com/d00mch/DartClojure/releases/tag/0.2.23 323 | [5]: https://calva.io/clojuredart/ 324 | [6]: https://marketplace.visualstudio.com/items?itemName=betterthantomorrow.calva 325 | [7]: https://www.reddit.com/r/Clojure/comments/vib5ie/how_to_translate_dart_to_clojuredart_inside/ 326 | -------------------------------------------------------------------------------- /src/dumch/parse.cljc: -------------------------------------------------------------------------------- 1 | (ns dumch.parse 2 | (:require 3 | #?(:clj [clojure.java.io :as io]) 4 | #?(:cljs [clojure.edn :refer [read-string]]) 5 | [clojure.string :as str] 6 | [clojure.set :as set] 7 | #?(:cljs [dumch.base64 :as b64-cljs]) 8 | [dumch.util :refer [ws nl maps mapn mapcats mapcatn]] 9 | #?(:cljs [dumch.util :refer-macros [inline-resource]]) 10 | #?(:clj [instaparse.core :as insta :refer [defparser]] 11 | :cljs [instaparse.core :as insta :refer-macros [defparser]]) 12 | [rewrite-clj.node :as n 13 | :refer [list-node map-node token-node keyword-node vector-node] 14 | :rename {list-node lnode, vector-node vnode, map-node mnode, 15 | token-node tnode, keyword-node knode}] 16 | #_[clj-java-decompiler.core :refer [decompile]] 17 | #_[criterium.core :refer [quick-bench]]) 18 | #?(:clj 19 | (:import java.util.Base64))) 20 | 21 | #?(:clj (set! *warn-on-reflection* true)) 22 | 23 | (defparser widget-parser 24 | #?(:clj (io/resource "widget-parser.bnf") 25 | :cljs (inline-resource "widget-parser.bnf")) 26 | :auto-whitespace :standard) 27 | 28 | (defn- dart-op->clj-op [o] 29 | (case o 30 | "is" 'dart/is? 31 | "??" 'or 32 | "==" '= 33 | "!=" 'not= 34 | "%" 'rem 35 | "~/" 'quot 36 | (symbol o))) 37 | 38 | (defn- substitute-curly-quotes [s & {f :backward}] 39 | ;; crutch for cases like ''' ' ''' and '\'' 40 | (if f 41 | (-> (str/replace s #"”" "\"") 42 | (str/replace #"’" "'")) 43 | (-> (str/replace s #"\"" "”") 44 | (str/replace #"'" "’")))) 45 | 46 | (defn- split-by-$-expr [s] 47 | ;; two reasons for it to be that complex: 48 | ;; - can't make regex for nested {{}} work in jvm: (?=\{((?:[^{}]++|\{(?1)\})++)\}) 49 | ;; - regex is slow anyway; 50 | (loop [stack [] ;; to count balanced curly: '{', '}' 51 | rslt [] 52 | cur-str [] 53 | cur-expr [] 54 | i 0] 55 | (if (>= i (count s)) 56 | (conj rslt (apply str (if (empty? cur-expr) cur-str cur-expr))) 57 | 58 | (let [ch (.charAt ^String s i) 59 | building-str? (empty? stack) 60 | allow-open-b? (and (> i 0) (= (.charAt ^String s (dec i)) \$)) 61 | open-b? (and (or allow-open-b? (seq stack)) (= ch \{)) 62 | close-b? (= ch \}) 63 | expr-ends? (and close-b? (= (count stack) 1))] 64 | 65 | (if building-str? 66 | (recur 67 | (if open-b? (conj stack 1) stack) 68 | (if open-b? 69 | (conj rslt (subs (apply str cur-str) 0 (dec (count cur-str)))) 70 | rslt) 71 | (if open-b? [] (conj cur-str ch)) 72 | cur-expr 73 | (inc i)) 74 | 75 | (recur 76 | (cond open-b? (conj stack 1) 77 | close-b? (pop stack) 78 | :else stack) 79 | (if expr-ends? (conj rslt (apply str cur-expr)) rslt) 80 | cur-str 81 | (if expr-ends? [] (conj cur-expr ch)) 82 | (inc i))))))) 83 | 84 | (defn- substitute-$ 85 | "Returns string AST with $ substitutions" 86 | [^:String s] 87 | (let [p #"\$[a-zA-Z_]+[a-zA-Z0-9!_]*" 88 | s (str/replace s p (fn [m] (str "${" (subs m 1) "}"))) 89 | sq (split-by-$-expr s)] 90 | (if (= (count sq) 1) 91 | [:string+ s] 92 | [:strings+ (->> sq 93 | (map-indexed #(if (zero? (mod (inc %1) 2)) 94 | (widget-parser %2) 95 | (when (seq %2) [:string+ %2]))) 96 | (filter some?))]))) 97 | 98 | (defn- node->string-ast 99 | "Returns ast, handling $, de-`substitute-curly-quotes`, commas and r (raw str)" 100 | [[_ s]] 101 | (if (-> s first (= \r)) 102 | [:string+ (str/replace s #"^r.|.$" "")] 103 | (-> (str/replace s #"^.|.$" "") 104 | (substitute-curly-quotes :backward true) 105 | substitute-$))) 106 | 107 | (defn- node->number [[tag value]] 108 | (cond (not= tag :number) 109 | (throw (ex-info "node with wrong tag passed" {:tag tag})) 110 | 111 | (str/starts-with? value "0x") 112 | (symbol value) 113 | 114 | :else 115 | (-> value (str/replace #"^\." "0.") read-string))) 116 | 117 | (declare ast->clj) 118 | 119 | (defn- flatten-dot [node] 120 | (loop [[tag v1 v2 :as node] node ;; having structure like [dot [dot a b] c] 121 | stack [] ;; put here 'c', then 'b', while trying to find 'a' ^ 122 | [a [tag2 n params :as b] :as rslt] [] ;; result will look like [a b c] 123 | op? false] 124 | (cond (= :dot tag) (recur v1 (conj stack v2) rslt op?) 125 | (= :dot-op tag) (recur v1 (conj stack v2) rslt true) 126 | node (recur nil (conj stack node) rslt op?) 127 | (seq stack) (recur node (pop stack) (conj rslt (peek stack)) op?) 128 | op? (lnode (list* (tnode 'some->) ws (maps ast->clj rslt))) 129 | (= (count rslt) 2) 130 | (ast->clj [tag2 n (cons :params (cons [:argument a] (next params)))]) 131 | :else (lnode (list* (tnode '->) ws (maps ast->clj rslt)))))) 132 | 133 | (defn- dot->clj [[tag v1 v2]] 134 | (let [dt (if (= tag :invoke) "." ".-")] 135 | (if (and v2 (> (count v2) 1)) 136 | (lnode (list* (ast->clj [tag v1]) ws (ast->clj v2))) 137 | (tnode (symbol (str dt (ast->clj v1))))))) 138 | 139 | (defn flatten-same-node [[f & params]] ;; [f [f 1 2] 3] -> [f 1 2 3] 140 | (mapcat 141 | #(if (and (sequential? %) (= (first %) f)) 142 | (flatten-same-node %) 143 | [%]) 144 | params)) 145 | 146 | (defn flatten-cascade [node] 147 | (let [flt (flatten-same-node node)] 148 | (lnode 149 | (list* (tnode 'doto) ws 150 | (ast->clj (first flt)) 151 | (->> flt 152 | (drop 1) 153 | (map (fn [[tag & params :as node]] 154 | (if (= tag :constructor) 155 | (cons :invoke params) 156 | node))) 157 | (maps ast->clj)))))) 158 | 159 | (defn- flatten-commutative-node [[f :as node]] 160 | (list* 161 | [:identifier (case f :and "and", :or "or", :add "+", :mul "*")] 162 | (flatten-same-node node))) 163 | 164 | (defn compare-longest-path 165 | "Getting a seq of nodes like: 166 | `([:compare [:identifier \"a\"] \">\" [:identifier \"b\"]] 167 | [:compare [:identifier \"b\"] \">\" [:identifier \"c\"]] ...)`. 168 | In other words, we have a graph here. Example: 169 | `a -> b, b -> c, b -> d, c -> e`. 170 | This function returns the seq of nodes which is the longest path. 171 | In terms of 'Example' above, it is going to be: `a -> b -> c -> e`" 172 | ([nodes] 173 | (compare-longest-path nodes (group-by #(-> % second second) nodes))) 174 | ([nodes dictionary] 175 | (apply max-key 176 | count 177 | ; node exmaple 178 | (for [[_ [_ _] _ [_ end] :as node] nodes 179 | :let [continues (get dictionary end)]] 180 | (cons 181 | node 182 | (when continues 183 | (compare-longest-path continues (dissoc dictionary end)))))))) 184 | 185 | (defn- build-compare-ast [compare-vals] 186 | (list* :compare+ 187 | [:identifier (nth (first compare-vals) 2)] 188 | (second (first compare-vals)) 189 | (map #(nth % 3) compare-vals))) 190 | 191 | (defn- unify-compare 192 | "If we have different compare functions in the node, like `<` and `>`, 193 | replace all `<` with `>` and `<=` with `>=`. 194 | Returns grouped by function sequences" 195 | [compare-nodes] 196 | (let [compare-fns (set (map #(nth % 2) compare-nodes))] 197 | (if (<= (count compare-fns) 1) 198 | [compare-nodes] 199 | (->> compare-nodes 200 | (mapv 201 | (fn [[tag e1 f e2 :as node]] 202 | (cond (= f "<") [tag e2 ">" e1] 203 | (= f "<=") [tag e2 ">=" e1] 204 | :else node))) 205 | (group-by #(nth % 2)) 206 | vals)))) 207 | 208 | (defn- flatten-compare [[tag & params :as and-node]] 209 | (let [{compare-nodes true, 210 | other-nodes false} (group-by (fn [[f]] (= f :compare)) params)] 211 | (if compare-nodes 212 | ;; `seq` below means `seq of nodes` 213 | (let [compare-seqs (unify-compare compare-nodes) 214 | longest-seqs (map compare-longest-path compare-seqs) 215 | ast-seqs (map build-compare-ast longest-seqs) 216 | other-nodes (apply set/difference 217 | (set (apply concat other-nodes compare-seqs)) 218 | (or (map set longest-seqs) '(#{})))] 219 | (cond (seq other-nodes) 220 | (concat [tag] other-nodes ast-seqs) 221 | 222 | (= (count ast-seqs) 1) (next (first ast-seqs)) 223 | 224 | :else (cons tag ast-seqs))) 225 | and-node))) 226 | 227 | (defn dfs [f sq] 228 | (some f (tree-seq coll? seq sq))) 229 | 230 | (defn- switch-case-ok? [[tag v1 v2 v3]] 231 | (or (= tag :default-case) 232 | (and (= tag :switch-case) 233 | (= (first v1) :cases) 234 | (or (some-> v3 second (= "break")) 235 | (dfs #{:return} v2))))) 236 | 237 | (defn- if->clj [node] 238 | (case (count node) 239 | 3 (lnode (list* (tnode 'when) ws (->> node rest (maps ast->clj)))) 240 | 4 (lnode (list* (tnode 'if) ws (->> node rest (maps ast->clj)))) 241 | (lnode 242 | (if (even? (count node)) 243 | (concat 244 | (list* (tnode 'cond) ws (->> node butlast rest (maps ast->clj))) 245 | [ws (knode :else) ws (ast->clj (peek node))]) 246 | (list* (tnode 'cond) ws (->> node rest (maps ast->clj))))))) 247 | 248 | (defn- switch-ok? [[_ _ & cases]] 249 | (reduce #(and %1 %2) (map switch-case-ok? cases))) 250 | 251 | (defn- switch-case->clj-nodes [[_ [_ & cases] body]] 252 | (let [body (ast->clj body)] 253 | (mapcat 254 | #(list (ast->clj %) body) 255 | cases))) 256 | 257 | (defn- switch-branch->clj-nodes [[tag v1 :as node]] 258 | (if (= tag :switch-case) 259 | (switch-case->clj-nodes node) 260 | [(ast->clj v1)])) 261 | 262 | (defn- switch->case-or-warn [[_ expr & cases :as node]] 263 | (if (switch-ok? node) 264 | (lnode 265 | (list* 266 | (tnode 'case) ws 267 | (ast->clj expr) nl 268 | (mapcatn #(switch-branch->clj-nodes %) cases))) 269 | :unidiomatic)) 270 | 271 | (defn- try-on->clj-node [[_ [_ q] [_ e] body :as on-part]] 272 | (lnode [(tnode 'catch) ws 273 | (ast->clj (or q [:identifier "Exception"])) ws 274 | (ast->clj (or e [:identifier "e"])) nl 275 | (ast->clj body)])) 276 | 277 | (defn- try-branch->clj-node [node] 278 | (if (= (count node) 2) 279 | (lnode [(tnode 'finally) ws (ast->clj (second node))]) 280 | (try-on->clj-node node))) 281 | 282 | (defn- try->clj [[_ body & branches]] 283 | (lnode 284 | (list* 285 | (tnode 'try) nl 286 | (ast->clj body) 287 | (map #(try-branch->clj-node %) branches)))) 288 | 289 | (defn- var-declare->clj [[_ v1 :as node]] 290 | (let [inits (filter sequential? node) 291 | const? (= v1 "const") 292 | with-const (fn [[_ n v :as var-init-node]] 293 | (if const? 294 | [:var-init [:const n] v] 295 | var-init-node))] 296 | (if (= (count inits) 1) 297 | (ast->clj (with-const (first inits))) 298 | (lnode 299 | (list* (tnode 'do) ws 300 | (->> (map with-const inits) 301 | (maps ast->clj))))))) 302 | 303 | (defn ast->clj [[tag v1 v2 v3 :as node]] 304 | #_(println :node node) 305 | (case tag 306 | :s (ast->clj v1) 307 | :code (if v2 308 | (lnode (list* (tnode 'do) nl (mapn ast->clj (rest node)))) 309 | (ast->clj v1)) 310 | 311 | :file (if v2 312 | (n/list-node (list* (tnode 'do) nl (mapn ast->clj (rest node)))) 313 | (ast->clj v1)) 314 | :import-block (lnode (list* (tnode 'require) ws (mapn ast->clj (rest node)))) 315 | :import-as (vnode [(ast->clj v1) ws (knode :as) ws (ast->clj v2)]) 316 | :import-naked (vnode [(ast->clj v1) ws (knode :as) ws 'give-an-alias-or-refer]) 317 | :import-show (vnode [(ast->clj v1) ws 318 | (knode :refer) ws 319 | (vnode (maps ast->clj (drop 2 node)))]) 320 | :import-hide (vnode [(ast->clj v1) ws (knode :as) ws 'be-aware-of-hide-here]) 321 | :import-full 322 | (vnode [(ast->clj v1) ws 323 | (knode :as) ws 324 | (ast->clj v2) ws 325 | (knode :refer) ws 326 | (vnode (maps ast->clj (drop 3 node)))]) 327 | :var-declare (var-declare->clj node) 328 | :var-init (lnode [(tnode 'def) ws 329 | (ast->clj v1) ws 330 | (or (some-> v2 ast->clj) (tnode 'nil))]) 331 | :class 332 | (lnode (list* 333 | (tnode 'comment) nl 334 | "use flutter/widget macro instead of classes" nl 335 | (mapcat #(if (sequential? %) % [%]) 336 | (mapn ast->clj (rest node))))) 337 | :method (lnode [(tnode 'defn) ws 338 | (ast->clj v1) ws 339 | (ast->clj v2) ws 340 | (ast->clj v3)]) 341 | 342 | :constructor (lnode (list* (ast->clj v1) ws (ast->clj v2))) 343 | :params (mapcats ast->clj (rest node)) 344 | :argument (if v2 (map ast->clj (rest node)) [(ast->clj v1)]) 345 | :named-arg (tnode (symbol (str "." (ast->clj v1)))) 346 | 347 | :dot (flatten-dot node) 348 | :dot-op (flatten-dot node) 349 | :invoke (dot->clj node) 350 | :field (dot->clj node) 351 | 352 | :lambda (lnode [(tnode 'fn) ws (ast->clj v1) nl (ast->clj v2)]) 353 | :lambda-args (vnode (->> node rest (maps ast->clj))) 354 | :block (ast->clj (cons :code (rest node))) 355 | 356 | :ternary (ast->clj [:if v1 v2 v3]) 357 | :if (if->clj node) 358 | :switch (switch->case-or-warn node) 359 | :try (try->clj node) 360 | :cascade (flatten-cascade node) 361 | 362 | :for-in (n/list-node [(tnode 'for) ws 363 | (vnode [(ast->clj v1) ws (ast->clj v2)]) nl 364 | (ast->clj v3)]) 365 | 366 | :return (if v1 (ast->clj v1) (tnode 'nil)) 367 | :typecasting (ast->clj v1) 368 | :const (n/meta-node (tnode :const) (ast->clj v1)) 369 | :identifier (symbol (str/replace v1 #"!" "")) 370 | :qualified (tnode (symbol (str/join "." (map ast->clj (next node))))) 371 | :list (n/vector-node (maps ast->clj (rest node))) 372 | :map (mnode (maps ast->clj (rest node))) 373 | :get (lnode [(tnode 'get) ws (ast->clj v1) ws (ast->clj v2)]) 374 | :string (-> node node->string-ast ast->clj) 375 | :string+ v1 376 | :strings+ (lnode (list* (tnode 'str) ws (maps ast->clj v1))) 377 | :number (node->number node) 378 | 379 | :neg (lnode [(tnode '-) ws (ast->clj v1)]) 380 | :sub (lnode [(tnode '-) ws (ast->clj v1) ws (ast->clj v2)]) 381 | :await (lnode [(tnode 'await) ws (ast->clj v1)]) 382 | 383 | :and (->> node flatten-commutative-node flatten-compare (maps ast->clj) lnode) 384 | :compare+ (lnode (list* (ast->clj v1) ws (->> node (drop 2) (maps ast->clj)))) 385 | (:or :add :mul) (lnode (maps ast->clj (flatten-commutative-node node))) 386 | (:not :dec :inc) (lnode [(tnode (symbol tag)) ws (ast->clj v1)]) 387 | (:compare :div :ifnull :equality) 388 | (lnode [(tnode (dart-op->clj-op v2)) ws (ast->clj v1) ws (ast->clj v3)]) 389 | 390 | (cond 391 | (and (keyword? tag) (-> tag str second (= \_))) :unidiomatic 392 | :else :unknown))) 393 | 394 | (defn- encode [^String to-encode] 395 | #?(:clj (.encodeToString (Base64/getEncoder) (.getBytes to-encode)) 396 | :cljs (b64-cljs/utf8_to_b64 to-encode))) 397 | 398 | (defn- decode [^String to-decode] 399 | #?(:clj (String. (.decode (Base64/getDecoder) to-decode)) 400 | :cljs (b64-cljs/b64_to_utf8 to-decode))) 401 | 402 | (defn- multiline->single [s] 403 | (let [pattern #"'{3}([\s\S]*?'{3})|\"{3}([\s\S]*?\"{3})" 404 | transform (fn [[m]] (substitute-curly-quotes m))] 405 | (-> s 406 | (str/replace pattern transform) 407 | (str/replace #"”””|’’’" "'")))) 408 | 409 | (defn clean 410 | "removes comments from string, transforms multiline string 411 | to singleline, replaces quotes (', \") with 'curly-quotes' (“)" 412 | [code] 413 | (let [str-pattern #"([\"\'])(?:(?=(\\?))\2.)*?\1" 414 | transform #(fn [[m]] 415 | (str "'" (% (subs m 1 (dec (count m)))) "'"))] 416 | (-> code 417 | 418 | ;; to simplify modifications below 419 | multiline->single 420 | 421 | ;; TODO: find another way to deal with comments 422 | ;; the problem is that comments could appear inside strings 423 | (str/replace str-pattern (transform encode)) ; encode strings to Base64 424 | 425 | ;; cleaning code from comments 426 | (str/replace #"/\*(\*(?!/)|[^*])*\*/" "") ; /* ... */ 427 | (str/replace #"(//).*" "") ; // ... 428 | 429 | ;; new is optional 430 | (str/replace "new " "") 431 | 432 | (str/replace str-pattern 433 | (transform (comp substitute-curly-quotes decode)))))) 434 | 435 | (defn save-read [code] 436 | (try 437 | (n/sexpr code) 438 | (catch #?(:clj Exception 439 | :cljs js/Error) e (n/string code)))) 440 | 441 | (defn dart->ast [^:String dart] 442 | (insta/parse widget-parser (clean dart))) 443 | 444 | (defn dart->clojure [^:String dart] 445 | (-> dart dart->ast (ast->clj) save-read)) 446 | 447 | (comment 448 | 449 | (def code " 450 | class A { 451 | static var i = 1; 452 | } 453 | ") 454 | 455 | (def code2 " 456 | Future createOrderMessage() async { 457 | var order = await fetchUserOrder(); 458 | return 'Your order is: $order'; 459 | } 460 | ") 461 | 462 | (insta/parses widget-parser code2) 463 | 464 | (dart->clojure code2) 465 | 466 | (-> "a && b && c" 467 | dart->ast 468 | ast->clj 469 | n/string)) 470 | -------------------------------------------------------------------------------- /test/dumch/parse_test.cljc: -------------------------------------------------------------------------------- 1 | (ns dumch.parse-test 2 | (:require #?(:cljs [clojure.edn :refer [read-string]]) 3 | [clojure.test :refer [deftest testing is]] 4 | [dumch.improve :as improve :refer [simplify]] 5 | [dumch.parse :refer [clean widget-parser dart->clojure dart->ast ast->clj]] 6 | [instaparse.core :as insta] 7 | [rewrite-clj.zip :as z] 8 | [rewrite-clj.node :as n])) 9 | 10 | (def ^:private dart->clj-simplified 11 | (comp z/sexpr simplify ast->clj dart->ast)) 12 | 13 | (def ^:private dart->clj-string 14 | (comp z/string simplify ast->clj dart->ast)) 15 | 16 | (deftest numbers-test 17 | (testing "real numbers" 18 | (is (= (dart->clojure "1") 1)) 19 | (is (= (dart->clojure "10.10") 10.1)) 20 | 21 | (testing ": exponential" 22 | (is (= (dart->clojure "1.0E03") 1000.0)) 23 | (is (= (dart->clojure "-1.23e+45") -1.23E45)))) 24 | 25 | (testing "colors" 26 | ;; this test uses string because hex format is auto-converted to long 27 | (is (= (str (dart->clojure "new Color(0xFFE3F2FD)")) 28 | "(Color 0xFFE3F2FD)")))) 29 | 30 | (deftest import-test 31 | (testing "import with 'hide'" 32 | (is (= (dart->clojure "import 'pkg:goog/maps.dart' hide LatLng") 33 | '(require ["pkg:goog/maps.dart" :as be-aware-of-hide-here])))) 34 | (testing "import with 'show'" 35 | (is (= (dart->clojure "import 'package:f/s.dart' show Delta;") 36 | '(require ["package:f/s.dart" :refer [Delta]])))) 37 | (testing "import without specifications" 38 | (is (= (dart->clojure "import 'package:flutter/widgets.dart';") 39 | '(require ["package:flutter/widgets.dart" :as give-an-alias-or-refer])))) 40 | (testing "import with 'as' and 'show'" 41 | (is (= (dart->clojure "import 'pkg:goog/maps.dart' as GMap show LatLng;") 42 | '(require ["pkg:goog/maps.dart" :as GMap :refer [LatLng]]))))) 43 | 44 | (deftest methods-test 45 | (testing "method with body" 46 | (is (= (dart->clojure 47 | "@override 48 | Widget build(BuildContext context) { 49 | return Text('name'); 50 | }") 51 | '(defn build [context] (Text "name"))))) 52 | (testing "static method" 53 | (is (= (dart->clojure 54 | "static void staticVoid() { print(1); }") 55 | '(defn staticVoid [] (print 1))))) 56 | (testing "void method with expression" 57 | (is (= (dart->clojure 58 | "void _toggleFavorite() => setState(() { print(1); });") 59 | '(defn _toggleFavorite [] (setState (fn [] (print 1)))))) 60 | (is (= (dart->clojure 61 | "void main() => runApp(App());") 62 | '(defn main [] (runApp (App)))))) 63 | (testing "method with dot in type" 64 | (is (= (dart->clojure "A.B.C a() => 1") '(defn a [] 1)))) 65 | (testing "method without type" 66 | (is (= (dart->clojure "a() => 1") '(defn a [] 1))))) 67 | 68 | (deftest get-set-test 69 | (testing "getter with => and with body {}" 70 | (is (= (dart->clojure "class A { 71 | Key get dividerKey => Key('$this'); 72 | Key get dividerKey2 { return 1; }; 73 | }") 74 | '(comment "use flutter/widget macro instead of classes" 75 | :unknown 76 | :unknown)))) 77 | (testing "setter with => and with body {}" 78 | (is (= (dart->clojure "class A { 79 | set right(double value) => left = value - width; 80 | set right(double value) { a = b; } 81 | }") 82 | '(comment 83 | "use flutter/widget macro instead of classes" 84 | (defn right [value] :unidiomatic) 85 | (defn right [value] :unidiomatic)))))) 86 | 87 | (deftest invocations-name-test 88 | (testing "simple constructor" 89 | (is (= (dart->clojure "Text('text')") 90 | (-> '(Text "text"))))) 91 | (testing "typed constructor" 92 | (is (= (dart->clojure "Text, C?>('text')") 93 | (-> '(Text "text"))))) 94 | (testing "line invocations" 95 | (is (= (dart->clojure "One(1).two().three(2, 3)") 96 | '(-> (One 1) .two (.three 2 3))))) 97 | (testing "instance method invocation" 98 | (is (= (dart->clojure "_pinPut.copyWith(border: 1)") 99 | '(.copyWith _pinPut .border 1)))) 100 | (testing "field's field.method invocation" 101 | (is (= (dart->clojure "field!.pinPut.copyWith(border: 1)") 102 | '(-> field .-pinPut (.copyWith .border 1))))) 103 | (testing "static field method invocation" 104 | (is (= (dart->clojure "SClass.field.copyWith(border: 1)") 105 | '(-> SClass .-field (.copyWith .border 1))))) 106 | (testing "invocation on list" 107 | (is (= (-> "[1].cast()" dart->clojure) 108 | '(.cast [1]))) 109 | (is (= (-> "[1].length" dart->clojure) 110 | '(.-length [1])))) 111 | (testing "invocation on map" 112 | (is (= (-> "{1:1}.cast()" dart->clojure) 113 | '(.cast {1 1}))) 114 | (is (= (-> "{1:1}.length" dart->clojure) 115 | '(.-length {1 1})))) 116 | (testing "long chaing of dots" 117 | (is (= (-> "a.b().c.d().e()" dart->clojure) 118 | '(-> a .b .-c .d .e))))) 119 | 120 | (deftest optional-name-test 121 | (testing "optional field somewhere in the chain" 122 | (is (= (-> "obj?.field.name?.first" dart->clojure) 123 | '(some-> obj .-field .-name .-first))) 124 | (is (= (-> "obj.field?.name" dart->clojure) 125 | '(some-> obj .-field .-name)))) 126 | (testing "field in optional object" 127 | (is (= (-> "obj?.name" dart->clojure) 128 | '(some-> obj .-name)))) 129 | (testing "only one optional in the chain" 130 | (is (= (-> "a.b?.c.d().e" dart->clojure) 131 | '(some-> a .-b .-c .d .-e))))) 132 | 133 | (deftest optional-invocation-test 134 | (testing "optional field somewhere in the invocation chain" 135 | (is (= (dart->clojure "SClass?.field.copyWith(border: 1)") 136 | '(some-> SClass .-field (.copyWith .border 1)))) 137 | (is (= (dart->clojure "SClass.field?.copyWith()") 138 | '(some-> SClass .-field .copyWith)))) 139 | (testing "invocation on optional field" 140 | (is (= (dart->clojure "instance?.copyWith(border: 1)") 141 | '(some-> instance (.copyWith .border 1)))))) 142 | 143 | (deftest ^:current list-test 144 | (testing "empty list" (is (= (dart->clojure "[]") '[]))) 145 | (testing "ignore spread operator" 146 | (is (= (-> "[...state.a.map((acc) => _t(ctx, acc))]" 147 | dart->clojure) 148 | '[(-> :unidiomatic .-a (.map (fn [acc] (_t ctx acc))))]))) 149 | (testing "typed list" 150 | (is (= (-> "[1, 2]" dart->clojure) 151 | [1 2]))) 152 | (testing "column children typeless list" 153 | (is 154 | (= (-> "Column(children: [const Text('name'), 155 | Icon(Icons.widgets)])" 156 | dart->clojure) 157 | '(Column .children [(Text "name") (Icon (.-widgets Icons))])))) 158 | (testing "ifnull and ternary list elements" 159 | (is (= (-> "[ a? 1 : b, c ?? d ]" dart->clojure) 160 | '[(if a 1 b) (or c d)])))) 161 | 162 | (deftest map-test 163 | (testing "empty map" (is (= (dart->clojure "{}") '{}))) 164 | (testing "map with end comma" (is (= (dart->clojure "{1: 1,}") '{1 1}))) 165 | (testing "typeless map as named parameter" 166 | (is 167 | (= (dart->clojure "ListCell.icon(m: {1 : 2, 'a' : b, c : 'd'})") 168 | '(.icon ListCell .m {1 2, "a" b, c "d"})))) 169 | (testing "typed map" 170 | (is 171 | (= (-> ">{1: [1, 2]}" dart->clojure) 172 | {1 [1 2]}))) 173 | (testing "ifnull and ternary map elements" 174 | (is 175 | (= (-> ">{ a ? 1 : 2 : a ?? b}" dart->clojure) 176 | '{(if a 1 2) (or a b)})))) 177 | 178 | (deftest set!-test 179 | (is (= (dart->clojure "a = b") :unidiomatic))) 180 | 181 | (deftest get-test 182 | (testing "get for field" 183 | (is (= (dart->clojure "Colors.red[500]!") 184 | '(get (.-red Colors) 500)))) 185 | (testing "single get" 186 | (is (= (dart->clojure "tabs[2]") '(get tabs 2)))) 187 | (testing "serveral get in a row" 188 | (is (= (dart->clojure "questions[1]['two']") 189 | '(get (get questions 1) "two"))))) 190 | 191 | (deftest logic-test 192 | (testing "and: &&" 193 | (is (= (dart->clojure "b && a") '(and b a)))) 194 | (testing "or: ||, ??" 195 | (is (= (dart->clojure "b || a") '(or b a))) 196 | (is (= (dart->clojure "b ?? a") '(or b a)))) 197 | (testing "compare: >, <, =>, <=" 198 | (is (= (dart->clojure "b > a") '(> b a))) 199 | (is (= (dart->clojure "b < a") '(< b a))) 200 | (is (= (dart->clojure "b >= a") '(>= b a))) 201 | (is (= (dart->clojure "b <= a") '(<= b a))) 202 | (is (= (dart->clojure "1 is int") '(dart/is? 1 int)))) 203 | (testing "equality: ==, !=" 204 | (is (= (dart->clojure "b == a") '(= b a))) 205 | (is (= (dart->clojure "b != a") '(not= b a))))) 206 | 207 | (deftest ternary-test 208 | (testing "simple ternary" 209 | (is (= (dart->clojure "a ? b : c") '(if a b c)))) 210 | (testing "lambda as ternary parameter" 211 | (is (= (dart->clojure 212 | "TextButton(onPressed: _searchEnabled ? () { pop(); } : null)") 213 | '(TextButton 214 | .onPressed 215 | (if _searchEnabled 216 | (fn [] (pop)) 217 | null)))))) 218 | 219 | (deftest cascade-test 220 | (is (= (dart->clojure 221 | "getAddress() 222 | ..setStreet('Elm', '13a') 223 | ..city = 'Carthage' 224 | ..state = 'Eurasia' 225 | ..zip(66666, extended: 6666);") 226 | '(doto 227 | (getAddress) 228 | (.setStreet "Elm" "13a") 229 | :unidiomatic 230 | :unidiomatic 231 | (.zip 66666 .extended 6666))))) 232 | 233 | (deftest for-test 234 | (testing "for-in, expressiong body" 235 | (is (= (dart->clojure 236 | "for (int n in names) { print(n); } ") 237 | '(for [n names] (print n))))) 238 | (testing "for-in, curly-body" 239 | (is (= (dart->clojure 240 | "for (int i in names) print(i); ") 241 | '(for [i names] (print i))))) 242 | (testing "for, curly body" 243 | (is (= (dart->clojure 244 | "for (int i = 0; i < 5; i++) {print('GeeksForGeeks');}") 245 | :unidiomatic)))) 246 | 247 | (deftest while-test 248 | (testing "while" 249 | (is (= (dart->clojure "while(num >=1) { num--; }") 250 | :unidiomatic))) 251 | (testing "do-while" 252 | (is (= (dart->clojure "do { number++; } while (number < 10);") 253 | :unidiomatic)))) 254 | 255 | (deftest const-test 256 | (testing "invocation const" 257 | (is (= (dart->clj-string 258 | "IconButton(padding: const EdgeInsets.all(0),);") 259 | "(m/IconButton .padding ^:const (.all m/EdgeInsets 0))"))) 260 | (testing "invocation constructor" 261 | (is (= (dart->clj-string 262 | "const Icon(Icons.star)") 263 | "^:const (m/Icon (.-star m/Icons))"))) 264 | (testing "invocation constructor" 265 | (is (= (dart->clj-string 266 | "const Icon(Icons.star)") 267 | "^:const (m/Icon (.-star m/Icons))")))) 268 | 269 | (deftest unary-prefix-test 270 | (testing "not" (is (= (dart->clojure "!a") '(not a)))) 271 | (testing "inc" (is (= (dart->clojure "++a") '(inc a)))) 272 | (testing "dec" (is (= (dart->clojure "--a") '(dec a)))) 273 | (testing "-" (is (= (dart->clojure "-a") '(- a))))) 274 | 275 | (deftest math-test 276 | (testing "difference" 277 | (is (= (dart->clojure "b - a") '(- b a)))) 278 | (testing "sum" 279 | (is (= (dart->clojure "b + a") '(+ b a)))) 280 | (testing "remainder" 281 | (is (= (dart->clojure "b % a") '(rem b a)))) 282 | (testing "divide and round" 283 | (is (= (dart->clojure "b ~/ a") '(quot b a)))) 284 | (testing "division" 285 | (is (= (dart->clojure "b / a") '(/ b a)))) 286 | (testing "multiply" 287 | (is (= (dart->clojure "b * a") '(* b a))))) 288 | 289 | (deftest lambda-test 290 | (testing "lambda with =>" 291 | (is (= (dart->clojure "Button(onPressed: (ctx) => 1 + 1;)") 292 | '(Button .onPressed (fn [ctx] (+ 1 1)))))) 293 | (testing "lambda with body" 294 | (is (= (dart->clojure "Button(onPressed: (ctx) { println(a == a); setState(a); })") 295 | '(Button .onPressed (fn [ctx] (do (println (= a a)) (setState a))))))) 296 | (testing "lambda with typed argument" 297 | (is (= (dart->clojure "Button(onPressed: (Context ctx) => 1 + 1;)") 298 | '(Button .onPressed (fn [ctx] (+ 1 1))))))) 299 | 300 | (deftest if-test 301 | (testing "one branch if with curly body" 302 | (is (= (dart->clojure "if (a == b) print('a');") 303 | '(when (= a b) (print "a"))))) 304 | (testing "if else with and without body" 305 | (is (= (dart->clojure "if (b) { print(1); return 3; } else return 2;") 306 | '(if b (do (print 1) 3) 2)))) 307 | (testing "if and else-if" 308 | (is (= (dart->clojure "if (b) b; else if (a) a; else if (c) c;") 309 | '(cond b b a a c c)))) 310 | (testing "if, and else-if, and else" 311 | (is (= (dart->clojure "if (b) b; else if (a) a; else c;") 312 | '(cond b b a a :else c))))) 313 | 314 | (deftest switch-test 315 | (testing "idiomatic switch with default" 316 | (is (= (dart->clojure 317 | "switch(grade) { 318 | case 'A': return 'Great!'; 319 | 320 | case 'B': { print('Good'); } 321 | break; 322 | 323 | case 'C': 324 | case 'D': { print('Bad'); } 325 | break; 326 | 327 | default: print('Invalid choice'); 328 | break; 329 | }") 330 | '(case grade 331 | "A" "Great!" 332 | "B" (print "Good") 333 | "C" (print "Bad") 334 | "D" (print "Bad") 335 | (print "Invalid choice"))))) 336 | (testing "idiomatic switch" 337 | (is (= (dart->clojure 338 | "switch (x) { 339 | case 1: return 1; 340 | case 2: return 2; 341 | }") 342 | '(case x 1 1 2 2)))) 343 | (testing "unidiomatic cases" 344 | (is (= (dart->clojure 345 | "switch (x) { 346 | case 42: print('hello'); 347 | continue world; 348 | case 37: print('goodbye'); 349 | break; 350 | world: 351 | case 87: print('world'); 352 | }") 353 | :unidiomatic)))) 354 | 355 | (deftest try-test 356 | (is (= (dart->clojure 357 | "try { 358 | breedMoreLlamas(); 359 | } on Lib.OutOfLlamasException { 360 | buyMoreLlamas(); 361 | } on Exception catch (e) { 362 | print('Unknown exception: $e'); 363 | } catch (e) { 364 | print('Something really unknown: $e'); 365 | } finally { 366 | cleanLlamaStalls(); 367 | }") 368 | '(try 369 | (breedMoreLlamas) 370 | (catch Lib.OutOfLlamasException e (buyMoreLlamas)) 371 | (catch Exception e (print (str "Unknown exception: " e))) 372 | (catch Exception e (print (str "Something really unknown: " e))) 373 | (finally (cleanLlamaStalls)))))) 374 | 375 | (deftest comments-test 376 | (testing "line comment" 377 | (is (= (dart->clojure "Text( 378 | 'name', // comment 379 | )") 380 | '(Text "name")))) 381 | (testing "block comment" 382 | (is (= (dart->clojure "Text(widget.photo.user!.name /* comment */ )") 383 | '(Text (-> widget .-photo .-user .-name))))) 384 | (testing "comment-like structure inside string" 385 | (is (= (dart->clojure "Text( 386 | 'http://looks-like-comment', 387 | '/* one more */' 388 | )") 389 | '(Text "http://looks-like-comment" "/* one more */"))))) 390 | 391 | (deftest strings-test 392 | (testing "special symbols inside string test" 393 | (is 394 | (= (->> "''' cat's name \"bob\" '''" 395 | clean 396 | dart->clojure 397 | ) 398 | " cat's name \"bob\" "))) 399 | (testing "special symbols inside string test" 400 | (is 401 | (= 1 402 | (->> "'\n\t\\s\"'" 403 | clean 404 | (insta/parses widget-parser) 405 | count)))) 406 | (testing "multiline string with inner comments" 407 | (is 408 | (= 1 409 | (->> 410 | "\"\"\" 411 | multiline // comment like 412 | \" some string inside multiline string \" 413 | /* another comment */ \"\"\"" 414 | clean 415 | (insta/parses widget-parser) 416 | count)))) 417 | (testing "$ substitution" 418 | (is (= (dart->clojure "Text('Some $field and ${Factory.create()}')") 419 | '(Text (str "Some " field " and " (.create Factory)))))) 420 | (testing "ignore $-substitution on raw sting" 421 | (is (= (dart->clojure "Text(r\"Some $field and ${Factory.create()}\")") 422 | '(Text "Some $field and ${Factory.create()}"))))) 423 | 424 | (deftest assignment-test 425 | (testing "typeless var assignment" 426 | (is (= (dart->clojure "var a = b;") '(def a b)))) 427 | (testing "final assignment" 428 | (is (= (dart->clojure "final String s = '1'; ") '(def s "1")))) 429 | (testing "const assignment" 430 | (is (= (dart->clj-string "const bar = 100;") 431 | "(def ^:const bar 100)"))) 432 | (testing "assign value with type with dot" 433 | (is (= (dart->clojure "A.C bar = 1;") '(def bar 1))))) 434 | 435 | (deftest var-declaration-test 436 | (let [code "var bar = 0; 437 | const bar = 1; 438 | static bar = 2; 439 | static final bar = 3; 440 | static const int bar = 4; 441 | static final int bar = 5; 442 | static final int bar = 6, lar;" 443 | result '((def bar 0) 444 | (def bar 1) 445 | (def bar 2) 446 | (def bar 3) 447 | (def bar 4) 448 | (def bar 5) 449 | (do (def bar 6) (def lar nil)))] 450 | (testing "lambda vars" 451 | (is (= (dart->clj-simplified (str "() { " code " }")) 452 | (cons 'fn `( [] ~@result))))) 453 | (testing "method vars" 454 | (is (= (dart->clj-simplified (str "void main() { " code " }")) 455 | (list* 'defn 'main `([] ~@result))))) 456 | (testing "class vars" 457 | (is (= (drop 2 (dart->clj-simplified (str "class A { " code " }"))) 458 | result))) 459 | (testing "global vars" 460 | (is (= (next (dart->clj-simplified code)) 461 | result))))) 462 | 463 | (deftest await-test 464 | (is (= (dart->clojure "await a") '(await a))) 465 | (is (= (dart->clojure "await db.collection('todos').get();") 466 | '(await (-> db (.collection "todos") .get))))) 467 | 468 | (deftest statement-test 469 | (testing "several expressions | statements in a row with | without ';'" 470 | (is (= (dart->clojure "a = 2; 471 | if (item.isLoading) { 472 | print(1) 473 | } 474 | a") 475 | '(do :unidiomatic (when (.-isLoading item) (print 1)) a))))) 476 | 477 | (deftest return-test 478 | (is (= (-> "if (a) return;" dart->clojure) '(when a nil)))) 479 | 480 | (deftest annotaions-test 481 | (is (= (-> "@Foo(42) 482 | class Foo { 483 | 484 | @Deprecated('until further notice'); 485 | final int x; 486 | 487 | @FOO 488 | const Foo(this.x); 489 | 490 | @override 491 | void main() { 492 | print(a); 493 | } 494 | } 495 | 496 | @JsonKey(fromJson: _variableFromJson) 497 | enum FieldType { 498 | @JsonEnum('Text') text, 499 | @JsonEnum('Number') number 500 | }" 501 | dart->clojure) 502 | '(do 503 | (comment 504 | "use flutter/widget macro instead of classes" 505 | (def x nil) 506 | (defn main [] (print a))) 507 | :unknown)))) 508 | 509 | (deftest flatten-same-operators 510 | #?(:clj ; TODO: How to do this in ClojureScript? 511 | (testing "calculation results" 512 | (is (-> "(2 + 1 + 1 == 4 && true) && (1 == 1 || false) && 3 == 3" 513 | dart->clj-string 514 | read-string 515 | eval)))) 516 | (testing "+, *, and, or" 517 | (doseq [sym ["+" "*" "||" "&&"]] 518 | (is (= (-> (str 1 sym 2 sym 3 sym 4 sym 5) dart->clojure) 519 | `(~(symbol (case sym "||" 'or, "&&" 'and sym)) 1 2 3 4 5))))) 520 | (testing "flatten compare operators when possible" 521 | (is (= (-> "1 < 2 && 2 < 3" dart->clojure) 522 | '(< 1 2 3))) 523 | (is (= (-> "3 > 2 && 2 > 1 && 4 > 3 && true" dart->clj-string) 524 | "(and true (> 4 3 2 1))")) 525 | (is (#{'(and (>= 4 3) (or (>= 3 2) (>= 2 1))) 526 | '(and (or (>= 3 2) (>= 2 1)) (>= 4 3))} 527 | (-> "4 >= 3 && 3 >= 2 || 2 >= 1" dart->clojure))) 528 | (is (= (-> "5 >= 4 && 4 >= 3 && 3 >= 2 || 2 >= 1" dart->clojure) 529 | '(and (or (>= 3 2) (>= 2 1)) (>= 5 4 3)))) 530 | 531 | 532 | (is (= (-> "a > b || (c > d && d > e && e < f)" dart->clojure) 533 | '(or (> a b) (and (> f e) (> c d e))))) 534 | (is (= (-> "a > b || (c > d && d > e && f < e)" dart->clojure) 535 | '(or (> a b) (> c d e f)))) 536 | (is (= (-> "(c <= b && a >= b) || (c > d && d > e && f < e)" dart->clojure) 537 | '(or (>= a b c) (> c d e f)))))) 538 | 539 | #_(dart->clojure "4 >= 3 && 3 >= 2 || 2 >= 1") 540 | -------------------------------------------------------------------------------- /npm-test-app/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "npm-test-app", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "npm-test-app", 9 | "version": "1.0.0", 10 | "license": "MIT", 11 | "dependencies": { 12 | "dartclojure": "file:.." 13 | }, 14 | "devDependencies": { 15 | "http-server": "^14.1.1", 16 | "shadow-cljs": "^2.19.3" 17 | } 18 | }, 19 | "..": { 20 | "name": "dartclojure", 21 | "version": "0.2.6", 22 | "license": "Apache License, Version 2.0", 23 | "bin": { 24 | "dartclojure": "target/npm-app/index.js" 25 | }, 26 | "devDependencies": { 27 | "rimraf": "3.0.2", 28 | "shadow-cljs": "^2.19.3" 29 | } 30 | }, 31 | "node_modules/asn1.js": { 32 | "version": "5.4.1", 33 | "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", 34 | "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", 35 | "dev": true, 36 | "dependencies": { 37 | "bn.js": "^4.0.0", 38 | "inherits": "^2.0.1", 39 | "minimalistic-assert": "^1.0.0", 40 | "safer-buffer": "^2.1.0" 41 | } 42 | }, 43 | "node_modules/asn1.js/node_modules/bn.js": { 44 | "version": "4.12.0", 45 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", 46 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", 47 | "dev": true 48 | }, 49 | "node_modules/assert": { 50 | "version": "1.5.0", 51 | "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", 52 | "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", 53 | "dev": true, 54 | "dependencies": { 55 | "object-assign": "^4.1.1", 56 | "util": "0.10.3" 57 | } 58 | }, 59 | "node_modules/assert/node_modules/inherits": { 60 | "version": "2.0.1", 61 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", 62 | "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==", 63 | "dev": true 64 | }, 65 | "node_modules/assert/node_modules/util": { 66 | "version": "0.10.3", 67 | "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", 68 | "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==", 69 | "dev": true, 70 | "dependencies": { 71 | "inherits": "2.0.1" 72 | } 73 | }, 74 | "node_modules/async": { 75 | "version": "2.6.4", 76 | "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", 77 | "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", 78 | "dev": true, 79 | "dependencies": { 80 | "lodash": "^4.17.14" 81 | } 82 | }, 83 | "node_modules/base64-js": { 84 | "version": "1.5.1", 85 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 86 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 87 | "dev": true, 88 | "funding": [ 89 | { 90 | "type": "github", 91 | "url": "https://github.com/sponsors/feross" 92 | }, 93 | { 94 | "type": "patreon", 95 | "url": "https://www.patreon.com/feross" 96 | }, 97 | { 98 | "type": "consulting", 99 | "url": "https://feross.org/support" 100 | } 101 | ] 102 | }, 103 | "node_modules/basic-auth": { 104 | "version": "2.0.1", 105 | "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", 106 | "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", 107 | "dev": true, 108 | "dependencies": { 109 | "safe-buffer": "5.1.2" 110 | }, 111 | "engines": { 112 | "node": ">= 0.8" 113 | } 114 | }, 115 | "node_modules/bn.js": { 116 | "version": "5.2.1", 117 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", 118 | "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", 119 | "dev": true 120 | }, 121 | "node_modules/brorand": { 122 | "version": "1.1.0", 123 | "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", 124 | "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", 125 | "dev": true 126 | }, 127 | "node_modules/browserify-aes": { 128 | "version": "1.2.0", 129 | "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", 130 | "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", 131 | "dev": true, 132 | "dependencies": { 133 | "buffer-xor": "^1.0.3", 134 | "cipher-base": "^1.0.0", 135 | "create-hash": "^1.1.0", 136 | "evp_bytestokey": "^1.0.3", 137 | "inherits": "^2.0.1", 138 | "safe-buffer": "^5.0.1" 139 | } 140 | }, 141 | "node_modules/browserify-cipher": { 142 | "version": "1.0.1", 143 | "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", 144 | "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", 145 | "dev": true, 146 | "dependencies": { 147 | "browserify-aes": "^1.0.4", 148 | "browserify-des": "^1.0.0", 149 | "evp_bytestokey": "^1.0.0" 150 | } 151 | }, 152 | "node_modules/browserify-des": { 153 | "version": "1.0.2", 154 | "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", 155 | "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", 156 | "dev": true, 157 | "dependencies": { 158 | "cipher-base": "^1.0.1", 159 | "des.js": "^1.0.0", 160 | "inherits": "^2.0.1", 161 | "safe-buffer": "^5.1.2" 162 | } 163 | }, 164 | "node_modules/browserify-rsa": { 165 | "version": "4.1.0", 166 | "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", 167 | "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", 168 | "dev": true, 169 | "dependencies": { 170 | "bn.js": "^5.0.0", 171 | "randombytes": "^2.0.1" 172 | } 173 | }, 174 | "node_modules/browserify-sign": { 175 | "version": "4.2.1", 176 | "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", 177 | "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", 178 | "dev": true, 179 | "dependencies": { 180 | "bn.js": "^5.1.1", 181 | "browserify-rsa": "^4.0.1", 182 | "create-hash": "^1.2.0", 183 | "create-hmac": "^1.1.7", 184 | "elliptic": "^6.5.3", 185 | "inherits": "^2.0.4", 186 | "parse-asn1": "^5.1.5", 187 | "readable-stream": "^3.6.0", 188 | "safe-buffer": "^5.2.0" 189 | } 190 | }, 191 | "node_modules/browserify-sign/node_modules/readable-stream": { 192 | "version": "3.6.0", 193 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 194 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 195 | "dev": true, 196 | "dependencies": { 197 | "inherits": "^2.0.3", 198 | "string_decoder": "^1.1.1", 199 | "util-deprecate": "^1.0.1" 200 | }, 201 | "engines": { 202 | "node": ">= 6" 203 | } 204 | }, 205 | "node_modules/browserify-sign/node_modules/safe-buffer": { 206 | "version": "5.2.1", 207 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 208 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 209 | "dev": true, 210 | "funding": [ 211 | { 212 | "type": "github", 213 | "url": "https://github.com/sponsors/feross" 214 | }, 215 | { 216 | "type": "patreon", 217 | "url": "https://www.patreon.com/feross" 218 | }, 219 | { 220 | "type": "consulting", 221 | "url": "https://feross.org/support" 222 | } 223 | ] 224 | }, 225 | "node_modules/browserify-zlib": { 226 | "version": "0.2.0", 227 | "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", 228 | "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", 229 | "dev": true, 230 | "dependencies": { 231 | "pako": "~1.0.5" 232 | } 233 | }, 234 | "node_modules/buffer": { 235 | "version": "4.9.2", 236 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", 237 | "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", 238 | "dev": true, 239 | "dependencies": { 240 | "base64-js": "^1.0.2", 241 | "ieee754": "^1.1.4", 242 | "isarray": "^1.0.0" 243 | } 244 | }, 245 | "node_modules/buffer-xor": { 246 | "version": "1.0.3", 247 | "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", 248 | "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", 249 | "dev": true 250 | }, 251 | "node_modules/builtin-status-codes": { 252 | "version": "3.0.0", 253 | "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", 254 | "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", 255 | "dev": true 256 | }, 257 | "node_modules/call-bind": { 258 | "version": "1.0.2", 259 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 260 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 261 | "dev": true, 262 | "dependencies": { 263 | "function-bind": "^1.1.1", 264 | "get-intrinsic": "^1.0.2" 265 | }, 266 | "funding": { 267 | "url": "https://github.com/sponsors/ljharb" 268 | } 269 | }, 270 | "node_modules/cipher-base": { 271 | "version": "1.0.4", 272 | "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", 273 | "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", 274 | "dev": true, 275 | "dependencies": { 276 | "inherits": "^2.0.1", 277 | "safe-buffer": "^5.0.1" 278 | } 279 | }, 280 | "node_modules/color-convert": { 281 | "version": "2.0.1", 282 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 283 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 284 | "dev": true, 285 | "dependencies": { 286 | "color-name": "~1.1.4" 287 | }, 288 | "engines": { 289 | "node": ">=7.0.0" 290 | } 291 | }, 292 | "node_modules/color-name": { 293 | "version": "1.1.4", 294 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 295 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 296 | "dev": true 297 | }, 298 | "node_modules/console-browserify": { 299 | "version": "1.2.0", 300 | "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", 301 | "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", 302 | "dev": true 303 | }, 304 | "node_modules/constants-browserify": { 305 | "version": "1.0.0", 306 | "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", 307 | "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", 308 | "dev": true 309 | }, 310 | "node_modules/core-util-is": { 311 | "version": "1.0.3", 312 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", 313 | "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", 314 | "dev": true 315 | }, 316 | "node_modules/corser": { 317 | "version": "2.0.1", 318 | "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", 319 | "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", 320 | "dev": true, 321 | "engines": { 322 | "node": ">= 0.4.0" 323 | } 324 | }, 325 | "node_modules/create-ecdh": { 326 | "version": "4.0.4", 327 | "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", 328 | "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", 329 | "dev": true, 330 | "dependencies": { 331 | "bn.js": "^4.1.0", 332 | "elliptic": "^6.5.3" 333 | } 334 | }, 335 | "node_modules/create-ecdh/node_modules/bn.js": { 336 | "version": "4.12.0", 337 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", 338 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", 339 | "dev": true 340 | }, 341 | "node_modules/create-hash": { 342 | "version": "1.2.0", 343 | "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", 344 | "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", 345 | "dev": true, 346 | "dependencies": { 347 | "cipher-base": "^1.0.1", 348 | "inherits": "^2.0.1", 349 | "md5.js": "^1.3.4", 350 | "ripemd160": "^2.0.1", 351 | "sha.js": "^2.4.0" 352 | } 353 | }, 354 | "node_modules/create-hmac": { 355 | "version": "1.1.7", 356 | "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", 357 | "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", 358 | "dev": true, 359 | "dependencies": { 360 | "cipher-base": "^1.0.3", 361 | "create-hash": "^1.1.0", 362 | "inherits": "^2.0.1", 363 | "ripemd160": "^2.0.0", 364 | "safe-buffer": "^5.0.1", 365 | "sha.js": "^2.4.8" 366 | } 367 | }, 368 | "node_modules/crypto-browserify": { 369 | "version": "3.12.0", 370 | "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", 371 | "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", 372 | "dev": true, 373 | "dependencies": { 374 | "browserify-cipher": "^1.0.0", 375 | "browserify-sign": "^4.0.0", 376 | "create-ecdh": "^4.0.0", 377 | "create-hash": "^1.1.0", 378 | "create-hmac": "^1.1.0", 379 | "diffie-hellman": "^5.0.0", 380 | "inherits": "^2.0.1", 381 | "pbkdf2": "^3.0.3", 382 | "public-encrypt": "^4.0.0", 383 | "randombytes": "^2.0.0", 384 | "randomfill": "^1.0.3" 385 | }, 386 | "engines": { 387 | "node": "*" 388 | } 389 | }, 390 | "node_modules/dartclojure": { 391 | "resolved": "..", 392 | "link": true 393 | }, 394 | "node_modules/des.js": { 395 | "version": "1.0.1", 396 | "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", 397 | "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", 398 | "dev": true, 399 | "dependencies": { 400 | "inherits": "^2.0.1", 401 | "minimalistic-assert": "^1.0.0" 402 | } 403 | }, 404 | "node_modules/diffie-hellman": { 405 | "version": "5.0.3", 406 | "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", 407 | "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", 408 | "dev": true, 409 | "dependencies": { 410 | "bn.js": "^4.1.0", 411 | "miller-rabin": "^4.0.0", 412 | "randombytes": "^2.0.0" 413 | } 414 | }, 415 | "node_modules/diffie-hellman/node_modules/bn.js": { 416 | "version": "4.12.0", 417 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", 418 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", 419 | "dev": true 420 | }, 421 | "node_modules/domain-browser": { 422 | "version": "1.2.0", 423 | "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", 424 | "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", 425 | "dev": true, 426 | "engines": { 427 | "node": ">=0.4", 428 | "npm": ">=1.2" 429 | } 430 | }, 431 | "node_modules/elliptic": { 432 | "version": "6.5.4", 433 | "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", 434 | "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", 435 | "dev": true, 436 | "dependencies": { 437 | "bn.js": "^4.11.9", 438 | "brorand": "^1.1.0", 439 | "hash.js": "^1.0.0", 440 | "hmac-drbg": "^1.0.1", 441 | "inherits": "^2.0.4", 442 | "minimalistic-assert": "^1.0.1", 443 | "minimalistic-crypto-utils": "^1.0.1" 444 | } 445 | }, 446 | "node_modules/elliptic/node_modules/bn.js": { 447 | "version": "4.12.0", 448 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", 449 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", 450 | "dev": true 451 | }, 452 | "node_modules/eventemitter3": { 453 | "version": "4.0.7", 454 | "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", 455 | "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", 456 | "dev": true 457 | }, 458 | "node_modules/events": { 459 | "version": "3.3.0", 460 | "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", 461 | "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", 462 | "dev": true, 463 | "engines": { 464 | "node": ">=0.8.x" 465 | } 466 | }, 467 | "node_modules/evp_bytestokey": { 468 | "version": "1.0.3", 469 | "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", 470 | "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", 471 | "dev": true, 472 | "dependencies": { 473 | "md5.js": "^1.3.4", 474 | "safe-buffer": "^5.1.1" 475 | } 476 | }, 477 | "node_modules/follow-redirects": { 478 | "version": "1.15.1", 479 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", 480 | "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", 481 | "dev": true, 482 | "funding": [ 483 | { 484 | "type": "individual", 485 | "url": "https://github.com/sponsors/RubenVerborgh" 486 | } 487 | ], 488 | "engines": { 489 | "node": ">=4.0" 490 | }, 491 | "peerDependenciesMeta": { 492 | "debug": { 493 | "optional": true 494 | } 495 | } 496 | }, 497 | "node_modules/function-bind": { 498 | "version": "1.1.1", 499 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 500 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 501 | "dev": true 502 | }, 503 | "node_modules/get-intrinsic": { 504 | "version": "1.1.2", 505 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", 506 | "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", 507 | "dev": true, 508 | "dependencies": { 509 | "function-bind": "^1.1.1", 510 | "has": "^1.0.3", 511 | "has-symbols": "^1.0.3" 512 | }, 513 | "funding": { 514 | "url": "https://github.com/sponsors/ljharb" 515 | } 516 | }, 517 | "node_modules/has": { 518 | "version": "1.0.3", 519 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 520 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 521 | "dev": true, 522 | "dependencies": { 523 | "function-bind": "^1.1.1" 524 | }, 525 | "engines": { 526 | "node": ">= 0.4.0" 527 | } 528 | }, 529 | "node_modules/has-flag": { 530 | "version": "4.0.0", 531 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 532 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 533 | "dev": true, 534 | "engines": { 535 | "node": ">=8" 536 | } 537 | }, 538 | "node_modules/has-symbols": { 539 | "version": "1.0.3", 540 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 541 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 542 | "dev": true, 543 | "engines": { 544 | "node": ">= 0.4" 545 | }, 546 | "funding": { 547 | "url": "https://github.com/sponsors/ljharb" 548 | } 549 | }, 550 | "node_modules/hash-base": { 551 | "version": "3.1.0", 552 | "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", 553 | "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", 554 | "dev": true, 555 | "dependencies": { 556 | "inherits": "^2.0.4", 557 | "readable-stream": "^3.6.0", 558 | "safe-buffer": "^5.2.0" 559 | }, 560 | "engines": { 561 | "node": ">=4" 562 | } 563 | }, 564 | "node_modules/hash-base/node_modules/readable-stream": { 565 | "version": "3.6.0", 566 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 567 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 568 | "dev": true, 569 | "dependencies": { 570 | "inherits": "^2.0.3", 571 | "string_decoder": "^1.1.1", 572 | "util-deprecate": "^1.0.1" 573 | }, 574 | "engines": { 575 | "node": ">= 6" 576 | } 577 | }, 578 | "node_modules/hash-base/node_modules/safe-buffer": { 579 | "version": "5.2.1", 580 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 581 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 582 | "dev": true, 583 | "funding": [ 584 | { 585 | "type": "github", 586 | "url": "https://github.com/sponsors/feross" 587 | }, 588 | { 589 | "type": "patreon", 590 | "url": "https://www.patreon.com/feross" 591 | }, 592 | { 593 | "type": "consulting", 594 | "url": "https://feross.org/support" 595 | } 596 | ] 597 | }, 598 | "node_modules/hash.js": { 599 | "version": "1.1.7", 600 | "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", 601 | "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", 602 | "dev": true, 603 | "dependencies": { 604 | "inherits": "^2.0.3", 605 | "minimalistic-assert": "^1.0.1" 606 | } 607 | }, 608 | "node_modules/he": { 609 | "version": "1.2.0", 610 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 611 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 612 | "dev": true, 613 | "bin": { 614 | "he": "bin/he" 615 | } 616 | }, 617 | "node_modules/hmac-drbg": { 618 | "version": "1.0.1", 619 | "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", 620 | "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", 621 | "dev": true, 622 | "dependencies": { 623 | "hash.js": "^1.0.3", 624 | "minimalistic-assert": "^1.0.0", 625 | "minimalistic-crypto-utils": "^1.0.1" 626 | } 627 | }, 628 | "node_modules/html-encoding-sniffer": { 629 | "version": "3.0.0", 630 | "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", 631 | "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", 632 | "dev": true, 633 | "dependencies": { 634 | "whatwg-encoding": "^2.0.0" 635 | }, 636 | "engines": { 637 | "node": ">=12" 638 | } 639 | }, 640 | "node_modules/http-proxy": { 641 | "version": "1.18.1", 642 | "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", 643 | "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", 644 | "dev": true, 645 | "dependencies": { 646 | "eventemitter3": "^4.0.0", 647 | "follow-redirects": "^1.0.0", 648 | "requires-port": "^1.0.0" 649 | }, 650 | "engines": { 651 | "node": ">=8.0.0" 652 | } 653 | }, 654 | "node_modules/http-server": { 655 | "version": "14.1.1", 656 | "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", 657 | "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", 658 | "dev": true, 659 | "dependencies": { 660 | "basic-auth": "^2.0.1", 661 | "chalk": "^4.1.2", 662 | "corser": "^2.0.1", 663 | "he": "^1.2.0", 664 | "html-encoding-sniffer": "^3.0.0", 665 | "http-proxy": "^1.18.1", 666 | "mime": "^1.6.0", 667 | "minimist": "^1.2.6", 668 | "opener": "^1.5.1", 669 | "portfinder": "^1.0.28", 670 | "secure-compare": "3.0.1", 671 | "union": "~0.5.0", 672 | "url-join": "^4.0.1" 673 | }, 674 | "bin": { 675 | "http-server": "bin/http-server" 676 | }, 677 | "engines": { 678 | "node": ">=12" 679 | } 680 | }, 681 | "node_modules/http-server/node_modules/ansi-styles": { 682 | "version": "4.3.0", 683 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 684 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 685 | "dev": true, 686 | "dependencies": { 687 | "color-convert": "^2.0.1" 688 | }, 689 | "engines": { 690 | "node": ">=8" 691 | }, 692 | "funding": { 693 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 694 | } 695 | }, 696 | "node_modules/http-server/node_modules/chalk": { 697 | "version": "4.1.2", 698 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 699 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 700 | "dev": true, 701 | "dependencies": { 702 | "ansi-styles": "^4.1.0", 703 | "supports-color": "^7.1.0" 704 | }, 705 | "engines": { 706 | "node": ">=10" 707 | }, 708 | "funding": { 709 | "url": "https://github.com/chalk/chalk?sponsor=1" 710 | } 711 | }, 712 | "node_modules/http-server/node_modules/supports-color": { 713 | "version": "7.2.0", 714 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 715 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 716 | "dev": true, 717 | "dependencies": { 718 | "has-flag": "^4.0.0" 719 | }, 720 | "engines": { 721 | "node": ">=8" 722 | } 723 | }, 724 | "node_modules/https-browserify": { 725 | "version": "1.0.0", 726 | "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", 727 | "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", 728 | "dev": true 729 | }, 730 | "node_modules/iconv-lite": { 731 | "version": "0.6.3", 732 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", 733 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", 734 | "dev": true, 735 | "dependencies": { 736 | "safer-buffer": ">= 2.1.2 < 3.0.0" 737 | }, 738 | "engines": { 739 | "node": ">=0.10.0" 740 | } 741 | }, 742 | "node_modules/ieee754": { 743 | "version": "1.2.1", 744 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 745 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 746 | "dev": true, 747 | "funding": [ 748 | { 749 | "type": "github", 750 | "url": "https://github.com/sponsors/feross" 751 | }, 752 | { 753 | "type": "patreon", 754 | "url": "https://www.patreon.com/feross" 755 | }, 756 | { 757 | "type": "consulting", 758 | "url": "https://feross.org/support" 759 | } 760 | ] 761 | }, 762 | "node_modules/inherits": { 763 | "version": "2.0.4", 764 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 765 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 766 | "dev": true 767 | }, 768 | "node_modules/isarray": { 769 | "version": "1.0.0", 770 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 771 | "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", 772 | "dev": true 773 | }, 774 | "node_modules/isexe": { 775 | "version": "2.0.0", 776 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 777 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 778 | "dev": true 779 | }, 780 | "node_modules/lodash": { 781 | "version": "4.17.21", 782 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 783 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 784 | "dev": true 785 | }, 786 | "node_modules/md5.js": { 787 | "version": "1.3.5", 788 | "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", 789 | "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", 790 | "dev": true, 791 | "dependencies": { 792 | "hash-base": "^3.0.0", 793 | "inherits": "^2.0.1", 794 | "safe-buffer": "^5.1.2" 795 | } 796 | }, 797 | "node_modules/miller-rabin": { 798 | "version": "4.0.1", 799 | "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", 800 | "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", 801 | "dev": true, 802 | "dependencies": { 803 | "bn.js": "^4.0.0", 804 | "brorand": "^1.0.1" 805 | }, 806 | "bin": { 807 | "miller-rabin": "bin/miller-rabin" 808 | } 809 | }, 810 | "node_modules/miller-rabin/node_modules/bn.js": { 811 | "version": "4.12.0", 812 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", 813 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", 814 | "dev": true 815 | }, 816 | "node_modules/mime": { 817 | "version": "1.6.0", 818 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 819 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 820 | "dev": true, 821 | "bin": { 822 | "mime": "cli.js" 823 | }, 824 | "engines": { 825 | "node": ">=4" 826 | } 827 | }, 828 | "node_modules/minimalistic-assert": { 829 | "version": "1.0.1", 830 | "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", 831 | "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", 832 | "dev": true 833 | }, 834 | "node_modules/minimalistic-crypto-utils": { 835 | "version": "1.0.1", 836 | "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", 837 | "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", 838 | "dev": true 839 | }, 840 | "node_modules/minimist": { 841 | "version": "1.2.6", 842 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", 843 | "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", 844 | "dev": true 845 | }, 846 | "node_modules/mkdirp": { 847 | "version": "0.5.6", 848 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", 849 | "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", 850 | "dev": true, 851 | "dependencies": { 852 | "minimist": "^1.2.6" 853 | }, 854 | "bin": { 855 | "mkdirp": "bin/cmd.js" 856 | } 857 | }, 858 | "node_modules/node-libs-browser": { 859 | "version": "2.2.1", 860 | "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", 861 | "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", 862 | "dev": true, 863 | "dependencies": { 864 | "assert": "^1.1.1", 865 | "browserify-zlib": "^0.2.0", 866 | "buffer": "^4.3.0", 867 | "console-browserify": "^1.1.0", 868 | "constants-browserify": "^1.0.0", 869 | "crypto-browserify": "^3.11.0", 870 | "domain-browser": "^1.1.1", 871 | "events": "^3.0.0", 872 | "https-browserify": "^1.0.0", 873 | "os-browserify": "^0.3.0", 874 | "path-browserify": "0.0.1", 875 | "process": "^0.11.10", 876 | "punycode": "^1.2.4", 877 | "querystring-es3": "^0.2.0", 878 | "readable-stream": "^2.3.3", 879 | "stream-browserify": "^2.0.1", 880 | "stream-http": "^2.7.2", 881 | "string_decoder": "^1.0.0", 882 | "timers-browserify": "^2.0.4", 883 | "tty-browserify": "0.0.0", 884 | "url": "^0.11.0", 885 | "util": "^0.11.0", 886 | "vm-browserify": "^1.0.1" 887 | } 888 | }, 889 | "node_modules/object-assign": { 890 | "version": "4.1.1", 891 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 892 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 893 | "dev": true, 894 | "engines": { 895 | "node": ">=0.10.0" 896 | } 897 | }, 898 | "node_modules/object-inspect": { 899 | "version": "1.12.2", 900 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", 901 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", 902 | "dev": true, 903 | "funding": { 904 | "url": "https://github.com/sponsors/ljharb" 905 | } 906 | }, 907 | "node_modules/opener": { 908 | "version": "1.5.2", 909 | "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", 910 | "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", 911 | "dev": true, 912 | "bin": { 913 | "opener": "bin/opener-bin.js" 914 | } 915 | }, 916 | "node_modules/os-browserify": { 917 | "version": "0.3.0", 918 | "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", 919 | "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", 920 | "dev": true 921 | }, 922 | "node_modules/pako": { 923 | "version": "1.0.11", 924 | "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", 925 | "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", 926 | "dev": true 927 | }, 928 | "node_modules/parse-asn1": { 929 | "version": "5.1.6", 930 | "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", 931 | "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", 932 | "dev": true, 933 | "dependencies": { 934 | "asn1.js": "^5.2.0", 935 | "browserify-aes": "^1.0.0", 936 | "evp_bytestokey": "^1.0.0", 937 | "pbkdf2": "^3.0.3", 938 | "safe-buffer": "^5.1.1" 939 | } 940 | }, 941 | "node_modules/path-browserify": { 942 | "version": "0.0.1", 943 | "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", 944 | "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", 945 | "dev": true 946 | }, 947 | "node_modules/pbkdf2": { 948 | "version": "3.1.2", 949 | "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", 950 | "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", 951 | "dev": true, 952 | "dependencies": { 953 | "create-hash": "^1.1.2", 954 | "create-hmac": "^1.1.4", 955 | "ripemd160": "^2.0.1", 956 | "safe-buffer": "^5.0.1", 957 | "sha.js": "^2.4.8" 958 | }, 959 | "engines": { 960 | "node": ">=0.12" 961 | } 962 | }, 963 | "node_modules/portfinder": { 964 | "version": "1.0.28", 965 | "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", 966 | "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", 967 | "dev": true, 968 | "dependencies": { 969 | "async": "^2.6.2", 970 | "debug": "^3.1.1", 971 | "mkdirp": "^0.5.5" 972 | }, 973 | "engines": { 974 | "node": ">= 0.12.0" 975 | } 976 | }, 977 | "node_modules/portfinder/node_modules/debug": { 978 | "version": "3.2.7", 979 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", 980 | "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", 981 | "dev": true, 982 | "dependencies": { 983 | "ms": "^2.1.1" 984 | } 985 | }, 986 | "node_modules/portfinder/node_modules/ms": { 987 | "version": "2.1.3", 988 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 989 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 990 | "dev": true 991 | }, 992 | "node_modules/process": { 993 | "version": "0.11.10", 994 | "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", 995 | "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", 996 | "dev": true, 997 | "engines": { 998 | "node": ">= 0.6.0" 999 | } 1000 | }, 1001 | "node_modules/process-nextick-args": { 1002 | "version": "2.0.1", 1003 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 1004 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", 1005 | "dev": true 1006 | }, 1007 | "node_modules/public-encrypt": { 1008 | "version": "4.0.3", 1009 | "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", 1010 | "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", 1011 | "dev": true, 1012 | "dependencies": { 1013 | "bn.js": "^4.1.0", 1014 | "browserify-rsa": "^4.0.0", 1015 | "create-hash": "^1.1.0", 1016 | "parse-asn1": "^5.0.0", 1017 | "randombytes": "^2.0.1", 1018 | "safe-buffer": "^5.1.2" 1019 | } 1020 | }, 1021 | "node_modules/public-encrypt/node_modules/bn.js": { 1022 | "version": "4.12.0", 1023 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", 1024 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", 1025 | "dev": true 1026 | }, 1027 | "node_modules/punycode": { 1028 | "version": "1.4.1", 1029 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 1030 | "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", 1031 | "dev": true 1032 | }, 1033 | "node_modules/qs": { 1034 | "version": "6.10.5", 1035 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.5.tgz", 1036 | "integrity": "sha512-O5RlPh0VFtR78y79rgcgKK4wbAI0C5zGVLztOIdpWX6ep368q5Hv6XRxDvXuZ9q3C6v+e3n8UfZZJw7IIG27eQ==", 1037 | "dev": true, 1038 | "dependencies": { 1039 | "side-channel": "^1.0.4" 1040 | }, 1041 | "engines": { 1042 | "node": ">=0.6" 1043 | }, 1044 | "funding": { 1045 | "url": "https://github.com/sponsors/ljharb" 1046 | } 1047 | }, 1048 | "node_modules/querystring": { 1049 | "version": "0.2.0", 1050 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", 1051 | "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", 1052 | "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", 1053 | "dev": true, 1054 | "engines": { 1055 | "node": ">=0.4.x" 1056 | } 1057 | }, 1058 | "node_modules/querystring-es3": { 1059 | "version": "0.2.1", 1060 | "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", 1061 | "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", 1062 | "dev": true, 1063 | "engines": { 1064 | "node": ">=0.4.x" 1065 | } 1066 | }, 1067 | "node_modules/randombytes": { 1068 | "version": "2.1.0", 1069 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 1070 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 1071 | "dev": true, 1072 | "dependencies": { 1073 | "safe-buffer": "^5.1.0" 1074 | } 1075 | }, 1076 | "node_modules/randomfill": { 1077 | "version": "1.0.4", 1078 | "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", 1079 | "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", 1080 | "dev": true, 1081 | "dependencies": { 1082 | "randombytes": "^2.0.5", 1083 | "safe-buffer": "^5.1.0" 1084 | } 1085 | }, 1086 | "node_modules/readable-stream": { 1087 | "version": "2.3.7", 1088 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 1089 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 1090 | "dev": true, 1091 | "dependencies": { 1092 | "core-util-is": "~1.0.0", 1093 | "inherits": "~2.0.3", 1094 | "isarray": "~1.0.0", 1095 | "process-nextick-args": "~2.0.0", 1096 | "safe-buffer": "~5.1.1", 1097 | "string_decoder": "~1.1.1", 1098 | "util-deprecate": "~1.0.1" 1099 | } 1100 | }, 1101 | "node_modules/readline-sync": { 1102 | "version": "1.4.10", 1103 | "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz", 1104 | "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==", 1105 | "dev": true, 1106 | "engines": { 1107 | "node": ">= 0.8.0" 1108 | } 1109 | }, 1110 | "node_modules/requires-port": { 1111 | "version": "1.0.0", 1112 | "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", 1113 | "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", 1114 | "dev": true 1115 | }, 1116 | "node_modules/ripemd160": { 1117 | "version": "2.0.2", 1118 | "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", 1119 | "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", 1120 | "dev": true, 1121 | "dependencies": { 1122 | "hash-base": "^3.0.0", 1123 | "inherits": "^2.0.1" 1124 | } 1125 | }, 1126 | "node_modules/safe-buffer": { 1127 | "version": "5.1.2", 1128 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1129 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 1130 | "dev": true 1131 | }, 1132 | "node_modules/safer-buffer": { 1133 | "version": "2.1.2", 1134 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1135 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 1136 | "dev": true 1137 | }, 1138 | "node_modules/secure-compare": { 1139 | "version": "3.0.1", 1140 | "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", 1141 | "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==", 1142 | "dev": true 1143 | }, 1144 | "node_modules/setimmediate": { 1145 | "version": "1.0.5", 1146 | "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", 1147 | "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", 1148 | "dev": true 1149 | }, 1150 | "node_modules/sha.js": { 1151 | "version": "2.4.11", 1152 | "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", 1153 | "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", 1154 | "dev": true, 1155 | "dependencies": { 1156 | "inherits": "^2.0.1", 1157 | "safe-buffer": "^5.0.1" 1158 | }, 1159 | "bin": { 1160 | "sha.js": "bin.js" 1161 | } 1162 | }, 1163 | "node_modules/shadow-cljs": { 1164 | "version": "2.19.3", 1165 | "resolved": "https://registry.npmjs.org/shadow-cljs/-/shadow-cljs-2.19.3.tgz", 1166 | "integrity": "sha512-9TsTCRlmR8m1g2ekwblgomRUgJpbifQI99VlRrlH9NMqEzklev3zYAD1dvy4d5h8BoAhgdxOOEg7ld2d45CWTA==", 1167 | "dev": true, 1168 | "dependencies": { 1169 | "node-libs-browser": "^2.2.1", 1170 | "readline-sync": "^1.4.7", 1171 | "shadow-cljs-jar": "1.3.2", 1172 | "source-map-support": "^0.4.15", 1173 | "which": "^1.3.1", 1174 | "ws": "^7.4.6" 1175 | }, 1176 | "bin": { 1177 | "shadow-cljs": "cli/runner.js" 1178 | }, 1179 | "engines": { 1180 | "node": ">=6.0.0" 1181 | } 1182 | }, 1183 | "node_modules/shadow-cljs-jar": { 1184 | "version": "1.3.2", 1185 | "resolved": "https://registry.npmjs.org/shadow-cljs-jar/-/shadow-cljs-jar-1.3.2.tgz", 1186 | "integrity": "sha512-XmeffAZHv8z7451kzeq9oKh8fh278Ak+UIOGGrapyqrFBB773xN8vMQ3O7J7TYLnb9BUwcqadKkmgaq7q6fhZg==", 1187 | "dev": true 1188 | }, 1189 | "node_modules/side-channel": { 1190 | "version": "1.0.4", 1191 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 1192 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 1193 | "dev": true, 1194 | "dependencies": { 1195 | "call-bind": "^1.0.0", 1196 | "get-intrinsic": "^1.0.2", 1197 | "object-inspect": "^1.9.0" 1198 | }, 1199 | "funding": { 1200 | "url": "https://github.com/sponsors/ljharb" 1201 | } 1202 | }, 1203 | "node_modules/source-map": { 1204 | "version": "0.5.7", 1205 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 1206 | "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", 1207 | "dev": true, 1208 | "engines": { 1209 | "node": ">=0.10.0" 1210 | } 1211 | }, 1212 | "node_modules/source-map-support": { 1213 | "version": "0.4.18", 1214 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", 1215 | "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", 1216 | "dev": true, 1217 | "dependencies": { 1218 | "source-map": "^0.5.6" 1219 | } 1220 | }, 1221 | "node_modules/stream-browserify": { 1222 | "version": "2.0.2", 1223 | "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", 1224 | "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", 1225 | "dev": true, 1226 | "dependencies": { 1227 | "inherits": "~2.0.1", 1228 | "readable-stream": "^2.0.2" 1229 | } 1230 | }, 1231 | "node_modules/stream-http": { 1232 | "version": "2.8.3", 1233 | "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", 1234 | "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", 1235 | "dev": true, 1236 | "dependencies": { 1237 | "builtin-status-codes": "^3.0.0", 1238 | "inherits": "^2.0.1", 1239 | "readable-stream": "^2.3.6", 1240 | "to-arraybuffer": "^1.0.0", 1241 | "xtend": "^4.0.0" 1242 | } 1243 | }, 1244 | "node_modules/string_decoder": { 1245 | "version": "1.1.1", 1246 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 1247 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 1248 | "dev": true, 1249 | "dependencies": { 1250 | "safe-buffer": "~5.1.0" 1251 | } 1252 | }, 1253 | "node_modules/timers-browserify": { 1254 | "version": "2.0.12", 1255 | "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", 1256 | "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", 1257 | "dev": true, 1258 | "dependencies": { 1259 | "setimmediate": "^1.0.4" 1260 | }, 1261 | "engines": { 1262 | "node": ">=0.6.0" 1263 | } 1264 | }, 1265 | "node_modules/to-arraybuffer": { 1266 | "version": "1.0.1", 1267 | "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", 1268 | "integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==", 1269 | "dev": true 1270 | }, 1271 | "node_modules/tty-browserify": { 1272 | "version": "0.0.0", 1273 | "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", 1274 | "integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==", 1275 | "dev": true 1276 | }, 1277 | "node_modules/union": { 1278 | "version": "0.5.0", 1279 | "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", 1280 | "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", 1281 | "dev": true, 1282 | "dependencies": { 1283 | "qs": "^6.4.0" 1284 | }, 1285 | "engines": { 1286 | "node": ">= 0.8.0" 1287 | } 1288 | }, 1289 | "node_modules/url": { 1290 | "version": "0.11.0", 1291 | "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", 1292 | "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", 1293 | "dev": true, 1294 | "dependencies": { 1295 | "punycode": "1.3.2", 1296 | "querystring": "0.2.0" 1297 | } 1298 | }, 1299 | "node_modules/url-join": { 1300 | "version": "4.0.1", 1301 | "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", 1302 | "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", 1303 | "dev": true 1304 | }, 1305 | "node_modules/url/node_modules/punycode": { 1306 | "version": "1.3.2", 1307 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", 1308 | "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", 1309 | "dev": true 1310 | }, 1311 | "node_modules/util": { 1312 | "version": "0.11.1", 1313 | "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", 1314 | "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", 1315 | "dev": true, 1316 | "dependencies": { 1317 | "inherits": "2.0.3" 1318 | } 1319 | }, 1320 | "node_modules/util-deprecate": { 1321 | "version": "1.0.2", 1322 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1323 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", 1324 | "dev": true 1325 | }, 1326 | "node_modules/util/node_modules/inherits": { 1327 | "version": "2.0.3", 1328 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 1329 | "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", 1330 | "dev": true 1331 | }, 1332 | "node_modules/vm-browserify": { 1333 | "version": "1.1.2", 1334 | "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", 1335 | "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", 1336 | "dev": true 1337 | }, 1338 | "node_modules/whatwg-encoding": { 1339 | "version": "2.0.0", 1340 | "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", 1341 | "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", 1342 | "dev": true, 1343 | "dependencies": { 1344 | "iconv-lite": "0.6.3" 1345 | }, 1346 | "engines": { 1347 | "node": ">=12" 1348 | } 1349 | }, 1350 | "node_modules/which": { 1351 | "version": "1.3.1", 1352 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 1353 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 1354 | "dev": true, 1355 | "dependencies": { 1356 | "isexe": "^2.0.0" 1357 | }, 1358 | "bin": { 1359 | "which": "bin/which" 1360 | } 1361 | }, 1362 | "node_modules/ws": { 1363 | "version": "7.5.8", 1364 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.8.tgz", 1365 | "integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==", 1366 | "dev": true, 1367 | "engines": { 1368 | "node": ">=8.3.0" 1369 | }, 1370 | "peerDependencies": { 1371 | "bufferutil": "^4.0.1", 1372 | "utf-8-validate": "^5.0.2" 1373 | }, 1374 | "peerDependenciesMeta": { 1375 | "bufferutil": { 1376 | "optional": true 1377 | }, 1378 | "utf-8-validate": { 1379 | "optional": true 1380 | } 1381 | } 1382 | }, 1383 | "node_modules/xtend": { 1384 | "version": "4.0.2", 1385 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", 1386 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", 1387 | "dev": true, 1388 | "engines": { 1389 | "node": ">=0.4" 1390 | } 1391 | } 1392 | }, 1393 | "dependencies": { 1394 | "asn1.js": { 1395 | "version": "5.4.1", 1396 | "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", 1397 | "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", 1398 | "dev": true, 1399 | "requires": { 1400 | "bn.js": "^4.0.0", 1401 | "inherits": "^2.0.1", 1402 | "minimalistic-assert": "^1.0.0", 1403 | "safer-buffer": "^2.1.0" 1404 | }, 1405 | "dependencies": { 1406 | "bn.js": { 1407 | "version": "4.12.0", 1408 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", 1409 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", 1410 | "dev": true 1411 | } 1412 | } 1413 | }, 1414 | "assert": { 1415 | "version": "1.5.0", 1416 | "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", 1417 | "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", 1418 | "dev": true, 1419 | "requires": { 1420 | "object-assign": "^4.1.1", 1421 | "util": "0.10.3" 1422 | }, 1423 | "dependencies": { 1424 | "inherits": { 1425 | "version": "2.0.1", 1426 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", 1427 | "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==", 1428 | "dev": true 1429 | }, 1430 | "util": { 1431 | "version": "0.10.3", 1432 | "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", 1433 | "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==", 1434 | "dev": true, 1435 | "requires": { 1436 | "inherits": "2.0.1" 1437 | } 1438 | } 1439 | } 1440 | }, 1441 | "async": { 1442 | "version": "2.6.4", 1443 | "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", 1444 | "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", 1445 | "dev": true, 1446 | "requires": { 1447 | "lodash": "^4.17.14" 1448 | } 1449 | }, 1450 | "base64-js": { 1451 | "version": "1.5.1", 1452 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 1453 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 1454 | "dev": true 1455 | }, 1456 | "basic-auth": { 1457 | "version": "2.0.1", 1458 | "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", 1459 | "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", 1460 | "dev": true, 1461 | "requires": { 1462 | "safe-buffer": "5.1.2" 1463 | } 1464 | }, 1465 | "bn.js": { 1466 | "version": "5.2.1", 1467 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", 1468 | "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", 1469 | "dev": true 1470 | }, 1471 | "brorand": { 1472 | "version": "1.1.0", 1473 | "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", 1474 | "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", 1475 | "dev": true 1476 | }, 1477 | "browserify-aes": { 1478 | "version": "1.2.0", 1479 | "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", 1480 | "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", 1481 | "dev": true, 1482 | "requires": { 1483 | "buffer-xor": "^1.0.3", 1484 | "cipher-base": "^1.0.0", 1485 | "create-hash": "^1.1.0", 1486 | "evp_bytestokey": "^1.0.3", 1487 | "inherits": "^2.0.1", 1488 | "safe-buffer": "^5.0.1" 1489 | } 1490 | }, 1491 | "browserify-cipher": { 1492 | "version": "1.0.1", 1493 | "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", 1494 | "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", 1495 | "dev": true, 1496 | "requires": { 1497 | "browserify-aes": "^1.0.4", 1498 | "browserify-des": "^1.0.0", 1499 | "evp_bytestokey": "^1.0.0" 1500 | } 1501 | }, 1502 | "browserify-des": { 1503 | "version": "1.0.2", 1504 | "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", 1505 | "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", 1506 | "dev": true, 1507 | "requires": { 1508 | "cipher-base": "^1.0.1", 1509 | "des.js": "^1.0.0", 1510 | "inherits": "^2.0.1", 1511 | "safe-buffer": "^5.1.2" 1512 | } 1513 | }, 1514 | "browserify-rsa": { 1515 | "version": "4.1.0", 1516 | "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", 1517 | "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", 1518 | "dev": true, 1519 | "requires": { 1520 | "bn.js": "^5.0.0", 1521 | "randombytes": "^2.0.1" 1522 | } 1523 | }, 1524 | "browserify-sign": { 1525 | "version": "4.2.1", 1526 | "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", 1527 | "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", 1528 | "dev": true, 1529 | "requires": { 1530 | "bn.js": "^5.1.1", 1531 | "browserify-rsa": "^4.0.1", 1532 | "create-hash": "^1.2.0", 1533 | "create-hmac": "^1.1.7", 1534 | "elliptic": "^6.5.3", 1535 | "inherits": "^2.0.4", 1536 | "parse-asn1": "^5.1.5", 1537 | "readable-stream": "^3.6.0", 1538 | "safe-buffer": "^5.2.0" 1539 | }, 1540 | "dependencies": { 1541 | "readable-stream": { 1542 | "version": "3.6.0", 1543 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 1544 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 1545 | "dev": true, 1546 | "requires": { 1547 | "inherits": "^2.0.3", 1548 | "string_decoder": "^1.1.1", 1549 | "util-deprecate": "^1.0.1" 1550 | } 1551 | }, 1552 | "safe-buffer": { 1553 | "version": "5.2.1", 1554 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1555 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1556 | "dev": true 1557 | } 1558 | } 1559 | }, 1560 | "browserify-zlib": { 1561 | "version": "0.2.0", 1562 | "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", 1563 | "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", 1564 | "dev": true, 1565 | "requires": { 1566 | "pako": "~1.0.5" 1567 | } 1568 | }, 1569 | "buffer": { 1570 | "version": "4.9.2", 1571 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", 1572 | "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", 1573 | "dev": true, 1574 | "requires": { 1575 | "base64-js": "^1.0.2", 1576 | "ieee754": "^1.1.4", 1577 | "isarray": "^1.0.0" 1578 | } 1579 | }, 1580 | "buffer-xor": { 1581 | "version": "1.0.3", 1582 | "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", 1583 | "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", 1584 | "dev": true 1585 | }, 1586 | "builtin-status-codes": { 1587 | "version": "3.0.0", 1588 | "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", 1589 | "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", 1590 | "dev": true 1591 | }, 1592 | "call-bind": { 1593 | "version": "1.0.2", 1594 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 1595 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 1596 | "dev": true, 1597 | "requires": { 1598 | "function-bind": "^1.1.1", 1599 | "get-intrinsic": "^1.0.2" 1600 | } 1601 | }, 1602 | "cipher-base": { 1603 | "version": "1.0.4", 1604 | "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", 1605 | "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", 1606 | "dev": true, 1607 | "requires": { 1608 | "inherits": "^2.0.1", 1609 | "safe-buffer": "^5.0.1" 1610 | } 1611 | }, 1612 | "color-convert": { 1613 | "version": "2.0.1", 1614 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1615 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1616 | "dev": true, 1617 | "requires": { 1618 | "color-name": "~1.1.4" 1619 | } 1620 | }, 1621 | "color-name": { 1622 | "version": "1.1.4", 1623 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1624 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 1625 | "dev": true 1626 | }, 1627 | "console-browserify": { 1628 | "version": "1.2.0", 1629 | "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", 1630 | "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", 1631 | "dev": true 1632 | }, 1633 | "constants-browserify": { 1634 | "version": "1.0.0", 1635 | "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", 1636 | "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", 1637 | "dev": true 1638 | }, 1639 | "core-util-is": { 1640 | "version": "1.0.3", 1641 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", 1642 | "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", 1643 | "dev": true 1644 | }, 1645 | "corser": { 1646 | "version": "2.0.1", 1647 | "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", 1648 | "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", 1649 | "dev": true 1650 | }, 1651 | "create-ecdh": { 1652 | "version": "4.0.4", 1653 | "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", 1654 | "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", 1655 | "dev": true, 1656 | "requires": { 1657 | "bn.js": "^4.1.0", 1658 | "elliptic": "^6.5.3" 1659 | }, 1660 | "dependencies": { 1661 | "bn.js": { 1662 | "version": "4.12.0", 1663 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", 1664 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", 1665 | "dev": true 1666 | } 1667 | } 1668 | }, 1669 | "create-hash": { 1670 | "version": "1.2.0", 1671 | "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", 1672 | "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", 1673 | "dev": true, 1674 | "requires": { 1675 | "cipher-base": "^1.0.1", 1676 | "inherits": "^2.0.1", 1677 | "md5.js": "^1.3.4", 1678 | "ripemd160": "^2.0.1", 1679 | "sha.js": "^2.4.0" 1680 | } 1681 | }, 1682 | "create-hmac": { 1683 | "version": "1.1.7", 1684 | "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", 1685 | "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", 1686 | "dev": true, 1687 | "requires": { 1688 | "cipher-base": "^1.0.3", 1689 | "create-hash": "^1.1.0", 1690 | "inherits": "^2.0.1", 1691 | "ripemd160": "^2.0.0", 1692 | "safe-buffer": "^5.0.1", 1693 | "sha.js": "^2.4.8" 1694 | } 1695 | }, 1696 | "crypto-browserify": { 1697 | "version": "3.12.0", 1698 | "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", 1699 | "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", 1700 | "dev": true, 1701 | "requires": { 1702 | "browserify-cipher": "^1.0.0", 1703 | "browserify-sign": "^4.0.0", 1704 | "create-ecdh": "^4.0.0", 1705 | "create-hash": "^1.1.0", 1706 | "create-hmac": "^1.1.0", 1707 | "diffie-hellman": "^5.0.0", 1708 | "inherits": "^2.0.1", 1709 | "pbkdf2": "^3.0.3", 1710 | "public-encrypt": "^4.0.0", 1711 | "randombytes": "^2.0.0", 1712 | "randomfill": "^1.0.3" 1713 | } 1714 | }, 1715 | "dartclojure": { 1716 | "version": "file:..", 1717 | "requires": { 1718 | "rimraf": "3.0.2", 1719 | "shadow-cljs": "^2.19.3" 1720 | } 1721 | }, 1722 | "des.js": { 1723 | "version": "1.0.1", 1724 | "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", 1725 | "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", 1726 | "dev": true, 1727 | "requires": { 1728 | "inherits": "^2.0.1", 1729 | "minimalistic-assert": "^1.0.0" 1730 | } 1731 | }, 1732 | "diffie-hellman": { 1733 | "version": "5.0.3", 1734 | "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", 1735 | "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", 1736 | "dev": true, 1737 | "requires": { 1738 | "bn.js": "^4.1.0", 1739 | "miller-rabin": "^4.0.0", 1740 | "randombytes": "^2.0.0" 1741 | }, 1742 | "dependencies": { 1743 | "bn.js": { 1744 | "version": "4.12.0", 1745 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", 1746 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", 1747 | "dev": true 1748 | } 1749 | } 1750 | }, 1751 | "domain-browser": { 1752 | "version": "1.2.0", 1753 | "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", 1754 | "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", 1755 | "dev": true 1756 | }, 1757 | "elliptic": { 1758 | "version": "6.5.4", 1759 | "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", 1760 | "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", 1761 | "dev": true, 1762 | "requires": { 1763 | "bn.js": "^4.11.9", 1764 | "brorand": "^1.1.0", 1765 | "hash.js": "^1.0.0", 1766 | "hmac-drbg": "^1.0.1", 1767 | "inherits": "^2.0.4", 1768 | "minimalistic-assert": "^1.0.1", 1769 | "minimalistic-crypto-utils": "^1.0.1" 1770 | }, 1771 | "dependencies": { 1772 | "bn.js": { 1773 | "version": "4.12.0", 1774 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", 1775 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", 1776 | "dev": true 1777 | } 1778 | } 1779 | }, 1780 | "eventemitter3": { 1781 | "version": "4.0.7", 1782 | "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", 1783 | "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", 1784 | "dev": true 1785 | }, 1786 | "events": { 1787 | "version": "3.3.0", 1788 | "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", 1789 | "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", 1790 | "dev": true 1791 | }, 1792 | "evp_bytestokey": { 1793 | "version": "1.0.3", 1794 | "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", 1795 | "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", 1796 | "dev": true, 1797 | "requires": { 1798 | "md5.js": "^1.3.4", 1799 | "safe-buffer": "^5.1.1" 1800 | } 1801 | }, 1802 | "follow-redirects": { 1803 | "version": "1.15.1", 1804 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", 1805 | "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", 1806 | "dev": true 1807 | }, 1808 | "function-bind": { 1809 | "version": "1.1.1", 1810 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 1811 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 1812 | "dev": true 1813 | }, 1814 | "get-intrinsic": { 1815 | "version": "1.1.2", 1816 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", 1817 | "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", 1818 | "dev": true, 1819 | "requires": { 1820 | "function-bind": "^1.1.1", 1821 | "has": "^1.0.3", 1822 | "has-symbols": "^1.0.3" 1823 | } 1824 | }, 1825 | "has": { 1826 | "version": "1.0.3", 1827 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 1828 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 1829 | "dev": true, 1830 | "requires": { 1831 | "function-bind": "^1.1.1" 1832 | } 1833 | }, 1834 | "has-flag": { 1835 | "version": "4.0.0", 1836 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1837 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1838 | "dev": true 1839 | }, 1840 | "has-symbols": { 1841 | "version": "1.0.3", 1842 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 1843 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 1844 | "dev": true 1845 | }, 1846 | "hash-base": { 1847 | "version": "3.1.0", 1848 | "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", 1849 | "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", 1850 | "dev": true, 1851 | "requires": { 1852 | "inherits": "^2.0.4", 1853 | "readable-stream": "^3.6.0", 1854 | "safe-buffer": "^5.2.0" 1855 | }, 1856 | "dependencies": { 1857 | "readable-stream": { 1858 | "version": "3.6.0", 1859 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 1860 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 1861 | "dev": true, 1862 | "requires": { 1863 | "inherits": "^2.0.3", 1864 | "string_decoder": "^1.1.1", 1865 | "util-deprecate": "^1.0.1" 1866 | } 1867 | }, 1868 | "safe-buffer": { 1869 | "version": "5.2.1", 1870 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1871 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1872 | "dev": true 1873 | } 1874 | } 1875 | }, 1876 | "hash.js": { 1877 | "version": "1.1.7", 1878 | "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", 1879 | "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", 1880 | "dev": true, 1881 | "requires": { 1882 | "inherits": "^2.0.3", 1883 | "minimalistic-assert": "^1.0.1" 1884 | } 1885 | }, 1886 | "he": { 1887 | "version": "1.2.0", 1888 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 1889 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 1890 | "dev": true 1891 | }, 1892 | "hmac-drbg": { 1893 | "version": "1.0.1", 1894 | "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", 1895 | "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", 1896 | "dev": true, 1897 | "requires": { 1898 | "hash.js": "^1.0.3", 1899 | "minimalistic-assert": "^1.0.0", 1900 | "minimalistic-crypto-utils": "^1.0.1" 1901 | } 1902 | }, 1903 | "html-encoding-sniffer": { 1904 | "version": "3.0.0", 1905 | "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", 1906 | "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", 1907 | "dev": true, 1908 | "requires": { 1909 | "whatwg-encoding": "^2.0.0" 1910 | } 1911 | }, 1912 | "http-proxy": { 1913 | "version": "1.18.1", 1914 | "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", 1915 | "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", 1916 | "dev": true, 1917 | "requires": { 1918 | "eventemitter3": "^4.0.0", 1919 | "follow-redirects": "^1.0.0", 1920 | "requires-port": "^1.0.0" 1921 | } 1922 | }, 1923 | "http-server": { 1924 | "version": "14.1.1", 1925 | "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", 1926 | "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", 1927 | "dev": true, 1928 | "requires": { 1929 | "basic-auth": "^2.0.1", 1930 | "chalk": "^4.1.2", 1931 | "corser": "^2.0.1", 1932 | "he": "^1.2.0", 1933 | "html-encoding-sniffer": "^3.0.0", 1934 | "http-proxy": "^1.18.1", 1935 | "mime": "^1.6.0", 1936 | "minimist": "^1.2.6", 1937 | "opener": "^1.5.1", 1938 | "portfinder": "^1.0.28", 1939 | "secure-compare": "3.0.1", 1940 | "union": "~0.5.0", 1941 | "url-join": "^4.0.1" 1942 | }, 1943 | "dependencies": { 1944 | "ansi-styles": { 1945 | "version": "4.3.0", 1946 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 1947 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 1948 | "dev": true, 1949 | "requires": { 1950 | "color-convert": "^2.0.1" 1951 | } 1952 | }, 1953 | "chalk": { 1954 | "version": "4.1.2", 1955 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 1956 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 1957 | "dev": true, 1958 | "requires": { 1959 | "ansi-styles": "^4.1.0", 1960 | "supports-color": "^7.1.0" 1961 | } 1962 | }, 1963 | "supports-color": { 1964 | "version": "7.2.0", 1965 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1966 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1967 | "dev": true, 1968 | "requires": { 1969 | "has-flag": "^4.0.0" 1970 | } 1971 | } 1972 | } 1973 | }, 1974 | "https-browserify": { 1975 | "version": "1.0.0", 1976 | "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", 1977 | "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", 1978 | "dev": true 1979 | }, 1980 | "iconv-lite": { 1981 | "version": "0.6.3", 1982 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", 1983 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", 1984 | "dev": true, 1985 | "requires": { 1986 | "safer-buffer": ">= 2.1.2 < 3.0.0" 1987 | } 1988 | }, 1989 | "ieee754": { 1990 | "version": "1.2.1", 1991 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 1992 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 1993 | "dev": true 1994 | }, 1995 | "inherits": { 1996 | "version": "2.0.4", 1997 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1998 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1999 | "dev": true 2000 | }, 2001 | "isarray": { 2002 | "version": "1.0.0", 2003 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 2004 | "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", 2005 | "dev": true 2006 | }, 2007 | "isexe": { 2008 | "version": "2.0.0", 2009 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 2010 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 2011 | "dev": true 2012 | }, 2013 | "lodash": { 2014 | "version": "4.17.21", 2015 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 2016 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 2017 | "dev": true 2018 | }, 2019 | "md5.js": { 2020 | "version": "1.3.5", 2021 | "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", 2022 | "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", 2023 | "dev": true, 2024 | "requires": { 2025 | "hash-base": "^3.0.0", 2026 | "inherits": "^2.0.1", 2027 | "safe-buffer": "^5.1.2" 2028 | } 2029 | }, 2030 | "miller-rabin": { 2031 | "version": "4.0.1", 2032 | "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", 2033 | "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", 2034 | "dev": true, 2035 | "requires": { 2036 | "bn.js": "^4.0.0", 2037 | "brorand": "^1.0.1" 2038 | }, 2039 | "dependencies": { 2040 | "bn.js": { 2041 | "version": "4.12.0", 2042 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", 2043 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", 2044 | "dev": true 2045 | } 2046 | } 2047 | }, 2048 | "mime": { 2049 | "version": "1.6.0", 2050 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 2051 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 2052 | "dev": true 2053 | }, 2054 | "minimalistic-assert": { 2055 | "version": "1.0.1", 2056 | "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", 2057 | "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", 2058 | "dev": true 2059 | }, 2060 | "minimalistic-crypto-utils": { 2061 | "version": "1.0.1", 2062 | "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", 2063 | "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", 2064 | "dev": true 2065 | }, 2066 | "minimist": { 2067 | "version": "1.2.6", 2068 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", 2069 | "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", 2070 | "dev": true 2071 | }, 2072 | "mkdirp": { 2073 | "version": "0.5.6", 2074 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", 2075 | "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", 2076 | "dev": true, 2077 | "requires": { 2078 | "minimist": "^1.2.6" 2079 | } 2080 | }, 2081 | "node-libs-browser": { 2082 | "version": "2.2.1", 2083 | "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", 2084 | "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", 2085 | "dev": true, 2086 | "requires": { 2087 | "assert": "^1.1.1", 2088 | "browserify-zlib": "^0.2.0", 2089 | "buffer": "^4.3.0", 2090 | "console-browserify": "^1.1.0", 2091 | "constants-browserify": "^1.0.0", 2092 | "crypto-browserify": "^3.11.0", 2093 | "domain-browser": "^1.1.1", 2094 | "events": "^3.0.0", 2095 | "https-browserify": "^1.0.0", 2096 | "os-browserify": "^0.3.0", 2097 | "path-browserify": "0.0.1", 2098 | "process": "^0.11.10", 2099 | "punycode": "^1.2.4", 2100 | "querystring-es3": "^0.2.0", 2101 | "readable-stream": "^2.3.3", 2102 | "stream-browserify": "^2.0.1", 2103 | "stream-http": "^2.7.2", 2104 | "string_decoder": "^1.0.0", 2105 | "timers-browserify": "^2.0.4", 2106 | "tty-browserify": "0.0.0", 2107 | "url": "^0.11.0", 2108 | "util": "^0.11.0", 2109 | "vm-browserify": "^1.0.1" 2110 | } 2111 | }, 2112 | "object-assign": { 2113 | "version": "4.1.1", 2114 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 2115 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 2116 | "dev": true 2117 | }, 2118 | "object-inspect": { 2119 | "version": "1.12.2", 2120 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", 2121 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", 2122 | "dev": true 2123 | }, 2124 | "opener": { 2125 | "version": "1.5.2", 2126 | "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", 2127 | "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", 2128 | "dev": true 2129 | }, 2130 | "os-browserify": { 2131 | "version": "0.3.0", 2132 | "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", 2133 | "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", 2134 | "dev": true 2135 | }, 2136 | "pako": { 2137 | "version": "1.0.11", 2138 | "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", 2139 | "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", 2140 | "dev": true 2141 | }, 2142 | "parse-asn1": { 2143 | "version": "5.1.6", 2144 | "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", 2145 | "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", 2146 | "dev": true, 2147 | "requires": { 2148 | "asn1.js": "^5.2.0", 2149 | "browserify-aes": "^1.0.0", 2150 | "evp_bytestokey": "^1.0.0", 2151 | "pbkdf2": "^3.0.3", 2152 | "safe-buffer": "^5.1.1" 2153 | } 2154 | }, 2155 | "path-browserify": { 2156 | "version": "0.0.1", 2157 | "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", 2158 | "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", 2159 | "dev": true 2160 | }, 2161 | "pbkdf2": { 2162 | "version": "3.1.2", 2163 | "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", 2164 | "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", 2165 | "dev": true, 2166 | "requires": { 2167 | "create-hash": "^1.1.2", 2168 | "create-hmac": "^1.1.4", 2169 | "ripemd160": "^2.0.1", 2170 | "safe-buffer": "^5.0.1", 2171 | "sha.js": "^2.4.8" 2172 | } 2173 | }, 2174 | "portfinder": { 2175 | "version": "1.0.28", 2176 | "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", 2177 | "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", 2178 | "dev": true, 2179 | "requires": { 2180 | "async": "^2.6.2", 2181 | "debug": "^3.1.1", 2182 | "mkdirp": "^0.5.5" 2183 | }, 2184 | "dependencies": { 2185 | "debug": { 2186 | "version": "3.2.7", 2187 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", 2188 | "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", 2189 | "dev": true, 2190 | "requires": { 2191 | "ms": "^2.1.1" 2192 | } 2193 | }, 2194 | "ms": { 2195 | "version": "2.1.3", 2196 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 2197 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 2198 | "dev": true 2199 | } 2200 | } 2201 | }, 2202 | "process": { 2203 | "version": "0.11.10", 2204 | "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", 2205 | "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", 2206 | "dev": true 2207 | }, 2208 | "process-nextick-args": { 2209 | "version": "2.0.1", 2210 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 2211 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", 2212 | "dev": true 2213 | }, 2214 | "public-encrypt": { 2215 | "version": "4.0.3", 2216 | "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", 2217 | "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", 2218 | "dev": true, 2219 | "requires": { 2220 | "bn.js": "^4.1.0", 2221 | "browserify-rsa": "^4.0.0", 2222 | "create-hash": "^1.1.0", 2223 | "parse-asn1": "^5.0.0", 2224 | "randombytes": "^2.0.1", 2225 | "safe-buffer": "^5.1.2" 2226 | }, 2227 | "dependencies": { 2228 | "bn.js": { 2229 | "version": "4.12.0", 2230 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", 2231 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", 2232 | "dev": true 2233 | } 2234 | } 2235 | }, 2236 | "punycode": { 2237 | "version": "1.4.1", 2238 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 2239 | "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", 2240 | "dev": true 2241 | }, 2242 | "qs": { 2243 | "version": "6.10.5", 2244 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.5.tgz", 2245 | "integrity": "sha512-O5RlPh0VFtR78y79rgcgKK4wbAI0C5zGVLztOIdpWX6ep368q5Hv6XRxDvXuZ9q3C6v+e3n8UfZZJw7IIG27eQ==", 2246 | "dev": true, 2247 | "requires": { 2248 | "side-channel": "^1.0.4" 2249 | } 2250 | }, 2251 | "querystring": { 2252 | "version": "0.2.0", 2253 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", 2254 | "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", 2255 | "dev": true 2256 | }, 2257 | "querystring-es3": { 2258 | "version": "0.2.1", 2259 | "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", 2260 | "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", 2261 | "dev": true 2262 | }, 2263 | "randombytes": { 2264 | "version": "2.1.0", 2265 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 2266 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 2267 | "dev": true, 2268 | "requires": { 2269 | "safe-buffer": "^5.1.0" 2270 | } 2271 | }, 2272 | "randomfill": { 2273 | "version": "1.0.4", 2274 | "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", 2275 | "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", 2276 | "dev": true, 2277 | "requires": { 2278 | "randombytes": "^2.0.5", 2279 | "safe-buffer": "^5.1.0" 2280 | } 2281 | }, 2282 | "readable-stream": { 2283 | "version": "2.3.7", 2284 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 2285 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 2286 | "dev": true, 2287 | "requires": { 2288 | "core-util-is": "~1.0.0", 2289 | "inherits": "~2.0.3", 2290 | "isarray": "~1.0.0", 2291 | "process-nextick-args": "~2.0.0", 2292 | "safe-buffer": "~5.1.1", 2293 | "string_decoder": "~1.1.1", 2294 | "util-deprecate": "~1.0.1" 2295 | } 2296 | }, 2297 | "readline-sync": { 2298 | "version": "1.4.10", 2299 | "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz", 2300 | "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==", 2301 | "dev": true 2302 | }, 2303 | "requires-port": { 2304 | "version": "1.0.0", 2305 | "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", 2306 | "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", 2307 | "dev": true 2308 | }, 2309 | "ripemd160": { 2310 | "version": "2.0.2", 2311 | "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", 2312 | "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", 2313 | "dev": true, 2314 | "requires": { 2315 | "hash-base": "^3.0.0", 2316 | "inherits": "^2.0.1" 2317 | } 2318 | }, 2319 | "safe-buffer": { 2320 | "version": "5.1.2", 2321 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 2322 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 2323 | "dev": true 2324 | }, 2325 | "safer-buffer": { 2326 | "version": "2.1.2", 2327 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 2328 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 2329 | "dev": true 2330 | }, 2331 | "secure-compare": { 2332 | "version": "3.0.1", 2333 | "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", 2334 | "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==", 2335 | "dev": true 2336 | }, 2337 | "setimmediate": { 2338 | "version": "1.0.5", 2339 | "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", 2340 | "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", 2341 | "dev": true 2342 | }, 2343 | "sha.js": { 2344 | "version": "2.4.11", 2345 | "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", 2346 | "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", 2347 | "dev": true, 2348 | "requires": { 2349 | "inherits": "^2.0.1", 2350 | "safe-buffer": "^5.0.1" 2351 | } 2352 | }, 2353 | "shadow-cljs": { 2354 | "version": "2.19.3", 2355 | "resolved": "https://registry.npmjs.org/shadow-cljs/-/shadow-cljs-2.19.3.tgz", 2356 | "integrity": "sha512-9TsTCRlmR8m1g2ekwblgomRUgJpbifQI99VlRrlH9NMqEzklev3zYAD1dvy4d5h8BoAhgdxOOEg7ld2d45CWTA==", 2357 | "dev": true, 2358 | "requires": { 2359 | "node-libs-browser": "^2.2.1", 2360 | "readline-sync": "^1.4.7", 2361 | "shadow-cljs-jar": "1.3.2", 2362 | "source-map-support": "^0.4.15", 2363 | "which": "^1.3.1", 2364 | "ws": "^7.4.6" 2365 | } 2366 | }, 2367 | "shadow-cljs-jar": { 2368 | "version": "1.3.2", 2369 | "resolved": "https://registry.npmjs.org/shadow-cljs-jar/-/shadow-cljs-jar-1.3.2.tgz", 2370 | "integrity": "sha512-XmeffAZHv8z7451kzeq9oKh8fh278Ak+UIOGGrapyqrFBB773xN8vMQ3O7J7TYLnb9BUwcqadKkmgaq7q6fhZg==", 2371 | "dev": true 2372 | }, 2373 | "side-channel": { 2374 | "version": "1.0.4", 2375 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 2376 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 2377 | "dev": true, 2378 | "requires": { 2379 | "call-bind": "^1.0.0", 2380 | "get-intrinsic": "^1.0.2", 2381 | "object-inspect": "^1.9.0" 2382 | } 2383 | }, 2384 | "source-map": { 2385 | "version": "0.5.7", 2386 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 2387 | "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", 2388 | "dev": true 2389 | }, 2390 | "source-map-support": { 2391 | "version": "0.4.18", 2392 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", 2393 | "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", 2394 | "dev": true, 2395 | "requires": { 2396 | "source-map": "^0.5.6" 2397 | } 2398 | }, 2399 | "stream-browserify": { 2400 | "version": "2.0.2", 2401 | "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", 2402 | "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", 2403 | "dev": true, 2404 | "requires": { 2405 | "inherits": "~2.0.1", 2406 | "readable-stream": "^2.0.2" 2407 | } 2408 | }, 2409 | "stream-http": { 2410 | "version": "2.8.3", 2411 | "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", 2412 | "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", 2413 | "dev": true, 2414 | "requires": { 2415 | "builtin-status-codes": "^3.0.0", 2416 | "inherits": "^2.0.1", 2417 | "readable-stream": "^2.3.6", 2418 | "to-arraybuffer": "^1.0.0", 2419 | "xtend": "^4.0.0" 2420 | } 2421 | }, 2422 | "string_decoder": { 2423 | "version": "1.1.1", 2424 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 2425 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 2426 | "dev": true, 2427 | "requires": { 2428 | "safe-buffer": "~5.1.0" 2429 | } 2430 | }, 2431 | "timers-browserify": { 2432 | "version": "2.0.12", 2433 | "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", 2434 | "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", 2435 | "dev": true, 2436 | "requires": { 2437 | "setimmediate": "^1.0.4" 2438 | } 2439 | }, 2440 | "to-arraybuffer": { 2441 | "version": "1.0.1", 2442 | "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", 2443 | "integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==", 2444 | "dev": true 2445 | }, 2446 | "tty-browserify": { 2447 | "version": "0.0.0", 2448 | "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", 2449 | "integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==", 2450 | "dev": true 2451 | }, 2452 | "union": { 2453 | "version": "0.5.0", 2454 | "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", 2455 | "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", 2456 | "dev": true, 2457 | "requires": { 2458 | "qs": "^6.4.0" 2459 | } 2460 | }, 2461 | "url": { 2462 | "version": "0.11.0", 2463 | "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", 2464 | "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", 2465 | "dev": true, 2466 | "requires": { 2467 | "punycode": "1.3.2", 2468 | "querystring": "0.2.0" 2469 | }, 2470 | "dependencies": { 2471 | "punycode": { 2472 | "version": "1.3.2", 2473 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", 2474 | "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", 2475 | "dev": true 2476 | } 2477 | } 2478 | }, 2479 | "url-join": { 2480 | "version": "4.0.1", 2481 | "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", 2482 | "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", 2483 | "dev": true 2484 | }, 2485 | "util": { 2486 | "version": "0.11.1", 2487 | "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", 2488 | "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", 2489 | "dev": true, 2490 | "requires": { 2491 | "inherits": "2.0.3" 2492 | }, 2493 | "dependencies": { 2494 | "inherits": { 2495 | "version": "2.0.3", 2496 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 2497 | "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", 2498 | "dev": true 2499 | } 2500 | } 2501 | }, 2502 | "util-deprecate": { 2503 | "version": "1.0.2", 2504 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 2505 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", 2506 | "dev": true 2507 | }, 2508 | "vm-browserify": { 2509 | "version": "1.1.2", 2510 | "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", 2511 | "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", 2512 | "dev": true 2513 | }, 2514 | "whatwg-encoding": { 2515 | "version": "2.0.0", 2516 | "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", 2517 | "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", 2518 | "dev": true, 2519 | "requires": { 2520 | "iconv-lite": "0.6.3" 2521 | } 2522 | }, 2523 | "which": { 2524 | "version": "1.3.1", 2525 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 2526 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 2527 | "dev": true, 2528 | "requires": { 2529 | "isexe": "^2.0.0" 2530 | } 2531 | }, 2532 | "ws": { 2533 | "version": "7.5.8", 2534 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.8.tgz", 2535 | "integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==", 2536 | "dev": true, 2537 | "requires": {} 2538 | }, 2539 | "xtend": { 2540 | "version": "4.0.2", 2541 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", 2542 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", 2543 | "dev": true 2544 | } 2545 | } 2546 | } 2547 | --------------------------------------------------------------------------------