├── .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 | ![Files](https://user-images.githubusercontent.com/449224/77821627-af2ed780-7126-11ea-8f85-a6e84603a840.png) 42 | ![Workspace](https://user-images.githubusercontent.com/449224/77821629-b2c25e80-7126-11ea-8931-69aae531fb8d.png) 43 | ![Dependency tree](https://user-images.githubusercontent.com/449224/77821631-b524b880-7126-11ea-8a00-b8f1e1576938.png) 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 | --------------------------------------------------------------------------------