├── .gitignore ├── LICENSE ├── README.md ├── baidu_image.js ├── baidu_image_categorys.json ├── baidu_image_map.json ├── baidu_images.json ├── baidu_translate_hot_key_tool.js ├── boss_toolkit.js ├── chinese_mooc_toolkit.js ├── csdn_rewrite.js ├── dark_mode.js ├── gitea_toolkit.js ├── graphQL_toolkit.js ├── juejin_avatar_toolkit.js ├── mkv.js ├── mobile_cleaner.js ├── package.json ├── pagination.js ├── pnpm-lock.yaml ├── pub_dev_toolkit.js ├── qq_speed_bbs_toolkit.js ├── sketch_meaxure_toolkit.js ├── swagger_toolkit.js ├── twitter_toolkit.js └── wechat_read_toolkit.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | node_modules 3 | package-lock.json 4 | yarn.lock 5 | .DS_Store -------------------------------------------------------------------------------- /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 | Copyright (C) 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 | # 这里是一些自己瞎写的油猴脚本 2 | 3 | ## 1. CSDN 去广告沉浸阅读模式 4 | 沉浸阅读模式, [详情](https://greasyfork.org/zh-CN/scripts/373457-csdn-%E5%8E%BB%E5%B9%BF%E5%91%8A%E6%B2%89%E6%B5%B8%E9%98%85%E8%AF%BB%E6%A8%A1%E5%BC%8F) 5 | 6 | - 点击右下角小齿轮设置背景图片 7 | - 屏蔽广告 8 | - 移除与正文无关的 sidebar & header 9 | - 正文部分宽度放大 10 | - 绕过阅读更多按钮; 直接展开正文内容 11 | - 增强广告屏蔽,建议使用 ABP 等插件屏蔽广告,还可以明显提升页面加载速度 12 | - 屏蔽登录弹窗 13 | - 增加随机背景图并设置透明度 14 | - 移除点击文章中的链接拦截, 直接跳转到目标链接, 建议使用鼠标中键在新窗口打开链接! 15 | - 解除跳转拦截 16 | 17 | ### 1.1 调试 18 | ``` 19 | . 20 | ├── baidu_image_categorys.json [output] 图片类目 json 21 | ├── baidu_image.js source code 22 | ├── baidu_image_map.json [output] 图片 id: name 映射 23 | └── baidu_images.json [input] 百度 API response 原始数据 24 | ``` 25 | 26 | ```bash 27 | curl -o baidu_images.json https://www.baidu.com/home/skin/data/skin # 从百度服务器获取背景图片 json 28 | node baidu_image.js # 转换数据, 将会更新 `baidu_image_categorys.json` & `baidu_image_map.json` 29 | ``` 30 | 31 | ## 2. dark_mode++ 32 | 降低页面亮度, 可手动调节(通过 `q` 降低 / `w` 提升)亮度 , [详情](https://greasyfork.org/zh-CN/scripts/376268-dark) 33 | 34 | ## 3. baidu_translate_hot_key_tool 35 | 百度翻译快捷键插件, [详情](https://greasyfork.org/zh-CN/scripts/373456-baidu-translate-hot-key-tool) 36 | 37 | - ctrl+meta+up 聚焦搜索框 38 | - ctrl+meta+left 搜索内容发音 39 | - ctrl+meta+right 翻译结果发音 40 | -------------------------------------------------------------------------------- /baidu_image.js: -------------------------------------------------------------------------------- 1 | const imagesJson = require('./baidu_images.json') 2 | const fs = require('fs') 3 | 4 | const result = {} // categoryName, idList 5 | const map = {} // id: name 6 | 7 | const originList = imagesJson.bsResult.data 8 | 9 | const CATEGORY_FIELDS = ['skinData', 'starData'] 10 | const convert = () => { 11 | for (const row of originList) { 12 | if (Array.isArray(row.bgitem)) { 13 | handleRows(row, row.bgitem) 14 | } else { 15 | for (const field of CATEGORY_FIELDS) { 16 | if (!Array.isArray(row[field])) continue 17 | for (category of row[field]) { 18 | for (const rows of row[field]) { 19 | handleRows(rows, rows.list) 20 | } 21 | break 22 | } 23 | break 24 | } 25 | } 26 | } 27 | } 28 | 29 | const handleRows = (parent, rows) => { 30 | let index = 0 31 | for (const r of rows) { 32 | const categoryName = (parent.type || '') + (parent.name || '') + (parent.filewriter || '') 33 | const img = { 34 | id: Number(r.filename || r.dataindex), 35 | name: (r.name || r.filewriter) 36 | ? ((r.name || '') + ' ' + (r.filewriter || '')) 37 | : categoryName + index 38 | } 39 | if (img.id > 10000) continue // 过滤自定义背景图 ?? 40 | if (categoryName === '最近使用') continue 41 | console.log(categoryName, img.name) 42 | // console.log(img) 43 | // if (!img.name.trim()) console.log(rows) 44 | // if (map[img.id]) console.log(map[img.id]) 45 | map[img.id] = img.name 46 | if (!Array.isArray(result[categoryName])) result[categoryName] = [] 47 | result[categoryName].push(img.id) 48 | index++ 49 | } 50 | } 51 | 52 | convert() 53 | 54 | // console.log(result) 55 | // console.log(map) 56 | 57 | fs.writeFileSync('./baidu_image_categorys.json', JSON.stringify(result)) 58 | fs.writeFileSync('./baidu_image_map.json', JSON.stringify(map)) -------------------------------------------------------------------------------- /baidu_image_categorys.json: -------------------------------------------------------------------------------- 1 | {"热门":[887,886,883,882,881,880,879,878,877,876,874,875,872,873,859,832,833,834,827,828,829,830,831,817,818,819,820,821,805,806,807,808,809,810,811,812,813,814,815,816,796,797,798,799,800,801,802,803,804,776,777,778,781,784,765,767,768,766,611,610,608,720],"冒险岛2":[860,861,862,863,864,865,866,867,868,869,870,871],"守望先锋":[835,836,837,838,839,840,841,842,843,844,845,846],"魔兽世界":[721,722,723,724,725,726,727,728,729,730,731,732],"炉石传说":[733,734,735,736,737,738,739,740,741,742,743,744],"风暴英雄":[660,661,662,663,664,665,666,667,668,669,670,671],"暗黑破坏神Ⅲ":[672,673,674,675,676,677,678,679,680,681,682,683],"星际争霸II":[684,685,686,687,688,689,690,691,692,693,694,695],"冷兔":[749,750,751,752,753,754,755,756,757,758,759,760],"阿狸":[521,114,523,524,525,526,527,528,529,530,531,532],"炮炮兵":[540,534,535,536,537,538,539,533,541,542,543,544],"林心如":[437,438,440,439,441,443,447,444,445,446,442,448],"郑爽":[509,510,511,512,515,514,513,516,517,518,519,520],"戚薇":[449,456,451,452,453,454,455,450,457,459,458,460],"佟丽娅":[485,486,490,488,489,487,491,492,493,494,495,496],"Angelababy":[400,401,402,403,407,405,406,410,404,409,408,411],"唐嫣":[473,474,475,482,480,478,479,477,476,481,483,484],"李冰冰":[424,425,427,430,426,429,428,431,432,433,434,435],"高圆圆":[412,413,418,415,416,417,414,419,420,421,422,423],"孙俪":[461,462,463,464,471,466,468,467,469,470,465,472],"姚晨":[497,498,499,506,502,501,503,504,505,507,500,508],"杨幂":[200,201,202,203,204,205,206,207,208,209,210,211],"刘诗诗":[273,274,275,276,277,278,279,280,281,282,283],"胡歌":[260,261,262,263,628,629,630,631,268,269,270,271],"邓紫棋":[320,321,322,323,324,325,326,327,328,329,330,331],"赵丽颖":[249,2481,250,251,252,253,254,255,256,257,258,259],"马天宇":[284,285,286,287,288,289,290,291,292,293,294,295],"陈晓":[233,225,226,227,228,229,230,231,232,224,234,235],"陈伟霆":[308,309,310,311,312,313,314,315,316,317,318,319],"柳岩":[236,2371,238,239,240,241,242,243,244,245,246,247],"吴奇隆":[297,298,299,300,301,302,304,296,305,306,307],"风景":[822,823,824,825,826,54,62,5,37,115,116,117,118,120,122,123,49,25,121,26,43,45,48,51,70,4,10,11,17,23,6,28,38,16,31,42,163,164,165,166,167,168,170,171,172,174,175,177,178,179,180,181,182,184,185,186,69,57,13,67],"简约":[12,111,114,53,27,33,41,35,2,14,44,21,36,8,150,125,1,169,173,176,183,46,61,47,52,64,24,58,18,59,55,9,20],"小清新":[74,71,113,119,124,29,65,32,34,39,40,50,60,73,30,63,126,128,66,19,112,22,68,7,15,3,56]} -------------------------------------------------------------------------------- /baidu_image_map.json: -------------------------------------------------------------------------------- 1 | {"1":"原野 全景图片","2":"银汉迢迢 全景图片","3":"紫色郁金香 百度相册","4":"飞瀑如练 全景图片","5":"梦里水乡 探摄小子","6":"长天一色 全景图片","7":"春意浓 sprint207","8":"暮色四合 探摄小子","9":"出水芙蓉 探摄小子","10":"壁立千仞 全景图片","11":"廊桥遗梦 探摄小子","12":"寥落星河 全景图片","13":"层林尽染 全景图片","14":"晨曦 探摄小子","15":"早梅争春 探摄小子","16":"千山雪 刘霄","17":"海之梦 全景图片","18":"白色飞羽 sprint207","19":"在路上 jesse2young","20":"锦鲤 sprint207","21":"雨夜 yunxiaoqian","22":"水墨江南 戈斯拉918","23":"城市之光 戈斯拉918","24":"三叶草 wanzathe","25":" 全景图片","26":" 全景图片","27":" 全景图片","28":" 全景图片","29":" 全景图片","30":" 全景图片","31":" 全景图片","32":" 全景图片","33":" 全景图片","34":" 全景图片","35":" 全景图片","36":" 全景图片","37":" 全景图片","38":" 全景图片","39":" 全景图片","40":" 全景图片","41":" 全景图片","42":" 全景图片","43":" 全景图片","44":" 全景图片","45":" 全景图片","46":" 全景图片","47":" 全景图片","48":" 全景图片","49":" 全景图片","50":" 全景图片","51":" 全景图片","52":" 全景图片","53":" ranklau","54":" silsnow","55":" weifengqingyu","56":" 张云洁01","57":" tiffanywangbei","58":" ying_ok_delang","59":" sherry_dundun","60":" 源形毕露","61":" 路璐","62":" richard-wang","63":" 源形毕露","64":" 圣名若瑟","65":" 米壹映画","66":" 米壹映画","67":" 路璐","68":" 路璐","69":" 毛嘉文","70":" richard-wang","71":" fish,胡子鱼","73":" fish,胡子鱼","74":" fish,胡子鱼","111":" 全景图片","112":" fish,胡子鱼","113":" fish,胡子鱼","114":" 全景图片","115":" 彼岸Claire","116":" 落绪纷飞","117":" 魔神咒","118":" lemonchen07","119":" 决明","120":" 长老亮","121":" 蓝月玩转西部","122":" 小pie","123":" woodfishbbi","124":" 早川","125":"波涛汹涌 全景","126":"火车飞驰 全景","128":"演唱会 全景","150":"激情世界杯 ","163":" shenmishashou","164":" 我叫孟夕","165":" 穷游晓明","166":" 1024小虎牙","167":" shenmishashou","168":" shenmishashou","169":" 0535xiaoyudi","170":" 穷游晓明","171":" 西西里玩不停","172":" 西西里玩不停","173":" 1024小虎牙","174":" shenmishashou","175":" 穷游晓明","176":" 1024小虎牙","177":" 我叫孟夕","178":" 1024小虎牙","179":" shenmishashou","180":" 西西里玩不停","181":" 我叫孟夕","182":" 蓝色呓语","183":" 西西里玩不停","184":" 西西里玩不停","185":" 我叫孟夕","186":" 西西里玩不停","200":"杨幂0","201":"杨幂1","202":"杨幂2","203":"杨幂3","204":"杨幂4","205":"杨幂5","206":"杨幂6","207":"杨幂7","208":"杨幂8","209":"杨幂9","210":"杨幂10","211":"杨幂11","224":"陈晓9","225":"陈晓1","226":"陈晓2","227":"陈晓3","228":"陈晓4","229":"陈晓5","230":"陈晓6","231":"陈晓7","232":"陈晓8","233":"陈晓0","234":"陈晓10","235":"陈晓11","236":"柳岩0","238":"柳岩2","239":"柳岩3","240":"柳岩4","241":"柳岩5","242":"柳岩6","243":"柳岩7","244":"柳岩8","245":"柳岩9","246":"柳岩10","247":"柳岩11","249":"赵丽颖0","250":"赵丽颖2","251":"赵丽颖3","252":"赵丽颖4","253":"赵丽颖5","254":"赵丽颖6","255":"赵丽颖7","256":"赵丽颖8","257":"赵丽颖9","258":"赵丽颖10","259":"赵丽颖11","260":"胡歌0","261":"胡歌1","262":"胡歌2","263":"胡歌3","268":"胡歌8","269":"胡歌9","270":"胡歌10","271":"胡歌11","273":"刘诗诗0","274":"刘诗诗1","275":"刘诗诗2","276":"刘诗诗3","277":"刘诗诗4","278":"刘诗诗5","279":"刘诗诗6","280":"刘诗诗7","281":"刘诗诗8","282":"刘诗诗9","283":"刘诗诗10","284":"马天宇0","285":"马天宇1","286":"马天宇2","287":"马天宇3","288":"马天宇4","289":"马天宇5","290":"马天宇6","291":"马天宇7","292":"马天宇8","293":"马天宇9","294":"马天宇10","295":"马天宇11","296":"吴奇隆7","297":"吴奇隆0","298":"吴奇隆1","299":"吴奇隆2","300":"吴奇隆3","301":"吴奇隆4","302":"吴奇隆5","304":"吴奇隆6","305":"吴奇隆8","306":"吴奇隆9","307":"吴奇隆10","308":"陈伟霆0","309":"陈伟霆1","310":"陈伟霆2","311":"陈伟霆3","312":"陈伟霆4","313":"陈伟霆5","314":"陈伟霆6","315":"陈伟霆7","316":"陈伟霆8","317":"陈伟霆9","318":"陈伟霆10","319":"陈伟霆11","320":"邓紫棋0","321":"邓紫棋1","322":"邓紫棋2","323":"邓紫棋3","324":"邓紫棋4","325":"邓紫棋5","326":"邓紫棋6","327":"邓紫棋7","328":"邓紫棋8","329":"邓紫棋9","330":"邓紫棋10","331":"邓紫棋11","400":"Angelababy0","401":"Angelababy1","402":"Angelababy2","403":"Angelababy3","404":"Angelababy8","405":"Angelababy5","406":"Angelababy6","407":"Angelababy4","408":"Angelababy10","409":"Angelababy9","410":"Angelababy7","411":"Angelababy11","412":"高圆圆0","413":"高圆圆1","414":"高圆圆6","415":"高圆圆3","416":"高圆圆4","417":"高圆圆5","418":"高圆圆2","419":"高圆圆7","420":"高圆圆8","421":"高圆圆9","422":"高圆圆10","423":"高圆圆11","424":"李冰冰0","425":"李冰冰1","426":"李冰冰4","427":"李冰冰2","428":"李冰冰6","429":"李冰冰5","430":"李冰冰3","431":"李冰冰7","432":"李冰冰8","433":"李冰冰9","434":"李冰冰10","435":"李冰冰11","437":"林心如0","438":"林心如1","439":"林心如3","440":"林心如2","441":"林心如4","442":"林心如10","443":"林心如5","444":"林心如7","445":"林心如8","446":"林心如9","447":"林心如6","448":"林心如11","449":"戚薇0","450":"戚薇7","451":"戚薇2","452":"戚薇3","453":"戚薇4","454":"戚薇5","455":"戚薇6","456":"戚薇1","457":"戚薇8","458":"戚薇10","459":"戚薇9","460":"戚薇11","461":" 陈漫","462":"孙俪1","463":"孙俪2","464":"孙俪3","465":"孙俪10","466":"孙俪5","467":"孙俪7","468":" 陈漫","469":" 陈漫","470":"孙俪9","471":"孙俪4","472":"孙俪11","473":"唐嫣0","474":"唐嫣1","475":"唐嫣2","476":"唐嫣8","477":"唐嫣7","478":"唐嫣5","479":"唐嫣6","480":"唐嫣4","481":"唐嫣9","482":"唐嫣3","483":"唐嫣10","484":"唐嫣11","485":"佟丽娅0","486":"佟丽娅1","487":"佟丽娅5","488":"佟丽娅3","489":"佟丽娅4","490":"佟丽娅2","491":"佟丽娅6","492":"佟丽娅7","493":"佟丽娅8","494":"佟丽娅9","495":"佟丽娅10","496":"佟丽娅11","497":"姚晨0","498":"姚晨1","499":"姚晨2","500":"姚晨10","501":"姚晨5","502":"姚晨4","503":"姚晨6","504":"姚晨7","505":"姚晨8","506":"姚晨3","507":"姚晨9","508":"姚晨11","509":"郑爽0","510":"郑爽1","511":"郑爽2","512":"郑爽3","513":"郑爽6","514":"郑爽5","515":"郑爽4","516":"郑爽7","517":"郑爽8","518":"郑爽9","519":"郑爽10","520":"郑爽11","521":"阿狸0","523":"阿狸2","524":"阿狸3","525":"阿狸4","526":"阿狸5","527":"阿狸6","528":"阿狸7","529":"阿狸8","530":"阿狸9","531":"阿狸10","532":"阿狸11","533":"炮炮兵7","534":"炮炮兵1","535":"炮炮兵2","536":"炮炮兵3","537":"炮炮兵4","538":"炮炮兵5","539":"炮炮兵6","540":"炮炮兵0","541":"炮炮兵8","542":"炮炮兵9","543":"炮炮兵10","544":"炮炮兵11","608":"热门60","610":"热门59","611":"热门58","628":"胡歌4","629":"胡歌5","630":"胡歌6","631":"胡歌7","660":"风暴英雄0","661":"风暴英雄1","662":"风暴英雄2","663":"风暴英雄3","664":"风暴英雄4","665":"风暴英雄5","666":"风暴英雄6","667":"风暴英雄7","668":"风暴英雄8","669":"风暴英雄9","670":"风暴英雄10","671":"风暴英雄11","672":"暗黑破坏神Ⅲ0","673":"暗黑破坏神Ⅲ1","674":"暗黑破坏神Ⅲ2","675":"暗黑破坏神Ⅲ3","676":"暗黑破坏神Ⅲ4","677":"暗黑破坏神Ⅲ5","678":"暗黑破坏神Ⅲ6","679":"暗黑破坏神Ⅲ7","680":"暗黑破坏神Ⅲ8","681":"暗黑破坏神Ⅲ9","682":"暗黑破坏神Ⅲ10","683":"暗黑破坏神Ⅲ11","684":"星际争霸II0","685":"星际争霸II1","686":"星际争霸II2","687":"星际争霸II3","688":"星际争霸II4","689":"星际争霸II5","690":"星际争霸II6","691":"星际争霸II7","692":"星际争霸II8","693":"星际争霸II9","694":"星际争霸II10","695":"星际争霸II11","720":"热门61","721":"魔兽世界0","722":"魔兽世界1","723":"魔兽世界2","724":"魔兽世界3","725":"魔兽世界4","726":"魔兽世界5","727":"魔兽世界6","728":"魔兽世界7","729":"魔兽世界8","730":"魔兽世界9","731":"魔兽世界10","732":"魔兽世界11","733":"炉石传说0","734":"炉石传说1","735":"炉石传说2","736":"炉石传说3","737":"炉石传说4","738":"炉石传说5","739":"炉石传说6","740":"炉石传说7","741":"炉石传说8","742":"炉石传说9","743":"炉石传说10","744":"炉石传说11","749":"冷兔0","750":"冷兔1","751":"冷兔2","752":"冷兔3","753":"冷兔4","754":"冷兔5","755":"冷兔6","756":"冷兔7","757":"冷兔8","758":"冷兔9","759":"冷兔10","760":"冷兔11","765":"热门54","766":"热门57","767":"热门55","768":"热门56","776":" 光线影业","777":" 光线影业","778":" 光线影业","781":" 光线影业","784":" 枫海影业","796":" 欢瑞世纪","797":" 欢瑞世纪","798":" 欢瑞世纪","799":" 欢瑞世纪","800":" 欢瑞世纪","801":" 欢瑞世纪","802":" 恒业影业","803":" 周迅工作室","804":" 华映传媒","805":" 爱奇艺","806":" 爱奇艺","807":" 爱奇艺","808":" 世纪长龙","809":" 世纪长龙","810":" 世纪长龙","811":" 嘉映影业","812":" 林心如工作室","813":" 环球影业","814":" 环球影业","815":" 环球影业","816":" 环球影业","817":" 环球影业","818":" 环球影业","819":" 派拉蒙影业","820":" 派拉蒙影业","821":" 黄子韬工作室","822":" 高品图像","823":" 高品图像","824":" 高品图像","825":" 高品图像","826":" 高品图像","827":" 爱奇艺影业","828":" 爱奇艺影业","829":" 优酷","830":" 基美影业","831":" 基美影业","832":" 魔威映画","833":" 亚洲星光娱乐","834":" 周冬雨工作室","835":"守望先锋0","836":"守望先锋1","837":"守望先锋2","838":"守望先锋3","839":"守望先锋4","840":"守望先锋5","841":"守望先锋6","842":"守望先锋7","843":"守望先锋8","844":"守望先锋9","845":"守望先锋10","846":"守望先锋11","859":" 记忆大师","860":"冒险岛20","861":"冒险岛21","862":"冒险岛22","863":"冒险岛23","864":"冒险岛24","865":"冒险岛25","866":"冒险岛26","867":"冒险岛27","868":"冒险岛28","869":"冒险岛29","870":"冒险岛210","871":"冒险岛211","872":" 天龙八部","873":" 天龙八部","874":" 变形金刚ol","875":" 变形金刚ol","876":" 一品芝麻狐","877":" 一品芝麻狐","878":" 一品芝麻狐","879":" 一品芝麻狐","880":" 一品芝麻狐","881":" 一品芝麻狐","882":" 白敬亭","883":" 剑灵","886":" 最强nba","887":" 最强nba","2371":"柳岩1","2481":"赵丽颖1"} -------------------------------------------------------------------------------- /baidu_translate_hot_key_tool.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name baidu_translate_hot_key_tool 3 | // @namespace http://tampermonkey.net/ 4 | // @version 1.2.0 5 | // @description v0.1.0 百度翻译快捷键插件;支持聚焦/搜索内容发音/翻译结果发音 6 | // @description v1.0.0 整理代码, 移除兼容部分代码 7 | // @description v1.1.0 为了方便纯键盘操作(使用 vimium 插件), 在发音时使输入框失去焦点 8 | // @description v1.2.0 支持自定义 group keys, 包含 ctrl, alt, shift, meta; 详情见 log 9 | // @icon http://fanyi.bdstatic.com/static/translation/img/favicon/favicon_d87cd2a.ico 10 | // @author sven 11 | // @include https://fanyi.baidu.com/* 12 | // @match <$URL$> 13 | // ==/UserScript== 14 | 15 | ; (function () { 16 | if (location.href.indexOf('https://fanyi.baidu.com/#') !== 0) return false 17 | const input = document.getElementById('baidu_translate_input') 18 | const Handler = { 19 | _originBtn: null, 20 | _resultBtn: null, 21 | _defaultTriggerKeys: ['ctrl', 'meta'], 22 | get triggerKeys() { 23 | const cache = localStorage.getItem('triggerKeys') 24 | return JSON.parse(cache) || this._defaultTriggerKeys 25 | }, 26 | get originBtn() { 27 | return this._originBtn || (this._originBtn = document.querySelector('.input-operate .operate-btn.op-sound')) 28 | }, 29 | get resultBtn() { 30 | return this._resultBtn || (this._resultBtn = document.querySelector('.output-operate .operate-btn.op-sound')) 31 | }, 32 | init() { 33 | Handler.listenKeyup() 34 | Handler.addTips() 35 | console.log('%c[baidu_translate_hot_key_tool] %c可以使用例如 `%clocalStorage.setItem("triggerKeys", \'["ctrl", "alt"]\')%c` 方式修改默认快捷键(user settings), 只支持 ctrl, alt, meta, shift', 'color: teal', 'color: auto', 'color: #FFF', 'color: auto') 36 | const userTriggerKeys = localStorage.getItem('triggerKeys'); 37 | if (Array.isArray(JSON.parse(userTriggerKeys))) { 38 | console.log('%c[baidu_translate_hot_key_tool] %c已使用自定义快捷键: ' + userTriggerKeys, 'color: teal', 'color: #FFF') 39 | } 40 | }, 41 | /** 42 | * 监听键盘事件 43 | * ctrl+meta+up(focus) 聚焦并选中 44 | * ctrl+meta+left(say) 发音[输入内容] 45 | * ctrl+meta+right(say) 发音[翻译结果] 46 | * Mac 下 meta 键换为 alt 键 47 | */ 48 | listenKeyup() { 49 | document.addEventListener('keyup', evt => { 50 | const { 51 | altKey, ctrlKey, shiftKey, keyCode, metaKey 52 | } = evt 53 | const trigger = this.triggerKeys.every(t => evt[t + 'Key']) 54 | if (!trigger) return false 55 | const originBtn = document.querySelector('.input-operate .operate-btn.op-sound') 56 | const resultBtn = document.querySelector('.output-operate .operate-btn.op-sound') 57 | switch (keyCode) { 58 | case 38: // up 59 | if (evt.target.tagName === 'TEXTAREA') return false; 60 | input.focus() 61 | input.select() 62 | break 63 | case 37: // left 64 | originBtn && originBtn.click() 65 | input.blur() 66 | break 67 | case 39: // right 68 | resultBtn && resultBtn.click() 69 | input.blur() 70 | break 71 | } 72 | }) 73 | }, 74 | addTips() { 75 | // window.addEventListener('load', evt => { 76 | // if (this.originBtn) this.originBtn.innerHTML += '
ctrl+meta+left
' 77 | // if (this.resultBtn) this.resultBtn.innerHTML += '
ctrl+meta+right
' 78 | // }) 79 | } 80 | } 81 | Handler.init() 82 | })(); -------------------------------------------------------------------------------- /boss_toolkit.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name BOSS 直聘简历下载工具 3 | // @namespace SublimeCT 4 | // @version 1.1.0 5 | // @description 在简历预览页直接下载当前显示的内容, 可以下载为图片(开发中)(下载内容区元素截图) 或 PDF(调用浏览器打印功能可以保存为 PDF) 6 | // @update v1.0.1 更新打印简历时的样式, 去掉边距; 在预览模板时也可以打印 7 | // @author SublimeCT 8 | // @match https://www.zhipin.com/web/geek/resumetpl 9 | // @icon https://www.zhipin.com/favicon.ico 10 | // @grant none 11 | // ==/UserScript== 12 | 13 | ; (() => { 14 | class ToolkitModule { 15 | constructor() { } 16 | isActive = true 17 | } 18 | class DownloadToolkitModule extends ToolkitModule { 19 | async onload(options) { 20 | await Toolkit.waitDOMLoaded(() => document.querySelector('.header .btn-box')) 21 | const btnBox = document.querySelector('.header .btn-box') 22 | await Toolkit.waitDOMLoaded(() => btnBox.querySelector('.btn.btn-download[ka=resumer_maker_preview_download]')) 23 | const downloadButton = btnBox.querySelector('.btn.btn-download[ka=resumer_maker_preview_download]') 24 | const downloadToolketButton = downloadButton.cloneNode(true) 25 | const screenShortToolketButton = downloadButton.cloneNode(true) 26 | downloadToolketButton.setAttribute('ka', 'downloadToolketButton') 27 | downloadToolketButton.style.width = 'auto' 28 | downloadToolketButton.innerText = '下载简历(PDF)' 29 | screenShortToolketButton.setAttribute('ka', 'screenShortToolketButton') 30 | screenShortToolketButton.style.width = 'auto' 31 | // 功能开发中 ... 暂时隐藏 32 | screenShortToolketButton.style.display = 'none' 33 | screenShortToolketButton.innerText = '下载简历(图片)' 34 | // btnBox.removeChild(downloadButton) 35 | btnBox.appendChild(downloadToolketButton) 36 | btnBox.appendChild(screenShortToolketButton) 37 | downloadToolketButton.addEventListener('click', event => { 38 | // 1. 切换为下载 PDF 的样式 39 | this._changeMode('download-pdf') 40 | // 2. 调用浏览器的打印 41 | window.print() 42 | // 3. 切换到原始样式 43 | this._changeMode() 44 | }) 45 | screenShortToolketButton.addEventListener('click', event => { 46 | console.log('??') 47 | }) 48 | } 49 | _changeMode(mode = '') { 50 | document.body.setAttribute('mode', mode) 51 | } 52 | } 53 | /** 54 | * 加入自定义样式 55 | */ 56 | class SheetsToolkitModule extends ToolkitModule { 57 | static _getSheets() { 58 | return ` 59 | /* 显示最外层的滚动条 */ 60 | #wrap { 61 | height: auto !important; 62 | } 63 | .switch-templates-wrapper .btn[ka="resumer_maker_preview_download"] { 64 | display: none !important; 65 | } 66 | .switch-templates-wrapper .btn { 67 | margin-right: 15px; 68 | } 69 | .switch-templates-wrapper .btn:last-of-type { 70 | margin-right: 0; 71 | } 72 | /* 下载 PDF 时的样式 */ 73 | body[mode="download-pdf"] { 74 | width: 790px; 75 | } 76 | body[mode="download-pdf"] #wrap { 77 | min-width: 790px; 78 | } 79 | body[mode="download-pdf"] .select-templates-box { 80 | display: none !important; 81 | } 82 | body[mode="download-pdf"] .switch-templates-wrapper > .header { 83 | display: none !important; 84 | } 85 | body[mode="download-pdf"] .switch-templates-wrapper > .preview-box { 86 | margin: 0 !important; 87 | width: 100% !important; 88 | } 89 | body[mode="download-pdf"] .switch-templates-wrapper > .template-container { 90 | padding-top: 0 !important; 91 | padding-bottom: 0 !important; 92 | } 93 | ` 94 | } 95 | init(ctx) { 96 | ctx.log('加入自定义样式') 97 | SheetsToolkitModule.appendSheets() 98 | } 99 | // 通过注入 css 实现隐藏广告并固定布局 100 | static appendSheets() { 101 | const sheet = document.createTextNode(SheetsToolkitModule._getSheets()) 102 | const el = document.createElement('style') 103 | el.id = 'handle-sheets' 104 | el.appendChild(sheet) 105 | document.getElementsByTagName('head')[0].appendChild(el) 106 | } 107 | } 108 | /** 109 | * 工具类 110 | */ 111 | class Toolkit { 112 | debug = true 113 | options = {} 114 | users = {} 115 | constructor(options = {}) { 116 | Object.assign(this.options, options) 117 | this.emitHook('init') 118 | } 119 | /** 120 | * 工具集 121 | */ 122 | static modules = [] 123 | /** 124 | * 注册工具模块 125 | */ 126 | static use(moduleItem) { 127 | // 禁用未激活的模块 128 | if (!moduleItem.isActive) return 129 | Array.isArray(moduleItem) ? moduleItem.map(item => Toolkit.use(item)) : Toolkit.modules.push(moduleItem) 130 | } 131 | /** 132 | * 触发钩子函数 133 | * @param {string}} hook 钩子函数名 134 | */ 135 | emitHook(hook) { 136 | this.log('触发钩子函数: ' + hook, Toolkit.modules.length) 137 | Toolkit.modules.map(module => module[hook] && typeof module[hook] === 'function' && module[hook](this)) 138 | } 139 | log(...args) { 140 | console.log('%c[BOSS Toolkit] LOG: ', 'color:teal', ...args) 141 | } 142 | static delay(timeout = 200) { 143 | return new Promise(resolve => setTimeout(resolve, timeout)) 144 | } 145 | static async waitDOMLoaded(domGetter, delay) { 146 | for (let times = 20; times--;) { 147 | await Toolkit.delay(delay) 148 | if (domGetter()) break 149 | } 150 | } 151 | } 152 | Toolkit.use(new SheetsToolkitModule()) 153 | Toolkit.use(new DownloadToolkitModule()) 154 | window._$BOSSToolkit = new Toolkit() 155 | document.addEventListener('readystatechange', async () => { 156 | console.log('readystatechange') 157 | // 执行所有模块的钩子函数 158 | window._$BOSSToolkit.emitHook('onload') 159 | }) 160 | })(); -------------------------------------------------------------------------------- /chinese_mooc_toolkit.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name 中国大学Mooc工具箱 3 | // @namespace http://tampermonkey.net/ 4 | // @icon https://edu-image.nosdn.127.net/32a8dd2a-b9aa-4ec9-abd5-66cd8751befb.png 5 | // @version 0.3 6 | // @description 自动切换🎬最高清晰度 | 🎨 解除页面被灰度处理 7 | // @note v0.2 fix: 修复网站源码中对于 `EventTarget.prototype.addEventListener` 的劫持导致的所有脚本触发的事件无效的问题 8 | // @note v0.3 feat: 增加课程详情页切换清晰度支持 9 | // @author Sven 10 | // @match https://www.icourse163.org/* 11 | // @grant none 12 | // @license GPL-3.0-only 13 | // ==/UserScript== 14 | 15 | (function () { 16 | 'use strict'; 17 | // @require file:///Users/sven/projects/greasy_monkey_scripts/chinese_mooc_toolkit.js 18 | class Store { 19 | static getOptions() { 20 | const options = localStorage.getItem('Chinese_Mooc_Toolkit_options') 21 | if (!options) return {} 22 | try { 23 | return JSON.parse(options) || {} 24 | } catch (err) { 25 | console.log(err) 26 | return {} 27 | } 28 | } 29 | static setOption(options) { 30 | localStorage.setItem('Chinese_Mooc_Toolkit_options', JSON.stringify(options)) 31 | } 32 | } 33 | class ToolkitModule { 34 | /** 35 | * 页面配置 36 | * @description 针对不同页面的细粒度配置, 对应页面的 URL path key 37 | */ 38 | static PAGES = { 39 | // 课程内容页 40 | content_video: { // 视频页, 这里不区分是视频还是课件页面, 因为视频和课件将在一起显示 41 | // 检测是否是当前页面 42 | pathCheck: url => url.indexOf('#/learn/content?type=detail&id=') > 0, 43 | // 允许启用的功能模块 44 | get enableModules() { return [SheetsToolkitModule, PlayerToolkitModule, EventTargetSaveToolkitModule] }, 45 | }, 46 | announce: { // 公告 47 | get enableModules() { return [SheetsToolkitModule, EventTargetSaveToolkitModule] }, 48 | }, 49 | score: { // 评分标准 50 | get enableModules() { return [SheetsToolkitModule, EventTargetSaveToolkitModule] }, 51 | }, 52 | content: { // 课件 53 | get enableModules() { return [SheetsToolkitModule, EventTargetSaveToolkitModule] }, 54 | }, 55 | testlist: { // 测试与作业 56 | get enableModules() { return [SheetsToolkitModule, EventTargetSaveToolkitModule] }, 57 | }, 58 | examlist: { // 考试 59 | get enableModules() { return [SheetsToolkitModule, EventTargetSaveToolkitModule] }, 60 | }, 61 | // 课程详情页 62 | courseForumindex: { // 讨论区 63 | // 检测是否是当前页面 64 | pathCheck: url => url.indexOf('/course/') === 0, 65 | get enableModules() { return [SheetsToolkitModule, CoverPlayerToolkitModule] }, 66 | }, 67 | } 68 | /** 69 | * 当前页类型 70 | */ 71 | static get page() { 72 | for (const p in ToolkitModule.PAGES) { 73 | const urlPath = location.pathname + location.search + location.hash 74 | const useCheckFunction = typeof ToolkitModule.PAGES[p].pathCheck === 'function' 75 | const checkResult = useCheckFunction 76 | ? ToolkitModule.PAGES[p].pathCheck(urlPath) 77 | : urlPath.indexOf('/learn/' + p) > 0 78 | if (checkResult) return ToolkitModule.PAGES[p] 79 | } 80 | } 81 | static QUALITYS = [ 82 | { key: '超高清' }, 83 | { key: '高清' }, 84 | { key: '标清' }, 85 | ] 86 | // 视频清晰度按钮组 87 | static get DOM_QUALITY_LIST() { return document.querySelector('.m-popover-quality > ul') } 88 | // 课程详情页播放按钮 89 | static get DOM_COURSE_DETAILS_PLAY_BTN() { return document.querySelector('.click-btn-wrapper .clickBtn') } 90 | // 视频当前清晰度按钮 91 | static get DOM_QUALITY_BUTTONS() { return ToolkitModule.DOM_QUALITY_LIST && ToolkitModule.DOM_QUALITY_LIST.children } 92 | onload(ctx) {} 93 | } 94 | /** 95 | * 加入自定义样式 96 | */ 97 | class SheetsToolkitModule extends ToolkitModule { 98 | static _getSheets() { 99 | return ` 100 | html { 101 | --document-filter: grayscale(0); /* #html 防止网页被黑白处理, 适用于特殊日期 */ 102 | } 103 | /* 外层全局样式 */ 104 | html { 105 | filter: var(--document-filter) !important; 106 | } 107 | /* 视频页样式 */ 108 | .u-learnBCUI { width: 100%; } 109 | .u-learnBCUI .u-select { width: auto; } 110 | .up.j-up.f-thide { background-position: right center; } 111 | .up.j-up.f-thide::after { 112 | content: ''; 113 | position: absolute; 114 | top: 38%; 115 | width: 0; 116 | height: 0; 117 | border: 4px solid transparent; 118 | border-width: 6px 5px 0 5px; 119 | border-top-color: #c6c6c6; 120 | -webkit-transition: all .3s; 121 | transition: all .3s; 122 | cursor: pointer; 123 | } 124 | .down.f-bg.j-list { width: auto !important; } 125 | /* 推荐课程, 会在暂停播放是弹出 */ 126 | .ux-modal.um-recommend-modal { display: none; } 127 | ` 128 | } 129 | init(ctx) { 130 | ctx.log('加入自定义样式') 131 | SheetsToolkitModule.appendSheets() 132 | } 133 | // 通过注入 css 实现隐藏广告并固定布局 134 | static appendSheets() { 135 | const sheet = document.createTextNode(SheetsToolkitModule._getSheets()) 136 | const el = document.createElement('style') 137 | el.id = 'handle-sheets' 138 | el.appendChild(sheet) 139 | document.getElementsByTagName('head')[0].appendChild(el) 140 | } 141 | } 142 | /** 143 | * 处理视频播放器 144 | */ 145 | class PlayerToolkitModule extends ToolkitModule { 146 | /** 147 | * 是否忽略被隐藏的清晰度选项按钮 148 | * @description 课程详情页非全屏时可能会隐藏最高清晰度选项, 视频详情页会显示全部可用的清晰度 149 | */ 150 | ignoreQualityDisplay = false 151 | init(ctx) { 152 | ctx.log('⚙ 开始修改视频清晰度') 153 | this._fixedQuality(ctx) 154 | } 155 | async _fixedQuality(ctx) { 156 | for (let times = 40; times--;) { 157 | const qualityBtnList = ToolkitModule.DOM_QUALITY_LIST 158 | await Toolkit.delay(300) 159 | if (!qualityBtnList) continue 160 | if (qualityBtnList.length === 1) break // 仅有一个清晰度时不作处理 161 | const changed = this._handleQuality(ctx) 162 | if (changed) break 163 | } 164 | } 165 | _handleQuality(ctx) { 166 | // 寻找最高清晰度 167 | ctx.highestQuality = this._findHighestQualityBtn() // 最高清晰度 168 | // 切换到最高清晰度, ⚠️ 这里需要多次调用 click(), 实测一次可能不会成功 169 | const changed = this.changeQuality(ctx) 170 | if (changed) { 171 | ctx.log('⚙ 修改视频清晰度成功') 172 | return true 173 | } else { 174 | ctx.log('⚙ 修改视频清晰度ing ...') 175 | } 176 | } 177 | /** 178 | * 寻找最高清晰度 179 | */ 180 | _findHighestQualityBtn() { 181 | let _highestQualityBtn = null 182 | for (const q of ToolkitModule.QUALITYS) { 183 | for (const d of Array.from(ToolkitModule.DOM_QUALITY_BUTTONS)) { 184 | if (d.innerHTML === q.key && (this.ignoreQualityDisplay || (!this.ignoreQualityDisplay && window.getComputedStyle(d).display !== 'none'))) { 185 | _highestQualityBtn = d 186 | break 187 | } 188 | } 189 | if (_highestQualityBtn) break 190 | } 191 | return _highestQualityBtn 192 | } 193 | /** 194 | * 点击最高清晰度按钮, 返回是否切换成功 195 | */ 196 | changeQuality(ctx) { 197 | if (!ctx.highestQuality) return 198 | ctx.quality = Array.from(ToolkitModule.DOM_QUALITY_BUTTONS).find(d => d.classList.contains('z-sel')) 199 | ctx.highestQuality.click() 200 | return ctx.quality === ctx.highestQuality 201 | } 202 | } 203 | class CoverPlayerToolkitModule extends PlayerToolkitModule { 204 | /** 205 | * 是否忽略被隐藏的清晰度选项按钮 206 | * @description 课程详情页非全屏时可能会隐藏最高清晰度选项, 视频详情页会显示全部可用的清晰度 207 | */ 208 | ignoreQualityDisplay = true 209 | async init(ctx) { 210 | for (let times = 40; times--;) { 211 | await Toolkit.delay(300) 212 | const playBtn = ToolkitModule.DOM_COURSE_DETAILS_PLAY_BTN 213 | if (!playBtn) continue 214 | playBtn.addEventListener('click', evt => { 215 | this._fixedQuality(ctx) 216 | }) 217 | break 218 | } 219 | } 220 | } 221 | class EventTargetSaveToolkitModule extends ToolkitModule { 222 | init(ctx) { 223 | ctx.log('init event target', ctx.evtTarget) 224 | ctx.evtTargetProto = EventTarget.prototype 225 | EventTarget = new Proxy(EventTarget, { 226 | get(target, p, receiver) { 227 | let value = Reflect.get(target, p, receiver) 228 | // ~~会无情的触发 read-only 报错, 请无视这个报错, 目前没有发现其他解决方案~~ 229 | if (p === 'prototype') return 230 | return value 231 | } 232 | }) 233 | } 234 | } 235 | class Toolkit { 236 | debug = true 237 | options = {} 238 | quality = null // 当前清晰度 239 | highestQuality = null // 最高清晰度 240 | constructor(options = {}) { 241 | Object.assign(this.options, options) 242 | this.emitHook('init') 243 | } 244 | /** 245 | * 工具集 246 | */ 247 | static modules = [] 248 | /** 249 | * 注册工具模块 250 | */ 251 | static use(moduleItem) { 252 | Array.isArray(moduleItem) ? moduleItem.map(item => Toolkit.use(item)) : Toolkit.modules.push(moduleItem) 253 | } 254 | /** 255 | * 触发钩子函数 256 | * @param {string}} hook 钩子函数名 257 | */ 258 | emitHook(hook) { 259 | Toolkit.modules.forEach(module => { 260 | const page = ToolkitModule.page 261 | // 未知页面不处理 262 | if (!page) return 263 | // 如果当前模块不包含在当前页面的可使用模块列表中, 就忽略这个模块 264 | if (Array.isArray(page.enableModules) && !page.enableModules.includes(module.constructor)) { 265 | // this.log('⚠️ disabled module', module.constructor && module.constructor.name) 266 | return 267 | } 268 | // this.log('🚗 enable module: ', module.constructor && module.constructor.name) 269 | if (module[hook] && typeof module[hook] === 'function') { 270 | try { 271 | module[hook](this) 272 | } catch(err) { 273 | if (err.message && err.message.indexOf(`property 'prototype' is a read-only`) > 0) return 274 | console.error(err) 275 | } 276 | } 277 | }) 278 | } 279 | log(...args) { 280 | console.log('%c[Chinese_Mooc_Toolkit] LOG: ', 'color:teal', ...args) 281 | } 282 | static delay(timeout = 200) { 283 | return new Promise(resolve => setTimeout(resolve, timeout)) 284 | } 285 | } 286 | 287 | Toolkit.use(new EventTargetSaveToolkitModule()) 288 | Toolkit.use(new CoverPlayerToolkitModule()) 289 | Toolkit.use(new SheetsToolkitModule()) 290 | Toolkit.use(new PlayerToolkitModule()) 291 | window._$Toolkit = new Toolkit() 292 | // ⚠️ 单页面应用中 onload 仅触发一次, 这里手动监听页面跳转以触发 init 事件 293 | window.addEventListener('DOMContentLoaded', () => window._$Toolkit.emitHook('onload')) 294 | window.addEventListener('hashchange', () => window._$Toolkit.emitHook('init')) 295 | })(); -------------------------------------------------------------------------------- /dark_mode.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Dark++ 3 | // @namespace http://tampermonkey.net/ 4 | // @version 1.0 5 | // @description CSS 实现夜间模式; 代码是从贴吧抄的, 嗯 ... over; 由于该实现本质上是覆盖一层, 可能会有未知问题出现: 如 sortTable.js 拖拽无效 6 | // @description v0.5 增加 file://* 协议支持 7 | // @description v0.6 通过修改 run-at: docuemnt-body 实现无感知增加遮罩层 8 | // @description v0.7 增加延迟设置, 应对延迟载入内容的页面 9 | // @description v0.8 修复因精度问题导致的透明度设置无效的问题 10 | // @description v1.0 增加亮度同步功能, 在单个页面修改后在所有页面生效 11 | // @icon https://gss0.baidu.com/7Ls0a8Sm2Q5IlBGlnYG/sys/portraith/item/feb81406?t=1435668917 12 | // @author sven 13 | // @include https://* 14 | // @include http://* 15 | // @include file://* 16 | // @match .* 17 | // @grant GM_getValue 18 | // @grant GM_setValue 19 | // @grant GM_addValueChangeListener 20 | // @run-at document-body 21 | // ==/UserScript== 22 | 23 | (function () { 24 | 'use strict'; 25 | const LOCAL_OPACITY_FIELD_NAME = 'dark_model_opacity' // 保存到本地的亮度 key 26 | const m = document.createElement('div') 27 | m.style.zIndex = '999999' 28 | m.style.position = 'absolute' 29 | m.style.height = '100vh' 30 | m.style.width = '100vw' 31 | m.style.position = 'fixed' 32 | m.style.top = '0' 33 | m.style.left = '-9999px' 34 | m.id = 'dark-modal' 35 | let opacity = GM_getValue(LOCAL_OPACITY_FIELD_NAME) || 0.4 36 | const step = 0.05 37 | const updateOpacity = opacityVal => m.style.outline = `rgba(0, 0, 0, ${opacity = opacityVal}) solid 10000px` 38 | const setOpacity = ({ opa, add, sub } = {}) => { 39 | let _opa = Number(opa || opacity) || 0 40 | _opa = add 41 | ? _opa + step 42 | : (sub ? (_opa - step) : _opa) 43 | _opa = Math.max(0, _opa) 44 | _opa = Math.min(1, _opa) 45 | GM_setValue(LOCAL_OPACITY_FIELD_NAME, _opa.toFixed(2)) 46 | console.log('%c[Dark++ plugin] %copacity: ' + _opa.toFixed(2), 'color: teal;', 'color: #FFF;') 47 | updateOpacity(_opa) 48 | } 49 | const init = () => { 50 | let delay = localStorage.getItem('DARK_PLUS_PLUS_DELAY') 51 | if (delay === null) { 52 | document.body.append(m) 53 | setOpacity() 54 | } else { 55 | delay = Number(delay) 56 | delay = (isNaN(delay) || delay < 0 || !Number.isInteger(delay)) ? 0 : delay 57 | setTimeout(() => { 58 | document.body.append(m) 59 | setOpacity() 60 | }, delay) 61 | } 62 | // 增加监听函数, 当其他页面修改亮度时在当前页面同步更新 63 | GM_addValueChangeListener(LOCAL_OPACITY_FIELD_NAME, (name, oldVal, val) => updateOpacity(val)) 64 | console.log(`%c[Dark++ plugin] delay: ${delay} | %c设置延迟载入遮罩层: %clocalStorage.setItem('DARK_PLUS_PLUS_DELAY', 200)`, 'color: teal', 'color: #FFF', 'color: #AAA') 65 | } 66 | const keyMap = { 67 | 81: () => setOpacity({ add: true }), 68 | 87: () => setOpacity({ sub: true }) 69 | } 70 | init() 71 | document.addEventListener('keydown', evt => { 72 | keyMap[evt.keyCode] && keyMap[evt.keyCode](evt) 73 | }) 74 | })(); -------------------------------------------------------------------------------- /gitea_toolkit.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Gitea 工具箱 3 | // @namespace http://gogs.yunss.com/ 4 | // @version 0.1 5 | // @description fork的子项目多分支批量合并 6 | // @author Sven 7 | // @match *://gogs.yunss.com/* 8 | // @run-at document-start 9 | // @grant none 10 | // ==/UserScript== 11 | 12 | (function () { 13 | 'use strict'; 14 | // @require file:///Users/test/projects/greasy_monkey_scripts/gitea_toolkit.js 15 | class Store { 16 | static getOptions() { 17 | const options = localStorage.getItem('GiteaToolkit_options') 18 | if (!options) return {} 19 | try { 20 | return JSON.parse(options) || {} 21 | } catch (err) { 22 | console.log(err) 23 | return {} 24 | } 25 | } 26 | static setOption(options) { 27 | localStorage.setItem('GiteaToolkit_options', JSON.stringify(options)) 28 | } 29 | } 30 | class ToolkitModule { 31 | /** 32 | * 页面元素 33 | */ 34 | static DOM_NAVBAR = null 35 | static DOM_MAIN = null 36 | static DOM_FORK_LINK = null 37 | static get DOM_BRANCH_LIST() { return document.querySelector('.ui.container .ui.stackable .menu.transition.visible .scrolling.menu') } 38 | static get INFO_USER_NAME() { const d = document.querySelector('.right.stackable.menu .ui.header strong'); return d ? d.innerText : null } 39 | static get DOM_MERGE_BTN() { return document.querySelector('#new-pull-request') } 40 | static get INFO_FORK_LINK() { const d = document.querySelector('.fork-flag > a'); return d ? d.innerText : null } 41 | static get INFO_REPOSTORY_NAME() { 42 | const nameDom = document.querySelector('.ui.huge.breadcrumb.repo-title') 43 | if (nameDom) { 44 | const titleParts = document.title 45 | return titleParts.split(' ')[0] 46 | } else { 47 | return null 48 | } 49 | } 50 | // onload () { throw new Error('must implemention') } 51 | onload(ctx) { 52 | if (ctx.debug) console.log('获取页面元素') 53 | const [navbar, main] = document.querySelectorAll('body>div:first-of-type>div') 54 | if (navbar) ToolkitModule.DOM_NAVBAR = navbar 55 | if (main) ToolkitModule.DOM_MAIN = main 56 | } 57 | } 58 | class BatchMergeBranchToolkitModule extends ToolkitModule { 59 | constructor() { super() } 60 | name = 'BatchMergeBranchToolkit' 61 | _currentBranchList = [] 62 | 63 | onload(ctx) { 64 | super.onload(ctx) 65 | if (!ToolkitModule.DOM_MERGE_BTN || !ToolkitModule.INFO_FORK_LINK) return 66 | ctx.log('获取分支列表, 显示所有分支') 67 | setTimeout(() => { 68 | this._showBranchSelector(ctx) 69 | }, 100); 70 | } 71 | _getUrlByBranchName(name) { 72 | const basePath = location.protocol + '//' + location.host + '/' 73 | const forkLink = ToolkitModule.INFO_FORK_LINK 74 | return basePath + forkLink + '/compare/' + name + '...' + ToolkitModule.INFO_USER_NAME + ':' + name 75 | } 76 | _showBranchSelector(ctx) { 77 | const branchBtn = document.querySelector('.ui.basic.small.compact.button') 78 | branchBtn.click() 79 | // 修改创建合并请求按钮 80 | ToolkitModule.DOM_MERGE_BTN.innerText = '🚗🚕🚙🚓🚑🚒 批量创建合并请求' 81 | ToolkitModule.DOM_MERGE_BTN.parentNode.href = 'javascript:;' 82 | ToolkitModule.DOM_MERGE_BTN.addEventListener('click', async evt => { 83 | evt.stopPropagation() 84 | // such as: https://gitxxxxxxxx.com/vue_web/shanshou_vue/compare/oem.food.1060...sven:yss.retail.1040.electron 85 | const urlList = [] 86 | const branches = this._getCurrentRepostorySelectedBranches() 87 | for (const b of branches) { 88 | urlList.push(this._getUrlByBranchName(b)) 89 | } 90 | for (const u of urlList) { 91 | await Toolkit.delay() 92 | window.open(u) 93 | } 94 | }) 95 | setTimeout(() => { 96 | // 处理分支数据并显示分支选择框 97 | const branchListDom = ToolkitModule.DOM_BRANCH_LIST 98 | const branchList = [] 99 | for (const b of branchListDom.children) { 100 | branchList.push(b.innerText) 101 | } 102 | this._currentBranchList = branchList 103 | branchBtn.click() 104 | branchBtn.addEventListener('click', evt => { 105 | setTimeout(() => { 106 | if (!ToolkitModule.DOM_BRANCH_LIST) return 107 | const selectedList = this._getCurrentRepostorySelectedBranches() 108 | for (const item of ToolkitModule.DOM_BRANCH_LIST.children) { 109 | const branchName = item.innerText 110 | const isSelect = selectedList.includes(branchName) 111 | const checkboxDom = document.createElement('input') 112 | checkboxDom.type = 'checkbox' 113 | checkboxDom.checked = isSelect 114 | checkboxDom.style.setProperty('width', '20px') 115 | checkboxDom.style.setProperty('height', '20px') 116 | checkboxDom.style.setProperty('float', 'left') 117 | checkboxDom.style.setProperty('cursor', 'pointer') 118 | item.appendChild(checkboxDom) 119 | checkboxDom.addEventListener('click', evt => { 120 | this._toggleBranch(evt.target.checked, evt.target.parentNode.innerText) 121 | evt.stopPropagation() 122 | }) 123 | const sendPRBtn = document.createElement('button') 124 | sendPRBtn.innerText = '创建合并请求' 125 | sendPRBtn.style.setProperty('float', 'right') 126 | sendPRBtn.style.setProperty('cursor', 'pointer') 127 | sendPRBtn.addEventListener('click', evt => { 128 | const url = this._getUrlByBranchName(branchName) 129 | window.open(url) 130 | evt.stopPropagation() 131 | }) 132 | item.appendChild(sendPRBtn) 133 | } 134 | }, 100) 135 | }) 136 | }, 100) 137 | } 138 | _getCurrentRepostorySelectedBranches() { 139 | const name = ToolkitModule.INFO_REPOSTORY_NAME 140 | const options = Store.getOptions() 141 | const selectedList = (options.selectedList && options.selectedList[name]) || [] 142 | return selectedList 143 | } 144 | _setCurrentRepostorySelectedBranches(list) { 145 | const name = ToolkitModule.INFO_REPOSTORY_NAME 146 | const options = Store.getOptions() 147 | if (!options.selectedList) options.selectedList = {} 148 | options.selectedList[name] = list 149 | Store.setOption(options) 150 | } 151 | _toggleBranch(checked, branchName) { 152 | const selectedList = this._getCurrentRepostorySelectedBranches() 153 | const index = selectedList.indexOf(branchName) 154 | if (checked && index === -1) { 155 | selectedList.push(branchName) 156 | } else if (!checked && index !== -1) { 157 | selectedList.splice(index, 1) 158 | } 159 | this._setCurrentRepostorySelectedBranches(selectedList) 160 | } 161 | } 162 | class Toolkit { 163 | debug = true 164 | options = {} 165 | constructor(options = {}) { 166 | Object.assign(this.options, options) 167 | this.emitHook('init') 168 | } 169 | /** 170 | * 工具集 171 | */ 172 | static modules = [] 173 | /** 174 | * 注册工具模块 175 | */ 176 | static use(moduleItem) { 177 | Array.isArray(moduleItem) ? moduleItem.map(item => Toolkit.use(item)) : Toolkit.modules.push(moduleItem) 178 | } 179 | /** 180 | * 触发钩子函数 181 | * @param {string}} hook 钩子函数名 182 | */ 183 | emitHook(hook) { 184 | Toolkit.modules.map(module => module[hook] && typeof module[hook] === 'function' && module[hook](this)) 185 | } 186 | log(...args) { 187 | console.log('%c[Gitea Toolkit] LOG: ', 'color:teal', ...args) 188 | } 189 | static delay(timeout = 200) { 190 | return new Promise(resolve => setTimeout(resolve, timeout)) 191 | } 192 | } 193 | 194 | Toolkit.use(new BatchMergeBranchToolkitModule()) 195 | window._$Toolkit = new Toolkit() 196 | window.addEventListener('DOMContentLoaded', () => window._$Toolkit.emitHook('onload')) 197 | })(); -------------------------------------------------------------------------------- /graphQL_toolkit.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name graphQL-toolkit 3 | // @namespace https://github.com/SublimeCT/greasy_monkey_scripts 4 | // @version 0.0.1 5 | // @description graphQL 工具脚本 💪 6 | // @note v0.0.2 记住上次的搜索内容 7 | // @note v0.0.1 使文档居左 8 | // @author Sven 9 | // @icon https://graphql.cn/img/favicon.png 10 | // @include https://* 11 | // @include http://* 12 | // @grant none 13 | // @run-at document-start 14 | // ==/UserScript== 15 | 16 | ; (() => { 17 | class ToolkitModule { 18 | constructor() { } 19 | isActive = true 20 | } 21 | class Store { 22 | static getOptions() { 23 | const options = localStorage.getItem('GraphQLToolkit_options') 24 | if (!options) return {} 25 | try { 26 | return JSON.parse(options) || {} 27 | } catch (err) { 28 | console.log(err) 29 | return {} 30 | } 31 | } 32 | static setOption(options) { 33 | localStorage.setItem('GraphQLToolkit_options', JSON.stringify(options)) 34 | } 35 | static updateOptions(options) { 36 | const allOptions = Store.getOptions() 37 | Object.assign(allOptions, options) 38 | Store.setOption(allOptions) 39 | } 40 | } 41 | /** 42 | * 使用上次的搜索内容 43 | */ 44 | class QueryToolkitModule extends ToolkitModule { 45 | init(ctx) { } 46 | static async addEventListeners() { 47 | let items 48 | for (let times = 20; times--;) { 49 | await Toolkit.delay() 50 | items = document.querySelectorAll('.graphiql-wrapper > div > div') 51 | if (items && items.length) break 52 | } 53 | if (items.length < 2) throw new Error('missing sidebar element') 54 | const sidebar = items[1] 55 | const buttons = sidebar.querySelectorAll('div:nth-child(1) > div') 56 | buttons[0].click() 57 | const apiDoms = items[items.length - 1] 58 | let searchInput 59 | for (let times = 30; times--;) { 60 | await Toolkit.delay() 61 | searchInput = apiDoms.querySelector('input[type="text"]') 62 | if (searchInput) break 63 | } 64 | // 直接使用上次搜索内容 65 | const options = Store.getOptions() 66 | if (options.query) { 67 | searchInput.value = options.query // 填充值 68 | d.setState({ searchValue: options.query }) // 直接搜索 69 | } 70 | // 绑定 input 事件记录输入值 71 | searchInput.addEventListener('input', evt => { 72 | Store.setOption({ query: evt.target.value }) 73 | }) 74 | } 75 | onload() { 76 | QueryToolkitModule.addEventListeners() 77 | } 78 | } 79 | /** 80 | * 加入自定义样式 81 | */ 82 | class SheetsToolkitModule extends ToolkitModule { 83 | static _getSheets() { 84 | return ` 85 | /* 布局样式 */ 86 | .graphiql-wrapper > div > div:last-of-type { 87 | right: auto; 88 | left: 30vw; 89 | max-width: 70vw !important; 90 | } 91 | ` 92 | } 93 | init(ctx) { 94 | // ctx.log('加入自定义样式') 95 | // SheetsToolkitModule.appendSheets() 96 | } 97 | // 通过注入 css 实现隐藏广告并固定布局 98 | static appendSheets() { 99 | const sheet = document.createTextNode(SheetsToolkitModule._getSheets()) 100 | const el = document.createElement('style') 101 | el.id = 'handle-sheets' 102 | el.appendChild(sheet) 103 | document.getElementsByTagName('head')[0].appendChild(el) 104 | } 105 | onload(ctx) { 106 | ctx.log('加入自定义样式') 107 | SheetsToolkitModule.appendSheets() 108 | // console.error('onload ????????????????') 109 | } 110 | } 111 | /** 112 | * 工具类 113 | */ 114 | class Toolkit { 115 | debug = true 116 | options = {} 117 | users = {} 118 | constructor(options = {}) { 119 | Object.assign(this.options, options) 120 | // 禁用 init, 因为必须要等到 onload 才能确定是否是 GraphQL 页面 121 | // this.emitHook('init') 122 | } 123 | /** 124 | * 工具集 125 | */ 126 | static modules = [] 127 | /** 128 | * 注册工具模块 129 | */ 130 | static use(moduleItem) { 131 | // 禁用未激活的模块 132 | if (!moduleItem.isActive) return 133 | Array.isArray(moduleItem) ? moduleItem.map(item => Toolkit.use(item)) : Toolkit.modules.push(moduleItem) 134 | } 135 | /** 136 | * 触发钩子函数 137 | * @param {string}} hook 钩子函数名 138 | */ 139 | emitHook(hook) { 140 | this.log('触发钩子函数: ' + hook, Toolkit.modules.length) 141 | Toolkit.modules.map(module => module[hook] && typeof module[hook] === 'function' && module[hook](this)) 142 | } 143 | log(...args) { 144 | console.log('%c[GraphQL Toolkit] LOG: ', 'color:teal', ...args) 145 | } 146 | static delay(timeout = 200) { 147 | return new Promise(resolve => setTimeout(resolve, timeout)) 148 | } 149 | } 150 | Toolkit.use(new SheetsToolkitModule()) 151 | Toolkit.use(new QueryToolkitModule()) 152 | window._$GraphQLToolkit = new Toolkit() 153 | window.addEventListener('DOMContentLoaded', async () => { 154 | for (let times = 10; times--;) { 155 | await Toolkit.delay() 156 | if (window.GraphQLPlayground) break 157 | } 158 | if (!window.GraphQLPlayground) return 159 | // 执行所有模块的钩子函数 160 | window._$GraphQLToolkit.emitHook('onload') 161 | }) 162 | })(); -------------------------------------------------------------------------------- /juejin_avatar_toolkit.js: -------------------------------------------------------------------------------- 1 | ;(() => { 2 | class ToolkitModule { 3 | constructor() { } 4 | isActive = true 5 | } 6 | class Store { 7 | static getOptions() { 8 | const options = localStorage.getItem('JueJinAvatarToolkit_options') 9 | if (!options) return {} 10 | try { 11 | return JSON.parse(options) || {} 12 | } catch (err) { 13 | console.log(err) 14 | return {} 15 | } 16 | } 17 | static setOption(options) { 18 | localStorage.setItem('JueJinAvatarToolkit_options', JSON.stringify(options)) 19 | } 20 | static updateOptions(options) { 21 | const allOptions = Store.getOptions() 22 | Object.assign(allOptions, options) 23 | Store.setOption(allOptions) 24 | } 25 | } 26 | /** 27 | * 增加新的点击上传按钮并绑定上传事件 28 | */ 29 | class HandleToolkitModule extends ToolkitModule { 30 | get BUTTON() { return document.querySelector('.upload-btn') } 31 | get BUTTON_WRAPPER() { return document.querySelector('.action-box') } 32 | async init(ctx) { 33 | if (ctx.options.form) return 34 | const form = document.createElement('form') 35 | form.setAttribute('enctype', 'multipart/form-data') 36 | form.style.setProperty('display', 'none') 37 | const fileField = document.createElement('input') 38 | fileField.setAttribute('type', 'file') 39 | fileField.id = ctx.options.AVATAR_INPUT_ID 40 | fileField.setAttribute('name', 'avatar') 41 | fileField.addEventListener('change', this.onFileChange.bind(this)) 42 | const aidField = document.createElement('input') 43 | aidField.setAttribute('name', 'aid') 44 | aidField.value = '2608' 45 | form.appendChild(fileField) 46 | form.appendChild(aidField) 47 | ctx.options.form = form 48 | document.body.appendChild(form) 49 | await this.waitDOMLoaded() 50 | ctx.log('BUTTON: ', this.BUTTON) 51 | if (!this.BUTTON) throw new Error('Button not found!') 52 | this._start(ctx) 53 | } 54 | onFileChange() { 55 | window._$JueJinAvatarToolkit.options.form.submit() 56 | } 57 | async waitDOMLoaded() { 58 | for (let times = 20; times--;) { 59 | await Toolkit.delay() 60 | if (this.BUTTON) break 61 | } 62 | } 63 | _start(ctx) { 64 | ctx.options.handleButton = this.BUTTON.cloneNode(true) 65 | this._addListeners(ctx.options.handleButton, ctx) 66 | 67 | this.BUTTON.style.setProperty('display', 'none') 68 | 69 | this.BUTTON_WRAPPER.appendChild(ctx.options.handleButton) 70 | // this.BUTTON.insertBefore(ctx.options.handleButton) 71 | } 72 | onload(ctx) { 73 | this._start(ctx) 74 | } 75 | _addListeners(btn, ctx) { 76 | btn.addEventListener('click', evt => { 77 | const fileInput = document.getElementById(ctx.options.AVATAR_INPUT_ID) 78 | fileInput.click() 79 | }) 80 | } 81 | } 82 | /** 83 | * 加入自定义样式 84 | */ 85 | class SheetsToolkitModule extends ToolkitModule { 86 | static _getSheets() { 87 | return ` 88 | /* 布局样式 */ 89 | .upload-btn { 90 | // display: none; 91 | } 92 | ` 93 | } 94 | init(ctx) { 95 | ctx.log('加入自定义样式') 96 | SheetsToolkitModule.appendSheets() 97 | } 98 | // 通过注入 css 实现隐藏广告并固定布局 99 | static appendSheets() { 100 | const sheet = document.createTextNode(SheetsToolkitModule._getSheets()) 101 | const el = document.createElement('style') 102 | el.id = 'handle-sheets' 103 | el.appendChild(sheet) 104 | document.getElementsByTagName('head')[0].appendChild(el) 105 | } 106 | } 107 | /** 108 | * 工具类 109 | */ 110 | class Toolkit { 111 | options = { 112 | AVATAR_INPUT_ID: 'juejin-avatar-toolkit-avatar', 113 | handleButton: null, // 新增的上传按钮 114 | form: null, // 用于上传图片的表单 115 | } 116 | constructor(options = {}) { 117 | Object.assign(this.options, options) 118 | this.emitHook('init') 119 | } 120 | /** 121 | * 工具集 122 | */ 123 | static modules = [] 124 | /** 125 | * 注册工具模块 126 | */ 127 | static use(moduleItem) { 128 | // 禁用未激活的模块 129 | if (!moduleItem.isActive) return 130 | Array.isArray(moduleItem) ? moduleItem.map(item => Toolkit.use(item)) : Toolkit.modules.push(moduleItem) 131 | } 132 | /** 133 | * 触发钩子函数 134 | * @param {string}} hook 钩子函数名 135 | */ 136 | emitHook(hook) { 137 | this.log('触发钩子函数: ' + hook, Toolkit.modules.length) 138 | Toolkit.modules.map(module => module[hook] && typeof module[hook] === 'function' && module[hook](this)) 139 | } 140 | log(...args) { 141 | console.log('%c[JueJinAvatar Toolkit] LOG: ', 'color:teal', ...args) 142 | } 143 | static delay(timeout = 200) { 144 | return new Promise(resolve => setTimeout(resolve, timeout)) 145 | } 146 | } 147 | Toolkit.use(new SheetsToolkitModule()) 148 | Toolkit.use(new HandleToolkitModule()) 149 | window._$JueJinAvatarToolkit = new Toolkit() 150 | })(); -------------------------------------------------------------------------------- /mkv.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | ; (() => { 3 | const SCRIPT_KEY = 'mkv_toolkit' 4 | class ToolkitModule { 5 | constructor() { } 6 | isActive = true 7 | /** 8 | * create DOM 9 | * @param {string} tagName 10 | * @param {string} id 11 | * @param {object} param2 12 | * @returns {Element} dom 13 | */ 14 | createElement(tagName, id, { classList, props, sheets, innerText } = {}) { 15 | const dom = document.createElement(tagName) 16 | if (id) dom.id = id 17 | if (Array.isArray(classList)) { 18 | for (const c of classList) { 19 | dom.classList.add(c) 20 | } 21 | } 22 | if (props) { 23 | for (const p in props) { 24 | dom.setAttribute(p, props[p]) 25 | } 26 | } 27 | if (sheets) { 28 | for (const s in sheets) { 29 | dom.style.setProperty(s, sheets[s]) 30 | } 31 | } 32 | if (innerText) dom.innerText = innerText 33 | return dom 34 | } 35 | } 36 | class Sheets { 37 | static append(key, sheets) { 38 | const sheet = document.createTextNode(sheets) 39 | const el = document.createElement('style') 40 | el.id = SCRIPT_KEY + '_' + key 41 | el.appendChild(sheet) 42 | document.head.appendChild(el) 43 | } 44 | } 45 | /** 46 | * SearchUI 47 | */ 48 | class SearchUIModule extends ToolkitModule { 49 | constructor() { super() } 50 | get isActive() { return location.href.indexOf('http://www.mtv-ktv.net/v/pan.asp') === 0 || location.href.indexOf('http://www.mtv-ktv.com/v/pan.asp') === 0 } 51 | init(ctx) { 52 | } 53 | async onload(ctx) { 54 | $.getJSON = url => { 55 | const command = `curl '${url}' -H 'Accept: application/json, text/javascript, */*; q=0.01' -H 'Referer: ${location.href}' -H 'User-Agent: ${navigator.userAgent.replace(/\d/, Math.random())}'` 56 | const timeDOM = document.querySelector('.fs--1.mb-1') 57 | timeDOM.id = 'command-curl' 58 | timeDOM.innerText = command 59 | this.toCopyText(command) 60 | throw new Error('已生成 curl 命令') 61 | } 62 | for (let times = 40; times--;) { 63 | const downloadDOM = document.querySelector('.btn.btn-outline-secondary.fs--1') 64 | await Toolkit.delay(300) 65 | if (!downloadDOM) continue 66 | downloadDOM.click() 67 | break 68 | } 69 | for (let times = 40; times--;) { 70 | const textareaFormDOM = document.querySelector('form#register-form') 71 | await Toolkit.delay(300) 72 | if (!textareaFormDOM) continue 73 | this.includeTextarea(textareaFormDOM) 74 | break 75 | } 76 | } 77 | toCopyText(text) { 78 | var tag = document.createElement('input') 79 | tag.setAttribute('id', 'cp_hgz_input') 80 | tag.value = text 81 | document.getElementsByTagName('body')[0].appendChild(tag) 82 | document.getElementById('cp_hgz_input').select() 83 | document.execCommand('copy') 84 | document.getElementById('cp_hgz_input').remove() 85 | } 86 | includeTextarea(textareaFormDOM) { 87 | textareaFormDOM.innerHTML = '' 88 | const textarea = this.createElement('textarea', 'response', { sheets: { width: '100%', height: '100%' } }) 89 | const downloadLink = this.createElement('a', 'download-link') 90 | const wgetCommand = this.createElement('textarea', 'wget-command', { sheets: { width: '100%', height: '200px' } }) 91 | downloadLink.setAttribute('href', 'javascript:;') 92 | downloadLink.setAttribute('target', '_blank') 93 | downloadLink.innerText = '等待解析下载地址' 94 | textarea.addEventListener('paste', e => { 95 | const responseClipboard = e.clipboardData || window.clipboardData 96 | const response = responseClipboard.getData('Text') 97 | let downloadURL = '' 98 | const res = JSON.parse(response) 99 | downloadURL = res.downurl 100 | console.log(downloadURL, res) 101 | if (downloadURL) { 102 | downloadLink.setAttribute('href', downloadURL) 103 | wgetCommand.value = this.getWgetCommand(downloadURL) 104 | } 105 | }) 106 | textareaFormDOM.appendChild(textarea) 107 | textareaFormDOM.appendChild(downloadLink) 108 | textareaFormDOM.appendChild(wgetCommand) 109 | } 110 | getWgetCommand(downloadURL) { 111 | const fileName = document.title.replace(/\.mkv\s.*/, '.mkv') 112 | return `wget -O '${fileName}' '${downloadURL}'` 113 | } 114 | } 115 | 116 | /** 117 | * to download url 118 | */ 119 | class ToDownloadPageModule extends ToolkitModule { 120 | constructor() { super() } 121 | get isActive() { return location.href.indexOf('http://www.mtv-ktv.net/v/ctfile.asp') === 0 || location.href.indexOf('http://www.mtv-ktv.com/v/ctfile.asp') === 0 } 122 | sheets = ` 123 | .oset > a { display: none; } 124 | .oset > span { cursor: pointer; } 125 | ` 126 | init(ctx) {} 127 | async onload(ctx) { 128 | Sheets.append('download', this.sheets) 129 | for (let times = 30; times--;) { 130 | const rows = document.querySelectorAll('.oset') 131 | await Toolkit.delay(300) 132 | if (!rows) continue 133 | this.appendDownloadLink() 134 | break 135 | } 136 | } 137 | appendDownloadLink() { 138 | const rows = document.querySelectorAll('.oset') 139 | if (!rows) return 140 | for (const r of Array.from(rows)) { 141 | const rowDOM = this.createElement('span', undefined, { classList: ['row-link'], innerText: '下载' }) 142 | rowDOM.addEventListener('click', async evt => { 143 | const link = evt.target.previousSibling 144 | if (!link) return 145 | let downloadURL = link.getAttribute('data-download-url') 146 | if (!link.getAttribute('data-download-url')) { 147 | downloadURL = await this.toDownloadPage(link.href) 148 | link.setAttribute('data-download-url', downloadURL) 149 | link.setAttribute('href', downloadURL) 150 | } 151 | if (downloadURL) link.click() 152 | }) 153 | r.appendChild(rowDOM) 154 | } 155 | } 156 | async toDownloadPage(url) { 157 | const res = await fetch(url, { method: 'GET' }) 158 | const rawText = await res.text() 159 | // href="https://mvxzjl.ctfile.com/fs/ 160 | const matches = rawText.match(/href\=\"(https:\/\/mvxzjl\.ctfile\.com\/fs\/[\d\-]*)"/) 161 | return matches[1] 162 | } 163 | } 164 | 165 | /** 166 | * n456 pan page 167 | */ 168 | class DownloadPanModule extends ToolkitModule { 169 | constructor() { super() } 170 | get isActive() { return location.href.indexOf('https://n459.com/file/') === 0 || location.href.indexOf('https://tv5.us/file') === 0 || location.href.indexOf('https://545c.com/file') === 0 } 171 | init(ctx) { 172 | const songList = this.createElement('div', 'sont-list', { 173 | sheets: { 174 | width: '20px', 175 | height: '95vh', 176 | position: 'fixed', 177 | top: '0', 178 | left: '0', 179 | // 'background-color': 'teal' 180 | } 181 | }) 182 | document.body.appendChild(songList) 183 | } 184 | onload(ctx) { 185 | ctx.log('onload') 186 | } 187 | } 188 | 189 | class MvxzModule extends ToolkitModule { 190 | constructor() { super() } 191 | get isActive() { return location.href.indexOf('http://mvxz.com/imv.asp') === 0 } 192 | init() {} 193 | async onload(ctx) { 194 | for (let times = 40; times--;) { 195 | const btn = document.querySelector('.button.special.fit.icon.fa-download') 196 | await Toolkit.delay(300) 197 | if (!btn) continue 198 | btn.setAttribute('href', 'javascript:;') 199 | break 200 | } 201 | } 202 | } 203 | 204 | /** 205 | * 工具类 206 | */ 207 | class Toolkit { 208 | debug = true 209 | options = {} 210 | users = {} 211 | constructor(options = {}) { 212 | Object.assign(this.options, options) 213 | this.emitHook('init') 214 | } 215 | /** 216 | * 工具集 217 | */ 218 | static modules = [] 219 | /** 220 | * 注册工具模块 221 | */ 222 | static use(moduleItem) { 223 | // 禁用未激活的模块 224 | if (!moduleItem.isActive) return 225 | Array.isArray(moduleItem) ? moduleItem.map(item => Toolkit.use(item)) : Toolkit.modules.push(moduleItem) 226 | } 227 | /** 228 | * 触发钩子函数 229 | * @param {string} hook 钩子函数名 230 | */ 231 | emitHook(hook) { 232 | this.log('触发钩子函数: ' + hook, Toolkit.modules.length) 233 | Toolkit.modules.map(module => module[hook] && typeof module[hook] === 'function' && module[hook](this)) 234 | } 235 | log(...args) { 236 | console.log('%c[MKV Toolkit] LOG: ', 'color:teal', ...args) 237 | } 238 | static delay(timeout = 200) { 239 | return new Promise(resolve => setTimeout(resolve, timeout)) 240 | } 241 | } 242 | Toolkit.use(new SearchUIModule()) 243 | Toolkit.use(new ToDownloadPageModule()) 244 | Toolkit.use(new DownloadPanModule()) 245 | Toolkit.use(new MvxzModule()) 246 | window._$MKVToolkit = new Toolkit() 247 | window.addEventListener('DOMContentLoaded', () => window._$MKVToolkit.emitHook('onload')) 248 | })(); -------------------------------------------------------------------------------- /mobile_cleaner.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name 🥊 百度手机端自动展开搜索结果 3 | // @namespace SublimeCT 4 | // @icon https://www.mycodes.net/favicon.ico 5 | // @version 1.0.2 6 | // @description ⚡️ 自动展开被百度折叠的搜索结果 | 🥊 禁止所有提示下载 APP 的行为 7 | // @note v1.0.1 在 isEnable 判断中加入 www.baidu.com 域名 8 | // @note v1.0.2 BaiduIndex 加入百家号页面判断 9 | // @author Sven 10 | // @homepage https://github.com/SublimeCT/greasy_monkey_scripts 11 | // @supportURL https://github.com/SublimeCT/greasy_monkey_scripts/issues 12 | // @match *://*baidu.com* 13 | // @include *://*baidu.com* 14 | // @grant none 15 | // @license GPL-3.0-only 16 | // @run-at document-start 17 | // ==/UserScript== 18 | 19 | ; (() => { 20 | const SCRIPT_KEY = 'mobile_cleaner' 21 | class ToolkitModule { 22 | key = '' 23 | static isMobile = /Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent) 24 | constructor() { } 25 | isEnable(evtName) { throw new Error('You must override isEnable attributes') } 26 | } 27 | class Sheets { 28 | static append(key, sheets) { 29 | const sheet = document.createTextNode(sheets) 30 | const el = document.createElement('style') 31 | el.id = SCRIPT_KEY + '_' + key 32 | el.appendChild(sheet) 33 | document.head.appendChild(el) 34 | } 35 | } 36 | /** 37 | * 展开百度搜索文章页 38 | */ 39 | class CleanBaiduArticleModule extends ToolkitModule { 40 | key = 'CleanBaiduArticle' 41 | constructor() { super() } 42 | sheets = ` 43 | /* 44 | * 45 | * 展开百度搜索文章页 46 | * 2020-04-25 11:22:31 47 | * 48 | */ 49 | /* 展开更多搜索结果按钮 */ .mainContent { height: auto !important; } 50 | /* 点击展开全文 */ .packupButton, 51 | /* open APP */ .commentEmbed-backHomeCard, 52 | /* open APP */ a[data-bdlog=news_interest] > div > span:first-child 53 | { display: none !important; } 54 | ` 55 | isEnable(evtName) { 56 | return ToolkitModule.isMobile && (location.origin === 'https://mbd.baidu.com' || location.origin.indexOf('baijiahao') > 0 || location.pathname.indexOf('baijiahao') > 0) 57 | } 58 | init(ctx) { 59 | Sheets.append(this.key, this.sheets) 60 | } 61 | onload(ctx) { 62 | ctx.loopUntil(() => { 63 | const relateLinks = document.querySelectorAll('a.relateFont') 64 | if (relateLinks && relateLinks.length) { 65 | for (const link of relateLinks) { 66 | link.parentNode.innerHTML = link.parentNode.innerHTML 67 | } 68 | return true 69 | } 70 | })() 71 | } 72 | } 73 | /** 74 | * 展开百度搜索首页 75 | */ 76 | class CleanBaiduIndexModule extends ToolkitModule { 77 | key = 'CleanBaiduIndex' 78 | constructor() { super() } 79 | sheets = ` 80 | /* 81 | * 82 | * 搜索首页 83 | * 2020-04-25 11:22:31 84 | * 85 | */ 86 | /* 展开更多搜索结果按钮 */ .index-banner 87 | { display: none !important; } 88 | ` 89 | isEnable(evtName) { 90 | return ToolkitModule.isMobile && 91 | (location.origin === 'https://m.baidu.com' || location.origin === 'https://www.baidu.com') && 92 | location.pathname === '/' 93 | } 94 | init(ctx) { 95 | Sheets.append(this.key, this.sheets) 96 | } 97 | } 98 | /** 99 | * 展开百度搜索结果 100 | */ 101 | class CleanBaiduSearchModule extends ToolkitModule { 102 | key = 'CleanBaiduSearch' 103 | constructor() { super() } 104 | sheets = ` 105 | /* 106 | * 搜索结果页 107 | * 2020-04-25 11:22:31 108 | */ 109 | /* 展开更多搜索结果按钮 */ 110 | .hint-fold-results-wrapper { height: auto: !important; } 111 | /* 展开更多搜索结果背景 */ 112 | .hint-fold-results-wrapper > .hint-fold-results-box { display: none !important; } 113 | /* 显示相关搜索box */ 114 | .se-page-relative { display: block !important; } 115 | /* 显示翻页按钮 */ 116 | .se-page-controller { display: block !important; } 117 | /* 仅显示底部LOGO部分 */ 118 | #page-copyright > div:not([m-name=logo]):not(#copyright) { display: none !important; } 119 | 120 | /* 相关搜索 */ #relativewords .c-line-clamp1, 121 | /* 其他人还在搜 */ .c-invoke-willshow-class, 122 | /* 前往百度 APP 提示 */ #popupLead, 123 | /* 影响浏览体验的底部弹窗 */ .egg-bubble, 124 | /* 填问卷, 赢大奖? 呵呵 */ .se-ft-promlink 125 | { display: none !important; } 126 | ` 127 | isEnable(evtName) { 128 | return ToolkitModule.isMobile && 129 | (location.origin === 'https://m.baidu.com' || location.origin === 'https://www.baidu.com') && 130 | location.pathname.indexOf('/s') !== -1 && 131 | location.search.indexOf('word=') > 0 132 | } 133 | init(ctx) { 134 | Sheets.append(this.key, this.sheets) 135 | } 136 | } 137 | /** 138 | * 工具类 139 | */ 140 | class Toolkit { 141 | debug = true 142 | options = {} 143 | constructor(options = {}) { 144 | Object.assign(this.options, options) 145 | this.emitHook('init') 146 | } 147 | /** 148 | * 工具集 149 | */ 150 | static modules = [] 151 | /** 152 | * 注册工具模块 153 | */ 154 | static use(moduleItem) { 155 | Array.isArray(moduleItem) ? moduleItem.map(item => Toolkit.use(item)) : Toolkit.modules.push(moduleItem) 156 | } 157 | /** 158 | * 触发钩子函数 159 | * @param {string}} hook 钩子函数名 160 | */ 161 | emitHook(hook) { 162 | this.log('触发钩子函数: ' + hook) 163 | Toolkit.modules.forEach(module => { 164 | const isEnable = module.isEnable(hook) 165 | if (isEnable) this.log(module.key + ' launch') 166 | isEnable && module[hook] && typeof module[hook] === 'function' && module[hook](this) 167 | }) 168 | } 169 | log(...args) { 170 | console.log('%c[Mobile Cleaner] LOG: ', 'color:teal', ...args) 171 | } 172 | static delay(timeout = 200) { 173 | return new Promise(resolve => setTimeout(resolve, timeout)) 174 | } 175 | loopUntil(fun, times = 30, timeout = 300) { 176 | return function () { 177 | const interval = setInterval(() => { 178 | const res = fun() 179 | // 到达最大执行次数或函数主体返回 true 则停止执行 180 | if ((--times <= 0) || res) clearInterval(interval) 181 | }, timeout); 182 | } 183 | } 184 | } 185 | Toolkit.use(new CleanBaiduSearchModule()) 186 | Toolkit.use(new CleanBaiduArticleModule()) 187 | Toolkit.use(new CleanBaiduIndexModule()) 188 | // Toolkit.use(new BlockShitApkModule()) 189 | // Toolkit.use(new AllowBackModule()) 190 | // Toolkit.use(new BlockOpenAppModule()) 191 | window._$MobileCleanerToolkit = new Toolkit() 192 | window.addEventListener('DOMContentLoaded', () => window._$MobileCleanerToolkit.emitHook('onload')) 193 | })(); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "greasy_monkey_scripts", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "repository": "git@github.com:SublimeCT/greasy_monkey_scripts.git", 6 | "author": "sven ", 7 | "license": "MIT", 8 | "config": { 9 | "commitizen": { 10 | "path": "./node_modules/cz-conventional-changelog" 11 | } 12 | }, 13 | "devDependencies": { 14 | "commitizen": "^4.0.3", 15 | "cz-conventional-changelog": "^3.0.2" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /pagination.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name 翻页助手 3 | // @namespace http://tampermonkey.net/ 4 | // @version 0.1 5 | // @description try to take over the world! 6 | // @author sven 7 | // @include https://* 8 | // @include http://* 9 | // @include file://* 10 | // @match .* 11 | // @grant none 12 | // ==/UserScript== 13 | 14 | (function () { 15 | 'use strict'; 16 | // @require file:///Users/test/projects/greasy_monkey_scripts/pagination.js 17 | /** 18 | * 用于翻页的元素的选择器集合 19 | */ 20 | const classSelector = { 21 | prev: [ 22 | '.prev', '.btn-prev', '.previous', '.btn-previous', '.prev-page', '.previous-page', '.pager-item-left', 23 | '#prev', '#btn-prev', '#previous', '#btn-previous', '#prev-page', '#previous-page', '#pager-item-left', 24 | // baidu.com 25 | '.n', 26 | ], 27 | next: [ 28 | '.next', '.btn-next', '.next-page', '.pager-item-right', 29 | '#next', '#btn-next', '#next-page', '#pager-item-right', 30 | // baidu.com 31 | '.n', 32 | ] 33 | } 34 | /** 35 | * 所有的翻页元素匹配的 innerText 内容集合 36 | */ 37 | const textList = { 38 | prev: ['<', '‹', 'previous', 'prev', '上一页', '上一页>', 'previouspostslink', '上页', '上一章', '上章', '<上一页', '«'], 39 | next: ['>', '›', 'next', '下一页', '下一页>', 'nextpostslink', '下页', '下一章', '下章', '<下一页', '»'], 40 | } 41 | /** 42 | * 若匹配到的翻页元素内存在 , 则使用该内容模糊匹配 43 | */ 44 | const iconClassPartList = { 45 | prev: ['angle-left', 'left', 'arrow-left'], 46 | next: ['angle-right', 'right', 'arrow-right'], 47 | } 48 | window.PaginationToolkit = { 49 | init () { 50 | const prev = document.createElement('button') 51 | const next = document.createElement('button') 52 | prev.style.display = next.style.display = 'none' 53 | prev.setAttribute('id', 'PaginationToolkit-prev') 54 | next.setAttribute('id', 'PaginationToolkit-next') 55 | prev.addEventListener('click', evt => this.prev()) 56 | next.addEventListener('click', evt => this.next()) 57 | document.body.appendChild(prev) 58 | document.body.appendChild(next) 59 | }, 60 | trigger(type = 'next') { 61 | // 获取可能的翻页元素 62 | const selector = classSelector[type].join(',') + ',' + textList[type].map(t => `[title="${t}"]`).join(',') 63 | let elements = document.querySelectorAll(selector) 64 | console.log(selector, elements) 65 | if (!elements.length === 0) { console.warn('%c[pagination toolkit] %cprev element not found', 'color: teal', 'color: red'); return } 66 | for (const el of elements) { 67 | if (el.children.length && el.children[0].tagName === 'I') { 68 | const childClassName = Array.from(el.children[0].classList).join(' ') 69 | for (const part of iconClassPartList[type]) { 70 | if (childClassName.indexOf(part) !== -1) { 71 | el.click() 72 | console.warn('%c[pagination toolkit] %cexists handle icon child', 'color: teal', 'color: cyan') 73 | break 74 | } 75 | } 76 | } 77 | const elText = el.innerText 78 | if (textList[type].includes(elText)) { 79 | el.click() 80 | console.warn('%c[pagination toolkit] %cexists handle element', 'color: teal', 'color: cyan') 81 | break 82 | } 83 | } 84 | }, 85 | prev() { this.trigger('prev') }, 86 | next() { this.trigger() } 87 | } 88 | window.PaginationToolkit.init() 89 | })(); -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | devDependencies: 11 | commitizen: 12 | specifier: ^4.0.3 13 | version: 4.3.1(@types/node@22.13.10)(typescript@5.8.2) 14 | cz-conventional-changelog: 15 | specifier: ^3.0.2 16 | version: 3.3.0(@types/node@22.13.10)(typescript@5.8.2) 17 | 18 | packages: 19 | 20 | '@babel/code-frame@7.26.2': 21 | resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} 22 | engines: {node: '>=6.9.0'} 23 | 24 | '@babel/helper-validator-identifier@7.25.9': 25 | resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} 26 | engines: {node: '>=6.9.0'} 27 | 28 | '@commitlint/config-validator@19.8.0': 29 | resolution: {integrity: sha512-+r5ZvD/0hQC3w5VOHJhGcCooiAVdynFlCe2d6I9dU+PvXdV3O+fU4vipVg+6hyLbQUuCH82mz3HnT/cBQTYYuA==} 30 | engines: {node: '>=v18'} 31 | 32 | '@commitlint/execute-rule@19.8.0': 33 | resolution: {integrity: sha512-fuLeI+EZ9x2v/+TXKAjplBJWI9CNrHnyi5nvUQGQt4WRkww/d95oVRsc9ajpt4xFrFmqMZkd/xBQHZDvALIY7A==} 34 | engines: {node: '>=v18'} 35 | 36 | '@commitlint/load@19.8.0': 37 | resolution: {integrity: sha512-4rvmm3ff81Sfb+mcWT5WKlyOa+Hd33WSbirTVUer0wjS1Hv/Hzr07Uv1ULIV9DkimZKNyOwXn593c+h8lsDQPQ==} 38 | engines: {node: '>=v18'} 39 | 40 | '@commitlint/resolve-extends@19.8.0': 41 | resolution: {integrity: sha512-CLanRQwuG2LPfFVvrkTrBR/L/DMy3+ETsgBqW1OvRxmzp/bbVJW0Xw23LnnExgYcsaFtos967lul1CsbsnJlzQ==} 42 | engines: {node: '>=v18'} 43 | 44 | '@commitlint/types@19.8.0': 45 | resolution: {integrity: sha512-LRjP623jPyf3Poyfb0ohMj8I3ORyBDOwXAgxxVPbSD0unJuW2mJWeiRfaQinjtccMqC5Wy1HOMfa4btKjbNxbg==} 46 | engines: {node: '>=v18'} 47 | 48 | '@types/conventional-commits-parser@5.0.1': 49 | resolution: {integrity: sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==} 50 | 51 | '@types/node@22.13.10': 52 | resolution: {integrity: sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==} 53 | 54 | ajv@8.17.1: 55 | resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} 56 | 57 | ansi-escapes@4.3.2: 58 | resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} 59 | engines: {node: '>=8'} 60 | 61 | ansi-regex@5.0.1: 62 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 63 | engines: {node: '>=8'} 64 | 65 | ansi-styles@3.2.1: 66 | resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} 67 | engines: {node: '>=4'} 68 | 69 | ansi-styles@4.3.0: 70 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 71 | engines: {node: '>=8'} 72 | 73 | argparse@2.0.1: 74 | resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} 75 | 76 | at-least-node@1.0.0: 77 | resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} 78 | engines: {node: '>= 4.0.0'} 79 | 80 | balanced-match@1.0.2: 81 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 82 | 83 | base64-js@1.5.1: 84 | resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} 85 | 86 | bl@4.1.0: 87 | resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} 88 | 89 | brace-expansion@1.1.11: 90 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 91 | 92 | braces@3.0.3: 93 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} 94 | engines: {node: '>=8'} 95 | 96 | buffer@5.7.1: 97 | resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} 98 | 99 | cachedir@2.3.0: 100 | resolution: {integrity: sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==} 101 | engines: {node: '>=6'} 102 | 103 | callsites@3.1.0: 104 | resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} 105 | engines: {node: '>=6'} 106 | 107 | chalk@2.4.2: 108 | resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} 109 | engines: {node: '>=4'} 110 | 111 | chalk@4.1.2: 112 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 113 | engines: {node: '>=10'} 114 | 115 | chalk@5.4.1: 116 | resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} 117 | engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} 118 | 119 | chardet@0.7.0: 120 | resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} 121 | 122 | cli-cursor@3.1.0: 123 | resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} 124 | engines: {node: '>=8'} 125 | 126 | cli-spinners@2.9.2: 127 | resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} 128 | engines: {node: '>=6'} 129 | 130 | cli-width@3.0.0: 131 | resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} 132 | engines: {node: '>= 10'} 133 | 134 | clone@1.0.4: 135 | resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} 136 | engines: {node: '>=0.8'} 137 | 138 | color-convert@1.9.3: 139 | resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} 140 | 141 | color-convert@2.0.1: 142 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 143 | engines: {node: '>=7.0.0'} 144 | 145 | color-name@1.1.3: 146 | resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} 147 | 148 | color-name@1.1.4: 149 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 150 | 151 | commitizen@4.3.1: 152 | resolution: {integrity: sha512-gwAPAVTy/j5YcOOebcCRIijn+mSjWJC+IYKivTu6aG8Ei/scoXgfsMRnuAk6b0GRste2J4NGxVdMN3ZpfNaVaw==} 153 | engines: {node: '>= 12'} 154 | hasBin: true 155 | 156 | concat-map@0.0.1: 157 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 158 | 159 | conventional-commit-types@3.0.0: 160 | resolution: {integrity: sha512-SmmCYnOniSsAa9GqWOeLqc179lfr5TRu5b4QFDkbsrJ5TZjPJx85wtOr3zn+1dbeNiXDKGPbZ72IKbPhLXh/Lg==} 161 | 162 | cosmiconfig-typescript-loader@6.1.0: 163 | resolution: {integrity: sha512-tJ1w35ZRUiM5FeTzT7DtYWAFFv37ZLqSRkGi2oeCK1gPhvaWjkAtfXvLmvE1pRfxxp9aQo6ba/Pvg1dKj05D4g==} 164 | engines: {node: '>=v18'} 165 | peerDependencies: 166 | '@types/node': '*' 167 | cosmiconfig: '>=9' 168 | typescript: '>=5' 169 | 170 | cosmiconfig@9.0.0: 171 | resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} 172 | engines: {node: '>=14'} 173 | peerDependencies: 174 | typescript: '>=4.9.5' 175 | peerDependenciesMeta: 176 | typescript: 177 | optional: true 178 | 179 | cz-conventional-changelog@3.3.0: 180 | resolution: {integrity: sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw==} 181 | engines: {node: '>= 10'} 182 | 183 | dedent@0.7.0: 184 | resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} 185 | 186 | defaults@1.0.4: 187 | resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} 188 | 189 | detect-file@1.0.0: 190 | resolution: {integrity: sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==} 191 | engines: {node: '>=0.10.0'} 192 | 193 | detect-indent@6.1.0: 194 | resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} 195 | engines: {node: '>=8'} 196 | 197 | emoji-regex@8.0.0: 198 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 199 | 200 | env-paths@2.2.1: 201 | resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} 202 | engines: {node: '>=6'} 203 | 204 | error-ex@1.3.2: 205 | resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} 206 | 207 | escape-string-regexp@1.0.5: 208 | resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} 209 | engines: {node: '>=0.8.0'} 210 | 211 | expand-tilde@2.0.2: 212 | resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==} 213 | engines: {node: '>=0.10.0'} 214 | 215 | external-editor@3.1.0: 216 | resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} 217 | engines: {node: '>=4'} 218 | 219 | fast-deep-equal@3.1.3: 220 | resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} 221 | 222 | fast-uri@3.0.6: 223 | resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} 224 | 225 | figures@3.2.0: 226 | resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} 227 | engines: {node: '>=8'} 228 | 229 | fill-range@7.1.1: 230 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} 231 | engines: {node: '>=8'} 232 | 233 | find-node-modules@2.1.3: 234 | resolution: {integrity: sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg==} 235 | 236 | find-root@1.1.0: 237 | resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} 238 | 239 | findup-sync@4.0.0: 240 | resolution: {integrity: sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==} 241 | engines: {node: '>= 8'} 242 | 243 | fs-extra@9.1.0: 244 | resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} 245 | engines: {node: '>=10'} 246 | 247 | fs.realpath@1.0.0: 248 | resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} 249 | 250 | glob@7.2.3: 251 | resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} 252 | deprecated: Glob versions prior to v9 are no longer supported 253 | 254 | global-directory@4.0.1: 255 | resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} 256 | engines: {node: '>=18'} 257 | 258 | global-modules@1.0.0: 259 | resolution: {integrity: sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==} 260 | engines: {node: '>=0.10.0'} 261 | 262 | global-prefix@1.0.2: 263 | resolution: {integrity: sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==} 264 | engines: {node: '>=0.10.0'} 265 | 266 | graceful-fs@4.2.11: 267 | resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} 268 | 269 | has-flag@3.0.0: 270 | resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} 271 | engines: {node: '>=4'} 272 | 273 | has-flag@4.0.0: 274 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 275 | engines: {node: '>=8'} 276 | 277 | homedir-polyfill@1.0.3: 278 | resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} 279 | engines: {node: '>=0.10.0'} 280 | 281 | iconv-lite@0.4.24: 282 | resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} 283 | engines: {node: '>=0.10.0'} 284 | 285 | ieee754@1.2.1: 286 | resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} 287 | 288 | import-fresh@3.3.1: 289 | resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} 290 | engines: {node: '>=6'} 291 | 292 | import-meta-resolve@4.1.0: 293 | resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} 294 | 295 | inflight@1.0.6: 296 | resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} 297 | deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. 298 | 299 | inherits@2.0.4: 300 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 301 | 302 | ini@1.3.8: 303 | resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} 304 | 305 | ini@4.1.1: 306 | resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} 307 | engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} 308 | 309 | inquirer@8.2.5: 310 | resolution: {integrity: sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==} 311 | engines: {node: '>=12.0.0'} 312 | 313 | is-arrayish@0.2.1: 314 | resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} 315 | 316 | is-extglob@2.1.1: 317 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 318 | engines: {node: '>=0.10.0'} 319 | 320 | is-fullwidth-code-point@3.0.0: 321 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 322 | engines: {node: '>=8'} 323 | 324 | is-glob@4.0.3: 325 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 326 | engines: {node: '>=0.10.0'} 327 | 328 | is-interactive@1.0.0: 329 | resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} 330 | engines: {node: '>=8'} 331 | 332 | is-number@7.0.0: 333 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 334 | engines: {node: '>=0.12.0'} 335 | 336 | is-unicode-supported@0.1.0: 337 | resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} 338 | engines: {node: '>=10'} 339 | 340 | is-utf8@0.2.1: 341 | resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==} 342 | 343 | is-windows@1.0.2: 344 | resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} 345 | engines: {node: '>=0.10.0'} 346 | 347 | isexe@2.0.0: 348 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 349 | 350 | jiti@2.4.2: 351 | resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} 352 | hasBin: true 353 | 354 | js-tokens@4.0.0: 355 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 356 | 357 | js-yaml@4.1.0: 358 | resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} 359 | hasBin: true 360 | 361 | json-parse-even-better-errors@2.3.1: 362 | resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} 363 | 364 | json-schema-traverse@1.0.0: 365 | resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} 366 | 367 | jsonfile@6.1.0: 368 | resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} 369 | 370 | lines-and-columns@1.2.4: 371 | resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} 372 | 373 | lodash.isplainobject@4.0.6: 374 | resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} 375 | 376 | lodash.map@4.6.0: 377 | resolution: {integrity: sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==} 378 | 379 | lodash.merge@4.6.2: 380 | resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} 381 | 382 | lodash.mergewith@4.6.2: 383 | resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} 384 | 385 | lodash.uniq@4.5.0: 386 | resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} 387 | 388 | lodash@4.17.21: 389 | resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} 390 | 391 | log-symbols@4.1.0: 392 | resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} 393 | engines: {node: '>=10'} 394 | 395 | longest@2.0.1: 396 | resolution: {integrity: sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==} 397 | engines: {node: '>=0.10.0'} 398 | 399 | merge@2.1.1: 400 | resolution: {integrity: sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==} 401 | 402 | micromatch@4.0.8: 403 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} 404 | engines: {node: '>=8.6'} 405 | 406 | mimic-fn@2.1.0: 407 | resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} 408 | engines: {node: '>=6'} 409 | 410 | minimatch@3.1.2: 411 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 412 | 413 | minimist@1.2.7: 414 | resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} 415 | 416 | mute-stream@0.0.8: 417 | resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} 418 | 419 | once@1.4.0: 420 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 421 | 422 | onetime@5.1.2: 423 | resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} 424 | engines: {node: '>=6'} 425 | 426 | ora@5.4.1: 427 | resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} 428 | engines: {node: '>=10'} 429 | 430 | os-tmpdir@1.0.2: 431 | resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} 432 | engines: {node: '>=0.10.0'} 433 | 434 | parent-module@1.0.1: 435 | resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} 436 | engines: {node: '>=6'} 437 | 438 | parse-json@5.2.0: 439 | resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} 440 | engines: {node: '>=8'} 441 | 442 | parse-passwd@1.0.0: 443 | resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==} 444 | engines: {node: '>=0.10.0'} 445 | 446 | path-is-absolute@1.0.1: 447 | resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} 448 | engines: {node: '>=0.10.0'} 449 | 450 | picocolors@1.1.1: 451 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 452 | 453 | picomatch@2.3.1: 454 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 455 | engines: {node: '>=8.6'} 456 | 457 | readable-stream@3.6.2: 458 | resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} 459 | engines: {node: '>= 6'} 460 | 461 | require-from-string@2.0.2: 462 | resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} 463 | engines: {node: '>=0.10.0'} 464 | 465 | resolve-dir@1.0.1: 466 | resolution: {integrity: sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==} 467 | engines: {node: '>=0.10.0'} 468 | 469 | resolve-from@4.0.0: 470 | resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} 471 | engines: {node: '>=4'} 472 | 473 | resolve-from@5.0.0: 474 | resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} 475 | engines: {node: '>=8'} 476 | 477 | restore-cursor@3.1.0: 478 | resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} 479 | engines: {node: '>=8'} 480 | 481 | run-async@2.4.1: 482 | resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} 483 | engines: {node: '>=0.12.0'} 484 | 485 | rxjs@7.8.2: 486 | resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} 487 | 488 | safe-buffer@5.2.1: 489 | resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 490 | 491 | safer-buffer@2.1.2: 492 | resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} 493 | 494 | signal-exit@3.0.7: 495 | resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} 496 | 497 | string-width@4.2.3: 498 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 499 | engines: {node: '>=8'} 500 | 501 | string_decoder@1.3.0: 502 | resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} 503 | 504 | strip-ansi@6.0.1: 505 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 506 | engines: {node: '>=8'} 507 | 508 | strip-bom@4.0.0: 509 | resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} 510 | engines: {node: '>=8'} 511 | 512 | strip-json-comments@3.1.1: 513 | resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} 514 | engines: {node: '>=8'} 515 | 516 | supports-color@5.5.0: 517 | resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} 518 | engines: {node: '>=4'} 519 | 520 | supports-color@7.2.0: 521 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 522 | engines: {node: '>=8'} 523 | 524 | through@2.3.8: 525 | resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} 526 | 527 | tmp@0.0.33: 528 | resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} 529 | engines: {node: '>=0.6.0'} 530 | 531 | to-regex-range@5.0.1: 532 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 533 | engines: {node: '>=8.0'} 534 | 535 | tslib@2.8.1: 536 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} 537 | 538 | type-fest@0.21.3: 539 | resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} 540 | engines: {node: '>=10'} 541 | 542 | typescript@5.8.2: 543 | resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} 544 | engines: {node: '>=14.17'} 545 | hasBin: true 546 | 547 | undici-types@6.20.0: 548 | resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} 549 | 550 | universalify@2.0.1: 551 | resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} 552 | engines: {node: '>= 10.0.0'} 553 | 554 | util-deprecate@1.0.2: 555 | resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} 556 | 557 | wcwidth@1.0.1: 558 | resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} 559 | 560 | which@1.3.1: 561 | resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} 562 | hasBin: true 563 | 564 | word-wrap@1.2.5: 565 | resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} 566 | engines: {node: '>=0.10.0'} 567 | 568 | wrap-ansi@7.0.0: 569 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} 570 | engines: {node: '>=10'} 571 | 572 | wrappy@1.0.2: 573 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 574 | 575 | snapshots: 576 | 577 | '@babel/code-frame@7.26.2': 578 | dependencies: 579 | '@babel/helper-validator-identifier': 7.25.9 580 | js-tokens: 4.0.0 581 | picocolors: 1.1.1 582 | optional: true 583 | 584 | '@babel/helper-validator-identifier@7.25.9': 585 | optional: true 586 | 587 | '@commitlint/config-validator@19.8.0': 588 | dependencies: 589 | '@commitlint/types': 19.8.0 590 | ajv: 8.17.1 591 | optional: true 592 | 593 | '@commitlint/execute-rule@19.8.0': 594 | optional: true 595 | 596 | '@commitlint/load@19.8.0(@types/node@22.13.10)(typescript@5.8.2)': 597 | dependencies: 598 | '@commitlint/config-validator': 19.8.0 599 | '@commitlint/execute-rule': 19.8.0 600 | '@commitlint/resolve-extends': 19.8.0 601 | '@commitlint/types': 19.8.0 602 | chalk: 5.4.1 603 | cosmiconfig: 9.0.0(typescript@5.8.2) 604 | cosmiconfig-typescript-loader: 6.1.0(@types/node@22.13.10)(cosmiconfig@9.0.0(typescript@5.8.2))(typescript@5.8.2) 605 | lodash.isplainobject: 4.0.6 606 | lodash.merge: 4.6.2 607 | lodash.uniq: 4.5.0 608 | transitivePeerDependencies: 609 | - '@types/node' 610 | - typescript 611 | optional: true 612 | 613 | '@commitlint/resolve-extends@19.8.0': 614 | dependencies: 615 | '@commitlint/config-validator': 19.8.0 616 | '@commitlint/types': 19.8.0 617 | global-directory: 4.0.1 618 | import-meta-resolve: 4.1.0 619 | lodash.mergewith: 4.6.2 620 | resolve-from: 5.0.0 621 | optional: true 622 | 623 | '@commitlint/types@19.8.0': 624 | dependencies: 625 | '@types/conventional-commits-parser': 5.0.1 626 | chalk: 5.4.1 627 | optional: true 628 | 629 | '@types/conventional-commits-parser@5.0.1': 630 | dependencies: 631 | '@types/node': 22.13.10 632 | optional: true 633 | 634 | '@types/node@22.13.10': 635 | dependencies: 636 | undici-types: 6.20.0 637 | optional: true 638 | 639 | ajv@8.17.1: 640 | dependencies: 641 | fast-deep-equal: 3.1.3 642 | fast-uri: 3.0.6 643 | json-schema-traverse: 1.0.0 644 | require-from-string: 2.0.2 645 | optional: true 646 | 647 | ansi-escapes@4.3.2: 648 | dependencies: 649 | type-fest: 0.21.3 650 | 651 | ansi-regex@5.0.1: {} 652 | 653 | ansi-styles@3.2.1: 654 | dependencies: 655 | color-convert: 1.9.3 656 | 657 | ansi-styles@4.3.0: 658 | dependencies: 659 | color-convert: 2.0.1 660 | 661 | argparse@2.0.1: 662 | optional: true 663 | 664 | at-least-node@1.0.0: {} 665 | 666 | balanced-match@1.0.2: {} 667 | 668 | base64-js@1.5.1: {} 669 | 670 | bl@4.1.0: 671 | dependencies: 672 | buffer: 5.7.1 673 | inherits: 2.0.4 674 | readable-stream: 3.6.2 675 | 676 | brace-expansion@1.1.11: 677 | dependencies: 678 | balanced-match: 1.0.2 679 | concat-map: 0.0.1 680 | 681 | braces@3.0.3: 682 | dependencies: 683 | fill-range: 7.1.1 684 | 685 | buffer@5.7.1: 686 | dependencies: 687 | base64-js: 1.5.1 688 | ieee754: 1.2.1 689 | 690 | cachedir@2.3.0: {} 691 | 692 | callsites@3.1.0: 693 | optional: true 694 | 695 | chalk@2.4.2: 696 | dependencies: 697 | ansi-styles: 3.2.1 698 | escape-string-regexp: 1.0.5 699 | supports-color: 5.5.0 700 | 701 | chalk@4.1.2: 702 | dependencies: 703 | ansi-styles: 4.3.0 704 | supports-color: 7.2.0 705 | 706 | chalk@5.4.1: 707 | optional: true 708 | 709 | chardet@0.7.0: {} 710 | 711 | cli-cursor@3.1.0: 712 | dependencies: 713 | restore-cursor: 3.1.0 714 | 715 | cli-spinners@2.9.2: {} 716 | 717 | cli-width@3.0.0: {} 718 | 719 | clone@1.0.4: {} 720 | 721 | color-convert@1.9.3: 722 | dependencies: 723 | color-name: 1.1.3 724 | 725 | color-convert@2.0.1: 726 | dependencies: 727 | color-name: 1.1.4 728 | 729 | color-name@1.1.3: {} 730 | 731 | color-name@1.1.4: {} 732 | 733 | commitizen@4.3.1(@types/node@22.13.10)(typescript@5.8.2): 734 | dependencies: 735 | cachedir: 2.3.0 736 | cz-conventional-changelog: 3.3.0(@types/node@22.13.10)(typescript@5.8.2) 737 | dedent: 0.7.0 738 | detect-indent: 6.1.0 739 | find-node-modules: 2.1.3 740 | find-root: 1.1.0 741 | fs-extra: 9.1.0 742 | glob: 7.2.3 743 | inquirer: 8.2.5 744 | is-utf8: 0.2.1 745 | lodash: 4.17.21 746 | minimist: 1.2.7 747 | strip-bom: 4.0.0 748 | strip-json-comments: 3.1.1 749 | transitivePeerDependencies: 750 | - '@types/node' 751 | - typescript 752 | 753 | concat-map@0.0.1: {} 754 | 755 | conventional-commit-types@3.0.0: {} 756 | 757 | cosmiconfig-typescript-loader@6.1.0(@types/node@22.13.10)(cosmiconfig@9.0.0(typescript@5.8.2))(typescript@5.8.2): 758 | dependencies: 759 | '@types/node': 22.13.10 760 | cosmiconfig: 9.0.0(typescript@5.8.2) 761 | jiti: 2.4.2 762 | typescript: 5.8.2 763 | optional: true 764 | 765 | cosmiconfig@9.0.0(typescript@5.8.2): 766 | dependencies: 767 | env-paths: 2.2.1 768 | import-fresh: 3.3.1 769 | js-yaml: 4.1.0 770 | parse-json: 5.2.0 771 | optionalDependencies: 772 | typescript: 5.8.2 773 | optional: true 774 | 775 | cz-conventional-changelog@3.3.0(@types/node@22.13.10)(typescript@5.8.2): 776 | dependencies: 777 | chalk: 2.4.2 778 | commitizen: 4.3.1(@types/node@22.13.10)(typescript@5.8.2) 779 | conventional-commit-types: 3.0.0 780 | lodash.map: 4.6.0 781 | longest: 2.0.1 782 | word-wrap: 1.2.5 783 | optionalDependencies: 784 | '@commitlint/load': 19.8.0(@types/node@22.13.10)(typescript@5.8.2) 785 | transitivePeerDependencies: 786 | - '@types/node' 787 | - typescript 788 | 789 | dedent@0.7.0: {} 790 | 791 | defaults@1.0.4: 792 | dependencies: 793 | clone: 1.0.4 794 | 795 | detect-file@1.0.0: {} 796 | 797 | detect-indent@6.1.0: {} 798 | 799 | emoji-regex@8.0.0: {} 800 | 801 | env-paths@2.2.1: 802 | optional: true 803 | 804 | error-ex@1.3.2: 805 | dependencies: 806 | is-arrayish: 0.2.1 807 | optional: true 808 | 809 | escape-string-regexp@1.0.5: {} 810 | 811 | expand-tilde@2.0.2: 812 | dependencies: 813 | homedir-polyfill: 1.0.3 814 | 815 | external-editor@3.1.0: 816 | dependencies: 817 | chardet: 0.7.0 818 | iconv-lite: 0.4.24 819 | tmp: 0.0.33 820 | 821 | fast-deep-equal@3.1.3: 822 | optional: true 823 | 824 | fast-uri@3.0.6: 825 | optional: true 826 | 827 | figures@3.2.0: 828 | dependencies: 829 | escape-string-regexp: 1.0.5 830 | 831 | fill-range@7.1.1: 832 | dependencies: 833 | to-regex-range: 5.0.1 834 | 835 | find-node-modules@2.1.3: 836 | dependencies: 837 | findup-sync: 4.0.0 838 | merge: 2.1.1 839 | 840 | find-root@1.1.0: {} 841 | 842 | findup-sync@4.0.0: 843 | dependencies: 844 | detect-file: 1.0.0 845 | is-glob: 4.0.3 846 | micromatch: 4.0.8 847 | resolve-dir: 1.0.1 848 | 849 | fs-extra@9.1.0: 850 | dependencies: 851 | at-least-node: 1.0.0 852 | graceful-fs: 4.2.11 853 | jsonfile: 6.1.0 854 | universalify: 2.0.1 855 | 856 | fs.realpath@1.0.0: {} 857 | 858 | glob@7.2.3: 859 | dependencies: 860 | fs.realpath: 1.0.0 861 | inflight: 1.0.6 862 | inherits: 2.0.4 863 | minimatch: 3.1.2 864 | once: 1.4.0 865 | path-is-absolute: 1.0.1 866 | 867 | global-directory@4.0.1: 868 | dependencies: 869 | ini: 4.1.1 870 | optional: true 871 | 872 | global-modules@1.0.0: 873 | dependencies: 874 | global-prefix: 1.0.2 875 | is-windows: 1.0.2 876 | resolve-dir: 1.0.1 877 | 878 | global-prefix@1.0.2: 879 | dependencies: 880 | expand-tilde: 2.0.2 881 | homedir-polyfill: 1.0.3 882 | ini: 1.3.8 883 | is-windows: 1.0.2 884 | which: 1.3.1 885 | 886 | graceful-fs@4.2.11: {} 887 | 888 | has-flag@3.0.0: {} 889 | 890 | has-flag@4.0.0: {} 891 | 892 | homedir-polyfill@1.0.3: 893 | dependencies: 894 | parse-passwd: 1.0.0 895 | 896 | iconv-lite@0.4.24: 897 | dependencies: 898 | safer-buffer: 2.1.2 899 | 900 | ieee754@1.2.1: {} 901 | 902 | import-fresh@3.3.1: 903 | dependencies: 904 | parent-module: 1.0.1 905 | resolve-from: 4.0.0 906 | optional: true 907 | 908 | import-meta-resolve@4.1.0: 909 | optional: true 910 | 911 | inflight@1.0.6: 912 | dependencies: 913 | once: 1.4.0 914 | wrappy: 1.0.2 915 | 916 | inherits@2.0.4: {} 917 | 918 | ini@1.3.8: {} 919 | 920 | ini@4.1.1: 921 | optional: true 922 | 923 | inquirer@8.2.5: 924 | dependencies: 925 | ansi-escapes: 4.3.2 926 | chalk: 4.1.2 927 | cli-cursor: 3.1.0 928 | cli-width: 3.0.0 929 | external-editor: 3.1.0 930 | figures: 3.2.0 931 | lodash: 4.17.21 932 | mute-stream: 0.0.8 933 | ora: 5.4.1 934 | run-async: 2.4.1 935 | rxjs: 7.8.2 936 | string-width: 4.2.3 937 | strip-ansi: 6.0.1 938 | through: 2.3.8 939 | wrap-ansi: 7.0.0 940 | 941 | is-arrayish@0.2.1: 942 | optional: true 943 | 944 | is-extglob@2.1.1: {} 945 | 946 | is-fullwidth-code-point@3.0.0: {} 947 | 948 | is-glob@4.0.3: 949 | dependencies: 950 | is-extglob: 2.1.1 951 | 952 | is-interactive@1.0.0: {} 953 | 954 | is-number@7.0.0: {} 955 | 956 | is-unicode-supported@0.1.0: {} 957 | 958 | is-utf8@0.2.1: {} 959 | 960 | is-windows@1.0.2: {} 961 | 962 | isexe@2.0.0: {} 963 | 964 | jiti@2.4.2: 965 | optional: true 966 | 967 | js-tokens@4.0.0: 968 | optional: true 969 | 970 | js-yaml@4.1.0: 971 | dependencies: 972 | argparse: 2.0.1 973 | optional: true 974 | 975 | json-parse-even-better-errors@2.3.1: 976 | optional: true 977 | 978 | json-schema-traverse@1.0.0: 979 | optional: true 980 | 981 | jsonfile@6.1.0: 982 | dependencies: 983 | universalify: 2.0.1 984 | optionalDependencies: 985 | graceful-fs: 4.2.11 986 | 987 | lines-and-columns@1.2.4: 988 | optional: true 989 | 990 | lodash.isplainobject@4.0.6: 991 | optional: true 992 | 993 | lodash.map@4.6.0: {} 994 | 995 | lodash.merge@4.6.2: 996 | optional: true 997 | 998 | lodash.mergewith@4.6.2: 999 | optional: true 1000 | 1001 | lodash.uniq@4.5.0: 1002 | optional: true 1003 | 1004 | lodash@4.17.21: {} 1005 | 1006 | log-symbols@4.1.0: 1007 | dependencies: 1008 | chalk: 4.1.2 1009 | is-unicode-supported: 0.1.0 1010 | 1011 | longest@2.0.1: {} 1012 | 1013 | merge@2.1.1: {} 1014 | 1015 | micromatch@4.0.8: 1016 | dependencies: 1017 | braces: 3.0.3 1018 | picomatch: 2.3.1 1019 | 1020 | mimic-fn@2.1.0: {} 1021 | 1022 | minimatch@3.1.2: 1023 | dependencies: 1024 | brace-expansion: 1.1.11 1025 | 1026 | minimist@1.2.7: {} 1027 | 1028 | mute-stream@0.0.8: {} 1029 | 1030 | once@1.4.0: 1031 | dependencies: 1032 | wrappy: 1.0.2 1033 | 1034 | onetime@5.1.2: 1035 | dependencies: 1036 | mimic-fn: 2.1.0 1037 | 1038 | ora@5.4.1: 1039 | dependencies: 1040 | bl: 4.1.0 1041 | chalk: 4.1.2 1042 | cli-cursor: 3.1.0 1043 | cli-spinners: 2.9.2 1044 | is-interactive: 1.0.0 1045 | is-unicode-supported: 0.1.0 1046 | log-symbols: 4.1.0 1047 | strip-ansi: 6.0.1 1048 | wcwidth: 1.0.1 1049 | 1050 | os-tmpdir@1.0.2: {} 1051 | 1052 | parent-module@1.0.1: 1053 | dependencies: 1054 | callsites: 3.1.0 1055 | optional: true 1056 | 1057 | parse-json@5.2.0: 1058 | dependencies: 1059 | '@babel/code-frame': 7.26.2 1060 | error-ex: 1.3.2 1061 | json-parse-even-better-errors: 2.3.1 1062 | lines-and-columns: 1.2.4 1063 | optional: true 1064 | 1065 | parse-passwd@1.0.0: {} 1066 | 1067 | path-is-absolute@1.0.1: {} 1068 | 1069 | picocolors@1.1.1: 1070 | optional: true 1071 | 1072 | picomatch@2.3.1: {} 1073 | 1074 | readable-stream@3.6.2: 1075 | dependencies: 1076 | inherits: 2.0.4 1077 | string_decoder: 1.3.0 1078 | util-deprecate: 1.0.2 1079 | 1080 | require-from-string@2.0.2: 1081 | optional: true 1082 | 1083 | resolve-dir@1.0.1: 1084 | dependencies: 1085 | expand-tilde: 2.0.2 1086 | global-modules: 1.0.0 1087 | 1088 | resolve-from@4.0.0: 1089 | optional: true 1090 | 1091 | resolve-from@5.0.0: 1092 | optional: true 1093 | 1094 | restore-cursor@3.1.0: 1095 | dependencies: 1096 | onetime: 5.1.2 1097 | signal-exit: 3.0.7 1098 | 1099 | run-async@2.4.1: {} 1100 | 1101 | rxjs@7.8.2: 1102 | dependencies: 1103 | tslib: 2.8.1 1104 | 1105 | safe-buffer@5.2.1: {} 1106 | 1107 | safer-buffer@2.1.2: {} 1108 | 1109 | signal-exit@3.0.7: {} 1110 | 1111 | string-width@4.2.3: 1112 | dependencies: 1113 | emoji-regex: 8.0.0 1114 | is-fullwidth-code-point: 3.0.0 1115 | strip-ansi: 6.0.1 1116 | 1117 | string_decoder@1.3.0: 1118 | dependencies: 1119 | safe-buffer: 5.2.1 1120 | 1121 | strip-ansi@6.0.1: 1122 | dependencies: 1123 | ansi-regex: 5.0.1 1124 | 1125 | strip-bom@4.0.0: {} 1126 | 1127 | strip-json-comments@3.1.1: {} 1128 | 1129 | supports-color@5.5.0: 1130 | dependencies: 1131 | has-flag: 3.0.0 1132 | 1133 | supports-color@7.2.0: 1134 | dependencies: 1135 | has-flag: 4.0.0 1136 | 1137 | through@2.3.8: {} 1138 | 1139 | tmp@0.0.33: 1140 | dependencies: 1141 | os-tmpdir: 1.0.2 1142 | 1143 | to-regex-range@5.0.1: 1144 | dependencies: 1145 | is-number: 7.0.0 1146 | 1147 | tslib@2.8.1: {} 1148 | 1149 | type-fest@0.21.3: {} 1150 | 1151 | typescript@5.8.2: 1152 | optional: true 1153 | 1154 | undici-types@6.20.0: 1155 | optional: true 1156 | 1157 | universalify@2.0.1: {} 1158 | 1159 | util-deprecate@1.0.2: {} 1160 | 1161 | wcwidth@1.0.1: 1162 | dependencies: 1163 | defaults: 1.0.4 1164 | 1165 | which@1.3.1: 1166 | dependencies: 1167 | isexe: 2.0.0 1168 | 1169 | word-wrap@1.2.5: {} 1170 | 1171 | wrap-ansi@7.0.0: 1172 | dependencies: 1173 | ansi-styles: 4.3.0 1174 | string-width: 4.2.3 1175 | strip-ansi: 6.0.1 1176 | 1177 | wrappy@1.0.2: {} 1178 | -------------------------------------------------------------------------------- /pub_dev_toolkit.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name flutter packages site toolkit script 3 | // @license GPL-3.0-only 4 | // @namespace https://pub.dev 5 | // @icon https://pub.flutter-io.cn/favicon.ico?hash=nk4nss8c7444fg0chird9erqef2vkhb8 6 | // @version 1.0.1 7 | // @description 1. copy dependencies info cash as: "dio: ^1.2.3"; ~~2. open package page by search string~~ 8 | // @note 1.0.1 "click to copy" button change to 9 | // @author Sven 10 | // @match https://pub.dev/packages/* 11 | // @match https://pub.dev/packages?q=* 12 | // @match https://pub.dev 13 | // @match https://pub.flutter-io.cn/packages/* 14 | // @match https://pub.flutter-io.cn/packages?q=* 15 | // @match https://pub.flutter-io.cn 16 | // @run-at document-start 17 | // @grant none 18 | // ==/UserScript== 19 | 20 | ; (function () { 21 | class Toolkit { 22 | static SHEETS = ` 23 | :root { 24 | --toolkit-border: 1px solid #CCC; 25 | } 26 | #dependencies-info { display: flex; font-size: 14px; margin-bottom: 15px; } 27 | #dependencies-info > div { padding: 5px 8px; font-weight: bolder; cursor: pointer; } 28 | #dependencies-info .version { 29 | background-color: #e7f8ff; 30 | color: #666; 31 | } 32 | #dependencies-info .tips { 33 | background-color: #0175c2; 34 | color: #FFF; 35 | } 36 | #dependencies-info .tips > a { color: #FFF; } 37 | #dependencies-info .tips:hover { background-color: #37a4ec; } 38 | ` 39 | constructor() { 40 | window.addEventListener('DOMContentLoaded', evt => { 41 | this.appendSheets() 42 | this.showDependenciesInfo() 43 | }) 44 | } 45 | appendSheets() { 46 | const sheet = document.createTextNode(Toolkit.SHEETS) 47 | const el = document.createElement('style') 48 | el.id = 'toolkit-sheets' 49 | el.appendChild(sheet) 50 | document.getElementsByTagName('head')[0].appendChild(el) 51 | } 52 | showDependenciesInfo() { 53 | const titleWrapper = document.querySelector('.detail-header') 54 | const titleDom = document.querySelector('.detail-header .title') 55 | const infoParts = titleDom.innerText.split(' ') 56 | const info = `${infoParts[0]}: ^${infoParts[1]}` 57 | const infoDom = this._getDependenciesInfoDom(info) 58 | titleWrapper.insertBefore(infoDom, document.querySelector('.detail-header .metadata')) 59 | } 60 | _getDependenciesInfoDom(info) { 61 | const infoDom = document.createElement('div') 62 | const versionDom = document.createElement('div') 63 | const tipsDom = document.createElement('div') 64 | const tipsInfoDom = document.createElement('a') 65 | tipsInfoDom.setAttribute('href', 'javascript:;') 66 | versionDom.innerText = info 67 | versionDom.classList.add('version') 68 | tipsInfoDom.innerText = location.host === 'pub.dev' ? '𝒄𝒍𝒊𝒄𝒌 𝒕𝒐 𝒄𝒐𝒑𝒚' : '点击复制' 69 | tipsDom.classList.add('tips') 70 | infoDom.setAttribute('id', 'dependencies-info') 71 | infoDom.appendChild(versionDom) 72 | tipsDom.appendChild(tipsInfoDom) 73 | infoDom.appendChild(tipsDom) 74 | infoDom.addEventListener('click', evt => { 75 | if (evt.target === infoDom) return 76 | this.clickToCopy(info) 77 | }) 78 | return infoDom 79 | } 80 | clickToCopy(info) { 81 | const tempInput = document.createElement('input') 82 | tempInput.setAttribute('value', info) 83 | document.body.appendChild(tempInput) 84 | tempInput.select() 85 | const successfully = document.execCommand('copy') 86 | document.body.removeChild(tempInput) 87 | this.log(successfully ? 'copy successfully' : 'copy failed') 88 | } 89 | log(...args) { 90 | console.log('%c[pub.dev Toolkit] LOG: ', 'color:teal', ...args) 91 | } 92 | } 93 | window._$PubDevToolkit = new Toolkit() 94 | })(); -------------------------------------------------------------------------------- /qq_speed_bbs_toolkit.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name QQ飞车官方论坛视频处理工具 - 自动识别视频并以