├── .gitattributes ├── entry ├── dev.js ├── release.js ├── manifest.json └── main.css ├── .gitignore ├── src └── app │ ├── comp │ ├── hot_corner.cljs │ ├── loading.cljs │ ├── command.cljs │ ├── notifications.cljs │ ├── orphans.cljs │ ├── modal_stack.cljs │ ├── def.cljs │ ├── rename_path.cljs │ ├── hydrate.cljs │ ├── stack.cljs │ ├── file_tree.cljs │ ├── container.cljs │ ├── brief_file.cljs │ ├── graph.cljs │ ├── workspace.cljs │ └── palette.cljs │ ├── updater │ ├── modal.cljs │ ├── router.cljs │ ├── notification.cljs │ ├── graph.cljs │ ├── collection.cljs │ └── stack.cljs │ ├── util │ ├── querystring.cljs │ ├── dom.cljs │ ├── keycode.cljs │ ├── detect.cljs │ ├── stack.cljs │ └── analyze.cljs │ ├── schema.cljs │ ├── page.cljs │ ├── style │ └── widget.cljs │ ├── util.cljs │ ├── updater.cljs │ ├── actions.cljs │ └── main.cljs ├── server └── app │ ├── walk.cljs │ └── server.cljs ├── package.json ├── .github └── workflows │ ├── npm-publish.yaml │ └── upload.yaml ├── shadow-cljs.edn ├── README.md └── yarn.lock /.gitattributes: -------------------------------------------------------------------------------- 1 | 2 | 3 | yarn.lock -diff linguist-generated 4 | -------------------------------------------------------------------------------- /entry/dev.js: -------------------------------------------------------------------------------- 1 | require('respo-ui'); 2 | require('./main.css'); 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | 3 | .shadow-cljs/ 4 | target/ 5 | node_modules/ 6 | dist/ 7 | 8 | example/ 9 | -------------------------------------------------------------------------------- /entry/release.js: -------------------------------------------------------------------------------- 1 | require('respo-ui'); 2 | require('./main.css'); 3 | require('../target/release/app.main.js'); 4 | -------------------------------------------------------------------------------- /src/app/comp/hot_corner.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.comp.hot-corner 3 | (:require [hsl.core :refer [hsl]] 4 | [respo.core :refer [defcomp <> div span]] 5 | [respo.comp.space :refer [=<]] 6 | [respo-ui.core :as ui])) 7 | -------------------------------------------------------------------------------- /src/app/updater/modal.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.updater.modal ) 3 | 4 | (defn mould [store op-data op-id] 5 | (let [modal op-data] (update store :modal-stack (fn [stack] (conj stack modal))))) 6 | 7 | (defn recycle [store op-data op-id] 8 | (update store :modal-stack (fn [stack] (into [] (butlast stack))))) 9 | -------------------------------------------------------------------------------- /src/app/util/querystring.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.util.querystring (:require [clojure.string :as string])) 3 | 4 | (defn parse-query [search] 5 | (if (= search "") 6 | {} 7 | (let [content (subs search 1) 8 | pairs (map (fn [piece] (string/split piece "=")) (string/split content "&"))] 9 | (into {} pairs)))) 10 | -------------------------------------------------------------------------------- /src/app/util/dom.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.util.dom ) 3 | 4 | (defn focus-palette! [] 5 | (js/requestAnimationFrame 6 | (fn [] 7 | (let [target (.querySelector js/document "#command-palette")] 8 | (if (some? target) (.focus target)))))) 9 | 10 | (defn focus-rename! [] (-> (.querySelector js/document "#rename-box") (.focus))) 11 | -------------------------------------------------------------------------------- /src/app/schema.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.schema ) 3 | 4 | (def store 5 | {:router {:name :loading, :data :definitions, :show-palette? false}, 6 | :collection {:package nil, :root nil, :files {}}, 7 | :graph {:tree nil, :orphans nil, :path [], :ns-path []}, 8 | :writer {:stack [], :pointer 0, :clipboard []}, 9 | :notifications [], 10 | :modal-stack [], 11 | :states {}}) 12 | -------------------------------------------------------------------------------- /entry/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Stack Editor", 3 | "name": "Stack Editor", 4 | "icons": [ 5 | { 6 | "src": "http://repo.cirru.org/logo.cirru.org/cirru-400x400.png", 7 | "sizes": "400x400" 8 | } 9 | ], 10 | "start_url": "index.html", 11 | "display": "standalone", 12 | "orientation": "portrait", 13 | "background_color": "#eeeeff", 14 | "theme_color": "#eeeeff" 15 | } -------------------------------------------------------------------------------- /src/app/util/keycode.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.util.keycode ) 3 | 4 | (def key-a 65) 5 | 6 | (def key-b 66) 7 | 8 | (def key-d 68) 9 | 10 | (def key-down 40) 11 | 12 | (def key-e 69) 13 | 14 | (def key-enter 13) 15 | 16 | (def key-esc 27) 17 | 18 | (def key-i 73) 19 | 20 | (def key-j 74) 21 | 22 | (def key-k 75) 23 | 24 | (def key-p 80) 25 | 26 | (def key-s 83) 27 | 28 | (def key-u 85) 29 | 30 | (def key-up 38) 31 | -------------------------------------------------------------------------------- /entry/main.css: -------------------------------------------------------------------------------- 1 | 2 | body { 3 | margin: 0; 4 | overscroll-behavior-y: none; 5 | overscroll-behavior-x: none; 6 | } 7 | 8 | body * { 9 | box-sizing: border-box; 10 | } 11 | 12 | .is-unremarkable { 13 | opacity: 0.6; 14 | } 15 | 16 | .is-unremarkable:hover { 17 | opacity: 1; 18 | } 19 | 20 | ::-webkit-scrollbar { 21 | width: 1px; 22 | height: 1px; 23 | } 24 | 25 | ::-webkit-scrollbar-track { 26 | background-color: hsla(0,0%,100%,0); 27 | } 28 | 29 | ::-webkit-scrollbar-thumb { 30 | background-color: hsla(0,0%,100%,0.3); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/app/comp/loading.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.comp.loading 3 | (:require [hsl.core :refer [hsl]] 4 | [respo.core :refer [defcomp div <> span input]] 5 | [respo-ui.core :as ui])) 6 | 7 | (def style-loading 8 | {:background-color (hsl 200 40 10), 9 | :justify-content "center", 10 | :color (hsl 0 0 80), 11 | :font-size "32px", 12 | :font-weight "100", 13 | :font-family ui/font-fancy}) 14 | 15 | (defcomp 16 | comp-loading 17 | () 18 | (div {:style (merge ui/fullscreen ui/row-center style-loading)} (<> "Loading..." nil))) 19 | -------------------------------------------------------------------------------- /src/app/updater/router.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.updater.router 3 | (:require [app.util.stack :refer [get-path]] [clojure.string :as string])) 4 | 5 | (defn open-file-tree [store op-data op-id] 6 | (let [code-path (get-path store)] 7 | (-> store 8 | (assoc-in [:router :name] :file-tree) 9 | (assoc-in [:graph :ns-path] (vec (string/split (:ns code-path) ".")))))) 10 | 11 | (defn route [store op-data] (let [router op-data] (assoc store :router router))) 12 | 13 | (defn toggle-palette [store op-data op-id] (update-in store [:router :show-palette?] not)) 14 | -------------------------------------------------------------------------------- /server/app/walk.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.walk 3 | (:require ["fs" :as fs] 4 | ["path" :as path])) 5 | 6 | (defn dir? [x] (.isDirectory (fs/statSync x))) 7 | (defn file? [x] (.isFile (fs/statSync x))) 8 | 9 | (defn walk [base-dir collect!] 10 | (let [children (js->clj (fs/readdirSync base-dir))] 11 | (doall 12 | (map 13 | (fn [child] 14 | (let [child-path (path/join base-dir child)] 15 | (cond 16 | (dir? child-path) 17 | (walk child-path collect!) 18 | (file? child-path) 19 | (collect! child-path) 20 | :else (println "Invalid file stats:" child-path)))) 21 | children)))) 22 | -------------------------------------------------------------------------------- /src/app/updater/notification.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.updater.notification ) 3 | 4 | (defn add-one [store op-data op-id] 5 | (let [notification op-data] 6 | (-> store 7 | (update 8 | :notifications 9 | (fn [notifications] (into [] (cons [op-id notification] (take 3 notifications)))))))) 10 | 11 | (defn remove-one [store op-data] 12 | (let [notification-id op-data] 13 | (-> store 14 | (update 15 | :notifications 16 | (fn [notifications] 17 | (filterv 18 | (fn [notification] (not= notification-id (first notification))) 19 | notifications)))))) 20 | 21 | (defn remove-since [store op-data] 22 | (let [pos op-data] 23 | (-> store (update :notifications (fn [notifications] (take pos notifications)))))) 24 | -------------------------------------------------------------------------------- /src/app/comp/command.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.comp.command 3 | (:require [clojure.string :as string] 4 | [respo.core :refer [defcomp div <> span input]] 5 | [hsl.core :refer [hsl]] 6 | [respo.comp.space :refer [=<]] 7 | [respo-ui.core :as ui])) 8 | 9 | (def style-command 10 | {:backgroud-color (hsl 0 0 0), 11 | :padding "0 8px", 12 | :line-height "30px", 13 | :font-family ui/font-normal, 14 | :cursor "pointer"}) 15 | 16 | (defcomp 17 | comp-command 18 | (command selected? on-select) 19 | (div 20 | {:style (merge style-command (if selected? {:background-color (hsl 0 0 20 0.8)})), 21 | :on-click (fn [e dispatch!] (on-select dispatch!))} 22 | (case (first command) 23 | :defs (div {} (<> (get command 2)) (=< 16 nil) (<> (get command 1) {:color (hsl 0 0 40)})) 24 | (<> (string/join " " command) nil)))) 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "stack-editor", 3 | "version": "0.4.0-a3", 4 | "description": "Stack editor", 5 | "main": "index.js", 6 | "scripts": { 7 | "tiye": "rsync -r dist/ cirru.org:repo/Cirru/stack-editor", 8 | "watch": "shadow-cljs watch client server", 9 | "page": "yarn shadow-cljs compile page && env=dev node target/page.js", 10 | "del": "rm -rf dist/*", 11 | "serve": "serve dist", 12 | "html": "shadow-cljs compile page && node target/page.js", 13 | "build": "yarn del && shadow-cljs release client && yarn html" 14 | }, 15 | "bin": { 16 | "stack-editor": "./dist/server.js", 17 | "se": "./dist/server.js" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "https://github.com/Cirru/stack-editor" 22 | }, 23 | "author": "jiyinyiyong", 24 | "license": "MIT", 25 | "devDependencies": { 26 | "shadow-cljs": "^2.8.93", 27 | "source-map-support": "^0.5.16" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/app/comp/notifications.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.comp.notifications 3 | (:require [hsl.core :refer [hsl]] 4 | [respo-ui.core :as ui] 5 | [respo.core :refer [defcomp list-> div <> span input]])) 6 | 7 | (defn on-click [idx] (fn [e dispatch!] (dispatch! :notification/remove-since idx))) 8 | 9 | (def style-notification 10 | {:position "fixed", 11 | :top "8px", 12 | :right "8px", 13 | :transition "320ms", 14 | :line-height "32px", 15 | :white-space "nowrap", 16 | :color (hsl 0 0 100 0.5), 17 | :background-color (hsl 300 30 70 0.2), 18 | :z-index 999, 19 | :min-width "160px", 20 | :padding "0 16px", 21 | :cursor "pointer", 22 | :border-radius "2px"}) 23 | 24 | (defcomp 25 | comp-notifications 26 | (notifications) 27 | (list-> 28 | {} 29 | (->> notifications 30 | (map-indexed 31 | (fn [idx entry] 32 | [(first entry) 33 | (div 34 | {:style (merge style-notification {:top (str (+ 8 (* 40 idx)) "px")}), 35 | :on-click (on-click idx)} 36 | (<> span (last entry) nil))]))))) 37 | -------------------------------------------------------------------------------- /src/app/comp/orphans.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.comp.orphans 3 | (:require [hsl.core :refer [hsl]] 4 | [respo.core :refer [defcomp div list-> <> span input]] 5 | [respo-ui.core :as ui])) 6 | 7 | (defn on-edit [def-info] 8 | (fn [e dispatch!] 9 | (dispatch! 10 | :collection/edit 11 | {:kind :defs, :ns (:ns def-info), :extra (:def def-info), :focus [1]}) 12 | (dispatch! :modal/recycle nil))) 13 | 14 | (def style-container 15 | {:width 800, :height 400, :overflow :auto, :padding 16, :background (hsl 0 0 0 0.9)}) 16 | 17 | (def style-def {:min-width 200, :display :inline-block, :cursor :pointer}) 18 | 19 | (def style-title {:font-size 24, :font-weight 100, :font-family "Josefin Sans"}) 20 | 21 | (defcomp 22 | comp-orphans 23 | (orphans) 24 | (div 25 | {:style style-container} 26 | (div {} (<> span "Orphans:" style-title)) 27 | (list-> 28 | {} 29 | (->> orphans 30 | (map 31 | (fn [def-info] 32 | (let [def-id (str (:ns def-info) "/" (:def def-info))] 33 | [def-id 34 | (div {:inner-text def-id, :style style-def, :on-click (on-edit def-info)})]))))))) 35 | -------------------------------------------------------------------------------- /src/app/page.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.page 3 | (:require [respo.core :refer [create-element]] 4 | [respo.core :refer [html head title script style meta' div link body]] 5 | [respo.render.html :refer [make-string]] 6 | [app.comp.container :refer [comp-container]] 7 | [shell-page.core :refer [make-page slurp spit]] 8 | [app.schema :as schema] 9 | [cljs.reader :refer [read-string]])) 10 | 11 | (def base-info 12 | {:title "Stack Editor", 13 | :icon "http://logo.cirru.org/cirru-400x400.png", 14 | :ssr nil, 15 | :inilne-html "", 16 | :styles ["http://cdn.tiye.me/favored-fonts/main-fonts.css"]}) 17 | 18 | (defn dev-page [] (make-page "" (merge base-info {:scripts ["/client.js"]}))) 19 | 20 | (defn prod-page [] 21 | (let [html-content (make-string (comp-container schema/store)) 22 | assets (read-string (slurp "dist/assets.edn"))] 23 | (make-page 24 | html-content 25 | (merge base-info {:scripts (map (fn [x] (:output-name x)) assets)})))) 26 | 27 | (defn main! [] 28 | (if (= js/process.env.env "dev") 29 | (spit "target/index.html" (dev-page)) 30 | (spit "dist/index.html" (prod-page)))) 31 | -------------------------------------------------------------------------------- /src/app/style/widget.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.style.widget (:require [hsl.core :refer [hsl]] [respo-ui.core :as ui])) 3 | 4 | (def button 5 | (merge 6 | ui/button 7 | {:background-color (hsl 0 0 100 0.2), 8 | :color (hsl 0 0 100 0.6), 9 | :height 28, 10 | :line-height "28px", 11 | :border :none})) 12 | 13 | (def clickable-text 14 | {:text-decoration :underline, 15 | :cursor :pointer, 16 | :color (hsl 0 0 80), 17 | :font-family "Josefin Sans"}) 18 | 19 | (def entry 20 | {:display "inline-block", 21 | :background-color (hsl 200 10 40 0), 22 | :color (hsl 0 0 100), 23 | :padding "0 8px", 24 | :cursor "pointer", 25 | :margin-bottom "8px"}) 26 | 27 | (def var-entry 28 | {:color (hsl 0 0 80), 29 | :cursor "pointer", 30 | :font-family "Source Code Pro,Menlo,monospace", 31 | :font-size "14px", 32 | :line-height "24px", 33 | :min-width "160px"}) 34 | 35 | (def entry-line (merge var-entry {:display "block"})) 36 | 37 | (def input 38 | (merge 39 | ui/input 40 | {:background-color (hsl 0 0 100 0.14), 41 | :color (hsl 0 0 100), 42 | :font-family "Source Code Pro,Menlo,monospace", 43 | :width "200px", 44 | :border :none})) 45 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yaml: -------------------------------------------------------------------------------- 1 | name: npm publish 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | publish-npm: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: docker://timbru31/java-node:latest 13 | - uses: actions/setup-node@v1 14 | with: 15 | node-version: 12 16 | registry-url: https://registry.npmjs.org/ 17 | 18 | - name: Get yarn cache 19 | id: yarn-cache 20 | run: echo "::set-output name=dir::$(yarn cache dir)" 21 | 22 | - uses: actions/cache@v1 23 | name: Cache node modules of yarn 24 | with: 25 | path: ${{ steps.yarn-cache.outputs.dir }} 26 | key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} 27 | restore-keys: | 28 | ${{ runner.os }}-yarn- 29 | 30 | - name: Cache Clojars 31 | uses: actions/cache@v1 32 | env: 33 | cache-name: cache-clojars 34 | with: 35 | path: ~/.m2 36 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('shadow-cljs.edn') }} 37 | restore-keys: | 38 | ${{ runner.os }}-clojars 39 | 40 | - run: yarn && yarn shadow-cljs release server && npm publish 41 | env: 42 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 43 | -------------------------------------------------------------------------------- /src/app/util/detect.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.util.detect (:require [clojure.string :as string])) 3 | 4 | (defn =def? [x y] (and (= (:ns x) (:ns y)) (= (:def x) (:def y)))) 5 | 6 | (defn =path? [x y] 7 | (and (= (:ns x) (:ns y)) (= (:kind x) (:kind y)) (= (:extra x) (:extra y)))) 8 | 9 | (defn cirru-vec? [x] 10 | (if (vector? x) (every? (fn [y] (or (string? y) (cirru-vec? y))) x) false)) 11 | 12 | (defn contains-def? [files ns-part name-part] 13 | (println "Contains def:" ns-part name-part) 14 | (if (contains? files ns-part) 15 | (let [dict (get-in files [ns-part :defs])] (contains? dict name-part)) 16 | false)) 17 | 18 | (defn def-order [x y] 19 | (cond 20 | (and (:circular? x) (not (:circular? y))) -1 21 | (and (:circular? y) (not (:circular? x))) 1 22 | (and (:external? x) (not (:external? y))) 1 23 | (and (:external? y) (not (:external? x))) -1 24 | :else (compare (str (:ns x) "/" (:def x)) (str (:ns y) "/" (:def y))))) 25 | 26 | (defn fuzzy-search [pieces queries] 27 | (every? 28 | (fn [query] 29 | (some 30 | (fn [piece] (string/includes? (str piece) query)) 31 | (if (= :defs (first pieces)) (subvec pieces 1) pieces))) 32 | queries)) 33 | 34 | (defn strip-atom [token] 35 | (-> token 36 | (string/replace (re-pattern "^@") "") 37 | (string/replace (re-pattern "\\.$") "") 38 | (string/replace (re-pattern "/@") "/"))) 39 | 40 | (defn use-vector? [xs] (= "[]" (first xs))) 41 | -------------------------------------------------------------------------------- /shadow-cljs.edn: -------------------------------------------------------------------------------- 1 | { 2 | :source-paths ["src" "server"] 3 | :dependencies [ 4 | [mvc-works/hsl "0.1.2"] 5 | [cumulo/shallow-diff "0.1.3"] 6 | [mvc-works/shell-page "0.1.10"] 7 | [cirru/editor "0.3.0-a2"] 8 | [respo "0.12.1"] 9 | [respo/ui "0.3.14"] 10 | [cljs-ajax "0.8.0"] 11 | [cumulo/shallow-diff "0.1.3"] 12 | [fipp "0.6.22"] 13 | [cirru/edn "0.0.9-a1"] 14 | [cirru/sepal "0.2.7"] 15 | [mvc-works/polyfill "0.1.1"] 16 | ] 17 | :open-file-command [ 18 | "subl" 19 | ["%s:%s:%s" :file :line :column] 20 | ] 21 | :dev-http {7000 "target/"} 22 | :builds { 23 | :client { 24 | :output-dir "target", :target :browser, :asset-path "./" 25 | :compiler-options {:infer-externs :auto} 26 | :modules { 27 | :client {:init-fn app.main/main!} 28 | } 29 | :release { 30 | :output-dir "dist/", :module-hash-names 8 31 | :build-options {:manifest-name "assets.edn"} 32 | } 33 | :devtools {:after-load app.main/reload!} 34 | } 35 | :page { 36 | :target :node-script, :output-to "target/page.js", :main app.page/main! 37 | :devtools {:after-load app.page/main!} 38 | } 39 | :server { 40 | :target :node-script, :main app.server/main!, :output-to "target/server.js" 41 | :compiler-options {:infer-externs :auto} 42 | :release {:output-to "dist/server.js"} 43 | :devtools {:after-load app.server/reload!} 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /src/app/comp/modal_stack.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.comp.modal-stack 3 | (:require [hsl.core :refer [hsl]] 4 | [respo.core :refer [defcomp list-> div <> >> span input]] 5 | [respo-ui.core :as ui] 6 | [app.style.widget :as widget] 7 | [app.comp.rename-path :refer [comp-rename-path]] 8 | [app.comp.hydrate :refer [comp-hydrate]] 9 | [app.comp.orphans :refer [comp-orphans]])) 10 | 11 | (defn on-recycle [e dispatch!] (dispatch! :modal/recycle nil)) 12 | 13 | (defn on-tip [e dispatch!] ) 14 | 15 | (defn renderer [states kind title data] 16 | (div 17 | {} 18 | (case title 19 | :rename-path (comp-rename-path (>> states :rename-path) data) 20 | :hydrate (comp-hydrate (>> states :hydrate)) 21 | :orphans (comp-orphans data) 22 | (<> span title nil)))) 23 | 24 | (def style-modal 25 | (merge 26 | ui/center 27 | {:background-color (hsl 0 0 0 0.6), 28 | :z-index 900, 29 | :position :fixed, 30 | :top 0, 31 | :right 0, 32 | :width "100%", 33 | :height "100%"})) 34 | 35 | (defcomp 36 | comp-modal-stack 37 | (states modal-stack) 38 | (list-> 39 | {} 40 | (->> modal-stack 41 | (map-indexed 42 | (fn [idx modal] 43 | (let [kind (:kind modal), title (:title modal), data (:data modal)] 44 | [idx 45 | (div 46 | {:style style-modal, :on-click on-recycle} 47 | (div {:on-click on-tip} (renderer states kind title data)))])))))) 48 | -------------------------------------------------------------------------------- /src/app/comp/def.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.comp.def 3 | (:require [hsl.core :refer [hsl]] 4 | [respo.core :refer [defcomp div <> span input]] 5 | [respo-ui.core :as ui] 6 | [respo.comp.space :refer [=<]])) 7 | 8 | (defn on-view [path child-node] 9 | (fn [e dispatch!] 10 | (if (.-metaKey (:original-event e)) 11 | (dispatch! 12 | :collection/edit 13 | {:kind :defs, :ns (:ns child-node), :extra (:def child-node), :focus []}) 14 | (dispatch! 15 | :graph/view-path 16 | (conj path {:ns (:ns child-node), :def (:def child-node)}))))) 17 | 18 | (def style-circular {:text-decoration :underline}) 19 | 20 | (def style-count {:font-size 12, :color (hsl 0 0 100 0.4)}) 21 | 22 | (def style-def 23 | {:color (hsl 0 0 70 0.7), :font-size 14, :cursor :pointer, :white-space :nowrap}) 24 | 25 | (def style-external {:color (hsl 260 16 44), :font-size 12, :cursor :default}) 26 | 27 | (def style-highlight {:color (hsl 0 0 100 0.86)}) 28 | 29 | (defcomp 30 | comp-def 31 | (child-node path selected?) 32 | (div 33 | {:style (merge 34 | style-def 35 | (if (:external? child-node) style-external) 36 | (if selected? style-highlight) 37 | (if (:circular? child-node) style-circular)), 38 | :on-click (on-view path child-node)} 39 | (<> span (str (:ns child-node) " / " (:def child-node)) nil) 40 | (=< 4 nil) 41 | (let [many-deps (count (:deps child-node))] 42 | (if (pos? many-deps) (<> span many-deps style-count))))) 43 | -------------------------------------------------------------------------------- /src/app/comp/rename_path.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.comp.rename-path 3 | (:require [respo.core :refer [defcomp div <> span input]] 4 | [respo.comp.space :refer [=<]] 5 | [respo-ui.core :as ui] 6 | [app.style.widget :as widget] 7 | [app.util.keycode :as keycode])) 8 | 9 | (defn init-state [code-path] 10 | (let [{ns-part :ns, kind :kind, extra-name :extra} code-path] 11 | (if (= kind :defs) (str ns-part "/" extra-name) ns-part))) 12 | 13 | (defn on-input [e dispatch! m!] (m! (:value e))) 14 | 15 | (defn on-keydown [code-path text] 16 | (fn [e d! m!] 17 | (println keycode/key-esc) 18 | (cond 19 | (= (:key-code e) keycode/key-enter) 20 | (do (d! :collection/rename [code-path text]) (d! :modal/recycle nil) (m! nil)) 21 | (= (:key-code e) keycode/key-esc) (d! :modal/recycle nil) 22 | :else nil))) 23 | 24 | (defn on-rename [code-path text] 25 | (fn [e d! m!] (d! :collection/rename [code-path text]) (d! :modal/recycle nil) (m! nil))) 26 | 27 | (defcomp 28 | comp-rename-path 29 | (states code-path) 30 | (let [state (or (:data states) (init-state code-path))] 31 | (div 32 | {} 33 | (div {} (<> span (str "Rename: " (:ns code-path) "/" (:extra code-path)) nil)) 34 | (div 35 | {} 36 | (input 37 | {:value state, 38 | :id "rename-box", 39 | :style (merge ui/input {:width 400}), 40 | :on-input on-input, 41 | :on-keydown (on-keydown code-path state)}) 42 | (=< 16 nil) 43 | (div 44 | {:inner-text "Rename", :style widget/button, :on-click (on-rename code-path state)}))))) 45 | -------------------------------------------------------------------------------- /.github/workflows/upload.yaml: -------------------------------------------------------------------------------- 1 | name: Upload Assets 2 | 3 | on: 4 | push: {} 5 | 6 | jobs: 7 | upload-assets: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v2 11 | - uses: docker://timbru31/java-node:latest 12 | 13 | - name: Get yarn cache 14 | id: yarn-cache 15 | run: echo "::set-output name=dir::$(yarn cache dir)" 16 | 17 | - uses: actions/cache@v1 18 | name: Cache node modules of yarn 19 | with: 20 | path: ${{ steps.yarn-cache.outputs.dir }} 21 | key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} 22 | restore-keys: | 23 | ${{ runner.os }}-yarn- 24 | 25 | - name: Cache Clojars 26 | uses: actions/cache@v1 27 | env: 28 | cache-name: cache-clojars 29 | with: 30 | path: ~/.m2 31 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('shadow-cljs.edn') }} 32 | restore-keys: | 33 | ${{ runner.os }}-clojars 34 | 35 | - run: yarn && yarn build 36 | name: Build web assets 37 | 38 | - name: Deploy to server 39 | id: deploy 40 | uses: Pendect/action-rsyncer@v1.1.0 41 | env: 42 | DEPLOY_KEY: ${{secrets.rsync_private_key}} 43 | with: 44 | flags: '-avzr --progress' 45 | options: '' 46 | ssh_options: '' 47 | src: 'dist/*' 48 | dest: 'rsync-user@fe.jimu.io:/web-assets/repo/${{ github.repository }}' 49 | 50 | - name: Display status from deploy 51 | run: echo "${{ steps.deploy.outputs.status }}" 52 | -------------------------------------------------------------------------------- /src/app/comp/hydrate.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.comp.hydrate 3 | (:require [hsl.core :refer [hsl]] 4 | [respo.core :refer [defcomp div <> >> span input button textarea]] 5 | [respo.comp.space :refer [=<]] 6 | [respo-ui.core :as ui] 7 | [app.style.widget :as widget] 8 | [cljs.reader :refer [read-string]] 9 | [app.util.detect :refer [cirru-vec?]])) 10 | 11 | (defn on-change [cursor] (fn [e dispatch!] (dispatch! :states [cursor (:value e)]))) 12 | 13 | (defn on-hydrate [text] 14 | (fn [e dispatch!] 15 | (let [piece (read-string text)] 16 | (if (cirru-vec? piece) 17 | (do (dispatch! :collection/hydrate piece) (dispatch! :modal/recycle nil)) 18 | (dispatch! :notification/add-one (str "Checking failed: " (pr-str text))))))) 19 | 20 | (def style-hint {:font-family "Hind"}) 21 | 22 | (def style-textarea 23 | {:background-color (hsl 0 0 100 0.2), 24 | :font-family "Source Code Pro, Menlo", 25 | :color :white, 26 | :resize :none, 27 | :width 640, 28 | :height 200, 29 | :line-height "24px"}) 30 | 31 | (def style-toolbar {:justify-content :flex-end}) 32 | 33 | (defcomp 34 | comp-hydrate 35 | (states) 36 | (let [cursor (:cursor states), state (:data states)] 37 | (div 38 | {} 39 | (div {:style style-hint} (<> span "EDN Cirru code to hydrate:" nil)) 40 | (div 41 | {} 42 | (textarea 43 | {:value state, 44 | :style (merge ui/textarea style-textarea), 45 | :on-input (on-change cursor)})) 46 | (=< nil 8) 47 | (div 48 | {:style (merge ui/row style-toolbar)} 49 | (button {:style widget/button, :on-click (on-hydrate state)} (<> span "Hydrate" nil)))))) 50 | -------------------------------------------------------------------------------- /src/app/util/stack.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.util.stack (:require [app.util.detect :refer [=path?]])) 3 | 4 | (defn get-path [store] 5 | (let [writer (:writer store), {stack :stack, pointer :pointer} writer] (get stack pointer))) 6 | 7 | (defn path-index-of 8 | ([xs y] (path-index-of xs y 0)) 9 | ([xs y idx] 10 | (if (empty? xs) -1 (if (=path? y (first xs)) idx (recur (rest xs) y (inc idx)))))) 11 | 12 | (defn push-paths [new-paths] 13 | (fn [writer] 14 | (if (empty? new-paths) 15 | writer 16 | (let [stack (:stack writer), pointer (:pointer writer)] 17 | (if (and (= 1 (count new-paths)) (>= (path-index-of stack (first new-paths)) 0)) 18 | (do 19 | (println "hit" (path-index-of stack (first new-paths))) 20 | (assoc writer :pointer (path-index-of stack (first new-paths)))) 21 | (cond 22 | (empty? stack) 23 | {:stack (into [] new-paths), :pointer 0, :focus (:focus (first new-paths))} 24 | (= (inc pointer) (count stack)) 25 | (-> writer 26 | (assoc :stack (into [] (concat stack new-paths))) 27 | (update :pointer inc) 28 | (assoc :focus (:focus (first new-paths)))) 29 | :else 30 | (-> writer 31 | (assoc 32 | :stack 33 | (into 34 | [] 35 | (concat 36 | (subvec stack 0 (inc pointer)) 37 | new-paths 38 | (subvec stack (inc pointer))))) 39 | (update :pointer inc) 40 | (assoc :focus (:focus (first new-paths)))))))))) 41 | 42 | (defn push-path [x] (push-paths [x])) 43 | -------------------------------------------------------------------------------- /src/app/comp/stack.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.comp.stack 3 | (:require [hsl.core :refer [hsl]] 4 | [respo.core :refer [defcomp div list-> <> span input]] 5 | [clojure.string :as string] 6 | [respo-ui.core :as ui])) 7 | 8 | (defn on-click [pointer] 9 | (fn [e dispatch!] 10 | (let [event (:original-event e) 11 | command? (or (.-ctrlKey event) (.-metaKey event)) 12 | shift? (.-shiftKey event)] 13 | (cond 14 | command? (dispatch! :stack/collapse pointer) 15 | shift? (do (.preventDefault event) (dispatch! :stack/shift pointer)) 16 | :else (do (dispatch! :stack/point-to pointer)))))) 17 | 18 | (def style-bar 19 | {:padding "4px 8px", 20 | :cursor "pointer", 21 | :color (hsl 0 0 60), 22 | :font-family "Source Code Pro,Menlo,monospace", 23 | :font-size 13, 24 | :line-height 1.4, 25 | :white-space "nowrap"}) 26 | 27 | (def style-bright {:color (hsl 0 0 90)}) 28 | 29 | (def style-container 30 | {:overflow "auto", :padding "16px 0 160px 0", :user-select :nonworkspacee}) 31 | 32 | (def style-ns 33 | {:font-size "11px", :line-height 1.4, :color (hsl 0 0 50), :font-family "Hind"}) 34 | 35 | (def style-ns-main 36 | {:padding "0 8px", 37 | :line-height "36px", 38 | :cursor "pointer", 39 | :color (hsl 0 0 60), 40 | :font-family "Hind", 41 | :font-size "13px", 42 | :white-space "nowrap"}) 43 | 44 | (defcomp 45 | comp-stack 46 | (stack pointer) 47 | (list-> 48 | {:style (merge ui/flex style-container)} 49 | (->> stack 50 | (map-indexed 51 | (fn [idx item] 52 | [idx 53 | (let [{ns-part :ns, kind :kind, extra-name :extra} item] 54 | (if (= kind :defs) 55 | (div 56 | {:style style-bar, :on-click (on-click idx)} 57 | (div {:style (if (= idx pointer) style-bright)} (<> span extra-name nil)) 58 | (div {:style style-ns} (<> span ns-part nil))) 59 | (div 60 | {:style (merge style-ns-main (if (= idx pointer) style-bright)), 61 | :on-click (on-click idx)} 62 | (<> span ns-part nil))))]))))) 63 | -------------------------------------------------------------------------------- /src/app/updater/graph.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.updater.graph 3 | (:require (app.util.analyze :refer (parse-ns-deps pick-dep expand-deps-tree)) 4 | (app.util.stack :refer (push-path)) 5 | (clojure.set :refer (union difference)) 6 | (app.util :refer (collect-defs)) 7 | (clojure.string :as string))) 8 | 9 | (defn edit-current [store op] 10 | (let [maybe-path (last (get-in store [:graph :path]))] 11 | (if (some? maybe-path) 12 | (-> store 13 | (update 14 | :writer 15 | (push-path 16 | {:ns (:ns maybe-path), :kind :defs, :extra (:def maybe-path), :focus []})) 17 | (assoc :router {:name :workspace, :data nil})) 18 | store))) 19 | 20 | (defn load-graph [store op-data] 21 | (let [root-info (get-in store [:collection :root]) 22 | files (get-in store [:collection :files]) 23 | internal-ns (:ns root-info) 24 | ns-deps (parse-ns-deps (get-in files [internal-ns :ns])) 25 | def-expr (get-in files [(:ns root-info) :defs (:def root-info)]) 26 | pkg (get-in store [:collection :package]) 27 | this-file (get files internal-ns) 28 | deps-tree (expand-deps-tree internal-ns (:def root-info) files pkg #{})] 29 | (comment println ns-deps) 30 | (println) 31 | (-> store (assoc-in [:graph :tree] deps-tree)))) 32 | 33 | (defn show-orphans [store op-data] 34 | (let [all-defs (->> (get-in store [:collection :files]) 35 | (map 36 | (fn [file-entry] 37 | (let [ns-text (first file-entry) 38 | defs (keys (:defs (val file-entry)))] 39 | (->> defs 40 | (map (fn [def-text] {:ns ns-text, :def def-text})) 41 | (into #{}))))) 42 | (apply union)) 43 | deps-tree (get-in store [:graph :tree]) 44 | defs-in-tree (collect-defs deps-tree)] 45 | (update 46 | store 47 | :modal-stack 48 | (fn [xs] (conj xs {:title :orphans, :data (difference all-defs defs-in-tree)}))))) 49 | 50 | (defn view-ns [store op-data] (assoc-in store [:graph :ns-path] op-data)) 51 | 52 | (defn view-path [store op-data] (assoc-in store [:graph :path] op-data)) 53 | -------------------------------------------------------------------------------- /src/app/util.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.util 3 | (:require [app.util.detect :refer [contains-def? =path?]] 4 | (clojure.set :refer (union)) 5 | (clojure.string :as string))) 6 | 7 | (defn collect-defs [node] 8 | (let [base-result #{(select-keys node [:ns :def])}] 9 | (if (contains? node :deps) 10 | (union (apply union (map collect-defs (:deps node))) base-result) 11 | base-result))) 12 | 13 | (defn has-ns? [x] (string/includes? x "/")) 14 | 15 | (defn make-short-path [info] 16 | (let [kind (:kind info)] 17 | (if (= kind :defs) [(:ns info) :defs (:extra info)] [(:ns info) kind]))) 18 | 19 | (defn helper-create-def [ns-part name-part code-path focus] 20 | (fn [files] 21 | (if (contains-def? files ns-part name-part) 22 | files 23 | (assoc-in 24 | files 25 | [ns-part :defs name-part] 26 | (let [as-fn? (and (not (empty? focus)) (zero? (last focus)))] 27 | (if as-fn? 28 | (let [expression (get-in 29 | files 30 | (concat (make-short-path code-path) (butlast focus)))] 31 | (if (> (count expression) 1) 32 | ["defn" name-part (subvec expression 1)] 33 | ["defn" name-part []])) 34 | ["def" name-part []])))))) 35 | 36 | (defn helper-notify [op-id data] 37 | (fn [notifications] (into [] (cons [op-id data] notifications)))) 38 | 39 | (defn make-path [info] 40 | (let [kind (:kind info)] 41 | (if (= kind :defs) 42 | [:collection :files (:ns info) :defs (:extra info)] 43 | [:collection :files (:ns info) kind]))) 44 | 45 | (defn make-focus-path [store] 46 | (let [writer (:writer store) 47 | pointer (:pointer writer) 48 | stack (:stack writer) 49 | code-path (get stack pointer)] 50 | (concat (make-path code-path) (:focus code-path)))) 51 | 52 | (defn now! [] (.now js/performance)) 53 | 54 | (defn remove-idx [xs idx] 55 | (let [xs-size (count xs)] 56 | (cond 57 | (or (>= idx xs-size) (neg? idx)) xs 58 | (= xs-size 1) [] 59 | (zero? idx) (subvec xs 1) 60 | (= idx (dec xs-size)) (subvec xs 0 idx) 61 | :else (into [] (concat (subvec xs 0 idx) (subvec xs (inc idx))))))) 62 | 63 | (defn view-focused [store] (get-in store (make-focus-path store))) 64 | -------------------------------------------------------------------------------- /src/app/comp/file_tree.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.comp.file-tree 3 | (:require [hsl.core :refer [hsl]] 4 | [respo.core :refer [defcomp div list-> >> <> span input button]] 5 | [respo-ui.core :as ui] 6 | [clojure.string :as string] 7 | [respo.comp.space :refer [=<]] 8 | [app.comp.brief-file :refer [comp-brief-file]] 9 | [app.style.widget :as widget] 10 | [app.util.keycode :as keycode])) 11 | 12 | (defn on-keydown [draft cursor] 13 | (fn [e dispatch!] 14 | (if (= keycode/key-enter (.-keyCode (:original-event e))) 15 | (do 16 | (if (string/includes? draft "/") 17 | (dispatch! :collection/add-definition (string/split draft "/")) 18 | (dispatch! :collection/add-namespace draft)) 19 | (dispatch! cursor {:draft ""}))))) 20 | 21 | (def style-body {:flex 1, :overflow :auto}) 22 | 23 | (def style-file-tree {:background-color (hsl 0 0 0), :padding "0 16px"}) 24 | 25 | (defcomp 26 | comp-file-tree 27 | (states store) 28 | (let [cursor (:cursor states) 29 | state (or (:data states) {:draft "", :selected-ns nil}) 30 | files (get-in store [:collection :files]) 31 | selected-ns (:selected-ns state)] 32 | (div 33 | {:style (merge ui/expand ui/column style-file-tree)} 34 | (div 35 | {:style (merge ui/row style-body)} 36 | (div 37 | {:style ui/column} 38 | (input 39 | {:value (:draft state), 40 | :placeholder "ns/def or ns", 41 | :style widget/input, 42 | :on-input (fn [e dispatch!] (dispatch! cursor (assoc state :draft (:value e)))), 43 | :on-keydown (on-keydown (:draft state) cursor)}) 44 | (list-> 45 | {:style {:overflow :auto, :padding "8px 0px 200px 0px"}} 46 | (->> (keys files) 47 | (sort) 48 | (map 49 | (fn [ns-name] 50 | [ns-name 51 | (div 52 | {:on-click (fn [e d!] (d! cursor (assoc state :selected-ns ns-name))), 53 | :style (merge 54 | {:color (hsl 0 0 50), :cursor :pointer} 55 | (if (= ns-name selected-ns) {:color (hsl 0 0 100)}))} 56 | (<> ns-name))]))))) 57 | (=< 8 nil) 58 | (if (contains? files selected-ns) 59 | (comp-brief-file (>> states selected-ns) selected-ns (get files selected-ns))))))) 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | Stack Editor 3 | ---- 4 | 5 | > A syntax tree editor for Clojure(Script). 6 | 7 | * [Client App](http://repo.cirru.org/stack-editor/) 8 | * [Editor Shortcuts](https://github.com/Cirru/stack-editor/wiki/Keyboard-Shortcuts) 9 | * [Code Shortcuts](https://github.com/Cirru/respo-cirru-editor/wiki/Keyboard-Shortcuts) 10 | * [Video Introduction](https://youtu.be/PdP7DHlQBoQ) 11 | 12 | ### Different from Calcit Editor 13 | 14 | Current status of Stack Editor is mainly for learning and research. If you want to use in you project, [use Calcit Editor instead!](https://github.com/Cirru/calcit-editor). Calcit Editor has more details and refinements. 15 | 16 | * Stack Editor uses `stack.cirru` as snapshot file, which is mostly vectors in Cirru EDN and human-readalbe. 17 | * Stack Editor connects server via HTTP, which is a bit harder to be consistent. 18 | * Stack Editor has more code loaded in browser, that makes it available for more analysis. 19 | * Stack Editor has not been actively maintained in the years, fewer features... 20 | 21 | ### Usage 22 | 23 | ```bash 24 | npm install -g stack-editor 25 | ``` 26 | 27 | Create `stack.cirru`(witn an entry `app.main/main!`) as snapshot file: 28 | 29 | ```cirru 30 | {} (:package |app) 31 | :root $ {} (:ns |main) (:def |main!) 32 | :files $ {} 33 | ``` 34 | 35 | Run editor: 36 | 37 | ```bash 38 | stack-editor stack.cirru 39 | ``` 40 | 41 |  42 |  43 |  44 | 45 | ### Options 46 | 47 | For the UI, it's served at http://repo.cirru.org/stack-editor/?host=localhost&port=7010 with options: 48 | 49 | * `port`, defaults to `7010`, server port 50 | * `host`, defaults to `"localhost"`, server domain 51 | 52 | The CLI support options: 53 | 54 | ```bash 55 | op=watch port=7010 extension=.cljs out=src/ stack-editor stack.cirru 56 | ``` 57 | 58 | * `port`, defaults to `7010`, server port corresponding to the UI part 59 | * `extension`, defaults to `".cljs"`, file extension of the generated files 60 | * `out`, defaults `src/` output folder 61 | * `op`, defaults to `watch`, or you may use `op=compile` to force compiling 62 | 63 | ### License 64 | 65 | MIT 66 | -------------------------------------------------------------------------------- /src/app/updater.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.updater 3 | (:require [respo.cursor :refer [update-states]] 4 | [app.updater.router :as router] 5 | [app.updater.collection :as collection] 6 | [app.updater.notification :as notification] 7 | [app.updater.stack :as stack] 8 | [app.updater.modal :as modal] 9 | [app.updater.graph :as graph])) 10 | 11 | (defn default-handler [store op-data] store) 12 | 13 | (defn updater [store op op-data op-id] 14 | (let [handler (case op 15 | :states (fn [x] (update-states x op-data)) 16 | :router/route router/route 17 | :router/toggle-palette router/toggle-palette 18 | :router/open-file-tree router/open-file-tree 19 | :collection/add-definition collection/add-definition 20 | :collection/add-namespace collection/add-namespace 21 | :collection/edit collection/edit 22 | :collection/edit-ns collection/edit-ns 23 | :collection/write collection/write-code 24 | :collection/load collection/load-remote 25 | :collection/remove-this collection/remove-this 26 | :collection/remove-file collection/remove-file 27 | :collection/rename collection/rename 28 | :collection/hydrate collection/hydrate 29 | :notification/add-one notification/add-one 30 | :notification/remove-one notification/remove-one 31 | :notification/remove-since notification/remove-since 32 | :stack/goto-definition stack/goto-definition 33 | :stack/dependents stack/dependents 34 | :stack/go-back stack/go-back 35 | :stack/go-next stack/go-next 36 | :stack/point-to stack/point-to 37 | :stack/collapse stack/collapse 38 | :stack/shift stack/shift-one 39 | :modal/mould modal/mould 40 | :modal/recycle modal/recycle 41 | :graph/load-graph graph/load-graph 42 | :graph/view-path graph/view-path 43 | :graph/view-ns graph/view-ns 44 | :graph/edit-current graph/edit-current 45 | :graph/show-orphans graph/show-orphans 46 | default-handler)] 47 | (handler store op-data op-id))) 48 | -------------------------------------------------------------------------------- /src/app/comp/container.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.comp.container 3 | (:require [hsl.core :refer [hsl]] 4 | [respo.comp.inspect :refer [comp-inspect]] 5 | [respo.core :refer [defcomp div >> <> span input]] 6 | [respo-ui.core :as ui] 7 | [app.comp.loading :refer [comp-loading]] 8 | [app.comp.workspace :refer [comp-workspace]] 9 | [app.comp.notifications :refer [comp-notifications]] 10 | [app.comp.palette :refer [comp-palette]] 11 | [app.comp.modal-stack :refer [comp-modal-stack]] 12 | [app.comp.graph :refer [comp-graph]] 13 | [app.util.keycode :as keycode] 14 | [app.util.dom :as dom] 15 | [app.style.widget :as widget] 16 | [app.comp.file-tree :refer [comp-file-tree]])) 17 | 18 | (defcomp 19 | comp-tab 20 | (title code selected?) 21 | (div 22 | {:style (merge 23 | {:font-family ui/font-fancy, 24 | :font-size 18, 25 | :font-weight 300, 26 | :min-width 60, 27 | :color (hsl 0 0 50), 28 | :cursor :pointer} 29 | (if selected? {:color (hsl 0 0 100)})), 30 | :on-click (fn [e d!] (d! :router/route {:name code}))} 31 | (<> title))) 32 | 33 | (defcomp 34 | comp-container 35 | (store) 36 | (let [router (:router store), states (:states store), page (:name router)] 37 | (if (= :router (:name router)) 38 | (comp-loading) 39 | (div 40 | {:style (merge 41 | ui/global 42 | ui/fullscreen 43 | ui/column 44 | {:background-color (hsl 0 0 0), :color (hsl 0 0 70)})} 45 | (div 46 | {:style (merge ui/row-middle {:padding "0 8px"})} 47 | (comp-tab "Files" :file-tree (= page :file-tree)) 48 | (comp-tab "Editor" :workspace (= page :workspace)) 49 | (comp-tab "Graph" :graph (= page :graph))) 50 | (case (:name router) 51 | :workspace (comp-workspace store) 52 | :graph (comp-graph store) 53 | :file-tree (comp-file-tree (>> states :file-tree) store) 54 | (<> (str router) nil)) 55 | (comp-notifications (:notifications store)) 56 | (comment 57 | comp-inspect 58 | "Store" 59 | store 60 | {:bottom 0, :background-color (hsl 0 0 0), :opacity 1, :color :white}) 61 | (if (:show-palette? router) 62 | (comp-palette (>> states :palette) (:files (:collection store)))) 63 | (comp-modal-stack states (:modal-stack store)))))) 64 | -------------------------------------------------------------------------------- /src/app/comp/brief_file.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.comp.brief-file 3 | (:require [hsl.core :refer [hsl]] 4 | [respo.core :refer [defcomp div list-> <> span input]] 5 | [clojure.string :as string] 6 | [respo-ui.core :as ui] 7 | [respo.comp.space :refer [=<]] 8 | [app.style.widget :as widget] 9 | [app.util.keycode :as keycode])) 10 | 11 | (defn on-edit-def [ns-text def-text] 12 | (fn [e dispatch!] 13 | (dispatch! :collection/edit {:kind :defs, :ns ns-text, :extra def-text, :focus [2]}))) 14 | 15 | (defn on-edit-ns [ns-text] 16 | (fn [e dispatch!] 17 | (dispatch! :collection/edit {:kind :ns, :ns ns-text, :extra nil, :focus []}))) 18 | 19 | (defn on-edit-procs [ns-text] 20 | (fn [e dispatch!] 21 | (dispatch! :collection/edit {:kind :procs, :ns ns-text, :extra nil, :focus []}))) 22 | 23 | (defn on-remove [ns-text] (fn [e d! m!] (d! :collection/remove-file ns-text))) 24 | 25 | (def style-file {:padding "0 8px 16px 8px", :line-height 1.6}) 26 | 27 | (defcomp 28 | comp-brief-file 29 | (states ns-text file) 30 | (let [cursor (:cursor states), state (or (:data states) "")] 31 | (div 32 | {:style style-file} 33 | (div 34 | {:style ui/row} 35 | (<> ns-text nil) 36 | (=< 16 nil) 37 | (span {:inner-text "ns", :style {:cursor :pointer}, :on-click (on-edit-ns ns-text)}) 38 | (=< 16 nil) 39 | (span 40 | {:inner-text "procs", :style {:cursor :pointer}, :on-click (on-edit-procs ns-text)}) 41 | (=< 16 nil) 42 | (span 43 | {:inner-text "Delete", :style widget/clickable-text, :on-click (on-remove ns-text)})) 44 | (div 45 | {} 46 | (input 47 | {:value state, 48 | :placeholder "new def", 49 | :style widget/input, 50 | :on-input (fn [e d!] (d! cursor (:value e))), 51 | :on-keydown (fn [e d!] 52 | (if (= keycode/key-enter (:key-code e)) 53 | (if (not (string/blank? state)) 54 | (do (d! :collection/add-definition [ns-text state]) (d! cursor "")))))})) 55 | (=< nil 8) 56 | (list-> 57 | {} 58 | (->> (:defs file) 59 | (sort compare) 60 | (map 61 | (fn [entry] 62 | (let [def-text (key entry)] 63 | [def-text 64 | (div 65 | {:inner-text def-text, 66 | :style {:cursor :pointer, 67 | :font-size 14, 68 | :line-height "24px", 69 | :color (hsl 0 0 50)}, 70 | :on-click (on-edit-def ns-text def-text)})])))))))) 71 | 72 | (defn on-keydown [ns-text def-text] 73 | (fn [e d! m!] 74 | (println "event") 75 | (if (= keycode/key-enter (:key-code e)) 76 | (if (not (string/blank? def-text)) 77 | (do (d! :collection/add-definition [ns-text def-text]) (m! "")))))) 78 | -------------------------------------------------------------------------------- /src/app/actions.cljs: -------------------------------------------------------------------------------- 1 | 2 | (ns app.actions 3 | (:require [cljs.reader :refer [read-string]] 4 | [ajax.core :refer [GET POST PATCH json-request-format]] 5 | [app.util :refer [make-path]] 6 | [app.util.querystring :refer [parse-query]] 7 | [shallow-diff.diff :refer [diff]])) 8 | 9 | (defonce *remote-sepal (atom nil)) 10 | 11 | (defn display-code! [store] 12 | (let [writer (:writer store) 13 | collection (:collection store) 14 | path-info (get (:stack writer) (:pointer writer)) 15 | tree (get-in store (make-path path-info))] 16 | (if (some? tree) 17 | (-> js/window (.open) (.-document) (.write "
" (pr-str tree) "")))))
18 |
19 | (def options
20 | (merge {"port" "7010", "host" "localhost"} (parse-query (.-search js/location))))
21 |
22 | (defn load-collection! [dispatch! file-tree?]
23 | (println (pr-str options))
24 | (GET
25 | (str "http://" (get options "host") ":" (get options "port"))
26 | {:handler (fn [response]
27 | (let [sepal-data (read-string response)]
28 | (if (not (contains? sepal-data :package)) (js/alert "Cannot find a :package field"))
29 | (dispatch! :collection/load sepal-data)
30 | (if file-tree?
31 | (do
32 | (dispatch! :router/route {:name :file-tree, :data nil})
33 | (comment dispatch! :graph/load-graph nil)))
34 | (reset! *remote-sepal sepal-data))),
35 | :error-handler (fn [error]
36 | (println error)
37 | (dispatch! :notification/add-one "Failed to fetch collection"))}))
38 |
39 | (defn submit-changes! [collection dispatch!]
40 | (PATCH
41 | (str "http://" (get options "host") ":" (get options "port"))
42 | {:format (json-request-format),
43 | :body (pr-str (diff @*remote-sepal collection)),
44 | :handler (fn [response]
45 | (println response)
46 | (dispatch! :notification/add-one "Patched")
47 | (reset! *remote-sepal collection)),
48 | :error-handler (fn [error]
49 | (println error)
50 | (if (zero? (:status error))
51 | (dispatch! :notification/add-one "Connection failed!")
52 | (let [response (read-string (:response error))]
53 | (dispatch! :notification/add-one (:status response)))))}))
54 |
55 | (defn submit-collection! [collection dispatch!]
56 | (POST
57 | (str "http://" (get options "host") ":" (get options "port"))
58 | {:format (json-request-format),
59 | :body (pr-str collection),
60 | :handler (fn [response]
61 | (println response)
62 | (dispatch! :notification/add-one "Saved")
63 | (reset! *remote-sepal collection)),
64 | :error-handler (fn [error]
65 | (println error)
66 | (if (zero? (:status error))
67 | (dispatch! :notification/add-one "Connection failed!")
68 | (let [response (read-string (:response error))]
69 | (dispatch! :notification/add-one (:status response)))))}))
70 |
--------------------------------------------------------------------------------
/src/app/comp/graph.cljs:
--------------------------------------------------------------------------------
1 |
2 | (ns app.comp.graph
3 | (:require [hsl.core :refer [hsl]]
4 | [respo.core :refer [defcomp div list-> <> span input button]]
5 | [respo-ui.core :as ui]
6 | [app.comp.def :refer [comp-def]]
7 | [app.util.detect :refer [def-order =def?]]
8 | [respo.comp.space :refer [=<]]
9 | [app.style.widget :as widget]
10 | [clojure.set :as set]))
11 |
12 | (defn on-load [e dispatch!] (dispatch! :graph/load-graph nil))
13 |
14 | (defn on-orphans [e dispatch!] (dispatch! :graph/show-orphans nil))
15 |
16 | (def style-toolbar {:padding 16})
17 |
18 | (defn render-toolbar []
19 | (div
20 | {:style style-toolbar}
21 | (div
22 | {}
23 | (button {:inner-text "Build tree", :style widget/button, :on-click on-load})
24 | (=< 8 nil)
25 | (button {:inner-text "Find orphans", :style widget/button, :on-click on-orphans}))))
26 |
27 | (def style-body {:flex 1, :overflow :auto})
28 |
29 | (def style-column {:min-width 80, :overflow :auto, :padding "16px 16px", :flex-shrink 0})
30 |
31 | (def style-graph {:background-color (hsl 0 0 0), :overflow :auto})
32 |
33 | (defcomp
34 | comp-graph
35 | (store)
36 | (div
37 | {:style (merge ui/expand ui/column style-graph)}
38 | (render-toolbar)
39 | (let [tree (get-in store [:graph :tree])
40 | root-tree (assoc (get-in store [:collection :root]) :deps #{tree})
41 | view-path (get-in store [:graph :path])]
42 | (if (some? tree)
43 | (list->
44 | {:style (merge ui/row style-body)}
45 | (loop [branch root-tree, children [], path []]
46 | (let [next-path (conj path (get view-path (count path)))
47 | next-pos (get view-path (count path))
48 | next-children (conj
49 | children
50 | [(count children)
51 | (list->
52 | {:style style-column}
53 | (->> (:deps branch)
54 | (sort def-order)
55 | (map-indexed
56 | (fn [idx child-node]
57 | [idx
58 | (comp-def
59 | child-node
60 | path
61 | (=def? next-pos child-node))]))))])]
62 | (if (= path view-path)
63 | next-children
64 | (let [next-branch (->> (:deps branch)
65 | (set/select
66 | (fn [x] (=def? (get view-path (count path)) x)))
67 | (first))]
68 | (recur next-branch next-children next-path))))))
69 | (<> div "Not generated yet." {:padding "0 16px"})))))
70 |
--------------------------------------------------------------------------------
/src/app/main.cljs:
--------------------------------------------------------------------------------
1 |
2 | (ns app.main
3 | (:require [respo.core :refer [render! clear-cache! render-element realize-ssr!]]
4 | [app.schema :as schema]
5 | [app.comp.container :refer [comp-container]]
6 | [cljs.reader :refer [read-string]]
7 | [app.updater :refer [updater]]
8 | [app.util.keycode :as keycode]
9 | [app.util.dom :as dom]
10 | [app.util :refer [now!]]
11 | [app.actions
12 | :refer
13 | [load-collection! submit-collection! submit-changes! display-code!]]
14 | [cirru-editor.util.dom :refer [focus!]]))
15 |
16 | (def *focus-moved? (atom false))
17 |
18 | (defonce *store (atom schema/store))
19 |
20 | (defn dispatch! [op op-data]
21 | (println "Dispatch!" op)
22 | (case op
23 | :effect/submit
24 | (let [shift? op-data, sepal-data (:collection @*store)]
25 | (if shift?
26 | (submit-collection! sepal-data dispatch!)
27 | (submit-changes! sepal-data dispatch!)))
28 | :effect/dehydrate (display-code! @*store)
29 | :effect/load (load-collection! dispatch! false)
30 | (let [new-store (updater @*store op op-data (now!))]
31 | (reset!
32 | *focus-moved?
33 | (not
34 | (and (identical? (:collection @*store) (:collection new-store))
35 | (identical? (:writer @*store) (:writer new-store)))))
36 | (reset! *store new-store))))
37 |
38 | (def mount-target (.querySelector js/document ".app"))
39 |
40 | (defn render-app! [renderer]
41 | (renderer mount-target (comp-container @*store) dispatch!)
42 | (if @*focus-moved? (do (reset! *focus-moved? false) (focus!))))
43 |
44 | (def ssr? (some? (.querySelector js/document "meta.server-rendered")))
45 |
46 | (defn main! []
47 | (if ssr? (render-app! realize-ssr!))
48 | (render-app! render!)
49 | (add-watch *store :changes (fn [] (render-app! render!)))
50 | (.addEventListener
51 | js/window
52 | "keydown"
53 | (fn [event]
54 | (let [code (.-keyCode event)
55 | command? (or (.-metaKey event) (.-ctrlKey event))
56 | shift? (.-shiftKey event)]
57 | (cond
58 | (and command? (= code keycode/key-p))
59 | (do
60 | (.preventDefault event)
61 | (.stopPropagation event)
62 | (dispatch! :router/toggle-palette nil)
63 | (dom/focus-palette!))
64 | (and shift? command? (= code keycode/key-a))
65 | (do
66 | (let [router (:router @*store), writer (:writer @*store)]
67 | (if (= (:name router) :workspace)
68 | (dispatch! :router/route {:name :graph, :data nil})
69 | (if (not (empty? (:stack writer)))
70 | (dispatch! :router/route {:name :workspace, :data nil})))))
71 | :else nil))))
72 | (println "app started!")
73 | (load-collection! dispatch! true))
74 |
75 | (defn reload! [] (clear-cache!) (render-app! render!) (println "Code updated."))
76 |
--------------------------------------------------------------------------------
/src/app/comp/workspace.cljs:
--------------------------------------------------------------------------------
1 |
2 | (ns app.comp.workspace
3 | (:require [hsl.core :refer [hsl]]
4 | [respo.core :refer [defcomp div <> >> span input]]
5 | [respo.comp.space :refer [=<]]
6 | [respo.comp.inspect :refer [comp-inspect]]
7 | [respo-ui.core :as ui]
8 | [app.comp.stack :refer [comp-stack]]
9 | [cirru-editor.comp.editor :refer [comp-editor]]
10 | [app.util.keycode :as keycode]
11 | [app.util.dom :as dom]
12 | [app.util :refer [make-path]]
13 | [app.style.widget :as widget]))
14 |
15 | (defn on-command [store]
16 | (fn [snapshot dispatch! e]
17 | (let [code (:key-code e)
18 | event (:original-event e)
19 | command? (or (.-metaKey event) (.-ctrlKey event))
20 | shift? (.-shiftKey event)]
21 | (cond
22 | (= code keycode/key-d)
23 | (do (.preventDefault event) (dispatch! :stack/goto-definition shift?))
24 | (= code keycode/key-u)
25 | (do (.preventDefault event) (dispatch! :stack/dependents nil))
26 | (= code keycode/key-i) (do (.preventDefault event) (dispatch! :stack/go-back nil))
27 | (= code keycode/key-k)
28 | (do (.preventDefault event) (dispatch! :stack/shift (-> store :writer :pointer)))
29 | (= code keycode/key-j) (do (.preventDefault event) (dispatch! :stack/go-next nil))
30 | (= code keycode/key-s)
31 | (do (.preventDefault event) (dispatch! :effect/submit shift?))
32 | (and command? (= code keycode/key-p))
33 | (do
34 | (.preventDefault event)
35 | (.stopPropagation event)
36 | (dispatch! :router/toggle-palette nil)
37 | (dom/focus-palette!))
38 | (and command? (not shift?) (= code keycode/key-e))
39 | (do (.preventDefault event) (dispatch! :collection/edit-ns nil))
40 | :else nil))))
41 |
42 | (defn on-remove [e dispatch!] (dispatch! :collection/remove-this nil))
43 |
44 | (defn on-rename [code-path]
45 | (fn [e dispatch!]
46 | (println "the code path:" code-path)
47 | (dispatch! :modal/mould {:title :rename-path, :data code-path})
48 | (dom/focus-rename!)))
49 |
50 | (defn on-update [snapshot dispatch!] (dispatch! :collection/write snapshot))
51 |
52 | (def style-container {:background-color (hsl 0 0 0)})
53 |
54 | (def style-debugger {:z-index 999, :background-color (hsl 0 0 0), :opacity 1})
55 |
56 | (def style-removed
57 | {:margin "32px 16px",
58 | :font-size "20px",
59 | :font-weight "lighter",
60 | :color (hsl 0 80 50),
61 | :font-family "Josefin Sans",
62 | :padding "0 16px",
63 | :display "inline-block",
64 | :max-width "400px"})
65 |
66 | (def style-sidebar {:width "180px", :background-color (hsl 0 0 0), :color (hsl 0 0 80)})
67 |
68 | (def style-toolbar {:background-color (hsl 0 0 0), :justify-content "flex-start"})
69 |
70 | (defcomp
71 | comp-workspace
72 | (store)
73 | (let [router (:router store)
74 | states (:states store)
75 | writer (:writer store)
76 | stack (get-in store [:writer :stack])
77 | pointer (get-in store [:writer :pointer])
78 | code-path (get stack pointer)
79 | tree (if (some? code-path) (get-in store (make-path code-path)) nil)]
80 | (div
81 | {:style (merge ui/expand ui/row style-container)}
82 | (div {:style (merge ui/column style-sidebar)} (comp-stack stack pointer))
83 | (comment comp-inspect writer style-debugger)
84 | (if (some? tree)
85 | (div
86 | {:style (merge ui/column ui/flex)}
87 | (comp-editor
88 | (>> states :editor)
89 | {:tree tree, :focus (:focus code-path), :clipboard (:clipboard writer)}
90 | on-update
91 | (on-command store))
92 | (div
93 | {:style (merge ui/row style-toolbar)}
94 | (div
95 | {:inner-text "Rename",
96 | :class-name "is-unremarkable",
97 | :style widget/clickable-text,
98 | :on-click (on-rename code-path)})
99 | (=< 8 nil)
100 | (div
101 | {:inner-text "Delete",
102 | :class-name "is-unremarkable",
103 | :style widget/clickable-text,
104 | :on-click on-remove})))
105 | (div
106 | {:style (merge ui/column ui/flex)}
107 | (div {:style style-removed} (<> span "No expression" nil)))))))
108 |
--------------------------------------------------------------------------------
/src/app/comp/palette.cljs:
--------------------------------------------------------------------------------
1 |
2 | (ns app.comp.palette
3 | (:require [clojure.string :as string]
4 | [hsl.core :refer [hsl]]
5 | [respo.core :refer [defcomp list-> div <> span input]]
6 | [respo-ui.core :as ui]
7 | [cirru-editor.util.dom :refer [focus!]]
8 | [app.comp.command :refer [comp-command]]
9 | [app.util.keycode :as keycode]
10 | [app.style.widget :as widget]
11 | [app.util.detect :refer [fuzzy-search]]))
12 |
13 | (def basic-commands [[:save] [:load] [:hydrate] [:dehydrate] [:graph]])
14 |
15 | (defn handle-command [cursor commands files dispatch!]
16 | (let [command (get (into [] commands) cursor)]
17 | (println "Command" (pr-str command))
18 | (dispatch! :router/toggle-palette nil)
19 | (case (first command)
20 | :load (dispatch! :effect/load nil)
21 | :patch (dispatch! :effect/submit true)
22 | :dehydrate (dispatch! :effect/dehydrate nil)
23 | :hydrate (dispatch! :modal/mould {:title :hydrate, :data nil})
24 | :graph (dispatch! :router/route {:name :graph, :data nil})
25 | :defs
26 | (do
27 | (dispatch!
28 | :collection/edit
29 | {:ns (get command 1), :kind :defs, :extra (last command), :focus [0]}))
30 | :ns
31 | (do
32 | (dispatch!
33 | :collection/edit
34 | {:ns (get command 1), :kind :ns, :extra nil, :focus [0]}))
35 | :procs
36 | (do
37 | (dispatch!
38 | :collection/edit
39 | {:ns (get command 1), :kind :procs, :extra nil, :focus [0]})))))
40 |
41 | (def initial-state {:text "", :cursor 0})
42 |
43 | (defn on-input [cursor state]
44 | (fn [e dispatch!] (dispatch! :states [cursor (merge state {:text (:value e), :cursor 0})])))
45 |
46 | (defn on-keydown [respo-cursor state commands cursor collection]
47 | (fn [e dispatch!]
48 | (let [code (:key-code e), total (count commands)]
49 | (cond
50 | (= code keycode/key-esc)
51 | (do
52 | (dispatch! :states [respo-cursor (merge state {:text ""})])
53 | (dispatch! :router/toggle-palette nil)
54 | (focus!))
55 | (= code keycode/key-down)
56 | (if (< cursor (dec total))
57 | (dispatch! :states [respo-cursor (merge state {:cursor (inc cursor)})]))
58 | (= code keycode/key-up)
59 | (if (> cursor 0)
60 | (dispatch! :states [respo-cursor (merge state {:cursor (dec cursor)})]))
61 | (= code keycode/key-enter)
62 | (do
63 | (dispatch! :states [respo-cursor (merge state {:text ""})])
64 | (handle-command cursor commands collection dispatch!))
65 | :else nil))))
66 |
67 | (defn on-select [cursor commands files]
68 | (fn [dispatch!] (handle-command cursor commands files dispatch!)))
69 |
70 | (def style-container
71 | {:position "fixed", :background-color (hsl 200 40 10 0.8), :justify-content "center"})
72 |
73 | (defcomp
74 | comp-palette
75 | (states files)
76 | (let [ns-names (->> (keys files) (map (fn [path] [:ns path])))
77 | cursor (:cursor states)
78 | state (or (:data states) initial-state)
79 | def-paths (->> files
80 | (map
81 | (fn [entry]
82 | (let [[ns-part tree] entry]
83 | (->> (:defs tree)
84 | (keys)
85 | (map (fn [def-name] [:defs ns-part def-name]))))))
86 | (apply concat))
87 | procedure-names (->> (keys files) (map (fn [proc-name] [:procs proc-name])))
88 | queries (string/split (:text state) " ")
89 | commands (->> (concat def-paths ns-names procedure-names basic-commands)
90 | (filter (fn [command] (fuzzy-search command queries))))]
91 | (div
92 | {:style (merge ui/fullscreen ui/row style-container)}
93 | (div
94 | {:style (merge ui/column {:background-color (hsl 0 0 0 0.8), :width "800px"})}
95 | (input
96 | {:placeholder "write command...",
97 | :id "command-palette",
98 | :value (:text state),
99 | :style (merge widget/input {:width "100%", :line-height "40px"}),
100 | :autocomplete "off",
101 | :on-input (on-input cursor state),
102 | :on-keydown (on-keydown cursor state commands (:cursor state) files)})
103 | (list->
104 | {:style (merge ui/flex {:overflow "auto"})}
105 | (->> commands
106 | (map-indexed
107 | (fn [idx command]
108 | [idx
109 | (comp-command command (= idx (:cursor state)) (on-select idx commands files))]))))))))
110 |
--------------------------------------------------------------------------------
/server/app/server.cljs:
--------------------------------------------------------------------------------
1 | (ns app.server
2 | (:require [cljs.reader :refer [read-string]]
3 | [clojure.string :as string]
4 | [clojure.set :refer [difference]]
5 | [cljs.core.async :refer [! timeout chan]]
6 | [shallow-diff.patch :refer [patch]]
7 | [cirru-sepal.analyze :refer [write-file ns->path]]
8 | [cirru-edn.core :as cirru-edn]
9 | [fipp.edn :refer [pprint]]
10 | [app.walk :refer [walk]]
11 | ["fs" :as fs]
12 | ["http" :as http]
13 | ["path" :as path]
14 | ["mkdirp" :as mkdirp])
15 | (:require-macros [cljs.core.async.macros :refer [go]]))
16 |
17 | (def ir-path
18 | (or
19 | (get (js->clj js/process.argv) 2)
20 | (if (fs/existsSync "stack.cirru") "stack.cirru")
21 | (do
22 | (println "Missing file: stack.cirru not found!")
23 | (.exit js/process 1))))
24 |
25 | (def ref-sepal
26 | (atom
27 | (if (fs/existsSync ir-path)
28 | (cirru-edn/parse (fs/readFileSync ir-path "utf8"))
29 | (do (.log js/console (str "Error: " ir-path " does not exist!"))
30 | (.exit js/process 1)))))
31 |
32 | (def extension (or js/process.env.extension (:extension @ref-sepal) ".cljs"))
33 | (def out-folder (or js/process.env.out (get-in @ref-sepal [:options :src]) "src/"))
34 | (def port (js/parseInt (or js/process.env.port (get-in @ref-sepal [:options :port]) "7010")))
35 |
36 | (defn read-body [^js req]
37 | (let [body-ref (atom "")
38 | body-chan (chan)]
39 | (.on req "data" (fn [chunk] (swap! body-ref str chunk)))
40 | (.on req "end" (fn [] (go (>! body-chan @body-ref))))
41 | body-chan))
42 |
43 | (defn rewrite-file! [content]
44 | (fs/writeFileSync ir-path (cirru-edn/write content)))
45 |
46 | (defn write-by-file [pkg ns-part file-info]
47 | (let [file-name (str (ns->path pkg ns-part) extension)
48 | content (write-file file-info)
49 | file-target (path/join out-folder file-name)
50 | container (path/dirname file-target)]
51 | (println "File compiled:" file-name)
52 | (if (not (fs/existsSync container))
53 | (do
54 | (println "Creating folder:" container)
55 | (mkdirp/sync container)))
56 | (fs/writeFileSync file-target content)))
57 |
58 | (defn compare-write-source! [sepal-data]
59 | (doseq [entry (:files sepal-data)]
60 | (let [[ns-part file-info] entry
61 | changed? (not (identical? file-info (get-in @ref-sepal [:files ns-part])))]
62 | (if changed?
63 | (write-by-file (:package sepal-data) ns-part file-info)))))
64 |
65 | (defn compile-source! [sepal-data]
66 | (doseq [entry (:files sepal-data)]
67 | (let [[ns-part file-info] entry]
68 | (write-by-file (:package sepal-data) ns-part file-info))))
69 |
70 | (defn req-handler [^js req ^js res]
71 | (if (some? req.headers.origin)
72 | (.setHeader res "Access-Control-Allow-Origin" req.headers.origin))
73 | (.setHeader res "Content-Type" "text/edn; charset=UTF-8")
74 | (.setHeader res "Access-Control-Allow-Methods" "GET, POST, PATCH, OPTIONS")
75 | (case req.method
76 | "GET" (.end res (pr-str @ref-sepal))
77 | "POST"
78 | (go (let [content (> data
20 | (filter (fn [x] (not= x "[]")))
21 | (map (fn [x] [x {:kind :refer, :ns ns-text, :text x}]))
22 | (into {})
23 | (merge result))
24 | :else result)))))))
25 |
26 | (defn parse-ns-deps [expression]
27 | (let [branches (->> (subvec expression 2) (filter (fn [expr] (= ":require" (first expr)))))]
28 | (if (empty? branches) {} (doall (reduce parse-rule {} (rest (first branches)))))))
29 |
30 | (defn pick-dep [token]
31 | (cond
32 | (string/blank? token) nil
33 | (string/starts-with? token ":") nil
34 | (string/starts-with? token ".") nil
35 | (string/starts-with? token "|") nil
36 | (string/starts-with? token "#") nil
37 | (string/starts-with? token "[") nil
38 | (string/starts-with? token "'") nil
39 | (string/starts-with? token "{") nil
40 | (string/starts-with? token "%") nil
41 | (string/starts-with? token "\\") nil
42 | (= token "--") nil
43 | (string/includes? token "/")
44 | (let [[ns-piece def-piece] (string/split token "/")]
45 | {:kind :ns, :data ns-piece, :extra def-piece})
46 | (string/includes? token ".")
47 | (let [[def-piece prop-piece] (string/split token ".")] {:kind :def, :data def-piece})
48 | (string/starts-with? token "@") {:kind :def, :data (subs token 1)}
49 | :else {:kind :def, :data token}))
50 |
51 | (defn extract-deps [expression internal-ns file pkg]
52 | (let [external? (fn [ns-text] (not (string/starts-with? ns-text (str pkg "."))))
53 | ns-deps (parse-ns-deps (:ns file))]
54 | (->> expression
55 | (flatten)
56 | (map pick-dep)
57 | (filter some?)
58 | (map
59 | (fn [info]
60 | (case (:kind info)
61 | :def
62 | (let [def-text (:data info), defs (:defs file)]
63 | (cond
64 | (contains? ns-deps def-text)
65 | (let [using-mapping (get ns-deps def-text)]
66 | (if (= :refer (:kind using-mapping))
67 | (let [ns-text (:ns using-mapping)]
68 | {:ns ns-text, :def def-text, :external? (external? ns-text)})
69 | nil))
70 | (contains? defs def-text)
71 | {:ns (str pkg "." internal-ns), :def def-text, :external? false}
72 | :else nil))
73 | :ns
74 | (let [{ns-text :data, def-text :extra} info]
75 | (if (contains? ns-deps ns-text)
76 | (let [using-mapping (get ns-deps ns-text)]
77 | (if (= :as (:kind using-mapping))
78 | (let [ns-text (:ns using-mapping)]
79 | {:ns ns-text, :def def-text, :external? (external? ns-text)})
80 | nil))
81 | nil)))))
82 | (filter some?)
83 | (into #{}))))
84 |
85 | (defn expand-deps-tree [internal-ns def-text files pkg parents]
86 | (let [this-file (get files internal-ns)
87 | def-expr (get-in this-file [:defs def-text])
88 | stamp {:ns internal-ns, :def def-text}
89 | base-dep {:ns internal-ns, :def def-text, :external? false, :circular? false}]
90 | (if (nil? def-expr)
91 | (assoc base-dep :external? true)
92 | (if (contains? parents stamp)
93 | (assoc base-dep :circular? true)
94 | (assoc
95 | base-dep
96 | :deps
97 | (let [def-deps (if (some? def-expr)
98 | (extract-deps (subvec def-expr 2) internal-ns this-file pkg)
99 | nil)]
100 | (->> def-deps
101 | (map
102 | (fn [dep-info]
103 | (if (:external? dep-info)
104 | dep-info
105 | (let [child-internal-ns (string/replace-first
106 | (:ns dep-info)
107 | (str pkg ".")
108 | "")
109 | child-def (:def dep-info)
110 | next-parents (conj parents stamp)]
111 | (expand-deps-tree child-internal-ns child-def files pkg next-parents)))))
112 | (into #{}))))))))
113 |
114 | (defn list-dependent-ns [ns-name files pkg]
115 | (let [full-ns (str pkg "." ns-name)
116 | pick-ns (fn [xs] (if (use-vector? xs) (get xs 1) (first xs)))]
117 | (->> files
118 | (filter
119 | (fn [entry]
120 | (let [[ns-part file] entry
121 | ns-expr (:ns file)
122 | ns-rules (->> (subvec ns-expr 2)
123 | (map rest)
124 | (apply concat)
125 | (map pick-ns)
126 | (into #{}))]
127 | (comment println "Search:" ns-name ns-rules)
128 | (contains? ns-rules full-ns))))
129 | (map first)
130 | (into #{}))))
131 |
--------------------------------------------------------------------------------
/src/app/updater/collection.cljs:
--------------------------------------------------------------------------------
1 |
2 | (ns app.updater.collection
3 | (:require [clojure.string :as string]
4 | [app.util :refer [helper-notify make-path view-focused make-focus-path]]
5 | [app.util.detect :refer [=path?]]
6 | (app.util.stack :refer (push-path))))
7 |
8 | (defn add-definition [store op-data]
9 | (let [[that-ns that-name] op-data
10 | path [:collection :files that-ns :defs that-name]
11 | maybe-definition (get-in store path)]
12 | (if (some? maybe-definition) store (assoc-in store path ["defn" that-name []]))))
13 |
14 | (defn add-namespace [store op-data]
15 | (let [namespace' op-data
16 | basic-code ["ns" (str (get-in store [:collection :package]) "." namespace')]]
17 | (-> store
18 | (assoc-in [:collection :files namespace'] {:ns basic-code, :defs {}, :procs []}))))
19 |
20 | (defn edit [store op-data]
21 | (let [path op-data]
22 | (-> store
23 | (update :writer (push-path op-data))
24 | (assoc :router {:name :workspace, :data nil}))))
25 |
26 | (defn edit-ns [store op-data op-id]
27 | (let [writer (:writer store)
28 | stack (:stack writer)
29 | pointer (:pointer writer)
30 | code-path (get stack pointer)
31 | pkg (get-in store [:collection :package])]
32 | (comment println "Edit ns:" code-path)
33 | (if (= (:kind code-path) :ns)
34 | (let [guess-ns (view-focused store)
35 | ns-name (if (some? guess-ns) (string/replace guess-ns (str pkg ".") "") nil)]
36 | (if (and (some? ns-name) (some? (get-in store [:collection :files ns-name])))
37 | (update store :writer (push-path {:ns ns-name, :kind :ns, :extra nil, :focus []}))
38 | (update
39 | store
40 | :notifications
41 | (fn [notifications] (helper-notify op-id (str "\"" ns-name "\" not found"))))))
42 | (update
43 | store
44 | :writer
45 | (push-path {:ns (:ns code-path), :kind :ns, :extra nil, :focus []})))))
46 |
47 | (defn hydrate [store op-data op-id]
48 | (let [writer (:writer store)
49 | collection (:collection store)
50 | code-path (get (:stack writer) (:pointer writer))]
51 | (println code-path)
52 | (assoc-in store (concat (make-path code-path) (:focus code-path)) op-data)))
53 |
54 | (defn load-remote [store op-data]
55 | (let [collection op-data]
56 | (comment println "loading:" collection)
57 | (-> store (update :collection (fn [cursor] (merge cursor collection))))))
58 |
59 | (defn remove-file [store op-data op-id]
60 | (update-in store [:collection :files] (fn [files] (dissoc files op-data))))
61 |
62 | (defn remove-this [store op-data op-id]
63 | (let [writer (:writer store)
64 | stack (:stack writer)
65 | pointer (:pointer writer)
66 | {ns-part :ns, kind :kind, extra-name :extra} (get stack pointer)]
67 | (-> store
68 | (update-in
69 | [:collection :files]
70 | (fn [files]
71 | (case kind
72 | :defs (update-in files [ns-part :defs] (fn [defs] (dissoc defs extra-name)))
73 | :procs (assoc-in files [ns-part :procs] [])
74 | :ns (dissoc files ns-part)
75 | files)))
76 | (update-in
77 | [:writer :stack]
78 | (fn [stack]
79 | (cond
80 | (empty? stack) stack
81 | (zero? pointer) (subvec stack 1)
82 | (= (inc pointer) (count stack)) (subvec stack 0 (dec (count stack)))
83 | :else (into [] (concat (subvec stack 0 pointer) (subvec stack (inc pointer)))))))
84 | (update-in
85 | [:writer :pointer]
86 | (fn [pointer] (if (pos? pointer) (dec pointer) pointer))))))
87 |
88 | (defn rename [store op-data op-id]
89 | (let [[code-path new-form] op-data
90 | {ns-part :ns, kind :kind, extra-name :extra, focus :focus} code-path
91 | pointer (get-in store [:writer :pointer])]
92 | (case kind
93 | :ns
94 | (-> store
95 | (update-in
96 | [:collection :files]
97 | (fn [files] (-> files (dissoc ns-part) (assoc new-form (get files ns-part)))))
98 | (assoc-in
99 | [:writer :stack pointer]
100 | {:ns new-form, :kind :ns, :extra nil, :focus focus}))
101 | :defs
102 | (let [[new-ns new-name] (string/split new-form "/")]
103 | (-> store
104 | (update-in
105 | [:collection :files]
106 | (fn [files]
107 | (if (= new-ns ns-part)
108 | (update-in
109 | files
110 | [ns-part :defs]
111 | (fn [dict]
112 | (let [def-code (get dict extra-name)]
113 | (-> dict
114 | (dissoc extra-name)
115 | (assoc new-name (assoc def-code 1 new-name))))))
116 | (let [def-code (get-in files [ns-part :defs extra-name])]
117 | (-> files
118 | (update-in [ns-part :defs] (fn [dict] (dissoc dict extra-name)))
119 | (assoc-in [new-ns :defs new-name] (assoc def-code 1 new-name)))))))
120 | (assoc-in
121 | [:writer :stack pointer]
122 | {:ns new-ns, :kind :defs, :extra new-name, :focus focus})))
123 | (do (println "Cannot rename:" code-path new-form) store))))
124 |
125 | (defn write-code [store op-data]
126 | (let [tree (:tree op-data)
127 | focus (:focus op-data)
128 | writer (:writer store)
129 | stack (:stack writer)
130 | pointer (:pointer writer)
131 | clipboard (:clipboard op-data)
132 | path-info (get stack pointer)]
133 | (-> store
134 | (assoc-in [:writer :stack pointer :focus] focus)
135 | (assoc-in [:writer :clipboard] clipboard)
136 | (assoc-in (make-path path-info) tree))))
137 |
--------------------------------------------------------------------------------
/src/app/updater/stack.cljs:
--------------------------------------------------------------------------------
1 |
2 | (ns app.updater.stack
3 | (:require [clojure.string :as string]
4 | [app.util.analyze :refer [list-dependent-ns parse-ns-deps extract-deps]]
5 | [app.util.detect :refer [strip-atom contains-def? =path?]]
6 | [app.util :refer [remove-idx helper-notify helper-create-def make-path has-ns?]]
7 | (app.util.stack :refer (push-path push-paths))
8 | (clojure.set :refer (union))))
9 |
10 | (defn collapse [store op-data op-id]
11 | (let [cursor op-data]
12 | (update
13 | store
14 | :writer
15 | (fn [writer]
16 | (-> writer (assoc :pointer 0) (update :stack (fn [stack] (subvec stack cursor))))))))
17 |
18 | (defn dependents [store op-data op-id]
19 | (let [writer (:writer store)
20 | {stack :stack, pointer :pointer} writer
21 | code-path (get stack pointer)
22 | {ns-part :ns, kind :kind, extra-name :extra} code-path
23 | pkg (get-in store [:collection :package])
24 | def-as-dep {:ns (str pkg "." ns-part), :def extra-name, :external? false}
25 | files (get-in store [:collection :files])
26 | ns-list (list-dependent-ns ns-part files pkg)]
27 | (case kind
28 | :defs
29 | (let [new-paths (->> (conj ns-list ns-part)
30 | (map
31 | (fn [ns-text]
32 | (let [file (get files ns-text)]
33 | (into
34 | #{}
35 | (concat
36 | (->> (:defs file)
37 | (filter
38 | (fn [entry]
39 | (let [def-deps (extract-deps
40 | (subvec (val entry) 2)
41 | ns-part file
42 | pkg)]
43 | (contains? def-deps def-as-dep))))
44 | (map
45 | (fn [entry]
46 | {:kind :defs,
47 | :ns ns-text,
48 | :extra (first entry),
49 | :focus [2]})))
50 | (let [proc-deps (extract-deps
51 | (:procs file)
52 | ns-part
53 | file
54 | pkg)]
55 | (if (contains? proc-deps def-as-dep)
56 | (list
57 | {:kind :procs, :ns ns-text, :extra nil, :focus [0]})
58 | (list))))))))
59 | (apply concat)
60 | (filter (fn [x] (not (=path? x code-path)))))]
61 | (if (empty? new-paths)
62 | (update store :notifications (helper-notify op-id "Nothing found."))
63 | (update store :writer (push-paths new-paths))))
64 | :ns
65 | (let [new-paths (map (fn [x] [x :ns]) ns-list)]
66 | (comment println pointer new-paths)
67 | (update store :writer (push-paths new-paths)))
68 | store)))
69 |
70 | (defn go-back [store op-data]
71 | (-> store
72 | (update
73 | :writer
74 | (fn [writer]
75 | (if (pos? (:pointer writer))
76 | (-> writer (update :pointer dec) (assoc :focus []))
77 | writer)))))
78 |
79 | (defn go-next [store op-data]
80 | (-> store
81 | (update
82 | :writer
83 | (fn [writer]
84 | (if (< (:pointer writer) (dec (count (:stack writer))))
85 | (-> writer (update :pointer inc) (assoc :focus []))
86 | writer)))))
87 |
88 | (defn goto-definition [store op-data op-id]
89 | (let [forced? op-data
90 | {pkg :package, files :files} (get-in store [:collection])
91 | pkg_ (str pkg ".")
92 | {stack :stack, pointer :pointer} (:writer store)
93 | code-path (get stack pointer)
94 | focus (:focus code-path)
95 | target (strip-atom (get-in store (concat (make-path code-path) focus)))
96 | ns-deps (parse-ns-deps (get-in files [(:ns code-path) :ns]))
97 | current-ns-defs (get-in files [(:ns code-path) :defs])
98 | dep-info (if (has-ns? target)
99 | (let [[ns-text def-text] (string/split target "/")
100 | maybe-info (get ns-deps ns-text)]
101 | (if (and (some? maybe-info) (= :as (:kind maybe-info)))
102 | {:ns (:ns maybe-info), :def def-text}
103 | nil))
104 | (let [maybe-info (get ns-deps target)]
105 | (if (and (some? maybe-info) (= :refer (:kind maybe-info)))
106 | {:ns (:ns maybe-info), :def target}
107 | (if (or (contains? current-ns-defs target) forced?)
108 | {:ns (str pkg_ (:ns code-path)), :def target}
109 | nil))))]
110 | (comment println target dep-info)
111 | (if (some? dep-info)
112 | (if (string/starts-with? (:ns dep-info) pkg_)
113 | (let [existed? (some? (get-in files [(:ns dep-info) :defs (:def dep-info)]))
114 | shorten-ns (string/replace-first (:ns dep-info) pkg_ "")
115 | touch-def (fn [store]
116 | (println "touching" existed?)
117 | (if existed?
118 | store
119 | (-> store
120 | (update-in
121 | [:collection :files]
122 | (helper-create-def
123 | shorten-ns
124 | (:def dep-info)
125 | code-path
126 | (:focus code-path))))))]
127 | (-> store
128 | (touch-def)
129 | (update
130 | :writer
131 | (push-path {:kind :defs, :ns shorten-ns, :extra (:def dep-info), :focus [2]}))))
132 | (-> store
133 | (update
134 | :notifications
135 | (helper-notify op-id (str "External package: " (:ns dep-info))))))
136 | (-> store (update :notifications (helper-notify op-id (str "Can't find: " target)))))))
137 |
138 | (defn point-to [store op-data op-id]
139 | (let [pointer op-data] (assoc-in store [:writer :pointer] pointer)))
140 |
141 | (defn shift-one [store op-data op-id]
142 | (let [pointer op-data]
143 | (update
144 | store
145 | :writer
146 | (fn [writer]
147 | (-> writer
148 | (update :stack (fn [stack] (remove-idx stack pointer)))
149 | (update
150 | :pointer
151 | (fn [p] (if (= p pointer) (if (pos? p) (dec p) p) (if (< p pointer) p (dec p))))))))))
152 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | asn1.js@^4.0.0:
6 | version "4.10.1"
7 | resolved "https://registry.npm.taobao.org/asn1.js/download/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0"
8 | integrity sha1-ucK/WAXx5kqt7tbfOiv6+1pz9aA=
9 | dependencies:
10 | bn.js "^4.0.0"
11 | inherits "^2.0.1"
12 | minimalistic-assert "^1.0.0"
13 |
14 | asn1.js@^5.2.0:
15 | version "5.4.1"
16 | resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07"
17 | integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==
18 | dependencies:
19 | bn.js "^4.0.0"
20 | inherits "^2.0.1"
21 | minimalistic-assert "^1.0.0"
22 | safer-buffer "^2.1.0"
23 |
24 | assert@^1.1.1:
25 | version "1.5.0"
26 | resolved "https://registry.npm.taobao.org/assert/download/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb"
27 | integrity sha1-VcEJqvbgrv2z3EtxJAxwv1dLGOs=
28 | dependencies:
29 | object-assign "^4.1.1"
30 | util "0.10.3"
31 |
32 | async-limiter@~1.0.0:
33 | version "1.0.1"
34 | resolved "https://registry.npm.taobao.org/async-limiter/download/async-limiter-1.0.1.tgz?cache=0&sync_timestamp=1574272018408&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fasync-limiter%2Fdownload%2Fasync-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
35 | integrity sha1-3TeelPDbgxCwgpH51kwyCXZmF/0=
36 |
37 | available-typed-arrays@^1.0.7:
38 | version "1.0.7"
39 | resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846"
40 | integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==
41 | dependencies:
42 | possible-typed-array-names "^1.0.0"
43 |
44 | base64-js@^1.0.2:
45 | version "1.3.1"
46 | resolved "https://registry.npm.taobao.org/base64-js/download/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
47 | integrity sha1-WOzoy3XdB+ce0IxzarxfrE2/jfE=
48 |
49 | bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9:
50 | version "4.12.0"
51 | resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
52 | integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
53 |
54 | bn.js@^5.0.0, bn.js@^5.2.1:
55 | version "5.2.1"
56 | resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70"
57 | integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==
58 |
59 | brorand@^1.0.1, brorand@^1.1.0:
60 | version "1.1.0"
61 | resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
62 | integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
63 |
64 | browserify-aes@^1.0.0, browserify-aes@^1.0.4:
65 | version "1.2.0"
66 | resolved "https://registry.npm.taobao.org/browserify-aes/download/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48"
67 | integrity sha1-Mmc0ZC9APavDADIJhTu3CtQo70g=
68 | dependencies:
69 | buffer-xor "^1.0.3"
70 | cipher-base "^1.0.0"
71 | create-hash "^1.1.0"
72 | evp_bytestokey "^1.0.3"
73 | inherits "^2.0.1"
74 | safe-buffer "^5.0.1"
75 |
76 | browserify-cipher@^1.0.0:
77 | version "1.0.1"
78 | resolved "https://registry.npm.taobao.org/browserify-cipher/download/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0"
79 | integrity sha1-jWR0wbhwv9q807z8wZNKEOlPFfA=
80 | dependencies:
81 | browserify-aes "^1.0.4"
82 | browserify-des "^1.0.0"
83 | evp_bytestokey "^1.0.0"
84 |
85 | browserify-des@^1.0.0:
86 | version "1.0.2"
87 | resolved "https://registry.npm.taobao.org/browserify-des/download/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c"
88 | integrity sha1-OvTx9Zg5QDVy8cZiBDdfen9wPpw=
89 | dependencies:
90 | cipher-base "^1.0.1"
91 | des.js "^1.0.0"
92 | inherits "^2.0.1"
93 | safe-buffer "^5.1.2"
94 |
95 | browserify-rsa@^4.0.0:
96 | version "4.0.1"
97 | resolved "https://registry.npm.taobao.org/browserify-rsa/download/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524"
98 | integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=
99 | dependencies:
100 | bn.js "^4.1.0"
101 | randombytes "^2.0.1"
102 |
103 | browserify-rsa@^4.1.0:
104 | version "4.1.0"
105 | resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d"
106 | integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==
107 | dependencies:
108 | bn.js "^5.0.0"
109 | randombytes "^2.0.1"
110 |
111 | browserify-sign@^4.0.0:
112 | version "4.2.2"
113 | resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.2.tgz#e78d4b69816d6e3dd1c747e64e9947f9ad79bc7e"
114 | integrity sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==
115 | dependencies:
116 | bn.js "^5.2.1"
117 | browserify-rsa "^4.1.0"
118 | create-hash "^1.2.0"
119 | create-hmac "^1.1.7"
120 | elliptic "^6.5.4"
121 | inherits "^2.0.4"
122 | parse-asn1 "^5.1.6"
123 | readable-stream "^3.6.2"
124 | safe-buffer "^5.2.1"
125 |
126 | browserify-zlib@^0.2.0:
127 | version "0.2.0"
128 | resolved "https://registry.npm.taobao.org/browserify-zlib/download/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f"
129 | integrity sha1-KGlFnZqjviRf6P4sofRuLn9U1z8=
130 | dependencies:
131 | pako "~1.0.5"
132 |
133 | buffer-from@^1.0.0:
134 | version "1.1.1"
135 | resolved "https://registry.npm.taobao.org/buffer-from/download/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
136 | integrity sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8=
137 |
138 | buffer-xor@^1.0.3:
139 | version "1.0.3"
140 | resolved "https://registry.npm.taobao.org/buffer-xor/download/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
141 | integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=
142 |
143 | buffer@^4.3.0:
144 | version "4.9.2"
145 | resolved "https://registry.npm.taobao.org/buffer/download/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8"
146 | integrity sha1-Iw6tNEACmIZEhBqwJEr4xEu+Pvg=
147 | dependencies:
148 | base64-js "^1.0.2"
149 | ieee754 "^1.1.4"
150 | isarray "^1.0.0"
151 |
152 | builtin-status-codes@^3.0.0:
153 | version "3.0.0"
154 | resolved "https://registry.npm.taobao.org/builtin-status-codes/download/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
155 | integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=
156 |
157 | call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
158 | version "1.0.2"
159 | resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6"
160 | integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==
161 | dependencies:
162 | es-errors "^1.3.0"
163 | function-bind "^1.1.2"
164 |
165 | call-bind@^1.0.8:
166 | version "1.0.8"
167 | resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c"
168 | integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==
169 | dependencies:
170 | call-bind-apply-helpers "^1.0.0"
171 | es-define-property "^1.0.0"
172 | get-intrinsic "^1.2.4"
173 | set-function-length "^1.2.2"
174 |
175 | call-bound@^1.0.3, call-bound@^1.0.4:
176 | version "1.0.4"
177 | resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a"
178 | integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==
179 | dependencies:
180 | call-bind-apply-helpers "^1.0.2"
181 | get-intrinsic "^1.3.0"
182 |
183 | cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
184 | version "1.0.6"
185 | resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.6.tgz#8fe672437d01cd6c4561af5334e0cc50ff1955f7"
186 | integrity sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==
187 | dependencies:
188 | inherits "^2.0.4"
189 | safe-buffer "^5.2.1"
190 |
191 | console-browserify@^1.1.0:
192 | version "1.2.0"
193 | resolved "https://registry.npm.taobao.org/console-browserify/download/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336"
194 | integrity sha1-ZwY871fOts9Jk6KrOlWECujEkzY=
195 |
196 | constants-browserify@^1.0.0:
197 | version "1.0.0"
198 | resolved "https://registry.npm.taobao.org/constants-browserify/download/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
199 | integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=
200 |
201 | core-util-is@~1.0.0:
202 | version "1.0.2"
203 | resolved "https://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
204 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
205 |
206 | create-ecdh@^4.0.0:
207 | version "4.0.3"
208 | resolved "https://registry.npm.taobao.org/create-ecdh/download/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff"
209 | integrity sha1-yREbbzMEXEaX8UR4f5JUzcd8Rf8=
210 | dependencies:
211 | bn.js "^4.1.0"
212 | elliptic "^6.0.0"
213 |
214 | create-hash@^1.1.0, create-hash@^1.2.0:
215 | version "1.2.0"
216 | resolved "https://registry.npm.taobao.org/create-hash/download/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196"
217 | integrity sha1-iJB4rxGmN1a8+1m9IhmWvjqe8ZY=
218 | dependencies:
219 | cipher-base "^1.0.1"
220 | inherits "^2.0.1"
221 | md5.js "^1.3.4"
222 | ripemd160 "^2.0.1"
223 | sha.js "^2.4.0"
224 |
225 | create-hash@~1.1.3:
226 | version "1.1.3"
227 | resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.3.tgz#606042ac8b9262750f483caddab0f5819172d8fd"
228 | integrity sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA==
229 | dependencies:
230 | cipher-base "^1.0.1"
231 | inherits "^2.0.1"
232 | ripemd160 "^2.0.0"
233 | sha.js "^2.4.0"
234 |
235 | create-hmac@^1.1.0, create-hmac@^1.1.7:
236 | version "1.1.7"
237 | resolved "https://registry.npm.taobao.org/create-hmac/download/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff"
238 | integrity sha1-aRcMeLOrlXFHsriwRXLkfq0iQ/8=
239 | dependencies:
240 | cipher-base "^1.0.3"
241 | create-hash "^1.1.0"
242 | inherits "^2.0.1"
243 | ripemd160 "^2.0.0"
244 | safe-buffer "^5.0.1"
245 | sha.js "^2.4.8"
246 |
247 | crypto-browserify@^3.11.0:
248 | version "3.12.0"
249 | resolved "https://registry.npm.taobao.org/crypto-browserify/download/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
250 | integrity sha1-OWz58xN/A+S45TLFj2mCVOAPgOw=
251 | dependencies:
252 | browserify-cipher "^1.0.0"
253 | browserify-sign "^4.0.0"
254 | create-ecdh "^4.0.0"
255 | create-hash "^1.1.0"
256 | create-hmac "^1.1.0"
257 | diffie-hellman "^5.0.0"
258 | inherits "^2.0.1"
259 | pbkdf2 "^3.0.3"
260 | public-encrypt "^4.0.0"
261 | randombytes "^2.0.0"
262 | randomfill "^1.0.3"
263 |
264 | define-data-property@^1.1.4:
265 | version "1.1.4"
266 | resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
267 | integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
268 | dependencies:
269 | es-define-property "^1.0.0"
270 | es-errors "^1.3.0"
271 | gopd "^1.0.1"
272 |
273 | des.js@^1.0.0:
274 | version "1.0.1"
275 | resolved "https://registry.npm.taobao.org/des.js/download/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843"
276 | integrity sha1-U4IULhvcU/hdhtU+X0qn3rkeCEM=
277 | dependencies:
278 | inherits "^2.0.1"
279 | minimalistic-assert "^1.0.0"
280 |
281 | diffie-hellman@^5.0.0:
282 | version "5.0.3"
283 | resolved "https://registry.npm.taobao.org/diffie-hellman/download/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
284 | integrity sha1-QOjumPVaIUlgcUaSHGPhrl89KHU=
285 | dependencies:
286 | bn.js "^4.1.0"
287 | miller-rabin "^4.0.0"
288 | randombytes "^2.0.0"
289 |
290 | domain-browser@^1.1.1:
291 | version "1.2.0"
292 | resolved "https://registry.npm.taobao.org/domain-browser/download/domain-browser-1.2.0.tgz?cache=0&sync_timestamp=1575879334171&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdomain-browser%2Fdownload%2Fdomain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
293 | integrity sha1-PTH1AZGmdJ3RN1p/Ui6CPULlTto=
294 |
295 | dunder-proto@^1.0.1:
296 | version "1.0.1"
297 | resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a"
298 | integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==
299 | dependencies:
300 | call-bind-apply-helpers "^1.0.1"
301 | es-errors "^1.3.0"
302 | gopd "^1.2.0"
303 |
304 | elliptic@^6.0.0, elliptic@^6.5.4:
305 | version "6.6.1"
306 | resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.6.1.tgz#3b8ffb02670bf69e382c7f65bf524c97c5405c06"
307 | integrity sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==
308 | dependencies:
309 | bn.js "^4.11.9"
310 | brorand "^1.1.0"
311 | hash.js "^1.0.0"
312 | hmac-drbg "^1.0.1"
313 | inherits "^2.0.4"
314 | minimalistic-assert "^1.0.1"
315 | minimalistic-crypto-utils "^1.0.1"
316 |
317 | es-define-property@^1.0.0, es-define-property@^1.0.1:
318 | version "1.0.1"
319 | resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa"
320 | integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==
321 |
322 | es-errors@^1.3.0:
323 | version "1.3.0"
324 | resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
325 | integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
326 |
327 | es-object-atoms@^1.0.0, es-object-atoms@^1.1.1:
328 | version "1.1.1"
329 | resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1"
330 | integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==
331 | dependencies:
332 | es-errors "^1.3.0"
333 |
334 | events@^3.0.0:
335 | version "3.1.0"
336 | resolved "https://registry.npm.taobao.org/events/download/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59"
337 | integrity sha1-hCea8bNMt1qoi/X/KR9tC9mzGlk=
338 |
339 | evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
340 | version "1.0.3"
341 | resolved "https://registry.npm.taobao.org/evp_bytestokey/download/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02"
342 | integrity sha1-f8vbGY3HGVlDLv4ThCaE4FJaywI=
343 | dependencies:
344 | md5.js "^1.3.4"
345 | safe-buffer "^5.1.1"
346 |
347 | for-each@^0.3.5:
348 | version "0.3.5"
349 | resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.5.tgz#d650688027826920feeb0af747ee7b9421a41d47"
350 | integrity sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==
351 | dependencies:
352 | is-callable "^1.2.7"
353 |
354 | function-bind@^1.1.2:
355 | version "1.1.2"
356 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
357 | integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
358 |
359 | get-intrinsic@^1.2.4, get-intrinsic@^1.3.0:
360 | version "1.3.0"
361 | resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01"
362 | integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==
363 | dependencies:
364 | call-bind-apply-helpers "^1.0.2"
365 | es-define-property "^1.0.1"
366 | es-errors "^1.3.0"
367 | es-object-atoms "^1.1.1"
368 | function-bind "^1.1.2"
369 | get-proto "^1.0.1"
370 | gopd "^1.2.0"
371 | has-symbols "^1.1.0"
372 | hasown "^2.0.2"
373 | math-intrinsics "^1.1.0"
374 |
375 | get-proto@^1.0.1:
376 | version "1.0.1"
377 | resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1"
378 | integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==
379 | dependencies:
380 | dunder-proto "^1.0.1"
381 | es-object-atoms "^1.0.0"
382 |
383 | gopd@^1.0.1, gopd@^1.2.0:
384 | version "1.2.0"
385 | resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
386 | integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
387 |
388 | has-property-descriptors@^1.0.2:
389 | version "1.0.2"
390 | resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854"
391 | integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==
392 | dependencies:
393 | es-define-property "^1.0.0"
394 |
395 | has-symbols@^1.0.3, has-symbols@^1.1.0:
396 | version "1.1.0"
397 | resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338"
398 | integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==
399 |
400 | has-tostringtag@^1.0.2:
401 | version "1.0.2"
402 | resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc"
403 | integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
404 | dependencies:
405 | has-symbols "^1.0.3"
406 |
407 | hash-base@^2.0.0:
408 | version "2.0.2"
409 | resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-2.0.2.tgz#66ea1d856db4e8a5470cadf6fce23ae5244ef2e1"
410 | integrity sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw==
411 | dependencies:
412 | inherits "^2.0.1"
413 |
414 | hash-base@^3.0.0:
415 | version "3.0.4"
416 | resolved "https://registry.npm.taobao.org/hash-base/download/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918"
417 | integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=
418 | dependencies:
419 | inherits "^2.0.1"
420 | safe-buffer "^5.0.1"
421 |
422 | hash.js@^1.0.0, hash.js@^1.0.3:
423 | version "1.1.7"
424 | resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"
425 | integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==
426 | dependencies:
427 | inherits "^2.0.3"
428 | minimalistic-assert "^1.0.1"
429 |
430 | hasown@^2.0.2:
431 | version "2.0.2"
432 | resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
433 | integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
434 | dependencies:
435 | function-bind "^1.1.2"
436 |
437 | hmac-drbg@^1.0.1:
438 | version "1.0.1"
439 | resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
440 | integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=
441 | dependencies:
442 | hash.js "^1.0.3"
443 | minimalistic-assert "^1.0.0"
444 | minimalistic-crypto-utils "^1.0.1"
445 |
446 | https-browserify@^1.0.0:
447 | version "1.0.0"
448 | resolved "https://registry.npm.taobao.org/https-browserify/download/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
449 | integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
450 |
451 | ieee754@^1.1.4:
452 | version "1.1.13"
453 | resolved "https://registry.npm.taobao.org/ieee754/download/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"
454 | integrity sha1-7BaFWOlaoYH9h9N/VcMrvLZwi4Q=
455 |
456 | inherits@2.0.1:
457 | version "2.0.1"
458 | resolved "https://registry.npm.taobao.org/inherits/download/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
459 | integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=
460 |
461 | inherits@2.0.3:
462 | version "2.0.3"
463 | resolved "https://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
464 | integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
465 |
466 | inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3:
467 | version "2.0.4"
468 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
469 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
470 |
471 | is-callable@^1.2.7:
472 | version "1.2.7"
473 | resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
474 | integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
475 |
476 | is-typed-array@^1.1.14:
477 | version "1.1.15"
478 | resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.15.tgz#4bfb4a45b61cee83a5a46fba778e4e8d59c0ce0b"
479 | integrity sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==
480 | dependencies:
481 | which-typed-array "^1.1.16"
482 |
483 | isarray@^1.0.0, isarray@~1.0.0:
484 | version "1.0.0"
485 | resolved "https://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
486 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
487 |
488 | isarray@^2.0.5:
489 | version "2.0.5"
490 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
491 | integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
492 |
493 | isexe@^2.0.0:
494 | version "2.0.0"
495 | resolved "https://registry.npm.taobao.org/isexe/download/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
496 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
497 |
498 | math-intrinsics@^1.1.0:
499 | version "1.1.0"
500 | resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9"
501 | integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
502 |
503 | md5.js@^1.3.4:
504 | version "1.3.5"
505 | resolved "https://registry.npm.taobao.org/md5.js/download/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
506 | integrity sha1-tdB7jjIW4+J81yjXL3DR5qNCAF8=
507 | dependencies:
508 | hash-base "^3.0.0"
509 | inherits "^2.0.1"
510 | safe-buffer "^5.1.2"
511 |
512 | miller-rabin@^4.0.0:
513 | version "4.0.1"
514 | resolved "https://registry.npm.taobao.org/miller-rabin/download/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
515 | integrity sha1-8IA1HIZbDcViqEYpZtqlNUPHik0=
516 | dependencies:
517 | bn.js "^4.0.0"
518 | brorand "^1.0.1"
519 |
520 | minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
521 | version "1.0.1"
522 | resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
523 | integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
524 |
525 | minimalistic-crypto-utils@^1.0.1:
526 | version "1.0.1"
527 | resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
528 | integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
529 |
530 | minimist@^1.2.5:
531 | version "1.2.6"
532 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
533 | integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
534 |
535 | mkdirp@^0.5.1:
536 | version "0.5.4"
537 | resolved "https://registry.npm.taobao.org/mkdirp/download/mkdirp-0.5.4.tgz?cache=0&sync_timestamp=1584986102665&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmkdirp%2Fdownload%2Fmkdirp-0.5.4.tgz#fd01504a6797ec5c9be81ff43d204961ed64a512"
538 | integrity sha1-/QFQSmeX7Fyb6B/0PSBJYe1kpRI=
539 | dependencies:
540 | minimist "^1.2.5"
541 |
542 | node-libs-browser@^2.0.0:
543 | version "2.2.1"
544 | resolved "https://registry.npm.taobao.org/node-libs-browser/download/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425"
545 | integrity sha1-tk9RPRgzhiX5A0bSew0jXmMfZCU=
546 | dependencies:
547 | assert "^1.1.1"
548 | browserify-zlib "^0.2.0"
549 | buffer "^4.3.0"
550 | console-browserify "^1.1.0"
551 | constants-browserify "^1.0.0"
552 | crypto-browserify "^3.11.0"
553 | domain-browser "^1.1.1"
554 | events "^3.0.0"
555 | https-browserify "^1.0.0"
556 | os-browserify "^0.3.0"
557 | path-browserify "0.0.1"
558 | process "^0.11.10"
559 | punycode "^1.2.4"
560 | querystring-es3 "^0.2.0"
561 | readable-stream "^2.3.3"
562 | stream-browserify "^2.0.1"
563 | stream-http "^2.7.2"
564 | string_decoder "^1.0.0"
565 | timers-browserify "^2.0.4"
566 | tty-browserify "0.0.0"
567 | url "^0.11.0"
568 | util "^0.11.0"
569 | vm-browserify "^1.0.1"
570 |
571 | object-assign@^4.1.1:
572 | version "4.1.1"
573 | resolved "https://registry.npm.taobao.org/object-assign/download/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
574 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
575 |
576 | os-browserify@^0.3.0:
577 | version "0.3.0"
578 | resolved "https://registry.npm.taobao.org/os-browserify/download/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
579 | integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=
580 |
581 | pako@~1.0.5:
582 | version "1.0.11"
583 | resolved "https://registry.npm.taobao.org/pako/download/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
584 | integrity sha1-bJWZ00DVTf05RjgCUqNXBaa5kr8=
585 |
586 | parse-asn1@^5.0.0:
587 | version "5.1.5"
588 | resolved "https://registry.npm.taobao.org/parse-asn1/download/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e"
589 | integrity sha1-ADJxND2ljclMrOSU+u89IUfs6g4=
590 | dependencies:
591 | asn1.js "^4.0.0"
592 | browserify-aes "^1.0.0"
593 | create-hash "^1.1.0"
594 | evp_bytestokey "^1.0.0"
595 | pbkdf2 "^3.0.3"
596 | safe-buffer "^5.1.1"
597 |
598 | parse-asn1@^5.1.6:
599 | version "5.1.6"
600 | resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4"
601 | integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==
602 | dependencies:
603 | asn1.js "^5.2.0"
604 | browserify-aes "^1.0.0"
605 | evp_bytestokey "^1.0.0"
606 | pbkdf2 "^3.0.3"
607 | safe-buffer "^5.1.1"
608 |
609 | path-browserify@0.0.1:
610 | version "0.0.1"
611 | resolved "https://registry.npm.taobao.org/path-browserify/download/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a"
612 | integrity sha1-5sTd1+06onxoogzE5Q4aTug7vEo=
613 |
614 | pbkdf2@^3.0.3:
615 | version "3.1.3"
616 | resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.3.tgz#8be674d591d65658113424592a95d1517318dd4b"
617 | integrity sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA==
618 | dependencies:
619 | create-hash "~1.1.3"
620 | create-hmac "^1.1.7"
621 | ripemd160 "=2.0.1"
622 | safe-buffer "^5.2.1"
623 | sha.js "^2.4.11"
624 | to-buffer "^1.2.0"
625 |
626 | possible-typed-array-names@^1.0.0:
627 | version "1.1.0"
628 | resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz#93e3582bc0e5426586d9d07b79ee40fc841de4ae"
629 | integrity sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==
630 |
631 | process-nextick-args@~2.0.0:
632 | version "2.0.1"
633 | resolved "https://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
634 | integrity sha1-eCDZsWEgzFXKmud5JoCufbptf+I=
635 |
636 | process@^0.11.10:
637 | version "0.11.10"
638 | resolved "https://registry.npm.taobao.org/process/download/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
639 | integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
640 |
641 | public-encrypt@^4.0.0:
642 | version "4.0.3"
643 | resolved "https://registry.npm.taobao.org/public-encrypt/download/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0"
644 | integrity sha1-T8ydd6B+SLp1J+fL4N4z0HATMeA=
645 | dependencies:
646 | bn.js "^4.1.0"
647 | browserify-rsa "^4.0.0"
648 | create-hash "^1.1.0"
649 | parse-asn1 "^5.0.0"
650 | randombytes "^2.0.1"
651 | safe-buffer "^5.1.2"
652 |
653 | punycode@1.3.2:
654 | version "1.3.2"
655 | resolved "https://registry.npm.taobao.org/punycode/download/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
656 | integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
657 |
658 | punycode@^1.2.4:
659 | version "1.4.1"
660 | resolved "https://registry.npm.taobao.org/punycode/download/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
661 | integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
662 |
663 | querystring-es3@^0.2.0:
664 | version "0.2.1"
665 | resolved "https://registry.npm.taobao.org/querystring-es3/download/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
666 | integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=
667 |
668 | querystring@0.2.0:
669 | version "0.2.0"
670 | resolved "https://registry.npm.taobao.org/querystring/download/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
671 | integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
672 |
673 | randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
674 | version "2.1.0"
675 | resolved "https://registry.npm.taobao.org/randombytes/download/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
676 | integrity sha1-32+ENy8CcNxlzfYpE0mrekc9Tyo=
677 | dependencies:
678 | safe-buffer "^5.1.0"
679 |
680 | randomfill@^1.0.3:
681 | version "1.0.4"
682 | resolved "https://registry.npm.taobao.org/randomfill/download/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458"
683 | integrity sha1-ySGW/IarQr6YPxvzF3giSTHWFFg=
684 | dependencies:
685 | randombytes "^2.0.5"
686 | safe-buffer "^5.1.0"
687 |
688 | readable-stream@^2.0.2, readable-stream@^2.3.3, readable-stream@^2.3.6:
689 | version "2.3.7"
690 | resolved "https://registry.npm.taobao.org/readable-stream/download/readable-stream-2.3.7.tgz?cache=0&sync_timestamp=1581622984924&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freadable-stream%2Fdownload%2Freadable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
691 | integrity sha1-Hsoc9xGu+BTAT2IlKjamL2yyO1c=
692 | dependencies:
693 | core-util-is "~1.0.0"
694 | inherits "~2.0.3"
695 | isarray "~1.0.0"
696 | process-nextick-args "~2.0.0"
697 | safe-buffer "~5.1.1"
698 | string_decoder "~1.1.1"
699 | util-deprecate "~1.0.1"
700 |
701 | readable-stream@^3.6.2:
702 | version "3.6.2"
703 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"
704 | integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
705 | dependencies:
706 | inherits "^2.0.3"
707 | string_decoder "^1.1.1"
708 | util-deprecate "^1.0.1"
709 |
710 | readline-sync@^1.4.7:
711 | version "1.4.10"
712 | resolved "https://registry.npm.taobao.org/readline-sync/download/readline-sync-1.4.10.tgz#41df7fbb4b6312d673011594145705bf56d8873b"
713 | integrity sha1-Qd9/u0tjEtZzARWUFFcFv1bYhzs=
714 |
715 | ripemd160@=2.0.1:
716 | version "2.0.1"
717 | resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.1.tgz#0f4584295c53a3628af7e6d79aca21ce57d1c6e7"
718 | integrity sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w==
719 | dependencies:
720 | hash-base "^2.0.0"
721 | inherits "^2.0.1"
722 |
723 | ripemd160@^2.0.0, ripemd160@^2.0.1:
724 | version "2.0.2"
725 | resolved "https://registry.npm.taobao.org/ripemd160/download/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
726 | integrity sha1-ocGm9iR1FXe6XQeRTLyShQWFiQw=
727 | dependencies:
728 | hash-base "^3.0.0"
729 | inherits "^2.0.1"
730 |
731 | safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0:
732 | version "5.2.0"
733 | resolved "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
734 | integrity sha1-t02uxJsRSPiMZLaNSbHoFcHy9Rk=
735 |
736 | safe-buffer@^5.2.1:
737 | version "5.2.1"
738 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
739 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
740 |
741 | safe-buffer@~5.1.0, safe-buffer@~5.1.1:
742 | version "5.1.2"
743 | resolved "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
744 | integrity sha1-mR7GnSluAxN0fVm9/St0XDX4go0=
745 |
746 | safer-buffer@^2.1.0:
747 | version "2.1.2"
748 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
749 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
750 |
751 | set-function-length@^1.2.2:
752 | version "1.2.2"
753 | resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449"
754 | integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==
755 | dependencies:
756 | define-data-property "^1.1.4"
757 | es-errors "^1.3.0"
758 | function-bind "^1.1.2"
759 | get-intrinsic "^1.2.4"
760 | gopd "^1.0.1"
761 | has-property-descriptors "^1.0.2"
762 |
763 | setimmediate@^1.0.4:
764 | version "1.0.5"
765 | resolved "https://registry.npm.taobao.org/setimmediate/download/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
766 | integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
767 |
768 | sha.js@^2.4.0, sha.js@^2.4.11, sha.js@^2.4.8:
769 | version "2.4.12"
770 | resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.12.tgz#eb8b568bf383dfd1867a32c3f2b74eb52bdbf23f"
771 | integrity sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==
772 | dependencies:
773 | inherits "^2.0.4"
774 | safe-buffer "^5.2.1"
775 | to-buffer "^1.2.0"
776 |
777 | shadow-cljs-jar@1.3.2:
778 | version "1.3.2"
779 | resolved "https://registry.npm.taobao.org/shadow-cljs-jar/download/shadow-cljs-jar-1.3.2.tgz#97273afe1747b6a2311917c1c88d9e243c81957b"
780 | integrity sha1-lyc6/hdHtqIxGRfByI2eJDyBlXs=
781 |
782 | shadow-cljs@^2.8.93:
783 | version "2.8.93"
784 | resolved "https://registry.npm.taobao.org/shadow-cljs/download/shadow-cljs-2.8.93.tgz#60d475658819246892f74159ce5a6026b275892e"
785 | integrity sha1-YNR1ZYgZJGiS90FZzlpgJrJ1iS4=
786 | dependencies:
787 | mkdirp "^0.5.1"
788 | node-libs-browser "^2.0.0"
789 | readline-sync "^1.4.7"
790 | shadow-cljs-jar "1.3.2"
791 | source-map-support "^0.4.15"
792 | which "^1.3.1"
793 | ws "^3.0.0"
794 |
795 | source-map-support@^0.4.15:
796 | version "0.4.18"
797 | resolved "https://registry.npm.taobao.org/source-map-support/download/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f"
798 | integrity sha1-Aoam3ovkJkEzhZTpfM6nXwosWF8=
799 | dependencies:
800 | source-map "^0.5.6"
801 |
802 | source-map-support@^0.5.16:
803 | version "0.5.16"
804 | resolved "https://registry.npm.taobao.org/source-map-support/download/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042"
805 | integrity sha1-CuBp5/47p1OMZMmFFeNTOerFoEI=
806 | dependencies:
807 | buffer-from "^1.0.0"
808 | source-map "^0.6.0"
809 |
810 | source-map@^0.5.6:
811 | version "0.5.7"
812 | resolved "https://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
813 | integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
814 |
815 | source-map@^0.6.0:
816 | version "0.6.1"
817 | resolved "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
818 | integrity sha1-dHIq8y6WFOnCh6jQu95IteLxomM=
819 |
820 | stream-browserify@^2.0.1:
821 | version "2.0.2"
822 | resolved "https://registry.npm.taobao.org/stream-browserify/download/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b"
823 | integrity sha1-h1IdOKRKp+6RzhzSpH3wy0ndZgs=
824 | dependencies:
825 | inherits "~2.0.1"
826 | readable-stream "^2.0.2"
827 |
828 | stream-http@^2.7.2:
829 | version "2.8.3"
830 | resolved "https://registry.npm.taobao.org/stream-http/download/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc"
831 | integrity sha1-stJCRpKIpaJ+xP6JM6z2I95lFPw=
832 | dependencies:
833 | builtin-status-codes "^3.0.0"
834 | inherits "^2.0.1"
835 | readable-stream "^2.3.6"
836 | to-arraybuffer "^1.0.0"
837 | xtend "^4.0.0"
838 |
839 | string_decoder@^1.0.0, string_decoder@^1.1.1:
840 | version "1.3.0"
841 | resolved "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
842 | integrity sha1-QvEUWUpGzxqOMLCoT1bHjD7awh4=
843 | dependencies:
844 | safe-buffer "~5.2.0"
845 |
846 | string_decoder@~1.1.1:
847 | version "1.1.1"
848 | resolved "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
849 | integrity sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=
850 | dependencies:
851 | safe-buffer "~5.1.0"
852 |
853 | timers-browserify@^2.0.4:
854 | version "2.0.11"
855 | resolved "https://registry.npm.taobao.org/timers-browserify/download/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f"
856 | integrity sha1-gAsfPu4nLlvFPuRloE0OgEwxIR8=
857 | dependencies:
858 | setimmediate "^1.0.4"
859 |
860 | to-arraybuffer@^1.0.0:
861 | version "1.0.1"
862 | resolved "https://registry.npm.taobao.org/to-arraybuffer/download/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
863 | integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=
864 |
865 | to-buffer@^1.2.0:
866 | version "1.2.1"
867 | resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.2.1.tgz#2ce650cdb262e9112a18e65dc29dcb513c8155e0"
868 | integrity sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==
869 | dependencies:
870 | isarray "^2.0.5"
871 | safe-buffer "^5.2.1"
872 | typed-array-buffer "^1.0.3"
873 |
874 | tty-browserify@0.0.0:
875 | version "0.0.0"
876 | resolved "https://registry.npm.taobao.org/tty-browserify/download/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
877 | integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=
878 |
879 | typed-array-buffer@^1.0.3:
880 | version "1.0.3"
881 | resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz#a72395450a4869ec033fd549371b47af3a2ee536"
882 | integrity sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==
883 | dependencies:
884 | call-bound "^1.0.3"
885 | es-errors "^1.3.0"
886 | is-typed-array "^1.1.14"
887 |
888 | ultron@~1.1.0:
889 | version "1.1.1"
890 | resolved "https://registry.npm.taobao.org/ultron/download/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c"
891 | integrity sha1-n+FTahCmZKZSZqHjzPhf02MCvJw=
892 |
893 | url@^0.11.0:
894 | version "0.11.0"
895 | resolved "https://registry.npm.taobao.org/url/download/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
896 | integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=
897 | dependencies:
898 | punycode "1.3.2"
899 | querystring "0.2.0"
900 |
901 | util-deprecate@^1.0.1, util-deprecate@~1.0.1:
902 | version "1.0.2"
903 | resolved "https://registry.npm.taobao.org/util-deprecate/download/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
904 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
905 |
906 | util@0.10.3:
907 | version "0.10.3"
908 | resolved "https://registry.npm.taobao.org/util/download/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
909 | integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk=
910 | dependencies:
911 | inherits "2.0.1"
912 |
913 | util@^0.11.0:
914 | version "0.11.1"
915 | resolved "https://registry.npm.taobao.org/util/download/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61"
916 | integrity sha1-MjZzNyDsZLsn9uJvQhqqLhtYjWE=
917 | dependencies:
918 | inherits "2.0.3"
919 |
920 | vm-browserify@^1.0.1:
921 | version "1.1.2"
922 | resolved "https://registry.npm.taobao.org/vm-browserify/download/vm-browserify-1.1.2.tgz?cache=0&sync_timestamp=1572870776965&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvm-browserify%2Fdownload%2Fvm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
923 | integrity sha1-eGQcSIuObKkadfUR56OzKobl3aA=
924 |
925 | which-typed-array@^1.1.16:
926 | version "1.1.19"
927 | resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.19.tgz#df03842e870b6b88e117524a4b364b6fc689f956"
928 | integrity sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==
929 | dependencies:
930 | available-typed-arrays "^1.0.7"
931 | call-bind "^1.0.8"
932 | call-bound "^1.0.4"
933 | for-each "^0.3.5"
934 | get-proto "^1.0.1"
935 | gopd "^1.2.0"
936 | has-tostringtag "^1.0.2"
937 |
938 | which@^1.3.1:
939 | version "1.3.1"
940 | resolved "https://registry.npm.taobao.org/which/download/which-1.3.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwhich%2Fdownload%2Fwhich-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
941 | integrity sha1-pFBD1U9YBTFtqNYvn1CRjT2nCwo=
942 | dependencies:
943 | isexe "^2.0.0"
944 |
945 | ws@^3.0.0:
946 | version "3.3.3"
947 | resolved "https://registry.npm.taobao.org/ws/download/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2"
948 | integrity sha1-8c+E/i1ekB686U767OeF8YeiKPI=
949 | dependencies:
950 | async-limiter "~1.0.0"
951 | safe-buffer "~5.1.0"
952 | ultron "~1.1.0"
953 |
954 | xtend@^4.0.0:
955 | version "4.0.2"
956 | resolved "https://registry.npm.taobao.org/xtend/download/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
957 | integrity sha1-u3J3n1+kZRhrH0OPZ0+jR/2121Q=
958 |
--------------------------------------------------------------------------------