浏览代码

Reorg namespaces and add package.json

Also add db support
Gabriel Horner 2 年之前
父节点
当前提交
66fdb73bce

+ 1 - 1
bb.edn

@@ -35,7 +35,7 @@
   logseq.tasks.dev/build-publishing
   logseq.tasks.dev/build-publishing
 
 
   dev:publish
   dev:publish
-  (apply shell {:dir "deps/publish-spa"} "nbb-logseq -cp src -m logseq.publish-spa"
+  (apply shell {:dir "deps/publish-spa"} "yarn -s nbb-logseq -cp src -m logseq.publish-spa.cli"
                 *command-line-args*)
                 *command-line-args*)
 
 
   dev:npx-cap-run-ios
   dev:npx-cap-run-ios

+ 14 - 0
deps/publish-spa/package.json

@@ -0,0 +1,14 @@
+{
+  "name": "@logseq/publish-spa",
+  "version": "1.0.0",
+  "private": true,
+  "devDependencies": {
+    "@logseq/nbb-logseq": "^1.2.168"
+  },
+  "dependencies": {
+    "mldoc": "^1.5.1"
+  },
+  "scripts": {
+    "test": "nbb-logseq -cp src:test -m logseq.publish-spa.nbb-test-runner/run-tests"
+  }
+}

+ 29 - 87
deps/publish-spa/src/logseq/publish_spa.cljs

@@ -1,88 +1,30 @@
 (ns logseq.publish-spa
 (ns logseq.publish-spa
-  (:require [promesa.core :as p]
-            ["path" :as path]
-            ["fs-extra$default" :as fs]
-            [datascript.transit :as dt]
-            [logseq.graph-parser.cli :as gp-cli]
-            [logseq.publish-spa.html :as html]))
-
-(defn- handle-export-publish-assets
-  [html custom-css-path export-css-path repo-path asset-filenames output-path]
-  (let [app-path "../../static"
-        root-dir output-path
-        static-dir (path/join root-dir "static")
-        assets-from-dir (path/join repo-path "assets")
-        assets-to-dir (path/join root-dir "assets")
-        index-html-path (path/join root-dir "index.html")]
-    (p/let [_ (. fs ensureDir static-dir)
-            _ (. fs ensureDir assets-to-dir)
-            _ (p/all (concat
-                      [(. fs writeFile index-html-path html)
-
-
-                       (. fs copy (path/join app-path "404.html") (path/join root-dir "404.html"))]
-
-                      (map
-                       (fn [filename]
-                         (-> (. fs copy (path/join assets-from-dir filename) (path/join assets-to-dir filename))
-                             (p/catch
-                              (fn [e]
-                                ;; TODO: Make into a callback
-                                (println "Failed to copy"
-                                         (str {:from (path/join assets-from-dir filename)
-                                               :to (path/join assets-to-dir filename)})
-                                         e)))))
-                       asset-filenames)
-
-                      (map
-                       (fn [part]
-                         (. fs copy (path/join app-path part) (path/join static-dir part)))
-                       ["css" "fonts" "icons" "img" "js"])))
-            export-css (if (fs/existsSync export-css-path) (. fs readFile export-css-path) "")
-            _ (. fs writeFile (path/join static-dir "css" "export.css")  export-css)
-            custom-css (if (fs/existsSync custom-css-path) (. fs readFile custom-css-path) "")
-            _ (. fs writeFile (path/join static-dir "css" "custom.css") custom-css)
-            js-files ["main.js" "code-editor.js" "excalidraw.js" "tldraw.js"]
-            _ (p/all (map (fn [file]
-                            (. fs removeSync (path/join static-dir "js" file)))
-                          js-files))
-            _ (p/all (map (fn [file]
-                            (. fs moveSync
-                              (path/join static-dir "js" "publishing" file)
-                              (path/join static-dir "js" file)))
-                          js-files))
-            _ (. fs removeSync (path/join static-dir "js" "publishing"))
-            ;; remove source map files
-            ;; TODO: ugly, replace with ls-files and filter with ".map"
-            _ (p/all (map (fn [file]
-                            (. fs removeSync (path/join static-dir "js" (str file ".map"))))
-                          ["main.js" "code-editor.js" "excalidraw.js"]))]
-
-           ;; TODO: Make into a callback
-           (println
-            :notification
-            {:type "success"
-             :payload (str "Export public pages and publish assets to " root-dir " successfully 🎉")}))))
-
-(defn- get-app-state
-  []
-  {:ui/theme "dark", :ui/sidebar-collapsed-blocks {}, :ui/show-recent? false
-   :config {"local" {:feature/enable-whiteboards? true, :shortcuts {:editor/right ["mod+l" "right"], :ui/toggle-theme "t z"}, :ignored-page-references-keywords #{:description :desc}, :repo/dir-version 3, :default-templates {:journals ""}, :macros {"poem" "Rose is $1, violet's $2. Life's ordered: Org assists you."}, :shortcut/doc-mode-enter-for-new-block? false, :favorites ["foob"], :ui/show-empty-bullets? false, :preferred-file-format :edn, :preferred-workflow :now, :publishing/all-pages-public? true, :ref/default-open-blocks-level 2, :feature/enable-block-timestamps? false, :ref/linked-references-collapsed-threshold 50, :commands [], :meta/version 1, :hidden [], :default-queries {:journals '[{:title "🔨 NOW", :query [:find (pull ?h [*]) :in $ ?start ?today :where [?h :block/marker ?marker] [(contains? #{"NOW" "DOING"} ?marker)] [?h :block/page ?p] [?p :block/journal? true] [?p :block/journal-day ?d] [(>= ?d ?start)] [(<= ?d ?today)]], :inputs [:14d :today], :result-transform (fn [result] (sort-by (fn [h] (get h :block/priority "Z")) result)), :collapsed? false} {:title "📅 NEXT", :query [:find (pull ?h [*]) :in $ ?start ?next :where [?h :block/marker ?marker] [(contains? #{"NOW" "LATER" "TODO"} ?marker)] [?h :block/ref-pages ?p] [?p :block/journal? true] [?p :block/journal-day ?d] [(> ?d ?start)] [(< ?d ?next)]], :inputs [:today :7d-after], :collapsed? false}]}, :ui/enable-tooltip? true, :rich-property-values? false, :property/separated-by-commas #{:comma-prop}, :property-pages/excludelist #{:author}, :graph/settings {:journal? true, :excluded-pages? true, :orphan-pages? false, :builtin-pages? false}, :property-pages/enabled? true, :ui/show-command-doc? true, :preferred-format :markdown}}})
-
-(defn- get-db [graph-dir]
-  (let [{:keys [conn]} (gp-cli/parse-graph graph-dir {:verbose false})] @conn))
-
-(defn -main
-  [& args]
-  (let [repo-path  (or (first args)
-                       (throw (ex-info "GRAPH DIR required" {})))
-        output-path (or (second args)
-                        (throw (ex-info "OUT DIR required" {})))
-        ; html "WOOHOO"
-        db-str (dt/write-transit-str (get-db repo-path))
-        html (html/publishing-html db-str (pr-str (get-app-state)))
-        custom-css-path (path/join repo-path "logseq" "custom.css")
-        export-css-path (path/join repo-path "logseq" "export.css")
-        ;; TODO: Read from repo-path
-        asset-filenames []]
-    (handle-export-publish-assets html custom-css-path export-css-path repo-path asset-filenames output-path)))
+  (:require [datascript.transit :as dt]
+            [logseq.publish-spa.html :as html]
+            [logseq.publish-spa.export :as export]
+            [logseq.publish-spa.db :as db]
+            ["path" :as path]))
+
+(defn prep-for-export [db {:keys [app-state repo-config]}]
+  (let [[db asset-filenames']
+        (if (:publishing/all-pages-public? repo-config)
+          (db/clean-export! db)
+          (db/filter-only-public-pages-and-blocks db))
+        asset-filenames (remove nil? asset-filenames')
+        db-str (dt/write-transit-str db)
+        state (assoc (select-keys app-state
+                            [:ui/theme
+                             :ui/sidebar-collapsed-blocks
+                             :ui/show-recent?])
+                     :config {"local" repo-config})
+        raw-html-str (html/publishing-html db-str (pr-str state))]
+    {:html raw-html-str
+     :asset-filenames asset-filenames}))
+
+(defn publish [db graph-dir output-path options]
+  (let [{:keys [html asset-filenames]}
+        (prep-for-export db options)
+        custom-css-path (path/join graph-dir "logseq" "custom.css")
+        export-css-path (path/join graph-dir "logseq" "export.css")
+        app-path "../../static"]
+    (export/handle-export-publish-assets html app-path custom-css-path export-css-path graph-dir asset-filenames output-path)))

+ 32 - 0
deps/publish-spa/src/logseq/publish_spa/cli.cljs

@@ -0,0 +1,32 @@
+(ns logseq.publish-spa.cli
+  (:require [logseq.graph-parser.cli :as gp-cli]
+            [logseq.publish-spa :as publish-spa]
+            ["fs" :as fs]
+            ["path" :as path]
+            [clojure.edn :as edn]))
+
+(defn- get-repo-config
+  [dir]
+  (if (fs/existsSync (path/join dir "logseq" "config.edn"))
+    (-> (path/join dir "logseq" "config.edn") fs/readFileSync str edn/read-string)
+    {}))
+
+(defn- get-app-state
+  []
+  {:ui/theme "dark", :ui/sidebar-collapsed-blocks {}, :ui/show-recent? false})
+
+(defn- get-db [graph-dir]
+  (let [{:keys [conn]} (gp-cli/parse-graph graph-dir {:verbose false})] @conn))
+
+(defn -main
+  [& args]
+  (let [graph-dir  (or (first args)
+                       (throw (ex-info "GRAPH DIR required" {})))
+        output-path (or (second args)
+                        (throw (ex-info "OUT DIR required" {})))
+        repo-config (get-repo-config graph-dir)]
+    (publish-spa/publish (get-db graph-dir)
+                         graph-dir
+                         output-path
+                         {:app-state (get-app-state)
+                          :repo-config repo-config})))

+ 133 - 0
deps/publish-spa/src/logseq/publish_spa/db.cljs

@@ -0,0 +1,133 @@
+(ns logseq.publish-spa.db
+  (:require [datascript.core :as d]
+            [logseq.db.schema :as db-schema]
+            [clojure.string :as string]))
+
+;; Copied from pdf-utils
+(defn get-area-block-asset-url
+  [block page]
+  (when-some [props (and block page (:block/properties block))]
+    (when-some [uuid (:block/uuid block)]
+      (when-some [stamp (:hl-stamp props)]
+        (let [group-key      (string/replace-first (:block/original-name page) #"^hls__" "")
+              hl-page        (:hl-page props)
+              encoded-chars? (boolean (re-find #"(?i)%[0-9a-f]{2}" group-key))
+              group-key      (if encoded-chars? (js/encodeURI group-key) group-key)]
+          (str "./" "assets" "/" group-key "/" (str hl-page "_" uuid "_" stamp ".png")))))))
+
+(defn clean-asset-path-prefix
+  [path]
+  (when (string? path)
+    (string/replace-first path #"^[.\/\\]*(assets)[\/\\]+" "")))
+
+(defn seq-flatten [col]
+  (flatten (seq col)))
+
+(defn pull
+  [eid db]
+  (d/pull db '[*] eid))
+
+(defn get-public-pages
+  [db]
+  (-> (d/q
+       '[:find ?p
+         :where
+         [?p :block/name]
+         [?p :block/properties ?properties]
+         [(get ?properties :public) ?pub]
+         [(= true ?pub)]]
+       db)
+      (seq-flatten)))
+
+(defn get-public-false-pages
+  [db]
+  (-> (d/q
+       '[:find ?p
+         :where
+         [?p :block/name]
+         [?p :block/properties ?properties]
+         [(get ?properties :public) ?pub]
+         [(= false ?pub)]]
+       db)
+      (seq-flatten)))
+
+(defn get-public-false-block-ids
+  [db]
+  (-> (d/q
+       '[:find ?b
+         :where
+         [?p :block/name]
+         [?p :block/properties ?properties]
+         [(get ?properties :public) ?pub]
+         [(= false ?pub)]
+         [?b :block/page ?p]]
+       db)
+      (seq-flatten)))
+
+(defn get-assets
+  [db datoms]
+  (let [get-page-by-eid
+        (memoize #(some->
+                   (pull % db)
+                   :block/page
+                   :db/id
+                   (pull db)))]
+    (flatten
+     (keep
+      (fn [datom]
+        (cond-> []
+
+          (= :block/content (:a datom))
+          (concat (let [matched (re-seq #"\([./]*/assets/([^)]+)\)" (:v datom))]
+                    (when (seq matched)
+                      (for [[_ path] matched]
+                        (when (and (string? path)
+                                   (not (string/ends-with? path ".js")))
+                          path)))))
+          ;; area image assets
+          (= (:hl-type (:v datom)) "area")
+          (#(let [path (some-> (pull (:e datom) db)
+                               (get-area-block-asset-url
+                                (get-page-by-eid (:e datom))))
+                  path (clean-asset-path-prefix path)]
+              (conj % path)))))
+      datoms))))
+
+(defn clean-export!
+  [db]
+  (let [remove? #(contains? #{"me" "recent" "file"} %)
+        non-public-pages (get-public-false-pages db)
+        non-public-datoms (get-public-false-block-ids db)
+        non-public-datom-ids (set (concat non-public-pages non-public-datoms))
+        filtered-db (d/filter db
+                              (fn [_db datom]
+                                (let [ns (namespace (:a datom))]
+                                  (and (not (remove? ns))
+                                       (not (contains? #{:block/file} (:a datom)))
+                                       (not (contains? non-public-datom-ids (:e datom)))))))
+        datoms (d/datoms filtered-db :eavt)
+        assets (get-assets db datoms)]
+    [@(d/conn-from-datoms datoms db-schema/schema) assets]))
+
+(defn filter-only-public-pages-and-blocks
+  [db]
+  (let [public-pages (get-public-pages db)]
+    (when (seq public-pages)
+      (let [public-pages (set public-pages)
+            exported-namespace? #(contains? #{"block" "me" "recent"} %)
+            filtered-db (d/filter db
+                                  (fn [db datom]
+                                    (let [ns (namespace (:a datom))]
+                                      (and
+                                       (not (contains? #{:block/file} (:a datom)))
+                                       (not= ns "file")
+                                       (or
+                                        (not (exported-namespace? ns))
+                                        (and (= ns "block")
+                                             (or
+                                              (contains? public-pages (:e datom))
+                                              ;; TODO: Confirm entity isn't integer
+                                              (contains? public-pages (:db/id (:block/page (d/entity db (:e datom))))))))))))
+            datoms (d/datoms filtered-db :eavt)
+            assets (get-assets db datoms)]
+        [@(d/conn-from-datoms datoms db-schema/schema) assets]))))

+ 61 - 0
deps/publish-spa/src/logseq/publish_spa/export.cljs

@@ -0,0 +1,61 @@
+(ns logseq.publish-spa.export
+  (:require ["fs-extra$default" :as fs]
+            ["path" :as path]
+            [promesa.core :as p]))
+
+(defn handle-export-publish-assets
+  [html app-path custom-css-path export-css-path repo-path asset-filenames output-path]
+  (let [root-dir output-path
+        static-dir (path/join root-dir "static")
+        assets-from-dir (path/join repo-path "assets")
+        assets-to-dir (path/join root-dir "assets")
+        index-html-path (path/join root-dir "index.html")]
+    (p/let [_ (. fs ensureDir static-dir)
+            _ (. fs ensureDir assets-to-dir)
+            _ (p/all (concat
+                      [(. fs writeFile index-html-path html)
+
+
+                       (. fs copy (path/join app-path "404.html") (path/join root-dir "404.html"))]
+
+                      (map
+                       (fn [filename]
+                         (-> (. fs copy (path/join assets-from-dir filename) (path/join assets-to-dir filename))
+                             (p/catch
+                              (fn [e]
+                                ;; TODO: Make into a callback
+                                (println "Failed to copy"
+                                         (str {:from (path/join assets-from-dir filename)
+                                               :to (path/join assets-to-dir filename)})
+                                         e)))))
+                       asset-filenames)
+
+                      (map
+                       (fn [part]
+                         (. fs copy (path/join app-path part) (path/join static-dir part)))
+                       ["css" "fonts" "icons" "img" "js"])))
+            export-css (if (fs/existsSync export-css-path) (. fs readFile export-css-path) "")
+            _ (. fs writeFile (path/join static-dir "css" "export.css")  export-css)
+            custom-css (if (fs/existsSync custom-css-path) (. fs readFile custom-css-path) "")
+            _ (. fs writeFile (path/join static-dir "css" "custom.css") custom-css)
+            js-files ["main.js" "code-editor.js" "excalidraw.js" "tldraw.js"]
+            _ (p/all (map (fn [file]
+                            (. fs removeSync (path/join static-dir "js" file)))
+                          js-files))
+            _ (p/all (map (fn [file]
+                            (. fs moveSync
+                              (path/join static-dir "js" "publishing" file)
+                              (path/join static-dir "js" file)))
+                          js-files))
+            _ (. fs removeSync (path/join static-dir "js" "publishing"))
+            ;; remove source map files
+            ;; TODO: ugly, replace with ls-files and filter with ".map"
+            _ (p/all (map (fn [file]
+                            (. fs removeSync (path/join static-dir "js" (str file ".map"))))
+                          ["main.js" "code-editor.js" "excalidraw.js"]))]
+
+           ;; TODO: Make into a callback
+           (println
+            :notification
+            {:type "success"
+             :payload (str "Export public pages and publish assets to " root-dir " successfully 🎉")}))))

+ 2 - 4
deps/publish-spa/src/logseq/publish_spa/html.cljs

@@ -1,9 +1,7 @@
 (ns ^:no-doc logseq.publish-spa.html
 (ns ^:no-doc logseq.publish-spa.html
-  ; (:require-macros [hiccups.core])
   (:require [clojure.string :as string]
   (:require [clojure.string :as string]
             [goog.string :as gstring]
             [goog.string :as gstring]
-            [goog.string.format]
-            #_[hiccups.runtime]))
+            [goog.string.format]))
 
 
 (defn- escape-html
 (defn- escape-html
   "Change special characters into HTML character entities."
   "Change special characters into HTML character entities."
@@ -15,7 +13,7 @@
       (string/replace "\"" "logseq____&quot;")
       (string/replace "\"" "logseq____&quot;")
       (string/replace "'" "logseq____&apos;")))
       (string/replace "'" "logseq____&apos;")))
 
 
-;; from https://github.com/babashka/babashka/blob/8c1077af00c818ade9e646dfe1297bbe24b17f4d/examples/notes.clj#L21
+;; Copied from https://github.com/babashka/babashka/blob/8c1077af00c818ade9e646dfe1297bbe24b17f4d/examples/notes.clj#L21
 (defn html [v]
 (defn html [v]
   (cond (vector? v)
   (cond (vector? v)
     (let [tag (first v)
     (let [tag (first v)

+ 383 - 0
deps/publish-spa/yarn.lock

@@ -0,0 +1,383 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@logseq/nbb-logseq@^1.2.168":
+  version "1.2.168"
+  resolved "https://registry.yarnpkg.com/@logseq/nbb-logseq/-/nbb-logseq-1.2.168.tgz#e4120c4a7eb6c80737473292c1e20919b4453c91"
+  integrity sha512-lgZuAhck/74+9mT4vr6jVLkPcyRA/RO8ApBizq3d1L6LsPlPjdRp4nIaC2I1/p/AaIIB5vP89pMpqZfVsIHHQg==
+  dependencies:
+    import-meta-resolve "^2.1.0"
+
+ansi-regex@^2.0.0:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
+  integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==
+
+ansi-regex@^3.0.0:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1"
+  integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==
+
+camelcase@^5.0.0:
+  version "5.3.1"
+  resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
+  integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
+
+cliui@^4.0.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49"
+  integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==
+  dependencies:
+    string-width "^2.1.1"
+    strip-ansi "^4.0.0"
+    wrap-ansi "^2.0.0"
+
+code-point-at@^1.0.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
+  integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==
+
+cross-spawn@^6.0.0:
+  version "6.0.5"
+  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
+  integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
+  dependencies:
+    nice-try "^1.0.4"
+    path-key "^2.0.1"
+    semver "^5.5.0"
+    shebang-command "^1.2.0"
+    which "^1.2.9"
+
+decamelize@^1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
+  integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==
+
+end-of-stream@^1.1.0:
+  version "1.4.4"
+  resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
+  integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
+  dependencies:
+    once "^1.4.0"
+
+execa@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
+  integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==
+  dependencies:
+    cross-spawn "^6.0.0"
+    get-stream "^4.0.0"
+    is-stream "^1.1.0"
+    npm-run-path "^2.0.0"
+    p-finally "^1.0.0"
+    signal-exit "^3.0.0"
+    strip-eof "^1.0.0"
+
+find-up@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
+  integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==
+  dependencies:
+    locate-path "^3.0.0"
+
+get-caller-file@^1.0.1:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a"
+  integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==
+
+get-stream@^4.0.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
+  integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
+  dependencies:
+    pump "^3.0.0"
+
+import-meta-resolve@^2.1.0:
+  version "2.2.2"
+  resolved "https://registry.yarnpkg.com/import-meta-resolve/-/import-meta-resolve-2.2.2.tgz#75237301e72d1f0fbd74dbc6cca9324b164c2cc9"
+  integrity sha512-f8KcQ1D80V7RnqVm+/lirO9zkOxjGxhaTC1IPrBGd3MEfNgmNG67tSUO9gTi2F3Blr2Az6g1vocaxzkVnWl9MA==
+
+invert-kv@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02"
+  integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==
+
+is-fullwidth-code-point@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
+  integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==
+  dependencies:
+    number-is-nan "^1.0.0"
+
+is-fullwidth-code-point@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
+  integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==
+
+is-stream@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
+  integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==
+
+isexe@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
+  integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
+
+lcid@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf"
+  integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==
+  dependencies:
+    invert-kv "^2.0.0"
+
+locate-path@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e"
+  integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==
+  dependencies:
+    p-locate "^3.0.0"
+    path-exists "^3.0.0"
+
+map-age-cleaner@^0.1.1:
+  version "0.1.3"
+  resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a"
+  integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==
+  dependencies:
+    p-defer "^1.0.0"
+
+mem@^4.0.0:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178"
+  integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==
+  dependencies:
+    map-age-cleaner "^0.1.1"
+    mimic-fn "^2.0.0"
+    p-is-promise "^2.0.0"
+
+mimic-fn@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
+  integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
+
+mldoc@^1.5.1:
+  version "1.5.3"
+  resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-1.5.3.tgz#98d5bb276ac6908d72e1c58c27916e488ef9d395"
+  integrity sha512-hkI3PtjBHhbZqTr1U5/A8TIrIzg9DGZzCMLrfzePAdM+97GNeZijmPqUQXWEAyEQsDPnkipMoQZsBXxhnwzfJA==
+  dependencies:
+    yargs "^12.0.2"
+
+nice-try@^1.0.4:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
+  integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
+
+npm-run-path@^2.0.0:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
+  integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==
+  dependencies:
+    path-key "^2.0.0"
+
+number-is-nan@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
+  integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==
+
+once@^1.3.1, once@^1.4.0:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+  integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
+  dependencies:
+    wrappy "1"
+
+os-locale@^3.0.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a"
+  integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==
+  dependencies:
+    execa "^1.0.0"
+    lcid "^2.0.0"
+    mem "^4.0.0"
+
+p-defer@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c"
+  integrity sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==
+
+p-finally@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
+  integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==
+
+p-is-promise@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e"
+  integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==
+
+p-limit@^2.0.0:
+  version "2.3.0"
+  resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
+  integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
+  dependencies:
+    p-try "^2.0.0"
+
+p-locate@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4"
+  integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==
+  dependencies:
+    p-limit "^2.0.0"
+
+p-try@^2.0.0:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
+  integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
+
+path-exists@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
+  integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==
+
+path-key@^2.0.0, path-key@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
+  integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==
+
+pump@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
+  integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
+  dependencies:
+    end-of-stream "^1.1.0"
+    once "^1.3.1"
+
+require-directory@^2.1.1:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
+  integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
+
+require-main-filename@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
+  integrity sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==
+
+semver@^5.5.0:
+  version "5.7.1"
+  resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
+  integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
+
+set-blocking@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
+  integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==
+
+shebang-command@^1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
+  integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==
+  dependencies:
+    shebang-regex "^1.0.0"
+
+shebang-regex@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
+  integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==
+
+signal-exit@^3.0.0:
+  version "3.0.7"
+  resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
+  integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
+
+string-width@^1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
+  integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==
+  dependencies:
+    code-point-at "^1.0.0"
+    is-fullwidth-code-point "^1.0.0"
+    strip-ansi "^3.0.0"
+
+string-width@^2.0.0, string-width@^2.1.1:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
+  integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
+  dependencies:
+    is-fullwidth-code-point "^2.0.0"
+    strip-ansi "^4.0.0"
+
+strip-ansi@^3.0.0, strip-ansi@^3.0.1:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
+  integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==
+  dependencies:
+    ansi-regex "^2.0.0"
+
+strip-ansi@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
+  integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==
+  dependencies:
+    ansi-regex "^3.0.0"
+
+strip-eof@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
+  integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==
+
+which-module@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
+  integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==
+
+which@^1.2.9:
+  version "1.3.1"
+  resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
+  integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
+  dependencies:
+    isexe "^2.0.0"
+
+wrap-ansi@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
+  integrity sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==
+  dependencies:
+    string-width "^1.0.1"
+    strip-ansi "^3.0.1"
+
+wrappy@1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
+  integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
+
+"y18n@^3.2.1 || ^4.0.0":
+  version "4.0.3"
+  resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf"
+  integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==
+
+yargs-parser@^11.1.1:
+  version "11.1.1"
+  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4"
+  integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==
+  dependencies:
+    camelcase "^5.0.0"
+    decamelize "^1.2.0"
+
+yargs@^12.0.2:
+  version "12.0.5"
+  resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13"
+  integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==
+  dependencies:
+    cliui "^4.0.0"
+    decamelize "^1.2.0"
+    find-up "^3.0.0"
+    get-caller-file "^1.0.1"
+    os-locale "^3.0.0"
+    require-directory "^2.1.1"
+    require-main-filename "^1.0.1"
+    set-blocking "^2.0.0"
+    string-width "^2.0.0"
+    which-module "^2.0.0"
+    y18n "^3.2.1 || ^4.0.0"
+    yargs-parser "^11.1.1"