├── .github ├── FUNDING.yml └── workflows │ ├── ci.yml │ └── publish.yml ├── .gitignore ├── .vscode └── extensions.json ├── LICENSE ├── README.md ├── index.html ├── package.json ├── public ├── demo.gif ├── favicon.ico └── icon.png ├── src ├── App.svelte ├── Edge.svelte ├── Node.svelte ├── Sigma.svelte ├── __snapshots__ │ ├── graph.ts.snap │ └── stores.ts.snap ├── analysis.ts ├── graph.ts ├── logseq.ts ├── main.ts ├── settings │ ├── Settings.svelte │ ├── components │ │ └── NodeFilter.svelte │ ├── helpers │ │ └── search.ts │ └── themes.ts ├── shortestPath.ts ├── sigma │ ├── drawHover.ts │ ├── sigma.d.ts │ └── sigma.js ├── stores.ts └── vite-env.d.ts ├── svelte.config.js ├── tsconfig.json ├── vite.config.ts └── yarn.lock /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | ko_fi: trashhalo 2 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | branches: 10 | - main 11 | 12 | jobs: 13 | test: 14 | runs-on: ${{ matrix.os }} 15 | 16 | strategy: 17 | matrix: 18 | node: [16.x] 19 | os: [ubuntu-latest] 20 | fail-fast: false 21 | 22 | steps: 23 | - uses: actions/checkout@v3 24 | - name: Set node ${{ matrix.node }} 25 | uses: actions/setup-node@v3 26 | with: 27 | node-version: ${{ matrix.node }} 28 | 29 | - name: Setup 30 | run: npm i -g @antfu/ni 31 | 32 | - name: Install 33 | run: nci 34 | 35 | - name: Build 36 | run: nr build 37 | 38 | - name: Test 39 | run: nr test 40 | 41 | - name: Build Unpacked Plugin 42 | run: | 43 | mkdir logseq-graph-analysis 44 | cp package.json README.md logseq-graph-analysis 45 | mv dist logseq-graph-analysis 46 | 47 | - uses: jwalton/gh-find-current-pr@v1 48 | id: findPr 49 | with: 50 | state: open 51 | 52 | - uses: actions/upload-artifact@v3 53 | with: 54 | name: logseq-graph-analysis-${{ steps.findPr.outputs.pr }} 55 | path: logseq-graph-analysis 56 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Build plugin 2 | 3 | on: 4 | push: 5 | # Sequence of patterns matched against refs/tags 6 | tags: 7 | - "*" # Push events to matching any tag format, i.e. 1.0, 20.15.10 8 | 9 | env: 10 | PLUGIN_NAME: logseq-graph-analysis 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | - name: Use Node.js 19 | uses: actions/setup-node@v1 20 | with: 21 | node-version: "14.x" # You might need to adjust this value to your own version 22 | - name: Build 23 | id: build 24 | run: | 25 | npm install -g yarn 26 | yarn 27 | yarn build 28 | mkdir ${{ env.PLUGIN_NAME }} 29 | cp package.json README.md ${{ env.PLUGIN_NAME }} 30 | mv dist ${{ env.PLUGIN_NAME }} 31 | zip -r ${{ env.PLUGIN_NAME }}.zip ${{ env.PLUGIN_NAME }} 32 | ls 33 | echo "::set-output name=tag_name::$(git tag --sort version:refname | tail -n 1)" 34 | 35 | - name: Create Release 36 | uses: ncipollo/release-action@v1 37 | id: create_release 38 | env: 39 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 40 | VERSION: ${{ github.ref }} 41 | with: 42 | allowUpdates: true 43 | draft: false 44 | prerelease: false 45 | 46 | - name: Upload zip file 47 | id: upload_zip 48 | uses: actions/upload-release-asset@v1 49 | env: 50 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 51 | with: 52 | upload_url: ${{ steps.create_release.outputs.upload_url }} 53 | asset_path: ./${{ env.PLUGIN_NAME }}.zip 54 | asset_name: ${{ env.PLUGIN_NAME }}-${{ steps.build.outputs.tag_name }}.zip 55 | asset_content_type: application/zip 56 | 57 | - name: Upload package.json 58 | id: upload_metadata 59 | uses: actions/upload-release-asset@v1 60 | env: 61 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 62 | with: 63 | upload_url: ${{ steps.create_release.outputs.upload_url }} 64 | asset_path: ./package.json 65 | asset_name: package.json 66 | asset_content_type: application/json 67 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | coverage 15 | 16 | # Editor directories and files 17 | .vscode/* 18 | !.vscode/extensions.json 19 | .idea 20 | .DS_Store 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw? 26 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["svelte.svelte-vscode"] 3 | } 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | logseq-graph-analysis Copyright (C) 2022 Stephen Solka 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Logseq Graph Analysis 2 | 3 | Learn more about the relationships between between your notes using network analysis algorithms. 4 | 5 | ![demo](./public/demo.gif) 6 | 7 | ## Installation 8 | 9 | - Download a released version assets from Github. 10 | - Unzip it. 11 | - Click Load unpacked plugin, and select destination directory to the unzipped folder. 12 | 13 | ## Usage 14 | 15 | - Click the graph icon to go into `graph analysis` mode. 16 | - There are 3 modes to play with 17 | - Navigate - Clicking a node will open it in logseq to edit. 18 | - Shortest Path - Find the shortest path between 2 notes. Click a note to select it. 19 | - Adamic Adar - Find secret connections between your notes. Click a note to learn which notes the algorithm thinks are linked 20 | - CoCitation - Checks how alike documents are by looking at how close their shared references are 21 | - Shift-click node to add it to sidebar 22 | - If there are nodes you wish to hide from your graph add the page property `graph-hide:: true` or `exclude-from-graph-view:: true` 23 | - `graph-hide:: true` hides nodes from this plugin's `graph analysis` mode 24 | - `exclude-from-graph-view:: true` hides nodes from both this plugin and Logseq's native global graph view, see [the Logseq documentation](https://docs.logseq.com/#/page/built-in%20properties) 25 | - If you are interested in seeing suprising paths in your notes its a good idea to add this to notes that have lots of connections. 26 | 27 | ## Search and filters 28 | 29 | https://github.com/trashhalo/logseq-graph-analysis/assets/19637629/6094b35c-2e0c-4026-8256-12c6329795d7 30 | 31 | You can use Search to highlight page on grapg by title. `filter ` checkbox will keep only found pages + n neighbours 32 | 33 | `Filters` allows you to color nodes by search query. 34 | 35 | Both search and queries supports text search and regexp. Use `q: {your query}` to search using logseq quries 36 | 37 | ## Settings 38 | 39 | - journal: show journal pages on your graph. may be slower. default false 40 | 41 | ## Development 42 | 43 | 1. yarn 44 | 2. yarn build 45 | 3. Load the unpacked plugin 46 | 47 | ## Icon 48 | 49 | [Algorithm icons created by Becris - Flaticon](https://www.flaticon.com/free-icons/algorithm) 50 | 51 | ## Thank You 52 | 53 | Huge thanks to [obsidian graph analysis](https://github.com/SkepticMystic/graph-analysis) for the inspiration and implementation of the adar algorithm! 54 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Svelte + TS + Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "logseq-graph-analysis", 3 | "version": "0.12.0", 4 | "type": "module", 5 | "main": "./dist/index.html", 6 | "license": "GPL", 7 | "scripts": { 8 | "dev": "vite", 9 | "build": "vite build", 10 | "preview": "vite preview", 11 | "check": "svelte-check --tsconfig ./tsconfig.json", 12 | "test": "vitest", 13 | "coverage": "vitest run --coverage" 14 | }, 15 | "devDependencies": { 16 | "@iconify-json/mdi": "^1.1.24", 17 | "@sveltejs/vite-plugin-svelte": "^1.0.0-next.30", 18 | "@tsconfig/svelte": "^2.0.1", 19 | "@unocss/preset-icons": "^0.41.1", 20 | "c8": "^7.11.3", 21 | "graphology-types": "^0.24.4", 22 | "svelte": "^3.44.0", 23 | "svelte-check": "^2.2.7", 24 | "svelte-preprocess": "^4.9.8", 25 | "tslib": "^2.3.1", 26 | "typescript": "^4.5.4", 27 | "unocss": "^0.41.1", 28 | "vite": "^2.9.9", 29 | "vite-plugin-logseq": "^1.1.2", 30 | "vitest": "^0.16.0" 31 | }, 32 | "dependencies": { 33 | "@logseq/libs": "^0.0.15", 34 | "@unocss/reset": "^0.41.1", 35 | "graphology": "^0.25.1", 36 | "graphology-layout": "^0.6.0", 37 | "graphology-layout-force": "0.2.4", 38 | "graphology-layout-forceatlas2": "^0.10.1", 39 | "graphology-operators": "^1.5.1", 40 | "graphology-shortest-path": "^2.0.1", 41 | "sigma": "^2.3.1" 42 | }, 43 | "logseq": { 44 | "id": "_trashhalo-logseq-graph-analysis", 45 | "icon": "./dist/icon.png" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /public/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trashhalo/logseq-graph-analysis/0309a3c9a69e6ad1869bfbd0ade371c15fd5a0a2/public/demo.gif -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trashhalo/logseq-graph-analysis/0309a3c9a69e6ad1869bfbd0ade371c15fd5a0a2/public/favicon.ico -------------------------------------------------------------------------------- /public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trashhalo/logseq-graph-analysis/0309a3c9a69e6ad1869bfbd0ade371c15fd5a0a2/public/icon.png -------------------------------------------------------------------------------- /src/App.svelte: -------------------------------------------------------------------------------- 1 | 190 | 191 | 192 | 193 |
194 |
195 | 201 |
202 | 203 | {@const graph = filteredGraph( 204 | $graph, 205 | $settings.filter, 206 | $settings.search, 207 | $settings.filterLength, 208 | )} 209 | {#each graph.nodes() as node (node)} 210 | 211 | {/each} 212 | {#each graph.edges() as edge (edge)} 213 | 218 | {/each} 219 | 220 | 221 |
222 | 223 | 238 | -------------------------------------------------------------------------------- /src/Edge.svelte: -------------------------------------------------------------------------------- 1 | 38 | -------------------------------------------------------------------------------- /src/Node.svelte: -------------------------------------------------------------------------------- 1 | 29 | -------------------------------------------------------------------------------- /src/Sigma.svelte: -------------------------------------------------------------------------------- 1 | 318 | 319 |
320 | 321 | 322 | 331 | -------------------------------------------------------------------------------- /src/__snapshots__/graph.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1 2 | 3 | exports[`buildGraph > alias nodes empty cases shoud not fail 1`] = ` 4 | { 5 | "attributes": { 6 | "isInited": true, 7 | }, 8 | "edges": [], 9 | "nodes": [ 10 | { 11 | "attributes": { 12 | "aliases": [], 13 | "label": "A", 14 | "rawAliases": [], 15 | "type": "circle", 16 | }, 17 | }, 18 | { 19 | "attributes": { 20 | "aliases": [ 21 | "TEST", 22 | ], 23 | "label": "B", 24 | "rawAliases": [ 25 | "test", 26 | ], 27 | "type": "circle", 28 | }, 29 | }, 30 | { 31 | "attributes": { 32 | "aliases": [], 33 | "label": "C", 34 | "rawAliases": [], 35 | "type": "circle", 36 | }, 37 | }, 38 | ], 39 | "options": { 40 | "allowSelfLoops": true, 41 | "multi": false, 42 | "type": "mixed", 43 | }, 44 | } 45 | `; 46 | 47 | exports[`buildGraph > creates a graph with edges 1`] = ` 48 | { 49 | "attributes": { 50 | "isInited": true, 51 | }, 52 | "edges": [ 53 | { 54 | "attributes": { 55 | "weight": 1, 56 | }, 57 | "source": "1", 58 | "target": "2", 59 | }, 60 | ], 61 | "nodes": [ 62 | { 63 | "attributes": { 64 | "aliases": [], 65 | "label": "A", 66 | "rawAliases": [], 67 | "type": "circle", 68 | }, 69 | }, 70 | { 71 | "attributes": { 72 | "aliases": [], 73 | "label": "B", 74 | "rawAliases": [], 75 | "type": "circle", 76 | }, 77 | }, 78 | ], 79 | "options": { 80 | "allowSelfLoops": true, 81 | "multi": false, 82 | "type": "mixed", 83 | }, 84 | } 85 | `; 86 | 87 | exports[`buildGraph > does not shows journal pages when not requested 1`] = ` 88 | { 89 | "attributes": { 90 | "isInited": true, 91 | }, 92 | "edges": [], 93 | "nodes": [ 94 | { 95 | "attributes": { 96 | "aliases": [], 97 | "label": "A", 98 | "rawAliases": [], 99 | "type": "circle", 100 | }, 101 | }, 102 | ], 103 | "options": { 104 | "allowSelfLoops": true, 105 | "multi": false, 106 | "type": "mixed", 107 | }, 108 | } 109 | `; 110 | 111 | exports[`buildGraph > handles block references 1`] = ` 112 | { 113 | "attributes": { 114 | "isInited": true, 115 | }, 116 | "edges": [ 117 | { 118 | "attributes": { 119 | "weight": 1, 120 | }, 121 | "source": "1", 122 | "target": "2", 123 | }, 124 | ], 125 | "nodes": [ 126 | { 127 | "attributes": { 128 | "aliases": [], 129 | "label": "A", 130 | "rawAliases": [], 131 | "type": "circle", 132 | }, 133 | }, 134 | { 135 | "attributes": { 136 | "aliases": [], 137 | "label": "B", 138 | "rawAliases": [], 139 | "type": "circle", 140 | }, 141 | }, 142 | ], 143 | "options": { 144 | "allowSelfLoops": true, 145 | "multi": false, 146 | "type": "mixed", 147 | }, 148 | } 149 | `; 150 | 151 | exports[`buildGraph > increases the weight for multiple edges 1`] = ` 152 | { 153 | "attributes": { 154 | "isInited": true, 155 | }, 156 | "edges": [ 157 | { 158 | "attributes": { 159 | "weight": 2, 160 | }, 161 | "source": "1", 162 | "target": "2", 163 | }, 164 | ], 165 | "nodes": [ 166 | { 167 | "attributes": { 168 | "aliases": [], 169 | "label": "A", 170 | "rawAliases": [], 171 | "type": "circle", 172 | }, 173 | }, 174 | { 175 | "attributes": { 176 | "aliases": [], 177 | "label": "B", 178 | "rawAliases": [], 179 | "type": "circle", 180 | }, 181 | }, 182 | ], 183 | "options": { 184 | "allowSelfLoops": true, 185 | "multi": false, 186 | "type": "mixed", 187 | }, 188 | } 189 | `; 190 | 191 | exports[`buildGraph > links graphs to nested parents 1`] = ` 192 | { 193 | "attributes": { 194 | "isInited": true, 195 | }, 196 | "edges": [ 197 | { 198 | "attributes": { 199 | "weight": 1, 200 | }, 201 | "source": "1", 202 | "target": "2", 203 | }, 204 | { 205 | "attributes": { 206 | "weight": 1, 207 | }, 208 | "source": "2", 209 | "target": "3", 210 | }, 211 | ], 212 | "nodes": [ 213 | { 214 | "attributes": { 215 | "aliases": [], 216 | "label": "A", 217 | "rawAliases": [], 218 | "type": "circle", 219 | }, 220 | }, 221 | { 222 | "attributes": { 223 | "aliases": [], 224 | "label": "B", 225 | "rawAliases": [], 226 | "type": "circle", 227 | }, 228 | }, 229 | { 230 | "attributes": { 231 | "aliases": [], 232 | "label": "C", 233 | "rawAliases": [], 234 | "type": "circle", 235 | }, 236 | }, 237 | ], 238 | "options": { 239 | "allowSelfLoops": true, 240 | "multi": false, 241 | "type": "mixed", 242 | }, 243 | } 244 | `; 245 | 246 | exports[`buildGraph > links shared references in a block 1`] = ` 247 | { 248 | "attributes": { 249 | "isInited": true, 250 | }, 251 | "edges": [ 252 | { 253 | "attributes": { 254 | "weight": 1, 255 | }, 256 | "source": "1", 257 | "target": "2", 258 | }, 259 | { 260 | "attributes": { 261 | "weight": 1, 262 | }, 263 | "source": "1", 264 | "target": "3", 265 | }, 266 | { 267 | "attributes": { 268 | "weight": 1, 269 | }, 270 | "source": "2", 271 | "target": "3", 272 | }, 273 | { 274 | "attributes": { 275 | "weight": 1, 276 | }, 277 | "source": "3", 278 | "target": "2", 279 | }, 280 | ], 281 | "nodes": [ 282 | { 283 | "attributes": { 284 | "aliases": [], 285 | "label": "A", 286 | "rawAliases": [], 287 | "type": "circle", 288 | }, 289 | }, 290 | { 291 | "attributes": { 292 | "aliases": [], 293 | "label": "B", 294 | "rawAliases": [], 295 | "type": "circle", 296 | }, 297 | }, 298 | { 299 | "attributes": { 300 | "aliases": [], 301 | "label": "C", 302 | "rawAliases": [], 303 | "type": "circle", 304 | }, 305 | }, 306 | ], 307 | "options": { 308 | "allowSelfLoops": true, 309 | "multi": false, 310 | "type": "mixed", 311 | }, 312 | } 313 | `; 314 | 315 | exports[`buildGraph > merges alias nodes 1`] = ` 316 | { 317 | "attributes": { 318 | "isInited": true, 319 | }, 320 | "edges": [ 321 | { 322 | "attributes": { 323 | "weight": 1, 324 | }, 325 | "source": "3", 326 | "target": "1", 327 | }, 328 | ], 329 | "nodes": [ 330 | { 331 | "attributes": { 332 | "aliases": [ 333 | "B", 334 | ], 335 | "label": "A", 336 | "rawAliases": [ 337 | "B", 338 | ], 339 | "type": "circle", 340 | }, 341 | }, 342 | { 343 | "attributes": { 344 | "aliases": [], 345 | "label": "C", 346 | "rawAliases": [], 347 | "type": "circle", 348 | }, 349 | }, 350 | ], 351 | "options": { 352 | "allowSelfLoops": true, 353 | "multi": false, 354 | "type": "mixed", 355 | }, 356 | } 357 | `; 358 | 359 | exports[`buildGraph > shows journal pages when requested 1`] = ` 360 | { 361 | "attributes": { 362 | "isInited": true, 363 | }, 364 | "edges": [ 365 | { 366 | "attributes": { 367 | "weight": 1, 368 | }, 369 | "source": "1", 370 | "target": "2", 371 | }, 372 | ], 373 | "nodes": [ 374 | { 375 | "attributes": { 376 | "aliases": [], 377 | "label": "A", 378 | "rawAliases": [], 379 | "type": "circle", 380 | }, 381 | }, 382 | { 383 | "attributes": { 384 | "aliases": [], 385 | "label": "B", 386 | "rawAliases": [], 387 | "type": "circle", 388 | }, 389 | }, 390 | ], 391 | "options": { 392 | "allowSelfLoops": true, 393 | "multi": false, 394 | "type": "mixed", 395 | }, 396 | } 397 | `; 398 | 399 | exports[`buildGraph > skips pages with exclude-from-graph-view: true 1`] = ` 400 | { 401 | "attributes": { 402 | "isInited": true, 403 | }, 404 | "edges": [], 405 | "nodes": [ 406 | { 407 | "attributes": { 408 | "aliases": [], 409 | "label": "A", 410 | "rawAliases": [], 411 | "type": "circle", 412 | }, 413 | }, 414 | ], 415 | "options": { 416 | "allowSelfLoops": true, 417 | "multi": false, 418 | "type": "mixed", 419 | }, 420 | } 421 | `; 422 | 423 | exports[`buildGraph > skips pages with graph-hide: true 1`] = ` 424 | { 425 | "attributes": { 426 | "isInited": true, 427 | }, 428 | "edges": [], 429 | "nodes": [ 430 | { 431 | "attributes": { 432 | "aliases": [], 433 | "label": "A", 434 | "rawAliases": [], 435 | "type": "circle", 436 | }, 437 | }, 438 | ], 439 | "options": { 440 | "allowSelfLoops": true, 441 | "multi": false, 442 | "type": "mixed", 443 | }, 444 | } 445 | `; 446 | 447 | exports[`buildGraph > skips references to journal pages 1`] = ` 448 | { 449 | "attributes": { 450 | "isInited": true, 451 | }, 452 | "edges": [ 453 | { 454 | "attributes": { 455 | "weight": 1, 456 | }, 457 | "source": "1", 458 | "target": "3", 459 | }, 460 | ], 461 | "nodes": [ 462 | { 463 | "attributes": { 464 | "aliases": [], 465 | "label": "A", 466 | "rawAliases": [], 467 | "type": "circle", 468 | }, 469 | }, 470 | { 471 | "attributes": { 472 | "aliases": [], 473 | "label": "C", 474 | "rawAliases": [], 475 | "type": "circle", 476 | }, 477 | }, 478 | ], 479 | "options": { 480 | "allowSelfLoops": true, 481 | "multi": false, 482 | "type": "mixed", 483 | }, 484 | } 485 | `; 486 | -------------------------------------------------------------------------------- /src/__snapshots__/stores.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1 2 | 3 | exports[`buildGraph > creates a graph with edges 1`] = ` 4 | { 5 | "attributes": {}, 6 | "edges": [ 7 | { 8 | "attributes": { 9 | "weight": 1, 10 | }, 11 | "source": "1", 12 | "target": "2", 13 | }, 14 | ], 15 | "nodes": [ 16 | { 17 | "attributes": { 18 | "aliases": [], 19 | "label": "A", 20 | }, 21 | }, 22 | { 23 | "attributes": { 24 | "aliases": [], 25 | "label": "B", 26 | }, 27 | }, 28 | ], 29 | "options": { 30 | "allowSelfLoops": true, 31 | "multi": false, 32 | "type": "mixed", 33 | }, 34 | } 35 | `; 36 | 37 | exports[`buildGraph > does not shows journal pages when not requested 1`] = ` 38 | { 39 | "attributes": {}, 40 | "edges": [], 41 | "nodes": [ 42 | { 43 | "attributes": { 44 | "aliases": [], 45 | "label": "A", 46 | }, 47 | }, 48 | ], 49 | "options": { 50 | "allowSelfLoops": true, 51 | "multi": false, 52 | "type": "mixed", 53 | }, 54 | } 55 | `; 56 | 57 | exports[`buildGraph > handles block references 1`] = ` 58 | { 59 | "attributes": {}, 60 | "edges": [ 61 | { 62 | "attributes": { 63 | "weight": 1, 64 | }, 65 | "source": "1", 66 | "target": "2", 67 | }, 68 | ], 69 | "nodes": [ 70 | { 71 | "attributes": { 72 | "aliases": [], 73 | "label": "A", 74 | }, 75 | }, 76 | { 77 | "attributes": { 78 | "aliases": [], 79 | "label": "B", 80 | }, 81 | }, 82 | ], 83 | "options": { 84 | "allowSelfLoops": true, 85 | "multi": false, 86 | "type": "mixed", 87 | }, 88 | } 89 | `; 90 | 91 | exports[`buildGraph > increases the weight for multiple edges 1`] = ` 92 | { 93 | "attributes": {}, 94 | "edges": [ 95 | { 96 | "attributes": { 97 | "weight": 2, 98 | }, 99 | "source": "1", 100 | "target": "2", 101 | }, 102 | ], 103 | "nodes": [ 104 | { 105 | "attributes": { 106 | "aliases": [], 107 | "label": "A", 108 | }, 109 | }, 110 | { 111 | "attributes": { 112 | "aliases": [], 113 | "label": "B", 114 | }, 115 | }, 116 | ], 117 | "options": { 118 | "allowSelfLoops": true, 119 | "multi": false, 120 | "type": "mixed", 121 | }, 122 | } 123 | `; 124 | 125 | exports[`buildGraph > links graphs to nested parents 1`] = ` 126 | { 127 | "attributes": {}, 128 | "edges": [ 129 | { 130 | "attributes": { 131 | "weight": 1, 132 | }, 133 | "source": "1", 134 | "target": "2", 135 | }, 136 | { 137 | "attributes": { 138 | "weight": 1, 139 | }, 140 | "source": "2", 141 | "target": "3", 142 | }, 143 | ], 144 | "nodes": [ 145 | { 146 | "attributes": { 147 | "aliases": [], 148 | "label": "A", 149 | }, 150 | }, 151 | { 152 | "attributes": { 153 | "aliases": [], 154 | "label": "B", 155 | }, 156 | }, 157 | { 158 | "attributes": { 159 | "aliases": [], 160 | "label": "C", 161 | }, 162 | }, 163 | ], 164 | "options": { 165 | "allowSelfLoops": true, 166 | "multi": false, 167 | "type": "mixed", 168 | }, 169 | } 170 | `; 171 | 172 | exports[`buildGraph > merges alias nodes 1`] = ` 173 | { 174 | "attributes": {}, 175 | "edges": [ 176 | { 177 | "attributes": { 178 | "weight": 1, 179 | }, 180 | "source": "3", 181 | "target": "1", 182 | }, 183 | ], 184 | "nodes": [ 185 | { 186 | "attributes": { 187 | "aliases": [ 188 | "B", 189 | ], 190 | "label": "A", 191 | }, 192 | }, 193 | { 194 | "attributes": { 195 | "aliases": [], 196 | "label": "C", 197 | }, 198 | }, 199 | ], 200 | "options": { 201 | "allowSelfLoops": true, 202 | "multi": false, 203 | "type": "mixed", 204 | }, 205 | } 206 | `; 207 | 208 | exports[`buildGraph > shows journal pages when requested 1`] = ` 209 | { 210 | "attributes": {}, 211 | "edges": [ 212 | { 213 | "attributes": { 214 | "weight": 1, 215 | }, 216 | "source": "1", 217 | "target": "2", 218 | }, 219 | ], 220 | "nodes": [ 221 | { 222 | "attributes": { 223 | "aliases": [], 224 | "label": "A", 225 | }, 226 | }, 227 | { 228 | "attributes": { 229 | "aliases": [], 230 | "label": "B", 231 | }, 232 | }, 233 | ], 234 | "options": { 235 | "allowSelfLoops": true, 236 | "multi": false, 237 | "type": "mixed", 238 | }, 239 | } 240 | `; 241 | 242 | exports[`buildGraph > skips pages with graph-hide: true 1`] = ` 243 | { 244 | "attributes": {}, 245 | "edges": [], 246 | "nodes": [ 247 | { 248 | "attributes": { 249 | "aliases": [], 250 | "label": "A", 251 | }, 252 | }, 253 | ], 254 | "options": { 255 | "allowSelfLoops": true, 256 | "multi": false, 257 | "type": "mixed", 258 | }, 259 | } 260 | `; 261 | 262 | exports[`buildGraph > skips references to journal pages 1`] = ` 263 | { 264 | "attributes": {}, 265 | "edges": [ 266 | { 267 | "attributes": { 268 | "weight": 1, 269 | }, 270 | "source": "1", 271 | "target": "3", 272 | }, 273 | ], 274 | "nodes": [ 275 | { 276 | "attributes": { 277 | "aliases": [], 278 | "label": "A", 279 | }, 280 | }, 281 | { 282 | "attributes": { 283 | "aliases": [], 284 | "label": "C", 285 | }, 286 | }, 287 | ], 288 | "options": { 289 | "allowSelfLoops": true, 290 | "multi": false, 291 | "type": "mixed", 292 | }, 293 | } 294 | `; 295 | -------------------------------------------------------------------------------- /src/analysis.ts: -------------------------------------------------------------------------------- 1 | /* 2 | taken from https://github.com/SkepticMystic/graph-analysis 3 | https://raw.githubusercontent.com/SkepticMystic/graph-analysis/master/LICENSE 4 | */ 5 | 6 | import type Graph from "graphology"; 7 | import type { Attributes } from "graphology-types"; 8 | import { findNode } from "./graph"; 9 | 10 | const DECIMALS = 4; 11 | 12 | function intersection(nodes1: string[], nodes2: string[]) { 13 | return nodes1?.filter((node1) => nodes2.includes(node1)) ?? []; 14 | } 15 | 16 | function roundNumber(num: number, dec: number = DECIMALS): number { 17 | return Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec); 18 | } 19 | 20 | function sum(arr: number[]) { 21 | if (arr.length === 0) { 22 | return 0; 23 | } 24 | return arr.reduce((a, b) => a + b); 25 | } 26 | 27 | export interface ResultMap { 28 | [to: string]: { measure: number; extra: string[] }; 29 | } 30 | 31 | export function adamicAdar(graph: Graph, node: string) { 32 | const results: ResultMap = {}; 33 | const Na = graph.neighbors(node); 34 | 35 | graph.forEachNode((to) => { 36 | const Nb = graph.neighbors(to); 37 | const Nab = intersection(Na, Nb); 38 | let measure = Infinity; 39 | if (Nab.length) { 40 | const neighbours: number[] = Nab.map((n) => graph.outNeighbors(n).length); 41 | measure = roundNumber( 42 | sum(neighbours.map((neighbour) => 1 / Math.log(neighbour))) 43 | ); 44 | } 45 | results[to] = { measure, extra: Nab }; 46 | }); 47 | return Object.fromEntries( 48 | Object.entries(results).filter( 49 | ([key, val]) => val.measure !== 0 && Number.isFinite(val.measure) 50 | ) 51 | ); 52 | } 53 | 54 | // Simplified version of CoCitation analysis 55 | // Original implementation and SkepticMystic Obsidian plugin look at proximity of links. 56 | // The version below just takes links pointing at same information at block level 57 | // See here for original article: https://isg.beel.org/pubs/Citation%20Proximity%20Analysis%20(CPA)%20-%20A%20new%20approach%20for%20identifying%20related%20work%20based%20on%20Co-Citation%20Analysis%20--%20preprint.pdf 58 | 59 | export const coCitation = async (graph: Graph, node: string) => { 60 | const logseqQuery = (name: string) => `[ 61 | :find ?b ?page 62 | :where 63 | [?b :block/path-refs ?link] 64 | [?link :block/name "${name}"] 65 | [?b :block/path-refs ?otherlinks] 66 | [?otherlinks :block/name ?page] 67 | ]`; 68 | const attrs = graph.getNodeAttributes(node); 69 | const queryResults = await Promise.all( 70 | [attrs.label, ...attrs.rawAliases].map((n) => 71 | logseq.DB.datascriptQuery(logseqQuery(n)) 72 | ) 73 | ); 74 | console.log(queryResults); 75 | 76 | // group links by frequency 77 | const counter: { [key: string]: number } = {}; 78 | for (const link of queryResults.flat()) { 79 | const key = findNode(graph, link[1]); 80 | if (!key) { 81 | continue; 82 | } 83 | counter[key] ? (counter[key] += 1) : (counter[key] = 1); 84 | } 85 | 86 | // get highest frequency and normalize 87 | const maxVal = Math.max(...Object.values(counter)); 88 | const results: any = {}; 89 | for (const key of Object.keys(counter)) { 90 | results[key] = { 91 | measure: roundNumber((10 * counter[key]) / maxVal), 92 | extra: ["1"], 93 | }; 94 | } 95 | return results; 96 | }; 97 | -------------------------------------------------------------------------------- /src/graph.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | BlockEntity, 3 | BlockIdentity, 4 | EntityID, 5 | } from "@logseq/libs/dist/LSPlugin"; 6 | import Graph from "graphology"; 7 | import random from "graphology-layout/random"; 8 | import { singleSourceLength } from "graphology-shortest-path"; 9 | import { toUndirected } from "graphology-operators"; 10 | import { 11 | blockToReferences, 12 | refToPageRef, 13 | Page, 14 | Block, 15 | getBlockFn, 16 | } from "./logseq"; 17 | 18 | type getAllPagesFn = () => Promise; 19 | type getBlockReferencesFn = () => Promise; 20 | type getSettingsFn = () => { journal: boolean }; 21 | 22 | export async function buildGraph( 23 | getAllPages: getAllPagesFn, 24 | getBlockReferences: getBlockReferencesFn, 25 | getSettings: getSettingsFn, 26 | getBlock: getBlockFn 27 | ): Promise { 28 | console.log("building graph"); 29 | 30 | const g = new Graph(); 31 | let pages = await getAllPages(); 32 | const aliases = pagesToAliasMap(pages); 33 | pages = removeAliases(aliases, pages); 34 | const journals = pages.filter((p) => p["journal?"]); 35 | 36 | for (const page of pages) { 37 | if (page.properties && (page.properties.graphHide || page.properties.excludeFromGraphView)) { 38 | continue; 39 | } 40 | if (g.hasNode(page.id)) { 41 | continue; 42 | } 43 | 44 | if (getSettings().journal !== true && page["journal?"]) { 45 | continue; 46 | } 47 | 48 | const icon = page.properties?.icon || page.properties?.pageIcon; 49 | 50 | g.addNode(page.id, { 51 | ...(icon 52 | ? { 53 | type: "image", 54 | image: `data:image/svg+xml,${icon}`, 55 | } 56 | : { 57 | type: "circle", 58 | }), 59 | label: page.name, 60 | aliases: pageToAliases(page, true), 61 | rawAliases: pageToAliases(page, false), 62 | }); 63 | } 64 | 65 | const results = await getBlockReferences(); 66 | await Promise.all( 67 | results.flat().map(async (block) => { 68 | if (block.refs) { 69 | for (const ref of blockToReferences( 70 | getSettings().journal === true, 71 | journals, 72 | block 73 | )) { 74 | const targetRef = await refToPageRef( 75 | getBlock, 76 | aliases, 77 | pages, 78 | ref.target 79 | ); 80 | if (targetRef && g.hasNode(ref.source) && g.hasNode(targetRef)) { 81 | if (!g.hasEdge(ref.source, targetRef)) { 82 | g.addEdge(ref.source, targetRef, { weight: 1 }); 83 | } else { 84 | g.updateDirectedEdgeAttribute( 85 | ref.source, 86 | targetRef, 87 | "weight", 88 | (weight) => weight + 1 89 | ); 90 | } 91 | } 92 | } 93 | } 94 | }) 95 | ); 96 | 97 | 98 | console.log("graph complete", g.size); 99 | if (!g.getAttribute("isInited")) { 100 | random.assign(g); 101 | g.setAttribute("isInited", true); 102 | } 103 | 104 | return g; 105 | } 106 | 107 | export function pagesToAliasMap(pages: Page[]): Map { 108 | const aliases = new Map(); 109 | for (const page of pages) { 110 | if (page.properties && page.properties.alias) { 111 | const aliasedPages = normalizeAlias(page).map((a) => 112 | pages.find((p) => p.name.toUpperCase() === a.toUpperCase()) 113 | ); 114 | for (const alias of aliasedPages) { 115 | if (alias) { 116 | aliases.set(alias.id, page.id); 117 | } 118 | } 119 | } 120 | } 121 | return aliases; 122 | } 123 | 124 | function normalizeAlias(input: Page): string[] { 125 | if (!input.properties?.alias) { 126 | return []; 127 | } 128 | if (input.properties.alias === '') { 129 | return []; 130 | } else if (typeof input.properties.alias === "string") { 131 | return [input.properties.alias]; 132 | } 133 | else { 134 | return input.properties.alias; 135 | } 136 | } 137 | 138 | export function removeAliases( 139 | aliases: Map, 140 | pages: Page[] 141 | ): Page[] { 142 | return pages.filter((p) => !aliases.has(p.id)); 143 | } 144 | 145 | export function pageToAliases(page: Page, upper: boolean): string[] { 146 | return (normalizeAlias(page)).map((a) =>{ 147 | return upper ? a.toUpperCase() : a 148 | } 149 | ); 150 | } 151 | 152 | export function findNode(graph: Graph, name?: string): string | undefined { 153 | if (!name) { 154 | return undefined; 155 | } 156 | const up = name.toUpperCase(); 157 | return graph.findNode((_node, attrs) => { 158 | return ( 159 | attrs.label.toUpperCase() === up || 160 | (attrs.aliases && attrs.aliases.includes(up)) 161 | ); 162 | }); 163 | } 164 | 165 | export function nodeNameIndex(graph: Graph): Map { 166 | const map = new Map(); 167 | for (const node of graph.nodeEntries()) { 168 | map.set(node.attributes.label.toUpperCase(), node.node); 169 | if (node.attributes.aliases) { 170 | for (const alias of node.attributes.aliases) { 171 | map.set(alias.toUpperCase(), node.node); 172 | } 173 | } 174 | } 175 | return map; 176 | } 177 | 178 | export function filter( 179 | graph: Graph, 180 | search: string 181 | ): (node: string, searchLen: number) => boolean { 182 | const undirected = toUndirected(graph); 183 | const map = new Map(); 184 | for (const node of graph.nodeEntries()) { 185 | const label = node.attributes.label.toUpperCase(); 186 | const searchUp = search.toUpperCase(); 187 | if (label.includes(searchUp)) { 188 | const len = singleSourceLength(undirected, node.node); 189 | for (const [key, val] of Object.entries(len)) { 190 | const cur = map.get(key); 191 | if (!cur || cur > val) { 192 | map.set(key, val); 193 | } 194 | } 195 | } 196 | } 197 | console.log(map); 198 | return (node, searchLen) => { 199 | const len = map.get(node); 200 | if (len === undefined) { 201 | return true; 202 | } 203 | return searchLen <= len; 204 | }; 205 | } 206 | 207 | if (import.meta.vitest) { 208 | const { it, expect, describe, vi } = import.meta.vitest; 209 | describe("buildGraph", () => { 210 | function graphToJson(graph: Graph) { 211 | const json = graph.toJSON(); 212 | json.edges.forEach((e) => { 213 | delete e.key; 214 | }); 215 | json.nodes.forEach((n: any) => { 216 | delete n.key; 217 | delete n.attributes.x; 218 | delete n.attributes.y; 219 | }); 220 | return json; 221 | } 222 | 223 | it("creates a graph with edges", async () => { 224 | const getAllPages = async () => [ 225 | { id: 1, "journal?": false, name: "A" }, 226 | { id: 2, "journal?": false, name: "B" }, 227 | ]; 228 | const getBlockReferences = async () => [ 229 | [ 230 | { 231 | refs: [{ id: 2 }], 232 | "path-refs": [{ id: 1 }, { id: 2 }], 233 | page: { id: 1 }, 234 | }, 235 | ], 236 | ]; 237 | const getSettings = () => ({ journal: false }); 238 | const getBlock = async (ref: BlockIdentity | EntityID) => null; 239 | const graph = await buildGraph( 240 | getAllPages, 241 | getBlockReferences, 242 | getSettings, 243 | getBlock 244 | ); 245 | expect(graphToJson(graph)).toMatchSnapshot(); 246 | }); 247 | 248 | it("increases the weight for multiple edges", async () => { 249 | const getAllPages = async () => [ 250 | { id: 1, "journal?": false, name: "A" }, 251 | { id: 2, "journal?": false, name: "B" }, 252 | ]; 253 | const getBlockReferences = async () => [ 254 | [ 255 | { 256 | refs: [{ id: 2 }], 257 | "path-refs": [{ id: 1 }, { id: 2 }], 258 | page: { id: 1 }, 259 | }, 260 | { 261 | refs: [{ id: 2 }], 262 | "path-refs": [{ id: 1 }, { id: 2 }], 263 | page: { id: 1 }, 264 | }, 265 | ], 266 | ]; 267 | const getSettings = () => ({ journal: false }); 268 | const getBlock = async (ref: BlockIdentity | EntityID) => null; 269 | const graph = await buildGraph( 270 | getAllPages, 271 | getBlockReferences, 272 | getSettings, 273 | getBlock 274 | ); 275 | expect(graphToJson(graph)).toMatchSnapshot(); 276 | }); 277 | 278 | it("shows journal pages when requested", async () => { 279 | const getAllPages = async () => [ 280 | { id: 1, "journal?": false, name: "A" }, 281 | { id: 2, "journal?": true, name: "B" }, 282 | ]; 283 | const getBlockReferences = async () => [ 284 | [ 285 | { 286 | refs: [{ id: 2 }], 287 | "path-refs": [{ id: 1 }, { id: 2 }], 288 | page: { id: 1 }, 289 | }, 290 | ], 291 | ]; 292 | const getSettings = () => ({ journal: true }); 293 | const getBlock = async (ref: BlockIdentity | EntityID) => null; 294 | const graph = await buildGraph( 295 | getAllPages, 296 | getBlockReferences, 297 | getSettings, 298 | getBlock 299 | ); 300 | expect(graphToJson(graph)).toMatchSnapshot(); 301 | }); 302 | 303 | it("does not shows journal pages when not requested", async () => { 304 | const getAllPages = async () => [ 305 | { id: 1, "journal?": false, name: "A" }, 306 | { id: 2, "journal?": true, name: "B" }, 307 | ]; 308 | const getBlockReferences = async () => [ 309 | [ 310 | { 311 | refs: [{ id: 2 }], 312 | "path-refs": [{ id: 1 }, { id: 2 }], 313 | page: { id: 1 }, 314 | }, 315 | ], 316 | ]; 317 | const getSettings = () => ({ journal: false }); 318 | const getBlock = async (ref: BlockIdentity | EntityID) => null; 319 | const graph = await buildGraph( 320 | getAllPages, 321 | getBlockReferences, 322 | getSettings, 323 | getBlock 324 | ); 325 | expect(graphToJson(graph)).toMatchSnapshot(); 326 | }); 327 | 328 | it("links graphs to nested parents", async () => { 329 | const getAllPages = async () => [ 330 | { id: 1, "journal?": false, name: "A" }, 331 | { id: 2, "journal?": false, name: "B" }, 332 | { id: 3, "journal?": false, name: "C" }, 333 | ]; 334 | const getBlockReferences = async () => [ 335 | [ 336 | { 337 | refs: [{ id: 2 }], 338 | "path-refs": [{ id: 1 }, { id: 2 }], 339 | page: { id: 1 }, 340 | }, 341 | { 342 | refs: [{ id: 3 }], 343 | "path-refs": [{ id: 1 }, { id: 2 }, { id: 3 }], 344 | page: { id: 1 }, 345 | }, 346 | ], 347 | ]; 348 | const getSettings = () => ({ journal: false }); 349 | const getBlock = async (ref: BlockIdentity | EntityID) => null; 350 | const graph = await buildGraph( 351 | getAllPages, 352 | getBlockReferences, 353 | getSettings, 354 | getBlock 355 | ); 356 | expect(graphToJson(graph)).toMatchSnapshot(); 357 | }); 358 | 359 | it("handles block references", async () => { 360 | const getAllPages = async () => [ 361 | { id: 1, "journal?": false, name: "A" }, 362 | { id: 2, "journal?": false, name: "B" }, 363 | ]; 364 | const getBlockReferences = async () => [ 365 | [ 366 | { 367 | refs: [{ id: 3 }], 368 | "path-refs": [{ id: 1 }, { id: 3 }], 369 | page: { id: 1 }, 370 | }, 371 | ], 372 | ]; 373 | const getSettings = () => ({ journal: false }); 374 | const getBlock = vi 375 | .fn() 376 | .mockImplementationOnce(() => ({ page: { id: 2 } } as BlockEntity)); 377 | const graph = await buildGraph( 378 | getAllPages, 379 | getBlockReferences, 380 | getSettings, 381 | getBlock 382 | ); 383 | expect(getBlock).toBeCalledWith(3); 384 | expect(graphToJson(graph)).toMatchSnapshot(); 385 | }); 386 | 387 | it("skips references to journal pages", async () => { 388 | const getAllPages = async () => [ 389 | { id: 1, "journal?": false, name: "A" }, 390 | { id: 2, "journal?": true, name: "B" }, 391 | { id: 3, "journal?": false, name: "C" }, 392 | ]; 393 | const getBlockReferences = async () => [ 394 | [ 395 | { 396 | refs: [{ id: 2 }], 397 | "path-refs": [{ id: 1 }, { id: 2 }], 398 | page: { id: 1 }, 399 | }, 400 | { 401 | refs: [{ id: 3 }], 402 | "path-refs": [{ id: 1 }, { id: 2 }, { id: 3 }], 403 | page: { id: 1 }, 404 | }, 405 | ], 406 | ]; 407 | const getSettings = () => ({ journal: false }); 408 | const getBlock = async (ref: BlockIdentity | EntityID) => null; 409 | const graph = await buildGraph( 410 | getAllPages, 411 | getBlockReferences, 412 | getSettings, 413 | getBlock 414 | ); 415 | expect(graphToJson(graph)).toMatchSnapshot(); 416 | }); 417 | 418 | it("skips pages with graph-hide: true", async () => { 419 | const getAllPages = async () => [ 420 | { id: 1, "journal?": false, name: "A" }, 421 | { 422 | id: 2, 423 | "journal?": false, 424 | name: "B", 425 | properties: { graphHide: true }, 426 | }, 427 | ]; 428 | const getBlockReferences = async () => [ 429 | [ 430 | { 431 | refs: [{ id: 2 }], 432 | "path-refs": [{ id: 1 }, { id: 2 }], 433 | page: { id: 1 }, 434 | }, 435 | ], 436 | ]; 437 | const getSettings = () => ({ journal: false }); 438 | const getBlock = async (ref: BlockIdentity | EntityID) => null; 439 | const graph = await buildGraph( 440 | getAllPages, 441 | getBlockReferences, 442 | getSettings, 443 | getBlock 444 | ); 445 | expect(graphToJson(graph)).toMatchSnapshot(); 446 | }); 447 | 448 | it("skips pages with exclude-from-graph-view: true", async () => { 449 | const getAllPages = async () => [ 450 | { id: 1, "journal?": false, name: "A" }, 451 | { 452 | id: 2, 453 | "journal?": false, 454 | name: "B", 455 | properties: { excludeFromGraphView: true }, 456 | }, 457 | ]; 458 | const getBlockReferences = async () => [ 459 | [ 460 | { 461 | refs: [{ id: 2 }], 462 | "path-refs": [{ id: 1 }, { id: 2 }], 463 | page: { id: 1 }, 464 | }, 465 | ], 466 | ]; 467 | const getSettings = () => ({ journal: false }); 468 | const getBlock = async (ref: BlockIdentity | EntityID) => null; 469 | const graph = await buildGraph( 470 | getAllPages, 471 | getBlockReferences, 472 | getSettings, 473 | getBlock 474 | ); 475 | expect(graphToJson(graph)).toMatchSnapshot(); 476 | }); 477 | 478 | it("merges alias nodes", async () => { 479 | const getAllPages = async () => [ 480 | { id: 1, "journal?": false, name: "A", properties: { alias: ["B"] } }, 481 | { id: 2, "journal?": false, name: "B" }, 482 | { id: 3, "journal?": false, name: "C" }, 483 | ]; 484 | const getBlockReferences = async () => [ 485 | [ 486 | { 487 | refs: [{ id: 2 }], 488 | "path-refs": [{ id: 3 }, { id: 2 }], 489 | page: { id: 3 }, 490 | }, 491 | ], 492 | ]; 493 | const getSettings = () => ({ journal: false }); 494 | const getBlock = async (ref: BlockIdentity | EntityID) => null; 495 | const graph = await buildGraph( 496 | getAllPages, 497 | getBlockReferences, 498 | getSettings, 499 | getBlock 500 | ); 501 | expect(graphToJson(graph)).toMatchSnapshot(); 502 | }); 503 | it("alias nodes empty cases shoud not fail", async () => { 504 | const getAllPages = async () => [ 505 | { id: 1, "journal?": false, name: "A", properties: { alias: "" } }, 506 | { id: 2, "journal?": false, name: "B", properties: { alias: ["test"] } }, 507 | { id: 3, "journal?": false, name: "C" }, 508 | ]; 509 | const getBlockReferences = async () => [ 510 | [], 511 | ]; 512 | const getSettings = () => ({ journal: false }); 513 | const getBlock = async (ref: BlockIdentity | EntityID) => null; 514 | const graph = await buildGraph( 515 | getAllPages, 516 | getBlockReferences, 517 | getSettings, 518 | getBlock 519 | ); 520 | expect(graphToJson(graph)).toMatchSnapshot(); 521 | }); 522 | 523 | it("links shared references in a block", async () => { 524 | const getAllPages = async () => [ 525 | { id: 1, "journal?": false, name: "A" }, 526 | { id: 2, "journal?": false, name: "B" }, 527 | { id: 3, "journal?": false, name: "C" }, 528 | ]; 529 | const getBlockReferences = async () => [ 530 | [ 531 | { 532 | refs: [{ id: 2 }, { id: 3 }], 533 | "path-refs": [{ id: 1 }, { id: 2 }, { id: 3 }], 534 | page: { id: 1 }, 535 | }, 536 | ], 537 | ]; 538 | const getSettings = () => ({ journal: false }); 539 | const getBlock = async (ref: BlockIdentity | EntityID) => null; 540 | const graph = await buildGraph( 541 | getAllPages, 542 | getBlockReferences, 543 | getSettings, 544 | getBlock 545 | ); 546 | expect(graphToJson(graph)).toMatchSnapshot(); 547 | }); 548 | }); 549 | } 550 | 551 | -------------------------------------------------------------------------------- /src/logseq.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | BlockEntity, 3 | BlockIdentity, 4 | EntityID, 5 | } from "@logseq/libs/dist/LSPlugin"; 6 | 7 | export interface Page { 8 | id: number; 9 | "journal?": boolean; 10 | name: string; 11 | properties?: { 12 | graphHide?: boolean; 13 | excludeFromGraphView?: boolean; 14 | alias?: string[] | string; 15 | icon?: string; 16 | pageIcon?: string; 17 | }; 18 | } 19 | 20 | export interface Block { 21 | refs: { id: number }[]; 22 | "path-refs"?: { id: number }[]; 23 | page: { id: number }; 24 | } 25 | 26 | export interface Reference { 27 | source: number; 28 | target: number; 29 | } 30 | 31 | export type getBlockFn = ( 32 | srcBlock: BlockIdentity | EntityID, 33 | opts?: Partial<{ 34 | includeChildren: boolean; 35 | }> 36 | ) => Promise; 37 | 38 | export function blockToReferences( 39 | journalsEnabled: boolean, 40 | journals: Page[], 41 | block: Block 42 | ): Reference[] { 43 | const targets = block.refs; 44 | const targetIds = targets.map((p) => p.id); 45 | let pathsWithoutTargets = [] as { id: number }[]; 46 | for (const ref of block["path-refs"] ?? []) { 47 | const targetIsJournal = !!journals.find((j) => j.id === ref.id); 48 | if (!journalsEnabled && targetIsJournal) { 49 | continue; 50 | } 51 | if (ref.id === block.page.id) { 52 | continue; 53 | } 54 | if (targetIds.includes(ref.id)) { 55 | continue; 56 | } 57 | pathsWithoutTargets.push(ref); 58 | } 59 | 60 | let source = block.page; 61 | if (pathsWithoutTargets.length > 0) { 62 | source = pathsWithoutTargets[pathsWithoutTargets.length - 1]; 63 | } else { 64 | source = block.page; 65 | } 66 | const refs = targets.map((target) => ({ 67 | source: source.id, 68 | target: target.id, 69 | })); 70 | const sharedRefs = targets.flatMap((source, i) => 71 | [...targets.slice(0, i), ...targets.slice(i + 1)].map((target) => ({ 72 | source: source.id, 73 | target: target.id, 74 | undirected: true, 75 | })) 76 | ); 77 | return refs.concat(sharedRefs); 78 | } 79 | 80 | export async function refToPageRef( 81 | getBlock: getBlockFn, 82 | aliases: Map, 83 | pages: { id: number }[], 84 | ref: number 85 | ): Promise { 86 | if (pages.find((p) => p.id === ref)) { 87 | return ref; 88 | } 89 | if (aliases.has(ref)) { 90 | return aliases.get(ref); 91 | } 92 | const block = await getBlock(ref); 93 | if (block && block.page) { 94 | const id = block.page.id; 95 | if (aliases.has(id)) { 96 | return aliases.get(id); 97 | } else { 98 | return id; 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import "@logseq/libs"; 2 | import "uno.css"; 3 | import "@unocss/reset/normalize.css"; 4 | import App from "./App.svelte"; 5 | import type * as CSS from "csstype"; 6 | import type { SettingSchemaDesc } from "@logseq/libs/dist/LSPlugin.user"; 7 | import {setThemeColors} from "./settings/themes"; 8 | 9 | 10 | const settingsSchema: SettingSchemaDesc[] = [ 11 | { 12 | key: "journal", 13 | type: "boolean", 14 | title: "Show journal pages on graph", 15 | description: "Do you want to show journal pages on your graph?", 16 | default: false, 17 | }, 18 | { 19 | key: "filters", 20 | type: "object", 21 | title: "Graph settings and filters", 22 | description: "Graph settings and filters", 23 | default: [] 24 | }, 25 | ]; 26 | 27 | function createModel() { 28 | return { 29 | async openGraph() { 30 | logseq.showMainUI({ 31 | autoFocus: true, 32 | }); 33 | }, 34 | }; 35 | } 36 | 37 | async function main() { 38 | const app = new App({ 39 | target: document.getElementById("app") as Element, 40 | }); 41 | 42 | 43 | setThemeColors(); 44 | 45 | const baseStyles: CSS.Properties = { 46 | position: "fixed", 47 | zIndex: 12, 48 | height: "calc(100vh - 8px)", 49 | top: "8px", 50 | background: "var(--ls-primary-background-color)", 51 | color: "var(--ls-primary-text-color)", 52 | }; 53 | 54 | logseq.setMainUIInlineStyle(baseStyles); 55 | 56 | logseq.App.registerUIItem("toolbar", { 57 | key: "logseq-graph-analysis", 58 | template: ` 59 | 60 | 61 | 62 | 63 | `, 64 | }); 65 | } 66 | 67 | logseq.useSettingsSchema(settingsSchema); 68 | logseq.ready(createModel(), main).catch(() => console.error); 69 | -------------------------------------------------------------------------------- /src/settings/Settings.svelte: -------------------------------------------------------------------------------- 1 | 42 | 43 |
44 |
45 | 48 |
49 | 50 | 51 |
52 | {#if $settings.filter} 53 |
54 | 55 | 62 |
63 | {/if} 64 |
65 |
66 |

Mode

67 |
68 | 73 |
74 | {#if $settings.mode === Mode.ShortestPath} 75 |
76 | 77 | 78 |
79 |
80 | 81 | 82 |
83 |
84 | 85 | 86 |
87 | {/if} 88 | {#if $settings.mode === Mode.AdamicAdar || $settings.mode === Mode.CoCitation} 89 |
90 | 91 | 92 |
93 |
94 | 95 | 102 |
103 | {/if} 104 |
105 |
106 |
107 |
108 |

Filters

109 | 110 |
111 | {#each $settings.filters as { id, searchString, searchType, searchColor, foundNodeIds } (id)} 112 |
113 | removeFilter(id)} 121 | /> 122 | 123 |
124 | {:else} 125 |

Hit plus button to add filters

126 | {/each} 127 |
128 |
129 |
130 |

Display

131 |
132 | 133 | 140 |
141 |
142 | 143 | 150 |
151 |
152 | 153 | 160 |
161 |
162 | 163 | 170 |
171 | {#if $settings.filter} 172 |
173 | 174 | 181 |
182 | {/if} 183 |
184 | 185 | 189 |
190 |
191 |
192 | 193 | 301 | -------------------------------------------------------------------------------- /src/settings/components/NodeFilter.svelte: -------------------------------------------------------------------------------- 1 | 47 | 48 |
49 |
50 | 55 |
56 | {#if !filterSearchResults} 57 | 58 | {/if} 59 |
60 | 61 | 122 | -------------------------------------------------------------------------------- /src/settings/helpers/search.ts: -------------------------------------------------------------------------------- 1 | import type Graph from "graphology"; 2 | import type { Attributes } from "graphology-types"; 3 | 4 | export async function findNodes(query: string | undefined, graph: Graph) { 5 | let foundNodeIds: string[] = [] 6 | if (query === undefined || query === "") { 7 | return foundNodeIds 8 | } 9 | if (query.startsWith("q:")) { 10 | try { 11 | const res = await logseq.DB.q(query.slice(2).toLowerCase()); 12 | if (res) { 13 | foundNodeIds = res.map((r) => r.page.id.toString()); 14 | } 15 | } catch { 16 | console.log("error in query"); 17 | } 18 | } else { 19 | foundNodeIds = graph.filterNodes( 20 | (node: string, data: Attributes) => 21 | data.label?.match(query) || 22 | data["aliases"]?.find((a: string) => 23 | a.toUpperCase().match(query.toUpperCase()) 24 | ) 25 | ); 26 | } 27 | return foundNodeIds; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/settings/themes.ts: -------------------------------------------------------------------------------- 1 | interface Theme { 2 | // Background color and text color inherited from Logseq 3 | mode: "dark" | "light"; 4 | nodeColor: string; 5 | edgeColor: string; 6 | nodeLabelColor: string; 7 | nodeLabelBackground: string; 8 | nodeLabelShadowColor: string; 9 | } 10 | 11 | const lightTheme: Theme = { 12 | mode: "light", 13 | nodeColor: "#5c5c5c", 14 | edgeColor: "#e5e5e5", 15 | nodeLabelColor: "#000000", 16 | nodeLabelBackground: "#ffffff", 17 | nodeLabelShadowColor: "rgb(0, 0, 0)", 18 | }; 19 | 20 | const darkTheme: Theme = { 21 | mode: "dark", 22 | nodeColor: "#aaaaaa", 23 | edgeColor: "#444444", 24 | nodeLabelColor: "#ffffff", 25 | nodeLabelBackground: "rgb(0, 0, 0, 0.7)", 26 | nodeLabelShadowColor: "#ffffff", 27 | }; 28 | 29 | export const setThemeColors = () => { 30 | const root = parent.document.querySelector("#root"); 31 | if (root) { 32 | const rootStyles = getComputedStyle(root); 33 | document.body.style.setProperty("--theme-background", rootStyles.getPropertyValue("--ls-primary-background-color") || "#ffffff"); 34 | document.body.style.setProperty("--theme-color", rootStyles.getPropertyValue("--ls-primary-text-color") || "#000000"); 35 | document.body.style.setProperty("--theme-accent-color", rootStyles.getPropertyValue("--ls-primary-accent-color") || "#000000"); 36 | document.body.style.setProperty("--theme-secondary-background", rootStyles.getPropertyValue("--ls-secondary-background-color") || "#000000"); 37 | document.body.style.setProperty("--theme-border-color", rootStyles.getPropertyValue("--ls-border-color") || "#000000"); 38 | } 39 | }; 40 | export function getTheme(mode: "light" | "dark"): Theme { 41 | if (mode === "light") { 42 | return lightTheme; 43 | } else { 44 | return darkTheme; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/shortestPath.ts: -------------------------------------------------------------------------------- 1 | import Graph from "graphology"; 2 | import { toUndirected } from "graphology-operators"; 3 | import { dijkstra, edgePathFromNodePath } from "graphology-shortest-path"; 4 | import { findNode } from "./graph"; 5 | 6 | export function shortestPathDirected( 7 | graph: Graph, 8 | pathAStr: string, 9 | pathBStr: string 10 | ) { 11 | const pathA = findNode(graph, pathAStr); 12 | const pathB = findNode(graph, pathBStr); 13 | if (!pathA || !pathB) { 14 | return { nodes: undefined, edges: undefined } as const; 15 | } 16 | 17 | const nodes = 18 | dijkstra.bidirectional(graph, pathA, pathB) || 19 | dijkstra.bidirectional(graph, pathB, pathA); 20 | if (nodes) { 21 | const edges = edgePathFromNodePath(graph, nodes); 22 | return { nodes, edges } as const; 23 | } else { 24 | return { nodes: undefined, edges: undefined } as const; 25 | } 26 | } 27 | 28 | export function shortestPathUndirected( 29 | graph: Graph, 30 | pathAStr: string, 31 | pathBStr: string 32 | ) { 33 | const pathA = findNode(graph, pathAStr); 34 | const pathB = findNode(graph, pathBStr); 35 | if (!pathA || !pathB) { 36 | return { nodes: undefined, edges: undefined } as const; 37 | } 38 | 39 | const undirected = toUndirected(graph); 40 | 41 | const nodes = dijkstra.bidirectional(undirected, pathA, pathB); 42 | if (nodes) { 43 | const edges = [] as string[]; 44 | for (let i = 0; i < nodes.length - 1; i++) { 45 | const directedEdges = graph 46 | .directedEdges(nodes[i], nodes[i + 1]) 47 | .concat(graph.directedEdges(nodes[i], nodes[i + 1])); 48 | if (directedEdges.length) { 49 | edges.push(directedEdges[0]); 50 | } 51 | } 52 | return { nodes, edges } as const; 53 | } else { 54 | return { nodes: undefined, edges: undefined } as const; 55 | } 56 | } 57 | 58 | export function shortestPathEdgePredicate( 59 | edges: string[] | undefined | null, 60 | edge: string 61 | ) { 62 | return edges?.includes(edge); 63 | } 64 | 65 | if (import.meta.vitest) { 66 | const { it, expect, describe } = import.meta.vitest; 67 | 68 | describe("shortestPathDirected", () => { 69 | it("returns directed paths", () => { 70 | const graph = new Graph(); 71 | graph.addNode("A", { label: "A" }); 72 | graph.addNode("B", { label: "B" }); 73 | graph.addNode("C", { label: "C" }); 74 | graph.addEdge("A", "B"); 75 | graph.addEdge("B", "C"); 76 | const { nodes, edges } = shortestPathDirected(graph, "A", "C"); 77 | expect(nodes).toMatchObject(["A", "B", "C"]); 78 | expect(edges).toMatchObject([graph.edge("A", "B"), graph.edge("B", "C")]); 79 | }); 80 | 81 | it("returns directed paths even if backwards", () => { 82 | const graph = new Graph(); 83 | graph.addNode("A", { label: "A" }); 84 | graph.addNode("B", { label: "B" }); 85 | graph.addNode("C", { label: "C" }); 86 | graph.addEdge("A", "B"); 87 | graph.addEdge("B", "C"); 88 | const { nodes, edges } = shortestPathDirected(graph, "C", "A"); 89 | expect(nodes).toMatchObject(["A", "B", "C"]); 90 | expect(edges).toMatchObject([graph.edge("A", "B"), graph.edge("B", "C")]); 91 | }); 92 | 93 | it("will not return undirected paths", () => { 94 | const graph = new Graph(); 95 | graph.addNode("A", { label: "A" }); 96 | graph.addNode("B", { label: "B" }); 97 | graph.addNode("C", { label: "C" }); 98 | graph.addEdge("A", "B"); 99 | graph.addEdge("C", "B"); 100 | const { nodes, edges } = shortestPathDirected(graph, "C", "A"); 101 | expect(nodes).toBeUndefined(); 102 | expect(edges).toBeUndefined(); 103 | }); 104 | 105 | it("will not return disconnected paths", () => { 106 | const graph = new Graph(); 107 | graph.addNode("A", { label: "A" }); 108 | graph.addNode("B", { label: "B" }); 109 | graph.addNode("C", { label: "C" }); 110 | graph.addEdge("A", "B"); 111 | const { nodes, edges } = shortestPathDirected(graph, "A", "C"); 112 | expect(nodes).toBeUndefined(); 113 | expect(edges).toBeUndefined(); 114 | }); 115 | }); 116 | 117 | describe("shortestPathUndirected", () => { 118 | it("will return undirected paths", () => { 119 | const graph = new Graph(); 120 | graph.addNode("A", { label: "A" }); 121 | graph.addNode("B", { label: "B" }); 122 | graph.addNode("C", { label: "C" }); 123 | graph.addEdge("A", "B"); 124 | graph.addEdge("C", "B"); 125 | const { nodes, edges } = shortestPathUndirected(graph, "A", "C"); 126 | expect(nodes).toMatchObject(["A", "B", "C"]); 127 | expect(edges).toMatchObject([graph.edge("A", "B"), graph.edge("C", "B")]); 128 | }); 129 | 130 | it("will not return disconnected paths", () => { 131 | const graph = new Graph(); 132 | graph.addNode("A", { label: "A" }); 133 | graph.addNode("B", { label: "B" }); 134 | graph.addNode("C", { label: "C" }); 135 | graph.addEdge("A", "B"); 136 | const { nodes, edges } = shortestPathUndirected(graph, "A", "C"); 137 | expect(nodes).toBeUndefined(); 138 | expect(edges).toBeUndefined(); 139 | }); 140 | 141 | it("returns paths that involve aliases", () => { 142 | const graph = new Graph(); 143 | graph.addNode("A", { label: "A", aliases: ["B"] }); 144 | graph.addNode("C", { label: "C" }); 145 | graph.addEdge("C", "A"); 146 | const { nodes, edges } = shortestPathDirected(graph, "B", "C"); 147 | expect(nodes).toMatchObject(["C", "A"]); 148 | expect(edges).toMatchObject([graph.edge("C", "A")]); 149 | }); 150 | }); 151 | } 152 | -------------------------------------------------------------------------------- /src/sigma/drawHover.ts: -------------------------------------------------------------------------------- 1 | import type { NodeDisplayData, PartialButFor } from "sigma/types"; 2 | import drawLabel from "sigma/rendering/canvas/label"; 3 | import type { ExtendedSettings } from "./sigma/sigma"; 4 | 5 | /** 6 | * Draw an hovered node. 7 | * - if there is no label => display a shadow on the node 8 | * - if the label box is bigger than node size => display a label box that contains the node with a shadow 9 | * - else node with shadow and the label box 10 | */ 11 | export default function drawHover( 12 | context: CanvasRenderingContext2D, 13 | data: PartialButFor, 14 | settings: ExtendedSettings, 15 | ): void { 16 | const size = settings.labelSize, 17 | font = settings.labelFont, 18 | weight = settings.labelWeight; 19 | 20 | context.font = `${weight} ${size}px ${font}`; 21 | 22 | // Then we draw the label background 23 | context.fillStyle = settings.labelBackgroundColor || "#FFF"; 24 | context.shadowOffsetX = 0; 25 | context.shadowOffsetY = 0; 26 | context.shadowBlur = 8; 27 | context.shadowColor = settings.labelShadowColor || "#000"; 28 | 29 | const PADDING = 2; 30 | 31 | if (typeof data.label === "string") { 32 | const textWidth = context.measureText(data.label).width, 33 | boxWidth = Math.round(textWidth + 5), 34 | boxHeight = Math.round(size + 2 * PADDING), 35 | radius = Math.max(data.size, size / 2) + PADDING; 36 | 37 | const angleRadian = Math.asin(boxHeight / 2 / radius); 38 | const xDeltaCoord = Math.sqrt(Math.abs(Math.pow(radius, 2) - Math.pow(boxHeight / 2, 2))); 39 | 40 | context.beginPath(); 41 | context.moveTo(data.x + xDeltaCoord, data.y + boxHeight / 2); 42 | context.lineTo(data.x + radius + boxWidth, data.y + boxHeight / 2); 43 | context.lineTo(data.x + radius + boxWidth, data.y - boxHeight / 2); 44 | context.lineTo(data.x + xDeltaCoord, data.y - boxHeight / 2); 45 | context.arc(data.x, data.y, radius, angleRadian, -angleRadian); 46 | context.closePath(); 47 | context.fill(); 48 | } else { 49 | context.beginPath(); 50 | context.arc(data.x, data.y, data.size + PADDING, 0, Math.PI * 2); 51 | context.closePath(); 52 | context.fill(); 53 | } 54 | 55 | context.shadowOffsetX = 0; 56 | context.shadowOffsetY = 0; 57 | context.shadowBlur = 0; 58 | 59 | // And finally we draw the label 60 | drawLabel(context, data, settings); 61 | } 62 | 63 | -------------------------------------------------------------------------------- /src/sigma/sigma.d.ts: -------------------------------------------------------------------------------- 1 | import Sigma from "sigma"; 2 | import type { Settings } from "sigma/settings"; 3 | import type Graph from "graphology"; 4 | 5 | 6 | /** 7 | * `ExtendedSettings` interface extends the base `Settings` interface 8 | * to include an additional parameters for rendering 9 | */ 10 | export interface ExtendedSettings extends Settings { 11 | 12 | /** 13 | * Specifies the background color of labels. 14 | * Accepts hex color string. 15 | */ 16 | labelBackgroundColor: string; 17 | labelShadowColor: string; 18 | } 19 | 20 | /** 21 | * `ExtendedSigma` class extends the base `Sigma` class 22 | * to include an additional parameters for rendering 23 | */ 24 | export class ExtendedSigma extends Sigma { 25 | /** 26 | * @param settings - An optional `ExtendedSettings` object that includes 27 | * both the base `Settings` fields and the `labelBackgroundColor`. 28 | */ 29 | 30 | constructor(graph: Graph, container: HTMLElement, settings?: Partial) 31 | setSetting(key: K, value: ExtendedSettings[K]): this; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/sigma/sigma.js: -------------------------------------------------------------------------------- 1 | import Sigma from "sigma"; 2 | 3 | export class ExtendedSigma extends Sigma { 4 | constructor(graph, container, settings) { 5 | super(graph, container, settings); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/stores.ts: -------------------------------------------------------------------------------- 1 | import { derived, Writable, writable } from "svelte/store"; 2 | import { buildGraph } from "./graph"; 3 | import Graph from "graphology"; 4 | import type { Camera } from "sigma"; 5 | 6 | type SettingsSize = "in" | "out"; 7 | export enum Mode { 8 | Navigate = "Navigate", 9 | ShortestPath = "Shortest Path", 10 | AdamicAdar = "Adamic Adar", 11 | CoCitation = "CoCitation", 12 | } 13 | 14 | export type NodeFilter = { 15 | id: number, 16 | searchString: string, 17 | searchType: string, 18 | searchColor: string 19 | foundNodeIds: String[] 20 | } 21 | 22 | interface Settings { 23 | size: SettingsSize; 24 | search?: string; 25 | pathA?: string; 26 | pathB?: string; 27 | mode: Mode; 28 | directed: boolean; 29 | bubbleSize: number; 30 | filter: boolean; 31 | filterLength: number; 32 | cameraState?: ReturnType; 33 | labelThreshold: number; 34 | nodesGravity: number; 35 | scalingRatio: number; 36 | edgeWeightInfluence: number; 37 | filters: NodeFilter[]; 38 | themeMode: "dark" | "light"; 39 | } 40 | 41 | interface Store { 42 | uiVisibile: boolean; 43 | graph: Graph; 44 | } 45 | 46 | function createStore() { 47 | const { subscribe, update } = writable({ 48 | uiVisibile: false, 49 | graph: new Graph(), 50 | }); 51 | 52 | return { 53 | subscribe, 54 | update, 55 | visible: (visible: boolean) => { 56 | update((cur) => ({ 57 | ...cur, 58 | uiVisibile: visible, 59 | })); 60 | }, 61 | reload: () => { 62 | settings.update((settings) => { 63 | settings.cameraState = undefined; 64 | return settings; 65 | }); 66 | buildGraph( 67 | () => logseq.Editor.getAllPages(), 68 | () => 69 | logseq.DB.datascriptQuery( 70 | `[:find (pull ?b [*]) :in $ :where [?b :block/refs]]` 71 | ), 72 | () => ({ journal: logseq.settings?.journal === true }), 73 | (ref) => logseq.Editor.getBlock(ref) 74 | ).then((graph) => { 75 | update((cur) => ({ 76 | ...cur, 77 | graph, 78 | })); 79 | }); 80 | }, 81 | }; 82 | } 83 | 84 | export const store = createStore(); 85 | export const uiVisible = derived(store, (store) => store.uiVisibile); 86 | export const graph = derived(store, (store) => store.graph); 87 | 88 | export const settings: Writable = writable({ 89 | size: "in", 90 | mode: Mode.Navigate, 91 | directed: true, 92 | bubbleSize: 5, 93 | filter: false, 94 | filterLength: 3, 95 | labelThreshold: 100, 96 | nodesGravity: 1, 97 | scalingRatio: 1, 98 | edgeWeightInfluence: 0.5, 99 | filters: logseq.settings?.filters || [], 100 | themeMode: "dark", 101 | }); 102 | -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /svelte.config.js: -------------------------------------------------------------------------------- 1 | import sveltePreprocess from 'svelte-preprocess' 2 | 3 | export default { 4 | // Consult https://github.com/sveltejs/svelte-preprocess 5 | // for more information about preprocessors 6 | preprocess: sveltePreprocess() 7 | } 8 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/svelte/tsconfig.json", 3 | "compilerOptions": { 4 | "target": "ESNext", 5 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 6 | "baseUrl": "./src", 7 | "rootDir": "./src", 8 | "paths": { 9 | "@/": ["./src"] 10 | }, 11 | "allowJs": false, 12 | "skipLibCheck": true, 13 | "esModuleInterop": false, 14 | "strict": true, 15 | "forceConsistentCasingInFileNames": true, 16 | "module": "ESNext", 17 | "moduleResolution": "Node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react", 22 | "types": ["vite/client", "vitest/importMeta"] 23 | }, 24 | "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"] 25 | } 26 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vitest/config"; 2 | import { svelte } from "@sveltejs/vite-plugin-svelte"; 3 | import logseqPlugin from "vite-plugin-logseq"; 4 | import Unocss from "unocss/vite"; 5 | import presetWind from "@unocss/preset-wind"; 6 | import presetIcons from "@unocss/preset-icons"; 7 | import path from "path"; 8 | 9 | // https://vitejs.dev/config/ 10 | export default defineConfig({ 11 | plugins: [ 12 | svelte(), 13 | // @ts-ignore 14 | logseqPlugin.default(), 15 | Unocss({ 16 | presets: [presetIcons(), presetWind()], 17 | }), 18 | ], 19 | resolve: { 20 | alias: [ 21 | { 22 | find: '@', replacement: path.resolve(__dirname, '/src') 23 | } 24 | ] 25 | }, 26 | test: { 27 | includeSource: ["src/**/*.{ts,tsx}"], 28 | coverage: { 29 | reporter: ["text", "html"], 30 | }, 31 | }, 32 | }); 33 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@antfu/install-pkg@^0.1.0": 6 | version "0.1.0" 7 | resolved "https://registry.yarnpkg.com/@antfu/install-pkg/-/install-pkg-0.1.0.tgz#8d8c61820cbc32e5c37d82d515485ad3ee9bd052" 8 | integrity sha512-VaIJd3d1o7irZfK1U0nvBsHMyjkuyMP3HKYVV53z8DKyulkHKmjhhtccXO51WSPeeSHIeoJEoNOKavYpS7jkZw== 9 | dependencies: 10 | execa "^5.1.1" 11 | find-up "^5.0.0" 12 | 13 | "@antfu/utils@^0.5.0", "@antfu/utils@^0.5.1": 14 | version "0.5.2" 15 | resolved "https://registry.yarnpkg.com/@antfu/utils/-/utils-0.5.2.tgz#8c2d931ff927be0ebe740169874a3d4004ab414b" 16 | integrity sha512-CQkeV+oJxUazwjlHD0/3ZD08QWKuGQkhnrKo3e6ly5pd48VUpXbb77q0xMU4+vc2CkJnDS02Eq/M9ugyX20XZA== 17 | 18 | "@bcoe/v8-coverage@^0.2.3": 19 | version "0.2.3" 20 | resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" 21 | integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== 22 | 23 | "@iconify-json/mdi@^1.1.24": 24 | version "1.1.24" 25 | resolved "https://registry.yarnpkg.com/@iconify-json/mdi/-/mdi-1.1.24.tgz#635348c97622accf55283d6f95f4608ccac9f754" 26 | integrity sha512-pWz37BD5NmuNlWe5g7bnL5JhlDsbAzhm60H1XBlQWeuxT3ksfTdka99lLOl7RgWzfv54ff44BDuRT0bt2RhlVg== 27 | dependencies: 28 | "@iconify/types" "*" 29 | 30 | "@iconify/types@*", "@iconify/types@^1.1.0": 31 | version "1.1.0" 32 | resolved "https://registry.yarnpkg.com/@iconify/types/-/types-1.1.0.tgz#dc15fc988b1b3fd558dd140a24ede7e0aac11280" 33 | integrity sha512-Jh0llaK2LRXQoYsorIH8maClebsnzTcve+7U3rQUSnC11X4jtPnFuyatqFLvMxZ8MLG8dB4zfHsbPfuvxluONw== 34 | 35 | "@iconify/utils@^1.0.33": 36 | version "1.0.33" 37 | resolved "https://registry.yarnpkg.com/@iconify/utils/-/utils-1.0.33.tgz#9952ecae79e3b1685b83c58159c1d48959f6105a" 38 | integrity sha512-vGeAqo7aGPxOQmGdVoXFUOuyN+0V7Lcrx2EvaiRjxUD1x6Om0Tvq2bdm7E24l2Pz++4S0mWMCVFXe/17EtKImQ== 39 | dependencies: 40 | "@antfu/install-pkg" "^0.1.0" 41 | "@antfu/utils" "^0.5.0" 42 | "@iconify/types" "^1.1.0" 43 | debug "^4.3.4" 44 | kolorist "^1.5.1" 45 | local-pkg "^0.4.1" 46 | 47 | "@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": 48 | version "0.1.3" 49 | resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" 50 | integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== 51 | 52 | "@jridgewell/resolve-uri@^3.0.3": 53 | version "3.0.7" 54 | resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz#30cd49820a962aff48c8fffc5cd760151fca61fe" 55 | integrity sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA== 56 | 57 | "@jridgewell/sourcemap-codec@^1.4.10": 58 | version "1.4.13" 59 | resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz#b6461fb0c2964356c469e115f504c95ad97ab88c" 60 | integrity sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w== 61 | 62 | "@jridgewell/trace-mapping@^0.3.12": 63 | version "0.3.14" 64 | resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" 65 | integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== 66 | dependencies: 67 | "@jridgewell/resolve-uri" "^3.0.3" 68 | "@jridgewell/sourcemap-codec" "^1.4.10" 69 | 70 | "@jridgewell/trace-mapping@^0.3.9": 71 | version "0.3.13" 72 | resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz#dcfe3e95f224c8fe97a87a5235defec999aa92ea" 73 | integrity sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w== 74 | dependencies: 75 | "@jridgewell/resolve-uri" "^3.0.3" 76 | "@jridgewell/sourcemap-codec" "^1.4.10" 77 | 78 | "@logseq/libs@^0.0.15": 79 | version "0.0.15" 80 | resolved "https://registry.npmjs.org/@logseq/libs/-/libs-0.0.15.tgz#03b8b81a0a1557e3f022d68c978ddcb501cd4421" 81 | integrity sha512-Z4YrYGfu8Y3s9LTqVnPGkxlO+KZtP1YalH/A63zYgxP61cV5QtKlnHWNcjsKxsD5CkaSL4MlSN4mf7wNx/Fm0A== 82 | dependencies: 83 | csstype "3.1.0" 84 | debug "4.3.4" 85 | dompurify "2.3.8" 86 | eventemitter3 "4.0.7" 87 | fast-deep-equal "3.1.3" 88 | lodash-es "4.17.21" 89 | path "0.12.7" 90 | snake-case "3.0.4" 91 | 92 | "@nodelib/fs.scandir@2.1.5": 93 | version "2.1.5" 94 | resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" 95 | integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== 96 | dependencies: 97 | "@nodelib/fs.stat" "2.0.5" 98 | run-parallel "^1.1.9" 99 | 100 | "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": 101 | version "2.0.5" 102 | resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" 103 | integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== 104 | 105 | "@nodelib/fs.walk@^1.2.3": 106 | version "1.2.8" 107 | resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" 108 | integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== 109 | dependencies: 110 | "@nodelib/fs.scandir" "2.1.5" 111 | fastq "^1.6.0" 112 | 113 | "@polka/url@^1.0.0-next.20": 114 | version "1.0.0-next.21" 115 | resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1" 116 | integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g== 117 | 118 | "@rollup/pluginutils@^4.2.1": 119 | version "4.2.1" 120 | resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d" 121 | integrity sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ== 122 | dependencies: 123 | estree-walker "^2.0.1" 124 | picomatch "^2.2.2" 125 | 126 | "@sveltejs/vite-plugin-svelte@^1.0.0-next.30": 127 | version "1.0.0-next.47" 128 | resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.0-next.47.tgz#a7e2774a83f904591f49d179dae949e0793fa1ef" 129 | integrity sha512-J6n8UN51aq/TEZGQ89/EtdXTtca3cRcTJGzi6fi+xK8LkgsHQLCZhRj+PJ+swktRSWTX9IOmQS55SqVg6bz5fA== 130 | dependencies: 131 | "@rollup/pluginutils" "^4.2.1" 132 | debug "^4.3.4" 133 | deepmerge "^4.2.2" 134 | kleur "^4.1.4" 135 | magic-string "^0.26.2" 136 | svelte-hmr "^0.14.12" 137 | 138 | "@tsconfig/svelte@^2.0.1": 139 | version "2.0.1" 140 | resolved "https://registry.yarnpkg.com/@tsconfig/svelte/-/svelte-2.0.1.tgz#0e8d7caa693e9b2afce5e622c0475bb0fd89c12c" 141 | integrity sha512-aqkICXbM1oX5FfgZd2qSSAGdyo/NRxjWCamxoyi3T8iVQnzGge19HhDYzZ6NrVOW7bhcWNSq9XexWFtMzbB24A== 142 | 143 | "@types/chai-subset@^1.3.3": 144 | version "1.3.3" 145 | resolved "https://registry.yarnpkg.com/@types/chai-subset/-/chai-subset-1.3.3.tgz#97893814e92abd2c534de422cb377e0e0bdaac94" 146 | integrity sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw== 147 | dependencies: 148 | "@types/chai" "*" 149 | 150 | "@types/chai@*", "@types/chai@^4.3.1": 151 | version "4.3.1" 152 | resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.1.tgz#e2c6e73e0bdeb2521d00756d099218e9f5d90a04" 153 | integrity sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ== 154 | 155 | "@types/istanbul-lib-coverage@^2.0.1": 156 | version "2.0.4" 157 | resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" 158 | integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== 159 | 160 | "@types/node@*": 161 | version "17.0.40" 162 | resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.40.tgz#76ee88ae03650de8064a6cf75b8d95f9f4a16090" 163 | integrity sha512-UXdBxNGqTMtm7hCwh9HtncFVLrXoqA3oJW30j6XWp5BH/wu3mVeaxo7cq5benFdBw34HB3XDT2TRPI7rXZ+mDg== 164 | 165 | "@types/pug@^2.0.4": 166 | version "2.0.6" 167 | resolved "https://registry.yarnpkg.com/@types/pug/-/pug-2.0.6.tgz#f830323c88172e66826d0bde413498b61054b5a6" 168 | integrity sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg== 169 | 170 | "@types/sass@^1.16.0": 171 | version "1.43.1" 172 | resolved "https://registry.yarnpkg.com/@types/sass/-/sass-1.43.1.tgz#86bb0168e9e881d7dade6eba16c9ed6d25dc2f68" 173 | integrity sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g== 174 | dependencies: 175 | "@types/node" "*" 176 | 177 | "@unocss/cli@0.41.1": 178 | version "0.41.1" 179 | resolved "https://registry.yarnpkg.com/@unocss/cli/-/cli-0.41.1.tgz#01dde78614cfd8a0a20ff68a91a9d74dded62e4d" 180 | integrity sha512-vspN34NFWCkb91s9Zv2mMH926siYftrNWoX4BvCPzoVGTJCYnAAGSYl/xwf3wZvObftWylTP1w3mcwpdkgYRRg== 181 | dependencies: 182 | "@unocss/config" "0.41.1" 183 | "@unocss/core" "0.41.1" 184 | "@unocss/preset-uno" "0.41.1" 185 | cac "^6.7.12" 186 | chokidar "^3.5.3" 187 | colorette "^2.0.19" 188 | consola "^2.15.3" 189 | fast-glob "^3.2.11" 190 | pathe "^0.3.0" 191 | perfect-debounce "^0.1.3" 192 | 193 | "@unocss/config@0.41.1": 194 | version "0.41.1" 195 | resolved "https://registry.yarnpkg.com/@unocss/config/-/config-0.41.1.tgz#f32547546cf69271b51c392585099ca07bbd4bae" 196 | integrity sha512-CEMcxw5VkazTbkKMRxZ73FjO84OwMggIV9ehuSk/kGMXnyv12Kqs3wB4DzdpZJqxgEC3VYS7VZQQy49ijuYniw== 197 | dependencies: 198 | "@unocss/core" "0.41.1" 199 | unconfig "^0.3.4" 200 | 201 | "@unocss/core@0.41.1": 202 | version "0.41.1" 203 | resolved "https://registry.yarnpkg.com/@unocss/core/-/core-0.41.1.tgz#458a7578a4aebed18392be01a735449565cb39e0" 204 | integrity sha512-Y+ZpUZ1hED0Xz86Y2nuBRtd3G0Oij9iAqQm3XNMBW6h+cMUznR8VKFvDGqE2r0ag9fv5soAZb8/RjMlTeHwrDQ== 205 | 206 | "@unocss/inspector@0.41.1": 207 | version "0.41.1" 208 | resolved "https://registry.yarnpkg.com/@unocss/inspector/-/inspector-0.41.1.tgz#4e6480c60b8ce80a45e86ab93cfc928fb7f6f07c" 209 | integrity sha512-SC4RItSY4iGWR2gqOcpmdpjSds1AQxsFKPWg7qGOlz0UIELrcu7lg8HEpFmwsYdg+N0XdWTqpLWutrBNVqLkfA== 210 | dependencies: 211 | gzip-size "^6.0.0" 212 | sirv "^2.0.2" 213 | 214 | "@unocss/preset-attributify@0.41.1": 215 | version "0.41.1" 216 | resolved "https://registry.yarnpkg.com/@unocss/preset-attributify/-/preset-attributify-0.41.1.tgz#46052b9519ec1b48750a8d62401f6df8171ab678" 217 | integrity sha512-fC5cdJEXHAk1vxC/L0Ub3LR0X/6PZu860UOdfWbSFhB6e53B71JYhbXzPgv3wLVrDeHH1sxGwErXiCeLKOqyUA== 218 | dependencies: 219 | "@unocss/core" "0.41.1" 220 | 221 | "@unocss/preset-icons@0.41.1", "@unocss/preset-icons@^0.41.1": 222 | version "0.41.1" 223 | resolved "https://registry.yarnpkg.com/@unocss/preset-icons/-/preset-icons-0.41.1.tgz#2ab1395f59cb467acd7239caa17a0e7456bf0550" 224 | integrity sha512-7S4Xe4hOpgHMP2FPR/hecBTFf9rNImTRS1yp70ApJtDKYdmZWlJkO+tBNWyZc5OfV+czmKOmNMar0Fei0HH8eQ== 225 | dependencies: 226 | "@iconify/utils" "^1.0.33" 227 | "@unocss/core" "0.41.1" 228 | ohmyfetch "^0.4.18" 229 | 230 | "@unocss/preset-mini@0.41.1": 231 | version "0.41.1" 232 | resolved "https://registry.yarnpkg.com/@unocss/preset-mini/-/preset-mini-0.41.1.tgz#e7ee12183e237106ca7b6b22bfe2f4641af8925b" 233 | integrity sha512-UybylcC4AHPcFNF2BfXh7ThdUK/cQcVqR+0oilaiTqCnqTbeV6hdtabY6c6B2Ye0+MbYPr8r9TJeTo2P1i/oHw== 234 | dependencies: 235 | "@unocss/core" "0.41.1" 236 | 237 | "@unocss/preset-tagify@0.41.1": 238 | version "0.41.1" 239 | resolved "https://registry.yarnpkg.com/@unocss/preset-tagify/-/preset-tagify-0.41.1.tgz#39e7f50c1d34b7ab81970b3f8822396ea5faea8a" 240 | integrity sha512-OaplasrC1vn9BQZfvluls7LicfGaoaDdDRzpnLBYLzlhin/Vq4rKzYRjl4bbVcDLo9nwA3V7/SzXjkWxZPj0LQ== 241 | dependencies: 242 | "@unocss/core" "0.41.1" 243 | 244 | "@unocss/preset-typography@0.41.1": 245 | version "0.41.1" 246 | resolved "https://registry.yarnpkg.com/@unocss/preset-typography/-/preset-typography-0.41.1.tgz#5f0652770dc2213691533041c54bf8431c7453b4" 247 | integrity sha512-7E6atDSIQTtlRHZPoO+z+YdQYgZwHo8gWtkMc5EdTA1CZBkPhabziEOmtwDsS8rh4f2C9Vb07MCXjQtAi87GFQ== 248 | dependencies: 249 | "@unocss/core" "0.41.1" 250 | 251 | "@unocss/preset-uno@0.41.1": 252 | version "0.41.1" 253 | resolved "https://registry.yarnpkg.com/@unocss/preset-uno/-/preset-uno-0.41.1.tgz#556ea6eec8d4a44d500b2913c0676bc6ae6975a5" 254 | integrity sha512-itc2V5QUT/9hXusJNqYcZF0u73iXE/U9Kosjabh/e5w1Vv3KGZSEYy2XRZ31koBKNiYM0opDDFuwJKeInm2cGA== 255 | dependencies: 256 | "@unocss/core" "0.41.1" 257 | "@unocss/preset-mini" "0.41.1" 258 | "@unocss/preset-wind" "0.41.1" 259 | 260 | "@unocss/preset-web-fonts@0.41.1": 261 | version "0.41.1" 262 | resolved "https://registry.yarnpkg.com/@unocss/preset-web-fonts/-/preset-web-fonts-0.41.1.tgz#b60bd49ab8627d41215e50475f6fa13872ead130" 263 | integrity sha512-8uXoRskEgZI2TxfT7fNeZ8tgBYQoDjUDP/LX3YItjY1ggk14CfuJjvEjbEhFJ/Xh05MfljzuolqCHvjPGJQyig== 264 | dependencies: 265 | "@unocss/core" "0.41.1" 266 | ohmyfetch "^0.4.18" 267 | 268 | "@unocss/preset-wind@0.41.1": 269 | version "0.41.1" 270 | resolved "https://registry.yarnpkg.com/@unocss/preset-wind/-/preset-wind-0.41.1.tgz#d3cbfd8ee6aa76c33c64cf566570e25d7be70cdf" 271 | integrity sha512-4rtN42BohpuaxL++XsnoGozk3rIeUTZ5c3OVFNSadwKGajluvr/2l4IN8ITtu1+WzvXDe6ARC3IQzdrXNWtJ2Q== 272 | dependencies: 273 | "@unocss/core" "0.41.1" 274 | "@unocss/preset-mini" "0.41.1" 275 | 276 | "@unocss/reset@0.41.1", "@unocss/reset@^0.41.1": 277 | version "0.41.1" 278 | resolved "https://registry.yarnpkg.com/@unocss/reset/-/reset-0.41.1.tgz#ff77bdabc6d0c2d6dc100e859a5b998e62701693" 279 | integrity sha512-LuexPyQ/xOQdlE6Q3PfcSTisA1r3C26mTulunzN/N3vBheTqG+FlyHaGQUqJst/NFq4SD+lPiNVz3Y3/6/pvww== 280 | 281 | "@unocss/scope@0.41.1": 282 | version "0.41.1" 283 | resolved "https://registry.yarnpkg.com/@unocss/scope/-/scope-0.41.1.tgz#41a78239dd82f683b109a6cdfbcd552f8e308289" 284 | integrity sha512-b3BlydTqI96Fr2WBwjsXM2g1CmrMUwNzrsq3mvIDZ4n/7/WzbAIQzGWZEytmWv9TKOR+KM2v92IVR9GKslvvSw== 285 | 286 | "@unocss/transformer-compile-class@0.41.1": 287 | version "0.41.1" 288 | resolved "https://registry.yarnpkg.com/@unocss/transformer-compile-class/-/transformer-compile-class-0.41.1.tgz#38a82b9da3b33d0345766ef5d7268c5ac3f103ac" 289 | integrity sha512-YEV5ZsKpHJLDKDh4trP5eKDBMpiiqW9z99gIkAznYz+0kdkkCOMiTDHNdAf2fcwyGRqfcShGs69uttbO7MX+WQ== 290 | dependencies: 291 | "@unocss/core" "0.41.1" 292 | 293 | "@unocss/transformer-directives@0.41.1": 294 | version "0.41.1" 295 | resolved "https://registry.yarnpkg.com/@unocss/transformer-directives/-/transformer-directives-0.41.1.tgz#4e710e9250563e64f35027532d4bf32a3a02c95c" 296 | integrity sha512-w6/L648uGB3RgXcahGtEd7XokoZHcnCTNMukQpjVjfoeEfpscTQ2pN7P0afwB/GWjb0BHoU+rL6zT1SsErye5A== 297 | dependencies: 298 | "@unocss/core" "0.41.1" 299 | css-tree "^2.1.0" 300 | 301 | "@unocss/transformer-variant-group@0.41.1": 302 | version "0.41.1" 303 | resolved "https://registry.yarnpkg.com/@unocss/transformer-variant-group/-/transformer-variant-group-0.41.1.tgz#42967852dd1bd041c020a3ee3d1ed45e5c7c97f4" 304 | integrity sha512-1jrv1OqK/XY00ZH1XrED4cGe0VobtBfic/E+GNi4HGCgpXNiVOlYjUv6fBOlVPv6h8rSyGZNyUHxsdoyiWCcgw== 305 | dependencies: 306 | "@unocss/core" "0.41.1" 307 | 308 | "@unocss/vite@0.41.1": 309 | version "0.41.1" 310 | resolved "https://registry.yarnpkg.com/@unocss/vite/-/vite-0.41.1.tgz#2e7bec0d4b5aabc5d2067274d61d5b25c0417b49" 311 | integrity sha512-/vOOM0nN4u2B8myqYjaicCOSyZxFm03kOETQQG8vz5J/ZOBHKewystMRGocMzLZ3ZSgPL7KFa7VZnpRAu9KUpQ== 312 | dependencies: 313 | "@rollup/pluginutils" "^4.2.1" 314 | "@unocss/config" "0.41.1" 315 | "@unocss/core" "0.41.1" 316 | "@unocss/inspector" "0.41.1" 317 | "@unocss/scope" "0.41.1" 318 | "@unocss/transformer-directives" "0.41.1" 319 | magic-string "^0.26.2" 320 | 321 | "@yomguithereal/helpers@^1.1.1": 322 | version "1.1.1" 323 | resolved "https://registry.yarnpkg.com/@yomguithereal/helpers/-/helpers-1.1.1.tgz#185dfb0f88ca2beec53d0adf6eed15c33b1c549d" 324 | integrity sha512-UYvAq/XCA7xoh1juWDYsq3W0WywOB+pz8cgVnE1b45ZfdMhBvHDrgmSFG3jXeZSr2tMTYLGHFHON+ekG05Jebg== 325 | 326 | ansi-regex@^5.0.1: 327 | version "5.0.1" 328 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 329 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 330 | 331 | ansi-styles@^4.0.0: 332 | version "4.3.0" 333 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 334 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 335 | dependencies: 336 | color-convert "^2.0.1" 337 | 338 | anymatch@~3.1.2: 339 | version "3.1.2" 340 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" 341 | integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== 342 | dependencies: 343 | normalize-path "^3.0.0" 344 | picomatch "^2.0.4" 345 | 346 | assertion-error@^1.1.0: 347 | version "1.1.0" 348 | resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" 349 | integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== 350 | 351 | balanced-match@^1.0.0: 352 | version "1.0.2" 353 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 354 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 355 | 356 | binary-extensions@^2.0.0: 357 | version "2.2.0" 358 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" 359 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 360 | 361 | brace-expansion@^1.1.7: 362 | version "1.1.11" 363 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 364 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 365 | dependencies: 366 | balanced-match "^1.0.0" 367 | concat-map "0.0.1" 368 | 369 | braces@^3.0.2, braces@~3.0.2: 370 | version "3.0.2" 371 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 372 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 373 | dependencies: 374 | fill-range "^7.0.1" 375 | 376 | buffer-crc32@^0.2.5: 377 | version "0.2.13" 378 | resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" 379 | integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== 380 | 381 | c8@^7.11.3: 382 | version "7.11.3" 383 | resolved "https://registry.yarnpkg.com/c8/-/c8-7.11.3.tgz#88c8459c1952ed4f701b619493c9ae732b057163" 384 | integrity sha512-6YBmsaNmqRm9OS3ZbIiL2EZgi1+Xc4O24jL3vMYGE6idixYuGdy76rIfIdltSKDj9DpLNrcXSonUTR1miBD0wA== 385 | dependencies: 386 | "@bcoe/v8-coverage" "^0.2.3" 387 | "@istanbuljs/schema" "^0.1.3" 388 | find-up "^5.0.0" 389 | foreground-child "^2.0.0" 390 | istanbul-lib-coverage "^3.2.0" 391 | istanbul-lib-report "^3.0.0" 392 | istanbul-reports "^3.1.4" 393 | rimraf "^3.0.2" 394 | test-exclude "^6.0.0" 395 | v8-to-istanbul "^9.0.0" 396 | yargs "^16.2.0" 397 | yargs-parser "^20.2.9" 398 | 399 | cac@^6.7.12: 400 | version "6.7.12" 401 | resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.12.tgz#6fb5ea2ff50bd01490dbda497f4ae75a99415193" 402 | integrity sha512-rM7E2ygtMkJqD9c7WnFU6fruFcN3xe4FM5yUmgxhZzIKJk4uHl9U/fhwdajGFQbQuv43FAUo1Fe8gX/oIKDeSA== 403 | 404 | callsites@^3.0.0: 405 | version "3.1.0" 406 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" 407 | integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== 408 | 409 | chai@^4.3.6: 410 | version "4.3.6" 411 | resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.6.tgz#ffe4ba2d9fa9d6680cc0b370adae709ec9011e9c" 412 | integrity sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q== 413 | dependencies: 414 | assertion-error "^1.1.0" 415 | check-error "^1.0.2" 416 | deep-eql "^3.0.1" 417 | get-func-name "^2.0.0" 418 | loupe "^2.3.1" 419 | pathval "^1.1.1" 420 | type-detect "^4.0.5" 421 | 422 | check-error@^1.0.2: 423 | version "1.0.2" 424 | resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" 425 | integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== 426 | 427 | chokidar@^3.4.1, chokidar@^3.5.3: 428 | version "3.5.3" 429 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" 430 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== 431 | dependencies: 432 | anymatch "~3.1.2" 433 | braces "~3.0.2" 434 | glob-parent "~5.1.2" 435 | is-binary-path "~2.1.0" 436 | is-glob "~4.0.1" 437 | normalize-path "~3.0.0" 438 | readdirp "~3.6.0" 439 | optionalDependencies: 440 | fsevents "~2.3.2" 441 | 442 | cliui@^7.0.2: 443 | version "7.0.4" 444 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" 445 | integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== 446 | dependencies: 447 | string-width "^4.2.0" 448 | strip-ansi "^6.0.0" 449 | wrap-ansi "^7.0.0" 450 | 451 | color-convert@^2.0.1: 452 | version "2.0.1" 453 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 454 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 455 | dependencies: 456 | color-name "~1.1.4" 457 | 458 | color-name@~1.1.4: 459 | version "1.1.4" 460 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 461 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 462 | 463 | colorette@^2.0.19: 464 | version "2.0.19" 465 | resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" 466 | integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== 467 | 468 | concat-map@0.0.1: 469 | version "0.0.1" 470 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 471 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 472 | 473 | consola@^2.15.3: 474 | version "2.15.3" 475 | resolved "https://registry.yarnpkg.com/consola/-/consola-2.15.3.tgz#2e11f98d6a4be71ff72e0bdf07bd23e12cb61550" 476 | integrity sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw== 477 | 478 | convert-source-map@^1.6.0: 479 | version "1.8.0" 480 | resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" 481 | integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== 482 | dependencies: 483 | safe-buffer "~5.1.1" 484 | 485 | cross-spawn@^7.0.0, cross-spawn@^7.0.3: 486 | version "7.0.3" 487 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 488 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 489 | dependencies: 490 | path-key "^3.1.0" 491 | shebang-command "^2.0.0" 492 | which "^2.0.1" 493 | 494 | css-tree@^2.1.0: 495 | version "2.1.0" 496 | resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.1.0.tgz#170e27ccf94e7c5facb183765c25898be843d1d2" 497 | integrity sha512-PcysZRzToBbrpoUrZ9qfblRIRf8zbEAkU0AIpQFtgkFK0vSbzOmBCvdSAx2Zg7Xx5wiYJKUKk0NMP7kxevie/A== 498 | dependencies: 499 | mdn-data "2.0.27" 500 | source-map-js "^1.0.1" 501 | 502 | csstype@3.1.0: 503 | version "3.1.0" 504 | resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz#4ddcac3718d787cf9df0d1b7d15033925c8f29f2" 505 | integrity sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA== 506 | 507 | debug@4.3.4, debug@^4.3.4: 508 | version "4.3.4" 509 | resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" 510 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 511 | dependencies: 512 | ms "2.1.2" 513 | 514 | deep-eql@^3.0.1: 515 | version "3.0.1" 516 | resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" 517 | integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== 518 | dependencies: 519 | type-detect "^4.0.0" 520 | 521 | deepmerge@^4.2.2: 522 | version "4.2.2" 523 | resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" 524 | integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== 525 | 526 | defu@^6.0.0: 527 | version "6.0.0" 528 | resolved "https://registry.yarnpkg.com/defu/-/defu-6.0.0.tgz#b397a6709a2f3202747a3d9daf9446e41ad0c5fc" 529 | integrity sha512-t2MZGLf1V2rV4VBZbWIaXKdX/mUcYW0n2znQZoADBkGGxYL8EWqCuCZBmJPJ/Yy9fofJkyuuSuo5GSwo0XdEgw== 530 | 531 | destr@^1.1.1: 532 | version "1.1.1" 533 | resolved "https://registry.yarnpkg.com/destr/-/destr-1.1.1.tgz#910457d10a2f2f247add4ca4fdb4a03adcc49079" 534 | integrity sha512-QqkneF8LrYmwATMdnuD2MLI3GHQIcBnG6qFC2q9bSH430VTCDAVjcspPmUaKhPGtAtPAftIUFqY1obQYQuwmbg== 535 | 536 | detect-indent@^6.0.0: 537 | version "6.1.0" 538 | resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" 539 | integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== 540 | 541 | dompurify@2.3.8: 542 | version "2.3.8" 543 | resolved "https://registry.npmjs.org/dompurify/-/dompurify-2.3.8.tgz#224fe9ae57d7ebd9a1ae1ac18c1c1ca3f532226f" 544 | integrity sha512-eVhaWoVibIzqdGYjwsBWodIQIaXFSB+cKDf4cfxLMsK0xiud6SE+/WCVx/Xw/UwQsa4cS3T2eITcdtmTg2UKcw== 545 | 546 | dot-case@^3.0.4: 547 | version "3.0.4" 548 | resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" 549 | integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== 550 | dependencies: 551 | no-case "^3.0.4" 552 | tslib "^2.0.3" 553 | 554 | duplexer@^0.1.2: 555 | version "0.1.2" 556 | resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" 557 | integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== 558 | 559 | emoji-regex@^8.0.0: 560 | version "8.0.0" 561 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 562 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 563 | 564 | es6-promise@^3.1.2: 565 | version "3.3.1" 566 | resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" 567 | integrity sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg== 568 | 569 | esbuild-android-64@0.14.42: 570 | version "0.14.42" 571 | resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.42.tgz#d7ab3d44d3671218d22bce52f65642b12908d954" 572 | integrity sha512-P4Y36VUtRhK/zivqGVMqhptSrFILAGlYp0Z8r9UQqHJ3iWztRCNWnlBzD9HRx0DbueXikzOiwyOri+ojAFfW6A== 573 | 574 | esbuild-android-arm64@0.14.42: 575 | version "0.14.42" 576 | resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.42.tgz#45336d8bec49abddb3a022996a23373f45a57c27" 577 | integrity sha512-0cOqCubq+RWScPqvtQdjXG3Czb3AWI2CaKw3HeXry2eoA2rrPr85HF7IpdU26UWdBXgPYtlTN1LUiuXbboROhg== 578 | 579 | esbuild-darwin-64@0.14.42: 580 | version "0.14.42" 581 | resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.42.tgz#6dff5e44cd70a88c33323e2f5fb598e40c68a9e0" 582 | integrity sha512-ipiBdCA3ZjYgRfRLdQwP82rTiv/YVMtW36hTvAN5ZKAIfxBOyPXY7Cejp3bMXWgzKD8B6O+zoMzh01GZsCuEIA== 583 | 584 | esbuild-darwin-arm64@0.14.42: 585 | version "0.14.42" 586 | resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.42.tgz#2c7313e1b12d2fa5b889c03213d682fb92ca8c4f" 587 | integrity sha512-bU2tHRqTPOaoH/4m0zYHbFWpiYDmaA0gt90/3BMEFaM0PqVK/a6MA2V/ypV5PO0v8QxN6gH5hBPY4YJ2lopXgA== 588 | 589 | esbuild-freebsd-64@0.14.42: 590 | version "0.14.42" 591 | resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.42.tgz#ad1c5a564a7e473b8ce95ee7f76618d05d6daffc" 592 | integrity sha512-75h1+22Ivy07+QvxHyhVqOdekupiTZVLN1PMwCDonAqyXd8TVNJfIRFrdL8QmSJrOJJ5h8H1I9ETyl2L8LQDaw== 593 | 594 | esbuild-freebsd-arm64@0.14.42: 595 | version "0.14.42" 596 | resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.42.tgz#4bdb480234144f944f1930829bace7561135ddc7" 597 | integrity sha512-W6Jebeu5TTDQMJUJVarEzRU9LlKpNkPBbjqSu+GUPTHDCly5zZEQq9uHkmHHl7OKm+mQ2zFySN83nmfCeZCyNA== 598 | 599 | esbuild-linux-32@0.14.42: 600 | version "0.14.42" 601 | resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.42.tgz#ef18fd19f067e9d2b5f677d6b82fa81519f5a8c2" 602 | integrity sha512-Ooy/Bj+mJ1z4jlWcK5Dl6SlPlCgQB9zg1UrTCeY8XagvuWZ4qGPyYEWGkT94HUsRi2hKsXvcs6ThTOjBaJSMfg== 603 | 604 | esbuild-linux-64@0.14.42: 605 | version "0.14.42" 606 | resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.42.tgz#d84e7333b1c1b22cf8b5b9dbb5dd9b2ecb34b79f" 607 | integrity sha512-2L0HbzQfbTuemUWfVqNIjOfaTRt9zsvjnme6lnr7/MO9toz/MJ5tZhjqrG6uDWDxhsaHI2/nsDgrv8uEEN2eoA== 608 | 609 | esbuild-linux-arm64@0.14.42: 610 | version "0.14.42" 611 | resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.42.tgz#dc19e282f8c4ffbaa470c02a4d171e4ae0180cca" 612 | integrity sha512-c3Ug3e9JpVr8jAcfbhirtpBauLxzYPpycjWulD71CF6ZSY26tvzmXMJYooQ2YKqDY4e/fPu5K8bm7MiXMnyxuA== 613 | 614 | esbuild-linux-arm@0.14.42: 615 | version "0.14.42" 616 | resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.42.tgz#d49870e63e2242b8156bf473f2ee5154226be328" 617 | integrity sha512-STq69yzCMhdRaWnh29UYrLSr/qaWMm/KqwaRF1pMEK7kDiagaXhSL1zQGXbYv94GuGY/zAwzK98+6idCMUOOCg== 618 | 619 | esbuild-linux-mips64le@0.14.42: 620 | version "0.14.42" 621 | resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.42.tgz#f4e6ff9bf8a6f175470498826f48d093b054fc22" 622 | integrity sha512-QuvpHGbYlkyXWf2cGm51LBCHx6eUakjaSrRpUqhPwjh/uvNUYvLmz2LgPTTPwCqaKt0iwL+OGVL0tXA5aDbAbg== 623 | 624 | esbuild-linux-ppc64le@0.14.42: 625 | version "0.14.42" 626 | resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.42.tgz#ac9c66fc80ba9f8fda15a4cc08f4e55f6c0aed63" 627 | integrity sha512-8ohIVIWDbDT+i7lCx44YCyIRrOW1MYlks9fxTo0ME2LS/fxxdoJBwHWzaDYhjvf8kNpA+MInZvyOEAGoVDrMHg== 628 | 629 | esbuild-linux-riscv64@0.14.42: 630 | version "0.14.42" 631 | resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.42.tgz#21e0ae492a3a9bf4eecbfc916339a66e204256d0" 632 | integrity sha512-DzDqK3TuoXktPyG1Lwx7vhaF49Onv3eR61KwQyxYo4y5UKTpL3NmuarHSIaSVlTFDDpcIajCDwz5/uwKLLgKiQ== 633 | 634 | esbuild-linux-s390x@0.14.42: 635 | version "0.14.42" 636 | resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.42.tgz#06d40b957250ffd9a2183bfdfc9a03d6fd21b3e8" 637 | integrity sha512-YFRhPCxl8nb//Wn6SiS5pmtplBi4z9yC2gLrYoYI/tvwuB1jldir9r7JwAGy1Ck4D7sE7wBN9GFtUUX/DLdcEQ== 638 | 639 | esbuild-netbsd-64@0.14.42: 640 | version "0.14.42" 641 | resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.42.tgz#185664f05f10914f14ed43bd9e22b7de584267f7" 642 | integrity sha512-QYSD2k+oT9dqB/4eEM9c+7KyNYsIPgzYOSrmfNGDIyJrbT1d+CFVKvnKahDKNJLfOYj8N4MgyFaU9/Ytc6w5Vw== 643 | 644 | esbuild-openbsd-64@0.14.42: 645 | version "0.14.42" 646 | resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.42.tgz#c29006f659eb4e55283044bbbd4eb4054fae8839" 647 | integrity sha512-M2meNVIKWsm2HMY7+TU9AxM7ZVwI9havdsw6m/6EzdXysyCFFSoaTQ/Jg03izjCsK17FsVRHqRe26Llj6x0MNA== 648 | 649 | esbuild-sunos-64@0.14.42: 650 | version "0.14.42" 651 | resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.42.tgz#aa9eec112cd1e7105e7bb37000eca7d460083f8f" 652 | integrity sha512-uXV8TAZEw36DkgW8Ak3MpSJs1ofBb3Smkc/6pZ29sCAN1KzCAQzsje4sUwugf+FVicrHvlamCOlFZIXgct+iqQ== 653 | 654 | esbuild-windows-32@0.14.42: 655 | version "0.14.42" 656 | resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.42.tgz#c3fc450853c61a74dacc5679de301db23b73e61e" 657 | integrity sha512-4iw/8qWmRICWi9ZOnJJf9sYt6wmtp3hsN4TdI5NqgjfOkBVMxNdM9Vt3626G1Rda9ya2Q0hjQRD9W1o+m6Lz6g== 658 | 659 | esbuild-windows-64@0.14.42: 660 | version "0.14.42" 661 | resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.42.tgz#b877aa37ff47d9fcf0ccb1ca6a24b31475a5e555" 662 | integrity sha512-j3cdK+Y3+a5H0wHKmLGTJcq0+/2mMBHPWkItR3vytp/aUGD/ua/t2BLdfBIzbNN9nLCRL9sywCRpOpFMx3CxzA== 663 | 664 | esbuild-windows-arm64@0.14.42: 665 | version "0.14.42" 666 | resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.42.tgz#79da8744626f24bc016dc40d016950b5a4a2bac5" 667 | integrity sha512-+lRAARnF+hf8J0mN27ujO+VbhPbDqJ8rCcJKye4y7YZLV6C4n3pTRThAb388k/zqF5uM0lS5O201u0OqoWSicw== 668 | 669 | esbuild@^0.14.27: 670 | version "0.14.42" 671 | resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.42.tgz#98587df0b024d5f6341b12a1d735a2bff55e1836" 672 | integrity sha512-V0uPZotCEHokJdNqyozH6qsaQXqmZEOiZWrXnds/zaH/0SyrIayRXWRB98CENO73MIZ9T3HBIOsmds5twWtmgw== 673 | optionalDependencies: 674 | esbuild-android-64 "0.14.42" 675 | esbuild-android-arm64 "0.14.42" 676 | esbuild-darwin-64 "0.14.42" 677 | esbuild-darwin-arm64 "0.14.42" 678 | esbuild-freebsd-64 "0.14.42" 679 | esbuild-freebsd-arm64 "0.14.42" 680 | esbuild-linux-32 "0.14.42" 681 | esbuild-linux-64 "0.14.42" 682 | esbuild-linux-arm "0.14.42" 683 | esbuild-linux-arm64 "0.14.42" 684 | esbuild-linux-mips64le "0.14.42" 685 | esbuild-linux-ppc64le "0.14.42" 686 | esbuild-linux-riscv64 "0.14.42" 687 | esbuild-linux-s390x "0.14.42" 688 | esbuild-netbsd-64 "0.14.42" 689 | esbuild-openbsd-64 "0.14.42" 690 | esbuild-sunos-64 "0.14.42" 691 | esbuild-windows-32 "0.14.42" 692 | esbuild-windows-64 "0.14.42" 693 | esbuild-windows-arm64 "0.14.42" 694 | 695 | escalade@^3.1.1: 696 | version "3.1.1" 697 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" 698 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 699 | 700 | estree-walker@^2.0.1: 701 | version "2.0.2" 702 | resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" 703 | integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== 704 | 705 | eventemitter3@4.0.7: 706 | version "4.0.7" 707 | resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" 708 | integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== 709 | 710 | events@^3.3.0: 711 | version "3.3.0" 712 | resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" 713 | integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== 714 | 715 | execa@^5.1.1: 716 | version "5.1.1" 717 | resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" 718 | integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== 719 | dependencies: 720 | cross-spawn "^7.0.3" 721 | get-stream "^6.0.0" 722 | human-signals "^2.1.0" 723 | is-stream "^2.0.0" 724 | merge-stream "^2.0.0" 725 | npm-run-path "^4.0.1" 726 | onetime "^5.1.2" 727 | signal-exit "^3.0.3" 728 | strip-final-newline "^2.0.0" 729 | 730 | fast-deep-equal@3.1.3: 731 | version "3.1.3" 732 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 733 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 734 | 735 | fast-glob@^3.2.11, fast-glob@^3.2.7: 736 | version "3.2.11" 737 | resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" 738 | integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== 739 | dependencies: 740 | "@nodelib/fs.stat" "^2.0.2" 741 | "@nodelib/fs.walk" "^1.2.3" 742 | glob-parent "^5.1.2" 743 | merge2 "^1.3.0" 744 | micromatch "^4.0.4" 745 | 746 | fastq@^1.6.0: 747 | version "1.13.0" 748 | resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" 749 | integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== 750 | dependencies: 751 | reusify "^1.0.4" 752 | 753 | fill-range@^7.0.1: 754 | version "7.0.1" 755 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 756 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 757 | dependencies: 758 | to-regex-range "^5.0.1" 759 | 760 | find-up@^5.0.0: 761 | version "5.0.0" 762 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" 763 | integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== 764 | dependencies: 765 | locate-path "^6.0.0" 766 | path-exists "^4.0.0" 767 | 768 | foreground-child@^2.0.0: 769 | version "2.0.0" 770 | resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-2.0.0.tgz#71b32800c9f15aa8f2f83f4a6bd9bff35d861a53" 771 | integrity sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA== 772 | dependencies: 773 | cross-spawn "^7.0.0" 774 | signal-exit "^3.0.2" 775 | 776 | fs.realpath@^1.0.0: 777 | version "1.0.0" 778 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 779 | integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== 780 | 781 | fsevents@~2.3.2: 782 | version "2.3.2" 783 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" 784 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 785 | 786 | function-bind@^1.1.1: 787 | version "1.1.1" 788 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 789 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 790 | 791 | get-caller-file@^2.0.5: 792 | version "2.0.5" 793 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 794 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 795 | 796 | get-func-name@^2.0.0: 797 | version "2.0.0" 798 | resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" 799 | integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig== 800 | 801 | get-stream@^6.0.0: 802 | version "6.0.1" 803 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" 804 | integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== 805 | 806 | glob-parent@^5.1.2, glob-parent@~5.1.2: 807 | version "5.1.2" 808 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 809 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 810 | dependencies: 811 | is-glob "^4.0.1" 812 | 813 | glob@^7.1.3, glob@^7.1.4: 814 | version "7.2.3" 815 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" 816 | integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== 817 | dependencies: 818 | fs.realpath "^1.0.0" 819 | inflight "^1.0.4" 820 | inherits "2" 821 | minimatch "^3.1.1" 822 | once "^1.3.0" 823 | path-is-absolute "^1.0.0" 824 | 825 | graceful-fs@^4.1.3: 826 | version "4.2.10" 827 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" 828 | integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== 829 | 830 | graphology-indices@^0.17.0: 831 | version "0.17.0" 832 | resolved "https://registry.yarnpkg.com/graphology-indices/-/graphology-indices-0.17.0.tgz#b93ad32162ff8b09814547aedb101248f0fcbd2e" 833 | integrity sha512-A7RXuKQvdqSWOpn7ZVQo4S33O0vCfPBnUSf7FwE0zNCasqwZVUaCXePuWo5HBpWw68KJcwObZDHpFk6HKH6MYQ== 834 | dependencies: 835 | graphology-utils "^2.4.2" 836 | mnemonist "^0.39.0" 837 | 838 | graphology-layout-force@0.2.4: 839 | version "0.2.4" 840 | resolved "https://registry.yarnpkg.com/graphology-layout-force/-/graphology-layout-force-0.2.4.tgz#a9b5f2aa5c7b56985503d302dbce4c73c76b9eb3" 841 | integrity sha512-NYZz0YAnDkn5pkm30cvB0IScFoWGtbzJMrqaiH070dYlYJiag12Oc89dbVfaMaVR/w8DMIKxn/ix9Bqj+Umm9Q== 842 | dependencies: 843 | graphology-utils "^2.4.2" 844 | 845 | graphology-layout-forceatlas2@^0.10.1: 846 | version "0.10.1" 847 | resolved "https://registry.yarnpkg.com/graphology-layout-forceatlas2/-/graphology-layout-forceatlas2-0.10.1.tgz#741842135609d82d12db5a5fdf74672062c28205" 848 | integrity sha512-ogzBeF1FvWzjkikrIFwxhlZXvD2+wlY54lqhsrWprcdPjopM2J9HoMweUmIgwaTvY4bUYVimpSsOdvDv1gPRFQ== 849 | dependencies: 850 | graphology-utils "^2.1.0" 851 | 852 | graphology-layout@^0.6.0: 853 | version "0.6.0" 854 | resolved "https://registry.yarnpkg.com/graphology-layout/-/graphology-layout-0.6.0.tgz#a0af0c76413d9e71720835c91a883f6919016e4e" 855 | integrity sha512-QZIminJVOqOFHBOf6qEjcMp0m+BNP4/XqY1jrnJhH+fmUHFtNDdTPSXYhVa8Hr3AN5bOPP1Zte5oY1ZzOyzhvA== 856 | dependencies: 857 | graphology-utils "^2.3.0" 858 | pandemonium "^1.5.0" 859 | 860 | graphology-operators@^1.5.1: 861 | version "1.5.1" 862 | resolved "https://registry.yarnpkg.com/graphology-operators/-/graphology-operators-1.5.1.tgz#67f4447df21baa59b571ab7a4c688a2302f9ce20" 863 | integrity sha512-VojhTwtKlGtbopHPzOmAsAgM8MJY1HScgAs3G8FobtI+xsSlnFSKQeuWIibXEg6/wwPHGYT2oxMJbgHcwAEr3Q== 864 | dependencies: 865 | graphology-utils "^2.0.0" 866 | 867 | graphology-shortest-path@^2.0.1: 868 | version "2.0.1" 869 | resolved "https://registry.yarnpkg.com/graphology-shortest-path/-/graphology-shortest-path-2.0.1.tgz#2b332b5049d52b7c45c620e50c79036b7724bb70" 870 | integrity sha512-IYDbhK5EO+eiHjEXL0S+kcxeKYq6eFAfekeGA4YxH+XiAFV4UjeOWnjS0KjxD5+guoDwZYG7jXySExrV93YukQ== 871 | dependencies: 872 | "@yomguithereal/helpers" "^1.1.1" 873 | graphology-indices "^0.17.0" 874 | graphology-utils "^2.4.3" 875 | mnemonist "^0.39.0" 876 | 877 | graphology-types@^0.24.4: 878 | version "0.24.4" 879 | resolved "https://registry.yarnpkg.com/graphology-types/-/graphology-types-0.24.4.tgz#299120fb50dcd7915204068715e7cfc9ef8b5e3c" 880 | integrity sha512-CSgmycWiviCctMFO86YoUTJN1t4/PLKC5Pos2Hite+7kCUXTr+mGlDUAOgpcKG1IfFaeL9VDmTjFpzs2rTnPWw== 881 | 882 | graphology-utils@^2.0.0, graphology-utils@^2.1.0, graphology-utils@^2.3.0, graphology-utils@^2.4.2, graphology-utils@^2.4.3, graphology-utils@^2.5.0: 883 | version "2.5.2" 884 | resolved "https://registry.yarnpkg.com/graphology-utils/-/graphology-utils-2.5.2.tgz#4d30d6e567d27c01f105e1494af816742e8d2440" 885 | integrity sha512-ckHg8MXrXJkOARk56ZaSCM1g1Wihe2d6iTmz1enGOz4W/l831MBCKSayeFQfowgF8wd+PQ4rlch/56Vs/VZLDQ== 886 | 887 | graphology@^0.25.1: 888 | version "0.25.1" 889 | resolved "https://registry.yarnpkg.com/graphology/-/graphology-0.25.1.tgz#f92b86294782522d3898ce4480e4a577c0c2568a" 890 | integrity sha512-yYA7BJCcXN2DrKNQQ9Qf22zBHm/yTbyBR71T1MYBbGtywNHsv0QZtk8zaR6zxNcp2hCCZayUkHp9DyMSZCpoxQ== 891 | dependencies: 892 | events "^3.3.0" 893 | obliterator "^2.0.2" 894 | 895 | gzip-size@^6.0.0: 896 | version "6.0.0" 897 | resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" 898 | integrity sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q== 899 | dependencies: 900 | duplexer "^0.1.2" 901 | 902 | has-flag@^4.0.0: 903 | version "4.0.0" 904 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 905 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 906 | 907 | has@^1.0.3: 908 | version "1.0.3" 909 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" 910 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 911 | dependencies: 912 | function-bind "^1.1.1" 913 | 914 | html-escaper@^2.0.0: 915 | version "2.0.2" 916 | resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" 917 | integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== 918 | 919 | human-signals@^2.1.0: 920 | version "2.1.0" 921 | resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" 922 | integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== 923 | 924 | import-fresh@^3.2.1: 925 | version "3.3.0" 926 | resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" 927 | integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== 928 | dependencies: 929 | parent-module "^1.0.0" 930 | resolve-from "^4.0.0" 931 | 932 | inflight@^1.0.4: 933 | version "1.0.6" 934 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 935 | integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== 936 | dependencies: 937 | once "^1.3.0" 938 | wrappy "1" 939 | 940 | inherits@2: 941 | version "2.0.4" 942 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 943 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 944 | 945 | inherits@2.0.3: 946 | version "2.0.3" 947 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 948 | integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== 949 | 950 | is-binary-path@~2.1.0: 951 | version "2.1.0" 952 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 953 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 954 | dependencies: 955 | binary-extensions "^2.0.0" 956 | 957 | is-core-module@^2.8.1: 958 | version "2.9.0" 959 | resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" 960 | integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== 961 | dependencies: 962 | has "^1.0.3" 963 | 964 | is-extglob@^2.1.1: 965 | version "2.1.1" 966 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 967 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== 968 | 969 | is-fullwidth-code-point@^3.0.0: 970 | version "3.0.0" 971 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 972 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 973 | 974 | is-glob@^4.0.1, is-glob@~4.0.1: 975 | version "4.0.3" 976 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 977 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 978 | dependencies: 979 | is-extglob "^2.1.1" 980 | 981 | is-number@^7.0.0: 982 | version "7.0.0" 983 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 984 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 985 | 986 | is-stream@^2.0.0: 987 | version "2.0.1" 988 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" 989 | integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== 990 | 991 | isexe@^2.0.0: 992 | version "2.0.0" 993 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 994 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== 995 | 996 | istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: 997 | version "3.2.0" 998 | resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" 999 | integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== 1000 | 1001 | istanbul-lib-report@^3.0.0: 1002 | version "3.0.0" 1003 | resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" 1004 | integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== 1005 | dependencies: 1006 | istanbul-lib-coverage "^3.0.0" 1007 | make-dir "^3.0.0" 1008 | supports-color "^7.1.0" 1009 | 1010 | istanbul-reports@^3.1.4: 1011 | version "3.1.4" 1012 | resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" 1013 | integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== 1014 | dependencies: 1015 | html-escaper "^2.0.0" 1016 | istanbul-lib-report "^3.0.0" 1017 | 1018 | jiti@^1.13.0: 1019 | version "1.14.0" 1020 | resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.14.0.tgz#5350fff532a4d891ca4bcd700c47c1f40e6ee326" 1021 | integrity sha512-4IwstlaKQc9vCTC+qUXLM1hajy2ImiL9KnLvVYiaHOtS/v3wRjhLlGl121AmgDgx/O43uKmxownJghS5XMya2A== 1022 | 1023 | kleur@^4.1.4: 1024 | version "4.1.4" 1025 | resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.4.tgz#8c202987d7e577766d039a8cd461934c01cda04d" 1026 | integrity sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA== 1027 | 1028 | kolorist@^1.5.1: 1029 | version "1.5.1" 1030 | resolved "https://registry.yarnpkg.com/kolorist/-/kolorist-1.5.1.tgz#c3d66dc4fabde4f6b7faa6efda84c00491f9e52b" 1031 | integrity sha512-lxpCM3HTvquGxKGzHeknB/sUjuVoUElLlfYnXZT73K8geR9jQbroGlSCFBax9/0mpGoD3kzcMLnOlGQPJJNyqQ== 1032 | 1033 | local-pkg@^0.4.1: 1034 | version "0.4.1" 1035 | resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-0.4.1.tgz#e7b0d7aa0b9c498a1110a5ac5b00ba66ef38cfff" 1036 | integrity sha512-lL87ytIGP2FU5PWwNDo0w3WhIo2gopIAxPg9RxDYF7m4rr5ahuZxP22xnJHIvaLTe4Z9P6uKKY2UHiwyB4pcrw== 1037 | 1038 | locate-path@^6.0.0: 1039 | version "6.0.0" 1040 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" 1041 | integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== 1042 | dependencies: 1043 | p-locate "^5.0.0" 1044 | 1045 | lodash-es@4.17.21: 1046 | version "4.17.21" 1047 | resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" 1048 | integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== 1049 | 1050 | loupe@^2.3.1: 1051 | version "2.3.4" 1052 | resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.4.tgz#7e0b9bffc76f148f9be769cb1321d3dcf3cb25f3" 1053 | integrity sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ== 1054 | dependencies: 1055 | get-func-name "^2.0.0" 1056 | 1057 | lower-case@^2.0.2: 1058 | version "2.0.2" 1059 | resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" 1060 | integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== 1061 | dependencies: 1062 | tslib "^2.0.3" 1063 | 1064 | magic-string@^0.25.7: 1065 | version "0.25.9" 1066 | resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" 1067 | integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== 1068 | dependencies: 1069 | sourcemap-codec "^1.4.8" 1070 | 1071 | magic-string@^0.26.1, magic-string@^0.26.2: 1072 | version "0.26.2" 1073 | resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.26.2.tgz#5331700e4158cd6befda738bb6b0c7b93c0d4432" 1074 | integrity sha512-NzzlXpclt5zAbmo6h6jNc8zl2gNRGHvmsZW4IvZhTC4W7k4OlLP+S5YLussa/r3ixNT66KOQfNORlXHSOy/X4A== 1075 | dependencies: 1076 | sourcemap-codec "^1.4.8" 1077 | 1078 | make-dir@^3.0.0: 1079 | version "3.1.0" 1080 | resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" 1081 | integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== 1082 | dependencies: 1083 | semver "^6.0.0" 1084 | 1085 | mdn-data@2.0.27: 1086 | version "2.0.27" 1087 | resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.27.tgz#1710baa7b0db8176d3b3d565ccb7915fc69525ab" 1088 | integrity sha512-kwqO0I0jtWr25KcfLm9pia8vLZ8qoAKhWZuZMbneJq3jjBD3gl5nZs8l8Tu3ZBlBAHVQtDur9rdDGyvtfVraHQ== 1089 | 1090 | merge-stream@^2.0.0: 1091 | version "2.0.0" 1092 | resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" 1093 | integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== 1094 | 1095 | merge2@^1.3.0: 1096 | version "1.4.1" 1097 | resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" 1098 | integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== 1099 | 1100 | micromatch@^4.0.4: 1101 | version "4.0.5" 1102 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" 1103 | integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== 1104 | dependencies: 1105 | braces "^3.0.2" 1106 | picomatch "^2.3.1" 1107 | 1108 | mimic-fn@^2.1.0: 1109 | version "2.1.0" 1110 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" 1111 | integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== 1112 | 1113 | min-indent@^1.0.0: 1114 | version "1.0.1" 1115 | resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" 1116 | integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== 1117 | 1118 | minimatch@^3.0.4, minimatch@^3.1.1: 1119 | version "3.1.2" 1120 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 1121 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 1122 | dependencies: 1123 | brace-expansion "^1.1.7" 1124 | 1125 | minimist@^1.2.0, minimist@^1.2.6: 1126 | version "1.2.6" 1127 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" 1128 | integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== 1129 | 1130 | mkdirp@^0.5.1: 1131 | version "0.5.6" 1132 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" 1133 | integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== 1134 | dependencies: 1135 | minimist "^1.2.6" 1136 | 1137 | mnemonist@^0.39.0: 1138 | version "0.39.2" 1139 | resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.39.2.tgz#7e6a0bd5c7199460ee12a651103c7007adc6225a" 1140 | integrity sha512-n3ZCEosuMH03DVivZ9N0fcXPWiZrBLEdfSlEJ+S/mJxmk3zuo1ur0dj9URDczFyP1VS3wfiyKzqLLDXoPJ6rPA== 1141 | dependencies: 1142 | obliterator "^2.0.1" 1143 | 1144 | mri@^1.1.0: 1145 | version "1.2.0" 1146 | resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" 1147 | integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== 1148 | 1149 | mrmime@^1.0.0: 1150 | version "1.0.1" 1151 | resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-1.0.1.tgz#5f90c825fad4bdd41dc914eff5d1a8cfdaf24f27" 1152 | integrity sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw== 1153 | 1154 | ms@2.1.2: 1155 | version "2.1.2" 1156 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 1157 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 1158 | 1159 | nanoid@^3.3.4: 1160 | version "3.3.4" 1161 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" 1162 | integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== 1163 | 1164 | no-case@^3.0.4: 1165 | version "3.0.4" 1166 | resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" 1167 | integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== 1168 | dependencies: 1169 | lower-case "^2.0.2" 1170 | tslib "^2.0.3" 1171 | 1172 | node-fetch-native@^0.1.3: 1173 | version "0.1.4" 1174 | resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-0.1.4.tgz#09b06754f9e298bac23848050da2352125634f89" 1175 | integrity sha512-10EKpOCQPXwZVFh3U1ptOMWBgKTbsN7Vvo6WVKt5pw4hp8zbv6ZVBZPlXw+5M6Tyi1oc1iD4/sNPd71KYA16tQ== 1176 | 1177 | normalize-path@^3.0.0, normalize-path@~3.0.0: 1178 | version "3.0.0" 1179 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 1180 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 1181 | 1182 | npm-run-path@^4.0.1: 1183 | version "4.0.1" 1184 | resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" 1185 | integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== 1186 | dependencies: 1187 | path-key "^3.0.0" 1188 | 1189 | obliterator@^2.0.1, obliterator@^2.0.2: 1190 | version "2.0.4" 1191 | resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.4.tgz#fa650e019b2d075d745e44f1effeb13a2adbe816" 1192 | integrity sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ== 1193 | 1194 | ohmyfetch@^0.4.18: 1195 | version "0.4.18" 1196 | resolved "https://registry.yarnpkg.com/ohmyfetch/-/ohmyfetch-0.4.18.tgz#2952e04bd52662d0618d3d2f344db0250c3eeac2" 1197 | integrity sha512-MslzNrQzBLtZHmiZBI8QMOcMpdNFlK61OJ34nFNFynZ4v+4BonfCQ7VIN4EGXvGGq5zhDzgdJoY3o9S1l2T7KQ== 1198 | dependencies: 1199 | destr "^1.1.1" 1200 | node-fetch-native "^0.1.3" 1201 | ufo "^0.8.4" 1202 | undici "^5.2.0" 1203 | 1204 | once@^1.3.0: 1205 | version "1.4.0" 1206 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 1207 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== 1208 | dependencies: 1209 | wrappy "1" 1210 | 1211 | onetime@^5.1.2: 1212 | version "5.1.2" 1213 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" 1214 | integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== 1215 | dependencies: 1216 | mimic-fn "^2.1.0" 1217 | 1218 | p-limit@^3.0.2: 1219 | version "3.1.0" 1220 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" 1221 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== 1222 | dependencies: 1223 | yocto-queue "^0.1.0" 1224 | 1225 | p-locate@^5.0.0: 1226 | version "5.0.0" 1227 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" 1228 | integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== 1229 | dependencies: 1230 | p-limit "^3.0.2" 1231 | 1232 | pandemonium@^1.5.0: 1233 | version "1.5.0" 1234 | resolved "https://registry.yarnpkg.com/pandemonium/-/pandemonium-1.5.0.tgz#93f35af555de1420022b341e730215c51c725be3" 1235 | integrity sha512-9PU9fy93rJhZHLMjX+4M1RwZPEYl6g7DdWKGmGNhkgBZR5+tOBVExNZc00kzdEGMxbaAvWdQy9MqGAScGwYlcA== 1236 | 1237 | parent-module@^1.0.0: 1238 | version "1.0.1" 1239 | resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" 1240 | integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== 1241 | dependencies: 1242 | callsites "^3.0.0" 1243 | 1244 | path-exists@^4.0.0: 1245 | version "4.0.0" 1246 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" 1247 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 1248 | 1249 | path-is-absolute@^1.0.0: 1250 | version "1.0.1" 1251 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 1252 | integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== 1253 | 1254 | path-key@^3.0.0, path-key@^3.1.0: 1255 | version "3.1.1" 1256 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 1257 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 1258 | 1259 | path-parse@^1.0.7: 1260 | version "1.0.7" 1261 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" 1262 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== 1263 | 1264 | path@0.12.7: 1265 | version "0.12.7" 1266 | resolved "https://registry.yarnpkg.com/path/-/path-0.12.7.tgz#d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f" 1267 | integrity sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q== 1268 | dependencies: 1269 | process "^0.11.1" 1270 | util "^0.10.3" 1271 | 1272 | pathe@^0.3.0: 1273 | version "0.3.1" 1274 | resolved "https://registry.yarnpkg.com/pathe/-/pathe-0.3.1.tgz#e0e47bc0e8a1775fd001e2fdbf67d7f649a4a4f4" 1275 | integrity sha512-cKMVe/pikPpreoODbjoliSk0cIT66JjEOWN30akc9WTo8kUjxFPYqmXvMBVPMSAJGJlx6v/nYzqSSHkp1cfezQ== 1276 | 1277 | pathval@^1.1.1: 1278 | version "1.1.1" 1279 | resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" 1280 | integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== 1281 | 1282 | perfect-debounce@^0.1.3: 1283 | version "0.1.3" 1284 | resolved "https://registry.yarnpkg.com/perfect-debounce/-/perfect-debounce-0.1.3.tgz#ff6798ea543a3ba1f0efeeaf97c0340f5c8871ce" 1285 | integrity sha512-NOT9AcKiDGpnV/HBhI22Str++XWcErO/bALvHCuhv33owZW/CjH8KAFLZDCmu3727sihe0wTxpDhyGc6M8qacQ== 1286 | 1287 | picocolors@^1.0.0: 1288 | version "1.0.0" 1289 | resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" 1290 | integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== 1291 | 1292 | picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.3.1: 1293 | version "2.3.1" 1294 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 1295 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 1296 | 1297 | postcss@^8.4.13: 1298 | version "8.4.14" 1299 | resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.14.tgz#ee9274d5622b4858c1007a74d76e42e56fd21caf" 1300 | integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig== 1301 | dependencies: 1302 | nanoid "^3.3.4" 1303 | picocolors "^1.0.0" 1304 | source-map-js "^1.0.2" 1305 | 1306 | process@^0.11.1: 1307 | version "0.11.10" 1308 | resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" 1309 | integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== 1310 | 1311 | queue-microtask@^1.2.2: 1312 | version "1.2.3" 1313 | resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" 1314 | integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== 1315 | 1316 | readdirp@~3.6.0: 1317 | version "3.6.0" 1318 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" 1319 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 1320 | dependencies: 1321 | picomatch "^2.2.1" 1322 | 1323 | require-directory@^2.1.1: 1324 | version "2.1.1" 1325 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 1326 | integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== 1327 | 1328 | resolve-from@^4.0.0: 1329 | version "4.0.0" 1330 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" 1331 | integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== 1332 | 1333 | resolve@^1.22.0: 1334 | version "1.22.0" 1335 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" 1336 | integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== 1337 | dependencies: 1338 | is-core-module "^2.8.1" 1339 | path-parse "^1.0.7" 1340 | supports-preserve-symlinks-flag "^1.0.0" 1341 | 1342 | reusify@^1.0.4: 1343 | version "1.0.4" 1344 | resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" 1345 | integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== 1346 | 1347 | rimraf@^2.5.2: 1348 | version "2.7.1" 1349 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" 1350 | integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== 1351 | dependencies: 1352 | glob "^7.1.3" 1353 | 1354 | rimraf@^3.0.2: 1355 | version "3.0.2" 1356 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" 1357 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 1358 | dependencies: 1359 | glob "^7.1.3" 1360 | 1361 | rollup@^2.59.0: 1362 | version "2.75.5" 1363 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.75.5.tgz#7985c1962483235dd07966f09fdad5c5f89f16d0" 1364 | integrity sha512-JzNlJZDison3o2mOxVmb44Oz7t74EfSd1SQrplQk0wSaXV7uLQXtVdHbxlcT3w+8tZ1TL4r/eLfc7nAbz38BBA== 1365 | optionalDependencies: 1366 | fsevents "~2.3.2" 1367 | 1368 | run-parallel@^1.1.9: 1369 | version "1.2.0" 1370 | resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" 1371 | integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== 1372 | dependencies: 1373 | queue-microtask "^1.2.2" 1374 | 1375 | sade@^1.7.4: 1376 | version "1.8.1" 1377 | resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701" 1378 | integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A== 1379 | dependencies: 1380 | mri "^1.1.0" 1381 | 1382 | safe-buffer@~5.1.1: 1383 | version "5.1.2" 1384 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 1385 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 1386 | 1387 | sander@^0.5.0: 1388 | version "0.5.1" 1389 | resolved "https://registry.yarnpkg.com/sander/-/sander-0.5.1.tgz#741e245e231f07cafb6fdf0f133adfa216a502ad" 1390 | integrity sha1-dB4kXiMfB8r7b98PEzrfohalAq0= 1391 | dependencies: 1392 | es6-promise "^3.1.2" 1393 | graceful-fs "^4.1.3" 1394 | mkdirp "^0.5.1" 1395 | rimraf "^2.5.2" 1396 | 1397 | semver@^6.0.0: 1398 | version "6.3.0" 1399 | resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" 1400 | integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== 1401 | 1402 | shebang-command@^2.0.0: 1403 | version "2.0.0" 1404 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 1405 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 1406 | dependencies: 1407 | shebang-regex "^3.0.0" 1408 | 1409 | shebang-regex@^3.0.0: 1410 | version "3.0.0" 1411 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 1412 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 1413 | 1414 | sigma@^2.3.1: 1415 | version "2.3.1" 1416 | resolved "https://registry.yarnpkg.com/sigma/-/sigma-2.3.1.tgz#69fd9165479fa49ed84348afcd0432215fdf935f" 1417 | integrity sha512-YfQsVZf78CeIUv8EYLqp/yvhMwwBXGrbpy+rD1N2X9IqtJ11+VfQRjWfVqHDhjM8oPfWPsaJMtpWFQ8pIflvCA== 1418 | dependencies: 1419 | "@yomguithereal/helpers" "^1.1.1" 1420 | events "^3.3.0" 1421 | graphology-utils "^2.5.0" 1422 | 1423 | signal-exit@^3.0.2, signal-exit@^3.0.3: 1424 | version "3.0.7" 1425 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" 1426 | integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== 1427 | 1428 | sirv@^2.0.2: 1429 | version "2.0.2" 1430 | resolved "https://registry.yarnpkg.com/sirv/-/sirv-2.0.2.tgz#128b9a628d77568139cff85703ad5497c46a4760" 1431 | integrity sha512-4Qog6aE29nIjAOKe/wowFTxOdmbEZKb+3tsLljaBRzJwtqto0BChD2zzH0LhgCSXiI+V7X+Y45v14wBZQ1TK3w== 1432 | dependencies: 1433 | "@polka/url" "^1.0.0-next.20" 1434 | mrmime "^1.0.0" 1435 | totalist "^3.0.0" 1436 | 1437 | snake-case@3.0.4: 1438 | version "3.0.4" 1439 | resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c" 1440 | integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== 1441 | dependencies: 1442 | dot-case "^3.0.4" 1443 | tslib "^2.0.3" 1444 | 1445 | sorcery@^0.10.0: 1446 | version "0.10.0" 1447 | resolved "https://registry.yarnpkg.com/sorcery/-/sorcery-0.10.0.tgz#8ae90ad7d7cb05fc59f1ab0c637845d5c15a52b7" 1448 | integrity sha1-iukK19fLBfxZ8asMY3hF1cFaUrc= 1449 | dependencies: 1450 | buffer-crc32 "^0.2.5" 1451 | minimist "^1.2.0" 1452 | sander "^0.5.0" 1453 | sourcemap-codec "^1.3.0" 1454 | 1455 | source-map-js@^1.0.1, source-map-js@^1.0.2: 1456 | version "1.0.2" 1457 | resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" 1458 | integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== 1459 | 1460 | sourcemap-codec@^1.3.0, sourcemap-codec@^1.4.8: 1461 | version "1.4.8" 1462 | resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" 1463 | integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== 1464 | 1465 | string-width@^4.1.0, string-width@^4.2.0: 1466 | version "4.2.3" 1467 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 1468 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1469 | dependencies: 1470 | emoji-regex "^8.0.0" 1471 | is-fullwidth-code-point "^3.0.0" 1472 | strip-ansi "^6.0.1" 1473 | 1474 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 1475 | version "6.0.1" 1476 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1477 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1478 | dependencies: 1479 | ansi-regex "^5.0.1" 1480 | 1481 | strip-final-newline@^2.0.0: 1482 | version "2.0.0" 1483 | resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" 1484 | integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== 1485 | 1486 | strip-indent@^3.0.0: 1487 | version "3.0.0" 1488 | resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" 1489 | integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== 1490 | dependencies: 1491 | min-indent "^1.0.0" 1492 | 1493 | supports-color@^7.1.0: 1494 | version "7.2.0" 1495 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 1496 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1497 | dependencies: 1498 | has-flag "^4.0.0" 1499 | 1500 | supports-preserve-symlinks-flag@^1.0.0: 1501 | version "1.0.0" 1502 | resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" 1503 | integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== 1504 | 1505 | svelte-check@^2.2.7: 1506 | version "2.7.2" 1507 | resolved "https://registry.yarnpkg.com/svelte-check/-/svelte-check-2.7.2.tgz#0e31e4d3d766ca41f38812cfb1c3257654c93e34" 1508 | integrity sha512-TuVX4YtXHbRM8sVuK5Jk+mKWdm3f0d6hvAC6qCTp8yUszGZewpEBCo2V5fRWZCiz+0J4OCiDHOS+DFMxv39rJA== 1509 | dependencies: 1510 | "@jridgewell/trace-mapping" "^0.3.9" 1511 | chokidar "^3.4.1" 1512 | fast-glob "^3.2.7" 1513 | import-fresh "^3.2.1" 1514 | picocolors "^1.0.0" 1515 | sade "^1.7.4" 1516 | svelte-preprocess "^4.0.0" 1517 | typescript "*" 1518 | 1519 | svelte-hmr@^0.14.12: 1520 | version "0.14.12" 1521 | resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.14.12.tgz#a127aec02f1896500b10148b2d4d21ddde39973f" 1522 | integrity sha512-4QSW/VvXuqVcFZ+RhxiR8/newmwOCTlbYIezvkeN6302YFRE8cXy0naamHcjz8Y9Ce3ITTZtrHrIL0AGfyo61w== 1523 | 1524 | svelte-preprocess@^4.0.0, svelte-preprocess@^4.9.8: 1525 | version "4.10.7" 1526 | resolved "https://registry.yarnpkg.com/svelte-preprocess/-/svelte-preprocess-4.10.7.tgz#3626de472f51ffe20c9bc71eff5a3da66797c362" 1527 | integrity sha512-sNPBnqYD6FnmdBrUmBCaqS00RyCsCpj2BG58A1JBswNF7b0OKviwxqVrOL/CKyJrLSClrSeqQv5BXNg2RUbPOw== 1528 | dependencies: 1529 | "@types/pug" "^2.0.4" 1530 | "@types/sass" "^1.16.0" 1531 | detect-indent "^6.0.0" 1532 | magic-string "^0.25.7" 1533 | sorcery "^0.10.0" 1534 | strip-indent "^3.0.0" 1535 | 1536 | svelte@^3.44.0: 1537 | version "3.48.0" 1538 | resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.48.0.tgz#f98c866d45e155bad8e1e88f15f9c03cd28753d3" 1539 | integrity sha512-fN2YRm/bGumvjUpu6yI3BpvZnpIm9I6A7HR4oUNYd7ggYyIwSA/BX7DJ+UXXffLp6XNcUijyLvttbPVCYa/3xQ== 1540 | 1541 | test-exclude@^6.0.0: 1542 | version "6.0.0" 1543 | resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" 1544 | integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== 1545 | dependencies: 1546 | "@istanbuljs/schema" "^0.1.2" 1547 | glob "^7.1.4" 1548 | minimatch "^3.0.4" 1549 | 1550 | tinypool@^0.2.1: 1551 | version "0.2.1" 1552 | resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-0.2.1.tgz#7c3347514de36113f224212590de17f04fdf0078" 1553 | integrity sha512-HFU5ZYVq3wBfhSaf8qdqGsneaqXm0FgJQpoUlJbVdHpRLzm77IneKAD3RjzJWZvIv0YpPB9S7LUW53f6BE6ZSg== 1554 | 1555 | tinyspy@^0.3.3: 1556 | version "0.3.3" 1557 | resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-0.3.3.tgz#8b57f8aec7fe1bf583a3a49cb9ab30c742f69237" 1558 | integrity sha512-gRiUR8fuhUf0W9lzojPf1N1euJYA30ISebSfgca8z76FOvXtVXqd5ojEIaKLWbDQhAaC3ibxZIjqbyi4ybjcTw== 1559 | 1560 | to-regex-range@^5.0.1: 1561 | version "5.0.1" 1562 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 1563 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1564 | dependencies: 1565 | is-number "^7.0.0" 1566 | 1567 | totalist@^3.0.0: 1568 | version "3.0.0" 1569 | resolved "https://registry.yarnpkg.com/totalist/-/totalist-3.0.0.tgz#4ef9c58c5f095255cdc3ff2a0a55091c57a3a1bd" 1570 | integrity sha512-eM+pCBxXO/njtF7vdFsHuqb+ElbxqtI4r5EAvk6grfAFyJ6IvWlSkfZ5T9ozC6xWw3Fj1fGoSmrl0gUs46JVIw== 1571 | 1572 | tslib@^2.0.3, tslib@^2.3.1: 1573 | version "2.4.0" 1574 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" 1575 | integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== 1576 | 1577 | type-detect@^4.0.0, type-detect@^4.0.5: 1578 | version "4.0.8" 1579 | resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" 1580 | integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== 1581 | 1582 | typescript@*, typescript@^4.5.4: 1583 | version "4.7.3" 1584 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.3.tgz#8364b502d5257b540f9de4c40be84c98e23a129d" 1585 | integrity sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA== 1586 | 1587 | ufo@^0.8.4: 1588 | version "0.8.4" 1589 | resolved "https://registry.yarnpkg.com/ufo/-/ufo-0.8.4.tgz#23e9ed82398d2116dcb378e8fba5ced8eca2ee40" 1590 | integrity sha512-/+BmBDe8GvlB2nIflWasLLAInjYG0bC9HRnfEpNi4sw77J2AJNnEVnTDReVrehoh825+Q/evF3THXTAweyam2g== 1591 | 1592 | unconfig@^0.3.4: 1593 | version "0.3.4" 1594 | resolved "https://registry.yarnpkg.com/unconfig/-/unconfig-0.3.4.tgz#f0c85584a088a434dde2215d8a3b272427d6056c" 1595 | integrity sha512-cf39F1brwQuLSuMLTYXOdWJH0O1CJee6a4QW1nYtO7SoBUfVvQCvEel6ssTNXtPfi17kop1ADmVtmC49NlFkIQ== 1596 | dependencies: 1597 | "@antfu/utils" "^0.5.1" 1598 | defu "^6.0.0" 1599 | jiti "^1.13.0" 1600 | 1601 | undici@^5.2.0: 1602 | version "5.5.1" 1603 | resolved "https://registry.yarnpkg.com/undici/-/undici-5.5.1.tgz#baaf25844a99eaa0b22e1ef8d205bffe587c8f43" 1604 | integrity sha512-MEvryPLf18HvlCbLSzCW0U00IMftKGI5udnjrQbC5D4P0Hodwffhv+iGfWuJwg16Y/TK11ZFK8i+BPVW2z/eAw== 1605 | 1606 | unocss@^0.41.1: 1607 | version "0.41.1" 1608 | resolved "https://registry.yarnpkg.com/unocss/-/unocss-0.41.1.tgz#fee029fcf358ff4006316113d96d68526af12a9c" 1609 | integrity sha512-tsc/4Xw3Z6t4pda0KmEK2+XayZYgLhPypZHWfPjQofTWzkm43c+k3PO5vS72jEVorE8rK0VDcoRSvhKGvC5lww== 1610 | dependencies: 1611 | "@unocss/cli" "0.41.1" 1612 | "@unocss/core" "0.41.1" 1613 | "@unocss/preset-attributify" "0.41.1" 1614 | "@unocss/preset-icons" "0.41.1" 1615 | "@unocss/preset-mini" "0.41.1" 1616 | "@unocss/preset-tagify" "0.41.1" 1617 | "@unocss/preset-typography" "0.41.1" 1618 | "@unocss/preset-uno" "0.41.1" 1619 | "@unocss/preset-web-fonts" "0.41.1" 1620 | "@unocss/preset-wind" "0.41.1" 1621 | "@unocss/reset" "0.41.1" 1622 | "@unocss/transformer-compile-class" "0.41.1" 1623 | "@unocss/transformer-directives" "0.41.1" 1624 | "@unocss/transformer-variant-group" "0.41.1" 1625 | "@unocss/vite" "0.41.1" 1626 | 1627 | util@^0.10.3: 1628 | version "0.10.4" 1629 | resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" 1630 | integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== 1631 | dependencies: 1632 | inherits "2.0.3" 1633 | 1634 | v8-to-istanbul@^9.0.0: 1635 | version "9.0.1" 1636 | resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" 1637 | integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w== 1638 | dependencies: 1639 | "@jridgewell/trace-mapping" "^0.3.12" 1640 | "@types/istanbul-lib-coverage" "^2.0.1" 1641 | convert-source-map "^1.6.0" 1642 | 1643 | vite-plugin-logseq@^1.1.2: 1644 | version "1.1.2" 1645 | resolved "https://registry.yarnpkg.com/vite-plugin-logseq/-/vite-plugin-logseq-1.1.2.tgz#bf99747d002c16b631a9886ea236f5a93a0244bf" 1646 | integrity sha512-l5YvoH3K25Zx9eqgoJFug7NfVqSPwq7/FcYYhN1TkdG8ZOiD+c+TAwdCS2dJbGgvx8GmSpbgwSZWgslB+wH53g== 1647 | dependencies: 1648 | magic-string "^0.26.1" 1649 | 1650 | vite@^2.9.12: 1651 | version "2.9.13" 1652 | resolved "https://registry.yarnpkg.com/vite/-/vite-2.9.13.tgz#859cb5d4c316c0d8c6ec9866045c0f7858ca6abc" 1653 | integrity sha512-AsOBAaT0AD7Mhe8DuK+/kE4aWYFMx/i0ZNi98hJclxb4e0OhQcZYUrvLjIaQ8e59Ui7txcvKMiJC1yftqpQoDw== 1654 | dependencies: 1655 | esbuild "^0.14.27" 1656 | postcss "^8.4.13" 1657 | resolve "^1.22.0" 1658 | rollup "^2.59.0" 1659 | optionalDependencies: 1660 | fsevents "~2.3.2" 1661 | 1662 | vite@^2.9.9: 1663 | version "2.9.9" 1664 | resolved "https://registry.yarnpkg.com/vite/-/vite-2.9.9.tgz#8b558987db5e60fedec2f4b003b73164cb081c5e" 1665 | integrity sha512-ffaam+NgHfbEmfw/Vuh6BHKKlI/XIAhxE5QSS7gFLIngxg171mg1P3a4LSRME0z2ZU1ScxoKzphkipcYwSD5Ew== 1666 | dependencies: 1667 | esbuild "^0.14.27" 1668 | postcss "^8.4.13" 1669 | resolve "^1.22.0" 1670 | rollup "^2.59.0" 1671 | optionalDependencies: 1672 | fsevents "~2.3.2" 1673 | 1674 | vitest@^0.16.0: 1675 | version "0.16.0" 1676 | resolved "https://registry.yarnpkg.com/vitest/-/vitest-0.16.0.tgz#6858a864b25850d28252bc480b0c89014ff48ce8" 1677 | integrity sha512-Ntp6jrM8wf2NMtamMBLkRBBdeqHkgAH/WMh5Xryts1j2ft2D8QZQbiSVFkSl4WmEQzcPP0YM069g/Ga1vtnEtg== 1678 | dependencies: 1679 | "@types/chai" "^4.3.1" 1680 | "@types/chai-subset" "^1.3.3" 1681 | "@types/node" "*" 1682 | chai "^4.3.6" 1683 | debug "^4.3.4" 1684 | local-pkg "^0.4.1" 1685 | tinypool "^0.2.1" 1686 | tinyspy "^0.3.3" 1687 | vite "^2.9.12" 1688 | 1689 | which@^2.0.1: 1690 | version "2.0.2" 1691 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 1692 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1693 | dependencies: 1694 | isexe "^2.0.0" 1695 | 1696 | wrap-ansi@^7.0.0: 1697 | version "7.0.0" 1698 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 1699 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1700 | dependencies: 1701 | ansi-styles "^4.0.0" 1702 | string-width "^4.1.0" 1703 | strip-ansi "^6.0.0" 1704 | 1705 | wrappy@1: 1706 | version "1.0.2" 1707 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1708 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 1709 | 1710 | y18n@^5.0.5: 1711 | version "5.0.8" 1712 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" 1713 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 1714 | 1715 | yargs-parser@^20.2.2, yargs-parser@^20.2.9: 1716 | version "20.2.9" 1717 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" 1718 | integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== 1719 | 1720 | yargs@^16.2.0: 1721 | version "16.2.0" 1722 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" 1723 | integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== 1724 | dependencies: 1725 | cliui "^7.0.2" 1726 | escalade "^3.1.1" 1727 | get-caller-file "^2.0.5" 1728 | require-directory "^2.1.1" 1729 | string-width "^4.2.0" 1730 | y18n "^5.0.5" 1731 | yargs-parser "^20.2.2" 1732 | 1733 | yocto-queue@^0.1.0: 1734 | version "0.1.0" 1735 | resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" 1736 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== 1737 | --------------------------------------------------------------------------------