diff --git a/externs.js b/externs.js index c7138f931c..5a5eabb6ef 100644 --- a/externs.js +++ b/externs.js @@ -47,3 +47,6 @@ dummy.createWritable = function() {}; dummy.write = function() {}; dummy.close = function() {}; dummy.values = function() {}; +// Do we really need those? +dummy.filter = function() {}; +dummy.concat = function() {}; diff --git a/package.json b/package.json index e203539364..344f4ea2e4 100644 --- a/package.json +++ b/package.json @@ -48,17 +48,14 @@ "dependencies": { "codemirror": "^5.58.1", "diff": "^4.0.2", - "dropbox": "^5.2.0", + "fuzzysort": "^1.1.4", "ignore": "^5.1.8", "jszip": "^3.5.0", - "localforage": "^1.7.3", "mousetrap": "^1.6.5", - "parinfer-codemirror": "^1.4.2", "react": "^16.12.0", "react-dom": "^16.12.0", "react-textarea-autosize": "^8.0.1", "react-transition-group": "^4.3.0", - "webdav": "^3.3.0", "yargs-parser": "^20.2.4" } } diff --git a/src/main/frontend/components/search.cljs b/src/main/frontend/components/search.cljs index 13983cfa51..4f8366a986 100644 --- a/src/main/frontend/components/search.cljs +++ b/src/main/frontend/components/search.cljs @@ -85,7 +85,8 @@ :path-params {:path data}}) :block - (let [page (:page/name (:block/page data)) + (let [block-uuid (uuid (:block/uuid data)) + page (:page/name (:block/page (db/entity [:block/uuid block-uuid]))) path (str "/page/" (util/encode-str page) "#ls-block-" (:block/uuid data))] (route/redirect-with-fragment! path)) nil)) @@ -100,7 +101,8 @@ {:page page})) :block - (let [block (db/entity [:block/uuid (:block/uuid data)])] + (let [block-uuid (uuid (:block/uuid data)) + block (db/entity [:block/uuid block-uuid])] (state/sidebar-add-block! (state/get-current-repo) (:db/id block) diff --git a/src/main/frontend/db.cljs b/src/main/frontend/db.cljs index 028c5e6369..3eeaa4cb3f 100644 --- a/src/main/frontend/db.cljs +++ b/src/main/frontend/db.cljs @@ -1,6 +1,7 @@ (ns frontend.db (:require [datascript.core :as d] [frontend.date :as date] + [frontend.search.db :as search-db] [medley.core :as medley] [datascript.transit :as dt] [frontend.format :as format] @@ -21,7 +22,8 @@ [frontend.db-schema :as db-schema] [clojure.core.async :as async] [lambdaisland.glogi :as log] - [frontend.idb :as idb])) + [frontend.idb :as idb] + [cljs-bean.core :as bean])) ;; Query atom of map of Key ([repo q inputs]) -> atom ;; TODO: replace with LRUCache, only keep the latest 20 or 50 items? @@ -1930,6 +1932,9 @@ (swap! persistent-jobs assoc repo job))) ;; only save when user's idle + +;; TODO: pass as a parameter +(defonce *sync-search-indice-f (atom nil)) (defn- repo-listen-to-tx! [repo conn files-db?] (d/listen! conn :persistence @@ -1937,7 +1942,17 @@ (let [tx-id (get-tx-id tx-report)] (state/set-last-transact-time! repo (util/time-ms)) ;; (state/persist-transaction! repo files-db? tx-id (:tx-data tx-report)) - (persist-if-idle! repo))))) + (persist-if-idle! repo)) + + ;; rebuild search indices + (when-not files-db? + (let [data (:tx-data tx-report) + datoms (filter + (fn [datom] + (contains? #{:page/name :block/content} (:a datom))) + data)] + (when-let [f @*sync-search-indice-f] + (f datoms))))))) (defn- listen-and-persist! [repo] @@ -2415,6 +2430,18 @@ (reset! blocks-count-cache n) n)))) +;; block/uuid and block/content +(defn get-all-block-contents + [] + (->> (d/datoms (get-conn) :avet :block/uuid) + (map :v) + (map (fn [id] + (let [e (entity [:block/uuid id])] + {:db/id (:db/id e) + :block/uuid id + :block/content (:block/content e) + :block/format (:block/format e)}))))) + (defn get-all-templates [] (let [pred (fn [db properties] diff --git a/src/main/frontend/extensions/code.cljs b/src/main/frontend/extensions/code.cljs index 322b006555..e7c8d459bc 100644 --- a/src/main/frontend/extensions/code.cljs +++ b/src/main/frontend/extensions/code.cljs @@ -36,9 +36,7 @@ ["codemirror/mode/smalltalk/smalltalk"] ["codemirror/mode/sql/sql"] ["codemirror/mode/swift/swift"] - ["codemirror/mode/xml/xml"] - ;; ["parinfer-codemirror" :as par-cm] -)) + ["codemirror/mode/xml/xml"])) ;; codemirror diff --git a/src/main/frontend/handler.cljs b/src/main/frontend/handler.cljs index 1a7ed6264e..0f1992fb14 100644 --- a/src/main/frontend/handler.cljs +++ b/src/main/frontend/handler.cljs @@ -9,6 +9,8 @@ [promesa.core :as p] [cljs-bean.core :as bean] [frontend.date :as date] + [frontend.search :as search] + [frontend.search.db :as search-db] [frontend.handler.notification :as notification] [frontend.handler.page :as page-handler] [frontend.handler.repo :as repo-handler] @@ -25,9 +27,16 @@ (defn- watch-for-date! [] - (js/setInterval (fn [] - (when-not (state/nfs-refreshing?) - (repo-handler/create-today-journal!))) 1000)) + (let [f (fn [] + (when-not (state/nfs-refreshing?) + (repo-handler/create-today-journal!)) + (when-let [repo (state/get-current-repo)] + (when (and (search-db/empty? repo) + (not (state/file-in-writing!)) + (state/input-idle? repo)) + (search/rebuild-indices!))))] + (f) + (js/setInterval f 5000))) (defn store-schema! [] @@ -157,6 +166,7 @@ :example? true}])] (state/set-repos! repos) (restore-and-setup! me repos logged?))) + (reset! db/*sync-search-indice-f search/sync-search-indice!) (db/run-batch-txs!) (file-handler/run-writes-chan!) (editor-handler/periodically-save!))) diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index a2b0e5a809..a05a302832 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -1547,17 +1547,11 @@ editing-page (and block (when-let [page-id (:db/id (:block/page block))] (:page/name (db/entity page-id))))] - (let [pages (db/get-pages (state/get-current-repo)) - pages (if editing-page - ;; To prevent self references - (remove (fn [p] (= (string/lower-case p) editing-page)) pages) - pages)] - (filter - (fn [page] - (string/index-of - (string/lower-case page) - (string/lower-case q))) - pages)))) + (let [pages (search/page-search q 20)] + (if editing-page + ;; To prevent self references + (remove (fn [p] (= (string/lower-case p) editing-page)) pages) + pages)))) (defn get-matched-blocks [q] @@ -1567,7 +1561,7 @@ (fn [h] (= (:block/uuid current-block) (:block/uuid h))) - (search/search q 21)))) + (search/search q 10)))) (defn get-matched-templates [q] diff --git a/src/main/frontend/handler/search.cljs b/src/main/frontend/handler/search.cljs index 6bed5e7747..e7bd0b31f8 100644 --- a/src/main/frontend/handler/search.cljs +++ b/src/main/frontend/handler/search.cljs @@ -2,14 +2,15 @@ (:require [goog.object :as gobj] [frontend.state :as state] [goog.dom :as gdom] - [frontend.search :as search])) + [frontend.search :as search] + [frontend.handler.notification :as notification-handler])) (defn search [q] (swap! state/state assoc :search/result {:pages (search/page-search q) :files (search/file-search q) - :blocks (search/search q)})) + :blocks (search/search q 10)})) (defn clear-search! [] @@ -18,3 +19,11 @@ :search/q "") (when-let [input (gdom/getElement "search_field")] (gobj/set input "value" ""))) + +(defn rebuild-indices! + [] + (println "Starting to rebuild search indices!") + (search/rebuild-indices!) + (notification-handler/show! + "Search indices rebuilt successfully!" + :success)) diff --git a/src/main/frontend/keyboards.cljs b/src/main/frontend/keyboards.cljs index 080d128a1e..00f81dba16 100644 --- a/src/main/frontend/keyboards.cljs +++ b/src/main/frontend/keyboards.cljs @@ -3,7 +3,9 @@ [frontend.handler.history :as history-handler] [frontend.handler.ui :as ui-handler] [frontend.handler.route :as route-handler] + [frontend.handler.search :as search-handler] [frontend.state :as state] + [frontend.search :as search] [frontend.util :as util] [medley.core :as medley] ["mousetrap" :as mousetrap] @@ -70,7 +72,8 @@ "ctrl+h" editor-handler/highlight-format! "ctrl+shift+a" editor-handler/select-all-blocks! "alt+shift+up" (fn [state e] (editor-handler/move-up-down e true)) - "alt+shift+down" (fn [state e] (editor-handler/move-up-down e false))} + "alt+shift+down" (fn [state e] (editor-handler/move-up-down e false)) + "ctrl+c ctrl+s" (fn [state e] (search-handler/rebuild-indices!))} (medley/map-keys util/->system-modifier))) (defonce chords @@ -79,7 +82,8 @@ "t t" state/toggle-theme! "t r" ui-handler/toggle-right-sidebar! "t e" state/toggle-new-block-shortcut! - "s" route-handler/toggle-between-page-and-file!}) + "s" route-handler/toggle-between-page-and-file! + }) (defonce bind! (gobj/get mousetrap "bind")) diff --git a/src/main/frontend/search.cljs b/src/main/frontend/search.cljs index b1f98dec14..aca58acbbe 100644 --- a/src/main/frontend/search.cljs +++ b/src/main/frontend/search.cljs @@ -1,12 +1,67 @@ (ns frontend.search (:require [frontend.db :as db] + [frontend.search.db :as search-db :refer [indices]] [frontend.config :as config] [frontend.state :as state] - [frontend.util :as util] + [frontend.util :as util :refer-macros [profile]] [cljs-bean.core :as bean] [clojure.string :as string] + [clojure.set :as set] [frontend.regex :as regex] - [frontend.text :as text])) + [frontend.text :as text] + [cljs-bean.core :as bean] + [goog.object :as gobj] + ["fuzzysort" :as fuzzy])) + +(def fuzzy-go (gobj/get fuzzy "go")) +(defonce prepare (gobj/get fuzzy "prepare")) +(defonce highlight (gobj/get fuzzy "highlight")) + +(defn go + [q indice opts] + (fuzzy-go q indice opts)) + +(defn block->index + [{:block/keys [uuid content format] :as block}] + (when (<= (count content) 1000) ; performance + (when-let [result (->> (text/remove-level-spaces content format) + (text/remove-properties!) + (prepare))] + (gobj/set result "id" (:db/id block)) + (gobj/set result "uuid" (str uuid)) + result))) + +(defn make-blocks-indice! + [] + (when-let [repo (state/get-current-repo)] + (let [blocks (->> (db/get-all-block-contents) + (map block->index) + (remove nil?) + (bean/->js))] + (swap! indices assoc-in [repo :blocks] blocks) + blocks))) + +(defn make-pages-indice! + [] + (when-let [repo (state/get-current-repo)] + (let [pages (->> (db/get-pages (state/get-current-repo)) + (remove string/blank?) + (map (fn [p] {:name p})) + (bean/->js))] + (swap! indices assoc-in [repo :pages] pages) + pages))) + +;; TODO: persist indices to indexeddb, it'll be better if the future db +;; can has the direct fuzzy search support. +(defn rebuild-indices! + ([] + (rebuild-indices! (state/get-current-repo))) + ([repo] + (when repo + (let [result {:pages (make-pages-indice!) + :blocks (make-blocks-indice!)}] + (swap! indices assoc repo result) + result)))) ;; Copied from https://gist.github.com/vaughnd/5099299 (defn str-len-distance @@ -78,32 +133,48 @@ (defn search "Block search" ([q] - (search q 20)) + (search q 10)) ([q limit] - (when-not (string/blank? q) - (let [q (escape-str q) - q-pattern (re-pattern (str "(?i)" q))] - (when-not (string/blank? q) - (let [blocks (db/get-matched-blocks - (fn [content] - (re-find q-pattern content)) - ;; (fn [content] - ;; (> (score q (.toLowerCase content)) 0)) - limit)] - (map (fn [{:block/keys [content format _properties] :as block}] - (assoc block :block/content - (->> (text/remove-level-spaces content format) - (text/remove-properties!)))) blocks))))))) + (when-let [repo (state/get-current-repo)] + (when-not (string/blank? q) + (let [q (string/lower-case q) + q (escape-str q)] + (when-not (string/blank? q) + (let [indice (or (get-in @indices [repo :blocks]) + (make-blocks-indice!)) + result (-> + (go q indice (clj->js {:limit limit + :allowTypo false + :threshold -10000})) + (bean/->clj))] + (->> + (map + (fn [{:keys [target uuid]}] + {:block/uuid uuid + :block/content target}) + result) + (remove nil?))))))))) (defn page-search ([q] (page-search q 3)) ([q limit] - (let [q (clean-str q)] - (when-not (string/blank? q) - (let [pages (db/get-pages (state/get-current-repo))] - (when (seq pages) - (fuzzy-search pages q :limit limit))))))) + (when-let [repo (state/get-current-repo)] + (let [q (string/lower-case q) + q (clean-str q)] + (when-not (string/blank? q) + (let [indice (or (get-in @indices [repo :pages]) + (make-pages-indice!)) + result (->> (go q indice (clj->js {:limit limit + :key "name" + :allowTypo false + :threshold -10000})) + (bean/->clj))] + (->> (map + (fn [{:keys [obj]}] + (:name obj)) + result) + (remove nil?)))))))) (defn file-search ([q] @@ -128,3 +199,49 @@ (when (seq templates) (let [result (fuzzy-search (keys templates) q :limit limit)] (vec (select-keys templates result)))))))) + +(defn sync-search-indice! + [datoms] + (when (seq datoms) + (when-let [repo (state/get-current-repo)] + (let [datoms (group-by :a datoms) + pages (:page/name datoms) + blocks (:block/content datoms)] + (when (seq pages) + (let [pages-result (db/pull-many '[:db/id :page/original-name] (set (map :e pages))) + pages-to-add-set (->> (filter :added pages) + (map :e) + (set)) + pages-to-add (->> (filter (fn [page] + (contains? pages-to-add-set (:db/id page))) pages-result) + (map (fn [p] {:name (:page/original-name p)})) + (set)) + pages-to-remove-set (->> (remove :added pages) + (map :v) + (set))] + (swap! search-db/indices update-in [repo :pages] + (fn [pages] + (let [pages (or pages (array)) + pages (.filter pages (fn [page] + (not (contains? pages-to-remove-set + (string/lower-case (gobj/get page "name"))))))] + (.concat pages (bean/->js pages-to-add))))))) + (when (seq blocks) + (let [blocks-result (db/pull-many '[:db/id :block/uuid :block/format :block/content] (set (map :e blocks))) + blocks-to-add-set (->> (filter :added blocks) + (map :e) + (set)) + blocks-to-add (->> (filter (fn [block] + (contains? blocks-to-add-set (:db/id block))) + blocks-result) + (map block->index) + (set)) + blocks-to-remove-set (->> (remove :added blocks) + (map :e) + (set))] + (swap! search-db/indices update-in [repo :blocks] + (fn [blocks] + (let [blocks (or blocks (array)) + blocks (.filter blocks (fn [block] + (not (contains? blocks-to-remove-set (gobj/get block "id")))))] + (.concat blocks (bean/->js blocks-to-add))))))))))) diff --git a/src/main/frontend/search/db.cljs b/src/main/frontend/search/db.cljs new file mode 100644 index 0000000000..362264043b --- /dev/null +++ b/src/main/frontend/search/db.cljs @@ -0,0 +1,8 @@ +(ns frontend.search.db + (:refer-clojure :exclude [empty?])) + +(defonce indices (atom nil)) + +(defn empty? + [repo] + (nil? (get @indices repo))) diff --git a/src/main/frontend/sync/dropbox.cljs b/src/main/frontend/sync/dropbox.cljs deleted file mode 100644 index 6a67c8c852..0000000000 --- a/src/main/frontend/sync/dropbox.cljs +++ /dev/null @@ -1,58 +0,0 @@ -(ns frontend.sync.dropbox) - -;; (ns frontend.sync.dropbox -;; (:require ["dropbox" :as dropbox] -;; [goog.object :as gobj] -;; [frontend.sync.protocol :refer [Sync] :as sync] -;; [promesa.core :as p] -;; [cljs-bean.core :as bean])) - -;; ;; Note: there's also a `DropboxTeam` -;; (defonce DropboxModule (gobj/get dropbox "Dropbox")) - -;; (defonce *dropbox-client (atom nil)) - -;; (defn upload-file -;; [client path contents] -;; (.filesUpload ^Object client -;; (bean/->js {:path path -;; :contents contents -;; :mode {".tag" "overwrite"} -;; :autorename true}))) - -;; (defrecord Dropbox [token] -;; Sync -;; (get-client [this] -;; (if-let [client @*dropbox-client] -;; client -;; (let [client (DropboxModule. #js {:accessToken token})] -;; (reset! *dropbox-client client) -;; client))) -;; (signed? [this] -;; true) -;; (get-dir [this path] -;; (p/let [resp (.filesListFolder ^Object (sync/get-client this) (bean/->js {:path path}))] -;; (bean/->clj resp))) -;; (get-more-dir [this cursor] -;; (p/let [resp (.filesListFolderContinue ^Object (sync/get-client this) (bean/->js {:cursor cursor}))] -;; (bean/->clj resp))) -;; (create-file [this path contents] -;; (upload-file ^Object (sync/get-client this) path contents)) -;; (update-file [this path contents] -;; (upload-file ^Object (sync/get-client this) path contents)) -;; (get-file-contents-and-metadata [this path] -;; (-> -;; (p/let [resp (.filesDownload ^Object (sync/get-client this) (bean/->js {:path path})) -;; file-binary (gobj/get resp "fileBinary") -;; contents (.toString file-binary) -;; last-modified-at (gobj/get resp "server_modified")] -;; {:contents contents -;; :last-modified-at last-modified-at}) -;; (p/catch -;; (fn [error] -;; ;; TODO: -;; (println "Dropbox get file " path " failed:") -;; (js/console.dir error)) -;; ))) -;; (delete-file [this path] -;; (.filesDelete ^Object (sync/get-client this) (bean/->js {:path path})))) diff --git a/src/main/frontend/sync/protocol.cljs b/src/main/frontend/sync/protocol.cljs deleted file mode 100644 index 26dbe2a29c..0000000000 --- a/src/main/frontend/sync/protocol.cljs +++ /dev/null @@ -1,11 +0,0 @@ -(ns frontend.sync.protocol) - -(defprotocol Sync - (get-client [this]) - (signed? [this]) - (get-dir [this path]) - (get-more-dir [this more-state]) - (create-file [this path contents]) - (update-file [this path contents]) - (get-file-contents-and-metadata [this path]) - (delete-file [this path])) diff --git a/yarn.lock b/yarn.lock index bfe7205820..12442b480b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -559,13 +559,6 @@ autoprefixer@^9.8.6: postcss "^7.0.32" postcss-value-parser "^4.1.0" -axios@^0.20.0: - version "0.20.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.20.0.tgz#057ba30f04884694993a8cd07fa394cff11c50bd" - integrity sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA== - dependencies: - follow-redirects "^1.10.0" - bach@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/bach/-/bach-1.2.0.tgz#4b3ce96bf27134f79a1b414a51c14e34c3bd9880" @@ -591,12 +584,7 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= -base-64@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/base-64/-/base-64-0.1.0.tgz#780a99c84e7d600260361511c4877613bf24f6bb" - integrity sha1-eAqZyE59YAJgNhURxId2E78k9rs= - -base64-js@^1.0.2, base64-js@^1.3.1: +base64-js@^1.0.2: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -778,14 +766,6 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" -buffer@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" @@ -1621,14 +1601,6 @@ dot-prop@^5.2.0: dependencies: is-obj "^2.0.0" -dropbox@^5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/dropbox/-/dropbox-5.2.1.tgz#ef2f40d2216bfd90381d033beddb6c13e27b6e56" - integrity sha512-B34kdU6X56DdN1wGjRSb30I9oXy4t33ssu+JLbc9wHZACgstRb8Jb2hzoCOtHv+ZCCgwQJ0fEztVcXJRGpHQnQ== - dependencies: - buffer "^5.6.0" - moment "^2.25.3" - duplexify@^3.6.0: version "3.7.1" resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" @@ -1648,9 +1620,9 @@ each-props@^1.3.0: object.defaults "^1.1.0" electron-to-chromium@^1.3.621: - version "1.3.622" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.622.tgz#9726bd2e67a5462154750ce9701ca6af07d07877" - integrity sha512-AJT0Fm1W0uZlMVVkkJrcCVvczDuF8tPm3bwzQf5WO8AaASB2hwTRP7B8pU5rqjireH+ib6am8+hH5/QkXzzYKw== + version "1.3.625" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.625.tgz#a7bd18da4dc732c180b2e95e0e296c0bf22f3bd6" + integrity sha512-CsLk/r0C9dAzVPa9QF74HIXduxaucsaRfqiOYvIv2PRhvyC6EOqc/KbpgToQuDVgPf3sNAFZi3iBu4vpGOwGag== elliptic@^6.5.3: version "6.5.3" @@ -1907,11 +1879,6 @@ fast-levenshtein@^1.0.0: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz#e6a754cc8f15e58987aa9cbd27af66fd6f4e5af9" integrity sha1-5qdUzI8V5YmHqpy9J69m/W9OWvk= -fast-xml-parser@^3.17.4: - version "3.17.5" - resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.17.5.tgz#760bc7755681d2e1d70329c9ac6a1a7cb38b135e" - integrity sha512-lEvThd1Xq+CCylf1n+05bUZCDZjTufaaaqpxM3JZ+4iDqtlG+d/oKgtMmg9GEMOuzBgUoalIzFOaClht9YiGJQ== - fastest-levenshtein@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" @@ -2026,11 +1993,6 @@ flush-write-stream@^1.0.2: inherits "^2.0.3" readable-stream "^2.3.6" -follow-redirects@^1.10.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db" - integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA== - for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -2091,6 +2053,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +fuzzysort@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/fuzzysort/-/fuzzysort-1.1.4.tgz#a0510206ed44532cbb52cf797bf5a3cb12acd4ba" + integrity sha512-JzK/lHjVZ6joAg3OnCjylwYXYVjRiwTY6Yb25LvfpJHK8bjisfnZJ5bY8aVWwTwCXgxPNgLAtmHL+Hs5q1ddLQ== + gensync@^1.0.0-beta.1: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -2403,11 +2370,6 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" -he@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - hex-color-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" @@ -2446,11 +2408,6 @@ hosted-git-info@^3.0.6: dependencies: lru-cache "^6.0.0" -hot-patcher@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/hot-patcher/-/hot-patcher-0.5.0.tgz#9d401424585aaf3a91646b816ceff40eb6a916b9" - integrity sha512-2Uu2W0s8+dnqXzdlg0MRsRzPoDCs1wVjOGSyMRRaMzLDX4bgHw6xDYKccsWafXPPxQpkQfEjgW6+17pwcg60bw== - hsl-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" @@ -2488,7 +2445,7 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= -ieee754@^1.1.13, ieee754@^1.1.4: +ieee754@^1.1.4: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -3071,13 +3028,6 @@ lead@^1.0.0: dependencies: flush-write-stream "^1.0.2" -lie@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" - integrity sha1-mkNrLMd0bKWd56QfpGmz77dr2H4= - dependencies: - immediate "~3.0.5" - lie@~3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" @@ -3125,13 +3075,6 @@ load-json-file@^4.0.0: pify "^3.0.0" strip-bom "^3.0.0" -localforage@^1.7.3: - version "1.9.0" - resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.9.0.tgz#f3e4d32a8300b362b4634cc4e066d9d00d2f09d1" - integrity sha512-rR1oyNrKulpe+VM9cYmcFn6tsHuokyVHFaCM3+osEmxaHTbEk8oQu6eGDfS6DQLWi/N67XRmB8ECG37OES368g== - dependencies: - lie "3.1.1" - locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -3432,11 +3375,6 @@ modern-normalize@^1.0.0: resolved "https://registry.yarnpkg.com/modern-normalize/-/modern-normalize-1.0.0.tgz#539d84a1e141338b01b346f3e27396d0ed17601e" integrity sha512-1lM+BMLGuDfsdwf3rsgBSrxJwAZHFIrQ8YR61xIqdHo0uNKI9M52wNpHSrliZATJp51On6JD0AfRxd4YGSU0lw== -moment@^2.25.3: - version "2.29.1" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" - integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== - mousetrap@^1.6.5: version "1.6.5" resolved "https://registry.yarnpkg.com/mousetrap/-/mousetrap-1.6.5.tgz#8a766d8c272b08393d5f56074e0b5ec183485bf9" @@ -3484,11 +3422,6 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -nested-property@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/nested-property/-/nested-property-4.0.0.tgz#a67b5a31991e701e03cdbaa6453bc5b1011bb88d" - integrity sha512-yFehXNWRs4cM0+dz7QxCd06hTbWbSkV0ISsqBfkntU6TOY4Qm3Q88fRRLOddkGh2Qq6dZvnKVAahfhjcUvLnyA== - next-tick@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" @@ -3788,18 +3721,6 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parinfer-codemirror@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/parinfer-codemirror/-/parinfer-codemirror-1.4.2.tgz#2b9b7f27af65bf14282034a17731d4a82367d046" - integrity sha1-K5t/J69lvxQoIDShdzHUqCNn0EY= - dependencies: - parinfer "^3.11.0" - -parinfer@^3.11.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/parinfer/-/parinfer-3.12.0.tgz#6ea16236319717d579275aa9a94ed1197c3cbd62" - integrity sha512-iViQ8vtJ6CEa9x0SxcQCtsOYSCVVu7ILnuUJfKHPEGjxM0Z6R1EdAJX3kWyqZDrszvQyYWl/XpD9pN2IFgSF/g== - parse-asn1@^5.0.0, parse-asn1@^5.1.5: version "5.1.6" resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" @@ -3914,11 +3835,6 @@ path-parse@^1.0.6: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== -path-posix@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/path-posix/-/path-posix-1.0.0.tgz#06b26113f56beab042545a23bfa88003ccac260f" - integrity sha1-BrJhE/Vr6rBCVFojv6iAA8ysJg8= - path-root-regex@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" @@ -4537,11 +4453,6 @@ querystring@0.2.0: resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= -querystringify@^2.1.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" - integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== - quick-lru@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" @@ -4815,11 +4726,6 @@ require-main-filename@^1.0.1: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= - resolve-dir@^1.0.0, resolve-dir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" @@ -5776,19 +5682,6 @@ urix@^0.1.0: resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= -url-join@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7" - integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA== - -url-parse@^1.4.7: - version "1.4.7" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" - integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== - dependencies: - querystringify "^2.1.1" - requires-port "^1.0.0" - url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" @@ -5958,22 +5851,6 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -webdav@^3.3.0: - version "3.6.1" - resolved "https://registry.yarnpkg.com/webdav/-/webdav-3.6.1.tgz#ab01f8067faf748abe3938720dcaeb39836d78e3" - integrity sha512-WRE6M4iePpd4TPJ0l5PCWMuoZS4UOHawtf/fr7FcmTZWsSjx1syywyW3TbgEFHptqyh4mMoLUrv8dAUtmTqbEg== - dependencies: - axios "^0.20.0" - base-64 "^0.1.0" - fast-xml-parser "^3.17.4" - he "^1.2.0" - hot-patcher "^0.5.0" - minimatch "^3.0.4" - nested-property "^4.0.0" - path-posix "^1.0.0" - url-join "^4.0.1" - url-parse "^1.4.7" - which-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f"