diff --git a/.gitignore b/.gitignore index bbdb911..2f6bcc5 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,11 @@ target/ !**/src/main/**/target/ !**/src/test/**/target/ +/bin +/tmp +/bak +config.yaml + ### IntelliJ IDEA ### .idea/ .idea/modules.xml diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0ad25db --- /dev/null +++ b/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/README.md b/README.md index 75b51f2..447ce98 100644 --- a/README.md +++ b/README.md @@ -2,46 +2,35 @@ # DayZ Mod Translator +![JDK](https://img.shields.io/badge/JDK-21-%2300599C) +[![JavaFX](https://img.shields.io/badge/JavaFX-21.0.4-%2300599C)](https://openjfx.io/) +![platform](https://img.shields.io/badge/platform-Windows-blueviolet)
-
- JDK - platform -
- -[//]: # (
) - -[//]: # ( license) - -[//]: # ( commit) - -[//]: # (
) - -[//]: # (
) - -[//]: # ( stars) - -[//]: # ( GitHub all releases) - -[//]: # (
) +[![license](https://img.shields.io/github/license/octopusYan/dayz-mod-translator)](https://github.com/octopusYan/dayz-mod-translator) +![commit](https://img.shields.io/github/commit-activity/m/octopusYan/dayz-mod-translator?color=%23ff69b4) +
+![stars](https://img.shields.io/github/stars/octopusYan/dayz-mod-translator?style=social) +![GitHub all releases](https://img.shields.io/github/downloads/octopusYan/dayz-mod-translator/total?style=social)
-使用 JavaFx 编写的 DayZ 游戏mod 汉化GUI工具 +使用JavaFx编写的DayZ/ArmA游戏模组汉化工具 ### 使用 - 设置 -> 翻译,选择翻译接口,填写配置信息,点击确定 -- 点击左侧打开文件选择需要翻译的模组pbo文件 -- 待翻译文本获取完成后,点击右侧翻译按钮 +- 点击打开文件按钮选择需要翻译的模组pbo文件 +- 等待待可翻译文本获取完成,点击右侧翻译按钮 - 翻译完成后,点击打包按钮,选择保存位置 -
截图 +
+截图 -![Main window start](doc/img/screenshot01.png 'Main application window start') - -![Main window open file](doc/img/screenshot02.png 'Main window open file') +![start](doc/img/screenshot01.png 'start') +![open file](doc/img/screenshot02.png 'open file') +![edit](doc/img/screenshot03.png 'edit')
@@ -49,43 +38,50 @@ #### 环境说明 -| 名称 | 描述 | -|-------|---------------------------------------------------------| -| 系统环境 | windows11/10 | -| JDK版本 | 17 | -| 构建工具 | Mavne | -| 打包工具 | [JavaPackager](https://github.com/fvarrui/JavaPackager) | +| 名称 | 描述 | +|------|---------------------------------------------------------| +| 系统环境 | windows 10/11 | +| JDK | 21 | +| 构建工具 | Maven | +| 打包工具 | [JavaPackager](https://github.com/fvarrui/JavaPackager) | -#### 步骤 +#### 本地运行 -1. 环境配置 - - 打开 [JavaFx](https://gluonhq.com/products/javafx/) 官网环境下载页面 - - 在下方 Downloads 处 - - `JavaFX version` 选择 `17.0.12[LTS]` - - `Operating System` 选择 `Windows` - - `Type` 选择 `jmods` - - 点击右侧绿色按钮下载解压 - - 将解压文件夹内所有 `.jmod` 后缀名的文件复制到 `jdk环境目录` 的`jmods`文件夹中 -2. 下载源代码并使用 [IntelliJ IDEA](https://www.jetbrains.com/zh-cn/idea/download/?section=windows) 打开 +1. 克隆代码 ```bash - git clone https://github.com/octopusYan/dayz-mod-translator.git + git clone https://github.com/octopusYan/dayz-mod-translator + ``` +2. 运行 + ```bash + mvn clean javafx:run + ``` + +#### 打包 + +1. 克隆代码 + ```bash + git clone https://github.com/octopusYan/dayz-mod-translator + ``` +2. 运行 + ```bash + mvn clean package ``` -3. 打包 - - 使用 `IntelliJ IDEA` Maven UI - - 点击右侧工具栏的`Maven` - - 展开 `DayzModTranslator\Lifecycle` - - 点击 package - - 使用 mvn 命令 - ```bash - mvn package - ``` ### 可能会用到 吾爱论坛 / 谷歌翻译修复:[谷歌浏览器右键翻译失效了咋办,一键修复,才13KB](https://www.52pojie.cn/thread-1781877-1-1.html) -## 致谢 +### 依赖/引用的项目 -### 开源库 +
-- [pboman3](https://github.com/winseros/pboman3):打开、打包和解包 ArmA PBO 文件的工具。 \ No newline at end of file +| | | +|-----------------------------------------------------------------------------|--------------------------| +| [PBO Manager](https://github.com/winseros/pboman3) | 打开、打包和解包 ArmA PBO 文件的工具。 | +| [JavaFX](https://openjfx.io/) | Java 桌面开发 | +| [AtlantaFX](https://mkpaz.github.io/atlantafx/) | JavaFX CSS 主题集合 | +| [JavaPackager](https://github.com/fvarrui/JavaPackager) | 打包插件 | +| [Apache Commons](https://commons.apache.org/proper/commons-exec/index.html) | 工具包 | +| [SLF4J](https://slf4j.org/) | 日志工具 | + +
\ No newline at end of file diff --git a/doc/img/screenshot01.png b/doc/img/screenshot01.png index 10cfce3..85db6c5 100644 Binary files a/doc/img/screenshot01.png and b/doc/img/screenshot01.png differ diff --git a/doc/img/screenshot02.png b/doc/img/screenshot02.png index 920ea7c..4ed2b2e 100644 Binary files a/doc/img/screenshot02.png and b/doc/img/screenshot02.png differ diff --git a/doc/img/screenshot03.png b/doc/img/screenshot03.png new file mode 100644 index 0000000..5288011 Binary files /dev/null and b/doc/img/screenshot03.png differ diff --git a/pom.xml b/pom.xml index 3b7853b..322445c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,28 +5,40 @@ 4.0.0 cn.octopusyan - dayz-mod-translator - 0.0.1 - DayzModTranslator + dmt + 0.0.2 + dmt octopus_yan octopus_yan@foxmail.com + 2024 - DayZ 模组汉化工具 + DayZ/ArmA 模组汉化工具 UTF-8 - 17 - 17 - 17 + UTF-8 + 21 + 21 + 21 + + cn.octopusyan.dmt.AppLauncher + ${project.basedir}/src/main/resources/css + ${project.basedir}/target/classes/css 5.11.0 - 17.0.12 + 21.0.4 2.0.16 1.5.7 2.0.52 + 3.16.0 + 2.17.0 + 1.4.0 + 1.18.32 + 2.15.4 + 12.3.1 @@ -47,12 +59,13 @@ ${javafx.version} - - - - - - + + + io.github.mkpaz + atlantafx-base + 2.0.1 + + org.slf4j slf4j-api @@ -88,30 +101,62 @@ org.apache.commons commons-lang3 - 3.16.0 + ${common-lang3.version} commons-io commons-io - 2.16.1 + ${common-io.version} org.apache.commons commons-exec - 1.4.0 + ${common-exec.version} - - + - com.alibaba.fastjson2 - fastjson2 - ${fastjson.version} + org.projectlombok + lombok + ${lombok.version} + + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + ${jackson.version} + + + + + org.kordamp.ikonli + ikonli-javafx + + + org.kordamp.ikonli + ikonli-fontawesome-pack + + + org.kordamp.ikonli + ikonli-feather-pack + + + + org.kordamp.ikonli + ikonli-bom + ${ikonli.version} + pom + import + + + + nexus @@ -141,8 +186,17 @@ maven-compiler-plugin 3.13.0 - 17 - 17 + 21 + 21 + --enable-preview + UTF-8 + + + org.projectlombok + lombok + ${lombok.version} + + @@ -162,20 +216,25 @@ org.openjfx javafx-maven-plugin 0.0.8 + + true + 2 + true + true + launcher + app + app + cn.octopusyan.dmt/${exec.mainClass} + default-cli - - cn.octopusyan.dayzmodtranslator/cn.octopusyan.dayzmodtranslator.AppLuncher - - launcher - app - app - true - true - true + + + + @@ -186,20 +245,53 @@ javapackager 1.7.7-SNAPSHOT + ${exec.mainClass} true - cn.octopusyan.dayzmodtranslator.AppLuncher false + true + + --enable-preview + -Xmx100m + - bundling-for-windows + windows package package windows + ${project.name}-windows true + + gui + false + + + ${project.basedir}/src/main/resources/bin + + + + + windows-nojre + package + + package + + + ${project.name}-windows-nojre + windows + true + false + + gui + false + + + ${project.basedir}/src/main/resources/bin + diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/AppLuncher.java b/src/main/java/cn/octopusyan/dayzmodtranslator/AppLuncher.java deleted file mode 100644 index 158706f..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/AppLuncher.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.octopusyan.dayzmodtranslator; - -/** - * 启动类 - * - * @author octopus_yan@foxmail.com - */ -public class AppLuncher { - - public static void main(String[] args) { -// try { -// Runtime.getRuntime().exec("Taskkill /IM " + FrpManager.FRPC_CLIENT_FILE_NAME + " /f"); -// } catch (IOException e) { -// e.printStackTrace(); -// } - - Application.launch(Application.class, args); - } -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/Application.java b/src/main/java/cn/octopusyan/dayzmodtranslator/Application.java deleted file mode 100644 index a61f8fb..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/Application.java +++ /dev/null @@ -1,105 +0,0 @@ -package cn.octopusyan.dayzmodtranslator; - -import cn.octopusyan.dayzmodtranslator.config.AppConstant; -import cn.octopusyan.dayzmodtranslator.config.CustomConfig; -import cn.octopusyan.dayzmodtranslator.manager.http.HttpConfig; -import cn.octopusyan.dayzmodtranslator.controller.MainController; -import cn.octopusyan.dayzmodtranslator.manager.CfgConvertUtil; -import cn.octopusyan.dayzmodtranslator.manager.PBOUtil; -import cn.octopusyan.dayzmodtranslator.manager.thread.ThreadPoolManager; -import cn.octopusyan.dayzmodtranslator.manager.translate.TranslateUtil; -import cn.octopusyan.dayzmodtranslator.util.AlertUtil; -import cn.octopusyan.dayzmodtranslator.util.FxmlUtil; -import cn.octopusyan.dayzmodtranslator.manager.http.HttpUtil; -import javafx.fxml.FXMLLoader; -import javafx.scene.Scene; -import javafx.scene.layout.VBox; -import javafx.stage.Stage; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.ProxySelector; -import java.util.Objects; - -public class Application extends javafx.application.Application { - private static final Logger logger = LoggerFactory.getLogger(Application.class); - - @Override - public void init() throws Exception { - logger.info("application init ..."); - } - - @Override - public void start(Stage stage) throws IOException { - - logger.info("application start ..."); - - // bin转换 工具初始化 - CfgConvertUtil.init(); - - // PBO 工具初始化 - PBOUtil.init(CfgConvertUtil.getInstance()); - - // 客户端配置初始化 - CustomConfig.init(); - - // 初始化弹窗工具 - AlertUtil.initOwner(stage); - - // http请求工具初始化 - HttpConfig httpConfig = new HttpConfig(); - if (CustomConfig.hasProxy()) { - InetSocketAddress unresolved = InetSocketAddress.createUnresolved(CustomConfig.proxyHost(), CustomConfig.proxyPort()); - httpConfig.setProxySelector(ProxySelector.of(unresolved)); - } - httpConfig.setConnectTimeout(10); - HttpUtil.init(httpConfig); - - // TODO 全局异常处理 - Thread.setDefaultUncaughtExceptionHandler(this::showErrorDialog); - Thread.currentThread().setUncaughtExceptionHandler(this::showErrorDialog); - - // 启动主界面 - try { - FXMLLoader fxmlLoader = FxmlUtil.load("main-view"); - VBox root = fxmlLoader.load();//底层面板 - Scene scene = new Scene(root); - scene.getStylesheets().addAll(Objects.requireNonNull(getClass().getResource("/css/root.css")).toExternalForm()); - stage.setScene(scene); - stage.setMinHeight(330); - stage.setMinWidth(430); - stage.setMaxWidth(Double.MAX_VALUE); - stage.setMaxHeight(Double.MAX_VALUE); - stage.setTitle(AppConstant.APP_TITLE + " v" + AppConstant.APP_VERSION); - stage.show(); - - MainController controller = fxmlLoader.getController(); - controller.setApplication(this); - } catch (Throwable t) { - showErrorDialog(Thread.currentThread(), t); - } - - logger.info("application start over ..."); - } - - private void showErrorDialog(Thread t, Throwable e) { - logger.error("", e); - AlertUtil.exceptionAlert(new Exception(e)).show(); - } - - @Override - public void stop() throws Exception { - logger.info("application stop ..."); - - // 清除翻译任务 - TranslateUtil.getInstance().clear(); - // 停止所有线程 - ThreadPoolManager.getInstance().shutdown(); - // 保存应用数据 - CustomConfig.store(); - // 清理缓存 - PBOUtil.clear(); - } -} \ No newline at end of file diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/base/BaseController.java b/src/main/java/cn/octopusyan/dayzmodtranslator/base/BaseController.java deleted file mode 100644 index 7095c64..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/base/BaseController.java +++ /dev/null @@ -1,217 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.base; - -import cn.octopusyan.dayzmodtranslator.config.AppConstant; -import cn.octopusyan.dayzmodtranslator.util.FxmlUtil; -import cn.octopusyan.dayzmodtranslator.util.Loading; -import cn.octopusyan.dayzmodtranslator.util.TooltipUtil; -import javafx.application.Application; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; -import javafx.fxml.FXMLLoader; -import javafx.fxml.Initializable; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.scene.control.Label; -import javafx.scene.layout.Pane; -import javafx.stage.Modality; -import javafx.stage.Stage; -import javafx.stage.Window; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.URL; -import java.util.Objects; -import java.util.ResourceBundle; - -/** - * 通用视图控制器基类 - * - * @author octopus_yan@foxmail.com - */ -public abstract class BaseController

implements Initializable { - protected final Logger logger = LoggerFactory.getLogger(this.getClass()); - private Application application; - - private double xOffSet = 0, yOffSet = 0; - - private volatile Loading loading; - - protected TooltipUtil tooltipUtil; - - public void jumpTo(BaseController

controller) throws IOException { - FXMLLoader fxmlLoader = FxmlUtil.load(controller.getRootFxml()); - - Scene scene = getRootPanel().getScene(); - double oldHeight = getRootPanel().getPrefHeight(); - double oldWidth = getRootPanel().getPrefWidth(); - - Pane root = fxmlLoader.load(); - Stage stage = (Stage) scene.getWindow(); - // 窗口大小 - double newWidth = root.getPrefWidth(); - double newHeight = root.getPrefHeight(); - // 窗口位置 - double newX = stage.getX() - (newWidth - oldWidth) / 2; - double newY = stage.getY() - (newHeight - oldHeight) / 2; - scene.setRoot(root); - stage.setX(newX < 0 ? 0 : newX); - stage.setY(newY < 0 ? 0 : newY); - stage.setWidth(newWidth); - stage.setHeight(newHeight); - - controller = fxmlLoader.getController(); - controller.setApplication(getApplication()); - } - - protected void open(Class> clazz, String title) { - try { - FXMLLoader load = FxmlUtil.load(clazz.getDeclaredConstructor().newInstance().getRootFxml()); - Parent root = load.load(); - Scene scene = new Scene(root); - scene.getStylesheets().addAll(Objects.requireNonNull(getClass().getResource("/css/root.css")).toExternalForm()); - Stage stage = new Stage(); - stage.setScene(scene); - stage.setTitle(title); - stage.initOwner(getWindow()); - stage.initModality(Modality.WINDOW_MODAL); - stage.show(); - load.getController(); - } catch (Exception e) { - logger.error("", e); - } - } - - @Override - public void initialize(URL url, ResourceBundle resourceBundle) { - // 全局窗口拖拽 - if (dragWindow()) { - // 窗口拖拽 - getRootPanel().setOnMousePressed(event -> { - xOffSet = event.getSceneX(); - yOffSet = event.getSceneY(); - }); - getRootPanel().setOnMouseDragged(event -> { - Stage stage = (Stage) getWindow(); - stage.setX(event.getScreenX() - xOffSet); - stage.setY(event.getScreenY() - yOffSet); - }); - } - - // 窗口初始化完成监听 - getRootPanel().sceneProperty().addListener((observable, oldValue, newValue) -> { - newValue.windowProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, Window oldValue, Window newValue) { - //关闭窗口监听 - getWindow().setOnCloseRequest(windowEvent -> onDestroy()); - - // app 版本信息 - if (getAppVersionLabel() != null) getAppVersionLabel().setText("v" + AppConstant.APP_VERSION); - - // 初始化数据 - initData(); - - // 初始化视图样式 - initViewStyle(); - - // 初始化视图事件 - initViewAction(); - } - }); - }); - } - - public void showLoading() { - showLoading(null); - } - - public void showLoading(String message) { - if (loading == null) loading = new Loading((Stage) getWindow()); - - if (StringUtils.isNotEmpty(message)) loading.showMessage(message); - - loading.show(); - } - - public void setApplication(Application application) { - this.application = application; - } - - public Application getApplication() { - return application; - } - - public boolean isLoadShowing() { - return loading != null && loading.showing(); - } - - public void stopLoading() { - if (isLoadShowing()) - loading.closeStage(); - } - - protected TooltipUtil getTooltipUtil() { - if (tooltipUtil == null) tooltipUtil = TooltipUtil.getInstance(getRootPanel()); - return tooltipUtil; - } - - /** - * 窗口拖拽设置 - * - * @return 是否启用 - */ - public abstract boolean dragWindow(); - - /** - * 获取根布局 - * - * @return 根布局对象 - */ - public abstract P getRootPanel(); - - /** - * 获取根布局 - *

搭配 FxmlUtil.load 使用 - * - * @return 根布局对象 - * @see cn.octopusyan.dayzmodtranslator.util.FxmlUtil#load(String) - */ - public abstract String getRootFxml(); - - protected Window getWindow() { - return getRootPanel().getScene().getWindow(); - } - - /** - * App版本信息标签 - */ - public Label getAppVersionLabel() { - return null; - } - - /** - * 初始化数据 - */ - public abstract void initData(); - - /** - * 视图样式 - */ - public abstract void initViewStyle(); - - /** - * 视图事件 - */ - public abstract void initViewAction(); - - /** - * 关闭窗口 - */ - public void onDestroy() { - Stage stage = (Stage) getWindow(); - stage.hide(); - stage.close(); - } -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/config/AppConstant.java b/src/main/java/cn/octopusyan/dayzmodtranslator/config/AppConstant.java deleted file mode 100644 index 70c0d11..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/config/AppConstant.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.config; - -import cn.octopusyan.dayzmodtranslator.util.PropertiesUtils; -import org.apache.commons.io.FileUtils; - -import java.io.File; - -/** - * 应用信息 - * - * @author octopus_yan@foxmail.com - */ -public class AppConstant { - public static final String APP_TITLE = PropertiesUtils.getInstance().getProperty("app.title"); - public static final String APP_NAME = PropertiesUtils.getInstance().getProperty("app.name"); - public static final String APP_VERSION = PropertiesUtils.getInstance().getProperty("app.version"); - public static final String DATA_DIR_PATH = System.getProperty("user.home") + File.separator + "AppData" + File.separator + "Local" + File.separator + APP_NAME; - public static final String TMP_DIR_PATH = FileUtils.getTempDirectoryPath() + APP_NAME; - public static final String CUSTOM_CONFIG_PATH = DATA_DIR_PATH + File.separator + "config.properties"; - public static final String BAK_FILE_PATH = AppConstant.TMP_DIR_PATH + File.separator + "bak"; -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/config/CustomConfig.java b/src/main/java/cn/octopusyan/dayzmodtranslator/config/CustomConfig.java deleted file mode 100644 index a36ece7..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/config/CustomConfig.java +++ /dev/null @@ -1,174 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.config; - -import cn.octopusyan.dayzmodtranslator.manager.translate.TranslateSource; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.nio.charset.StandardCharsets; -import java.util.Properties; - -/** - * 客户端设置 - * - * @author octopus_yan@foxmail.com - */ -public class CustomConfig { - private static final Logger logger = LoggerFactory.getLogger(CustomConfig.class); - private static final Properties properties = new Properties(); - public static final String PROXY_HOST_KEY = "proxy.host"; - public static final String PROXY_PORT_KEY = "proxy.port"; - public static final String TRANSLATE_SOURCE_KEY = "translate.source"; - public static final String TRANSLATE_SOURCE_APPID_KEY = "translate.{}.appid"; - public static final String TRANSLATE_SOURCE_APIKEY_KEY = "translate.{}.apikey"; - public static final String TRANSLATE_SOURCE_QPS_KEY = "translate.{}.qps"; - - public static void init() { - File customConfigFile = new File(AppConstant.CUSTOM_CONFIG_PATH); - try { - if (!customConfigFile.exists()) { - // 初始配置 - properties.put(TRANSLATE_SOURCE_KEY, TranslateSource.FREE_GOOGLE.getName()); - // 保存配置文件 - store(); - } else { - properties.load(new FileInputStream(customConfigFile)); - } - } catch (IOException ignore) { - logger.error("读取配置文件失败"); - } - } - - /** - * 是否配置代理 - */ - public static boolean hasProxy() { - String host = proxyHost(); - Integer port = proxyPort(); - - return StringUtils.isNoneBlank(host) && null != port; - } - - /** - * 代理地址 - */ - public static String proxyHost() { - return properties.getProperty(PROXY_HOST_KEY); - } - - /** - * 代理地址 - */ - public static void proxyHost(String host) { - properties.setProperty(PROXY_HOST_KEY, host); - } - - /** - * 代理端口 - */ - public static Integer proxyPort() { - try { - return Integer.parseInt(properties.getProperty(PROXY_PORT_KEY)); - } catch (Exception ignored) { - } - return null; - } - - /** - * 代理端口 - */ - public static void proxyPort(int port) { - properties.setProperty(PROXY_PORT_KEY, String.valueOf(port)); - } - - /** - * 翻译源 - */ - public static TranslateSource translateSource() { - String name = properties.getProperty(TRANSLATE_SOURCE_KEY, TranslateSource.FREE_GOOGLE.getName()); - return TranslateSource.get(name); - } - - /** - * 翻译源 - */ - public static void translateSource(TranslateSource source) { - properties.setProperty(TRANSLATE_SOURCE_KEY, source.getName()); - } - - /** - * 是否配置接口认证 - * - * @param source 翻译源 - */ - public static boolean hasTranslateApiKey(TranslateSource source) { - return StringUtils.isNoneBlank(translateSourceAppid(source)) - && StringUtils.isNoneBlank(translateSourceApikey(source)); - } - - /** - * 设置翻译源appid - * - * @param source 翻译源 - * @param appid appid - */ - public static void translateSourceAppid(TranslateSource source, String appid) { - properties.setProperty(getTranslateSourceAppidKey(source), appid); - } - - /** - * 获取翻译源appid - * - * @param source 翻译源 - * @return appid - */ - public static String translateSourceAppid(TranslateSource source) { - return properties.getProperty(getTranslateSourceAppidKey(source)); - } - - public static void translateSourceApikey(TranslateSource source, String apikey) { - properties.setProperty(getTranslateSourceApikeyKey(source), apikey); - } - - public static String translateSourceApikey(TranslateSource source) { - return properties.getProperty(getTranslateSourceApikeyKey(source)); - } - - public static Integer translateSourceQps(TranslateSource source) { - String qpsStr = properties.getProperty(getTranslateSourceQpsKey(source)); - return qpsStr == null ? source.getDefaultQps() : Integer.parseInt(qpsStr); - } - - public static void translateSourceQps(TranslateSource source, int qps) { - properties.setProperty(getTranslateSourceQpsKey(source), String.valueOf(qps)); - } - - - /** - * 保存配置 - */ - public static void store() { - // 生成配置文件 - try { - properties.store(new PrintStream(AppConstant.CUSTOM_CONFIG_PATH), String.valueOf(StandardCharsets.UTF_8)); - } catch (IOException e) { - logger.error("保存客户端配置失败", e); - } - } - - private static String getTranslateSourceAppidKey(TranslateSource source) { - return StringUtils.replace(TRANSLATE_SOURCE_APPID_KEY, "{}", source.getName()); - } - - private static String getTranslateSourceApikeyKey(TranslateSource source) { - return StringUtils.replace(TRANSLATE_SOURCE_APIKEY_KEY, "{}", source.getName()); - } - - private static String getTranslateSourceQpsKey(TranslateSource source) { - return StringUtils.replace(TRANSLATE_SOURCE_QPS_KEY, "{}", source.getName()); - } -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/controller/MainController.java b/src/main/java/cn/octopusyan/dayzmodtranslator/controller/MainController.java deleted file mode 100644 index 46bd3d1..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/controller/MainController.java +++ /dev/null @@ -1,515 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.controller; - -import cn.octopusyan.dayzmodtranslator.base.BaseController; -import cn.octopusyan.dayzmodtranslator.manager.PBOUtil; -import cn.octopusyan.dayzmodtranslator.manager.file.FileTreeItem; -import cn.octopusyan.dayzmodtranslator.manager.translate.TranslateUtil; -import cn.octopusyan.dayzmodtranslator.manager.word.WordCsvItem; -import cn.octopusyan.dayzmodtranslator.manager.word.WordItem; -import cn.octopusyan.dayzmodtranslator.util.AlertUtil; -import cn.octopusyan.dayzmodtranslator.util.ClipUtil; -import javafx.application.Platform; -import javafx.beans.property.StringProperty; -import javafx.collections.ObservableList; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.scene.control.*; -import javafx.scene.control.cell.TextFieldTableCell; -import javafx.scene.input.*; -import javafx.scene.layout.StackPane; -import javafx.scene.layout.VBox; -import javafx.stage.FileChooser; -import org.apache.commons.io.FileUtils; - -import java.io.File; -import java.io.IOException; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Function; -import java.util.regex.Pattern; - -/** - * 主控制器 - * - * @author octopus_yan@foxmail.com - */ -public class MainController extends BaseController { - - public VBox root; - public MenuItem openFileSetupBtn; - public MenuItem translateSetupBtn; - public MenuItem proxySetupBtn; - public Label filePath; - public StackPane fileBox; - public VBox openFileBox; - public Button openFile; - public VBox dragFileBox; - public Label dragFileLabel; - public VBox loadFileBox; - public Label loadFileLabel; - public ProgressBar loadFileProgressBar; - public TreeView treeFileBox; - public StackPane wordBox; - public TableView wordTableBox; - public VBox wordMsgBox; - public Label wordMsgLabel; - public ProgressBar loadWordProgressBar; - public Button translateWordBtn; - public Button packBtn; - private final PBOUtil pboUtil = PBOUtil.getInstance(); - private final TranslateUtil translateUtil = TranslateUtil.getInstance(); - - /** - * 翻译标志 用于停止翻译 - */ - private AtomicBoolean transTag; - /** - * 已翻译文本下标缓存 - */ - private Set transNum; - - @Override - public boolean dragWindow() { - return false; - } - - @Override - public VBox getRootPanel() { - return root; - } - - @Override - public String getRootFxml() { - return "main-view"; - } - - /** - * 初始化数据 - */ - @Override - public void initData() { - - // 解包监听 - pboUtil.setOnUnpackListener(new PBOUtil.OnUnpackListener() { - @Override - public void onStart() { - refreshWordBox(); - } - - @Override - public void onUnpackSuccess(String unpackDirPath) { - loadFileLabel.textProperty().setValue("加载完成,正在获取文件目录"); - // 展示解包文件内容 - logger.info("正在获取文件目录。。"); - showDirectory(new File(unpackDirPath)); - // 展示可翻译语句 - logger.info("正在查询待翻译文本目录。。"); - showTranslateWord(); - } - - @Override - public void onUnpackError(String msg) { - loadFileLabel.textProperty().setValue("打开文件失败"); - logger.info("打开文件失败: \n" + msg); - } - - @Override - public void onUnpackOver() { - - } - }); - - // 打包监听 - pboUtil.setOnPackListener(new PBOUtil.OnPackListener() { - @Override - public void onStart() { - showLoading("正在打包pbo文件"); - } - - @Override - public void onProgress(long current, long all) { - showLoading(String.format("正在打包pbo文件(%d / %d)", current, all)); - } - - @Override - public void onPackSuccess(File packFile) { - // 选择文件保存地址 - FileChooser fileChooser = new FileChooser(); - FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("PBO files (*.pbo)", "*.pbo"); - fileChooser.getExtensionFilters().add(extFilter); - File file = fileChooser.showSaveDialog(getWindow()); - if (file == null) - return; - if (file.exists()) { - //文件已存在,则删除覆盖文件 - FileUtils.deleteQuietly(file); - } - String exportFilePath = file.getAbsolutePath(); - logger.info("导出文件的路径 =>" + exportFilePath); - - try { - FileUtils.copyFile(packFile, file); - } catch (IOException e) { - logger.error("保存文件失败!", e); - - Platform.runLater(() -> AlertUtil.exception(e).content("保存文件失败!").show()); - } - } - - @Override - public void onPackError(String msg) { - AlertUtil.error("保存文件失败!").show(); - logger.info("保存文件失败: \n" + msg); - } - - @Override - public void onPackOver() { - stopLoading(); - } - }); - - // 获取待翻译文字 - pboUtil.setOnFindTransWordListener((words, isOver) -> { - loadWordProgressBar.setVisible(false); - - if (words == null || words.isEmpty()) { - if (isOver) { - wordMsgLabel.textProperty().set("未找到待翻译文本"); - } - } else { - // 展示翻译按钮 - translateWordBtn.setVisible(true); - // 展示打包按钮 - packBtn.setVisible(true); - - // 绑定TableView - boolean isCsvItem = (words.get(0) instanceof WordCsvItem); - bindWordTable(words, isCsvItem); - } - }); - - } - - /** - * 视图样式 - */ - @Override - public void initViewStyle() { - wordMsgLabel.textProperty().setValue("请打开PBO文件"); - } - - /** - * 视图事件 - */ - @Override - public void initViewAction() { - // 翻译设置 - translateSetupBtn.setOnAction(event -> open(SetupTranslateController.class, "翻译源设置")); - // 代理设置 - proxySetupBtn.setOnAction(event -> open(SetupProxyController.class, "代理设置")); - - // 选择pbo文件 - EventHandler selectPboFileAction = actionEvent -> { - // 文件选择器 - FileChooser fileChooser = new FileChooser(); - FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("PBO files (*.pbo)", "*.pbo"); - fileChooser.getExtensionFilters().add(extFilter); - selectFile(fileChooser.showOpenDialog(getWindow())); - }; - openFileSetupBtn.setOnAction(selectPboFileAction); - openFile.setOnAction(selectPboFileAction); - - // 拖拽效果 start --------------------- - fileBox.setOnDragEntered(dragEvent -> { - Dragboard dragboard = dragEvent.getDragboard(); - if (dragboard.hasFiles() && isPboFile(dragboard.getFiles().get(0))) { - disableBox(); - dragFileBox.setVisible(true); - } - }); - fileBox.setOnDragExited(dragEvent -> { - if (!loadFileBox.isVisible()) { - disableBox(); - openFileBox.setVisible(true); - } - }); - fileBox.setOnDragOver(dragEvent -> { - Dragboard dragboard = dragEvent.getDragboard(); - if (dragEvent.getGestureSource() != fileBox && dragboard.hasFiles()) { - /* allow for both copying and moving, whatever user chooses */ - dragEvent.acceptTransferModes(TransferMode.COPY_OR_MOVE); - } - dragEvent.consume(); - }); - fileBox.setOnDragDropped(dragEvent -> { - disableBox(); - openFileBox.setVisible(true); - - Dragboard db = dragEvent.getDragboard(); - boolean success = false; - File file = db.getFiles().get(0); - if (db.hasFiles() && isPboFile(file)) { - selectFile(file); - success = true; - } - /* 让源知道字符串是否已成功传输和使用 */ - dragEvent.setDropCompleted(success); - - dragEvent.consume(); - }); - // 拖拽效果 end --------------------- - - // 翻译按钮 - translateWordBtn.setOnMouseClicked(mouseEvent -> { - - // 是否初次翻译 - if (transTag == null) { - transNum = new HashSet<>(); - transTag = new AtomicBoolean(true); - // 开始翻译 - startTranslate(); - } else { - // 获取翻译列表 - ObservableList items = wordTableBox.getItems(); - // 未获取到翻译列表 或 翻译完成 则不做处理 - if (items == null || items.isEmpty() || transNum.size() == items.size()) - return; - - // 设置翻译标识 - transTag.set(!transTag.get()); - - if (Boolean.FALSE.equals(transTag.get())) { - stopTranslate(); - } else { - startTranslate(); - } - } - - - }); - - // 打包按钮 - packBtn.setOnAction(event -> pboUtil.pack(wordTableBox.getItems())); - - // 复制文本 - getRootPanel().getScene().getAccelerators() - .put(new KeyCodeCombination(KeyCode.C, KeyCombination.CONTROL_ANY), new Runnable() { - @Override - public void run() { - TablePosition tablePosition = wordTableBox.getSelectionModel().getSelectedCells().get(0); - Object cellData = tablePosition.getTableColumn().getCellData(tablePosition.getRow()); - ClipUtil.setClip(String.valueOf(cellData)); - } - }); - } - - /** - * 开始翻译 - */ - private void startTranslate() { - // 获取翻译列表 - ObservableList items = wordTableBox.getItems(); - if (items == null || items.isEmpty()) return; - - // 开始/继续 翻译 - String label = translateWordBtn.getText().replaceAll("已暂停|一键翻译", "正在翻译"); - translateWordBtn.textProperty().setValue(label); - - // 禁用打包按钮 - packBtn.setDisable(true); - - boolean isCsvItem = (items.get(0) instanceof WordCsvItem); - // 循环提交翻译任务 - for (int i = 0; i < items.size(); i++) { - // 跳过已翻译文本 - if (transNum.contains(i)) continue; - - WordItem item = items.get(i); - - // 提交翻译任务 - int finalI = i; - translateUtil.translate(finalI, item.getOriginal(), new TranslateUtil.OnTranslateListener() { - @Override - public void onTranslate(String result) { - // 防止多线程执行时停止不及时 - if (Boolean.FALSE.equals(transTag.get())) { - return; - } - - // 含有中文则不翻译 - if (!containsChinese(item.getChinese())) - item.setChinese(result); - - // 设置简中文本 - if (isCsvItem) { - WordCsvItem csvItem = ((WordCsvItem) item); - if (!containsChinese(csvItem.getChineseSimp())) - csvItem.setChineseSimp(result); - } - - // 设置翻译进度 - transNum.add(finalI); - String label; - if (transNum.size() >= items.size()) { - label = "翻译完成(" + items.size() + ")"; - transTag.set(false); - // 启用打包按钮 - packBtn.setDisable(false); - } else { - label = "正在翻译(" + transNum.size() + "/" + items.size() + ")"; - } - translateWordBtn.textProperty().setValue(label); - } - }); - } - } - - /** - * 停止翻译 - */ - private void stopTranslate() { - // 清除未完成的翻译任务 - translateUtil.clear(); - // 设置翻译状态 - String label = translateWordBtn.getText().replace("正在翻译", "已暂停"); - translateWordBtn.textProperty().setValue(label); - // 启用打包按钮 - packBtn.setDisable(false); - } - - /** - * 选择待汉化pbo文件 - *

TODO 多文件汉化 - * - * @param file 待汉化文件 - */ - private void selectFile(File file) { - if (file == null || !file.exists()) return; - - filePath.textProperty().set(file.getName()); - - // 重置文件界面 - disableBox(); - loadFileBox.setVisible(true); - // 重置翻译文本状态 - wordBox.getChildren().remove(wordTableBox); - wordTableBox = null; - - loadFileLabel.textProperty().setValue("正在加载模组文件"); - pboUtil.unpack(file); - } - - /** - * 展示文件夹内容 - * - * @param file 根目录 - */ - private void showDirectory(File file) { - if (file == null || !file.exists() || !file.isDirectory()) { - return; - } - disableBox(); - treeFileBox.setVisible(true); - - // 加载pbo文件目录 - FileTreeItem fileTreeItem = new FileTreeItem(file, File::listFiles); - treeFileBox.setRoot(fileTreeItem); - treeFileBox.setShowRoot(false); - } - - /** - * 展示待翻译语句 - */ - private void showTranslateWord() { - wordMsgLabel.textProperty().setValue("正在获取可翻译文本"); - loadWordProgressBar.setVisible(true); - - pboUtil.startFindWord(); - } - - /** - * 绑定表格数据 - * - * @param words 单词列表 - * @param isCsvItem 是否csv - */ - private void bindWordTable(List words, boolean isCsvItem) { - if (wordTableBox == null) { - wordTableBox = new TableView<>(); - wordBox.getChildren().add(wordTableBox); - // 可编辑 - wordTableBox.setEditable(true); - // 单元格选择模式而不是行选择 - wordTableBox.getSelectionModel().setCellSelectionEnabled(true); - // 不允许选择多个单元格 - wordTableBox.getSelectionModel().setSelectionMode(SelectionMode.SINGLE); - // 鼠标事件清空 - wordTableBox.addEventFilter(MouseEvent.MOUSE_PRESSED, event -> { - if (event.isControlDown()) { - return; - } - - if (wordTableBox.getEditingCell() == null) { - wordTableBox.getSelectionModel().clearSelection(); - } - }); - - // 创建列 - wordTableBox.getColumns().add(createColumn("原始文本", WordItem::originalProperty)); - wordTableBox.getColumns().add(createColumn("中文", WordItem::chineseProperty)); - - if (isCsvItem) { - wordTableBox.getColumns().add(createColumn("简体中文", WordCsvItem::chineseSimpProperty)); - } - } - - // 添加表数据 - wordTableBox.getItems().addAll(words); - } - - private TableColumn createColumn(String colName, Function colField) { - TableColumn tableColumn = new TableColumn<>(colName); - tableColumn.setCellValueFactory(features -> colField.apply((T) features.getValue())); - tableColumn.setCellFactory(TextFieldTableCell.forTableColumn()); - tableColumn.setPrefWidth(150); - tableColumn.setSortable(false); - tableColumn.setEditable(!"原始文本".equals(colName)); - return tableColumn; - } - - private void disableBox() { - openFileBox.setVisible(false); - dragFileBox.setVisible(false); - loadFileBox.setVisible(false); - treeFileBox.setVisible(false); - } - - private void refreshWordBox() { - if (wordTableBox != null) { - wordBox.getChildren().remove(wordTableBox); - wordTableBox = null; - } - wordMsgLabel.textProperty().setValue("请打开pbo文件"); - loadWordProgressBar.setVisible(false); - translateWordBtn.textProperty().setValue("一键翻译"); - translateWordBtn.setVisible(false); - packBtn.setVisible(false); - } - - private boolean isPboFile(File file) { - if (file == null) return false; - return Pattern.compile(".*(.pbo)$").matcher(file.getName()).matches(); - } - - /** - * 给定字符串是否含有中文 - * - * @param str 需要判断的字符串 - * @return 是否含有中文 - */ - private boolean containsChinese(String str) { - return Pattern.compile("[\u4e00-\u9fa5]").matcher(str).find(); - } -} \ No newline at end of file diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/controller/SetupProxyController.java b/src/main/java/cn/octopusyan/dayzmodtranslator/controller/SetupProxyController.java deleted file mode 100644 index 8694915..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/controller/SetupProxyController.java +++ /dev/null @@ -1,162 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.controller; - -import cn.octopusyan.dayzmodtranslator.base.BaseController; -import cn.octopusyan.dayzmodtranslator.config.CustomConfig; -import cn.octopusyan.dayzmodtranslator.util.AlertUtil; -import cn.octopusyan.dayzmodtranslator.util.FxmlUtil; -import cn.octopusyan.dayzmodtranslator.manager.http.HttpUtil; -import javafx.scene.control.TextField; -import javafx.scene.layout.StackPane; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.math.NumberUtils; - -import java.io.IOException; -import java.net.URI; - -/** - * 应用配置 - * - * @author octopus_yan@foxmail.com - */ -public class SetupProxyController extends BaseController { - public StackPane root; - public TextField hostField; - public TextField portField; - public TextField testPath; - public static final String PROXY_ERROR = "ProxyError"; - - /** - * 窗口拖拽设置 - * - * @return 是否启用 - */ - @Override - public boolean dragWindow() { - return false; - } - - /** - * 获取根布局 - * - * @return 根布局对象 - */ - @Override - public StackPane getRootPanel() { - return root; - } - - /** - * 获取根布局 - *

搭配 FxmlUtil.load 使用 - * - * @return 根布局对象 - * @see FxmlUtil#load(String) - */ - @Override - public String getRootFxml() { - return "proxy-view"; - } - - /** - * 初始化数据 - */ - @Override - public void initData() { - // 是否已有代理配置 - if (CustomConfig.hasProxy()) { - hostField.textProperty().setValue(CustomConfig.proxyHost()); - portField.textProperty().setValue(String.valueOf(CustomConfig.proxyPort())); - } - - // 默认测试地址 - testPath.textProperty().setValue("https://translate.googleapis.com"); - } - - /** - * 视图样式 - */ - @Override - public void initViewStyle() { - - } - - /** - * 视图事件 - */ - @Override - public void initViewAction() { - - } - - private String getHost() { - String text = hostField.getText(); - if (StringUtils.isBlank(text)) { - throw new RuntimeException(PROXY_ERROR); - } - try { - URI.create(text); - } catch (Exception e) { - throw new RuntimeException(PROXY_ERROR); - } - - return text; - } - - private int getPort() { - String text = portField.getText(); - if (StringUtils.isBlank(text)) { - throw new RuntimeException(); - } - - boolean creatable = NumberUtils.isCreatable(text); - if (!creatable) { - throw new RuntimeException(PROXY_ERROR); - } - - return Integer.parseInt(text); - } - - private String getTestPath() { - String text = testPath.getText(); - if (StringUtils.isBlank(text)) { - throw new RuntimeException(PROXY_ERROR); - } - return (text.startsWith("http") ? "" : "http://") + text; - } - - /** - * 测试代理有效性 - */ - public void test() { - HttpUtil.getInstance().clearProxy(); - try { - String resp = HttpUtil.getInstance().proxy(getHost(), getPort()) - .get(getTestPath(), null, null); - AlertUtil.info("成功").show(); - } catch (IOException | InterruptedException e) { - logger.error("代理访问失败", e); - AlertUtil.error("失败!").show(); - } - } - - /** - * 保存代理配置 - */ - public void save() { - CustomConfig.proxyHost(getHost()); - CustomConfig.proxyPort(getPort()); - - CustomConfig.store(); - - onDestroy(); - } - - /** - * 取消 - */ - public void close() { - HttpUtil.getInstance().clearProxy(); - - onDestroy(); - } -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/controller/SetupTranslateController.java b/src/main/java/cn/octopusyan/dayzmodtranslator/controller/SetupTranslateController.java deleted file mode 100644 index f9c879f..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/controller/SetupTranslateController.java +++ /dev/null @@ -1,127 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.controller; - -import cn.octopusyan.dayzmodtranslator.base.BaseController; -import cn.octopusyan.dayzmodtranslator.config.CustomConfig; -import cn.octopusyan.dayzmodtranslator.manager.translate.TranslateSource; -import cn.octopusyan.dayzmodtranslator.util.AlertUtil; -import javafx.collections.ObservableList; -import javafx.scene.control.ComboBox; -import javafx.scene.control.TextField; -import javafx.scene.layout.StackPane; -import javafx.scene.layout.VBox; -import javafx.util.StringConverter; -import org.apache.commons.lang3.StringUtils; - -/** - * 翻译设置控制器 - * - * @author octopus_yan@foxmail.com - */ -public class SetupTranslateController extends BaseController { - public StackPane root; - public ComboBox translateSourceCombo; - public TextField qps; - public VBox appidBox; - public TextField appid; - public VBox apikeyBox; - public TextField apikey; - - @Override - public boolean dragWindow() { - return false; - } - - @Override - public StackPane getRootPanel() { - return root; - } - - @Override - public String getRootFxml() { - return "translate-view"; - } - - /** - * 初始化数据 - */ - @Override - public void initData() { - // 翻译源 - for (TranslateSource value : TranslateSource.values()) { - ObservableList items = translateSourceCombo.getItems(); - items.addAll(value); - } - translateSourceCombo.setConverter(new StringConverter<>() { - @Override - public String toString(TranslateSource object) { - if (object == null) return null; - - return object.getLabel(); - } - - @Override - public TranslateSource fromString(String string) { - return TranslateSource.getByLabel(string); - } - }); - translateSourceCombo.getSelectionModel() - .selectedItemProperty() - .addListener((observable, oldValue, newValue) -> { - boolean needApiKey = newValue.needApiKey(); - appidBox.setVisible(needApiKey); - apikeyBox.setVisible(needApiKey); - if (needApiKey) { - appid.textProperty().setValue(CustomConfig.translateSourceAppid(newValue)); - apikey.textProperty().setValue(CustomConfig.translateSourceApikey(newValue)); - - } - - qps.textProperty().setValue(String.valueOf(CustomConfig.translateSourceQps(newValue))); - }); - - // 当前翻译源 - translateSourceCombo.getSelectionModel().select(CustomConfig.translateSource()); - } - - /** - * 视图样式 - */ - @Override - public void initViewStyle() { - - } - - /** - * 视图事件 - */ - @Override - public void initViewAction() { - qps.textProperty().addListener((observable, oldValue, newValue) -> { - if (!newValue.matches("\\d*")) { - qps.setText(oldValue); - } - }); - } - - public void save() { - TranslateSource source = translateSourceCombo.getValue(); - String apikey = this.apikey.getText(); - String appid = this.appid.getText(); - int qps = Integer.parseInt(this.qps.getText()); - - CustomConfig.translateSource(source); - if (source.needApiKey()) { - if (StringUtils.isBlank(apikey) || StringUtils.isBlank(appid)) { - AlertUtil.error("认证信息不能为空"); - } - - CustomConfig.translateSourceApikey(source, apikey); - CustomConfig.translateSourceAppid(source, appid); - CustomConfig.translateSourceQps(source, qps); - } - // 保存到文件 - CustomConfig.store(); - // 退出 - onDestroy(); - } -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/CfgConvertUtil.java b/src/main/java/cn/octopusyan/dayzmodtranslator/manager/CfgConvertUtil.java deleted file mode 100644 index 37b1882..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/CfgConvertUtil.java +++ /dev/null @@ -1,137 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.manager; - -import cn.octopusyan.dayzmodtranslator.config.AppConstant; -import cn.octopusyan.dayzmodtranslator.util.FileUtil; -import cn.octopusyan.dayzmodtranslator.util.ProcessesUtil; -import org.apache.commons.io.FileUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.IOException; -import java.util.Objects; - -/** - * Cfg文件转换工具类 - * - * @author octopus_yan@foxmail.com - */ -public class CfgConvertUtil { - private static final Logger logger = LoggerFactory.getLogger(CfgConvertUtil.class); - private static CfgConvertUtil util; - private static final String CfgConvert_DIR_PATH = AppConstant.DATA_DIR_PATH + File.separator + "CfgConvert"; - private static final File CfgConvert_DIR = new File(CfgConvert_DIR_PATH); - private static final String CfgConvert_FILE_PATH = CfgConvert_DIR_PATH + File.separator + "CfgConvert.exe"; - private static final File CfgConvert_FILE = new File(CfgConvert_FILE_PATH); - private static final String COMMAND = CfgConvert_FILE_PATH + " %s -dst %s %s"; - - private CfgConvertUtil() { - } - - public static void init() { - if (util == null) { - util = new CfgConvertUtil(); - } - // 检查pbo解析文件 - util.checkCfgConvert(); - } - - public static synchronized CfgConvertUtil getInstance() { - if (util == null) - throw new RuntimeException("are you ready ?"); - return util; - } - - /** - * 检查Cfg转换文件 - */ - private void checkCfgConvert() { - if (!CfgConvert_FILE.exists()) initCfgConvert(); - } - - private void initCfgConvert() { - try { - FileUtils.forceMkdir(CfgConvert_DIR); - String cfgConvertFileName = "CfgConvert.exe"; - FileUtil.copyFile(Objects.requireNonNull(CfgConvertUtil.class.getResourceAsStream("/static/CfgConvert/" + cfgConvertFileName)), new File(CfgConvert_DIR_PATH + File.separator + cfgConvertFileName)); - } catch (IOException e) { - logger.error("", e); - } - } - - public void toTxt(File binFile, String outPath, OnToTxtListener onToTxtListener) { - String fileName = binFile.getAbsolutePath(); - ProcessesUtil.exec(toTxtCommand(binFile, outPath), new ProcessesUtil.OnExecuteListener() { - @Override - public void onExecute(String msg) { - logger.info(fileName + " : " + msg); - } - - @Override - public void onExecuteSuccess(int exitValue) { - logger.info(fileName + " : to txt success"); - String outFilePath = outFilePath(binFile, outPath, ".cpp"); - if (onToTxtListener != null) { - onToTxtListener.onToTxtSuccess(outFilePath); - } - } - - @Override - public void onExecuteError(Exception e) { - logger.error(fileName + " : to txt error", e); - if (onToTxtListener != null) { - onToTxtListener.onToTxtError(e); - } - } - - @Override - public void onExecuteOver() { - logger.info(fileName + " : to txt end..."); - } - }); - } - - public void toBin(File cppFile) { - ProcessesUtil.exec(toBinCommand(cppFile, cppFile.getParentFile().getAbsolutePath()), new ProcessesUtil.OnExecuteListener() { - @Override - public void onExecute(String msg) { - - } - - @Override - public void onExecuteSuccess(int exitValue) { - - } - - @Override - public void onExecuteError(Exception e) { - - } - - @Override - public void onExecuteOver() { - - } - }); - } - - private String toBinCommand(File cppFile, String outPath) { - String outFilePath = outFilePath(cppFile, outPath, ".bin"); - return String.format(COMMAND, "-bin", outFilePath, cppFile.getAbsolutePath()); - } - - private String toTxtCommand(File binFile, String outPath) { - String outFilePath = outFilePath(binFile, outPath, ".cpp"); - return String.format(COMMAND, "-txt", outFilePath, binFile.getAbsolutePath()); - } - - private String outFilePath(File file, String outPath, String suffix) { - return outPath + File.separator + FileUtil.mainName(file) + suffix; - } - - public interface OnToTxtListener { - void onToTxtSuccess(String txtFilePath); - - void onToTxtError(Exception e); - } -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/PBOUtil.java b/src/main/java/cn/octopusyan/dayzmodtranslator/manager/PBOUtil.java deleted file mode 100644 index c942531..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/PBOUtil.java +++ /dev/null @@ -1,628 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.manager; - -import cn.octopusyan.dayzmodtranslator.config.AppConstant; -import cn.octopusyan.dayzmodtranslator.manager.thread.ThreadPoolManager; -import cn.octopusyan.dayzmodtranslator.manager.word.WordCsvItem; -import cn.octopusyan.dayzmodtranslator.manager.word.WordItem; -import cn.octopusyan.dayzmodtranslator.util.AlertUtil; -import cn.octopusyan.dayzmodtranslator.util.FileUtil; -import cn.octopusyan.dayzmodtranslator.util.ProcessesUtil; -import javafx.application.Platform; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.apache.commons.io.LineIterator; -import org.apache.commons.io.filefilter.NameFileFilter; -import org.apache.commons.io.filefilter.TrueFileFilter; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.*; -import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -/** - * PBO 工具类 - * - * @author octopus_yan@foxmail.com - * @see https://github.com/winseros/pboman3 - */ -public class PBOUtil { - private static final Logger logger = LoggerFactory.getLogger(PBOUtil.class); - private static PBOUtil util; - private static final String PBOC_DIR_PATH = AppConstant.DATA_DIR_PATH + File.separator + "pboman"; - private static final File PBOC_DIR = new File(PBOC_DIR_PATH); - private static final String PBOC_FILE_PATH = PBOC_DIR_PATH + File.separator + "pboc.exe"; - private static final File PBOC_FILE = new File(PBOC_FILE_PATH); - private static final String UNPACK_COMMAND = PBOC_FILE_PATH + " unpack -o " + AppConstant.TMP_DIR_PATH + " %s"; - private static final String PACK_COMMAND = PBOC_FILE_PATH + " pack -o %s %s"; - private OnPackListener onPackListener; - private OnUnpackListener onUnpackListener; - private OnFindTransWordListener onFindTransWordListener; - private String unpackPath; - private CfgConvertUtil cfgConvertUtil; - private static final String FILE_NAME_STRING_TABLE = "stringtable.csv"; - private static final String FILE_NAME_CONFIG_BIN = "config.bin"; - private static final String FILE_NAME_CONFIG_CPP = "config.cpp"; - - private PBOUtil() { - } - - public static void init(CfgConvertUtil cfgConvertUtil) { - if (util == null) { - util = new PBOUtil(); - } - // cfg转换工具 - util.cfgConvertUtil = cfgConvertUtil; - // 检查pbo解析文件 - util.checkPboc(); - } - - public static synchronized PBOUtil getInstance() { - if (util == null) - throw new RuntimeException("are you ready ?"); - return util; - } - - /** - * 设置打包监听器 - * - * @param onPackListener 打包监听器 - */ - public void setOnPackListener(OnPackListener onPackListener) { - this.onPackListener = onPackListener; - } - - /** - * 设置解包监听器 - * - * @param onUnpackListener 监听器 - */ - public void setOnUnpackListener(OnUnpackListener onUnpackListener) { - this.onUnpackListener = onUnpackListener; - } - - public void setOnFindTransWordListener(OnFindTransWordListener onFindTransWordListener) { - this.onFindTransWordListener = onFindTransWordListener; - } - - private void checkPboc() { - if (!PBOC_FILE.exists()) initPboc(); - } - - private void initPboc() { - try { - FileUtils.forceMkdir(PBOC_DIR); - String pbocFileName = "pboc.exe"; - String dllFileName = "Qt6Core.dll"; - FileUtil.copyFile(Objects.requireNonNull(PBOUtil.class.getResourceAsStream("/static/pboc/" + pbocFileName)), new File(PBOC_DIR_PATH + File.separator + pbocFileName)); - FileUtil.copyFile(Objects.requireNonNull(PBOUtil.class.getResourceAsStream("/static/pboc/" + dllFileName)), new File(PBOC_DIR_PATH + File.separator + dllFileName)); - } catch (IOException e) { - logger.error("", e); - } - } - - /** - * 解压PBO文件 - * - * @param file PBO文件 - */ - public void unpack(File file) { - // 检查pbo解包程序 - checkPboc(); - // 清理缓存 - clear(); - - if (onUnpackListener != null) { - onUnpackListener.onStart(); - } - - String filePath = file.getAbsolutePath(); - if (filePath.contains(" ")) filePath = "\"" + filePath + "\""; - - String command = String.format(UNPACK_COMMAND, filePath); - logger.info(command); - try { - FileUtils.forceMkdir(new File(AppConstant.TMP_DIR_PATH)); - - // 执行命令 - ProcessesUtil.exec(command, new ProcessesUtil.OnExecuteListener() { - @Override - public void onExecute(String msg) { - logger.info(msg); - } - - @Override - public void onExecuteSuccess(int exitValue) { - if (exitValue != 0) { - String msg = "打开PBO文件失败!"; - logger.error(msg); - if (onUnpackListener != null) { - Platform.runLater(() -> { - onUnpackListener.onUnpackError(msg); - onUnpackListener.onUnpackOver(); - }); - } - return; - } - logger.info("打开PBO文件成功!"); - unpackPath = AppConstant.TMP_DIR_PATH + File.separator + FileUtil.mainName(file); - if (onUnpackListener != null) { - Platform.runLater(() -> { - onUnpackListener.onUnpackSuccess(unpackPath); - onUnpackListener.onUnpackOver(); - }); - } - } - - @Override - public void onExecuteError(Exception e) { - logger.error("", e); - if (onUnpackListener != null) { - Platform.runLater(() -> { - onUnpackListener.onUnpackError(e.getMessage()); - onUnpackListener.onUnpackOver(); - }); - } - } - - @Override - public void onExecuteOver() { - if (onUnpackListener != null) { - Platform.runLater(() -> onUnpackListener.onUnpackOver()); - } - } - }); - } catch (Exception e) { - logger.error("", e); - if (onUnpackListener != null) { - Platform.runLater(() -> { - onUnpackListener.onUnpackError(e.getMessage()); - onUnpackListener.onUnpackOver(); - }); - } - } - } - - /** - * 获取待翻译单词列表 - */ - public void startFindWord() { - // 检查pbo解包文件 - if (unpackPath == null || StringUtils.isBlank(unpackPath)) - throw new RuntimeException("No PBO file was obtained !"); - - ThreadPoolManager.getInstance().execute(() -> { - if (hasStringTable()) { - List worlds = new ArrayList<>(readCsvFile()); - if (onFindTransWordListener != null) { - Platform.runLater(() -> onFindTransWordListener.onFoundWords(worlds, true)); - } - } else { - findConfigWord(); - } - }); - } - - /** - * 获取csv中 原文及 简中单词 - * - * @return 待翻译语句列表 - */ - private List readCsvFile() { - List list = new ArrayList<>(); - AtomicInteger position = new AtomicInteger(0); - File stringTable = new File(unpackPath + File.separator + FILE_NAME_STRING_TABLE); - try (LineIterator it = FileUtils.lineIterator(stringTable, StandardCharsets.UTF_8.name())) { - while (it.hasNext()) { - String line = it.nextLine(); - - if (line.isEmpty() || line.startsWith("//") || line.startsWith("\"Language\"")) { - position.addAndGet(1); - continue; - } - - // 原句 - int startIndex = line.indexOf(",\"") + 2; - int endIndex = line.indexOf("\"", startIndex); - String original = line.substring(startIndex, endIndex); - - // 中文 - startIndex = StringUtils.ordinalIndexOf(line, ",\"", 11) + 2; - endIndex = line.indexOf("\"", startIndex); - int[] chinesePosition = new int[]{startIndex, endIndex}; - String chinese = line.substring(startIndex, endIndex); - - // 简中 - startIndex = StringUtils.ordinalIndexOf(line, ",\"", 14) + 2; - endIndex = line.indexOf("\"", startIndex); - int[] chineseSimpPosition = new int[]{startIndex, endIndex}; - String chineseSimp = line.substring(startIndex, endIndex); - - // 添加单词 - list.add(new WordCsvItem(stringTable, position.get(), original, chinese, chinesePosition, chineseSimp, chineseSimpPosition)); - - position.addAndGet(1); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - - list.sort(Comparator.comparingInt(WordItem::getLines)); - return list; - } - - /** - * 获取所有 config.bin 文件内 可翻译内容 - */ - private void findConfigWord() { - - // 搜索所有的 config.bin 文件,并按路径解包到bak文件夹 - List files = new ArrayList<>(FileUtils.listFiles(new File(unpackPath), new NameFileFilter(FILE_NAME_CONFIG_BIN, FILE_NAME_CONFIG_CPP), TrueFileFilter.INSTANCE)); - - files.forEach(file -> { - - // 转换bin文件为cpp可读取文件 - if (file.getName().endsWith("bin")) { - cfgConvertUtil.toTxt(file, file.getParentFile().getAbsolutePath(), new CfgConvertUtil.OnToTxtListener() { - @Override - public void onToTxtSuccess(String txtFilePath) { - // 读取 cpp 文件 - readCppFile(new File(txtFilePath), file.equals(files.get(files.size() - 1))); - } - - @Override - public void onToTxtError(Exception e) { - Platform.runLater(() -> { - AlertUtil.exception(e).content(FILE_NAME_CONFIG_BIN + "文件转换失败").show(); - }); - } - }); - } else { - // 读取 cpp 文件 - readCppFile(file, file.equals(files.get(files.size() - 1))); - } - }); - } - - - private static final Pattern pattern = Pattern.compile(".*((displayName|descriptionShort).?=.?\").*"); - - /** - * 读取cpp文件,查询可翻译文本 - * - * @param file cpp文件 - */ - private void readCppFile(File file, boolean isEnd) { - List list = new ArrayList<>(); - AtomicInteger lines = new AtomicInteger(0); - try (LineIterator it = FileUtils.lineIterator(file, StandardCharsets.UTF_8.name())) { - while (it.hasNext()) { - String line = it.nextLine(); - - Matcher matcher = pattern.matcher(line); - if (!line.contains("$") && matcher.find()) { - - String name = matcher.group(1); - - // 原始文本 - int startIndex = line.indexOf(name) + name.length(); - - int endIndex = line.indexOf("\"", startIndex); - String original; - try { - original = line.substring(startIndex, endIndex); - } catch (Exception e) { - lines.addAndGet(1); - continue; - } - - // 添加单词 - if (!"".endsWith(original) && !containsChinese(original)) { - list.add(new WordItem(file, lines.get(), original, "", new int[]{startIndex, endIndex})); - } - } - - lines.addAndGet(1); - } - } catch (IOException e) { - logger.error("", e); - throw new RuntimeException(e); - } - - list.sort(Comparator.comparingInt(WordItem::getLines)); - - if (onFindTransWordListener != null) { - Platform.runLater(() -> onFindTransWordListener.onFoundWords(list, isEnd)); - } - } - - /** - * 给定字符串是否存在中文 - * - * @param str 字符串 - * @return 是否存在中文 - */ - private boolean containsChinese(String str) { - // [\u4e00-\u9fa5] - return Pattern.compile("[\u4e00-\u9fa5]").matcher(str).find(); - } - - /** - * 打包PBO文件 - */ - public void pack(List words) { - if (onPackListener != null) { - Platform.runLater(() -> onPackListener.onStart()); - } - - ThreadPoolManager.getInstance().execute(() -> { - File unpackDir; - if (StringUtils.isBlank(unpackPath) - || !(unpackDir = new File(unpackPath)).exists() - || !unpackDir.isDirectory() - ) { - AlertUtil.error("未获取到打开的pbo文件!").show(); - return; - } - - // 写入翻译后文本 - try { - writeWords(words); - } catch (Exception e) { - logger.error("writeWords error", e); - if (onPackListener != null) { - Platform.runLater(() -> { - onPackListener.onPackOver(); - onPackListener.onPackError("writeWords error ==> " + e.getMessage()); - }); - } - throw new RuntimeException(e); - } - - // 打包文件临时保存路径 - String packFilePath = unpackPath + ".pbo"; - File packFile = new File(packFilePath); - if (packFile.exists()) { - // 如果存在则删除 - FileUtils.deleteQuietly(packFile); - } - - // 执行打包指令 - String command = String.format(PACK_COMMAND, AppConstant.TMP_DIR_PATH, unpackPath); - logger.info(command); - ProcessesUtil.exec(command, new ProcessesUtil.OnExecuteListener() { - @Override - public void onExecute(String msg) { - logger.info(msg); - } - - @Override - public void onExecuteSuccess(int exitValue) { - Platform.runLater(() -> { - if (exitValue != 0) { - logger.error("保存PBO文件失败!"); - if (onPackListener != null) { - onPackListener.onPackOver(); - onPackListener.onPackError("保存PBO文件失败!"); - } - } else { - if (onPackListener != null) { - onPackListener.onPackOver(); - onPackListener.onPackSuccess(packFile); - } - } - }); - } - - @Override - public void onExecuteError(Exception e) { - logger.error("保存PBO文件失败!"); - if (onPackListener != null) { - Platform.runLater(() -> { - onPackListener.onPackOver(); - onPackListener.onPackError(e.getMessage()); - }); - } - } - - @Override - public void onExecuteOver() { - if (onPackListener != null) { - Platform.runLater(() -> onPackListener.onPackOver()); - } - } - }); - }); - } - - /** - * 写入翻译文本 - * - * @param words 已经翻译好的文本对象 - */ - private void writeWords(List words) throws Exception { - Map> wordMap = words.stream() - .collect(Collectors.groupingBy(WordItem::getFile, Collectors.toList())); - - AtomicInteger progress = new AtomicInteger(0); - - // 0 执行成功 大于0 执行失败 - List> result = new ArrayList<>(); - - for (Map.Entry> entry : wordMap.entrySet()) { - Future submit = ThreadPoolManager.getInstance().submit(() -> { - try { - entry.getValue().sort(Comparator.comparingInt(WordItem::getLines)); - - File file = entry.getKey(); - // 创建备份文件 - File bakFile = getWordBakFile(file); - // 判断重复打包时 备份文件处理 - if (!bakFile.exists()) { - FileUtils.copyFile(file, bakFile); - } - - // 清空原始文件 - FileWriter fileWriter = new FileWriter(file); - fileWriter.write(""); - fileWriter.flush(); - fileWriter.close(); - - // 遍历拼接翻译文本并写入 - long lines = 0; - String line; - LineIterator it = FileUtils.lineIterator(bakFile, StandardCharsets.UTF_8.name()); - while (it.hasNext() && !entry.getValue().isEmpty()) { - line = it.nextLine(); - - WordItem item = entry.getValue().get(0); - int[] ip = item.getPosition(); - - // 拼接翻译后的文本 - if (lines == item.getLines()) { - if (item instanceof WordCsvItem csv) { - int[] simp = csv.getPositionSimp(); - // 判断 ip 是否比 simp 靠前 - boolean tag = ip[0] < simp[0]; - line = line.substring(0, (tag ? ip : simp)[0]) - + (tag ? csv.getChinese() : csv.getChineseSimp()) - + line.substring((tag ? ip : simp)[1], (tag ? simp : ip)[0]) - + (tag ? csv.getChineseSimp() : csv.getChinese()) - + line.substring((tag ? simp : ip)[1]); - } else { - try { - line = line.substring(0, ip[0]) - + item.getChinese() - + line.substring(ip[1]); - } catch (Exception e) { - System.out.println(line); - } - } - - entry.getValue().remove(item); - if (onPackListener != null) { - Platform.runLater(() -> onPackListener.onProgress(progress.addAndGet(1), words.size())); - } - } - - // 写入原始文件 - FileUtils.writeStringToFile(file, line + System.lineSeparator(), StandardCharsets.UTF_8, true); - - lines++; - } - - // 关闭流 - IOUtils.closeQuietly(it); - - // cpp 文件需要 转换为 bin - if (file.getName().endsWith("cpp")) { - File binFile = new File(file.getParent() + File.separator + FileUtil.mainName(file) + ".bin"); - if (binFile.exists()) { - // 转为bin文件 - cfgConvertUtil.toBin(file); - // 删除cpp文件 - FileUtils.deleteQuietly(file); - } - // 同目录下不存在bin文件,说明原始文件为cpp 无需转换 - } - } catch (Exception e) { - logger.error("写入翻译文本失败", e); - // 执行失败 - return 1; - } - // 执行成功 - return 0; - }); - - // 添加执行结果 - result.add(submit); - } - - for (Future future : result) { - if (future.get() > 0) - throw new IOException(); - } - } - - private File getWordBakFile(File wordFile) { - return new File(wordFile.getAbsolutePath().replace(unpackPath, AppConstant.BAK_FILE_PATH)); - } - - /** - * 是否有国际化翻译文件 - * - * @return 是否有 stringtable.csv 文件 - */ - private boolean hasStringTable() { - List fileNames = FileUtil.listFileNames(unpackPath); - return fileNames.stream().anyMatch(FILE_NAME_STRING_TABLE::equals); - } - - /** - * 清理缓存文件 - */ - public static void clear() { - File tmpDest = new File(AppConstant.TMP_DIR_PATH); - - if (tmpDest.exists()) - FileUtils.deleteQuietly(tmpDest); - } - - public interface OnUnpackListener { - /** - * 开始解包 - */ - void onStart(); - - /** - * 解包完成 - * - * @param unpackDirPath 解包文件夹绝对路径 - */ - void onUnpackSuccess(String unpackDirPath); - - /** - * 解包失败 - * - * @param msg 失败信息 - */ - void onUnpackError(String msg); - - void onUnpackOver(); - } - - public interface OnPackListener { - /** - * 开始解包 - */ - void onStart(); - - void onProgress(long current, long all); - - /** - * 打包完成 - */ - void onPackSuccess(File packFile); - - /** - * 打包失败 - * - * @param msg 失败信息 - */ - void onPackError(String msg); - - void onPackOver(); - } - - public interface OnFindTransWordListener { - void onFoundWords(List worlds, boolean isOver); - } -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/file/FileIcon.java b/src/main/java/cn/octopusyan/dayzmodtranslator/manager/file/FileIcon.java deleted file mode 100644 index 1ce5598..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/file/FileIcon.java +++ /dev/null @@ -1,49 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.manager.file; - - -import javafx.scene.canvas.Canvas; -import javafx.scene.image.PixelFormat; -import javafx.scene.image.PixelWriter; -import javafx.scene.image.WritablePixelFormat; - -import javax.swing.*; -import javax.swing.filechooser.FileSystemView; -import java.awt.*; -import java.awt.image.BufferedImage; -import java.awt.image.DataBufferInt; -import java.io.File; -import java.nio.IntBuffer; - -/** - * 文件图标 - * - * @author octopus_yan@foxmail.com - */ -public class FileIcon { - //设置图标 - public static Canvas getFileIconToNode(File file) { - //获取系统文件的图标 - Image image = ((ImageIcon) FileSystemView.getFileSystemView().getSystemIcon(file)).getImage(); - //构建图片缓冲区,设定图片缓冲区的大小和背景,背景为透明 - BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.BITMASK); - //把图片画到图片缓冲区 - bi.getGraphics().drawImage(image, 0, 0, null); - //将图片缓冲区的数据转换成int型数组 - int[] data = ((DataBufferInt) bi.getData().getDataBuffer()).getData(); - //获得写像素的格式模版 - WritablePixelFormat pixelFormat = PixelFormat.getIntArgbInstance(); - //新建javafx的画布 - Canvas canvas = new Canvas(bi.getWidth() + 2, bi.getHeight() + 2); - //获取像素的写入器 - PixelWriter pixelWriter = canvas.getGraphicsContext2D().getPixelWriter(); - //根据写像素的格式模版把int型数组写到画布 - pixelWriter.setPixels(0, 0, bi.getWidth(), bi.getHeight(), pixelFormat, data, 0, bi.getWidth()); - //设置树节点的图标 - return canvas; - - } - - public static String getFileName(File file) { - return FileSystemView.getFileSystemView().getSystemDisplayName(file); - } -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/file/FileTreeItem.java b/src/main/java/cn/octopusyan/dayzmodtranslator/manager/file/FileTreeItem.java deleted file mode 100644 index 9068700..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/file/FileTreeItem.java +++ /dev/null @@ -1,90 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.manager.file; - -import javafx.collections.ObservableList; -import javafx.scene.control.TreeItem; - -import javax.swing.filechooser.FileSystemView; -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Function; - -/** - * 文件目录 - * - * @author octopus_yan@foxmail.com - */ -public class FileTreeItem extends TreeItem { - public static File ROOT_FILE = FileSystemView.getFileSystemView().getRoots()[0]; - - //判断树节点是否被初始化,没有初始化为真 - private boolean notInitialized = true; - - private final File file; - private final Function supplier; - - public FileTreeItem(File file) { - super(FileIcon.getFileName(file), FileIcon.getFileIconToNode(file)); - this.file = file; - supplier = (File f) -> { - if (((FileTreeItem) this.getParent()).getFile() == ROOT_FILE) { - String name = FileIcon.getFileName(f); - if (name.equals("网络") || name.equals("家庭组")) { - return new File[0]; - } - } - return f.listFiles(); - }; - } - - public FileTreeItem(File file, Function supplier) { - super(FileIcon.getFileName(file), FileIcon.getFileIconToNode(file)); - this.file = file; - this.supplier = supplier; - } - - - //重写getchildren方法,让节点被展开时加载子目录 - @Override - public ObservableList> getChildren() { - - ObservableList> children = super.getChildren(); - //没有加载子目录时,则加载子目录作为树节点的孩子 - if (this.notInitialized && this.isExpanded()) { - - this.notInitialized = false; //设置没有初始化为假 - - /* - *判断树节点的文件是否是目录, - *如果是目录,着把目录里面的所有的文件添加入树节点的孩子中。 - */ - if (this.getFile().isDirectory()) { - List fileList = new ArrayList<>(); - for (File f : supplier.apply(this.getFile())) { - if (f.isDirectory()) - children.add(new FileTreeItem(f)); - else - fileList.add(new FileTreeItem(f)); - } - children.addAll(fileList); - } - } - return children; - } - - //重写叶子方法,如果该文件不是目录,则返回真 - @Override - public boolean isLeaf() { - - return !file.isDirectory(); - } - - /** - * @return the file - */ - public File getFile() { - return file; - } - - -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/http/HttpConfig.java b/src/main/java/cn/octopusyan/dayzmodtranslator/manager/http/HttpConfig.java deleted file mode 100644 index 0936834..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/http/HttpConfig.java +++ /dev/null @@ -1,183 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.manager.http; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLParameters; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; -import java.net.Authenticator; -import java.net.CookieHandler; -import java.net.ProxySelector; -import java.net.http.HttpClient; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.concurrent.Executor; - -/** - * Http配置参数 - * - * @author octopus_yan@foxmail.com - */ -public class HttpConfig { - private static final Logger logger = LoggerFactory.getLogger(HttpConfig.class); - /** - * http版本 - */ - private HttpClient.Version version = HttpClient.Version.HTTP_2; - - /** - * 转发策略 - */ - private HttpClient.Redirect redirect = HttpClient.Redirect.NORMAL; - - /** - * 线程池 - */ - private Executor executor; - - /** - * 认证 - */ - private Authenticator authenticator; - - /** - * 代理 - */ - private ProxySelector proxySelector; - - /** - * CookieHandler - */ - private CookieHandler cookieHandler; - - /** - * sslContext - */ - private SSLContext sslContext; - - /** - * sslParams - */ - private SSLParameters sslParameters; - - /** - * 连接超时时间毫秒 - */ - private int connectTimeout = 10000; - - /** - * 默认读取数据超时时间 - */ - private int defaultReadTimeout = 1200000; - - - public HttpConfig() { - TrustManager[] trustAllCertificates = new X509TrustManager[]{new X509TrustManager() { - @Override - public X509Certificate[] getAcceptedIssuers() { - return new X509Certificate[0]; // Not relevant. - } - - @Override - public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { - // TODO Auto-generated method stub - } - - @Override - public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { - // TODO Auto-generated method stub - } - }}; - sslParameters = new SSLParameters(); - sslParameters.setEndpointIdentificationAlgorithm(""); - - - try { - sslContext = SSLContext.getInstance("TLSv1.2"); - System.setProperty("jdk.internal.httpclient.disableHostnameVerification", "true");//取消主机名验证 - sslContext.init(null, trustAllCertificates, new SecureRandom()); - } catch (NoSuchAlgorithmException | KeyManagementException e) { - logger.error("", e); - } - - } - - - public HttpClient.Version getVersion() { - return version; - } - - public void setVersion(HttpClient.Version version) { - this.version = version; - } - - public int getConnectTimeout() { - return connectTimeout; - } - - public void setConnectTimeout(int connectTimeout) { - this.connectTimeout = connectTimeout; - } - - - public HttpClient.Redirect getRedirect() { - return redirect; - } - - public void setRedirect(HttpClient.Redirect redirect) { - this.redirect = redirect; - } - - public Executor getExecutor() { - return executor; - } - - public void setExecutor(Executor executor) { - this.executor = executor; - } - - public Authenticator getAuthenticator() { - return authenticator; - } - - public void setAuthenticator(Authenticator authenticator) { - this.authenticator = authenticator; - } - - public ProxySelector getProxySelector() { - return proxySelector; - } - - public void setProxySelector(ProxySelector proxySelector) { - this.proxySelector = proxySelector; - } - - public CookieHandler getCookieHandler() { - return cookieHandler; - } - - public void setCookieHandler(CookieHandler cookieHandler) { - this.cookieHandler = cookieHandler; - } - - public int getDefaultReadTimeout() { - return defaultReadTimeout; - } - - public void setDefaultReadTimeout(int defaultReadTimeout) { - this.defaultReadTimeout = defaultReadTimeout; - } - - public SSLContext getSslContext() { - return sslContext; - } - - public SSLParameters getSslParameters() { - return sslParameters; - } -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/thread/ThreadPoolManager.java b/src/main/java/cn/octopusyan/dayzmodtranslator/manager/thread/ThreadPoolManager.java deleted file mode 100644 index be46215..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/thread/ThreadPoolManager.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.manager.thread; - - -import java.util.concurrent.*; - -/** - * 线程池管理类 - */ -public final class ThreadPoolManager extends ThreadPoolExecutor { - - private static volatile ThreadPoolManager sInstance; - - private static ScheduledExecutorService scheduledExecutorService; - - private ThreadPoolManager() { - super(32, - 200, - 10, - TimeUnit.SECONDS, - new LinkedBlockingQueue<>(200), - new ThreadFactory(ThreadFactory.DEFAULT_THREAD_PREFIX), - new ThreadPoolExecutor.DiscardPolicy()); - } - - public static ThreadPoolManager getInstance() { - if (sInstance == null) sInstance = new ThreadPoolManager(); - return sInstance; - } -} \ No newline at end of file diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/ApiKey.java b/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/ApiKey.java deleted file mode 100644 index 0e22252..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/ApiKey.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.manager.translate; - -/** - * API 密钥配置 - * - * @author octopus_yan@foxmail.com - */ -public class ApiKey { - private String appid; - private String apiKey; - - public ApiKey() { - } - - public ApiKey(String appid, String apiKey) { - this.appid = appid; - this.apiKey = apiKey; - } - - public String getAppid() { - return appid; - } - - public String getApiKey() { - return apiKey; - } -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/TranslateSource.java b/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/TranslateSource.java deleted file mode 100644 index b55db46..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/TranslateSource.java +++ /dev/null @@ -1,65 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.manager.translate; - -/** - * 翻译引擎类型 - * - * @author octopus_yan@foxmail.com - */ -public enum TranslateSource { - FREE_GOOGLE("free_google", "谷歌(免费)", false, 50), - BAIDU("baidu", "百度(需认证)", true), - - ; - private final String name; - private final String label; - private final boolean needApiKey; - private Integer defaultQps; - - TranslateSource(String name, String label, boolean needApiKey) { - // 设置接口默认qps=10 - this(name, label, needApiKey, 10); - } - - TranslateSource(String name, String label, boolean needApiKey, int defaultQps) { - this.name = name; - this.label = label; - this.needApiKey = needApiKey; - this.defaultQps = defaultQps; - } - - public String getName() { - return name; - } - - public String getLabel() { - return label; - } - - public boolean needApiKey() { - return needApiKey; - } - - public Integer getDefaultQps() { - return defaultQps; - } - - public String getDefaultQpsStr() { - return String.valueOf(defaultQps); - } - - public static TranslateSource get(String type) { - for (TranslateSource value : values()) { - if (value.getName().equals(type)) - return value; - } - throw new RuntimeException("类型不存在"); - } - - public static TranslateSource getByLabel(String label) { - for (TranslateSource value : values()) { - if (value.getLabel().equals(label)) - return value; - } - throw new RuntimeException("类型不存在"); - } -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/TranslateUtil.java b/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/TranslateUtil.java deleted file mode 100644 index 8395bc4..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/TranslateUtil.java +++ /dev/null @@ -1,227 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.manager.translate; - -import cn.octopusyan.dayzmodtranslator.config.CustomConfig; -import cn.octopusyan.dayzmodtranslator.manager.thread.ThreadFactory; -import cn.octopusyan.dayzmodtranslator.manager.thread.ThreadPoolManager; -import cn.octopusyan.dayzmodtranslator.manager.translate.factory.TranslateFactory; -import cn.octopusyan.dayzmodtranslator.manager.translate.factory.TranslateFactoryImpl; -import javafx.application.Platform; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.*; - -/** - * 翻译工具 - * - * @author octopus_yan@foxmail.com - */ -public class TranslateUtil { - private static final Logger logger = LoggerFactory.getLogger(TranslateUtil.class); - private static TranslateUtil util; - private static final DelayQueue delayQueue = new DelayQueue<>(); - private final TranslateFactory factory; - private static WordThread wordThread; - private static ThreadPoolExecutor threadPoolExecutor; - - private TranslateUtil(TranslateFactory factory) { - this.factory = factory; - } - - public static TranslateUtil getInstance() { - if (util == null) { - util = new TranslateUtil(TranslateFactoryImpl.getInstance()); - } - return util; - } - - /** - * 提交翻译任务 - * - * @param index 序号 - * @param original 原始文本 - * @param listener 翻译结果回调 (主线程) - */ - public void translate(int index, String original, OnTranslateListener listener) { - - // 设置延迟时间 - DelayWord word = factory.getDelayWord(CustomConfig.translateSource(), index, original, listener); - // 添加到延迟队列 - delayQueue.add(word); - - if (wordThread == null) { - wordThread = new WordThread(); - wordThread.start(); - } - } - - /** - * 清除翻译任务 - */ - public void clear() { - // 尝试停止所有线程 - getThreadPoolExecutor().shutdownNow(); - // 清空队列 - delayQueue.clear(); - // 设置停止标记 - if (wordThread != null) - wordThread.setStop(true); - wordThread = null; - } - - /** - * 获取翻译任务用线程池 - */ - public static ThreadPoolExecutor getThreadPoolExecutor() { - if (threadPoolExecutor == null || threadPoolExecutor.isShutdown()) { - threadPoolExecutor = new ThreadPoolExecutor(32, - 200, - 10, - TimeUnit.SECONDS, - new LinkedBlockingQueue<>(200), - new ThreadFactory(ThreadFactory.DEFAULT_THREAD_PREFIX), - new ThreadPoolExecutor.DiscardPolicy()); - } - return threadPoolExecutor; - } - - public interface OnTranslateListener { - void onTranslate(String result); - } - - /** - * 延迟翻译对象 - */ - public static class DelayWord implements Delayed { - private TranslateSource source; - private final int index; - private final String original; - private final OnTranslateListener listener; - private long time; - - public DelayWord(int index, String original, OnTranslateListener listener) { - this.index = index; - this.original = original; - this.listener = listener; - - } - - public void setSource(TranslateSource source) { - this.source = source; - } - - public void setTime(long time, TimeUnit timeUnit) { - this.time = System.currentTimeMillis() + (time > 0 ? timeUnit.toMillis(time) : 0); - } - - public TranslateSource getSource() { - return source; - } - - public int getIndex() { - return index; - } - - public String getOriginal() { - return original; - } - - public OnTranslateListener getListener() { - return listener; - } - - @Override - public long getDelay(TimeUnit unit) { - return time - System.currentTimeMillis(); - } - - @Override - public int compareTo(Delayed o) { - DelayWord word = (DelayWord) o; - return Integer.compare(this.index, word.index); - } - } - - /** - * 延迟队列处理线程 - */ - private static class WordThread extends Thread { - private boolean stop = false; - - public void setStop(boolean stop) { - this.stop = stop; - } - - @Override - public void run() { - List tmp = new ArrayList<>(); - while (!delayQueue.isEmpty()) { - // 停止处理 - if (stop) { - this.interrupt(); - return; - } - - try { - // 取出待翻译文本 - DelayWord take = delayQueue.take(); - tmp.add(take); - - if (tmp.size() < CustomConfig.translateSourceQps(take.source)) - continue; - - tmp.forEach(word -> { - try { - getThreadPoolExecutor().execute(() -> { - // 翻译 - try { - String translate = util.factory.translate(word.getSource(), word.getOriginal()); - // 回调监听器 - if (word.getListener() != null) - // 主线程处理翻译结果 - Platform.runLater(() -> word.getListener().onTranslate(translate)); - } catch (InterruptedException ignored) { - } catch (Exception e) { - logger.error("翻译出错", e); - throw new RuntimeException(e); - } - }); - } catch (Exception e) { - logger.error("翻译出错", e); - throw new RuntimeException(e); - } - }); - - tmp.clear(); - } catch (InterruptedException ignored) { - } - } - - // 处理剩余 - tmp.forEach(word -> { - try { - ThreadPoolManager.getInstance().execute(() -> { - // 翻译 - try { - String translate = util.factory.translate(word.getSource(), word.getOriginal()); - // 回调监听器 - if (word.getListener() != null) - // 主线程处理翻译结果 - Platform.runLater(() -> word.getListener().onTranslate(translate)); - } catch (Exception e) { - logger.error("翻译出错", e); - throw new RuntimeException(e); - } - }); - } catch (Exception e) { - logger.error("翻译出错", e); - throw new RuntimeException(e); - } - }); - - tmp.clear(); - } - } -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/factory/TranslateFactory.java b/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/factory/TranslateFactory.java deleted file mode 100644 index 76ca022..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/factory/TranslateFactory.java +++ /dev/null @@ -1,32 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.manager.translate.factory; - -import cn.octopusyan.dayzmodtranslator.manager.translate.TranslateSource; -import cn.octopusyan.dayzmodtranslator.manager.translate.TranslateUtil; - -/** - * 翻译器接口 - * - * @author octopus_yan@foxmail.com - */ -public interface TranslateFactory { - /** - * 翻译处理 - * - * @param source 翻译源 - * @param sourceString 原始文本 - * @return 翻译结果 - * @throws Exception 翻译出错 - */ - String translate(TranslateSource source, String sourceString) throws Exception; - - /** - * 获取延迟翻译对象 - * - * @param source 翻译源 - * @param index 序号 - * @param original 原始文本 - * @param listener 监听器 - * @return 延迟翻译对象 - */ - TranslateUtil.DelayWord getDelayWord(TranslateSource source, int index, String original, TranslateUtil.OnTranslateListener listener); -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/factory/TranslateFactoryImpl.java b/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/factory/TranslateFactoryImpl.java deleted file mode 100644 index 01dda12..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/factory/TranslateFactoryImpl.java +++ /dev/null @@ -1,81 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.manager.translate.factory; - -import cn.octopusyan.dayzmodtranslator.manager.translate.TranslateSource; -import cn.octopusyan.dayzmodtranslator.manager.translate.TranslateUtil; -import cn.octopusyan.dayzmodtranslator.manager.translate.processor.AbstractTranslateProcessor; -import cn.octopusyan.dayzmodtranslator.manager.translate.processor.BaiduTranslateProcessor; -import cn.octopusyan.dayzmodtranslator.manager.translate.processor.FreeGoogleTranslateProcessor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; - -/** - * 翻译处理器 - * - * @author octopus_yan@foxmail.com - */ -public class TranslateFactoryImpl implements TranslateFactory { - private static final Logger logger = LoggerFactory.getLogger(TranslateFactoryImpl.class); - private static TranslateFactoryImpl impl; - private final Map processorMap = new HashMap<>(); - private final List processorList = new ArrayList<>(); - - private TranslateFactoryImpl() { - } - - public static synchronized TranslateFactoryImpl getInstance() { - if (impl == null) { - impl = new TranslateFactoryImpl(); - impl.initProcessor(); - } - return impl; - } - - private void initProcessor() { - processorList.addAll(Arrays.asList( - new FreeGoogleTranslateProcessor(TranslateSource.FREE_GOOGLE), - new BaiduTranslateProcessor(TranslateSource.BAIDU) - )); - for (AbstractTranslateProcessor processor : processorList) { - processorMap.put(processor.getSource(), processor); - } - } - - private AbstractTranslateProcessor getProcessor(TranslateSource source) { - return processorMap.get(source.getName()); - } - - /** - * 获取延迟翻译对象 - * - * @param source 翻译源 - * @param index 序号 - * @param original 原始文本 - * @param listener 监听器 - * @return 延迟翻译对象 - */ - @Override - public TranslateUtil.DelayWord getDelayWord(TranslateSource source, int index, String original, TranslateUtil.OnTranslateListener listener) { - // 生产翻译对象 - TranslateUtil.DelayWord word = new TranslateUtil.DelayWord(index, original, listener); - // 设置延迟 - getProcessor(source).setDelayTime(word); - - return word; - } - - /** - * 翻译(英->中) - *

TODO 切换语种 - * - * @param source 翻译源 - * @param sourceString 原始文本 - * @return 翻译结果 - * @throws Exception 翻译出错 - */ - @Override - public String translate(TranslateSource source, String sourceString) throws Exception { - return getProcessor(source).translate(sourceString); - } -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/processor/AbstractTranslateProcessor.java b/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/processor/AbstractTranslateProcessor.java deleted file mode 100644 index 517b03e..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/processor/AbstractTranslateProcessor.java +++ /dev/null @@ -1,99 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.manager.translate.processor; - -import cn.octopusyan.dayzmodtranslator.config.CustomConfig; -import cn.octopusyan.dayzmodtranslator.manager.translate.ApiKey; -import cn.octopusyan.dayzmodtranslator.manager.translate.TranslateSource; -import cn.octopusyan.dayzmodtranslator.manager.translate.TranslateUtil; -import cn.octopusyan.dayzmodtranslator.manager.http.HttpUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.TimeUnit; - -/** - * 翻译处理器抽象类 - * - * @author octopus_yan@foxmail.com - */ -public abstract class AbstractTranslateProcessor implements TranslateProcessor { - protected final Logger logger = LoggerFactory.getLogger(this.getClass()); - protected static final HttpUtil httpUtil = HttpUtil.getInstance(); - protected final TranslateSource translateSource; - protected ApiKey apiKey; - - public AbstractTranslateProcessor(TranslateSource translateSource) { - this.translateSource = translateSource; - } - - public String getSource() { - return translateSource.getName(); - } - - public TranslateSource source() { - return translateSource; - } - - @Override - public boolean needApiKey() { - return source().needApiKey(); - } - - @Override - public boolean configuredKey() { - return CustomConfig.hasTranslateApiKey(source()); - } - - @Override - public int qps() { - return CustomConfig.translateSourceQps(source()); - } - - /** - * 获取Api配置信息 - */ - protected ApiKey getApiKey() { - if (!configuredKey()) { - String message = String.format("未配置【%s】翻译源认证信息!", source().getLabel()); - logger.error(message); - throw new RuntimeException(message); - } - - String appid = CustomConfig.translateSourceAppid(source()); - String apikey = CustomConfig.translateSourceApikey(source()); - return new ApiKey(appid, apikey); - } - - @Override - public String translate(String source) throws Exception { - - if (needApiKey() && !configuredKey()) { - String message = String.format("未配置【%s】翻译源认证信息!", source().getLabel()); - logger.error(message); - throw new RuntimeException(message); - } - - return customTranslate(source); - } - - /** - * 翻译处理 - * - * @param source 原始文本 - * @return 翻译结果 - */ - public abstract String customTranslate(String source) throws Exception; - - /** - * 设置延迟对象 - * - * @param word 带翻译单词 - */ - public void setDelayTime(TranslateUtil.DelayWord word) { - // 设置翻译源 - word.setSource(source()); - - // 设置翻译延迟 - int time = word.getIndex() / qps(); - word.setTime(time, TimeUnit.SECONDS); - } -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/word/WordCsvItem.java b/src/main/java/cn/octopusyan/dayzmodtranslator/manager/word/WordCsvItem.java deleted file mode 100644 index 41c4eae..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/word/WordCsvItem.java +++ /dev/null @@ -1,52 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.manager.word; - -import javafx.beans.property.SimpleStringProperty; -import javafx.beans.property.StringProperty; - -import java.io.File; - -/** - * csv单词对象 - * - * @author octopus_yan@foxmail.com - */ -public class WordCsvItem extends WordItem { - /** - * 简体中文 - */ - private StringProperty chineseSimp; - - /** - * 文件中坐标(简体中文) - */ - private int[] positionSimp; - - public WordCsvItem() { - } - - public WordCsvItem(File stringTable, int lines, String original, String chineses, int[] position, String chineseSimp, int[] positionSimp) { - super(stringTable, lines, original, chineses, position); - this.chineseSimp = new SimpleStringProperty(chineseSimp); - this.positionSimp = positionSimp; - } - - public StringProperty chineseSimpProperty() { - return chineseSimp; - } - - public String getChineseSimp() { - return chineseSimp.get(); - } - - public void setChineseSimp(String chineseSimp) { - this.chineseSimp.setValue(chineseSimp); - } - - public int[] getPositionSimp() { - return positionSimp; - } - - public void setPositionSimp(int[] positionSimp) { - this.positionSimp = positionSimp; - } -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/word/WordItem.java b/src/main/java/cn/octopusyan/dayzmodtranslator/manager/word/WordItem.java deleted file mode 100644 index aae0d84..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/word/WordItem.java +++ /dev/null @@ -1,98 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.manager.word; - -import javafx.beans.property.SimpleStringProperty; -import javafx.beans.property.StringProperty; - -import java.io.File; - -/** - * 待翻译单词子项 - * - * @author octopus_yan@foxmail.com - */ -public class WordItem { - /** - * 所在文件 - *

PS: 文本所在的文件 - */ - private File file; - - /** - * 原始文本 - */ - private StringProperty original; - - /** - * 汉化 - */ - private StringProperty chinese; - - /** - * 行内下标 - */ - private int[] position; - - /** - * 文件第几行 - */ - private int lines; - - public WordItem() { - } - - public WordItem(File file, int lines, String original, String chinese, int[] position) { - this.file = file; - this.original = new SimpleStringProperty(original); - this.chinese = new SimpleStringProperty(chinese); - this.position = position; - this.lines = lines; - } - - public StringProperty originalProperty() { - return original; - } - - public String getOriginal() { - return original.get(); - } - - public void setOriginal(String original) { - this.original.setValue(original); - } - - public StringProperty chineseProperty() { - return chinese; - } - - public String getChinese() { - return chinese.get(); - } - - public void setChinese(String chinese) { - this.chinese.setValue(chinese); - } - - public int[] getPosition() { - return position; - } - - public void setPosition(int[] position) { - this.position = position; - } - - public int getLines() { - return lines; - } - - public void setLines(int lines) { - this.lines = lines; - } - - public File getFile() { - return file; - } - - public void setFile(File file) { - this.file = file; - } -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/util/AlertUtil.java b/src/main/java/cn/octopusyan/dayzmodtranslator/util/AlertUtil.java deleted file mode 100644 index 718cd03..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/util/AlertUtil.java +++ /dev/null @@ -1,228 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.util; - -import javafx.scene.control.*; -import javafx.scene.image.Image; -import javafx.scene.layout.GridPane; -import javafx.scene.layout.Priority; -import javafx.stage.Stage; -import javafx.stage.Window; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; - -/** - * 弹窗工具 - * - * @author octopus_yan@foxmail.com - */ -public class AlertUtil { - private static Window mOwner; - private static Builder builder; - - public static void initOwner(Stage stage) { - AlertUtil.mOwner = stage; - } - - public static class Builder { - T alert; - - public Builder(T alert) { - this.alert = alert; - if (mOwner != null) this.alert.initOwner(mOwner); - } - - public Builder title(String title) { - alert.setTitle(title); - return this; - } - - public Builder header(String header) { - alert.setHeaderText(header); - return this; - } - - public Builder content(String content) { - alert.setContentText(content); - return this; - } - - public Builder icon(String path) { - icon(new Image(Objects.requireNonNull(this.getClass().getResource(path)).toString())); - return this; - } - - public Builder icon(Image image) { - getStage().getIcons().add(image); - return this; - } - - public void show() { - if (AlertUtil.builder == null) { - AlertUtil.builder = this; - } else if (AlertUtil.builder.alert.isShowing()) { - if (!Objects.equals(AlertUtil.builder.alert.getContentText(), alert.getContentText())) - ((Alert) AlertUtil.builder.alert).setOnHidden(event -> { - AlertUtil.builder = null; - show(); - }); - } - alert.showAndWait(); - } - - /** - * AlertUtil.confirm - */ - public void show(OnClickListener listener) { - - Optional result = alert.showAndWait(); - - listener.onClicked(result.get().getText()); - } - - /** - * AlertUtil.confirm - */ - public void show(OnChoseListener listener) { - Optional result = alert.showAndWait(); - if (result.get() == ButtonType.OK) { - listener.confirm(); - } else { - listener.cancelOrClose(result.get()); - } - } - - /** - * AlertUtil.input - * 如果用户点击了取消按钮,将会返回null - */ - public String getInput() { - Optional result = alert.showAndWait(); - if (result.isPresent()) { - return result.get(); - } - return null; - } - - /** - * AlertUtil.choices - */ - public R getChoice(R... choices) { - Optional result = alert.showAndWait(); - return (R) result.get(); - } - - private Stage getStage() { - return (Stage) alert.getDialogPane().getScene().getWindow(); - } - } - - public static Builder info(String content) { - return new Builder(new Alert(Alert.AlertType.INFORMATION)).content(content).header(null); - } - - public static Builder info() { - return new Builder(new Alert(Alert.AlertType.INFORMATION)); - } - - public static Builder error(String message) { - return new Builder(new Alert(Alert.AlertType.ERROR)).header(null).content(message); - } - - public static Builder warning() { - return new Builder(new Alert(Alert.AlertType.WARNING)); - } - - public static Builder exception(Exception ex) { - return new Builder(exceptionAlert(ex)); - } - - public static Alert exceptionAlert(Exception ex) { - Alert alert = new Alert(Alert.AlertType.ERROR); - alert.setTitle("Exception Dialog"); - alert.setHeaderText(ex.getClass().getSimpleName()); - alert.setContentText(ex.getMessage()); - - // 创建可扩展的异常。 - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - ex.printStackTrace(pw); - String exceptionText = sw.toString(); - - Label label = new Label("The exception stacktrace was :"); - - TextArea textArea = new TextArea(exceptionText); - textArea.setEditable(false); - textArea.setWrapText(true); - - textArea.setMaxWidth(Double.MAX_VALUE); - textArea.setMaxHeight(Double.MAX_VALUE); - GridPane.setVgrow(textArea, Priority.ALWAYS); - GridPane.setHgrow(textArea, Priority.ALWAYS); - - GridPane expContent = new GridPane(); - expContent.setMaxWidth(Double.MAX_VALUE); - expContent.add(label, 0, 0); - expContent.add(textArea, 0, 1); - - // 将可扩展异常设置到对话框窗格中。 - alert.getDialogPane().setExpandableContent(expContent); - return alert; - } - - /** - * 确认对话框 - */ - public static Builder confirm() { - Alert alert = new Alert(Alert.AlertType.CONFIRMATION); - alert.setTitle("确认对话框"); - return new Builder(alert); - } - - /** - * 自定义确认对话框

- * "Cancel" OR "取消" 为取消按钮 - */ - public static Builder confirm(String... buttons) { - Alert alert = new Alert(Alert.AlertType.CONFIRMATION); - - List buttonList = Arrays.stream(buttons).map((type) -> { - ButtonBar.ButtonData buttonData = ButtonBar.ButtonData.OTHER; - if ("Cancel".equals(type) || "取消".equals(type)) - buttonData = ButtonBar.ButtonData.CANCEL_CLOSE; - return new ButtonType(type, buttonData); - }).collect(Collectors.toList()); - - alert.getButtonTypes().setAll(buttonList); - - return new Builder(alert); - } - - public static Builder input(String content) { - TextInputDialog dialog = new TextInputDialog(); - dialog.setContentText(content); - return new Builder(dialog); - } - - @SafeVarargs - public static Builder> choices(String hintText, T... choices) { - ChoiceDialog dialog = new ChoiceDialog(choices[0], choices); - dialog.setContentText(hintText); - return new Builder>(dialog); - } - - - public interface OnChoseListener { - void confirm(); - - void cancelOrClose(ButtonType buttonType); - } - - public interface OnClickListener { - void onClicked(String result); - } -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/util/Loading.java b/src/main/java/cn/octopusyan/dayzmodtranslator/util/Loading.java deleted file mode 100644 index a444ca8..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/util/Loading.java +++ /dev/null @@ -1,83 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.util; - -import javafx.application.Platform; -import javafx.scene.Scene; -import javafx.scene.control.Label; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; -import javafx.scene.layout.Background; -import javafx.scene.layout.BackgroundFill; -import javafx.scene.layout.StackPane; -import javafx.scene.paint.Color; -import javafx.scene.text.Font; -import javafx.stage.Modality; -import javafx.stage.Stage; -import javafx.stage.StageStyle; - -/** - * 加载等待弹窗 - * - * @author octopus_yan@foxmail.com - */ -public class Loading { - protected Stage stage; - protected StackPane root; - protected Label messageLb; - protected ImageView loadingView = new ImageView(new Image("https://blog-static.cnblogs.com/files/miaoqx/loading.gif")); - - public Loading(Stage owner) { - - messageLb = new Label("请耐心等待..."); - messageLb.setFont(Font.font(20)); - - root = new StackPane(); - root.setMouseTransparent(true); - root.setPrefSize(owner.getWidth(), owner.getHeight()); - root.setBackground(new Background(new BackgroundFill(Color.rgb(0, 0, 0, 0.3), null, null))); - root.getChildren().addAll(loadingView, messageLb); - - Scene scene = new Scene(root); - scene.setFill(Color.TRANSPARENT); - - stage = new Stage(); - stage.setX(owner.getX()); - stage.setY(owner.getY()); - stage.setScene(scene); - stage.setResizable(false); - stage.initOwner(owner); - stage.initStyle(StageStyle.TRANSPARENT); - stage.initModality(Modality.APPLICATION_MODAL); - stage.getIcons().addAll(owner.getIcons()); - stage.setX(owner.getX()); - stage.setY(owner.getY()); - stage.setHeight(owner.getHeight()); - stage.setWidth(owner.getWidth()); - } - - // 更改信息 - public Loading showMessage(String message) { - Platform.runLater(() -> messageLb.setText(message)); - return this; - } - - // 更改信息 - public Loading image(Image image) { - Platform.runLater(() -> loadingView.imageProperty().set(image)); - return this; - } - - // 显示 - public void show() { - Platform.runLater(() -> stage.show()); - } - - // 关闭 - public void closeStage() { - Platform.runLater(() -> stage.close()); - } - - // 是否正在展示 - public boolean showing() { - return stage.isShowing(); - } -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/util/ProcessesUtil.java b/src/main/java/cn/octopusyan/dayzmodtranslator/util/ProcessesUtil.java deleted file mode 100644 index 5b67cab..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/util/ProcessesUtil.java +++ /dev/null @@ -1,96 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.util; - -import org.apache.commons.exec.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; - -/** - * 命令工具类 - * - * @author octopus_yan@foxmail.com - */ -public class ProcessesUtil { - private static final Logger logger = LoggerFactory.getLogger(ProcessesUtil.class); - private static final String NEWLINE = System.lineSeparator(); - private static final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler(); - - public static boolean exec(String command) { - try { - exec(command, new OnExecuteListener() { - @Override - public void onExecute(String msg) { - - } - - @Override - public void onExecuteSuccess(int exitValue) { - - } - - @Override - public void onExecuteError(Exception e) { - - } - - @Override - public void onExecuteOver() { - - } - }); - handler.waitFor(); - } catch (Exception e) { - logger.error("", e); - } - return 0 == handler.getExitValue(); - } - - public static void exec(String command, OnExecuteListener listener) { - LogOutputStream logout = new LogOutputStream() { - @Override - protected void processLine(String line, int logLevel) { - if (listener != null) listener.onExecute(line + NEWLINE); - } - }; - - CommandLine commandLine = CommandLine.parse(command); - DefaultExecutor executor = DefaultExecutor.builder().get(); - executor.setStreamHandler(new PumpStreamHandler(logout, logout)); - DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler() { - @Override - public void onProcessComplete(int exitValue) { - if (listener != null) { - listener.onExecuteSuccess(exitValue); - } - } - - @Override - public void onProcessFailed(ExecuteException e) { - if (listener != null) { - listener.onExecuteError(e); - } - } - }; - try { - executor.execute(commandLine, handler); - } catch (IOException e) { - if (listener != null) listener.onExecuteError(e); - } - } - - public interface OnExecuteListener { - void onExecute(String msg); - - void onExecuteSuccess(int exitValue); - - void onExecuteError(Exception e); - void onExecuteOver(); - } - - /** - * Prevent construction. - */ - private ProcessesUtil() { - } -} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/util/TooltipUtil.java b/src/main/java/cn/octopusyan/dayzmodtranslator/util/TooltipUtil.java deleted file mode 100644 index 6c1b629..0000000 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/util/TooltipUtil.java +++ /dev/null @@ -1,113 +0,0 @@ -package cn.octopusyan.dayzmodtranslator.util; - -import javafx.beans.value.ChangeListener; -import javafx.scene.control.Tooltip; -import javafx.scene.input.MouseEvent; -import javafx.scene.layout.Pane; -import javafx.stage.Window; - -/** - * 提示工具 - * - * @author octopus_yan@foxmail.com - */ -public class TooltipUtil { - private static TooltipUtil util; - private final Tooltip tooltip = new Tooltip(); - private Window owner; - private ChangeListener xListener; - private ChangeListener yListener; - private boolean paneMove = false; - - private TooltipUtil(Window window) { - this.owner = window; - this.tooltip.styleProperty().set( - "-fx-background-color: white;" + - "-fx-text-fill: grey;" + - "-fx-font-size: 12px;" - ); - } - - public static TooltipUtil getInstance(Pane pane) { - if (pane == null) return null; - Window window = pane.getScene().getWindow(); - if (window == null) return null; - - if (util == null) { - util = new TooltipUtil(window); - // 窗口位置监听 - util.xListener = (observable, oldValue, newValue) -> { - util.tooltip.setAnchorX(util.tooltip.getAnchorX() + (newValue.doubleValue() - oldValue.doubleValue())); - util.paneMove = true; - }; - util.yListener = (observable, oldValue, newValue) -> { - util.tooltip.setAnchorY(util.tooltip.getAnchorY() + (newValue.doubleValue() - oldValue.doubleValue())); - util.paneMove = true; - }; - util.tooltip.focusedProperty().addListener((observable, oldValue, newValue) -> { - if (!newValue) util.paneMove = false; - }); - // 随窗口移动 - util.owner.xProperty().addListener(util.xListener); - util.owner.yProperty().addListener(util.yListener); - } - - if (!window.equals(util.owner)) { - // 删除旧监听 - util.owner.xProperty().removeListener(util.xListener); - util.owner.yProperty().removeListener(util.yListener); - // 新窗口 - util.owner = window; - // 随窗口移动 - util.owner.xProperty().addListener(util.xListener); - util.owner.yProperty().addListener(util.yListener); - } - - // 点击关闭 - pane.setOnMouseClicked(event -> { - if (!util.paneMove) util.tooltip.hide(); - util.paneMove = false; - }); - - util.tooltip.hide(); - - return util; - } - - public void showProxyTypeTip(MouseEvent event) { - tooltip.setText( - "提示:XTCP 映射成功率并不高,具体取决于 NAT 设备的复杂度。\n" + - "TCP :基础的 TCP 映射,适用于大多数服务,例如远程桌面、SSH、Minecraft、泰拉瑞亚等\n" + - "UDP :基础的 UDP 映射,适用于域名解析、部分基于 UDP 协议的游戏等\n" + - "HTTP :搭建网站专用映射,并通过 80 端口访问\n" + - "HTTPS :带有 SSL 加密的网站映射,通过 443 端口访问,服务器需要支持 SSL\n" + - "XTCP :客户端之间点对点 (P2P) 连接协议,流量不经过服务器,适合大流量传输的场景,需要两台设备之间都运行一个客户端\n" + - "STCP :安全交换 TCP 连接协议,基于 TCP,访问此服务的用户也需要运行一个客户端,才能建立连接,流量由服务器转发" - ); - show(event); - } - - private void show(MouseEvent event) { - - if (tooltip.isShowing()) { - tooltip.hide(); - } else { - tooltip.show(owner); - double mx = event.getScreenX(); - double my = event.getScreenY(); - double tw = tooltip.widthProperty().doubleValue(); - double th = tooltip.heightProperty().doubleValue(); - - tooltip.setX(mx - tw / 2); - tooltip.setY(my - th - 10); - } - } - - public void hide() { - tooltip.hide(); - } - - public boolean isShowing() { - return tooltip.isShowing(); - } -} diff --git a/src/main/java/cn/octopusyan/dmt/AppLauncher.java b/src/main/java/cn/octopusyan/dmt/AppLauncher.java new file mode 100644 index 0000000..0f94358 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/AppLauncher.java @@ -0,0 +1,13 @@ +package cn.octopusyan.dmt; + +/** + * 启动类 + * + * @author octopus_yan@foxmail.com + */ +public class AppLauncher { + + public static void main(String[] args) { + Application.launch(Application.class, args); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/Application.java b/src/main/java/cn/octopusyan/dmt/Application.java new file mode 100644 index 0000000..f840ea0 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/Application.java @@ -0,0 +1,114 @@ +package cn.octopusyan.dmt; + +import cn.octopusyan.dmt.common.config.Constants; +import cn.octopusyan.dmt.common.config.Context; +import cn.octopusyan.dmt.common.manager.ConfigManager; +import cn.octopusyan.dmt.common.manager.http.CookieManager; +import cn.octopusyan.dmt.common.manager.http.HttpConfig; +import cn.octopusyan.dmt.common.manager.http.HttpUtil; +import cn.octopusyan.dmt.common.manager.thread.ThreadPoolManager; +import cn.octopusyan.dmt.common.util.ProcessesUtil; +import cn.octopusyan.dmt.utils.PBOUtil; +import cn.octopusyan.dmt.view.alert.AlertUtil; +import javafx.application.Platform; +import javafx.scene.Scene; +import javafx.stage.Stage; +import lombok.Getter; +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.ProxySelector; +import java.net.http.HttpClient; +import java.util.Objects; + +public class Application extends javafx.application.Application { + private static final Logger logger = LoggerFactory.getLogger(Application.class); + @Getter + private static Stage primaryStage; + + @Override + public void init() { + logger.info("application init ..."); + + // 初始化客户端配置 + ConfigManager.load(); + + // 初始化 PBO工具 + PBOUtil.init(); + + // http请求工具初始化 + HttpConfig httpConfig = new HttpConfig(); + httpConfig.setCookieHandler(CookieManager.get()); + httpConfig.setExecutor(ThreadPoolManager.getInstance("http-pool")); + // 加载代理设置 + switch (ConfigManager.proxySetup()) { + case NO_PROXY -> httpConfig.setProxySelector(HttpClient.Builder.NO_PROXY); + case SYSTEM -> httpConfig.setProxySelector(ProxySelector.getDefault()); + case MANUAL -> { + if (ConfigManager.hasProxy()) { + InetSocketAddress unresolved = InetSocketAddress.createUnresolved( + Objects.requireNonNull(ConfigManager.proxyHost()), + ConfigManager.getProxyPort() + ); + httpConfig.setProxySelector(ProxySelector.of(unresolved)); + } + } + } + httpConfig.setConnectTimeout(3000); + HttpUtil.init(httpConfig); + } + + @Override + public void start(Stage primaryStage) throws IOException { + + logger.info("application start ..."); + + Application.primaryStage = primaryStage; + + Context.setApplication(this); + + // 初始化弹窗工具 + AlertUtil.initOwner(primaryStage); + + // 全局异常处理 + Thread.setDefaultUncaughtExceptionHandler(this::showErrorDialog); + Thread.currentThread().setUncaughtExceptionHandler(this::showErrorDialog); + + // 主题样式 + Application.setUserAgentStylesheet(ConfigManager.theme().getUserAgentStylesheet()); + + // 启动主界面 + primaryStage.setTitle(String.format("%s %s", Constants.APP_TITLE, Constants.APP_VERSION)); + Scene scene = Context.initScene(); + primaryStage.setScene(scene); + primaryStage.show(); + + + } + + private void showErrorDialog(Thread t, Throwable e) { + logger.error("未知异常", e); + Platform.runLater(() -> AlertUtil.exception(new Exception(e)).show()); + } + + @Override + public void stop() { + logger.info("application stop ..."); + // 关闭所有命令 + ProcessesUtil.destroyAll(); + // 保存应用数据 + ConfigManager.save(); + // 停止所有线程 + ThreadPoolManager.shutdownAll(); + // 删除缓存 + FileUtils.deleteQuietly(new File(Constants.TMP_DIR_PATH)); + FileUtils.deleteQuietly(new File(Constants.BAK_DIR_PATH)); + // 关闭主界面 + Platform.exit(); + System.exit(0); + } +} \ No newline at end of file diff --git a/src/main/java/cn/octopusyan/dmt/common/base/BaseBuilder.java b/src/main/java/cn/octopusyan/dmt/common/base/BaseBuilder.java new file mode 100644 index 0000000..2211134 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/common/base/BaseBuilder.java @@ -0,0 +1,57 @@ +package cn.octopusyan.dmt.common.base; + +import cn.octopusyan.dmt.common.manager.ConfigManager; +import javafx.application.Platform; +import javafx.scene.Node; +import javafx.scene.control.Dialog; +import javafx.stage.Window; +import lombok.Getter; + +/** + * @author octopus_yan + */ +@Getter +public abstract class BaseBuilder, D extends Dialog> { + protected D dialog; + + public BaseBuilder(D dialog, Window mOwner) { + this.dialog = dialog; + if (mOwner != null) + this.dialog.initOwner(mOwner); + } + + public T title(String title) { + dialog.setTitle(title); + return (T) this; + } + + public T header(String header) { + dialog.setHeaderText(header); + return (T) this; + } + + public T content(String content) { + dialog.setContentText(content); + return (T) this; + } + + public void show() { + + Node dialogPane = dialog.getDialogPane().getContent(); + if (dialogPane != null && ConfigManager.theme().isDarkMode()) { + dialogPane.setStyle(STR.""" + \{dialogPane.getStyle()} + -fx-border-color: rgb(209, 209, 214, 0.5); + -fx-border-width: 1; + -fx-border-radius: 10; + """); + } + + Platform.runLater(() -> dialog.showAndWait()); + } + + public void close() { + if (dialog.isShowing()) + dialog.close(); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/common/base/BaseController.java b/src/main/java/cn/octopusyan/dmt/common/base/BaseController.java new file mode 100644 index 0000000..22e133b --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/common/base/BaseController.java @@ -0,0 +1,146 @@ +package cn.octopusyan.dmt.common.base; + +import cn.octopusyan.dmt.Application; +import cn.octopusyan.dmt.common.config.Context; +import cn.octopusyan.dmt.common.util.FxmlUtil; +import cn.octopusyan.dmt.common.util.ViewUtil; +import javafx.application.Platform; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.layout.Pane; +import javafx.stage.Stage; +import lombok.Getter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.ResourceBundle; + +/** + * 通用视图控制器基类 + * + * @author octopus_yan@foxmail.com + */ +public abstract class BaseController implements Initializable { + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + @Getter + protected final VM viewModel; + + public BaseController() { + //初始化时保存当前Controller实例 + Context.getControllers().put(this.getClass().getSimpleName(), this); + + // view model + VM vm = null; + Type superclass = getClass().getGenericSuperclass(); + if (superclass instanceof ParameterizedType type) { + Class clazz = (Class) type.getActualTypeArguments()[0]; + try { + vm = clazz.getDeclaredConstructor().newInstance(); + } catch (Exception e) { + logger.error("", e); + } + } + viewModel = vm; + viewModel.setController(this); + } + + @FXML + @Override + public void initialize(URL url, ResourceBundle resourceBundle) { + // 全局窗口拖拽 + if (dragWindow() && getRootPanel() != null) { + // 窗口拖拽 + ViewUtil.bindDragged(getRootPanel()); + } + + // 初始化数据 + initData(); + + // 初始化视图样式 + initViewStyle(); + + // 初始化视图事件 + initViewAction(); + } + + /** + * 窗口拖拽设置 + * + * @return 是否启用 + */ + public boolean dragWindow() { + return false; + } + + /** + * 获取根布局 + * + * @return 根布局对象 + */ + public abstract Pane getRootPanel(); + + /** + * 获取根布局 + *

搭配 {@link FxmlUtil#load(String)} 使用 + * + * @return 根布局对象 + */ + protected String getRootFxml() { + System.out.println(getClass().getSimpleName()); + return ""; + } + + protected Stage getWindow() { + try { + return (Stage) getRootPanel().getScene().getWindow(); + } catch (Throwable _) { + return Application.getPrimaryStage(); + } + } + + /** + * 初始化数据 + */ + public abstract void initData(); + + /** + * 视图样式 + */ + public void initViewStyle() { + } + + /** + * 视图事件 + */ + public abstract void initViewAction(); + + private static List getAllField(Class class1) { + List list = new ArrayList<>(); + while (class1 != Object.class) { + list.addAll(Arrays.stream(class1.getDeclaredFields()).toList()); + //获取父类 + class1 = class1.getSuperclass(); + } + return list; + } + + public void exit() { + Platform.exit(); + } + + /** + * 关闭窗口 + */ + public void onDestroy() { + Stage stage = getWindow(); + stage.hide(); + stage.close(); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/common/base/BaseViewModel.java b/src/main/java/cn/octopusyan/dmt/common/base/BaseViewModel.java new file mode 100644 index 0000000..799509a --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/common/base/BaseViewModel.java @@ -0,0 +1,15 @@ +package cn.octopusyan.dmt.common.base; + +import lombok.Setter; + +/** + * View Model + * + * @author octopus_yan + */ +@Setter +public abstract class BaseViewModel, T extends BaseController> { + + protected T controller; + +} diff --git a/src/main/java/cn/octopusyan/dmt/common/config/Constants.java b/src/main/java/cn/octopusyan/dmt/common/config/Constants.java new file mode 100644 index 0000000..d003052 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/common/config/Constants.java @@ -0,0 +1,27 @@ +package cn.octopusyan.dmt.common.config; + + +import cn.octopusyan.dmt.common.util.PropertiesUtils; + +import java.io.File; +import java.nio.file.Paths; + +/** + * 应用信息 + * + * @author octopus_yan@foxmail.com + */ +public class Constants { + public static final String APP_TITLE = PropertiesUtils.getInstance().getProperty("app.title"); + public static final String APP_NAME = PropertiesUtils.getInstance().getProperty("app.name"); + public static final String APP_VERSION = PropertiesUtils.getInstance().getProperty("app.version"); + + public static final String DATA_DIR_PATH = Paths.get("").toFile().getAbsolutePath(); + public static final String BIN_DIR_PATH = STR."\{DATA_DIR_PATH}\{File.separator}bin"; + public static final String TMP_DIR_PATH = STR."\{DATA_DIR_PATH}\{File.separator}tmp"; + public static final String BAK_DIR_PATH = STR."\{DATA_DIR_PATH}\{File.separator}bak"; + + public static final String CONFIG_FILE_PATH = STR."\{DATA_DIR_PATH}\{File.separator}config.yaml"; + public static final String PBOC_FILE = STR."\{BIN_DIR_PATH}\{File.separator}pboc.exe"; + public static final String CFG_CONVERT_FILE = STR."\{BIN_DIR_PATH}\{File.separator}CfgConvert.exe"; +} diff --git a/src/main/java/cn/octopusyan/dmt/common/config/Context.java b/src/main/java/cn/octopusyan/dmt/common/config/Context.java new file mode 100644 index 0000000..1c9a4f4 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/common/config/Context.java @@ -0,0 +1,117 @@ +package cn.octopusyan.dmt.common.config; + +import cn.octopusyan.dmt.Application; +import cn.octopusyan.dmt.common.base.BaseController; +import cn.octopusyan.dmt.common.util.FxmlUtil; +import cn.octopusyan.dmt.common.util.ProcessesUtil; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.scene.layout.Pane; +import javafx.scene.paint.Color; +import javafx.util.Callback; +import lombok.Getter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +/** + * 上下文 + * + * @author octopus_yan + */ +public class Context { + @Getter + private static Application application; + private static final Logger log = LoggerFactory.getLogger(Context.class); + public static final ObjectProperty sceneProperty = new SimpleObjectProperty<>(); + + /** + * 控制器集合 + */ + @Getter + private static final Map> controllers = new HashMap<>(); + + + private Context() { + throw new IllegalStateException("Utility class"); + } + + // 获取控制工厂 + public static Callback, Object> getControlFactory() { + return type -> { + try { + return type.getDeclaredConstructor().newInstance(); + } catch (Exception e) { + log.error("", e); + return null; + } + }; + } + + public static void setApplication(Application application) { + Context.application = application; + } + + /** + * 有此类所在路径决定相对路径 + * + * @param path 资源文件相对路径 + * @return 资源文件路径 + */ + // 加载资源文件 + public static URL load(String path) { + return Context.class.getResource(path); + } + + /** + * 初始化场景 + * + * @return Scene + */ + public static Scene initScene() { + try { + FXMLLoader loader = FxmlUtil.load("main-view"); + //底层面板 + Pane root = loader.load(); + Optional.ofNullable(sceneProperty.get()).ifPresentOrElse( + s -> s.setRoot(root), + () -> { + Scene scene = new Scene(root, root.getPrefWidth() + 20, root.getPrefHeight() + 20, Color.TRANSPARENT); + URL resource = Objects.requireNonNull(Context.class.getResource("/css/main-view.css")); + scene.getStylesheets().addAll(resource.toExternalForm()); + scene.setFill(Color.TRANSPARENT); + sceneProperty.set(scene); + } + ); + } catch (Throwable e) { + log.error("loadScene error", e); + } + return sceneProperty.get(); + } + + public static void openUrl(String url) { + getApplication().getHostServices().showDocument(url); + } + + public static void openFolder(File file) { + openFile(file); + } + + public static void openFile(File file) { + if (!file.exists()) return; + + if (file.isDirectory()) { + ProcessesUtil.init(file.getAbsolutePath()).exec("explorer.exe ."); + } else { + ProcessesUtil.init(file.getParentFile().getAbsolutePath()).exec(STR."explorer.exe /select,\{file.getName()}"); + } + } +} \ No newline at end of file diff --git a/src/main/java/cn/octopusyan/dmt/common/config/LabelConstants.java b/src/main/java/cn/octopusyan/dmt/common/config/LabelConstants.java new file mode 100644 index 0000000..0028590 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/common/config/LabelConstants.java @@ -0,0 +1,11 @@ +package cn.octopusyan.dmt.common.config; + +/** + * 名称常量 + * + * @author octopus_yan + */ +public class LabelConstants { + public static final String CONFIRM = "确认"; + public static final String CANCEL = "取消"; +} diff --git a/src/main/java/cn/octopusyan/dmt/common/enums/ProxySetup.java b/src/main/java/cn/octopusyan/dmt/common/enums/ProxySetup.java new file mode 100644 index 0000000..a192847 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/common/enums/ProxySetup.java @@ -0,0 +1,29 @@ +package cn.octopusyan.dmt.common.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * 代理类型 + * + * @author octopus_yan + */ +@Getter +@RequiredArgsConstructor +public enum ProxySetup { + /** + * 不使用代理 + */ + NO_PROXY("no_proxy", "不使用代理"), + /** + * 系统代理 + */ + SYSTEM("system", "系统代理"), + /** + * 自定义代理 + */ + MANUAL("manual", "自定义代理"); + + private final String code; + private final String name; +} diff --git a/src/main/java/cn/octopusyan/dmt/common/manager/ConfigManager.java b/src/main/java/cn/octopusyan/dmt/common/manager/ConfigManager.java new file mode 100644 index 0000000..4204cb2 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/common/manager/ConfigManager.java @@ -0,0 +1,253 @@ +package cn.octopusyan.dmt.common.manager; + +import atlantafx.base.theme.*; +import cn.octopusyan.dmt.Application; +import cn.octopusyan.dmt.common.config.Constants; +import cn.octopusyan.dmt.common.enums.ProxySetup; +import cn.octopusyan.dmt.common.manager.http.HttpUtil; +import cn.octopusyan.dmt.common.manager.thread.ThreadPoolManager; +import cn.octopusyan.dmt.model.ConfigModel; +import cn.octopusyan.dmt.model.ProxyInfo; +import cn.octopusyan.dmt.model.Translate; +import cn.octopusyan.dmt.model.UpgradeConfig; +import cn.octopusyan.dmt.translate.TranslateApi; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import javafx.application.Platform; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.net.Socket; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 客户端设置 + * + * @author octopus_yan@foxmail.com + */ +public class ConfigManager { + private static final Logger logger = LoggerFactory.getLogger(ConfigManager.class); + public static ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory()); + + public static final UpgradeConfig upgradeConfig = new UpgradeConfig(); + public static final String DEFAULT_THEME = new PrimerLight().getName(); + public static List THEME_LIST = List.of( + new PrimerLight(), new PrimerDark(), + new NordLight(), new NordDark(), + new CupertinoLight(), new CupertinoDark(), + new Dracula() + ); + public static Map THEME_MAP = THEME_LIST.stream() + .collect(Collectors.toMap(Theme::getName, Function.identity())); + + private static ConfigModel configModel; + + static { + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); + } + + public static void load() { + configModel = loadConfig(Constants.CONFIG_FILE_PATH, ConfigModel.class); + if (configModel == null) + configModel = new ConfigModel(); + } + + public static T loadConfig(String path, Class clazz) { + File src = new File(path); + try { + if (!src.exists()) { + checkFile(src, clazz); + } + return objectMapper.readValue(src, clazz); + } catch (Exception e) { + logger.error(String.format("load %s error", clazz.getSimpleName()), e); + } + return null; + } + + private static void checkFile(File src, Class clazz) throws Exception { + if (!src.exists()) { + File parentDir = FileUtils.createParentDirectories(src); + if (!parentDir.exists()) + logger.error("{} 创建失败", src.getAbsolutePath()); + } + objectMapper.writeValue(src, clazz.getDeclaredConstructor().newInstance()); + } + + public static void save() { + try { + objectMapper.writeValue(new File(Constants.CONFIG_FILE_PATH), configModel); + } catch (IOException e) { + logger.error("save config error", e); + } + } + +// --------------------------------{ 主题 }------------------------------------------ + + public static String themeName() { + return configModel.getTheme(); + } + + public static Theme theme() { + return THEME_MAP.get(themeName()); + } + + public static void theme(Theme theme) { + Application.setUserAgentStylesheet(theme.getUserAgentStylesheet()); + configModel.setTheme(theme.getName()); + } + +// --------------------------------{ 翻译接口配置 }------------------------------------------ + + public static TranslateApi translateApi() { + return TranslateApi.get(configModel.getTranslate().getUse()); + } + + public static void translateApi(TranslateApi api) { + configModel.getTranslate().setUse(api.getName()); + } + + public static Translate.Config getTranslateConfig(TranslateApi api) { + return Optional.of(configModel.getTranslate().getConfig().get(api.getName())) + .orElse(api.translate()); + } + + public static boolean hasTranslateApiKey(TranslateApi api) { + return StringUtils.isNoneEmpty(getTranslateConfig(api).getAppId()); + } + + public static void translateAppid(TranslateApi api, String appId) { + getTranslateConfig(api).setAppId(appId); + } + + public static String translateAppid(TranslateApi api) { + return getTranslateConfig(api).getAppId(); + } + + public static void translateApikey(TranslateApi api, String secretKey) { + getTranslateConfig(api).setSecretKey(secretKey); + } + + public static String translateApikey(TranslateApi api) { + return getTranslateConfig(api).getSecretKey(); + } + + public static void translateQps(TranslateApi api, int qps) { + getTranslateConfig(api).setQps(qps); + } + + public static int translateQps(TranslateApi api) { + return getTranslateConfig(api).getQps(); + } + +// --------------------------------{ 网络代理 }------------------------------------------ + + public static ProxySetup proxySetup() { + return ProxySetup.valueOf(StringUtils.upperCase(getProxyInfo().getSetup())); + } + + public static void proxyTestUrl(String url) { + getProxyInfo().setTestUrl(url); + } + + public static String proxyTestUrl() { + return getProxyInfo().getTestUrl(); + } + + public static void proxySetup(ProxySetup setup) { + getProxyInfo().setSetup(setup.getCode()); + + switch (setup) { + case NO_PROXY -> HttpUtil.getInstance().clearProxy(); + case SYSTEM, MANUAL -> { + if (ProxySetup.MANUAL.equals(setup) && !hasProxy()) + return; + HttpUtil.getInstance().proxy(setup, ConfigManager.getProxyInfo()); + } + } + } + + public static boolean hasProxy() { + if (configModel == null) + return false; + ProxyInfo proxyInfo = getProxyInfo(); + return proxyInfo != null + && StringUtils.isNoneEmpty(proxyInfo.getHost()) + && StringUtils.isNoneEmpty(proxyInfo.getPort()) + && Integer.parseInt(proxyInfo.getPort()) > 0; + } + + public static ProxyInfo getProxyInfo() { + ProxyInfo proxyInfo = configModel.getProxy(); + + if (proxyInfo == null) + setProxyInfo(new ProxyInfo()); + + return configModel.getProxy(); + } + + private static void setProxyInfo(ProxyInfo info) { + configModel.setProxy(info); + } + + public static String proxyHost() { + return getProxyInfo().getHost(); + } + + public static void proxyHost(String host) { + getProxyInfo().setHost(host); + } + + public static String proxyPort() { + return getProxyInfo().getPort(); + } + + public static int getProxyPort() { + return Integer.parseInt(proxyPort()); + } + + public static void proxyPort(String port) { + if (!NumberUtils.isParsable(port)) return; + + getProxyInfo().setPort(port); + } + + public static void checkProxy(BiConsumer consumer) { + if (ProxySetup.SYSTEM.equals(proxySetup())) { + consumer.accept(true, ""); + return; + } + if (!hasProxy()) return; + + ThreadPoolManager.getInstance().execute(() -> { + try { + try (Socket socket = new Socket(proxyHost(), getProxyPort())) { + Platform.runLater(() -> consumer.accept(true, "success")); + } catch (IOException e) { + Platform.runLater(() -> consumer.accept(false, "connection timed out")); + } + } catch (Exception e) { + logger.error(STR."host=\{proxyHost()},port=\{proxyPort()}", e); + Platform.runLater(() -> consumer.accept(false, e.getMessage())); + } + }); + } + +// --------------------------------{ 版本检查 }------------------------------------------ + + public static UpgradeConfig upgradeConfig() { + return upgradeConfig; + } +} diff --git a/src/main/java/cn/octopusyan/dmt/common/manager/http/CookieManager.java b/src/main/java/cn/octopusyan/dmt/common/manager/http/CookieManager.java new file mode 100644 index 0000000..2a3096d --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/common/manager/http/CookieManager.java @@ -0,0 +1,371 @@ +package cn.octopusyan.dmt.common.manager.http; + +import java.net.*; +import java.util.*; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Cookie 管理 + * + * @author octopus_yan + */ +public class CookieManager { + + private static final InMemoryCookieStore inMemoryCookieStore = new InMemoryCookieStore(); + private static final java.net.CookieManager cookieManager = + new java.net.CookieManager(inMemoryCookieStore, CookiePolicy.ACCEPT_ALL); + + public static java.net.CookieManager get() { + return cookieManager; + } + + public static InMemoryCookieStore getStore() { + return inMemoryCookieStore; + } + + public static class InMemoryCookieStore implements CookieStore { + // the in-memory representation of cookies + private final List cookieJar; + + // the cookies are indexed by its domain and associated uri (if present) + // CAUTION: when a cookie removed from main data structure (i.e. cookieJar), + // it won't be cleared in domainIndex & uriIndex. Double-check the + // presence of cookie when retrieve one form index store. + private final Map> domainIndex; + private final Map> uriIndex; + + // use ReentrantLock instead of synchronized for scalability + private final ReentrantLock lock; + + + /** + * The default ctor + */ + public InMemoryCookieStore() { + cookieJar = new ArrayList<>(); + domainIndex = new HashMap<>(); + uriIndex = new HashMap<>(); + + lock = new ReentrantLock(false); + } + + /** + * Add one cookie into cookie store. + */ + public void add(URI uri, HttpCookie cookie) { + // pre-condition : argument can't be null + if (cookie == null) { + throw new NullPointerException("cookie is null"); + } + + + lock.lock(); + try { + // remove the ole cookie if there has had one + cookieJar.remove(cookie); + + // add new cookie if it has a non-zero max-age + if (cookie.getMaxAge() != 0) { + cookieJar.add(cookie); + // and add it to domain index + if (cookie.getDomain() != null) { + addIndex(domainIndex, cookie.getDomain(), cookie); + } + if (uri != null) { + // add it to uri index, too + addIndex(uriIndex, getEffectiveURI(uri), cookie); + } + } + } finally { + lock.unlock(); + } + } + + + /** + * Get all cookies, which: + * 1) given uri domain-matches with, or, associated with + * given uri when added to the cookie store. + * 3) not expired. + * See RFC 2965 sec. 3.3.4 for more detail. + */ + public List get(URI uri) { + // argument can't be null + if (uri == null) { + throw new NullPointerException("uri is null"); + } + + List cookies = new ArrayList<>(); + boolean secureLink = "https".equalsIgnoreCase(uri.getScheme()); + lock.lock(); + try { + // check domainIndex first + getInternal1(cookies, domainIndex, uri.getHost(), secureLink); + // check uriIndex then + getInternal2(cookies, uriIndex, getEffectiveURI(uri), secureLink); + } finally { + lock.unlock(); + } + + return cookies; + } + + /** + * Get all cookies in cookie store, except those have expired + */ + public List getCookies() { + List rt; + + lock.lock(); + try { + cookieJar.removeIf(HttpCookie::hasExpired); + } finally { + rt = Collections.unmodifiableList(cookieJar); + lock.unlock(); + } + + return rt; + } + + /** + * Get all URIs, which are associated with at least one cookie + * of this cookie store. + */ + public List getURIs() { + List uris; + + lock.lock(); + try { + Iterator it = uriIndex.keySet().iterator(); + while (it.hasNext()) { + URI uri = it.next(); + List cookies = uriIndex.get(uri); + if (cookies == null || cookies.isEmpty()) { + // no cookies list or an empty list associated with + // this uri entry, delete it + it.remove(); + } + } + } finally { + uris = new ArrayList<>(uriIndex.keySet()); + lock.unlock(); + } + + return uris; + } + + + /** + * Remove a cookie from store + */ + public boolean remove(URI uri, HttpCookie ck) { + // argument can't be null + if (ck == null) { + throw new NullPointerException("cookie is null"); + } + + boolean modified; + lock.lock(); + try { + modified = cookieJar.remove(ck); + } finally { + lock.unlock(); + } + + return modified; + } + + + /** + * Remove all cookies in this cookie store. + */ + public boolean removeAll() { + lock.lock(); + try { + if (cookieJar.isEmpty()) { + return false; + } + cookieJar.clear(); + domainIndex.clear(); + uriIndex.clear(); + } finally { + lock.unlock(); + } + + return true; + } + + + /* ---------------- Private operations -------------- */ + + + /* + * This is almost the same as HttpCookie.domainMatches except for + * one difference: It won't reject cookies when the 'H' part of the + * domain contains a dot ('.'). + * I.E.: RFC 2965 section 3.3.2 says that if host is x.y.domain.com + * and the cookie domain is .domain.com, then it should be rejected. + * However that's not how the real world works. Browsers don't reject and + * some sites, like yahoo.com do actually expect these cookies to be + * passed along. + * And should be used for 'old' style cookies (aka Netscape type of cookies) + */ + private boolean netscapeDomainMatches(String domain, String host) { + if (domain == null || host == null) { + return false; + } + + // if there's no embedded dot in domain and domain is not .local + boolean isLocalDomain = ".local".equalsIgnoreCase(domain); + int embeddedDotInDomain = domain.indexOf('.'); + if (embeddedDotInDomain == 0) { + embeddedDotInDomain = domain.indexOf('.', 1); + } + if (!isLocalDomain && (embeddedDotInDomain == -1 || embeddedDotInDomain == domain.length() - 1)) { + return false; + } + + // if the host name contains no dot and the domain name is .local + int firstDotInHost = host.indexOf('.'); + if (firstDotInHost == -1 && isLocalDomain) { + return true; + } + + int domainLength = domain.length(); + int lengthDiff = host.length() - domainLength; + if (lengthDiff == 0) { + // if the host name and the domain name are just string-compare equal + return host.equalsIgnoreCase(domain); + } else if (lengthDiff > 0) { + // need to check H & D component + String H = host.substring(0, lengthDiff); + String D = host.substring(lengthDiff); + + return (D.equalsIgnoreCase(domain)); + } else if (lengthDiff == -1) { + // if domain is actually .host + return (domain.charAt(0) == '.' && + host.equalsIgnoreCase(domain.substring(1))); + } + + return false; + } + + private void getInternal1(List cookies, Map> cookieIndex, + String host, boolean secureLink) { + // Use a separate list to handle cookies that need to be removed so + // that there is no conflict with iterators. + ArrayList toRemove = new ArrayList<>(); + for (Map.Entry> entry : cookieIndex.entrySet()) { + String domain = entry.getKey(); + List lst = entry.getValue(); + for (HttpCookie c : lst) { + if ((c.getVersion() == 0 && netscapeDomainMatches(domain, host)) || + (c.getVersion() == 1 && HttpCookie.domainMatches(domain, host))) { + if ((cookieJar.contains(c))) { + // the cookie still in main cookie store + if (!c.hasExpired()) { + // don't add twice and make sure it's the proper + // security level + if ((secureLink || !c.getSecure()) && + !cookies.contains(c)) { + cookies.add(c); + } + } else { + toRemove.add(c); + } + } else { + // the cookie has been removed from main store, + // so also remove it from domain indexed store + toRemove.add(c); + } + } + } + // Clear up the cookies that need to be removed + for (HttpCookie c : toRemove) { + lst.remove(c); + cookieJar.remove(c); + + } + toRemove.clear(); + } + } + + // @param cookies [OUT] contains the found cookies + // @param cookieIndex the index + // @param comparator the prediction to decide whether or not + // a cookie in index should be returned + private void getInternal2(List cookies, + Map> cookieIndex, + Comparable comparator, boolean secureLink) { + for (T index : cookieIndex.keySet()) { + if (comparator.compareTo(index) == 0) { + List indexedCookies = cookieIndex.get(index); + // check the list of cookies associated with this domain + if (indexedCookies != null) { + Iterator it = indexedCookies.iterator(); + while (it.hasNext()) { + HttpCookie ck = it.next(); + if (cookieJar.contains(ck)) { + // the cookie still in main cookie store + if (!ck.hasExpired()) { + // don't add twice + if ((secureLink || !ck.getSecure()) && + !cookies.contains(ck)) + cookies.add(ck); + } else { + it.remove(); + cookieJar.remove(ck); + } + } else { + // the cookie has been removed from main store, + // so also remove it from domain indexed store + it.remove(); + } + } + } // end of indexedCookies != null + } // end of comparator.compareTo(index) == 0 + } // end of cookieIndex iteration + } + + // add 'cookie' indexed by 'index' into 'indexStore' + private void addIndex(Map> indexStore, + T index, + HttpCookie cookie) { + if (index != null) { + List cookies = indexStore.get(index); + if (cookies != null) { + // there may already have the same cookie, so remove it first + cookies.remove(cookie); + + cookies.add(cookie); + } else { + cookies = new ArrayList<>(); + cookies.add(cookie); + indexStore.put(index, cookies); + } + } + } + + + // + // for cookie purpose, the effective uri should only be http://host + // the path will be taken into account when path-match algorithm applied + // + private URI getEffectiveURI(URI uri) { + URI effectiveURI; + try { + effectiveURI = new URI("http", + uri.getHost(), + null, // path component + null, // query component + null // fragment component + ); + } catch (URISyntaxException ignored) { + effectiveURI = uri; + } + + return effectiveURI; + } + } +} diff --git a/src/main/java/cn/octopusyan/dmt/common/manager/http/HttpConfig.java b/src/main/java/cn/octopusyan/dmt/common/manager/http/HttpConfig.java new file mode 100644 index 0000000..46f5b7a --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/common/manager/http/HttpConfig.java @@ -0,0 +1,116 @@ +package cn.octopusyan.dmt.common.manager.http; + +import lombok.Data; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.net.Authenticator; +import java.net.CookieHandler; +import java.net.ProxySelector; +import java.net.http.HttpClient; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.cert.X509Certificate; +import java.util.concurrent.Executor; + +/** + * Http配置参数 + * + * @author octopus_yan@foxmail.com + */ +@Data +public class HttpConfig { + private static final Logger logger = LoggerFactory.getLogger(HttpConfig.class); + + static { + // 使用系统默认代理 + System.setProperty("java.net.useSystemProxies", "true"); + } + + /** + * http版本 + */ + private HttpClient.Version version = HttpClient.Version.HTTP_2; + + /** + * 转发策略 + */ + private HttpClient.Redirect redirect = HttpClient.Redirect.NORMAL; + + /** + * 线程池 + */ + private Executor executor; + + /** + * 认证 + */ + private Authenticator authenticator; + + /** + * 代理 + */ + private ProxySelector proxySelector; + + /** + * CookieHandler + */ + private CookieHandler cookieHandler; + + /** + * sslContext + */ + private SSLContext sslContext; + + /** + * sslParams + */ + private SSLParameters sslParameters; + + /** + * 连接超时时间毫秒 + */ + private int connectTimeout = 10000; + + /** + * 默认读取数据超时时间 + */ + private int defaultReadTimeout = 1200000; + + + public HttpConfig() { + // SSL + sslParameters = new SSLParameters(); + sslParameters.setEndpointIdentificationAlgorithm(""); + sslParameters.setProtocols(new String[]{"TLSv1.2"}); + try { + sslContext = SSLContext.getInstance("TLSv1.2"); + System.setProperty("jdk.internal.httpclient.disableHostnameVerification", "true");//取消主机名验证 + sslContext.init(null, trustAllCertificates, new SecureRandom()); + } catch (NoSuchAlgorithmException | KeyManagementException e) { + logger.error("", e); + } + } + + private static final TrustManager[] trustAllCertificates = new X509TrustManager[]{new X509TrustManager() { + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; // Not relevant. + } + + @Override + public void checkClientTrusted(X509Certificate[] arg0, String arg1) { + // TODO Auto-generated method stub + } + + @Override + public void checkServerTrusted(X509Certificate[] arg0, String arg1) { + // TODO Auto-generated method stub + } + }}; +} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/http/HttpUtil.java b/src/main/java/cn/octopusyan/dmt/common/manager/http/HttpUtil.java similarity index 51% rename from src/main/java/cn/octopusyan/dayzmodtranslator/manager/http/HttpUtil.java rename to src/main/java/cn/octopusyan/dmt/common/manager/http/HttpUtil.java index 09caa16..2bd1e5a 100644 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/http/HttpUtil.java +++ b/src/main/java/cn/octopusyan/dmt/common/manager/http/HttpUtil.java @@ -1,7 +1,13 @@ -package cn.octopusyan.dayzmodtranslator.manager.http; +package cn.octopusyan.dmt.common.manager.http; -import com.alibaba.fastjson2.JSONObject; +import cn.octopusyan.dmt.common.enums.ProxySetup; +import cn.octopusyan.dmt.common.manager.http.response.BodyHandler; +import cn.octopusyan.dmt.common.util.JsonUtil; +import cn.octopusyan.dmt.model.ProxyInfo; +import com.fasterxml.jackson.databind.JsonNode; +import lombok.extern.slf4j.Slf4j; +import java.io.File; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ProxySelector; @@ -11,15 +17,19 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; import java.time.Duration; -import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.function.BiConsumer; /** * 网络请求封装 * * @author octopus_yan@foxmail.com */ +@Slf4j public class HttpUtil { private volatile static HttpUtil util; private volatile HttpClient httpClient; @@ -57,15 +67,20 @@ public class HttpUtil { return builder.build(); } - public HttpUtil proxy(String host, int port) { + public void proxy(ProxySetup setup, ProxyInfo proxy) { if (httpClient == null) throw new RuntimeException("are you ready ?"); - InetSocketAddress unresolved = InetSocketAddress.createUnresolved(host, port); - ProxySelector other = ProxySelector.of(unresolved); - this.httpConfig.setProxySelector(other); + switch (setup) { + case NO_PROXY -> clearProxy(); + case SYSTEM -> httpConfig.setProxySelector(ProxySelector.getDefault()); + case MANUAL -> { + InetSocketAddress unresolved = InetSocketAddress.createUnresolved(proxy.getHost(), Integer.parseInt(proxy.getPort())); + httpConfig.setProxySelector(ProxySelector.of(unresolved)); + } + } + this.httpClient = createClient(httpConfig); - return this; } public void clearProxy() { @@ -76,24 +91,26 @@ public class HttpUtil { httpClient = createClient(httpConfig); } - public HttpClient getHttpClient() { - return httpClient; + public void close() { + if (httpClient == null) return; + httpClient.close(); } - public String get(String uri, JSONObject header, JSONObject param) throws IOException, InterruptedException { + public String get(String uri, JsonNode header, JsonNode param) throws IOException, InterruptedException { HttpRequest.Builder request = getRequest(uri + createFormParams(param), header).GET(); HttpResponse response = httpClient.send(request.build(), HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); return response.body(); } - public String post(String uri, JSONObject header, JSONObject param) throws IOException, InterruptedException { + public String post(String uri, JsonNode header, JsonNode param) throws IOException, InterruptedException { HttpRequest.Builder request = getRequest(uri, header) - .POST(HttpRequest.BodyPublishers.ofString(param.toJSONString())); + .header("Content-Type", "application/json;charset=utf-8") + .POST(HttpRequest.BodyPublishers.ofString(JsonUtil.toJsonString(param))); HttpResponse response = httpClient.send(request.build(), HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); return response.body(); } - public String postForm(String uri, JSONObject header, JSONObject param) throws IOException, InterruptedException { + public String postForm(String uri, JsonNode header, JsonNode param) throws IOException, InterruptedException { HttpRequest.Builder request = getRequest(uri + createFormParams(param), header) .POST(HttpRequest.BodyPublishers.noBody()); @@ -101,39 +118,73 @@ public class HttpUtil { return response.body(); } - private HttpRequest.Builder getRequest(String uri, JSONObject header) { + public void download(String url, String savePath, BiConsumer listener) throws IOException, InterruptedException { + HttpRequest request = getRequest(url, null).build(); + // 检查bin目录 + File binDir = new File(savePath); + if (!binDir.exists()) { + log.debug(STR."dir [\{savePath}] not exists"); + //noinspection ResultOfMethodCallIgnored + binDir.mkdirs(); + log.debug(STR."created dir [\{savePath}]"); + } + + // 下载处理器 + var handler = BodyHandler.create( + Path.of(savePath), + StandardOpenOption.CREATE, StandardOpenOption.WRITE + ); + + // 下载监听 + if (listener != null) + handler.listener(listener); + + HttpResponse response = httpClient.send(request, handler); + } + + private HttpRequest.Builder getRequest(String uri, JsonNode header) { HttpRequest.Builder request = HttpRequest.newBuilder(); // 请求地址 request.uri(URI.create(uri)); // 请求头 if (header != null && !header.isEmpty()) { - for (String key : header.keySet()) { - request.header(key, header.getString(key)); + for (Map.Entry property : header.properties()) { + String key = property.getKey(); + request.header(key, JsonUtil.toJsonString(property.getValue())); } } + // Cookie +// List cookies = CookieManager.getStore().get(URI.create(uri)); +// if (!cookies.isEmpty()) { +// String cookie = cookies.stream() +// .map(item -> STR."\{item.getName()}=\{item.getValue()}") +// .collect(Collectors.joining(";")); +// request.header("Cookie", cookie); +// } return request; } - private String createFormParams(JSONObject params) { + private String createFormParams(JsonNode params) { StringBuilder formParams = new StringBuilder(); if (params == null) { return formParams.toString(); } - for (String key : params.keySet()) { - Object value = params.get(key); - if (value instanceof String) { - value = URLEncoder.encode(String.valueOf(value), StandardCharsets.UTF_8); + for (Map.Entry property : params.properties()) { + String key = property.getKey(); + JsonNode value = params.get(key); + if (value.isTextual()) { + String value_ = URLEncoder.encode(String.valueOf(value.asText()), StandardCharsets.UTF_8); + formParams.append("&").append(key).append("=").append(value_); + } else if (value.isNumber()) { formParams.append("&").append(key).append("=").append(value); - } else if (value instanceof Number) { - formParams.append("&").append(key).append("=").append(value); - } else if (value instanceof List) { - formParams.append("&").append(key).append("=").append(params.getJSONArray(key)); + } else if (value.isArray()) { + formParams.append("&").append(key).append("=").append(JsonUtil.toJsonString(value)); } else { - formParams.append("&").append(key).append("=").append(params.getJSONObject(key)); + formParams.append("&").append(key).append("=").append(JsonUtil.toJsonString(value)); } } if (!formParams.isEmpty()) { - formParams = new StringBuilder("?" + formParams.substring(1)); + formParams = new StringBuilder(STR."?\{formParams.substring(1)}"); } return formParams.toString(); diff --git a/src/main/java/cn/octopusyan/dmt/common/manager/http/response/BodyHandler.java b/src/main/java/cn/octopusyan/dmt/common/manager/http/response/BodyHandler.java new file mode 100644 index 0000000..8934dd8 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/common/manager/http/response/BodyHandler.java @@ -0,0 +1,102 @@ +package cn.octopusyan.dmt.common.manager.http.response; + +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +import java.net.http.HttpResponse; +import java.nio.ByteBuffer; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.Flow; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +/** + * 下载处理 + * + * @author octopus_yan + */ +@Slf4j +public class BodyHandler implements HttpResponse.BodyHandler { + private final HttpResponse.BodyHandler handler; + private BiConsumer consumer; + + private BodyHandler(HttpResponse.BodyHandler handler) { + this.handler = handler; + } + + public static BodyHandler create(Path directory, OpenOption... openOptions) { + return new BodyHandler(HttpResponse.BodyHandlers.ofFileDownload(directory, openOptions)); + } + + @Override + public HttpResponse.BodySubscriber apply(HttpResponse.ResponseInfo responseInfo) { + AtomicLong length = new AtomicLong(-1); + // 获取文件大小 + Optional string = responseInfo.headers().firstValue("content-length"); + string.ifPresentOrElse(s -> { + length.set(Long.parseLong(s)); + log.debug(STR."========={content-length = \{s}}========="); + }, () -> { + String msg = "response not has header [content-length]"; + log.error(msg); + }); + + BodySubscriber subscriber = new BodySubscriber(handler.apply(responseInfo)); + subscriber.setConsumer(progress -> consumer.accept(length.get(), progress)); + + return subscriber; + } + + public void listener(BiConsumer consumer) { + this.consumer = consumer; + } + + public static class BodySubscriber implements HttpResponse.BodySubscriber { + private final HttpResponse.BodySubscriber subscriber; + private final AtomicLong progress = new AtomicLong(0); + @Setter + private Consumer consumer; + + public BodySubscriber(HttpResponse.BodySubscriber subscriber) { + this.subscriber = subscriber; + } + + @Override + public CompletionStage getBody() { + return subscriber.getBody(); + } + + @Override + public void onSubscribe(Flow.Subscription subscription) { + subscriber.onSubscribe(subscription); + } + + @Override + public void onNext(List item) { + subscriber.onNext(item); + + // 记录进度 + for (ByteBuffer byteBuffer : item) { + progress.addAndGet(byteBuffer.limit()); + } + consumer.accept(progress.get()); + } + + @Override + public void onError(Throwable throwable) { + subscriber.onError(throwable); + } + + @Override + public void onComplete() { + subscriber.onComplete(); + + consumer.accept(progress.get()); + } + } +} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/thread/ThreadFactory.java b/src/main/java/cn/octopusyan/dmt/common/manager/thread/ThreadFactory.java similarity index 82% rename from src/main/java/cn/octopusyan/dayzmodtranslator/manager/thread/ThreadFactory.java rename to src/main/java/cn/octopusyan/dmt/common/manager/thread/ThreadFactory.java index 8f3019e..3a31327 100644 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/thread/ThreadFactory.java +++ b/src/main/java/cn/octopusyan/dmt/common/manager/thread/ThreadFactory.java @@ -1,4 +1,4 @@ -package cn.octopusyan.dayzmodtranslator.manager.thread; +package cn.octopusyan.dmt.common.manager.thread; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,7 +26,7 @@ public class ThreadFactory implements java.util.concurrent.ThreadFactory { public ThreadFactory(String prefix) { group = Thread.currentThread().getThreadGroup(); - namePrefix = prefix + "-" + poolNumber.getAndIncrement() + "-thread-"; + namePrefix = STR."\{prefix}-\{poolNumber.getAndIncrement()}-thread-"; } @Override @@ -36,9 +36,7 @@ public class ThreadFactory implements java.util.concurrent.ThreadFactory { namePrefix + threadNumber.getAndIncrement(), 0); - t.setUncaughtExceptionHandler((t1, e) -> { - logger.error("thread : {}, error", t1.getName(), e); - }); + t.setUncaughtExceptionHandler((t1, e) -> logger.error("thread : {}, error", t1.getName(), e)); if (t.isDaemon()) t.setDaemon(false); diff --git a/src/main/java/cn/octopusyan/dmt/common/manager/thread/ThreadPoolManager.java b/src/main/java/cn/octopusyan/dmt/common/manager/thread/ThreadPoolManager.java new file mode 100644 index 0000000..726e5bf --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/common/manager/thread/ThreadPoolManager.java @@ -0,0 +1,55 @@ +package cn.octopusyan.dmt.common.manager.thread; + + +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * 线程池管理类 + */ +public final class ThreadPoolManager extends ThreadPoolExecutor { + + private static volatile ThreadPoolManager sInstance; + private static final List poolManagerList = new ArrayList<>(); + + private ThreadPoolManager() { + this(""); + } + + private ThreadPoolManager(String threadPoolName) { + super(32, + 200, + 10, + TimeUnit.SECONDS, + new LinkedBlockingQueue<>(200), + new ThreadFactory(StringUtils.isEmpty(threadPoolName) ? ThreadFactory.DEFAULT_THREAD_PREFIX : threadPoolName), + new DiscardPolicy()); + } + + public static ThreadPoolManager getInstance(String threadPoolName) { + ThreadPoolManager threadPoolManager = new ThreadPoolManager(threadPoolName); + poolManagerList.add(threadPoolManager); + return threadPoolManager; + } + + public static ThreadPoolManager getInstance() { + if (sInstance == null) { + synchronized (ThreadPoolManager.class) { + if (sInstance == null) { + sInstance = new ThreadPoolManager(); + } + } + } + return sInstance; + } + + public static void shutdownAll() { + getInstance().shutdown(); + poolManagerList.forEach(ThreadPoolExecutor::shutdown); + } +} \ No newline at end of file diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/util/ClipUtil.java b/src/main/java/cn/octopusyan/dmt/common/util/ClipUtil.java similarity index 79% rename from src/main/java/cn/octopusyan/dayzmodtranslator/util/ClipUtil.java rename to src/main/java/cn/octopusyan/dmt/common/util/ClipUtil.java index 771eb5e..f0b81b0 100644 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/util/ClipUtil.java +++ b/src/main/java/cn/octopusyan/dmt/common/util/ClipUtil.java @@ -1,18 +1,21 @@ -package cn.octopusyan.dayzmodtranslator.util; +package cn.octopusyan.dmt.common.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.awt.*; import java.awt.datatransfer.*; import java.io.IOException; /** - *

author : octopus yan - *

email : octopus_yan@foxmail.com - *

description : 剪切板工具 - *

create : 2022-4-14 23:21 + * 剪切板工具 + * + * @author octopus_yan */ public class ClipUtil { //获取系统剪切板 private static final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + private static final Logger log = LoggerFactory.getLogger(ClipUtil.class); public static void setClip(String data) { //构建String数据类型 @@ -28,7 +31,7 @@ public class ClipUtil { //从数据中获取文本值 return (String) content.getTransferData(DataFlavor.stringFlavor); } catch (UnsupportedFlavorException | IOException e) { - e.printStackTrace(); + log.error("", e); return null; } } diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/util/FxmlUtil.java b/src/main/java/cn/octopusyan/dmt/common/util/FxmlUtil.java similarity index 80% rename from src/main/java/cn/octopusyan/dayzmodtranslator/util/FxmlUtil.java rename to src/main/java/cn/octopusyan/dmt/common/util/FxmlUtil.java index 1061b96..aa11f31 100644 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/util/FxmlUtil.java +++ b/src/main/java/cn/octopusyan/dmt/common/util/FxmlUtil.java @@ -1,5 +1,6 @@ -package cn.octopusyan.dayzmodtranslator.util; +package cn.octopusyan.dmt.common.util; +import cn.octopusyan.dmt.common.config.Context; import javafx.fxml.FXMLLoader; import javafx.fxml.JavaFXBuilderFactory; @@ -19,7 +20,7 @@ public class FxmlUtil { FxmlUtil.class.getResource(prefix + name + suffix), null, new JavaFXBuilderFactory(), - null, + Context.getControlFactory(), StandardCharsets.UTF_8 ); } diff --git a/src/main/java/cn/octopusyan/dmt/common/util/JsonUtil.java b/src/main/java/cn/octopusyan/dmt/common/util/JsonUtil.java new file mode 100644 index 0000000..7964284 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/common/util/JsonUtil.java @@ -0,0 +1,187 @@ +package cn.octopusyan.dmt.common.util; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; + +/** + * Jackson 封装工具类 + * + * @author octopus_yan + */ +public class JsonUtil { + private static final Logger log = LoggerFactory.getLogger(JsonUtil.class); + private static final ObjectMapper objectMapper = new ObjectMapper(); + + /** + * 时间日期格式 + */ + private static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss"; + + static { + //对象的所有字段全部列入序列化 + objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS); + //取消默认转换timestamps形式 + objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); + //忽略空Bean转json的错误 + objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + //所有的日期格式都统一为以下的格式,即yyyy-MM-dd HH:mm:ss + objectMapper.setDateFormat(new SimpleDateFormat(STANDARD_FORMAT)); + //忽略 在json字符串中存在,但在java对象中不存在对应属性的情况。防止错误 + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } + + /** + * Json字符串 转 JavaBean + * + * @param jsonString Json字符串 + * @param clazz Java类对象 + * @param Java类 + * @return JavaBean + */ + public static T parseObject(String jsonString, Class clazz) { + T t = null; + try { + t = objectMapper.readValue(jsonString, clazz); + } catch (JsonProcessingException e) { + log.error("失败:{}", e.getMessage()); + } + return t; + } + + /** + * 读取Json文件 转 JavaBean + * + * @param file Json文件 + * @param clazz Java类对象 + * @param Java类 + * @return JavaBean + */ + public static T parseObject(File file, Class clazz) { + T t = null; + try { + t = objectMapper.readValue(file, clazz); + } catch (IOException e) { + log.error("失败:{}", e.getMessage()); + } + return t; + } + + /** + * 读取Json字符串 转 JavaBean集合 + * + * @param jsonArray Json字符串 + * @param reference 类型 + * @param JavaBean类型 + * @return JavaBean集合 + */ + public static T parseJsonArray(String jsonArray, TypeReference reference) { + T t = null; + try { + t = objectMapper.readValue(jsonArray, reference); + } catch (JsonProcessingException e) { + log.error("失败:{}", e.getMessage()); + } + return t; + } + + + /** + * JavaBean 转 Json字符串 + * + * @param object JavaBean + * @return Json字符串 + */ + public static String toJsonString(Object object) { + String jsonString = null; + try { + jsonString = objectMapper.writeValueAsString(object); + } catch (JsonProcessingException e) { + log.error("失败:{}", e.getMessage()); + } + return jsonString; + } + + /** + * JavaBean 转 字节数组 + * + * @param object JavaBean + * @return 字节数组 + */ + public static byte[] toByteArray(Object object) { + byte[] bytes = null; + try { + bytes = objectMapper.writeValueAsBytes(object); + } catch (JsonProcessingException e) { + log.error("失败:{}", e.getMessage()); + } + return bytes; + } + + /** + * JavaBean序列化到文件 + * + * @param file 写入文件对象 + * @param object JavaBean + */ + public static void objectToFile(File file, Object object) { + try { + objectMapper.writeValue(file, object); + } catch (Exception e) { + log.error("失败:{}", e.getMessage()); + } + } + + + /** + * Json字符串 转 JsonNode + * + * @param jsonString Json字符串 + * @return JsonNode + */ + public static JsonNode parseJsonObject(String jsonString) { + JsonNode jsonNode = null; + try { + jsonNode = objectMapper.readTree(jsonString); + } catch (JsonProcessingException e) { + log.error("失败:{}", e.getMessage()); + } + return jsonNode; + } + + /** + * JavaBean 转 JsonNode + * + * @param object JavaBean + * @return JsonNode + */ + public static JsonNode parseJsonObject(Object object) { + return objectMapper.valueToTree(object); + } + + /** + * JsonNode 转 Json字符串 + * + * @param jsonNode JsonNode + * @return Json字符串 + */ + public static String toJsonString(JsonNode jsonNode) { + String jsonString = null; + try { + jsonString = objectMapper.writeValueAsString(jsonNode); + } catch (JsonProcessingException e) { + log.error("失败:{}", e.getMessage()); + } + return jsonString; + } +} diff --git a/src/main/java/cn/octopusyan/dmt/common/util/ProcessesUtil.java b/src/main/java/cn/octopusyan/dmt/common/util/ProcessesUtil.java new file mode 100644 index 0000000..b814c48 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/common/util/ProcessesUtil.java @@ -0,0 +1,119 @@ +package cn.octopusyan.dmt.common.util; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.exec.*; + +import java.io.File; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * 命令工具类 + * + * @author octopus_yan@foxmail.com + */ +@Slf4j +public class ProcessesUtil { + private static final String NEW_LINE = System.lineSeparator(); + public static final int[] EXIT_VALUES = {0, 1}; + + private final DefaultExecutor executor; + private final ShutdownHookProcessDestroyer processDestroyer = new ShutdownHookProcessDestroyer(); + private OnExecuteListener listener; + private CommandLine commandLine; + + private static final Set set = new HashSet<>(); + + /** + * Prevent construction. + */ + private ProcessesUtil(String workingDirectory) { + this(new File(workingDirectory)); + } + + private ProcessesUtil(File workingDirectory) { + LogOutputStream logout = new LogOutputStream() { + @Override + protected void processLine(String line, int logLevel) { + if (listener != null) + listener.onExecute(line + NEW_LINE); + } + }; + PumpStreamHandler streamHandler = new PumpStreamHandler(logout, logout); + executor = DefaultExecutor.builder() + .setExecuteStreamHandler(streamHandler) + .setWorkingDirectory(workingDirectory) + .get(); + executor.setExitValues(EXIT_VALUES); + executor.setProcessDestroyer(processDestroyer); + } + + public static ProcessesUtil init(String workingDirectory) { + return init(new File(workingDirectory)); + } + public static ProcessesUtil init(File workingDirectory) { + ProcessesUtil util = new ProcessesUtil(workingDirectory); + set.add(util); + return util; + } + + public boolean exec(String command) { + commandLine = CommandLine.parse(command); + try { + int execute = executor.execute(commandLine); + return Arrays.stream(EXIT_VALUES).anyMatch(item -> item == execute); + } catch (Exception e) { + log.error("exec error", e); + return false; + } + } + + public void exec(String command, OnExecuteListener listener) { + this.listener = listener; + commandLine = CommandLine.parse(command); + DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler() { + @Override + public void onProcessComplete(int exitValue) { + if (listener != null) { + listener.onExecuteSuccess(Arrays.stream(EXIT_VALUES).noneMatch(item -> item == exitValue)); + } + } + + @Override + public void onProcessFailed(ExecuteException e) { + if (listener != null) { + listener.onExecuteError(e); + } + } + }; + try { + executor.execute(commandLine, handler); + } catch (Exception e) { + if (listener != null) listener.onExecuteError(e); + } + } + + public void destroy() { + if (processDestroyer.isEmpty()) return; + processDestroyer.run(); + } + + public boolean isRunning() { + return !processDestroyer.isEmpty(); + } + + public static void destroyAll() { + set.forEach(ProcessesUtil::destroy); + } + + public interface OnExecuteListener { + void onExecute(String msg); + + default void onExecuteSuccess(boolean success) { + } + + default void onExecuteError(Exception e) { + } + } +} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/util/PropertiesUtils.java b/src/main/java/cn/octopusyan/dmt/common/util/PropertiesUtils.java similarity index 69% rename from src/main/java/cn/octopusyan/dayzmodtranslator/util/PropertiesUtils.java rename to src/main/java/cn/octopusyan/dmt/common/util/PropertiesUtils.java index 1616515..839e110 100644 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/util/PropertiesUtils.java +++ b/src/main/java/cn/octopusyan/dmt/common/util/PropertiesUtils.java @@ -1,10 +1,13 @@ -package cn.octopusyan.dayzmodtranslator.util; +package cn.octopusyan.dmt.common.util; +import cn.octopusyan.dmt.utils.Resources; import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.util.Properties; /** @@ -17,14 +20,16 @@ public class PropertiesUtils { /** * 主配置文件 */ - private Properties properties; + private final Properties properties; /** * 启用配置文件 */ - private Properties propertiesCustom; + private final Properties propertiesCustom; private static PropertiesUtils propertiesUtils = new PropertiesUtils(); + public static final Logger logger = LoggerFactory.getLogger(PropertiesUtils.class); + /** * 私有构造,禁止直接创建 */ @@ -32,17 +37,18 @@ public class PropertiesUtils { // 读取配置启用的配置文件名 properties = new Properties(); propertiesCustom = new Properties(); - InputStream in = PropertiesUtils.class.getClassLoader().getResourceAsStream("application.properties"); + + InputStream in = Resources.getResourceAsStream("application.properties"); try { - properties.load(in); + properties.load(new InputStreamReader(in)); // 加载启用的配置 String property = properties.getProperty("profiles.active"); if (!StringUtils.isBlank(property)) { - InputStream cin = PropertiesUtils.class.getClassLoader().getResourceAsStream("application-" + property + ".properties"); - propertiesCustom.load(cin); + InputStream cin = Resources.getResourceAsStream("application-" + property + ".properties"); + propertiesCustom.load(new InputStreamReader(cin)); } } catch (IOException e) { - e.printStackTrace(); + logger.error("读取配置文件失败", e); } } @@ -58,17 +64,6 @@ public class PropertiesUtils { return propertiesUtils; } - /** - * 获取单例 - * - * @return PropertiesUtils - */ - public static PropertiesUtils getInstance(File file) { - PropertiesUtils util = new PropertiesUtils(); - - return util; - } - /** * 根据属性名读取值 * 先去主配置查询,如果查询不到,就去启用配置查询 diff --git a/src/main/java/cn/octopusyan/dmt/common/util/ViewUtil.java b/src/main/java/cn/octopusyan/dmt/common/util/ViewUtil.java new file mode 100644 index 0000000..f08bc44 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/common/util/ViewUtil.java @@ -0,0 +1,69 @@ +package cn.octopusyan.dmt.common.util; + +import cn.octopusyan.dmt.Application; +import javafx.scene.layout.Pane; +import javafx.stage.Screen; +import javafx.stage.Stage; + +import java.util.HashMap; +import java.util.Map; + +/** + * 工具 + * + * @author octopus_yan + */ +public class ViewUtil { + // 获取系统缩放比 + public static final double scaleX = Screen.getPrimary().getOutputScaleX(); + public static final double scaleY = Screen.getPrimary().getOutputScaleY(); + + + private static final Map paneXOffset = new HashMap<>(); + private static final Map paneYOffset = new HashMap<>(); + + public static void bindShadow(Pane pane) { + pane.setStyle(""" + -fx-background-radius: 5; + -fx-border-radius: 5; + -fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.3), 15, 0, 0, 0); + -fx-background-insets: 20; + -fx-padding: 20; + """); + } + + public static void bindDragged(Pane pane) { + Stage stage = getStage(pane); + bindDragged(pane, stage); + } + + public static void unbindDragged(Pane pane) { + pane.setOnMousePressed(null); + pane.setOnMouseDragged(null); + paneXOffset.remove(pane); + paneYOffset.remove(pane); + } + + public static void bindDragged(Pane pane, Stage stage) { + pane.setOnMousePressed(event -> { + paneXOffset.put(pane, stage.getX() - event.getScreenX()); + paneYOffset.put(pane, stage.getY() - event.getScreenY()); + }); + pane.setOnMouseDragged(event -> { + stage.setX(event.getScreenX() + paneXOffset.get(pane)); + stage.setY(event.getScreenY() + paneYOffset.get(pane)); + }); + } + + public static Stage getStage() { + return Application.getPrimaryStage(); + } + + public static Stage getStage(Pane pane) { + try { + return (Stage) pane.getScene().getWindow(); + } catch (Throwable e) { + return getStage(); + } + } +} diff --git a/src/main/java/cn/octopusyan/dmt/controller/MainController.java b/src/main/java/cn/octopusyan/dmt/controller/MainController.java new file mode 100644 index 0000000..b9bd2f8 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/controller/MainController.java @@ -0,0 +1,451 @@ +package cn.octopusyan.dmt.controller; + +import atlantafx.base.controls.ModalPane; +import atlantafx.base.theme.Styles; +import atlantafx.base.theme.Theme; +import cn.octopusyan.dmt.common.base.BaseController; +import cn.octopusyan.dmt.common.config.Context; +import cn.octopusyan.dmt.common.manager.ConfigManager; +import cn.octopusyan.dmt.common.util.ClipUtil; +import cn.octopusyan.dmt.common.util.FxmlUtil; +import cn.octopusyan.dmt.controller.component.WordEditController; +import cn.octopusyan.dmt.model.WordItem; +import cn.octopusyan.dmt.task.TranslateTask; +import cn.octopusyan.dmt.view.ConsoleLog; +import cn.octopusyan.dmt.view.EditButtonTableCell; +import cn.octopusyan.dmt.view.alert.AlertUtil; +import cn.octopusyan.dmt.view.filemanager.DirectoryTree; +import cn.octopusyan.dmt.viewModel.MainViewModel; +import javafx.application.Platform; +import javafx.beans.property.SimpleStringProperty; +import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; +import javafx.fxml.FXMLLoader; +import javafx.geometry.Pos; +import javafx.scene.Node; +import javafx.scene.control.*; +import javafx.scene.control.cell.TextFieldTableCell; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyCodeCombination; +import javafx.scene.input.KeyCombination; +import javafx.scene.input.TransferMode; +import javafx.scene.layout.Pane; +import javafx.scene.layout.Priority; +import javafx.scene.layout.StackPane; +import javafx.scene.layout.VBox; +import javafx.stage.FileChooser; +import org.apache.commons.io.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.regex.Pattern; + +/** + * 主界面 + * + * @author octopus_yan + */ +public class MainController extends BaseController { + private static final ConsoleLog consoleLog = ConsoleLog.getInstance(MainController.class); + + public Pane root; + + public Menu viewStyle; + + public static final ToggleGroup viewStyleGroup = new ToggleGroup(); + + public StackPane mainView; + // + public VBox translateView; + // 打开文件 + public StackPane selectFileBox; + public VBox openFileView; + public VBox dragFileView; + public VBox loadFileView; + // 工具栏 + public Button fileNameLabel; + public Button translate; + public ProgressBar translateProgress; + // 文件树加载 + public DirectoryTree treeFileBox; + public VBox loadWordBox; + public ProgressBar loadWordProgressBar; + // 翻译界面 + public Pane wordBox; + public TableView wordTable; + // 信息 + public TitledPane titledPane; + public TextArea logArea; + + public final ModalPane modalPane = new ModalPane(); + // 文件选择器 + public static final FileChooser fileChooser = new FileChooser(); + + static { + var extFilter = new FileChooser.ExtensionFilter("PBO files (*.pbo)", "*.pbo"); + fileChooser.getExtensionFilters().add(extFilter); + } + + @Override + public Pane getRootPanel() { + return root; + } + + @Override + public void initData() { + // 界面样式 + List list = ConfigManager.THEME_LIST.stream().map(this::createViewStyleItem).toList(); + viewStyle.getItems().addAll(list); + + // 信息 + ConsoleLog.init(logArea); + } + + @Override + public void initViewStyle() { + // 遮罩 + getRootPanel().getChildren().add(modalPane); + modalPane.displayProperty().addListener((_, _, val) -> { + if (!val) { + modalPane.setAlignment(Pos.CENTER); + modalPane.usePredefinedTransitionFactories(null); + } + }); + } + + @Override + public void initViewAction() { + + // 文件拖拽 + setDragAction(mainView); + + // 复制单元格内容 + Context.sceneProperty.addListener(_ -> Context.sceneProperty.get() + .getAccelerators() + .put(new KeyCodeCombination(KeyCode.C, KeyCombination.CONTROL_ANY), () -> { + ObservableList selectedCells = wordTable.getSelectionModel().getSelectedCells(); + for (TablePosition tablePosition : selectedCells) { + Object cellData = tablePosition.getTableColumn().getCellData(tablePosition.getRow()); + // 设置剪切板 + ClipUtil.setClip(cellData.toString()); + } + }) + ); + + // 日志栏清空 + logArea.contextMenuProperty().addListener(_ -> + logArea.getContextMenu().getItems().addListener((ListChangeListener) _ -> { + MenuItem clearLog = new MenuItem("清空"); + clearLog.setOnAction(_ -> logArea.clear()); + logArea.getContextMenu().getItems().add(clearLog); + }) + ); + } + + /** + * 设置文件拖拽效果 + */ + private void setDragAction(Pane fileBox) { + + // 进入 + fileBox.setOnDragEntered(dragEvent -> { + var dragboard = dragEvent.getDragboard(); + if (dragboard.hasFiles() && isPboFile(dragboard.getFiles().getFirst())) { + selectFileBox.setVisible(true); + dragFileView.setVisible(true); + } + }); + + //离开 + fileBox.setOnDragExited(_ -> { + selectFileBox.setVisible(false); + dragFileView.setVisible(false); + }); + + // + fileBox.setOnDragOver(dragEvent -> { + var dragboard = dragEvent.getDragboard(); + if (dragEvent.getGestureSource() != fileBox && dragboard.hasFiles()) { + /* allow for both copying and moving, whatever user chooses */ + dragEvent.acceptTransferModes(TransferMode.COPY_OR_MOVE); + } + dragEvent.consume(); + }); + + // 松手 + fileBox.setOnDragDropped(dragEvent -> { + dragFileView.setVisible(false); + + var db = dragEvent.getDragboard(); + boolean success = false; + var file = db.getFiles().getFirst(); + if (db.hasFiles() && isPboFile(file)) { + selectFile(file); + success = true; + } + /* 让源知道字符串是否已成功传输和使用 */ + dragEvent.setDropCompleted(success); + + dragEvent.consume(); + }); + } + + /** + * 打开文件选择器 + */ + public void selectFile() { + selectFile(fileChooser.showOpenDialog(getWindow())); + } + + /** + * 打开代理设置 + */ + public void openSetupProxy() throws IOException { + FXMLLoader load = FxmlUtil.load("setup/proxy-view"); + AlertUtil.builder(false) + .title("网络代理设置") + .content((Pane) load.load()) + .show(); + } + + /** + * 打开翻译设置 + */ + public void openSetupTranslate() throws IOException { + FXMLLoader load = FxmlUtil.load("setup/translate-view"); + AlertUtil.builder(false) + .title("翻译设置") + .content((Pane) load.load()) + .show(); + } + + public void setFileName(String name) { + fileNameLabel.setText("PBO文件:" + name); + } + + /** + * 显示加载PBO文件 + */ + public void onLoad() { + // 展示加载 + selectFileBox.setVisible(true); + loadFileView.setVisible(true); + wordBox.getChildren().remove(wordTable); + } + + /** + * 显示解包完成 + * + * @param path 解包路径 + */ + public void onUnpack(File path) { + // 加载解包目录 + treeFileBox.loadRoot(path); + // 隐藏文件选择 + loadFileView.setVisible(false); + selectFileBox.setVisible(false); + // 展示翻译界面 + translateView.setVisible(true); + loadWordBox.setVisible(true); + } + + /** + * 加载可翻译文本数据 + * + * @param wordItems 文本列表 + */ + public void onLoadWord(List wordItems) { + loadWordBox.setVisible(false); + wordBox.setVisible(true); + bindWordTable(wordItems); + translate.setDisable(false); + } + + /** + * 打包完成 + * + * @param packFile 打包临时文件 + */ + public void onPackOver(File packFile) { + // 选择文件保存地址 + fileChooser.setInitialFileName(packFile.getName()); + File file = fileChooser.showSaveDialog(getWindow()); + + if (file == null) + return; + + if (file.exists()) { + //文件已存在,则删除覆盖文件 + FileUtils.deleteQuietly(file); + } + + String exportFilePath = file.getAbsolutePath(); + consoleLog.info(STR."导出文件路径 => \{exportFilePath}"); + + try { + FileUtils.copyFile(packFile, file); + } catch (IOException e) { + consoleLog.error("保存文件失败!", e); + Platform.runLater(() -> AlertUtil.exception(e).content("保存文件失败!").show()); + } + } + + public void startTranslate() { + viewModel.startTranslate(); + } + + public void startPack() { + viewModel.pack(); + } + + public void selectAllLog() { + logArea.selectAll(); + } + + public void copyLog() { + logArea.copy(); + } + + public void clearLog() { + logArea.clear(); + } + + // ======================================{ }======================================== + + /** + * 打开文件 + */ + private void selectFile(File file) { + viewModel.selectFile(file); + viewModel.unpack(); + } + + /** + * 绑定表格数据 + * + * @param words 单词列表 + */ + private void bindWordTable(List words) { + + if (wordTable == null) { + wordTable = new TableView<>(); + // 填满 + VBox.setVgrow(wordTable, Priority.ALWAYS); + // 可编辑 + wordTable.setEditable(true); + // 自动调整列宽 + wordTable.setColumnResizePolicy(TableView.UNCONSTRAINED_RESIZE_POLICY); + // 边框 + Styles.toggleStyleClass(wordTable, Styles.BORDERED); +// // 行分隔 +// Styles.toggleStyleClass(wordTable, Styles.STRIPED); + // 单元格选择模式而不是行选择 + wordTable.getSelectionModel().setCellSelectionEnabled(true); + // 不允许选择多个单元格 + wordTable.getSelectionModel().setSelectionMode(SelectionMode.SINGLE); + + // 创建列 + TableColumn colFile = createColumn("文件"); + colFile.setCellValueFactory(param -> new SimpleStringProperty(param.getValue().getFile().getName())); + TableColumn colOriginal = createColumn("原文"); + colOriginal.setCellValueFactory(param -> param.getValue().getOriginalProperty()); + TableColumn colChinese = createColumn("中文翻译"); + colChinese.setCellValueFactory(param -> param.getValue().getChineseProperty()); + colChinese.setEditable(true); + TableColumn colIcon = new TableColumn<>(""); + colIcon.setSortable(false); + colIcon.setCellFactory(EditButtonTableCell.forTableColumn(item -> { + // 展示编辑弹窗 + try { + showModal(getEditWordPane(item), false); + } catch (IOException e) { + consoleLog.error("加载布局失败", e); + } + }, item -> { + // 翻译当前文本 + new TranslateTask(Collections.singletonList(item)).execute(); + })); + + wordTable.getColumns().add(colFile); + wordTable.getColumns().add(colOriginal); + wordTable.getColumns().add(colChinese); + wordTable.getColumns().add(colIcon); + } + + // 添加表数据 + wordTable.getItems().clear(); + wordBox.getChildren().addFirst(wordTable); + wordTable.getItems().addAll(words); + } + + /** + * 表字段创建 + * + * @param colName 列名 + * @return 列定义 + */ + private TableColumn createColumn(String colName) { + TableColumn tableColumn = new TableColumn<>(colName); + tableColumn.setCellFactory(TextFieldTableCell.forTableColumn()); + tableColumn.setPrefWidth(150); + tableColumn.setSortable(false); + tableColumn.setEditable("中文翻译".equals(colName)); + return tableColumn; + } + + private MenuItem createViewStyleItem(Theme theme) { + var item = new RadioMenuItem(theme.getName()); + item.setSelected(theme.getName().equals(ConfigManager.themeName())); + item.setToggleGroup(viewStyleGroup); + item.setUserData(theme); + item.selectedProperty().subscribe(selected -> { + if (!selected) return; + ConfigManager.theme(theme); + }); + return item; + } + + /** + * 是否PBO文件 + */ + private boolean isPboFile(File file) { + if (file == null) return false; + return Pattern.compile(".*(.pbo)$").matcher(file.getName()).matches(); + } + + /** + * 展示遮罩弹窗 + *

+ * 当{@code persistent}为{@code true}时,需要调用{@link #hideModal}才能关闭 + * + * @param node 展示内容 + * @param persistent 是否持久性内容 + */ + private void showModal(Node node, boolean persistent) { + modalPane.setAlignment(Pos.CENTER); + modalPane.usePredefinedTransitionFactories(null); + modalPane.show(node); + modalPane.setPersistent(persistent); + } + + /** + * 关闭/隐藏遮罩弹窗 + */ + public void hideModal() { + modalPane.hide(false); + modalPane.setPersistent(false); + } + + /** + * 编辑 + */ + private Node getEditWordPane(WordItem data) throws IOException { + FXMLLoader load = FxmlUtil.load("component/edit-view"); + Pane pane = load.load(); + WordEditController ctrl = load.getController(); + ctrl.bindData(data); + return pane; + } +} diff --git a/src/main/java/cn/octopusyan/dmt/controller/ProxyController.java b/src/main/java/cn/octopusyan/dmt/controller/ProxyController.java new file mode 100644 index 0000000..b0e1cec --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/controller/ProxyController.java @@ -0,0 +1,70 @@ +package cn.octopusyan.dmt.controller; + +import cn.octopusyan.dmt.common.base.BaseController; +import cn.octopusyan.dmt.common.enums.ProxySetup; +import cn.octopusyan.dmt.common.manager.ConfigManager; +import cn.octopusyan.dmt.viewModel.ProxyViewModel; +import javafx.beans.binding.Bindings; +import javafx.scene.control.RadioButton; +import javafx.scene.control.TextField; +import javafx.scene.control.ToggleGroup; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; +import javafx.scene.layout.VBox; + +/** + * 设置 + * + * @author octopus_yan + */ +public class ProxyController extends BaseController { + public VBox root; + + public RadioButton noneProxy; + public RadioButton systemProxy; + public RadioButton manualProxy; + public ToggleGroup proxyGroup = new ToggleGroup(); + + public GridPane manualProxyView; + public TextField proxyHost; + public TextField proxyPort; + + @Override + public Pane getRootPanel() { + return root; + } + + @Override + public void initData() { + noneProxy.setUserData(ProxySetup.NO_PROXY); + systemProxy.setUserData(ProxySetup.SYSTEM); + manualProxy.setUserData(ProxySetup.MANUAL); + + noneProxy.setToggleGroup(proxyGroup); + systemProxy.setToggleGroup(proxyGroup); + manualProxy.setToggleGroup(proxyGroup); + + manualProxyView.disableProperty().bind( + Bindings.createBooleanBinding(() -> !manualProxy.selectedProperty().get(), manualProxy.selectedProperty()) + ); + } + + @Override + public void initViewAction() { + proxyGroup.selectedToggleProperty().addListener((_, _, value) -> { + viewModel.proxySetupProperty().set((ProxySetup) value.getUserData()); + }); + proxyGroup.selectToggle(switch (ConfigManager.proxySetup()) { + case ProxySetup.SYSTEM -> systemProxy; + case ProxySetup.MANUAL -> manualProxy; + default -> noneProxy; + }); + + proxyHost.textProperty().bindBidirectional(viewModel.proxyHostProperty()); + proxyPort.textProperty().bindBidirectional(viewModel.proxyPortProperty()); + } + + public void proxyTest() { + viewModel.proxyTest(); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/controller/TranslateController.java b/src/main/java/cn/octopusyan/dmt/controller/TranslateController.java new file mode 100644 index 0000000..a879ab1 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/controller/TranslateController.java @@ -0,0 +1,93 @@ +package cn.octopusyan.dmt.controller; + +import cn.octopusyan.dmt.common.base.BaseController; +import cn.octopusyan.dmt.common.manager.ConfigManager; +import cn.octopusyan.dmt.translate.TranslateApi; +import cn.octopusyan.dmt.view.alert.AlertUtil; +import cn.octopusyan.dmt.viewModel.TranslateViewModel; +import javafx.collections.ObservableList; +import javafx.scene.control.ComboBox; +import javafx.scene.control.TextField; +import javafx.scene.layout.Pane; +import javafx.scene.layout.VBox; +import javafx.util.StringConverter; +import org.apache.commons.lang3.StringUtils; + +/** + * 翻译 + * + * @author octopus_yan + */ +public class TranslateController extends BaseController { + public VBox root; + public ComboBox translateSourceCombo; + public TextField qps; + public VBox appidBox; + public TextField appid; + public VBox apikeyBox; + public TextField apikey; + + @Override + public Pane getRootPanel() { + return root; + } + + @Override + public void initData() { + + // 翻译源 + for (TranslateApi value : TranslateApi.values()) { + ObservableList items = translateSourceCombo.getItems(); + items.addAll(value); + } + + translateSourceCombo.setConverter(new StringConverter<>() { + @Override + public String toString(TranslateApi object) { + if (object == null) return null; + + return object.getLabel(); + } + + @Override + public TranslateApi fromString(String string) { + return TranslateApi.getByLabel(string); + } + }); + + // 当前翻译源 + translateSourceCombo.getSelectionModel().select(ConfigManager.translateApi()); + viewModel.getSource().bind(translateSourceCombo.getSelectionModel().selectedItemProperty()); + + qps.textProperty().bindBidirectional(viewModel.getQps()); + appid.textProperty().bindBidirectional(viewModel.getAppId()); + apikey.textProperty().bindBidirectional(viewModel.getApiKey()); + + appidBox.visibleProperty().bind(viewModel.getNeedApiKey()); + apikeyBox.visibleProperty().bind(viewModel.getNeedApiKey()); + } + + @Override + public void initViewAction() { + } + + public void save() { + TranslateApi source = translateSourceCombo.getValue(); + String apikey = this.apikey.getText(); + String appid = this.appid.getText(); + int qps = Integer.parseInt(this.qps.getText()); + + ConfigManager.translateApi(source); + ConfigManager.translateQps(source, qps); + if (source.needApiKey()) { + if (StringUtils.isBlank(apikey) || StringUtils.isBlank(appid)) { + AlertUtil.error("认证信息不能为空"); + } + + ConfigManager.translateApikey(source, apikey); + ConfigManager.translateAppid(source, appid); + } + + onDestroy(); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/controller/component/WordEditController.java b/src/main/java/cn/octopusyan/dmt/controller/component/WordEditController.java new file mode 100644 index 0000000..ddcbe2c --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/controller/component/WordEditController.java @@ -0,0 +1,63 @@ +package cn.octopusyan.dmt.controller.component; + +import cn.octopusyan.dmt.common.base.BaseController; +import cn.octopusyan.dmt.common.manager.ConfigManager; +import cn.octopusyan.dmt.common.manager.thread.ThreadPoolManager; +import cn.octopusyan.dmt.model.WordItem; +import cn.octopusyan.dmt.translate.factory.TranslateFactoryImpl; +import cn.octopusyan.dmt.view.alert.AlertUtil; +import cn.octopusyan.dmt.viewModel.WordEditViewModel; +import javafx.application.Platform; +import javafx.scene.control.Button; +import javafx.scene.control.ProgressIndicator; +import javafx.scene.control.TextArea; +import javafx.scene.layout.Pane; +import javafx.scene.layout.VBox; + +/** + * 文本编辑 + * + * @author octopus_yan + */ +public class WordEditController extends BaseController { + + public VBox root; + public TextArea original; + public Button translate; + public TextArea chinese; + public ProgressIndicator progress; + + @Override + public Pane getRootPanel() { + return root; + } + + @Override + public void initData() { + + } + + @Override + public void initViewAction() { + + } + + public void bindData(WordItem data) { + viewModel.setData(data); + original.textProperty().bind(viewModel.getOriginalProperty()); + chinese.textProperty().bindBidirectional(viewModel.getChineseProperty()); + } + + public void startTranslate() { + progress.setVisible(true); + ThreadPoolManager.getInstance().execute(() -> { + try { + String result = TranslateFactoryImpl.getInstance().translate(ConfigManager.translateApi(), original.getText()); + Platform.runLater(() -> chinese.setText(result)); + } catch (Exception e) { + Platform.runLater(() -> AlertUtil.exception(e).show()); + } + Platform.runLater(() -> progress.setVisible(false)); + }); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/model/ConfigModel.java b/src/main/java/cn/octopusyan/dmt/model/ConfigModel.java new file mode 100644 index 0000000..02dc387 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/model/ConfigModel.java @@ -0,0 +1,33 @@ +package cn.octopusyan.dmt.model; + +import cn.octopusyan.dmt.common.manager.ConfigManager; +import lombok.Data; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * GUI配置信息 + * + * @author octopus_yan + */ +@Data +public class ConfigModel { + private static final Logger log = LoggerFactory.getLogger(ConfigModel.class); + + /** + * 主题 + */ + private String theme = ConfigManager.DEFAULT_THEME; + + /** + * 代理设置 + */ + private ProxyInfo proxy = new ProxyInfo(); + + /** + * 代理设置 + */ + private Translate translate = new Translate(); + + +} diff --git a/src/main/java/cn/octopusyan/dmt/model/ProxyInfo.java b/src/main/java/cn/octopusyan/dmt/model/ProxyInfo.java new file mode 100644 index 0000000..a65a579 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/model/ProxyInfo.java @@ -0,0 +1,39 @@ +package cn.octopusyan.dmt.model; + +import cn.octopusyan.dmt.common.enums.ProxySetup; +import lombok.Data; + +/** + * 代理信息 + * + * @author octopus_yan + */ +@Data +public class ProxyInfo { + /** + * 主机地址 + */ + private String host = ""; + /** + * 端口 + */ + private String port = ""; + /** + * 登录名 + */ + private String username = ""; + /** + * 密码 + */ + private String password = ""; + /** + * 测试Url + */ + private String testUrl = "http://"; + /** + * 代理类型 + * + * @see ProxySetup + */ + private String setup = ProxySetup.NO_PROXY.getCode(); +} diff --git a/src/main/java/cn/octopusyan/dmt/model/Translate.java b/src/main/java/cn/octopusyan/dmt/model/Translate.java new file mode 100644 index 0000000..c750f72 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/model/Translate.java @@ -0,0 +1,52 @@ +package cn.octopusyan.dmt.model; + +import cn.octopusyan.dmt.translate.TranslateApi; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.HashMap; +import java.util.Map; + +/** + * 翻译配置 + * + * @author octopus_yan + */ +@Data +public class Translate { + /** + * 当前使用接口 + */ + private String use = TranslateApi.FREE_BAIDU.getName(); + /** + * 接口配置 + */ + private Map config = new HashMap<>() { + { + // 初始化 + for (TranslateApi api : TranslateApi.values()) { + put(api.getName(), new Config("", "", api.getDefaultQps())); + } + } + }; + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class Config { + /** + * api key + */ + private String appId; + /** + * api 密钥 + */ + private String secretKey; + /** + * 请求速率 + */ + private Integer qps; + + } +} diff --git a/src/main/java/cn/octopusyan/dmt/model/UpgradeConfig.java b/src/main/java/cn/octopusyan/dmt/model/UpgradeConfig.java new file mode 100644 index 0000000..e92b986 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/model/UpgradeConfig.java @@ -0,0 +1,29 @@ +package cn.octopusyan.dmt.model; + +import cn.octopusyan.dmt.common.util.PropertiesUtils; +import lombok.Data; + +/** + * 更新配置 + * + * @author octopus_yan + */ +@Data +public class UpgradeConfig { + + private final String owner = "octopusYan"; + + private final String repo = "dayz-mod-translator"; + + private String releaseFile = "DMT-windows-nojre.zip"; + + private String version = PropertiesUtils.getInstance().getProperty("app.version"); + + public String getReleaseApi() { + return STR."https://api.github.com/repos/\{getOwner()}/\{getRepo()}/releases/latest"; + } + + public String getDownloadUrl(String version) { + return STR."https://github.com/\{getOwner()}/\{getRepo()}/releases/download/\{version}/\{getReleaseFile()}"; + } +} diff --git a/src/main/java/cn/octopusyan/dmt/model/WordItem.java b/src/main/java/cn/octopusyan/dmt/model/WordItem.java new file mode 100644 index 0000000..a7d8193 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/model/WordItem.java @@ -0,0 +1,52 @@ +package cn.octopusyan.dmt.model; + +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import lombok.Data; + +import java.io.File; + +/** + * 翻译文本 + * + * @author octopus_yan + */ +@Data +public class WordItem { + /** + * 所在文件 + */ + private File file; + /** + * 行数 + */ + private Integer lines; + /** + * 开始下标 + */ + private Integer index; + /** + * 原文 + */ + private StringProperty originalProperty = new SimpleStringProperty(); + /** + * 中文 + */ + private StringProperty chineseProperty = new SimpleStringProperty(); + + public WordItem(File file, Integer lines, Integer index, String original, String chinese) { + this.file = file; + this.lines = lines; + this.index = index; + this.originalProperty.set(original); + this.chineseProperty.set(chinese); + } + + public String getChinese() { + return chineseProperty.get(); + } + + public String getOriginal() { + return originalProperty.get(); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/task/PackTask.java b/src/main/java/cn/octopusyan/dmt/task/PackTask.java new file mode 100644 index 0000000..cfd8f72 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/task/PackTask.java @@ -0,0 +1,80 @@ +package cn.octopusyan.dmt.task; + +import cn.octopusyan.dmt.model.WordItem; +import cn.octopusyan.dmt.task.base.BaseTask; +import cn.octopusyan.dmt.task.listener.DefaultTaskListener; +import cn.octopusyan.dmt.utils.PBOUtil; + +import java.io.File; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collector; +import java.util.stream.Collectors; + +/** + * 打包任务 + * + * @author octopus_yan + */ +public class PackTask extends BaseTask { + + private static final Function, List> sortFunc = items -> items.stream().sorted(Comparator.comparing(WordItem::getLines)).toList(); + private static final Collector> downstream = Collectors.collectingAndThen(Collectors.toList(), sortFunc); + + private final Map> wordFileMap; + private final String unpackPath; + + public PackTask(List words, String unpackPath) { + super("Pack"); + + if (words == null) + throw new RuntimeException("参数为null!"); + + this.unpackPath = unpackPath; + wordFileMap = words.stream().collect(Collectors.groupingBy(WordItem::getFile, downstream)); + } + + @Override + protected void task() throws Exception { + if (wordFileMap.isEmpty()) return; + + // 写入文件 + PBOUtil.writeWords(wordFileMap); + if (listener != null) listener.onWriteOver(); + // 打包 + File packFile = PBOUtil.pack(unpackPath); + if (listener != null) listener.onPackOver(packFile); + } + + /** + * 解包监听 + * + * @author octopus_yan + */ + public abstract static class PackListener extends DefaultTaskListener { + + public PackListener() { + super(true); + getProgress().setWidth(550); + } + + @Override + protected void onSucceed() { + + } + + /** + * 写入完成 + */ + public abstract void onWriteOver(); + + /** + * 打包完成 + * + * @param file 文件地址 + */ + public abstract void onPackOver(File file); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/task/ProxyCheckTask.java b/src/main/java/cn/octopusyan/dmt/task/ProxyCheckTask.java new file mode 100644 index 0000000..04c819c --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/task/ProxyCheckTask.java @@ -0,0 +1,28 @@ +package cn.octopusyan.dmt.task; + +import cn.octopusyan.dmt.common.manager.http.HttpUtil; +import cn.octopusyan.dmt.task.base.BaseTask; +import cn.octopusyan.dmt.task.listener.DefaultTaskListener; +import lombok.extern.slf4j.Slf4j; + +/** + * 代理检测任务 + * + * @author octopus_yan + */ +@Slf4j +public class ProxyCheckTask extends BaseTask { + private final String checkUrl; + + public ProxyCheckTask(String checkUrl) { + super(STR."ProxyCheck[\{checkUrl}]"); + this.checkUrl = checkUrl; + this.updateProgress(0d, 1d); + } + + @Override + protected void task() throws Exception { + String response = HttpUtil.getInstance().get(checkUrl, null, null); + log.debug(STR."Proxy check response result => \n\{response}"); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/task/TranslateTask.java b/src/main/java/cn/octopusyan/dmt/task/TranslateTask.java new file mode 100644 index 0000000..9c820aa --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/task/TranslateTask.java @@ -0,0 +1,91 @@ +package cn.octopusyan.dmt.task; + +import cn.octopusyan.dmt.common.manager.thread.ThreadPoolManager; +import cn.octopusyan.dmt.model.WordItem; +import cn.octopusyan.dmt.task.base.BaseTask; +import cn.octopusyan.dmt.task.listener.DefaultTaskListener; +import cn.octopusyan.dmt.translate.DelayWord; +import cn.octopusyan.dmt.translate.TranslateUtil; +import cn.octopusyan.dmt.view.ConsoleLog; +import javafx.application.Platform; +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.DelayQueue; +import java.util.concurrent.atomic.AtomicLong; + +/** + * 翻译工具 + * + * @author octopus_yan@foxmail.com + */ +public class TranslateTask extends BaseTask { + + public static final ConsoleLog consoleLog = ConsoleLog.getInstance(TranslateTask.class); + @Getter + private final ThreadPoolManager threadPoolManager = ThreadPoolManager.getInstance("translate-pool"); + private final DelayQueue delayQueue; + private final long total; + private final AtomicLong quantity = new AtomicLong(); + private final CountDownLatch countDownLatch; + + public TranslateTask(List data) { + this(TranslateUtil.getDelayQueue(data), data.size()); + } + + public TranslateTask(DelayQueue queue, int total) { + super("Translate"); + this.delayQueue = queue; + this.total = total; + this.quantity.set(total - delayQueue.size()); + countDownLatch = new CountDownLatch(queue.size()); + + updateProgress(quantity.get(), total); + } + + @Override + protected void task() throws Exception { + + while (!delayQueue.isEmpty() && !isCancelled()) { + // 取出文本 + DelayWord word = delayQueue.take(); + + // 多线程处理 + threadPoolManager.execute(() -> { + // 翻译 + try { + if (total == 1) { + consoleLog.info("正在翻译:{}", word.getWord().getOriginal()); + } + + String translate = TranslateUtil.translate(word.getApi(), word.getWord().getOriginal()); + // 回调监听器 + if (StringUtils.isEmpty(translate)) return; + + synchronized (quantity) { + long progress = quantity.addAndGet(1); + // 设置翻译结果 + Platform.runLater(() -> word.getWord().getChineseProperty().setValue(translate)); + // 更新进度 + updateProgress(progress, total); + // 输出信息 + if (total != 1) { + consoleLog.info("正在翻译({}/{})", progress, total); + } + } + + } catch (Exception e) { + if (!(e instanceof InterruptedException) || !isCancelled()) { + consoleLog.error("翻译失败", e); + } + delayQueue.add(word); + } + countDownLatch.countDown(); + }); + } + + countDownLatch.await(); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/task/UnpackTask.java b/src/main/java/cn/octopusyan/dmt/task/UnpackTask.java new file mode 100644 index 0000000..d85fd9d --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/task/UnpackTask.java @@ -0,0 +1,63 @@ +package cn.octopusyan.dmt.task; + +import cn.octopusyan.dmt.model.WordItem; +import cn.octopusyan.dmt.task.base.BaseTask; +import cn.octopusyan.dmt.task.listener.DefaultTaskListener; +import cn.octopusyan.dmt.utils.PBOUtil; + +import java.io.File; +import java.util.List; + +/** + * 解包PBO文件任务 + * + * @author octopus_yan + */ +public class UnpackTask extends BaseTask { + + private final File pboFile; + + public UnpackTask(File pboFile) { + super("Unpack " + pboFile.getName()); + this.pboFile = pboFile; + } + + @Override + protected void task() throws Exception { + // 解包 + String path = PBOUtil.unpack(pboFile); + if (listener != null) + listener.onUnpackOver(path); + + List wordItems = PBOUtil.findWord(path); + if (listener != null) + listener.onFindWordOver(wordItems); + } + + /** + * 解包监听 + * + * @author octopus_yan + */ + public abstract static class UnpackListener extends DefaultTaskListener { + + @Override + protected void onSucceed() { + + } + + /** + * 解包完成 + * + * @param path 输出路径 + */ + public abstract void onUnpackOver(String path); + + /** + * 查找可翻译文本 + * + * @param wordItems 可翻译文本列表 + */ + public abstract void onFindWordOver(List wordItems); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/task/UpgradeTask.java b/src/main/java/cn/octopusyan/dmt/task/UpgradeTask.java new file mode 100644 index 0000000..85affc2 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/task/UpgradeTask.java @@ -0,0 +1,55 @@ +package cn.octopusyan.dmt.task; + +import cn.octopusyan.dmt.common.manager.ConfigManager; +import cn.octopusyan.dmt.common.manager.http.HttpUtil; +import cn.octopusyan.dmt.common.util.JsonUtil; +import cn.octopusyan.dmt.model.UpgradeConfig; +import cn.octopusyan.dmt.task.base.BaseTask; +import cn.octopusyan.dmt.task.listener.DefaultTaskListener; +import com.fasterxml.jackson.databind.JsonNode; +import org.apache.commons.lang3.StringUtils; + +/** + * 检查更新任务 + * + * @author octopus_yan + */ +public class UpgradeTask extends BaseTask { + + private final UpgradeConfig upgradeConfig = ConfigManager.upgradeConfig(); + + protected UpgradeTask() { + super("Check Update"); + } + + @Override + protected void task() throws Exception { + String responseStr = HttpUtil.getInstance().get(upgradeConfig.getReleaseApi(), null, null); + JsonNode response = JsonUtil.parseJsonObject(responseStr); + + // TODO 校验返回内容 + String newVersion = response.get("tag_name").asText(); + + if (listener != null) + listener.onChecked(!StringUtils.equals(upgradeConfig.getVersion(), newVersion), newVersion); + } + + /** + * 检查更新监听默认实现 + * + * @author octopus_yan + */ + public abstract static class UpgradeListener extends DefaultTaskListener { + + public UpgradeListener() { + super(true); + } + + public abstract void onChecked(boolean hasUpgrade, String version); + + @Override + protected void onSucceed() { + // do nothing ... + } + } +} diff --git a/src/main/java/cn/octopusyan/dmt/task/base/BaseTask.java b/src/main/java/cn/octopusyan/dmt/task/base/BaseTask.java new file mode 100644 index 0000000..893917f --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/task/base/BaseTask.java @@ -0,0 +1,50 @@ +package cn.octopusyan.dmt.task.base; + +import cn.octopusyan.dmt.common.manager.thread.ThreadPoolManager; +import cn.octopusyan.dmt.task.listener.DefaultTaskListener; +import javafx.concurrent.Task; +import lombok.Getter; + +/** + * @author octopus_yan + */ +public abstract class BaseTask extends Task { + private final ThreadPoolManager Executor = ThreadPoolManager.getInstance("task-pool"); + protected T listener; + @Getter + private final String name; + + protected BaseTask(String name) { + this.name = name; + } + + public String getNameTag() { + return "Task " + name; + } + + @Override + protected Void call() throws Exception { + if (listener != null) listener.onStart(); + task(); + return null; + } + + protected abstract void task() throws Exception; + + public void onListen(T listener) { + this.listener = listener; + if (this.listener == null) + return; + if (listener instanceof DefaultTaskListener lis) + lis.setTask((BaseTask) this); + + setOnRunning(_ -> listener.onRunning()); + setOnCancelled(_ -> listener.onCancelled()); + setOnFailed(_ -> listener.onFailed(getException())); + setOnSucceeded(_ -> listener.onSucceeded()); + } + + public void execute() { + Executor.execute(this); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/task/base/Listener.java b/src/main/java/cn/octopusyan/dmt/task/base/Listener.java new file mode 100644 index 0000000..d2b2d2b --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/task/base/Listener.java @@ -0,0 +1,23 @@ +package cn.octopusyan.dmt.task.base; + +/** + * 任务监听 + * + * @author octopus_yan + */ +public interface Listener { + + default void onStart() { + } + + default void onRunning() { + } + + default void onCancelled() { + } + + default void onFailed(Throwable throwable) { + } + + void onSucceeded(); +} diff --git a/src/main/java/cn/octopusyan/dmt/task/listener/DefaultTaskListener.java b/src/main/java/cn/octopusyan/dmt/task/listener/DefaultTaskListener.java new file mode 100644 index 0000000..795c4fc --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/task/listener/DefaultTaskListener.java @@ -0,0 +1,78 @@ +package cn.octopusyan.dmt.task.listener; + +import cn.octopusyan.dmt.task.base.BaseTask; +import cn.octopusyan.dmt.task.base.Listener; +import cn.octopusyan.dmt.view.ConsoleLog; +import cn.octopusyan.dmt.view.alert.AlertUtil; +import cn.octopusyan.dmt.view.alert.builder.ProgressBuilder; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +/** + * 任务监听器默认实现 + * + * @author octopus_yan + */ +@Slf4j +public abstract class DefaultTaskListener implements Listener { + private ConsoleLog consoleLog; + @Getter + private BaseTask task; + /** + * 加载弹窗 + */ + @Getter + final ProgressBuilder progress = AlertUtil.progress(); + + /** + * 是否展示加载弹窗 + */ + private final boolean showProgress; + + public DefaultTaskListener() { + this(false); + } + + public DefaultTaskListener(boolean showProgress) { + this.showProgress = showProgress; + } + + public void setTask(BaseTask task) { + this.task = task; + consoleLog = ConsoleLog.getInstance(task.getClass().getSimpleName()); + progress.onCancel(task::cancel); + } + + @Override + public void onStart() { + consoleLog.info(STR."\{task.getNameTag()} start ..."); + } + + @Override + public void onRunning() { + // 展示加载弹窗 + if (showProgress) + progress.show(); + } + + @Override + public void onCancelled() { + progress.close(); + consoleLog.info(STR."\{task.getNameTag()} cancel ..."); + } + + @Override + public void onFailed(Throwable throwable) { + progress.close(); + consoleLog.error(STR."\{task.getNameTag()} fail ...", throwable); + } + + @Override + public void onSucceeded() { + progress.close(); + consoleLog.info(STR."\{task.getNameTag()} success ..."); + onSucceed(); + } + + protected abstract void onSucceed(); +} diff --git a/src/main/java/cn/octopusyan/dmt/translate/ApiKey.java b/src/main/java/cn/octopusyan/dmt/translate/ApiKey.java new file mode 100644 index 0000000..e7dc838 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/translate/ApiKey.java @@ -0,0 +1,13 @@ +package cn.octopusyan.dmt.translate; + +import lombok.Getter; + +/** + * API 密钥配置 + * + * @author octopus_yan@foxmail.com + */ +@Getter +public record ApiKey(String appid, String apiKey) { + +} diff --git a/src/main/java/cn/octopusyan/dmt/translate/DelayWord.java b/src/main/java/cn/octopusyan/dmt/translate/DelayWord.java new file mode 100644 index 0000000..a6f3abf --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/translate/DelayWord.java @@ -0,0 +1,39 @@ +package cn.octopusyan.dmt.translate; + +import cn.octopusyan.dmt.model.WordItem; +import lombok.Getter; +import lombok.Setter; + +import java.util.concurrent.Delayed; +import java.util.concurrent.TimeUnit; + +/** + * 延迟翻译对象 + * + * @author octopus_yan + */ +@Getter +public class DelayWord implements Delayed { + @Setter + private TranslateApi api; + private final WordItem word; + private long delayTime; + + public DelayWord(WordItem word) { + this.word = word; + } + + public void setDelayTime(long time, TimeUnit timeUnit) { + this.delayTime = System.currentTimeMillis() + (time > 0 ? TimeUnit.MILLISECONDS.convert(time, timeUnit) : 0); + } + + @Override + public long getDelay(TimeUnit unit) { + return unit.convert(delayTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); + } + + @Override + public int compareTo(Delayed o) { + return Long.compare(this.delayTime, ((DelayWord) o).delayTime); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/translate/TranslateApi.java b/src/main/java/cn/octopusyan/dmt/translate/TranslateApi.java new file mode 100644 index 0000000..f30309f --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/translate/TranslateApi.java @@ -0,0 +1,60 @@ +package cn.octopusyan.dmt.translate; + +import cn.octopusyan.dmt.model.Translate; +import lombok.Getter; + +/** + * 翻译引擎类型 + * + * @author octopus_yan@foxmail.com + */ +@Getter +public enum TranslateApi { + FREE_BAIDU("free_baidu", "百度", false), + FREE_GOOGLE("free_google", "谷歌", false), + BAIDU("baidu", "百度(需认证)", true), + ; + + @Getter + private final String name; + @Getter + private final String label; + private final boolean needApiKey; + private final Integer defaultQps; + + TranslateApi(String name, String label, boolean needApiKey) { + // 设置接口默认qps=10 + this(name, label, needApiKey, 10); + } + + TranslateApi(String name, String label, boolean needApiKey, int defaultQps) { + this.name = name; + this.label = label; + this.needApiKey = needApiKey; + this.defaultQps = defaultQps; + } + + public boolean needApiKey() { + return needApiKey; + } + + public Translate.Config translate() { + return new Translate.Config("", "", defaultQps); + } + + public static TranslateApi get(String name) { + for (TranslateApi value : values()) { + if (value.getName().equals(name)) + return value; + } + throw new RuntimeException("类型不存在"); + } + + public static TranslateApi getByLabel(String label) { + for (TranslateApi value : values()) { + if (value.getLabel().equals(label)) + return value; + } + throw new RuntimeException("类型不存在"); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/translate/TranslateUtil.java b/src/main/java/cn/octopusyan/dmt/translate/TranslateUtil.java new file mode 100644 index 0000000..4b8cfb2 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/translate/TranslateUtil.java @@ -0,0 +1,66 @@ +package cn.octopusyan.dmt.translate; + +import cn.octopusyan.dmt.common.manager.ConfigManager; +import cn.octopusyan.dmt.model.WordItem; +import cn.octopusyan.dmt.translate.factory.TranslateFactory; +import cn.octopusyan.dmt.translate.factory.TranslateFactoryImpl; + +import java.util.List; +import java.util.concurrent.DelayQueue; + +/** + * 翻译 + * + * @author octopus_yan + */ +public class TranslateUtil { + private static final TranslateFactory factory = TranslateFactoryImpl.getInstance(); + + /** + * 翻译(英->中) + *

TODO 切换语种 + * + * @param api 翻译源 + * @param sourceString 原始文本 + * @return 翻译结果 + * @throws Exception 翻译出错 + */ + public static String translate(TranslateApi api, String sourceString) throws Exception { + return factory.translate(api, sourceString); + } + + public static String translate(String sourceString) throws Exception { + return factory.translate(ConfigManager.translateApi(), sourceString); + } + + /** + * 获取延迟翻译对象 + * + * @param words 待翻译文本列表 + * @return 延迟对象 + */ + public static DelayQueue getDelayQueue(List words) { + return getDelayQueue(ConfigManager.translateApi(), words); + } + + /** + * 获取延迟翻译对象 + * + * @param source 翻译接口 + * @param words 待翻译文本列表 + * @return 延迟对象 + */ + public static DelayQueue getDelayQueue(TranslateApi source, List words) { + return factory.getDelayQueue(source, words); + } + + /** + * 重设延迟时间 + * + * @param index 序列号 + * @param delayWord 延迟对象 + */ + public static void resetDelayTime(int index, DelayWord delayWord) { + factory.resetDelayTime(ConfigManager.translateApi(), index, delayWord); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/translate/factory/TranslateFactory.java b/src/main/java/cn/octopusyan/dmt/translate/factory/TranslateFactory.java new file mode 100644 index 0000000..596a987 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/translate/factory/TranslateFactory.java @@ -0,0 +1,44 @@ +package cn.octopusyan.dmt.translate.factory; + + +import cn.octopusyan.dmt.model.WordItem; +import cn.octopusyan.dmt.translate.DelayWord; +import cn.octopusyan.dmt.translate.TranslateApi; + +import java.util.List; +import java.util.concurrent.DelayQueue; + +/** + * 翻译器接口 + * + * @author octopus_yan@foxmail.com + */ +public interface TranslateFactory { + /** + * 翻译处理 + * + * @param api 翻译源 + * @param sourceString 原始文本 + * @return 翻译结果 + * @throws Exception 翻译出错 + */ + String translate(TranslateApi api, String sourceString) throws Exception; + + /** + * 获取延迟翻译对象 + * + * @param api 翻译源 + * @param word 待翻译文本对象 + * @return 延迟翻译对象 + */ + DelayQueue getDelayQueue(TranslateApi api, List word); + + /** + * 重设延迟时间 + * + * @param api 翻译接口 + * @param index 序列号 + * @param delayWord 延迟对象 + */ + void resetDelayTime(TranslateApi api, int index, DelayWord delayWord); +} diff --git a/src/main/java/cn/octopusyan/dmt/translate/factory/TranslateFactoryImpl.java b/src/main/java/cn/octopusyan/dmt/translate/factory/TranslateFactoryImpl.java new file mode 100644 index 0000000..9951c64 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/translate/factory/TranslateFactoryImpl.java @@ -0,0 +1,95 @@ +package cn.octopusyan.dmt.translate.factory; + +import cn.octopusyan.dmt.model.WordItem; +import cn.octopusyan.dmt.translate.DelayWord; +import cn.octopusyan.dmt.translate.TranslateApi; +import cn.octopusyan.dmt.translate.processor.AbstractTranslateProcessor; +import cn.octopusyan.dmt.translate.processor.BaiduTranslateProcessor; +import cn.octopusyan.dmt.translate.processor.FreeBaiduTranslateProcessor; +import cn.octopusyan.dmt.translate.processor.FreeGoogleTranslateProcessor; +import lombok.extern.slf4j.Slf4j; + +import java.util.*; +import java.util.concurrent.DelayQueue; +import java.util.concurrent.TimeUnit; + +/** + * 翻译处理器 + * + * @author octopus_yan@foxmail.com + */ +@Slf4j +public class TranslateFactoryImpl implements TranslateFactory { + private static TranslateFactoryImpl impl; + private final Map processorMap = new HashMap<>(); + private final List processorList = new ArrayList<>(); + + private TranslateFactoryImpl() { + } + + public static synchronized TranslateFactoryImpl getInstance() { + if (impl == null) { + impl = new TranslateFactoryImpl(); + impl.initProcessor(); + } + return impl; + } + + private void initProcessor() { + processorList.addAll(Arrays.asList( + new FreeGoogleTranslateProcessor(), + new FreeBaiduTranslateProcessor(), + new BaiduTranslateProcessor() + )); + for (AbstractTranslateProcessor processor : processorList) { + processorMap.put(processor.getSource(), processor); + } + } + + private AbstractTranslateProcessor getProcessor(TranslateApi api) { + return processorMap.get(api.getName()); + } + + @Override + public DelayQueue getDelayQueue(TranslateApi api, List words) { + var queue = new DelayQueue(); + + // 设置翻译延迟 + AbstractTranslateProcessor processor = getProcessor(api); + for (int i = 0; i < words.size(); i++) { + // 翻译对象 + DelayWord delayWord = new DelayWord(words.get(i)); + + // 设置翻译源 + delayWord.setApi(api); + long time = 1000L / processor.qps(); + delayWord.setDelayTime(time * (i + 1), TimeUnit.MILLISECONDS); + + queue.add(delayWord); + } + return queue; + } + + @Override + public void resetDelayTime(TranslateApi api, int index, DelayWord delayWord) { + AbstractTranslateProcessor processor = getProcessor(api); + // 设置翻译源 + delayWord.setApi(api); + long time = 1000L / processor.qps(); + delayWord.setDelayTime(time * (index + 1), TimeUnit.MILLISECONDS); + } + + /** + * 翻译(英->中) + *

TODO 切换语种 + * + * @param api 翻译源 + * @param sourceString 原始文本 + * @return 翻译结果 + * @throws Exception 翻译出错 + */ + @Override + public String translate(TranslateApi api, String sourceString) throws Exception { + return getProcessor(api).translate(sourceString); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/translate/processor/AbstractTranslateProcessor.java b/src/main/java/cn/octopusyan/dmt/translate/processor/AbstractTranslateProcessor.java new file mode 100644 index 0000000..ce138c2 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/translate/processor/AbstractTranslateProcessor.java @@ -0,0 +1,81 @@ +package cn.octopusyan.dmt.translate.processor; + +import cn.octopusyan.dmt.common.manager.ConfigManager; +import cn.octopusyan.dmt.common.manager.http.HttpUtil; +import cn.octopusyan.dmt.translate.ApiKey; +import cn.octopusyan.dmt.translate.TranslateApi; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 翻译处理器抽象类 + * + * @author octopus_yan@foxmail.com + */ +public abstract class AbstractTranslateProcessor implements TranslateProcessor { + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + protected static final HttpUtil httpUtil = HttpUtil.getInstance(); + protected final TranslateApi translateApi; + + public AbstractTranslateProcessor(TranslateApi translateApi) { + this.translateApi = translateApi; + } + + public String getSource() { + return translateApi.getName(); + } + + public TranslateApi source() { + return translateApi; + } + + @Override + public boolean needApiKey() { + return source().needApiKey(); + } + + @Override + public boolean configuredKey() { + return ConfigManager.hasTranslateApiKey(source()); + } + + @Override + public int qps() { + return ConfigManager.translateQps(source()); + } + + /** + * 获取Api配置信息 + */ + protected ApiKey getApiKey() { + if (!configuredKey()) { + String message = String.format("未配置【%s】翻译源认证信息!", source().getLabel()); + logger.error(message); + throw new RuntimeException(message); + } + + String appid = ConfigManager.translateAppid(source()); + String apikey = ConfigManager.translateApikey(source()); + return new ApiKey(appid, apikey); + } + + @Override + public String translate(String original) throws Exception { + + if (needApiKey() && !configuredKey()) { + String message = String.format("未配置【%s】翻译源认证信息!", source().getLabel()); + logger.error(message); + throw new RuntimeException(message); + } + + return customTranslate(original); + } + + /** + * 翻译处理 + * + * @param source 原始文本 + * @return 翻译结果 + */ + public abstract String customTranslate(String source) throws Exception; +} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/processor/BaiduTranslateProcessor.java b/src/main/java/cn/octopusyan/dmt/translate/processor/BaiduTranslateProcessor.java similarity index 72% rename from src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/processor/BaiduTranslateProcessor.java rename to src/main/java/cn/octopusyan/dmt/translate/processor/BaiduTranslateProcessor.java index 2b1fd76..a3e1b18 100644 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/processor/BaiduTranslateProcessor.java +++ b/src/main/java/cn/octopusyan/dmt/translate/processor/BaiduTranslateProcessor.java @@ -1,13 +1,15 @@ -package cn.octopusyan.dayzmodtranslator.manager.translate.processor; +package cn.octopusyan.dmt.translate.processor; -import cn.octopusyan.dayzmodtranslator.manager.translate.ApiKey; -import cn.octopusyan.dayzmodtranslator.manager.translate.TranslateSource; -import com.alibaba.fastjson2.JSON; -import com.alibaba.fastjson2.JSONObject; +import cn.octopusyan.dmt.common.util.JsonUtil; +import cn.octopusyan.dmt.translate.ApiKey; +import cn.octopusyan.dmt.translate.TranslateApi; +import com.fasterxml.jackson.databind.JsonNode; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; +import java.util.HashMap; +import java.util.Map; import java.util.UUID; /** @@ -19,8 +21,8 @@ public class BaiduTranslateProcessor extends AbstractTranslateProcessor { private ApiKey apiKey; - public BaiduTranslateProcessor(TranslateSource translateSource) { - super(translateSource); + public BaiduTranslateProcessor() { + super(TranslateApi.BAIDU); } @Override @@ -37,10 +39,10 @@ public class BaiduTranslateProcessor extends AbstractTranslateProcessor { @Override public String customTranslate(String source) throws IOException, InterruptedException { apiKey = getApiKey(); - String appid = apiKey.getAppid(); + String appid = apiKey.appid(); String salt = UUID.randomUUID().toString().replace("-", ""); - JSONObject param = new JSONObject(); + Map param = new HashMap<>(); param.put("q", source); param.put("from", "auto"); param.put("to", "zh"); @@ -48,20 +50,20 @@ public class BaiduTranslateProcessor extends AbstractTranslateProcessor { param.put("salt", salt); param.put("sign", getSign(appid, source, salt)); - String resp = httpUtil.get(url(), null, param); - JSONObject jsonObject = JSON.parseObject(resp); + String resp = httpUtil.get(url(), null, JsonUtil.parseJsonObject(param)); + JsonNode json = JsonUtil.parseJsonObject(resp); - if (!jsonObject.containsKey("trans_result")) { - Object errorMsg = jsonObject.get("error_msg"); + if (!json.has("trans_result")) { + Object errorMsg = json.get("error_msg"); logger.error("翻译失败: {}", errorMsg); - throw new RuntimeException("翻译失败: " + errorMsg); + throw new RuntimeException(String.valueOf(errorMsg)); } - return jsonObject.getJSONArray("trans_result").getJSONObject(0).getString("dst"); + return json.get("trans_result").get(0).get("dst").asText(); } private String getSign(String appid, String q, String salt) { - return encrypt2ToMD5(appid + q + salt + apiKey.getApiKey()); + return encrypt2ToMD5(appid + q + salt + apiKey.apiKey()); } /** diff --git a/src/main/java/cn/octopusyan/dmt/translate/processor/FreeBaiduTranslateProcessor.java b/src/main/java/cn/octopusyan/dmt/translate/processor/FreeBaiduTranslateProcessor.java new file mode 100644 index 0000000..1e140fd --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/translate/processor/FreeBaiduTranslateProcessor.java @@ -0,0 +1,107 @@ +package cn.octopusyan.dmt.translate.processor; + +import cn.octopusyan.dmt.common.manager.http.CookieManager; +import cn.octopusyan.dmt.common.util.JsonUtil; +import cn.octopusyan.dmt.translate.TranslateApi; +import com.fasterxml.jackson.databind.JsonNode; + +import java.io.IOException; +import java.net.HttpCookie; +import java.net.URI; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 谷歌 免费翻译接口 + * + * @author octopus_yan@foxmail.com + */ +public class FreeBaiduTranslateProcessor extends AbstractTranslateProcessor { + private static final Map header = new HashMap<>(); + + static { + header.put("Origin", "https://fanyi.baidu.com"); + header.put("Referer", "https://fanyi.baidu.com"); + header.put("User-Agent", "Apifox/1.0.0 (https://apifox.com)"); + header.put("Accept","*/*"); + } + + public FreeBaiduTranslateProcessor() { + super(TranslateApi.FREE_BAIDU); + } + + @Override + public String url() { + return "https://fanyi.baidu.com/transapi"; + } + + @Override + public int qps() { + return source().getDefaultQps(); + } + + /** + * 翻译处理 + * + * @param source 待翻译单词 + * @return 翻译结果 + */ + @Override + public String customTranslate(String source) throws IOException, InterruptedException { + + Map param = new HashMap<>(); + param.put("query", source); + param.put("from", "auto"); + param.put("to", "zh"); + param.put("source", "txt"); + + String resp = httpUtil.post(url(), JsonUtil.parseJsonObject(header), JsonUtil.parseJsonObject(param)); + JsonNode json = JsonUtil.parseJsonObject(resp); + + if (!json.has("data")) { + String errorMsg = json.get("errmsg").asText(); + if("访问出现异常,请刷新后重试!".equals(errorMsg) && !header.containsKey("Cookie")) { + checkCookie(); + return customTranslate(source); + } + throw new RuntimeException(errorMsg); + } + + return json.get("data").get(0).get("dst").asText(); + } + + private void checkCookie() throws IOException, InterruptedException { + // 短时大量请求会被ban,需要添加验证cookie + + if (header.containsKey("Cookie")) return; + + List cookieList = CookieManager.getStore().get(URI.create("https://baidu.com")); + boolean noneMatch = cookieList.stream() + .filter(cookie -> "ab_sr".equals(cookie.getName()) || "BAIDUID".equals(cookie.getName())) + .count() < 2; + + if (noneMatch) { + String url = "https://miao.baidu.com/abdr?_o=https%3A%2F%2Ffanyi.baidu.com"; + Map param = new HashMap<>(); + param.put("data", miao_data); + param.put("key_id", "6e75c85adea0454a"); + param.put("enc", 2); + httpUtil.post(url, JsonUtil.parseJsonObject(header), JsonUtil.parseJsonObject(param)); + } + + cookieList = CookieManager.getStore().get(URI.create("https://baidu.com")); + List cookies = cookieList.stream() + .filter(cookie -> "ab_sr".equals(cookie.getName()) || "BAIDUID".equals(cookie.getName())) + .toList(); + + String collect = cookies.stream() + .map(cookie -> cookie.getName() + "=" + cookie.getValue()) + .collect(Collectors.joining(";")); + + header.put("Cookie", collect); + } + + private static final String miao_data = "+wPJcl395nhVS+Fg/zTBIkBognAAK5IQi6wkGt3z1jk1jMuJOn+IkhaL1M7GHYxq/0V6+zKXaEVRs77WDfP/fDS0suNzgl3NdbhGSoHJEJk4fVMeU0pZxrgFq7Bzch6Aehw7MD6WlUDfyHWMarBN9OxH1UiW6Dn38uUkBjpsTDZYeNWOlmwy8YKq3FlRZiWzGYaP7K3DfBwWbT059D0KT2/mGUrHVgPVAkU572qNLzTxFyFneYTmPDQC0j+fl6+kxhA460WIG5aL19v4Gx+T7YJwIGe07QdhlQuy8Q6bpAIb8lj1SGjX9kS8P8GtI7TQv7gOlZ8ShUgV7941JXbIsJZgoWHFNq5Xge6XcVOUJsSQzAKsAgIlhgnlfC9IBAGK85KzeDC7JoBi4t0BXKgKUjYM9Veh7cA3yfudWKjSpyN6mv97apGR4Vl+8wbugPSCQRQlxPDunGUTGionf4hKxNZJYz62dwm0E/pP21PGPwnihDi7mQNxh40aE7IG0kORudLChvrcj85n4U/Rxkoq3TXTnSK1YAc4Pi/dIuR5HSUZyUBEqlvldU3jXqgUlfqeqjkn5Ug9gS6IqYEHE6FZdAGw/3y247pojWs2L56RSrUc6LoyQ7P9QNPOBr/v9HngHLRnFovrrZ57KmMl2hCiX5r1Q473CyjBhTjix3gQIFCwmM6rmEPIIU+cr0lvQrdhjxsiETk2sd17dR9gR2EjbNjeTby9QyHJTima5T6lk0K0orADrF2lNA/Xo2Iv/cMFXkc1ss7a19UQTdMLmiKgWdllWxH8Yp8B5o4KrLh+pMCGy6NeFn6FuWeAQgY8EB1r9H3PuenKaQ02VckkUPN1h1szjDI7otIFHYnQFJrp4vy4aM8wwcQS/+R2Aw0FwA5e2IWcZSwoTIc1i9YIeKgUpiConxhqZeKIhUEz33qExW0IS9mMs558JbAYsUG8KcMFtyqVo2sgtXteMAXMB9yX5/huZMR9HOO0v8x4KCZ+hwZczoVe3AmmUZLq1+rY9ngCp5D/3CcElcH3SU9HmlVXZ2VvLpa9wGIRP1UAHFuTxwVLvxJP07fbR31rLkoC22DbemRshBnv4EbIP/mkO8l/P1Y6RGEkS3b7b2MoBIWh4atrqOmUCG6w1KwESSi4Y5VKpdEkU/gL4ea7kr/GRJVWomSKSDqUEuloUI4hfLpmJs4h1JZTotOBcVjarOIW5d3j2Gm6R8X6vk24sUukOR1QOzP1gkoUaOYR+6Jcl+20IQZtIFMwFeMYtKrB5HquwYgHmUvO5hdxuFRwXosegVJmo+9MxkYjHTJbAgqZfKMc8kRjr64YBhwE30P+KLw+TafbgrA3trZQCyN3u5O5/2rk3GJmbhcDhZlYrYepj4Rymw8FB6LF0PkZZzRtWtQWv2gnMZuLmo7i5flL/MbiUMXKnsy3+Z6HHKNOqUzGUOZx84xizLkxwVMzGHrtSOub4wIhSWr7/z9GNa9qJuNJYsPXIE8wn245mHaheCm+MCxjIJMKdb72PBbQFF517kV+BxsNrxbFGe6ffJ/03KhXg0jJ1lAQc07obvOkdGVRr8DHTiS3IBfN7ofZMjVhXXpH2kUtepLfWvQf053yH2VQIEq62uxZP+RfpmdiBePEXQRBk5EA+178YbyavPE6yeu8zlub6GGlvuvrtnQmPUyvmO1hebiQK8B/V5TXxB+7IhPQ8okEll6bldVCoIxkbyAIBTK7rrDhD53HJ9capFgh/Q0XHMchYSYielT+Et8UIqUmVO94K5yl/nQhO1Vc2FsHkp2JWDDMQTuZyfmv+FS5OTeu39UznwXD36kyr2HvBEVoCMBqJrhI9WnEng53aEtcWQk4ewS+HllIoBgeJgexfs3MQK0mMP+6qV/idvB3S8Kzt/+SZsA0cHGvPvQzdePCRGNgCFOHPcpHPW/Yz4bwo4dzM64CYnL17Z4/fwcodMBG+KqG6ZyXe7EBby5RUE5OnhAGdR8T6WlIjNlU5TAIPbZ32i5nugWAcYJWJKsuITjAl4sRYY6Tpj19yIdHX2CDnU/O4arL8ijniydgcIEyYJbSCFmeJwyIv+ZSrB3RW0fYuAs4Q3AbeSK5TA9EICpB2w22kgditKO+uvrxw2LzGGND5C684YZq+XGmocAfpcte6+1PFs4NwuN41lOxDry8dwXr2mUIugcpnzsoF5Wgwyen0ISb2qaXODTvd/T5HEJcmpZdUJ1c+g+nEPi2OyX+MBXR"; +} diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/processor/FreeGoogleTranslateProcessor.java b/src/main/java/cn/octopusyan/dmt/translate/processor/FreeGoogleTranslateProcessor.java similarity index 53% rename from src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/processor/FreeGoogleTranslateProcessor.java rename to src/main/java/cn/octopusyan/dmt/translate/processor/FreeGoogleTranslateProcessor.java index 66c9bf4..6604af9 100644 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/processor/FreeGoogleTranslateProcessor.java +++ b/src/main/java/cn/octopusyan/dmt/translate/processor/FreeGoogleTranslateProcessor.java @@ -1,10 +1,13 @@ -package cn.octopusyan.dayzmodtranslator.manager.translate.processor; +package cn.octopusyan.dmt.translate.processor; -import cn.octopusyan.dayzmodtranslator.manager.translate.TranslateSource; -import com.alibaba.fastjson2.JSONArray; -import com.alibaba.fastjson2.JSONObject; + +import cn.octopusyan.dmt.common.util.JsonUtil; +import cn.octopusyan.dmt.translate.TranslateApi; +import com.fasterxml.jackson.databind.JsonNode; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; /** * 谷歌 免费翻译接口 @@ -13,8 +16,8 @@ import java.io.IOException; */ public class FreeGoogleTranslateProcessor extends AbstractTranslateProcessor { - public FreeGoogleTranslateProcessor(TranslateSource translateSource) { - super(translateSource); + public FreeGoogleTranslateProcessor() { + super(TranslateApi.FREE_GOOGLE); } @Override @@ -22,6 +25,11 @@ public class FreeGoogleTranslateProcessor extends AbstractTranslateProcessor { return "https://translate.googleapis.com/translate_a/single"; } + @Override + public int qps() { + return source().getDefaultQps(); + } + /** * 翻译处理 * @@ -31,21 +39,22 @@ public class FreeGoogleTranslateProcessor extends AbstractTranslateProcessor { @Override public String customTranslate(String source) throws IOException, InterruptedException { - JSONObject form = new JSONObject(); + Map form = new HashMap<>(); form.put("client", "gtx"); form.put("dt", "t"); form.put("sl", "auto"); form.put("tl", "zh-CN"); form.put("q", source); - JSONObject header = new JSONObject(); + Map header = new HashMap<>(); StringBuilder retStr = new StringBuilder(); // TODO 短时大量请求会被ban,需要浏览器验证添加cookie - String resp = httpUtil.get(url(), header, form); - JSONArray jsonObject = JSONArray.parseArray(resp); - for (Object o : jsonObject.getJSONArray(0)) { - JSONArray a = (JSONArray) o; - retStr.append(a.getString(0)); + + String resp = httpUtil.get(url(), JsonUtil.parseJsonObject(header), JsonUtil.parseJsonObject(form)); + JsonNode json = JsonUtil.parseJsonObject(resp); + + for (JsonNode o : json.get(0)) { + retStr.append(o.get(0).asText()); } return retStr.toString(); diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/processor/TranslateProcessor.java b/src/main/java/cn/octopusyan/dmt/translate/processor/TranslateProcessor.java similarity index 76% rename from src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/processor/TranslateProcessor.java rename to src/main/java/cn/octopusyan/dmt/translate/processor/TranslateProcessor.java index 74b87d8..8a01cf1 100644 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/manager/translate/processor/TranslateProcessor.java +++ b/src/main/java/cn/octopusyan/dmt/translate/processor/TranslateProcessor.java @@ -1,4 +1,4 @@ -package cn.octopusyan.dayzmodtranslator.manager.translate.processor; +package cn.octopusyan.dmt.translate.processor; /** * 翻译处理器 @@ -6,6 +6,7 @@ package cn.octopusyan.dayzmodtranslator.manager.translate.processor; * @author octopus_yan@foxmail.com */ public interface TranslateProcessor { + /** * 翻译源 api接口地址 */ @@ -29,9 +30,9 @@ public interface TranslateProcessor { /** * 翻译 * - * @param source 原始文本 + * @param original 原始文本 * @return 翻译结果 * @throws Exception 翻译出错 */ - String translate(String source) throws Exception; + String translate(String original) throws Exception; } diff --git a/src/main/java/cn/octopusyan/dayzmodtranslator/util/FileUtil.java b/src/main/java/cn/octopusyan/dmt/utils/FileUtil.java similarity index 74% rename from src/main/java/cn/octopusyan/dayzmodtranslator/util/FileUtil.java rename to src/main/java/cn/octopusyan/dmt/utils/FileUtil.java index f507546..68508ec 100644 --- a/src/main/java/cn/octopusyan/dayzmodtranslator/util/FileUtil.java +++ b/src/main/java/cn/octopusyan/dmt/utils/FileUtil.java @@ -1,4 +1,4 @@ -package cn.octopusyan.dayzmodtranslator.util; +package cn.octopusyan.dmt.utils; import org.apache.commons.io.FileUtils; import org.apache.commons.io.filefilter.CanReadFileFilter; @@ -6,11 +6,9 @@ import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; import java.nio.file.Files; +import java.nio.file.Path; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; @@ -96,8 +94,24 @@ public class FileUtil { return fileName.substring(0, fileName.lastIndexOf(".")); } + public static String getMimeType(Path path) { + try { + return Files.probeContentType(path); + } catch (IOException e) { + return null; + } + } + + public static Collection listFile(File file) { + return FileUtils.listFiles(file, CanReadFileFilter.CAN_READ, null); + } + public static List listFileNames(String path) { - Collection files = FileUtils.listFiles(new File(path), CanReadFileFilter.CAN_READ, null); + return listFileNames(new File(path)); + } + + public static List listFileNames(File file) { + Collection files = listFile(file); return files.stream().map(File::getName).collect(Collectors.toList()); } @@ -132,4 +146,36 @@ public class FileUtil { } return path; } + + /** + * 判断文件的编码格式 + * + * @return 文件编码格式 + */ + public static String getCharsets(File file) { + try (InputStream in = new FileInputStream(file)) { + int p = (in.read() << 8) + in.read(); + String code = "GBK"; + + switch (p) { + case 59524: + code = "UTF-8"; + break; + case 0xfffe: + code = "Unicode"; + break; + case 0xfeff: + code = "UTF-16BE"; + break; + case 48581: + code = "GBK"; + break; + default: + } + return code; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } diff --git a/src/main/java/cn/octopusyan/dmt/utils/PBOUtil.java b/src/main/java/cn/octopusyan/dmt/utils/PBOUtil.java new file mode 100644 index 0000000..a283305 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/utils/PBOUtil.java @@ -0,0 +1,407 @@ +package cn.octopusyan.dmt.utils; + +import cn.octopusyan.dmt.common.config.Constants; +import cn.octopusyan.dmt.common.util.ProcessesUtil; +import cn.octopusyan.dmt.model.WordItem; +import cn.octopusyan.dmt.view.ConsoleLog; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.LineIterator; +import org.apache.commons.lang3.StringUtils; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * PBO 文件工具 + * + * @author octopus_yan + */ +public class PBOUtil { + public static final ConsoleLog consoleLog = ConsoleLog.getInstance(PBOUtil.class); + + private static final ProcessesUtil processesUtil = ProcessesUtil.init(Constants.BIN_DIR_PATH); + + private static final String UNPACK_COMMAND = STR."\{Constants.PBOC_FILE} unpack -o \{Constants.TMP_DIR_PATH} %s"; + private static final String PACK_COMMAND = STR."\{Constants.PBOC_FILE} pack -o %s %s"; + private static final String CFG_COMMAND = STR."\{Constants.CFG_CONVERT_FILE} %s -dst %s %s"; + + private static final String FILE_NAME_STRING_TABLE = "stringtable.csv"; + private static final String FILE_NAME_CONFIG_BIN = "config.bin"; + private static final String FILE_NAME_CONFIG_CPP = "config.cpp"; + private static final String[] FILE_NAME_LIST = new String[]{"csv", "bin", "cpp", "layout"}; + + private static final Pattern CPP_PATTERN = Pattern.compile(".*(displayName|descriptionShort) ?= ?\"(.*)\";.*"); + private static final Pattern LAYOUT_PATTERN = Pattern.compile(".*text \"(.*)\".*"); + + + public static void init() { + + String srcFilePath = Objects.requireNonNull(PBOUtil.class.getResource("/bin")).getPath(); + try { + File destDir = new File(Constants.BIN_DIR_PATH); + FileUtils.forceMkdir(destDir); + FileUtils.copyDirectory(new File(srcFilePath), destDir); + } catch (IOException e) { + consoleLog.error("Util 初始化失败", e); + } + } + + /** + * 解包pbo文件 + * + * @param path pbo文件地址 + * @return 解包输出路径 + */ + public static String unpack(String path) { + return unpack(new File(path)); + } + + /** + * 解包pbo文件 + * + * @param pboFile pbo文件 + * @return 解包输出路径 + */ + public static String unpack(File pboFile) { + if (!pboFile.exists()) + throw new RuntimeException("文件不存在!"); + + File directory = new File(Constants.TMP_DIR_PATH); + String outputPath = Constants.TMP_DIR_PATH + File.separator + FileUtil.mainName(pboFile); + try { + FileUtils.deleteQuietly(new File(outputPath)); + FileUtils.forceMkdir(directory); + } catch (IOException e) { + throw new RuntimeException("文件夹创建失败", e); + } + + String command = String.format(UNPACK_COMMAND, pboFile.getAbsolutePath()); + consoleLog.debug(STR."unpack command ==> [\{command}]"); + boolean exec = processesUtil.exec(command); + if (!exec) + throw new RuntimeException("解包失败!"); + + return outputPath; + } + + /** + * 打包pbo文件 + * + * @param unpackPath pbo解包文件路径 + * @return 打包文件 + */ + public static File pack(String unpackPath) { + String outputPath = STR."\{unpackPath}.pbo"; + + // 打包文件临时保存路径 + File packFile = new File(outputPath); + if (packFile.exists()) { + // 如果存在则删除 + FileUtils.deleteQuietly(packFile); + } + + String command = String.format(PACK_COMMAND, Constants.TMP_DIR_PATH, unpackPath); + consoleLog.debug(STR."pack command ==> [\{command}]"); + + boolean exec = processesUtil.exec(command); + if (!exec) throw new RuntimeException("打包失败!"); + + return packFile; + } + + /** + * 查找可翻译文本 + * + * @param path 根目录 + */ + public static List findWord(String path) { + return findWord(new File(path)); + } + + public static List findWord(File file) { + ArrayList wordItems = new ArrayList<>(); + if (!file.exists()) + return wordItems; + + List files = new ArrayList<>(FileUtils.listFiles(file, FILE_NAME_LIST, true)); + for (File item : files) { + wordItems.addAll(findWordByFile(item)); + } + + return wordItems; + } + + /** + * 写入文件 + * + * @param wordFileMap 文件对应文本map + */ + public static void writeWords(Map> wordFileMap) { + + for (Map.Entry> entry : wordFileMap.entrySet()) { + + Map wordMap = entry.getValue().stream() + .collect(Collectors.toMap(WordItem::getLines, Function.identity())); + + File file = entry.getKey(); + + // 需要转bin文件时,写入bak目录下cpp文件 + boolean hasBin = new File(outFilePath(file, ".bin")).exists(); + String writePath = file.getAbsolutePath().replace(Constants.BAK_DIR_PATH, Constants.TMP_DIR_PATH); + File writeFile = hasBin ? file : new File(writePath); + + AtomicInteger lineIndex = new AtomicInteger(0); + List lines = new ArrayList<>(); + + consoleLog.info("正在写入文件[{}]", writeFile.getAbsolutePath()); + + try (LineIterator it = FileUtils.lineIterator(file, StandardCharsets.UTF_8.name())) { + while (it.hasNext()) { + String line = it.next(); + WordItem word = wordMap.get(lineIndex.get()); + + // 当前行是否有需要替换的文本 + // TODO 是否替换空文本 + if (word != null && line.contains(word.getOriginal())) { + line = line.substring(0, word.getIndex()) + + line.substring(word.getIndex()).replace(word.getOriginal(), word.getChinese()); + } + + // 缓存行内容 + lines.add(line); + + lineIndex.addAndGet(1); + } + } catch (IOException e) { + consoleLog.error(STR."文件[\{file.getAbsoluteFile()}]读取出错", e); + } + + try { + // 写入文件 + String charsets = writeFile.getName().endsWith(".layout") ? FileUtil.getCharsets(writeFile) : StandardCharsets.UTF_8.name(); + FileUtils.writeLines(writeFile, charsets, lines); + } catch (IOException e) { + consoleLog.error(STR."文件(\{writeFile.getAbsoluteFile()})写入失败", e); + } + + // CPP转BIN (覆盖TMP下BIN文件) + if (hasBin) cpp2bin(writeFile); + } + } + + /** + * 查找文件内可翻译文本 + * + * @param file 文件 + * @return 可翻译文本信息列表 + */ + private static List findWordByFile(File file) { + if (!FILE_NAME_CONFIG_CPP.equals(file.getName()) + && !FILE_NAME_CONFIG_BIN.equals(file.getName()) + && !FILE_NAME_STRING_TABLE.equals(file.getName()) + && !file.getName().endsWith(".layout") + ) { + return Collections.emptyList(); + } + + // 创建备份(在bak文件夹下的同级目录 + file = createBak(file); + + // bin转cpp + if (FILE_NAME_CONFIG_BIN.equals(file.getName())) { + file = bin2cpp(file); + } + + String charset = file.getName().endsWith(".layout") ? FileUtil.getCharsets(file) : StandardCharsets.UTF_8.name(); + + try (LineIterator it = FileUtils.lineIterator(file, charset)) { + // CPP + if (FILE_NAME_CONFIG_CPP.equals(file.getName())) { + return findWordByCPP(file, it); + } + // CSV + if (FILE_NAME_STRING_TABLE.equals(file.getName())) { + return findWordByCSV(file, it); + } + // layout + if (file.getName().endsWith(".layout")) { + return findWordByLayout(file, it); + } + + // TODO 待添加更多文件格式 + return Collections.emptyList(); + + } catch (IOException e) { + consoleLog.error(STR."文件[\{file.getAbsoluteFile()}]读取出错", e); + } + + return Collections.emptyList(); + } + + /** + * 从csv文件中读取可翻译文本 + * + * @param file csv文件 + * @param it 行内容遍历器 + * @return 可翻译文本列表 + */ + private static List findWordByCSV(File file, LineIterator it) { + ArrayList wordItems = new ArrayList<>(); + AtomicInteger lines = new AtomicInteger(0); + int index = -1; + String line; + while (it.hasNext()) { + line = it.next(); + List split = Arrays.stream(line.split(",")).toList(); + + if (lines.get() == 0) { + index = split.indexOf("\"chinese\""); + } else if (index < split.size()) { + // 原文 + String original = split.get(index).replaceAll("\"", ""); + // 开始下标 + Integer startIndex = line.indexOf(original); + // 添加单词 + if (original.length() > 1) { + wordItems.add(new WordItem(file, lines.get(), startIndex, original, "")); + } + } + + lines.addAndGet(1); + } + return wordItems; + } + + /** + * 从layout文件中读取可翻译文本 + * + * @param file layout文件 + * @param it 行内容遍历器 + * @return 可翻译文本列表 + */ + private static List findWordByLayout(File file, LineIterator it) { + ArrayList wordItems = new ArrayList<>(); + AtomicInteger lines = new AtomicInteger(0); + String line; + Matcher matcher; + while (it.hasNext()) { + line = it.next(); + matcher = LAYOUT_PATTERN.matcher(line); + if (StringUtils.isNoneEmpty(line) && matcher.matches()) { + // 原文 + String original = matcher.group(1); + // 开始下标 + Integer startIndex = line.indexOf(original); + // 添加单词 + if (original.length() > 1) { + wordItems.add(new WordItem(file, lines.get(), startIndex, original, "")); + } + } + + lines.addAndGet(1); + } + return wordItems; + } + + /** + * 读取cpp文件内可翻译文本 + * + * @param file cpp文件 + * @param it 行内容遍历器 + * @return 可翻译文本列表 + */ + private static List findWordByCPP(File file, LineIterator it) { + ArrayList wordItems = new ArrayList<>(); + AtomicInteger lines = new AtomicInteger(0); + + while (it.hasNext()) { + String line = it.next(); + + Matcher matcher = CPP_PATTERN.matcher(line); + if (!line.contains("$") && matcher.matches()) { + + String name = matcher.group(1); + + // 原始文本 + int startIndex = line.indexOf(name) + name.length(); + String original = matcher.group(2); + + // 添加单词 + if (original.length() > 1) { + wordItems.add(new WordItem(file, lines.get(), startIndex, original, "")); + } + } + + lines.addAndGet(1); + } + return wordItems; + } + + /** + * 创建备份文件 + */ + private static File createBak(File file) { + try { + String absolutePath = file.getAbsolutePath().replace(Constants.TMP_DIR_PATH, Constants.BAK_DIR_PATH); + File destFile = new File(absolutePath); + FileUtils.copyFile(file, destFile); + return destFile; + } catch (IOException e) { + consoleLog.error(STR."创建备份文件失败[\{file.getAbsolutePath()}]", e); + } + return file; + } + + /** + * bin 转 cpp + * + * @param file bin文件 + * @return cpp文件 + */ + private static File bin2cpp(File file) { + boolean exec = processesUtil.exec(toTxtCommand(file)); + + if (!exec) throw new RuntimeException("bin2cpp 失败"); + + return new File(outFilePath(file, ".cpp")); + } + + /** + * cpp 转 bin + * + * @param file bin文件 + */ + private static void cpp2bin(File file) { + boolean exec = processesUtil.exec(toBinCommand(file)); + + if (!exec) throw new RuntimeException("cpp2bin 失败"); + } + + /** + * cpp to bin 命令 + */ + private static String toBinCommand(File cppFile) { + String outFilePath = outFilePath(cppFile, ".bin"); + outFilePath = outFilePath.replace(Constants.BAK_DIR_PATH, Constants.TMP_DIR_PATH); + return String.format(CFG_COMMAND, "-bin", outFilePath, cppFile.getAbsolutePath()); + } + + /** + * bin to cpp 命令 + */ + private static String toTxtCommand(File binFile) { + String outFilePath = outFilePath(binFile, ".cpp"); + return String.format(CFG_COMMAND, "-txt", outFilePath, binFile.getAbsolutePath()); + } + + private static String outFilePath(File file, String suffix) { + return file.getParentFile().getAbsolutePath() + File.separator + FileUtil.mainName(file) + suffix; + } +} diff --git a/src/main/java/cn/octopusyan/dmt/utils/Resources.java b/src/main/java/cn/octopusyan/dmt/utils/Resources.java new file mode 100644 index 0000000..e1e767d --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/utils/Resources.java @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: MIT */ + +package cn.octopusyan.dmt.utils; + +import cn.octopusyan.dmt.AppLauncher; + +import java.io.InputStream; +import java.net.URI; +import java.net.URL; +import java.util.Objects; +import java.util.prefs.Preferences; + +public final class Resources { + + public static final String MODULE_DIR = "/"; + + public static InputStream getResourceAsStream(String resource) { + String path = resolve(resource); + return Objects.requireNonNull( + AppLauncher.class.getResourceAsStream(resolve(path)), + "Resource not found: " + path + ); + } + + public static URI getResource(String resource) { + String path = resolve(resource); + URL url = Objects.requireNonNull(AppLauncher.class.getResource(resolve(path)), "Resource not found: " + path); + return URI.create(url.toExternalForm()); + } + + public static String resolve(String resource) { + Objects.requireNonNull(resource); + return resource.startsWith("/") ? resource : MODULE_DIR + resource; + } + + public static String getPropertyOrEnv(String propertyKey, String envKey) { + return System.getProperty(propertyKey, System.getenv(envKey)); + } + + public static Preferences getPreferences() { + return Preferences.userRoot().node("atlantafx"); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/view/ConsoleLog.java b/src/main/java/cn/octopusyan/dmt/view/ConsoleLog.java new file mode 100644 index 0000000..bb2a6cc --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/view/ConsoleLog.java @@ -0,0 +1,151 @@ +package cn.octopusyan.dmt.view; + +import javafx.application.Platform; +import javafx.scene.control.TextArea; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * 模拟控制台输出 + * + * @author octopus_yan + */ +public class ConsoleLog { + public static final String format = "yyyy/MM/dd hh:mm:ss"; + private static final Logger log = LoggerFactory.getLogger(ConsoleLog.class); + private static Logger markerLog; + private static TextArea logArea; + private final String tag; + @Setter + private static boolean showDebug = false; + + public static void init(TextArea logArea) { + ConsoleLog.logArea = logArea; + } + + private ConsoleLog(String tag) { + this.tag = tag; + } + + public static ConsoleLog getInstance(Class clazz) { + markerLog = LoggerFactory.getLogger(clazz); + return getInstance(clazz.getSimpleName()); + } + + public static ConsoleLog getInstance(String tag) { + return new ConsoleLog(tag); + } + + public static boolean isInit() { + return log != null; + } + + public void info(String message, Object... param) { + printLog(tag, Level.INFO, message, param); + } + + public void warning(String message, Object... param) { + printLog(tag, Level.WARN, message, param); + } + + public void debug(String message, Object... param) { + if (!showDebug) return; + printLog(tag, Level.DEBUG, message, param); + } + + public void error(String message, Object... param) { + printLog(tag, Level.ERROR, message, param); + } + + public void error(String message, Throwable throwable) { + markerLog.error(message, throwable); + message = STR."\{message} \{throwable.getMessage()}"; + printLog(tag, Level.ERROR, message); + } + + public void msg(String message, Object... params) { + if (StringUtils.isEmpty(message) || !isInit()) return; + message = format(message, params); + message = resetConsoleColor(message); + + print(message); + } + + final static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + public void printLog(String tag, Level level, String message, Object... params) { + if (!isInit()) return; + + // 时间 + String time = LocalDateTime.now().format(formatter); + // 级别 + String levelStr = level.code; + // 消息 + message = format(message, params); + + // 拼接后输出 + String input = STR."\{time} \{levelStr} [\{tag}] - \{message.replace(tag, "")}"; + + switch (level) { + case WARN -> markerLog.warn(message); + case DEBUG -> markerLog.debug(message); +// case ERROR -> markerLog.error(message); + default -> markerLog.info(message); + } + + print(input); + } + + private static void print(String message) { + var msg = message + (message.endsWith("\n") ? "" : "\n"); + Platform.runLater(() -> { + ConsoleLog.logArea.appendText(msg); + // 滚动到底部 + ConsoleLog.logArea.setScrollTop(Double.MAX_VALUE); + }); + } + +//==========================================={ 私有方法 }=================================================== + + private static String format(String msg, Object... params) { + int i = 0; + while (msg.contains("{}") && params != null) { + msg = msg.replaceFirst("\\{}", String.valueOf(params[i++]).replace("\\", "\\\\")); + } + return msg; + } + + /** + * 处理控制台输出颜色 + * + * @param msg 输出消息 + * @return 信息 + */ + private static String resetConsoleColor(String msg) { + if (!msg.contains("\033[")) return msg; + + return msg.replaceAll("\\033\\[(\\d;)?(\\d+)m", ""); + } + +//============================{ 枚举 }================================ + + @Getter + @RequiredArgsConstructor + public enum Level { + INFO("INFO", null), + DEBUG("DEBUG", null), + WARN("WARN", "-color-danger-emphasis"), + ERROR("ERROR", "-color-danger-fg"), + ; + + private final String code; + private final String color; + } +} diff --git a/src/main/java/cn/octopusyan/dmt/view/EditButtonTableCell.java b/src/main/java/cn/octopusyan/dmt/view/EditButtonTableCell.java new file mode 100644 index 0000000..fee39a9 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/view/EditButtonTableCell.java @@ -0,0 +1,74 @@ +package cn.octopusyan.dmt.view; + +import atlantafx.base.theme.Styles; +import cn.octopusyan.dmt.model.WordItem; +import cn.octopusyan.dmt.utils.Resources; +import javafx.scene.control.Button; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.HBox; +import javafx.util.Callback; +import org.kordamp.ikonli.feather.Feather; +import org.kordamp.ikonli.javafx.FontIcon; + +import java.util.function.Consumer; + +/** + * 按钮 + * + * @author octopus_yan + */ +public class EditButtonTableCell extends TableCell { + + public static Callback, TableCell> forTableColumn(Consumer edit, Consumer translate) { + return _ -> new EditButtonTableCell("", edit, translate); + } + + private final Button edit; + private final Button translate; + + private static final ImageView translateIcon = new ImageView(new Image(Resources.getResourceAsStream("images/icon/translate.png"))); + + static { + translateIcon.setFitHeight(20); + translateIcon.setFitWidth(20); + } + + public EditButtonTableCell(String text, Consumer edit, Consumer translate) { + // 编辑 + this.edit = new Button(text); + this.edit.getStyleClass().addAll(Styles.BUTTON_ICON, Styles.FLAT); + this.edit.setOnMouseClicked(_ -> { + WordItem data = getTableView().getItems().get(getIndex()); + edit.accept(data); + }); + this.edit.setGraphic(new FontIcon(Feather.EDIT)); + + // 翻译 + ImageView translateIcon = new ImageView(new Image(Resources.getResourceAsStream("images/icon/translate.png"))); + translateIcon.setFitHeight(20); + translateIcon.setFitWidth(20); + this.translate = new Button("", translateIcon); + this.translate.getStyleClass().addAll(Styles.BUTTON_ICON, Styles.FLAT); + this.translate.setOnMouseClicked(_ -> { + WordItem data = getTableView().getItems().get(getIndex()); + translate.accept(data); + }); + } + + @Override + protected void updateItem(WordItem item, boolean empty) { + super.updateItem(item, empty); + if (empty) { + setGraphic(null); + } else { + /* + * TODO 添加多个操作按钮 + * setGraphic(Hbox(btn1,btn2)); + */ + setGraphic(new HBox(edit, translate)); + } + } +} diff --git a/src/main/java/cn/octopusyan/dmt/view/PopupMenu.java b/src/main/java/cn/octopusyan/dmt/view/PopupMenu.java new file mode 100644 index 0000000..a72166f --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/view/PopupMenu.java @@ -0,0 +1,137 @@ +package cn.octopusyan.dmt.view; + +import atlantafx.base.controls.CaptionMenuItem; +import cn.octopusyan.dmt.common.config.Constants; +import cn.octopusyan.dmt.common.util.ViewUtil; +import javafx.application.Platform; +import javafx.beans.binding.StringBinding; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.scene.Scene; +import javafx.scene.control.ContextMenu; +import javafx.scene.control.Menu; +import javafx.scene.control.MenuItem; +import javafx.scene.control.SeparatorMenuItem; +import javafx.scene.layout.Region; +import javafx.stage.Stage; +import javafx.stage.StageStyle; + +/** + * 托盘图标 菜单 + * + * @author octopus_yan + */ +public class PopupMenu { + // 用来隐藏弹出窗口的任务栏图标 + private static final Stage utilityStage = new Stage(); + // 菜单栏 + private final ContextMenu root = new ContextMenu(); + + static { + utilityStage.initStyle(StageStyle.UTILITY); + utilityStage.setScene(new Scene(new Region())); + utilityStage.setOpacity(0); + } + + public PopupMenu() { + + root.focusedProperty().addListener((_, _, focused) -> { + if (!focused) + Platform.runLater(() -> { + root.hide(); + utilityStage.hide(); + }); + }); + } + + public PopupMenu addItem(String label, EventHandler handler) { + return addItem(new MenuItem(label), handler); + } + + public PopupMenu addItem(StringBinding bind, EventHandler handler) { + MenuItem menuItem = new MenuItem(); + menuItem.textProperty().bind(bind); + return addItem(menuItem, handler); + } + + public PopupMenu addItem(MenuItem node, EventHandler handler) { + node.setOnAction(handler); + return addItem(node); + } + + public PopupMenu addSeparator() { + return addItem(new SeparatorMenuItem()); + } + + public PopupMenu addCaptionItem() { + return addCaptionItem(null); + } + + public PopupMenu addCaptionItem(String title) { + return addItem(new CaptionMenuItem(title)); + } + + public PopupMenu addMenu(String label, MenuItem... items) { + return addMenu(new Menu(label), items); + } + + public PopupMenu addMenu(StringBinding label, MenuItem... items) { + Menu menu = new Menu(); + menu.textProperty().bind(label); + return addMenu(menu, items); + } + + public PopupMenu addMenu(Menu menu, MenuItem... items) { + menu.getItems().addAll(items); + return addItem(menu); + } + + public PopupMenu addTitleItem() { + return addTitleItem(Constants.APP_TITLE); + } + + public PopupMenu addTitleItem(String label) { + return addExitItem(label); + } + + public PopupMenu addExitItem() { + return addExitItem("Exit"); + } + + public PopupMenu addExitItem(String label) { + return addItem(label, _ -> Platform.exit()); + } + + private PopupMenu addItem(MenuItem node) { + root.getItems().add(node); + return this; + } + + public void show(java.awt.event.MouseEvent event) { + // 必须调用show才会隐藏任务栏图标 + utilityStage.show(); + + if (root.isShowing()) + root.hide(); + + root.show(utilityStage, + event.getX() / ViewUtil.scaleX, + event.getY() / ViewUtil.scaleY + ); + // 获取焦点 (失去焦点隐藏自身) + root.requestFocus(); + } + + public static MenuItem menuItem(String label, EventHandler handler) { + MenuItem menuItem = new MenuItem(label); + menuItem.setOnAction(handler); + return menuItem; + } + + public static MenuItem menuItem(StringBinding stringBinding, EventHandler handler) { + MenuItem menuItem = new MenuItem(); + menuItem.textProperty().bind(stringBinding); + menuItem.setOnAction(handler); + return menuItem; + } +} diff --git a/src/main/java/cn/octopusyan/dmt/view/alert/AlertUtil.java b/src/main/java/cn/octopusyan/dmt/view/alert/AlertUtil.java new file mode 100644 index 0000000..79597de --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/view/alert/AlertUtil.java @@ -0,0 +1,100 @@ +package cn.octopusyan.dmt.view.alert; + +import cn.octopusyan.dmt.view.alert.builder.*; +import javafx.scene.control.Alert; +import javafx.scene.control.ButtonType; +import javafx.stage.Stage; +import javafx.stage.Window; + +/** + * 弹窗工具 + * + * @author octopus_yan@foxmail.com + */ +public class AlertUtil { + private static Window mOwner; + + public static void initOwner(Stage stage) { + AlertUtil.mOwner = stage; + } + + public static DefaultBuilder builder() { + return new DefaultBuilder(mOwner, true); + } + + public static DefaultBuilder builder(boolean transparent) { + return new DefaultBuilder(mOwner, transparent); + } + + public static AlertBuilder info(String content) { + return info().content(content).header(null); + } + + public static AlertBuilder info() { + return alert(Alert.AlertType.INFORMATION); + } + + public static AlertBuilder error(String message) { + return alert(Alert.AlertType.ERROR).header(null).content(message); + } + + public static AlertBuilder warning() { + return alert(Alert.AlertType.WARNING); + } + + public static AlertBuilder exception(Exception ex) { + return alert(Alert.AlertType.ERROR).exception(ex); + } + + /** + * 确认对话框 + */ + public static AlertBuilder confirm() { + return alert(Alert.AlertType.CONFIRMATION); + } + + /** + * 自定义确认对话框

+ * + * @param buttons "Cancel" OR "取消" 为取消按钮 + */ + public static AlertBuilder confirm(String... buttons) { + return confirm().buttons(buttons); + } + + public static AlertBuilder confirm(ButtonType... buttons) { + return confirm().buttons(buttons); + } + + public static AlertBuilder alert(Alert.AlertType type) { + return new AlertBuilder(mOwner, type); + } + + public static TextInputBuilder input(String content) { + return new TextInputBuilder(mOwner); + } + + public static TextInputBuilder input(String content, String defaultResult) { + return new TextInputBuilder(mOwner, defaultResult).content(content); + } + + @SafeVarargs + public static ChoiceBuilder choices(String hintText, T... choices) { + return new ChoiceBuilder<>(mOwner, choices).content(hintText); + } + + public static ProgressBuilder progress() { + return new ProgressBuilder(mOwner); + } + + public interface OnChoseListener { + void confirm(); + + default void cancelOrClose(ButtonType buttonType) { + } + } + + public interface OnClickListener { + void onClicked(String result); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/view/alert/builder/AlertBuilder.java b/src/main/java/cn/octopusyan/dmt/view/alert/builder/AlertBuilder.java new file mode 100644 index 0000000..a50ecae --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/view/alert/builder/AlertBuilder.java @@ -0,0 +1,110 @@ +package cn.octopusyan.dmt.view.alert.builder; + +import cn.octopusyan.dmt.common.base.BaseBuilder; +import cn.octopusyan.dmt.common.config.LabelConstants; +import cn.octopusyan.dmt.view.alert.AlertUtil; +import javafx.scene.control.*; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Priority; +import javafx.stage.Window; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * @author octopus_yan + */ +public class AlertBuilder extends BaseBuilder { + + public AlertBuilder(Window owner, Alert.AlertType alertType) { + super(new Alert(alertType), owner); + } + + public AlertBuilder buttons(String... buttons) { + dialog.getButtonTypes().addAll(getButtonList(buttons)); + return this; + } + + public AlertBuilder buttons(ButtonType... buttons) { + dialog.getButtonTypes().addAll(buttons); + return this; + } + + public AlertBuilder exception(Exception ex) { + dialog.setTitle("Exception Dialog"); + dialog.setHeaderText(ex.getClass().getSimpleName()); + dialog.setContentText(ex.getMessage()); + + // 创建可扩展的异常。 + var sw = new StringWriter(); + var pw = new PrintWriter(sw); + ex.printStackTrace(pw); + var exceptionText = sw.toString(); + + var label = new Label("The exception stacktrace was :"); + + var textArea = new TextArea(exceptionText); + textArea.setEditable(false); + textArea.setWrapText(true); + + textArea.setMaxWidth(Double.MAX_VALUE); + textArea.setMaxHeight(Double.MAX_VALUE); + GridPane.setVgrow(textArea, Priority.ALWAYS); + GridPane.setHgrow(textArea, Priority.ALWAYS); + + var expContent = new GridPane(); + expContent.setMaxWidth(Double.MAX_VALUE); + expContent.add(label, 0, 0); + expContent.add(textArea, 0, 1); + + // 将可扩展异常设置到对话框窗格中。 + dialog.getDialogPane().setExpandableContent(expContent); + return this; + } + + /** + * 获取按钮列表 + * + * @param buttons "Cancel" / "取消" 为取消按钮 + */ + private List getButtonList(String[] buttons) { + if (ArrayUtils.isEmpty(buttons)) return Collections.emptyList(); + + return Arrays.stream(buttons).map((type) -> { + ButtonBar.ButtonData buttonData = ButtonBar.ButtonData.OTHER; + if ("cancel".equals(StringUtils.lowerCase(type)) || LabelConstants.CANCEL.equals(type)) { + return ButtonType.CANCEL; + } + return new ButtonType(type, buttonData); + }).collect(Collectors.toList()); + } + + /** + * AlertUtil.confirm + */ + public void show(AlertUtil.OnClickListener listener) { + Optional result = dialog.showAndWait(); + result.ifPresent(r -> listener.onClicked(r.getText())); + } + + /** + * AlertUtil.confirm + */ + public void show(AlertUtil.OnChoseListener listener) { + Optional result = dialog.showAndWait(); + result.ifPresent(r -> { + if (r == ButtonType.OK) { + listener.confirm(); + } else { + listener.cancelOrClose(r); + } + }); + } +} \ No newline at end of file diff --git a/src/main/java/cn/octopusyan/dmt/view/alert/builder/ChoiceBuilder.java b/src/main/java/cn/octopusyan/dmt/view/alert/builder/ChoiceBuilder.java new file mode 100644 index 0000000..2d13bd0 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/view/alert/builder/ChoiceBuilder.java @@ -0,0 +1,30 @@ +package cn.octopusyan.dmt.view.alert.builder; + +import cn.octopusyan.dmt.common.base.BaseBuilder; +import javafx.scene.control.ChoiceDialog; +import javafx.stage.Window; + +import java.util.Optional; + +/** + * @author octopus_yan + */ +public class ChoiceBuilder extends BaseBuilder, ChoiceDialog> { + + @SafeVarargs + public ChoiceBuilder(Window mOwner, R... choices) { + this(new ChoiceDialog<>(choices[0], choices), mOwner); + } + + public ChoiceBuilder(ChoiceDialog dialog, Window mOwner) { + super(dialog, mOwner); + } + + /** + * AlertUtil.choices + */ + public R showAndGetChoice() { + Optional result = dialog.showAndWait(); + return result.orElse(null); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/view/alert/builder/DefaultBuilder.java b/src/main/java/cn/octopusyan/dmt/view/alert/builder/DefaultBuilder.java new file mode 100644 index 0000000..f5c80d9 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/view/alert/builder/DefaultBuilder.java @@ -0,0 +1,52 @@ +package cn.octopusyan.dmt.view.alert.builder; + +import cn.octopusyan.dmt.common.base.BaseBuilder; +import cn.octopusyan.dmt.common.util.ViewUtil; +import javafx.scene.Node; +import javafx.scene.control.ButtonBar; +import javafx.scene.control.ButtonType; +import javafx.scene.control.Dialog; +import javafx.scene.control.DialogPane; +import javafx.scene.paint.Color; +import javafx.stage.StageStyle; +import javafx.stage.Window; + +/** + * 默认弹窗 + * + * @author octopus_yan + */ +public class DefaultBuilder extends BaseBuilder> { + + public DefaultBuilder(Window mOwner) { + this(mOwner, true); + } + + public DefaultBuilder(Window mOwner, boolean transparent) { + super(new Dialog<>(), mOwner); + + header(null); + + DialogPane dialogPane = dialog.getDialogPane(); + if (transparent) { + dialogPane.getScene().setFill(Color.TRANSPARENT); + ViewUtil.bindDragged(dialogPane); + ViewUtil.bindShadow(dialogPane); + ViewUtil.getStage(dialogPane).initStyle(StageStyle.TRANSPARENT); + } + + dialogPane.getButtonTypes().add(new ButtonType("取消", ButtonType.CANCEL.getButtonData())); + + for (Node child : dialogPane.getChildren()) { + if (child instanceof ButtonBar) { + dialogPane.getChildren().remove(child); + break; + } + } + } + + public DefaultBuilder content(Node content) { + dialog.getDialogPane().setContent(content); + return this; + } +} diff --git a/src/main/java/cn/octopusyan/dmt/view/alert/builder/ProgressBuilder.java b/src/main/java/cn/octopusyan/dmt/view/alert/builder/ProgressBuilder.java new file mode 100644 index 0000000..80a3b46 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/view/alert/builder/ProgressBuilder.java @@ -0,0 +1,59 @@ +package cn.octopusyan.dmt.view.alert.builder; + +import cn.octopusyan.dmt.common.config.LabelConstants; +import javafx.beans.binding.Bindings; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.control.Button; +import javafx.scene.control.ProgressBar; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; +import javafx.stage.Window; + +/** + * 加载弹窗 + * + * @author octopus_yan + */ +public class ProgressBuilder extends DefaultBuilder { + + private HBox hBox; + + public ProgressBuilder(Window mOwner) { + super(mOwner); + content(getContent()); + } + + public void setWidth(double width) { + hBox.setPrefWidth(width); + } + + private Pane getContent() { + hBox = new HBox(); + hBox.setPrefWidth(350); + hBox.setAlignment(Pos.CENTER); + hBox.setSpacing(10); + hBox.setPadding(new Insets(10, 0, 10, 0)); + + // 取消按钮 + Button cancel = new Button(LabelConstants.CANCEL); + cancel.setCancelButton(true); + cancel.setOnAction(_ -> dialog.close()); + + // 进度条 + ProgressBar progressBar = new ProgressBar(-1); + progressBar.prefWidthProperty().bind(Bindings.createDoubleBinding( + () -> hBox.widthProperty().get() - cancel.widthProperty().get() - 40, + hBox.widthProperty(), cancel.widthProperty() + )); + + hBox.getChildren().add(progressBar); + hBox.getChildren().add(cancel); + return hBox; + } + + public ProgressBuilder onCancel(Runnable run) { + dialog.setOnCloseRequest(_ -> run.run()); + return this; + } +} diff --git a/src/main/java/cn/octopusyan/dmt/view/alert/builder/TextInputBuilder.java b/src/main/java/cn/octopusyan/dmt/view/alert/builder/TextInputBuilder.java new file mode 100644 index 0000000..0e0a1c9 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/view/alert/builder/TextInputBuilder.java @@ -0,0 +1,36 @@ +package cn.octopusyan.dmt.view.alert.builder; + +import cn.octopusyan.dmt.common.base.BaseBuilder; +import javafx.scene.control.TextInputDialog; +import javafx.stage.Window; + +import java.util.Optional; + +/** + * 获取用户输入弹窗 + * + * @author octopus_yan + */ +public class TextInputBuilder extends BaseBuilder { + + public TextInputBuilder(Window mOwner) { + this(new TextInputDialog(), mOwner); + } + + public TextInputBuilder(Window mOwner, String defaultResult) { + this(new TextInputDialog(defaultResult), mOwner); + } + + public TextInputBuilder(TextInputDialog dialog, Window mOwner) { + super(dialog, mOwner); + } + + /** + * AlertUtil.input + * 如果用户点击了取消按钮,将会返回null + */ + public String getInput() { + Optional result = dialog.showAndWait(); + return result.orElse(null); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/view/filemanager/DirectoryTree.java b/src/main/java/cn/octopusyan/dmt/view/filemanager/DirectoryTree.java new file mode 100644 index 0000000..0728ff4 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/view/filemanager/DirectoryTree.java @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: MIT */ + +package cn.octopusyan.dmt.view.filemanager; + +import atlantafx.base.theme.Tweaks; +import cn.octopusyan.dmt.utils.FileUtil; +import javafx.scene.control.TreeCell; +import javafx.scene.control.TreeItem; +import javafx.scene.control.TreeView; +import javafx.scene.image.ImageView; + +import java.io.File; +import java.nio.file.Files; +import java.util.Comparator; + +public final class DirectoryTree extends TreeView { + public static final FileIconRepository fileIcon = new FileIconRepository(); + + // 文件夹在前 + static final Comparator> FILE_TYPE_COMPARATOR = Comparator.comparing( + item -> !Files.isDirectory(item.getValue().toPath()) + ); + + public DirectoryTree() { + super(); + + getStyleClass().add(Tweaks.ALT_ICON); + + setCellFactory(_ -> new TreeCell<>() { + @Override + protected void updateItem(File item, boolean empty) { + super.updateItem(item, empty); + if (empty || item == null) { + setText(null); + setGraphic(null); + } else { + setText(item.getName()); + + var image = new ImageView(item.isDirectory() ? + FileIconRepository.FOLDER : + fileIcon.getByMimeType(FileUtil.getMimeType(item.toPath())) + ); + image.setFitWidth(20); + image.setFitHeight(20); + setGraphic(image); + } + } + }); + } + + public void loadRoot(File value) { + var root = new TreeItem<>(value); + root.setExpanded(true); + setRoot(root); + + // scan file tree two levels deep for starters + scan(root, 5); + + // scan deeper as the user navigates down the tree + root.addEventHandler(TreeItem.branchExpandedEvent(), event -> { + TreeItem parent = event.getTreeItem(); + parent.getChildren().forEach(child -> { + var item = (TreeItem) child; + if (item.getChildren().isEmpty()) { + scan(item, 1); + } + }); + }); + } + + public static void scan(TreeItem parent, int depth) { + File[] files = parent.getValue().listFiles(); + depth--; + + if (files != null) { + for (File f : files) { + var item = new TreeItem<>(f); + parent.getChildren().add(item); + + if (depth > 0) { + scan(item, depth); + } + } + // 文件类型+名称排序 + parent.getChildren().sort(FILE_TYPE_COMPARATOR.thenComparing(TreeItem::getValue)); + } + } +} diff --git a/src/main/java/cn/octopusyan/dmt/view/filemanager/FileIconRepository.java b/src/main/java/cn/octopusyan/dmt/view/filemanager/FileIconRepository.java new file mode 100644 index 0000000..6afe253 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/view/filemanager/FileIconRepository.java @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: MIT */ + +package cn.octopusyan.dmt.view.filemanager; + +import cn.octopusyan.dmt.utils.Resources; +import javafx.scene.image.Image; + +import javax.swing.filechooser.FileSystemView; +import java.io.File; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public final class FileIconRepository { + + public static final String IMAGE_DIRECTORY = "images/papirus/"; + public static final Image UNKNOWN_FILE = new Image( + Resources.getResourceAsStream(IMAGE_DIRECTORY + "mimetypes/text-plain.png") + ); + public static final Image FOLDER = new Image( + Resources.getResourceAsStream(IMAGE_DIRECTORY + "places/folder-paleorange.png") + ); + + private final Map cache = new HashMap<>(); + private final Set unknownMimeTypes = new HashSet<>(); + + public Image getByMimeType(String mimeType) { + if (mimeType == null || unknownMimeTypes.contains(mimeType)) { + return UNKNOWN_FILE; + } + + var cachedImage = cache.get(mimeType); + if (cachedImage != null) { + return cachedImage; + } + + var fileName = mimeType.replaceAll("/", "-") + ".png"; + + try { + var image = new Image(Resources.getResourceAsStream(IMAGE_DIRECTORY + "mimetypes/" + fileName)); + cache.put(mimeType, image); + return image; + } catch (Exception e) { + unknownMimeTypes.add(mimeType); + return UNKNOWN_FILE; + } + } + + public static String getFileName(File file) { + return FileSystemView.getFileSystemView().getSystemDisplayName(file); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/viewModel/MainViewModel.java b/src/main/java/cn/octopusyan/dmt/viewModel/MainViewModel.java new file mode 100644 index 0000000..2e3a0f0 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/viewModel/MainViewModel.java @@ -0,0 +1,202 @@ +package cn.octopusyan.dmt.viewModel; + +import cn.octopusyan.dmt.common.base.BaseViewModel; +import cn.octopusyan.dmt.controller.MainController; +import cn.octopusyan.dmt.model.WordItem; +import cn.octopusyan.dmt.task.PackTask; +import cn.octopusyan.dmt.task.TranslateTask; +import cn.octopusyan.dmt.task.UnpackTask; +import cn.octopusyan.dmt.task.listener.DefaultTaskListener; +import cn.octopusyan.dmt.translate.DelayWord; +import cn.octopusyan.dmt.translate.TranslateUtil; +import cn.octopusyan.dmt.view.ConsoleLog; +import javafx.application.Platform; +import javafx.concurrent.Worker; +import javafx.scene.control.ProgressIndicator; +import org.apache.commons.lang3.StringUtils; +import org.kordamp.ikonli.feather.Feather; +import org.kordamp.ikonli.javafx.FontIcon; + +import java.io.File; +import java.util.List; +import java.util.concurrent.DelayQueue; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.regex.Pattern; + +/** + * 主界面 + * + * @author octopus_yan + */ +public class MainViewModel extends BaseViewModel { + private static final ConsoleLog consoleLog = ConsoleLog.getInstance(MainViewModel.class); + /** + * 解包任务 + */ + private UnpackTask unpackTask; + /** + * 翻译任务 + */ + private TranslateTask translateTask; + + private DelayQueue delayQueue; + + private String unpackPath; + private int total; + + FontIcon startIcon = new FontIcon(Feather.PLAY); + FontIcon pauseIcon = new FontIcon(Feather.PAUSE); + private List wordItems; + + /** + * 加载PBO文件 + */ + public void selectFile(File pboFile) { + if (pboFile == null) return; + + controller.setFileName(pboFile.getAbsolutePath()); + + unpackTask = new UnpackTask(pboFile); + } + + /** + * 解包 + */ + public void unpack() { + if (unpackTask == null) return; + + unpackTask.onListen(new UnpackTask.UnpackListener() { + + @Override + public void onRunning() { + // 展示加载 + controller.onLoad(); + // 重置进度 + resetProgress(); + } + + @Override + public void onUnpackOver(String path) { + MainViewModel.this.unpackPath = path; + Platform.runLater(() -> controller.onUnpack(new File(path))); + } + + @Override + public void onFindWordOver(List wordItems) { + total = wordItems.size(); + MainViewModel.this.wordItems = wordItems; + Platform.runLater(() -> controller.onLoadWord(wordItems)); + } + }); + + unpackTask.execute(); + } + + /** + * 开始翻译 + */ + public void startTranslate() { + if(wordItems.isEmpty()) return; + + if (translateTask == null) { + List words = wordItems.stream().filter(item -> StringUtils.isEmpty(item.getChinese())).toList(); + delayQueue = TranslateUtil.getDelayQueue(words); + translateTask = createTask(); + } + + if (!translateTask.isRunning()) { + // 检查进度 + if (!delayQueue.isEmpty()) { + AtomicInteger index = new AtomicInteger(0); + delayQueue.forEach(item -> TranslateUtil.resetDelayTime(index.getAndIncrement(), item)); + translateTask = createTask(); + } + + if (translateTask.getState() != Worker.State.SUCCEEDED) { + translateTask.execute(); + // 展示进度 + controller.translateProgress.setVisible(true); + controller.translateProgress.progressProperty().bind(translateTask.progressProperty()); + } + } else { + translateTask.cancel(); + } + + } + + /** + * 打包 + */ + public void pack() { + if(wordItems.isEmpty()) return; + + PackTask packTask = new PackTask(wordItems, unpackPath); + packTask.onListen(new PackTask.PackListener() { + @Override + public void onWriteOver() { + consoleLog.info("写入完成"); + } + + @Override + public void onPackOver(File file) { + Platform.runLater(() -> controller.onPackOver(file)); + } + + }); + packTask.execute(); + } + + private TranslateTask createTask() { + TranslateTask task = new TranslateTask(delayQueue, total); + task.onListen(new DefaultTaskListener() { + + @Override + public void onRunning() { + ProgressIndicator graphic = new ProgressIndicator(); + graphic.setPrefWidth(15); + graphic.setPrefHeight(15); + graphic.setOnMouseClicked(_ -> controller.startTranslate()); + controller.translate.setGraphic(graphic); + controller.translateProgress.setVisible(true); + } + + @Override + public void onCancelled() { + task.getThreadPoolManager().shutdownNow(); + TranslateTask.consoleLog.info("翻译暂停"); + Platform.runLater(() -> controller.translate.setGraphic(pauseIcon)); + } + + @Override + protected void onSucceed() { + if (delayQueue.isEmpty()) { + Platform.runLater(() -> controller.translate.setGraphic(startIcon)); + } else { + Platform.runLater(() -> controller.translate.setGraphic(pauseIcon)); + } + } + }); + return task; + } + + /** + * 加载PBO文件后,重置进度 + */ + private void resetProgress() { + translateTask = null; + controller.translate.setGraphic(startIcon); + controller.translateProgress.progressProperty().unbind(); + controller.translateProgress.setProgress(0); + controller.translateProgress.setVisible(false); + } + + /** + * 给定字符串是否含有中文 + * + * @param str 需要判断的字符串 + * @return 是否含有中文 + */ + private boolean containsChinese(String str) { + return Pattern.compile("[\u4e00-\u9fa5]").matcher(str).find(); + } +} diff --git a/src/main/java/cn/octopusyan/dmt/viewModel/ProxyViewModel.java b/src/main/java/cn/octopusyan/dmt/viewModel/ProxyViewModel.java new file mode 100644 index 0000000..61348b1 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/viewModel/ProxyViewModel.java @@ -0,0 +1,107 @@ +package cn.octopusyan.dmt.viewModel; + +import cn.octopusyan.dmt.common.base.BaseViewModel; +import cn.octopusyan.dmt.common.enums.ProxySetup; +import cn.octopusyan.dmt.common.manager.ConfigManager; +import cn.octopusyan.dmt.common.manager.http.HttpUtil; +import cn.octopusyan.dmt.controller.ProxyController; +import cn.octopusyan.dmt.task.ProxyCheckTask; +import cn.octopusyan.dmt.task.listener.DefaultTaskListener; +import cn.octopusyan.dmt.view.alert.AlertUtil; +import cn.octopusyan.dmt.view.alert.builder.ProgressBuilder; +import javafx.application.Platform; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import org.apache.commons.lang3.StringUtils; + +/** + * 设置 + * + * @author octopus_yan + */ +public class ProxyViewModel extends BaseViewModel { + private final StringProperty proxyHost = new SimpleStringProperty(ConfigManager.proxyHost()); + private final StringProperty proxyPort = new SimpleStringProperty(ConfigManager.proxyPort()); + private final ObjectProperty proxySetup = new SimpleObjectProperty<>(ConfigManager.proxySetup()); + private final StringProperty proxyTestUrl = new SimpleStringProperty(ConfigManager.proxyTestUrl()); + + public ProxyViewModel() { + proxySetup.addListener((_, _, newValue) -> ConfigManager.proxySetup(newValue)); + proxyTestUrl.addListener((_, _, newValue) -> ConfigManager.proxyTestUrl(newValue)); + proxyHost.addListener((_, _, newValue) -> { + ConfigManager.proxyHost(newValue); + setProxy(); + }); + proxyPort.addListener((_, _, newValue) -> { + ConfigManager.proxyPort(newValue); + setProxy(); + }); + } + + public ObjectProperty proxySetupProperty() { + return proxySetup; + } + + public StringProperty proxyHostProperty() { + return proxyHost; + } + + public StringProperty proxyPortProperty() { + return proxyPort; + } + + public void proxyTest() { + var checkUrl = AlertUtil.input("URL :", proxyTestUrl.getValue()) + .title("检查代理设置") + .header("请输入您要检查的任何URL:") + .getInput(); + + if (StringUtils.isEmpty(checkUrl)) return; + + proxyTestUrl.setValue(checkUrl); + + ProgressBuilder progress = AlertUtil.progress(); + progress.show(); + ConfigManager.checkProxy((success, msg) -> { + Platform.runLater(progress::close); + if (!success) { + final var tmp = "连接问题: "; + AlertUtil.error(STR."\{tmp}\{msg}").show(); + return; + } + + HttpUtil.getInstance().proxy(ConfigManager.proxySetup(), ConfigManager.getProxyInfo()); + getProxyCheckTask(checkUrl).execute(); + }); + } + + private void setProxy() { + ConfigManager.checkProxy((success, msg) -> { + if (!success) { + return; + } + + HttpUtil.getInstance().proxy(ConfigManager.proxySetup(), ConfigManager.getProxyInfo()); + }); + } + + private static ProxyCheckTask getProxyCheckTask(String checkUrl) { + var task = new ProxyCheckTask(checkUrl); + task.onListen(new DefaultTaskListener(true) { + + @Override + public void onSucceed() { + AlertUtil.info("连接成功").show(); + } + + @Override + public void onFailed(Throwable throwable) { + super.onFailed(throwable); + AlertUtil.exception(new Exception(throwable)).show(); + } + }); + return task; + } +} diff --git a/src/main/java/cn/octopusyan/dmt/viewModel/TranslateViewModel.java b/src/main/java/cn/octopusyan/dmt/viewModel/TranslateViewModel.java new file mode 100644 index 0000000..b61f05b --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/viewModel/TranslateViewModel.java @@ -0,0 +1,32 @@ +package cn.octopusyan.dmt.viewModel; + +import cn.octopusyan.dmt.common.base.BaseViewModel; +import cn.octopusyan.dmt.common.manager.ConfigManager; +import cn.octopusyan.dmt.controller.TranslateController; +import cn.octopusyan.dmt.translate.TranslateApi; +import javafx.beans.property.*; +import lombok.Getter; + +/** + * 翻译VM + * + * @author octopus_yan + */ +@Getter +public class TranslateViewModel extends BaseViewModel { + + private final ObjectProperty source = new SimpleObjectProperty<>(ConfigManager.translateApi()) { + { + addListener((_, _, newValue) -> { + appId.setValue(ConfigManager.translateAppid(newValue)); + apiKey.setValue(ConfigManager.translateApikey(newValue)); + qps.setValue(String.valueOf(ConfigManager.translateQps(newValue))); + needApiKey.setValue(newValue.needApiKey()); + }); + } + }; + private final StringProperty appId = new SimpleStringProperty(ConfigManager.translateAppid(ConfigManager.translateApi())); + private final StringProperty apiKey = new SimpleStringProperty(ConfigManager.translateApikey(ConfigManager.translateApi())); + private final StringProperty qps = new SimpleStringProperty(String.valueOf(ConfigManager.translateQps(ConfigManager.translateApi()))); + private final BooleanProperty needApiKey = new SimpleBooleanProperty(ConfigManager.translateApi().needApiKey()); +} diff --git a/src/main/java/cn/octopusyan/dmt/viewModel/WordEditViewModel.java b/src/main/java/cn/octopusyan/dmt/viewModel/WordEditViewModel.java new file mode 100644 index 0000000..c1754d7 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/viewModel/WordEditViewModel.java @@ -0,0 +1,37 @@ +package cn.octopusyan.dmt.viewModel; + +import cn.octopusyan.dmt.common.base.BaseViewModel; +import cn.octopusyan.dmt.controller.component.WordEditController; +import cn.octopusyan.dmt.model.WordItem; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 文本编辑 + * + * @author octopus_yan + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class WordEditViewModel extends BaseViewModel { + private WordItem data; + + /** + * 原文 + */ + private StringProperty originalProperty = new SimpleStringProperty(); + /** + * 中文 + */ + private StringProperty chineseProperty = new SimpleStringProperty(); + + public void setData(WordItem data) { + if(data == null) return; + this.data = data; + + originalProperty.bind(data.getOriginalProperty()); + chineseProperty.bindBidirectional(data.getChineseProperty()); + } +} diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index dd766d1..e52e70a 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,4 +1,4 @@ -module cn.octopusyan.dayzmodtranslator { +module cn.octopusyan.dmt { requires java.net.http; requires javafx.controls; requires javafx.fxml; @@ -9,14 +9,20 @@ module cn.octopusyan.dayzmodtranslator { requires org.slf4j; requires ch.qos.logback.core; requires ch.qos.logback.classic; - requires com.alibaba.fastjson2; + requires static lombok; + requires atlantafx.base; + requires com.fasterxml.jackson.annotation; + requires com.fasterxml.jackson.databind; + requires com.fasterxml.jackson.dataformat.yaml; + requires java.prefs; + requires org.kordamp.ikonli.javafx; + requires org.kordamp.ikonli.feather; - exports cn.octopusyan.dayzmodtranslator; - opens cn.octopusyan.dayzmodtranslator to javafx.fxml; - exports cn.octopusyan.dayzmodtranslator.base; - opens cn.octopusyan.dayzmodtranslator.base to javafx.fxml; - exports cn.octopusyan.dayzmodtranslator.controller; - opens cn.octopusyan.dayzmodtranslator.controller to javafx.fxml; - exports cn.octopusyan.dayzmodtranslator.manager.word; - opens cn.octopusyan.dayzmodtranslator.manager.word to javafx.base; + exports cn.octopusyan.dmt; + exports cn.octopusyan.dmt.model to com.fasterxml.jackson.databind; + opens cn.octopusyan.dmt.model to javafx.base; + opens cn.octopusyan.dmt.common.base to javafx.fxml; + opens cn.octopusyan.dmt.controller to javafx.fxml; + opens cn.octopusyan.dmt.controller.component to javafx.fxml; + opens cn.octopusyan.dmt.view.filemanager to javafx.fxml; } \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index cf1c3e0..994181c 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,3 +1,3 @@ app.name=${project.name} -app.title=DayZ\u6A21\u7EC4\u6C49\u5316\u5DE5\u5177 -app.version=${project.version} \ No newline at end of file +app.title=${project.description} +app.version=v${project.version} \ No newline at end of file diff --git a/src/main/resources/static/CfgConvert/CfgConvert.exe b/src/main/resources/bin/CfgConvert.exe similarity index 100% rename from src/main/resources/static/CfgConvert/CfgConvert.exe rename to src/main/resources/bin/CfgConvert.exe diff --git a/src/main/resources/static/pboc/Qt6Core.dll b/src/main/resources/bin/Qt6Core.dll similarity index 100% rename from src/main/resources/static/pboc/Qt6Core.dll rename to src/main/resources/bin/Qt6Core.dll diff --git a/src/main/resources/bin/pboc.exe b/src/main/resources/bin/pboc.exe new file mode 100644 index 0000000..0800317 Binary files /dev/null and b/src/main/resources/bin/pboc.exe differ diff --git a/src/main/resources/css/main-view.css b/src/main/resources/css/main-view.css index 9424355..e69de29 100644 --- a/src/main/resources/css/main-view.css +++ b/src/main/resources/css/main-view.css @@ -1,9 +0,0 @@ -#root{ - -fx-background-color: white; -} - -#dragFileLabel { - -fx-font-family: "Microsoft YaHei"; - -fx-text-fill: black; - -fx-font-size: 20; -} \ No newline at end of file diff --git a/src/main/resources/css/root.css b/src/main/resources/css/root.css deleted file mode 100644 index e23bc1d..0000000 --- a/src/main/resources/css/root.css +++ /dev/null @@ -1,10 +0,0 @@ -.box_class { - -fx-background-radius: 5; - -fx-border-style: solid; - -fx-border-color: rgba(136, 136, 136, 0.5); - -fx-background-color: white; -} - -.conf_menu_item { - -fx-pref-width: 100; -} \ No newline at end of file diff --git a/src/main/resources/fxml/component/edit-view.fxml b/src/main/resources/fxml/component/edit-view.fxml new file mode 100644 index 0000000..0e42f76 --- /dev/null +++ b/src/main/resources/fxml/component/edit-view.fxml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/fxml/proxy-view.fxml b/src/main/resources/fxml/proxy-view.fxml deleted file mode 100644 index fe3ccfa..0000000 --- a/src/main/resources/fxml/proxy-view.fxml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - diff --git a/src/main/resources/fxml/setup/proxy-view.fxml b/src/main/resources/fxml/setup/proxy-view.fxml new file mode 100644 index 0000000..0ff36ab --- /dev/null +++ b/src/main/resources/fxml/setup/proxy-view.fxml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/fxml/translate-view.fxml b/src/main/resources/fxml/translate-view.fxml deleted file mode 100644 index ed2af77..0000000 --- a/src/main/resources/fxml/translate-view.fxml +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/images/icon/translate.png b/src/main/resources/images/icon/translate.png new file mode 100644 index 0000000..15d6242 Binary files /dev/null and b/src/main/resources/images/icon/translate.png differ diff --git a/src/main/resources/images/papirus/LICENSE.txt b/src/main/resources/images/papirus/LICENSE.txt new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/src/main/resources/images/papirus/LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/src/main/resources/images/papirus/mimetypes/application-7zip.png b/src/main/resources/images/papirus/mimetypes/application-7zip.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-7zip.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-acad.png b/src/main/resources/images/papirus/mimetypes/application-acad.png new file mode 100644 index 0000000..087397b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-acad.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-afdesigner.png b/src/main/resources/images/papirus/mimetypes/application-afdesigner.png new file mode 100644 index 0000000..1694120 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-afdesigner.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-atom+xml.png b/src/main/resources/images/papirus/mimetypes/application-atom+xml.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-atom+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-autocad_dwg.png b/src/main/resources/images/papirus/mimetypes/application-autocad_dwg.png new file mode 100644 index 0000000..087397b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-autocad_dwg.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-bitwig-clip.png b/src/main/resources/images/papirus/mimetypes/application-bitwig-clip.png new file mode 100644 index 0000000..ab10b39 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-bitwig-clip.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-bitwig-device.png b/src/main/resources/images/papirus/mimetypes/application-bitwig-device.png new file mode 100644 index 0000000..ab10b39 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-bitwig-device.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-bitwig-preset.png b/src/main/resources/images/papirus/mimetypes/application-bitwig-preset.png new file mode 100644 index 0000000..4d0635a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-bitwig-preset.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-bitwig-project-folder.png b/src/main/resources/images/papirus/mimetypes/application-bitwig-project-folder.png new file mode 100644 index 0000000..72cc7a1 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-bitwig-project-folder.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-bitwig-project.png b/src/main/resources/images/papirus/mimetypes/application-bitwig-project.png new file mode 100644 index 0000000..ab10b39 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-bitwig-project.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-bitwig-template.png b/src/main/resources/images/papirus/mimetypes/application-bitwig-template.png new file mode 100644 index 0000000..b606bc1 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-bitwig-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-certificate.png b/src/main/resources/images/papirus/mimetypes/application-certificate.png new file mode 100644 index 0000000..a6ed6e4 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-certificate.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-dart.png b/src/main/resources/images/papirus/mimetypes/application-dart.png new file mode 100644 index 0000000..33bccf8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-dart.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-dicom.png b/src/main/resources/images/papirus/mimetypes/application-dicom.png new file mode 100644 index 0000000..9dfaa6d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-dicom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-dwg.png b/src/main/resources/images/papirus/mimetypes/application-dwg.png new file mode 100644 index 0000000..087397b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-dwg.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-dxf.png b/src/main/resources/images/papirus/mimetypes/application-dxf.png new file mode 100644 index 0000000..c22950f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-dxf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-epub+zip.png b/src/main/resources/images/papirus/mimetypes/application-epub+zip.png new file mode 100644 index 0000000..e26d68a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-epub+zip.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-excel.png b/src/main/resources/images/papirus/mimetypes/application-excel.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-excel.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-font-woff.png b/src/main/resources/images/papirus/mimetypes/application-font-woff.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-font-woff.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-geo+json.png b/src/main/resources/images/papirus/mimetypes/application-geo+json.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-geo+json.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-gml+xml.png b/src/main/resources/images/papirus/mimetypes/application-gml+xml.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-gml+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-gnunet-directory.png b/src/main/resources/images/papirus/mimetypes/application-gnunet-directory.png new file mode 100644 index 0000000..2635436 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-gnunet-directory.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-gpx+xml.png b/src/main/resources/images/papirus/mimetypes/application-gpx+xml.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-gpx+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-gpx.png b/src/main/resources/images/papirus/mimetypes/application-gpx.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-gpx.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-gvdesign.png b/src/main/resources/images/papirus/mimetypes/application-gvdesign.png new file mode 100644 index 0000000..3079226 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-gvdesign.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-gzip.png b/src/main/resources/images/papirus/mimetypes/application-gzip.png new file mode 100644 index 0000000..ad8e607 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-gzip.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-illustrator.png b/src/main/resources/images/papirus/mimetypes/application-illustrator.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-illustrator.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-java.png b/src/main/resources/images/papirus/mimetypes/application-java.png new file mode 100644 index 0000000..b10e170 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-java.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-javascript.png b/src/main/resources/images/papirus/mimetypes/application-javascript.png new file mode 100644 index 0000000..3c0ab6c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-javascript.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-json.png b/src/main/resources/images/papirus/mimetypes/application-json.png new file mode 100644 index 0000000..ff2c8c9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-json.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-ld+json.png b/src/main/resources/images/papirus/mimetypes/application-ld+json.png new file mode 100644 index 0000000..1bfca94 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-ld+json.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-loc+xml.png b/src/main/resources/images/papirus/mimetypes/application-loc+xml.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-loc+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-mathematica.png b/src/main/resources/images/papirus/mimetypes/application-mathematica.png new file mode 100644 index 0000000..6ec4117 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-mathematica.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-mathematicaplayer.png b/src/main/resources/images/papirus/mimetypes/application-mathematicaplayer.png new file mode 100644 index 0000000..b71c929 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-mathematicaplayer.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-mathml+xml.png b/src/main/resources/images/papirus/mimetypes/application-mathml+xml.png new file mode 100644 index 0000000..63c11ed Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-mathml+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-mbox.png b/src/main/resources/images/papirus/mimetypes/application-mbox.png new file mode 100644 index 0000000..b4b67b5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-mbox.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-metalink+xml.png b/src/main/resources/images/papirus/mimetypes/application-metalink+xml.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-metalink+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-metalink4+xml.png b/src/main/resources/images/papirus/mimetypes/application-metalink4+xml.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-metalink4+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-msexcel.png b/src/main/resources/images/papirus/mimetypes/application-msexcel.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-msexcel.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-mspowerpoint.png b/src/main/resources/images/papirus/mimetypes/application-mspowerpoint.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-mspowerpoint.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-msword-template.png b/src/main/resources/images/papirus/mimetypes/application-msword-template.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-msword-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-msword.png b/src/main/resources/images/papirus/mimetypes/application-msword.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-msword.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-octet-stream.png b/src/main/resources/images/papirus/mimetypes/application-octet-stream.png new file mode 100644 index 0000000..63d5616 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-octet-stream.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-oebps-package+xml.png b/src/main/resources/images/papirus/mimetypes/application-oebps-package+xml.png new file mode 100644 index 0000000..e26d68a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-oebps-package+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-ogg.png b/src/main/resources/images/papirus/mimetypes/application-ogg.png new file mode 100644 index 0000000..9e9d3d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-ogg.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-owl+xml.png b/src/main/resources/images/papirus/mimetypes/application-owl+xml.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-owl+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-pdf.png b/src/main/resources/images/papirus/mimetypes/application-pdf.png new file mode 100644 index 0000000..9f33646 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-pdf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-pgp-encrypted.png b/src/main/resources/images/papirus/mimetypes/application-pgp-encrypted.png new file mode 100644 index 0000000..f3ac1c7 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-pgp-encrypted.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-pgp-keys.png b/src/main/resources/images/papirus/mimetypes/application-pgp-keys.png new file mode 100644 index 0000000..822ad4b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-pgp-keys.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-pgp-signature.png b/src/main/resources/images/papirus/mimetypes/application-pgp-signature.png new file mode 100644 index 0000000..822ad4b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-pgp-signature.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-pgp.png b/src/main/resources/images/papirus/mimetypes/application-pgp.png new file mode 100644 index 0000000..822ad4b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-pgp.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-pkcs10.png b/src/main/resources/images/papirus/mimetypes/application-pkcs10.png new file mode 100644 index 0000000..a6ed6e4 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-pkcs10.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-pkcs12.png b/src/main/resources/images/papirus/mimetypes/application-pkcs12.png new file mode 100644 index 0000000..a6ed6e4 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-pkcs12.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-pkcs7-mime.png b/src/main/resources/images/papirus/mimetypes/application-pkcs7-mime.png new file mode 100644 index 0000000..a6ed6e4 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-pkcs7-mime.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-pkcs7-signature.png b/src/main/resources/images/papirus/mimetypes/application-pkcs7-signature.png new file mode 100644 index 0000000..822ad4b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-pkcs7-signature.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-pkcs8.png b/src/main/resources/images/papirus/mimetypes/application-pkcs8.png new file mode 100644 index 0000000..822ad4b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-pkcs8.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-pkix-cert.png b/src/main/resources/images/papirus/mimetypes/application-pkix-cert.png new file mode 100644 index 0000000..a6ed6e4 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-pkix-cert.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-pkix-crl.png b/src/main/resources/images/papirus/mimetypes/application-pkix-crl.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-pkix-crl.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-pkix-pkipath.png b/src/main/resources/images/papirus/mimetypes/application-pkix-pkipath.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-pkix-pkipath.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-postscript.png b/src/main/resources/images/papirus/mimetypes/application-postscript.png new file mode 100644 index 0000000..297b207 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-postscript.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-ram.png b/src/main/resources/images/papirus/mimetypes/application-ram.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-ram.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-rdf+xml.png b/src/main/resources/images/papirus/mimetypes/application-rdf+xml.png new file mode 100644 index 0000000..1bfca94 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-rdf+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-relaxng.png b/src/main/resources/images/papirus/mimetypes/application-relaxng.png new file mode 100644 index 0000000..466fe09 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-relaxng.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-rss+xml.png b/src/main/resources/images/papirus/mimetypes/application-rss+xml.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-rss+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-rtf.png b/src/main/resources/images/papirus/mimetypes/application-rtf.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-rtf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-shorten.png b/src/main/resources/images/papirus/mimetypes/application-shorten.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-shorten.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-slf+xml.png b/src/main/resources/images/papirus/mimetypes/application-slf+xml.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-slf+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-sql.png b/src/main/resources/images/papirus/mimetypes/application-sql.png new file mode 100644 index 0000000..7296d70 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-sql.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-sweethome3d.png b/src/main/resources/images/papirus/mimetypes/application-sweethome3d.png new file mode 100644 index 0000000..336ef76 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-sweethome3d.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-tcx+xml.png b/src/main/resources/images/papirus/mimetypes/application-tcx+xml.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-tcx+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-toml.png b/src/main/resources/images/papirus/mimetypes/application-toml.png new file mode 100644 index 0000000..e3aa894 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-toml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd-google-earth-kml.png b/src/main/resources/images/papirus/mimetypes/application-vnd-google-earth-kml.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd-google-earth-kml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.adobe.flash.movie.png b/src/main/resources/images/papirus/mimetypes/application-vnd.adobe.flash.movie.png new file mode 100644 index 0000000..45a10c2 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.adobe.flash.movie.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.afdesigner.png b/src/main/resources/images/papirus/mimetypes/application-vnd.afdesigner.png new file mode 100644 index 0000000..1694120 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.afdesigner.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.affinity-designer.png b/src/main/resources/images/papirus/mimetypes/application-vnd.affinity-designer.png new file mode 100644 index 0000000..1694120 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.affinity-designer.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.amazon.mobi8-ebook.png b/src/main/resources/images/papirus/mimetypes/application-vnd.amazon.mobi8-ebook.png new file mode 100644 index 0000000..a2c30fe Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.amazon.mobi8-ebook.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.android.package-archive.png b/src/main/resources/images/papirus/mimetypes/application-vnd.android.package-archive.png new file mode 100644 index 0000000..0fe73f8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.android.package-archive.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ant.fit.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ant.fit.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ant.fit.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.appimage.png b/src/main/resources/images/papirus/mimetypes/application-vnd.appimage.png new file mode 100644 index 0000000..2ceca8b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.appimage.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.apple.mpegurl.png b/src/main/resources/images/papirus/mimetypes/application-vnd.apple.mpegurl.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.apple.mpegurl.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.chess-pgn.png b/src/main/resources/images/papirus/mimetypes/application-vnd.chess-pgn.png new file mode 100644 index 0000000..c22e8c9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.chess-pgn.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.comicbook+zip.png b/src/main/resources/images/papirus/mimetypes/application-vnd.comicbook+zip.png new file mode 100644 index 0000000..4a549bb Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.comicbook+zip.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.comicbook-rar.png b/src/main/resources/images/papirus/mimetypes/application-vnd.comicbook-rar.png new file mode 100644 index 0000000..4a549bb Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.comicbook-rar.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.debian.binary-package.png b/src/main/resources/images/papirus/mimetypes/application-vnd.debian.binary-package.png new file mode 100644 index 0000000..c73e56d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.debian.binary-package.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.fai.igc.png b/src/main/resources/images/papirus/mimetypes/application-vnd.fai.igc.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.fai.igc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.fastcopy-disk-image.png b/src/main/resources/images/papirus/mimetypes/application-vnd.fastcopy-disk-image.png new file mode 100644 index 0000000..10a07e8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.fastcopy-disk-image.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.flatpak.png b/src/main/resources/images/papirus/mimetypes/application-vnd.flatpak.png new file mode 100644 index 0000000..4021b41 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.flatpak.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.flatpak.ref.png b/src/main/resources/images/papirus/mimetypes/application-vnd.flatpak.ref.png new file mode 100644 index 0000000..4021b41 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.flatpak.ref.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.flatpak.repo.png b/src/main/resources/images/papirus/mimetypes/application-vnd.flatpak.repo.png new file mode 100644 index 0000000..4021b41 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.flatpak.repo.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.geo+json.png b/src/main/resources/images/papirus/mimetypes/application-vnd.geo+json.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.geo+json.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.document.png b/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.document.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.document.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.drawing.png b/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.drawing.png new file mode 100644 index 0000000..80f000f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.drawing.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.form.png b/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.form.png new file mode 100644 index 0000000..df905f3 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.form.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.fusiontable.png b/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.fusiontable.png new file mode 100644 index 0000000..5a39394 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.fusiontable.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.map.png b/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.map.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.map.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.presentation.png b/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.presentation.png new file mode 100644 index 0000000..9b01a8d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.presentation.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.script.png b/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.script.png new file mode 100644 index 0000000..9889ec7 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.script.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.site.png b/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.site.png new file mode 100644 index 0000000..ae85178 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.site.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.spreadsheet.png b/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.spreadsheet.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.google-apps.spreadsheet.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.google-earth.kml+xml.png b/src/main/resources/images/papirus/mimetypes/application-vnd.google-earth.kml+xml.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.google-earth.kml+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.google-earth.kml.png b/src/main/resources/images/papirus/mimetypes/application-vnd.google-earth.kml.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.google-earth.kml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.google-earth.kmz.png b/src/main/resources/images/papirus/mimetypes/application-vnd.google-earth.kmz.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.google-earth.kmz.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.gvdesign.png b/src/main/resources/images/papirus/mimetypes/application-vnd.gvdesign.png new file mode 100644 index 0000000..3079226 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.gvdesign.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.iccprofile.png b/src/main/resources/images/papirus/mimetypes/application-vnd.iccprofile.png new file mode 100644 index 0000000..10d3650 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.iccprofile.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.doc.png b/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.doc.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.doc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.draw.png b/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.draw.png new file mode 100644 index 0000000..80f000f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.draw.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.form.png b/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.form.png new file mode 100644 index 0000000..df905f3 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.form.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.link.png b/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.link.png new file mode 100644 index 0000000..37dc607 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.link.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.note.png b/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.note.png new file mode 100644 index 0000000..de4b61e Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.note.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.script.png b/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.script.png new file mode 100644 index 0000000..9889ec7 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.script.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.sheet.png b/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.sheet.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.sheet.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.slides.png b/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.slides.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.slides.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.table.png b/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.table.png new file mode 100644 index 0000000..5a39394 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.insync.link.drive.table.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.kde.bluedevil-sendfile.png b/src/main/resources/images/papirus/mimetypes/application-vnd.kde.bluedevil-sendfile.png new file mode 100644 index 0000000..ee0206e Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.kde.bluedevil-sendfile.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.kde.fontspackage.png b/src/main/resources/images/papirus/mimetypes/application-vnd.kde.fontspackage.png new file mode 100644 index 0000000..ad8e607 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.kde.fontspackage.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.kde.kphotoalbum-import.png b/src/main/resources/images/papirus/mimetypes/application-vnd.kde.kphotoalbum-import.png new file mode 100644 index 0000000..feb40e1 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.kde.kphotoalbum-import.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.kde.okular-archive.png b/src/main/resources/images/papirus/mimetypes/application-vnd.kde.okular-archive.png new file mode 100644 index 0000000..ad8e607 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.kde.okular-archive.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ms-access.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-access.png new file mode 100644 index 0000000..f7f57e9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-access.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ms-asf.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-asf.png new file mode 100644 index 0000000..76c4570 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-asf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ms-cab-compressed.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-cab-compressed.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-cab-compressed.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ms-excel.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-excel.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-excel.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ms-excel.sheet.binary.macroenabled.12.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-excel.sheet.binary.macroenabled.12.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-excel.sheet.binary.macroenabled.12.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ms-excel.sheet.macroenabled.12.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-excel.sheet.macroenabled.12.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-excel.sheet.macroenabled.12.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ms-excel.template.macroenabled.12.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-excel.template.macroenabled.12.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-excel.template.macroenabled.12.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ms-htmlhelp.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-htmlhelp.png new file mode 100644 index 0000000..41ad9d6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-htmlhelp.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ms-powerpoint.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-powerpoint.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-powerpoint.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ms-powerpoint.presentation.macroenabled.12.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-powerpoint.presentation.macroenabled.12.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-powerpoint.presentation.macroenabled.12.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ms-powerpoint.slideshow.macroenabled.12.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-powerpoint.slideshow.macroenabled.12.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-powerpoint.slideshow.macroenabled.12.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ms-powerpoint.template.macroenabled.12.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-powerpoint.template.macroenabled.12.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-powerpoint.template.macroenabled.12.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ms-project.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-project.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-project.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ms-publisher.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-publisher.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-publisher.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ms-tnef.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-tnef.png new file mode 100644 index 0000000..e75dd0c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-tnef.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ms-word.document.macroenabled.12.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-word.document.macroenabled.12.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-word.document.macroenabled.12.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ms-word.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-word.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-word.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ms-word.template.macroenabled.12.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-word.template.macroenabled.12.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-word.template.macroenabled.12.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.ms-wpl.png b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-wpl.png new file mode 100644 index 0000000..76c4570 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.ms-wpl.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.msa-disk-image.png b/src/main/resources/images/papirus/mimetypes/application-vnd.msa-disk-image.png new file mode 100644 index 0000000..10a07e8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.msa-disk-image.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.mysql-workbench-model.png b/src/main/resources/images/papirus/mimetypes/application-vnd.mysql-workbench-model.png new file mode 100644 index 0000000..f6c75cd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.mysql-workbench-model.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.nintendo.snes.rom.png b/src/main/resources/images/papirus/mimetypes/application-vnd.nintendo.snes.rom.png new file mode 100644 index 0000000..011081c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.nintendo.snes.rom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.nmea.nmea.png b/src/main/resources/images/papirus/mimetypes/application-vnd.nmea.nmea.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.nmea.nmea.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.nokia.xml.qt.resource.png b/src/main/resources/images/papirus/mimetypes/application-vnd.nokia.xml.qt.resource.png new file mode 100644 index 0000000..15a0f28 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.nokia.xml.qt.resource.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.chart.png b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.chart.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.chart.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.database.png b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.database.png new file mode 100644 index 0000000..f7f57e9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.database.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.formula-template.png b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.formula-template.png new file mode 100644 index 0000000..63c11ed Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.formula-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.formula.png b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.formula.png new file mode 100644 index 0000000..63c11ed Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.formula.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.graphics-template.png b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.graphics-template.png new file mode 100644 index 0000000..1e04031 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.graphics-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.graphics.png b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.graphics.png new file mode 100644 index 0000000..1e04031 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.graphics.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.image.png b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.image.png new file mode 100644 index 0000000..1e04031 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.image.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.presentation-template.png b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.presentation-template.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.presentation-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.presentation.png b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.presentation.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.presentation.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.spreadsheet-template.png b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.spreadsheet-template.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.spreadsheet-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.spreadsheet.png b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.spreadsheet.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.spreadsheet.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.text-master.png b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.text-master.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.text-master.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.text-template.png b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.text-template.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.text-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.text-web.png b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.text-web.png new file mode 100644 index 0000000..466fe09 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.text-web.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.text.png b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.text.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.oasis.opendocument.text.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.openofficeorg.extension.png b/src/main/resources/images/papirus/mimetypes/application-vnd.openofficeorg.extension.png new file mode 100644 index 0000000..39ffd39 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.openofficeorg.extension.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.openxmlformats-officedocument.presentationml.presentation.png b/src/main/resources/images/papirus/mimetypes/application-vnd.openxmlformats-officedocument.presentationml.presentation.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.openxmlformats-officedocument.presentationml.presentation.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.openxmlformats-officedocument.presentationml.slideshow.png b/src/main/resources/images/papirus/mimetypes/application-vnd.openxmlformats-officedocument.presentationml.slideshow.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.openxmlformats-officedocument.presentationml.slideshow.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.openxmlformats-officedocument.spreadsheetml.sheet.png b/src/main/resources/images/papirus/mimetypes/application-vnd.openxmlformats-officedocument.spreadsheetml.sheet.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.openxmlformats-officedocument.spreadsheetml.sheet.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.openxmlformats-officedocument.wordprocessingml.document.png b/src/main/resources/images/papirus/mimetypes/application-vnd.openxmlformats-officedocument.wordprocessingml.document.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.openxmlformats-officedocument.wordprocessingml.document.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.oziexplorer.plt.png b/src/main/resources/images/papirus/mimetypes/application-vnd.oziexplorer.plt.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.oziexplorer.plt.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.oziexplorer.rte.png b/src/main/resources/images/papirus/mimetypes/application-vnd.oziexplorer.rte.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.oziexplorer.rte.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.oziexplorer.wpt.png b/src/main/resources/images/papirus/mimetypes/application-vnd.oziexplorer.wpt.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.oziexplorer.wpt.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.palm.png b/src/main/resources/images/papirus/mimetypes/application-vnd.palm.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.palm.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.rar.png b/src/main/resources/images/papirus/mimetypes/application-vnd.rar.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.rar.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.recordare.musicxml+xml.png b/src/main/resources/images/papirus/mimetypes/application-vnd.recordare.musicxml+xml.png new file mode 100644 index 0000000..66631d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.recordare.musicxml+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.recordare.musicxml.png b/src/main/resources/images/papirus/mimetypes/application-vnd.recordare.musicxml.png new file mode 100644 index 0000000..66631d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.recordare.musicxml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.rn-realmedia.png b/src/main/resources/images/papirus/mimetypes/application-vnd.rn-realmedia.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.rn-realmedia.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.scribus.png b/src/main/resources/images/papirus/mimetypes/application-vnd.scribus.png new file mode 100644 index 0000000..9967059 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.scribus.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.sqlite3.png b/src/main/resources/images/papirus/mimetypes/application-vnd.sqlite3.png new file mode 100644 index 0000000..7296d70 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.sqlite3.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.squashfs.png b/src/main/resources/images/papirus/mimetypes/application-vnd.squashfs.png new file mode 100644 index 0000000..3f7e9a0 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.squashfs.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.stardivision.calc.png b/src/main/resources/images/papirus/mimetypes/application-vnd.stardivision.calc.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.stardivision.calc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.stardivision.draw.png b/src/main/resources/images/papirus/mimetypes/application-vnd.stardivision.draw.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.stardivision.draw.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.stardivision.mail.png b/src/main/resources/images/papirus/mimetypes/application-vnd.stardivision.mail.png new file mode 100644 index 0000000..1979f1f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.stardivision.mail.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.stardivision.math.png b/src/main/resources/images/papirus/mimetypes/application-vnd.stardivision.math.png new file mode 100644 index 0000000..63c11ed Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.stardivision.math.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.base.png b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.base.png new file mode 100644 index 0000000..f7f57e9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.base.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.calc.png b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.calc.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.calc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.calc.template.png b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.calc.template.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.calc.template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.draw.png b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.draw.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.draw.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.draw.template.png b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.draw.template.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.draw.template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.impress.png b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.impress.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.impress.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.impress.template.png b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.impress.template.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.impress.template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.math.png b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.math.png new file mode 100644 index 0000000..63c11ed Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.math.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.writer.global.png b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.writer.global.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.writer.global.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.writer.png b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.writer.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.writer.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.writer.template.png b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.writer.template.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.sun.xml.writer.template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.tcpdump.pcap.png b/src/main/resources/images/papirus/mimetypes/application-vnd.tcpdump.pcap.png new file mode 100644 index 0000000..7c0708f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.tcpdump.pcap.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.visio.png b/src/main/resources/images/papirus/mimetypes/application-vnd.visio.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.visio.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.wap.wmlc.png b/src/main/resources/images/papirus/mimetypes/application-vnd.wap.wmlc.png new file mode 100644 index 0000000..466fe09 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.wap.wmlc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.wap.xhtml+xml.png b/src/main/resources/images/papirus/mimetypes/application-vnd.wap.xhtml+xml.png new file mode 100644 index 0000000..466fe09 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.wap.xhtml+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.wolfram.cdf.png b/src/main/resources/images/papirus/mimetypes/application-vnd.wolfram.cdf.png new file mode 100644 index 0000000..b71c929 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.wolfram.cdf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.wolfram.mathematica.package.png b/src/main/resources/images/papirus/mimetypes/application-vnd.wolfram.mathematica.package.png new file mode 100644 index 0000000..ee1632f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.wolfram.mathematica.package.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.wolfram.nb.png b/src/main/resources/images/papirus/mimetypes/application-vnd.wolfram.nb.png new file mode 100644 index 0000000..6ec4117 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.wolfram.nb.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.wolfram.player.png b/src/main/resources/images/papirus/mimetypes/application-vnd.wolfram.player.png new file mode 100644 index 0000000..b71c929 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.wolfram.player.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.wolfram.wl.png b/src/main/resources/images/papirus/mimetypes/application-vnd.wolfram.wl.png new file mode 100644 index 0000000..ee1632f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.wolfram.wl.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.wolfram.wls.png b/src/main/resources/images/papirus/mimetypes/application-vnd.wolfram.wls.png new file mode 100644 index 0000000..ee1632f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.wolfram.wls.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-vnd.wordperfect.png b/src/main/resources/images/papirus/mimetypes/application-vnd.wordperfect.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-vnd.wordperfect.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-winhlp.png b/src/main/resources/images/papirus/mimetypes/application-winhlp.png new file mode 100644 index 0000000..41ad9d6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-winhlp.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-5view.png b/src/main/resources/images/papirus/mimetypes/application-x-5view.png new file mode 100644 index 0000000..7c0708f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-5view.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-7z-compressed-tar.png b/src/main/resources/images/papirus/mimetypes/application-x-7z-compressed-tar.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-7z-compressed-tar.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-7z-compressed.png b/src/main/resources/images/papirus/mimetypes/application-x-7z-compressed.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-7z-compressed.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-7zip.png b/src/main/resources/images/papirus/mimetypes/application-x-7zip.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-7zip.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-abiword.png b/src/main/resources/images/papirus/mimetypes/application-x-abiword.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-abiword.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-acad.png b/src/main/resources/images/papirus/mimetypes/application-x-acad.png new file mode 100644 index 0000000..087397b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-acad.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-accountwizard-package.png b/src/main/resources/images/papirus/mimetypes/application-x-accountwizard-package.png new file mode 100644 index 0000000..080d1bd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-accountwizard-package.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-ace.png b/src/main/resources/images/papirus/mimetypes/application-x-ace.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-ace.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-addon.png b/src/main/resources/images/papirus/mimetypes/application-x-addon.png new file mode 100644 index 0000000..39ffd39 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-addon.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-amiga-disk-format.png b/src/main/resources/images/papirus/mimetypes/application-x-amiga-disk-format.png new file mode 100644 index 0000000..3f7e9a0 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-amiga-disk-format.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-aoi.png b/src/main/resources/images/papirus/mimetypes/application-x-aoi.png new file mode 100644 index 0000000..cf0e8d3 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-aoi.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-apple-diskimage.png b/src/main/resources/images/papirus/mimetypes/application-x-apple-diskimage.png new file mode 100644 index 0000000..3f7e9a0 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-apple-diskimage.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-applix-spreadsheet.png b/src/main/resources/images/papirus/mimetypes/application-x-applix-spreadsheet.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-applix-spreadsheet.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-applix-word.png b/src/main/resources/images/papirus/mimetypes/application-x-applix-word.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-applix-word.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-arc.png b/src/main/resources/images/papirus/mimetypes/application-x-arc.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-arc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-archive.png b/src/main/resources/images/papirus/mimetypes/application-x-archive.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-archive.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-ardour.png b/src/main/resources/images/papirus/mimetypes/application-x-ardour.png new file mode 100644 index 0000000..be14530 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-ardour.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-arj.png b/src/main/resources/images/papirus/mimetypes/application-x-arj.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-arj.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-asp.png b/src/main/resources/images/papirus/mimetypes/application-x-asp.png new file mode 100644 index 0000000..31a26db Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-asp.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-atari-2600-rom.png b/src/main/resources/images/papirus/mimetypes/application-x-atari-2600-rom.png new file mode 100644 index 0000000..bf18f7a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-atari-2600-rom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-atari-7800-rom.png b/src/main/resources/images/papirus/mimetypes/application-x-atari-7800-rom.png new file mode 100644 index 0000000..8aceffb Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-atari-7800-rom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-atari-lynx-rom.png b/src/main/resources/images/papirus/mimetypes/application-x-atari-lynx-rom.png new file mode 100644 index 0000000..cf1c86e Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-atari-lynx-rom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-audacity-project.png b/src/main/resources/images/papirus/mimetypes/application-x-audacity-project.png new file mode 100644 index 0000000..9e9d3d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-audacity-project.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-autocad.png b/src/main/resources/images/papirus/mimetypes/application-x-autocad.png new file mode 100644 index 0000000..087397b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-autocad.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-awk.png b/src/main/resources/images/papirus/mimetypes/application-x-awk.png new file mode 100644 index 0000000..47be445 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-awk.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-bittorrent.png b/src/main/resources/images/papirus/mimetypes/application-x-bittorrent.png new file mode 100644 index 0000000..680a346 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-bittorrent.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-blender.png b/src/main/resources/images/papirus/mimetypes/application-x-blender.png new file mode 100644 index 0000000..7463cbf Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-blender.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-bps-patch.png b/src/main/resources/images/papirus/mimetypes/application-x-bps-patch.png new file mode 100644 index 0000000..ef2d241 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-bps-patch.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-bsdiff.png b/src/main/resources/images/papirus/mimetypes/application-x-bsdiff.png new file mode 100644 index 0000000..ef2d241 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-bsdiff.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-bzdvi.png b/src/main/resources/images/papirus/mimetypes/application-x-bzdvi.png new file mode 100644 index 0000000..ad8e607 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-bzdvi.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-bzip-compressed-tar.png b/src/main/resources/images/papirus/mimetypes/application-x-bzip-compressed-tar.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-bzip-compressed-tar.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-bzip.png b/src/main/resources/images/papirus/mimetypes/application-x-bzip.png new file mode 100644 index 0000000..ad8e607 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-bzip.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-bzpostscript.png b/src/main/resources/images/papirus/mimetypes/application-x-bzpostscript.png new file mode 100644 index 0000000..297b207 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-bzpostscript.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-cabri.png b/src/main/resources/images/papirus/mimetypes/application-x-cabri.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-cabri.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-cb7.png b/src/main/resources/images/papirus/mimetypes/application-x-cb7.png new file mode 100644 index 0000000..4a549bb Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-cb7.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-cba.png b/src/main/resources/images/papirus/mimetypes/application-x-cba.png new file mode 100644 index 0000000..4a549bb Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-cba.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-cbr.png b/src/main/resources/images/papirus/mimetypes/application-x-cbr.png new file mode 100644 index 0000000..4a549bb Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-cbr.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-cbt.png b/src/main/resources/images/papirus/mimetypes/application-x-cbt.png new file mode 100644 index 0000000..4a549bb Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-cbt.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-cbz.png b/src/main/resources/images/papirus/mimetypes/application-x-cbz.png new file mode 100644 index 0000000..4a549bb Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-cbz.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-ccf-container.png b/src/main/resources/images/papirus/mimetypes/application-x-ccf-container.png new file mode 100644 index 0000000..e546bde Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-ccf-container.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-cd-image.png b/src/main/resources/images/papirus/mimetypes/application-x-cd-image.png new file mode 100644 index 0000000..3f7e9a0 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-cd-image.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-cda.png b/src/main/resources/images/papirus/mimetypes/application-x-cda.png new file mode 100644 index 0000000..3f7e9a0 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-cda.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-chm.png b/src/main/resources/images/papirus/mimetypes/application-x-chm.png new file mode 100644 index 0000000..41ad9d6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-chm.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-class-file.png b/src/main/resources/images/papirus/mimetypes/application-x-class-file.png new file mode 100644 index 0000000..b10e170 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-class-file.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-clementine.png b/src/main/resources/images/papirus/mimetypes/application-x-clementine.png new file mode 100644 index 0000000..087878b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-clementine.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-cmakecache.png b/src/main/resources/images/papirus/mimetypes/application-x-cmakecache.png new file mode 100644 index 0000000..41efa7f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-cmakecache.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-codeblocks-workspace.png b/src/main/resources/images/papirus/mimetypes/application-x-codeblocks-workspace.png new file mode 100644 index 0000000..d67c4a7 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-codeblocks-workspace.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-codeblocks.png b/src/main/resources/images/papirus/mimetypes/application-x-codeblocks.png new file mode 100644 index 0000000..8b28050 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-codeblocks.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-codelite-project.png b/src/main/resources/images/papirus/mimetypes/application-x-codelite-project.png new file mode 100644 index 0000000..3cb260b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-codelite-project.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-codelite-workspace.png b/src/main/resources/images/papirus/mimetypes/application-x-codelite-workspace.png new file mode 100644 index 0000000..fe4faa1 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-codelite-workspace.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-compress.png b/src/main/resources/images/papirus/mimetypes/application-x-compress.png new file mode 100644 index 0000000..ad8e607 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-compress.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-compressed-iso.png b/src/main/resources/images/papirus/mimetypes/application-x-compressed-iso.png new file mode 100644 index 0000000..ad8e607 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-compressed-iso.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-compressed-tar.png b/src/main/resources/images/papirus/mimetypes/application-x-compressed-tar.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-compressed-tar.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-core.png b/src/main/resources/images/papirus/mimetypes/application-x-core.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-core.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-cpio.png b/src/main/resources/images/papirus/mimetypes/application-x-cpio.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-cpio.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-cue.png b/src/main/resources/images/papirus/mimetypes/application-x-cue.png new file mode 100644 index 0000000..3f7e9a0 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-cue.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-dbf.png b/src/main/resources/images/papirus/mimetypes/application-x-dbf.png new file mode 100644 index 0000000..f7f57e9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-dbf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-dbm.png b/src/main/resources/images/papirus/mimetypes/application-x-dbm.png new file mode 100644 index 0000000..417c11a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-dbm.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-deb.png b/src/main/resources/images/papirus/mimetypes/application-x-deb.png new file mode 100644 index 0000000..c73e56d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-deb.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-deepinclone-dim.png b/src/main/resources/images/papirus/mimetypes/application-x-deepinclone-dim.png new file mode 100644 index 0000000..4469fd5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-deepinclone-dim.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-designer.png b/src/main/resources/images/papirus/mimetypes/application-x-designer.png new file mode 100644 index 0000000..8187344 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-designer.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-desktop.png b/src/main/resources/images/papirus/mimetypes/application-x-desktop.png new file mode 100644 index 0000000..c748a8d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-desktop.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-dia-diagram.png b/src/main/resources/images/papirus/mimetypes/application-x-dia-diagram.png new file mode 100644 index 0000000..77360ce Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-dia-diagram.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-dlc-container.png b/src/main/resources/images/papirus/mimetypes/application-x-dlc-container.png new file mode 100644 index 0000000..e546bde Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-dlc-container.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-drgeo.png b/src/main/resources/images/papirus/mimetypes/application-x-drgeo.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-drgeo.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-dwg.png b/src/main/resources/images/papirus/mimetypes/application-x-dwg.png new file mode 100644 index 0000000..087397b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-dwg.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-e-theme.png b/src/main/resources/images/papirus/mimetypes/application-x-e-theme.png new file mode 100644 index 0000000..7726b56 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-e-theme.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-egon.png b/src/main/resources/images/papirus/mimetypes/application-x-egon.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-egon.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-emerald-theme.png b/src/main/resources/images/papirus/mimetypes/application-x-emerald-theme.png new file mode 100644 index 0000000..626b9de Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-emerald-theme.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-eqonomize.png b/src/main/resources/images/papirus/mimetypes/application-x-eqonomize.png new file mode 100644 index 0000000..24378a0 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-eqonomize.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-etherpeek.png b/src/main/resources/images/papirus/mimetypes/application-x-etherpeek.png new file mode 100644 index 0000000..7c0708f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-etherpeek.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-excel.png b/src/main/resources/images/papirus/mimetypes/application-x-excel.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-excel.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-executable.png b/src/main/resources/images/papirus/mimetypes/application-x-executable.png new file mode 100644 index 0000000..c748a8d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-executable.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-extension-eml.png b/src/main/resources/images/papirus/mimetypes/application-x-extension-eml.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-extension-eml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-extension-fcstd.png b/src/main/resources/images/papirus/mimetypes/application-x-extension-fcstd.png new file mode 100644 index 0000000..2cc4f25 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-extension-fcstd.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-extension-rss.png b/src/main/resources/images/papirus/mimetypes/application-x-extension-rss.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-extension-rss.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-fictionbook+xml.png b/src/main/resources/images/papirus/mimetypes/application-x-fictionbook+xml.png new file mode 100644 index 0000000..e26a946 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-fictionbook+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-fictionbook.png b/src/main/resources/images/papirus/mimetypes/application-x-fictionbook.png new file mode 100644 index 0000000..e26a946 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-fictionbook.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-flash-video.png b/src/main/resources/images/papirus/mimetypes/application-x-flash-video.png new file mode 100644 index 0000000..313cfb2 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-flash-video.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-font-afm.png b/src/main/resources/images/papirus/mimetypes/application-x-font-afm.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-font-afm.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-font-bdf.png b/src/main/resources/images/papirus/mimetypes/application-x-font-bdf.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-font-bdf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-font-dos.png b/src/main/resources/images/papirus/mimetypes/application-x-font-dos.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-font-dos.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-font-framemaker.png b/src/main/resources/images/papirus/mimetypes/application-x-font-framemaker.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-font-framemaker.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-font-libgrx.png b/src/main/resources/images/papirus/mimetypes/application-x-font-libgrx.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-font-libgrx.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-font-linux-psf.png b/src/main/resources/images/papirus/mimetypes/application-x-font-linux-psf.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-font-linux-psf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-font-otf.png b/src/main/resources/images/papirus/mimetypes/application-x-font-otf.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-font-otf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-font-pcf.png b/src/main/resources/images/papirus/mimetypes/application-x-font-pcf.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-font-pcf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-font-snf.png b/src/main/resources/images/papirus/mimetypes/application-x-font-snf.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-font-snf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-font-speedo.png b/src/main/resources/images/papirus/mimetypes/application-x-font-speedo.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-font-speedo.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-font-sunos-news.png b/src/main/resources/images/papirus/mimetypes/application-x-font-sunos-news.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-font-sunos-news.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-font-tex-tfm.png b/src/main/resources/images/papirus/mimetypes/application-x-font-tex-tfm.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-font-tex-tfm.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-font-tex.png b/src/main/resources/images/papirus/mimetypes/application-x-font-tex.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-font-tex.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-font-ttf.png b/src/main/resources/images/papirus/mimetypes/application-x-font-ttf.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-font-ttf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-font-ttx.png b/src/main/resources/images/papirus/mimetypes/application-x-font-ttx.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-font-ttx.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-font-type1.png b/src/main/resources/images/papirus/mimetypes/application-x-font-type1.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-font-type1.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-font-vfont.png b/src/main/resources/images/papirus/mimetypes/application-x-font-vfont.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-font-vfont.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-fusioncomp.png b/src/main/resources/images/papirus/mimetypes/application-x-fusioncomp.png new file mode 100644 index 0000000..2d89db3 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-fusioncomp.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gambas3.png b/src/main/resources/images/papirus/mimetypes/application-x-gambas3.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gambas3.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gambasscript.png b/src/main/resources/images/papirus/mimetypes/application-x-gambasscript.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gambasscript.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gambasserverpage.png b/src/main/resources/images/papirus/mimetypes/application-x-gambasserverpage.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gambasserverpage.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gameboy-color-rom.png b/src/main/resources/images/papirus/mimetypes/application-x-gameboy-color-rom.png new file mode 100644 index 0000000..c8aa1a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gameboy-color-rom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gameboy-rom.png b/src/main/resources/images/papirus/mimetypes/application-x-gameboy-rom.png new file mode 100644 index 0000000..f554de0 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gameboy-rom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gamecube-rom.png b/src/main/resources/images/papirus/mimetypes/application-x-gamecube-rom.png new file mode 100644 index 0000000..23ab03c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gamecube-rom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gba-rom.png b/src/main/resources/images/papirus/mimetypes/application-x-gba-rom.png new file mode 100644 index 0000000..d9a3f1a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gba-rom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gcstar.png b/src/main/resources/images/papirus/mimetypes/application-x-gcstar.png new file mode 100644 index 0000000..a28aaf9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gcstar.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gdbm.png b/src/main/resources/images/papirus/mimetypes/application-x-gdbm.png new file mode 100644 index 0000000..7296d70 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gdbm.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gettext-translation.png b/src/main/resources/images/papirus/mimetypes/application-x-gettext-translation.png new file mode 100644 index 0000000..f0960ba Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gettext-translation.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-glabels.png b/src/main/resources/images/papirus/mimetypes/application-x-glabels.png new file mode 100644 index 0000000..d273c46 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-glabels.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-glade.png b/src/main/resources/images/papirus/mimetypes/application-x-glade.png new file mode 100644 index 0000000..7a8b36d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-glade.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gnonogram-puzzle.png b/src/main/resources/images/papirus/mimetypes/application-x-gnonogram-puzzle.png new file mode 100644 index 0000000..5928475 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gnonogram-puzzle.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gnumeric.png b/src/main/resources/images/papirus/mimetypes/application-x-gnumeric.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gnumeric.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-godot-project.png b/src/main/resources/images/papirus/mimetypes/application-x-godot-project.png new file mode 100644 index 0000000..ee82118 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-godot-project.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-goomod.png b/src/main/resources/images/papirus/mimetypes/application-x-goomod.png new file mode 100644 index 0000000..b1ba450 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-goomod.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gpx+xml.png b/src/main/resources/images/papirus/mimetypes/application-x-gpx+xml.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gpx+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gpx.png b/src/main/resources/images/papirus/mimetypes/application-x-gpx.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gpx.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-grsync-session.png b/src/main/resources/images/papirus/mimetypes/application-x-grsync-session.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-grsync-session.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gtktalog.png b/src/main/resources/images/papirus/mimetypes/application-x-gtktalog.png new file mode 100644 index 0000000..76c4570 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gtktalog.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gz-font-linux-psf.png b/src/main/resources/images/papirus/mimetypes/application-x-gz-font-linux-psf.png new file mode 100644 index 0000000..ad8e607 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gz-font-linux-psf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gzdvi.png b/src/main/resources/images/papirus/mimetypes/application-x-gzdvi.png new file mode 100644 index 0000000..ad8e607 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gzdvi.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gzip.png b/src/main/resources/images/papirus/mimetypes/application-x-gzip.png new file mode 100644 index 0000000..ad8e607 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gzip.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gzpdf.png b/src/main/resources/images/papirus/mimetypes/application-x-gzpdf.png new file mode 100644 index 0000000..9f33646 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gzpdf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-gzpostscript.png b/src/main/resources/images/papirus/mimetypes/application-x-gzpostscript.png new file mode 100644 index 0000000..297b207 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-gzpostscript.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-hda.png b/src/main/resources/images/papirus/mimetypes/application-x-hda.png new file mode 100644 index 0000000..f96723b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-hda.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-hdalc.png b/src/main/resources/images/papirus/mimetypes/application-x-hdalc.png new file mode 100644 index 0000000..f96723b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-hdalc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-hdanc.png b/src/main/resources/images/papirus/mimetypes/application-x-hdanc.png new file mode 100644 index 0000000..f96723b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-hdanc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-hip.png b/src/main/resources/images/papirus/mimetypes/application-x-hip.png new file mode 100644 index 0000000..a13f0ca Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-hip.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-hiplc.png b/src/main/resources/images/papirus/mimetypes/application-x-hiplc.png new file mode 100644 index 0000000..a13f0ca Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-hiplc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-hipnc.png b/src/main/resources/images/papirus/mimetypes/application-x-hipnc.png new file mode 100644 index 0000000..a13f0ca Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-hipnc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-homebank.png b/src/main/resources/images/papirus/mimetypes/application-x-homebank.png new file mode 100644 index 0000000..9c77132 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-homebank.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-icq.png b/src/main/resources/images/papirus/mimetypes/application-x-icq.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-icq.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-iff.png b/src/main/resources/images/papirus/mimetypes/application-x-iff.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-iff.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-ipod-firmware.png b/src/main/resources/images/papirus/mimetypes/application-x-ipod-firmware.png new file mode 100644 index 0000000..2635436 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-ipod-firmware.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-ips-patch.png b/src/main/resources/images/papirus/mimetypes/application-x-ips-patch.png new file mode 100644 index 0000000..ef2d241 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-ips-patch.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-iptrace.png b/src/main/resources/images/papirus/mimetypes/application-x-iptrace.png new file mode 100644 index 0000000..7c0708f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-iptrace.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-ipynb+json.png b/src/main/resources/images/papirus/mimetypes/application-x-ipynb+json.png new file mode 100644 index 0000000..27b6eee Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-ipynb+json.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-iso.png b/src/main/resources/images/papirus/mimetypes/application-x-iso.png new file mode 100644 index 0000000..3f7e9a0 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-iso.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-iso9660-appimage.png b/src/main/resources/images/papirus/mimetypes/application-x-iso9660-appimage.png new file mode 100644 index 0000000..2ceca8b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-iso9660-appimage.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-it87.png b/src/main/resources/images/papirus/mimetypes/application-x-it87.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-it87.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-jar.png b/src/main/resources/images/papirus/mimetypes/application-x-jar.png new file mode 100644 index 0000000..076dda1 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-jar.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-java-applet.png b/src/main/resources/images/papirus/mimetypes/application-x-java-applet.png new file mode 100644 index 0000000..b10e170 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-java-applet.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-java-archive.png b/src/main/resources/images/papirus/mimetypes/application-x-java-archive.png new file mode 100644 index 0000000..076dda1 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-java-archive.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-java.png b/src/main/resources/images/papirus/mimetypes/application-x-java.png new file mode 100644 index 0000000..b10e170 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-java.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-javascript.png b/src/main/resources/images/papirus/mimetypes/application-x-javascript.png new file mode 100644 index 0000000..3c0ab6c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-javascript.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-k3b.png b/src/main/resources/images/papirus/mimetypes/application-x-k3b.png new file mode 100644 index 0000000..3f7e9a0 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-k3b.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kcachegrind.png b/src/main/resources/images/papirus/mimetypes/application-x-kcachegrind.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kcachegrind.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kcsrc.png b/src/main/resources/images/papirus/mimetypes/application-x-kcsrc.png new file mode 100644 index 0000000..10d3650 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kcsrc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kdenlive.png b/src/main/resources/images/papirus/mimetypes/application-x-kdenlive.png new file mode 100644 index 0000000..178630b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kdenlive.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kdenlivetitle.png b/src/main/resources/images/papirus/mimetypes/application-x-kdenlivetitle.png new file mode 100644 index 0000000..178630b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kdenlivetitle.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-keepass.png b/src/main/resources/images/papirus/mimetypes/application-x-keepass.png new file mode 100644 index 0000000..f3ac1c7 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-keepass.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-keepass2.png b/src/main/resources/images/papirus/mimetypes/application-x-keepass2.png new file mode 100644 index 0000000..f3ac1c7 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-keepass2.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-keepassx.png b/src/main/resources/images/papirus/mimetypes/application-x-keepassx.png new file mode 100644 index 0000000..f3ac1c7 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-keepassx.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-keepassxc.png b/src/main/resources/images/papirus/mimetypes/application-x-keepassxc.png new file mode 100644 index 0000000..f3ac1c7 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-keepassxc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kexi-connectiondata.png b/src/main/resources/images/papirus/mimetypes/application-x-kexi-connectiondata.png new file mode 100644 index 0000000..f7f57e9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kexi-connectiondata.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kexiproject-shortcut.png b/src/main/resources/images/papirus/mimetypes/application-x-kexiproject-shortcut.png new file mode 100644 index 0000000..f7f57e9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kexiproject-shortcut.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kexiproject-sqlite2.png b/src/main/resources/images/papirus/mimetypes/application-x-kexiproject-sqlite2.png new file mode 100644 index 0000000..7296d70 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kexiproject-sqlite2.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kexiproject-sqlite3.png b/src/main/resources/images/papirus/mimetypes/application-x-kexiproject-sqlite3.png new file mode 100644 index 0000000..7296d70 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kexiproject-sqlite3.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kformula.png b/src/main/resources/images/papirus/mimetypes/application-x-kformula.png new file mode 100644 index 0000000..63c11ed Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kformula.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kgeo.png b/src/main/resources/images/papirus/mimetypes/application-x-kgeo.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kgeo.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kgetlist.png b/src/main/resources/images/papirus/mimetypes/application-x-kgetlist.png new file mode 100644 index 0000000..680a346 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kgetlist.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-khtml-adaptor.png b/src/main/resources/images/papirus/mimetypes/application-x-khtml-adaptor.png new file mode 100644 index 0000000..39ffd39 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-khtml-adaptor.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kicad-pcb.png b/src/main/resources/images/papirus/mimetypes/application-x-kicad-pcb.png new file mode 100644 index 0000000..ad036bd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kicad-pcb.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kicad-project.png b/src/main/resources/images/papirus/mimetypes/application-x-kicad-project.png new file mode 100644 index 0000000..1d7715d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kicad-project.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kicad-schematic.png b/src/main/resources/images/papirus/mimetypes/application-x-kicad-schematic.png new file mode 100644 index 0000000..b8bda43 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kicad-schematic.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kig.png b/src/main/resources/images/papirus/mimetypes/application-x-kig.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kig.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kmplot.png b/src/main/resources/images/papirus/mimetypes/application-x-kmplot.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kmplot.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kmymoney.png b/src/main/resources/images/papirus/mimetypes/application-x-kmymoney.png new file mode 100644 index 0000000..bb1b526 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kmymoney.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kns.png b/src/main/resources/images/papirus/mimetypes/application-x-kns.png new file mode 100644 index 0000000..ad8e607 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kns.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kodelife-project.png b/src/main/resources/images/papirus/mimetypes/application-x-kodelife-project.png new file mode 100644 index 0000000..8fd1a30 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kodelife-project.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kolf.png b/src/main/resources/images/papirus/mimetypes/application-x-kolf.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kolf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kommander.png b/src/main/resources/images/papirus/mimetypes/application-x-kommander.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kommander.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kontour.png b/src/main/resources/images/papirus/mimetypes/application-x-kontour.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kontour.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kontur.png b/src/main/resources/images/papirus/mimetypes/application-x-kontur.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kontur.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kopete-emoticons.png b/src/main/resources/images/papirus/mimetypes/application-x-kopete-emoticons.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kopete-emoticons.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kourse.png b/src/main/resources/images/papirus/mimetypes/application-x-kourse.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kourse.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kover.png b/src/main/resources/images/papirus/mimetypes/application-x-kover.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kover.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kpresenter.png b/src/main/resources/images/papirus/mimetypes/application-x-kpresenter.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kpresenter.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-krita-assistant.png b/src/main/resources/images/papirus/mimetypes/application-x-krita-assistant.png new file mode 100644 index 0000000..37caf61 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-krita-assistant.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-krita-paintoppresent.png b/src/main/resources/images/papirus/mimetypes/application-x-krita-paintoppresent.png new file mode 100644 index 0000000..37caf61 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-krita-paintoppresent.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-krita.png b/src/main/resources/images/papirus/mimetypes/application-x-krita.png new file mode 100644 index 0000000..37caf61 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-krita.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kseg.png b/src/main/resources/images/papirus/mimetypes/application-x-kseg.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kseg.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-ksysguard.png b/src/main/resources/images/papirus/mimetypes/application-x-ksysguard.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-ksysguard.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-ktheme.png b/src/main/resources/images/papirus/mimetypes/application-x-ktheme.png new file mode 100644 index 0000000..b8ee56f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-ktheme.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kudesigner.png b/src/main/resources/images/papirus/mimetypes/application-x-kudesigner.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kudesigner.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kva.png b/src/main/resources/images/papirus/mimetypes/application-x-kva.png new file mode 100644 index 0000000..39ffd39 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kva.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kvs.png b/src/main/resources/images/papirus/mimetypes/application-x-kvs.png new file mode 100644 index 0000000..47be445 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kvs.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kvtml.png b/src/main/resources/images/papirus/mimetypes/application-x-kvtml.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kvtml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kwallet.png b/src/main/resources/images/papirus/mimetypes/application-x-kwallet.png new file mode 100644 index 0000000..7c0708f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kwallet.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kword.png b/src/main/resources/images/papirus/mimetypes/application-x-kword.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kword.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-kwordquiz.png b/src/main/resources/images/papirus/mimetypes/application-x-kwordquiz.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-kwordquiz.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-lanalyzer.png b/src/main/resources/images/papirus/mimetypes/application-x-lanalyzer.png new file mode 100644 index 0000000..7c0708f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-lanalyzer.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-lha.png b/src/main/resources/images/papirus/mimetypes/application-x-lha.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-lha.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-lhz.png b/src/main/resources/images/papirus/mimetypes/application-x-lhz.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-lhz.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-linguist.png b/src/main/resources/images/papirus/mimetypes/application-x-linguist.png new file mode 100644 index 0000000..5f900d7 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-linguist.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-love-game.png b/src/main/resources/images/papirus/mimetypes/application-x-love-game.png new file mode 100644 index 0000000..4671abd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-love-game.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-lyx.png b/src/main/resources/images/papirus/mimetypes/application-x-lyx.png new file mode 100644 index 0000000..cf9ae97 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-lyx.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-lz4-compressed-tar.png b/src/main/resources/images/papirus/mimetypes/application-x-lz4-compressed-tar.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-lz4-compressed-tar.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-lzip-compressed-tar.png b/src/main/resources/images/papirus/mimetypes/application-x-lzip-compressed-tar.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-lzip-compressed-tar.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-lzma-compressed-tar.png b/src/main/resources/images/papirus/mimetypes/application-x-lzma-compressed-tar.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-lzma-compressed-tar.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-lzma.png b/src/main/resources/images/papirus/mimetypes/application-x-lzma.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-lzma.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-lzop.png b/src/main/resources/images/papirus/mimetypes/application-x-lzop.png new file mode 100644 index 0000000..ad8e607 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-lzop.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-lzpdf.png b/src/main/resources/images/papirus/mimetypes/application-x-lzpdf.png new file mode 100644 index 0000000..9f33646 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-lzpdf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-m4.png b/src/main/resources/images/papirus/mimetypes/application-x-m4.png new file mode 100644 index 0000000..41efa7f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-m4.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-macbinary.png b/src/main/resources/images/papirus/mimetypes/application-x-macbinary.png new file mode 100644 index 0000000..c2fabd4 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-macbinary.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-maff.png b/src/main/resources/images/papirus/mimetypes/application-x-maff.png new file mode 100644 index 0000000..466fe09 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-maff.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-matroska.png b/src/main/resources/images/papirus/mimetypes/application-x-matroska.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-matroska.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-mif.png b/src/main/resources/images/papirus/mimetypes/application-x-mif.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-mif.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-mimearchive.png b/src/main/resources/images/papirus/mimetypes/application-x-mimearchive.png new file mode 100644 index 0000000..466fe09 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-mimearchive.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-mobi8-ebook.png b/src/main/resources/images/papirus/mimetypes/application-x-mobi8-ebook.png new file mode 100644 index 0000000..a2c30fe Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-mobi8-ebook.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-mobipocket-ebook.png b/src/main/resources/images/papirus/mimetypes/application-x-mobipocket-ebook.png new file mode 100644 index 0000000..a2c30fe Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-mobipocket-ebook.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-ms-dos-executable.png b/src/main/resources/images/papirus/mimetypes/application-x-ms-dos-executable.png new file mode 100644 index 0000000..33c903a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-ms-dos-executable.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-ms-shortcut.png b/src/main/resources/images/papirus/mimetypes/application-x-ms-shortcut.png new file mode 100644 index 0000000..5361eea Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-ms-shortcut.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-ms-wim.png b/src/main/resources/images/papirus/mimetypes/application-x-ms-wim.png new file mode 100644 index 0000000..5361eea Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-ms-wim.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-msdos-program.png b/src/main/resources/images/papirus/mimetypes/application-x-msdos-program.png new file mode 100644 index 0000000..598e0d5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-msdos-program.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-msdownload.png b/src/main/resources/images/papirus/mimetypes/application-x-msdownload.png new file mode 100644 index 0000000..2635436 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-msdownload.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-msexcel.png b/src/main/resources/images/papirus/mimetypes/application-x-msexcel.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-msexcel.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-msi.png b/src/main/resources/images/papirus/mimetypes/application-x-msi.png new file mode 100644 index 0000000..5361eea Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-msi.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-mswinurl.png b/src/main/resources/images/papirus/mimetypes/application-x-mswinurl.png new file mode 100644 index 0000000..466fe09 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-mswinurl.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-mswrite.png b/src/main/resources/images/papirus/mimetypes/application-x-mswrite.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-mswrite.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-musescore+xml.png b/src/main/resources/images/papirus/mimetypes/application-x-musescore+xml.png new file mode 100644 index 0000000..66631d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-musescore+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-musescore.png b/src/main/resources/images/papirus/mimetypes/application-x-musescore.png new file mode 100644 index 0000000..66631d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-musescore.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-n64-rom.png b/src/main/resources/images/papirus/mimetypes/application-x-n64-rom.png new file mode 100644 index 0000000..083d988 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-n64-rom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-navi-animation.png b/src/main/resources/images/papirus/mimetypes/application-x-navi-animation.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-navi-animation.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-nes-rom.png b/src/main/resources/images/papirus/mimetypes/application-x-nes-rom.png new file mode 100644 index 0000000..b986f09 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-nes-rom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-netinstobserver.png b/src/main/resources/images/papirus/mimetypes/application-x-netinstobserver.png new file mode 100644 index 0000000..7c0708f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-netinstobserver.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-nettl.png b/src/main/resources/images/papirus/mimetypes/application-x-nettl.png new file mode 100644 index 0000000..7c0708f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-nettl.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-nintendo-3ds-executable.png b/src/main/resources/images/papirus/mimetypes/application-x-nintendo-3ds-executable.png new file mode 100644 index 0000000..edf9f5b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-nintendo-3ds-executable.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-nintendo-3ds-rom.png b/src/main/resources/images/papirus/mimetypes/application-x-nintendo-3ds-rom.png new file mode 100644 index 0000000..edf9f5b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-nintendo-3ds-rom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-nintendo-ds-rom.png b/src/main/resources/images/papirus/mimetypes/application-x-nintendo-ds-rom.png new file mode 100644 index 0000000..3489b39 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-nintendo-ds-rom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-nzb.png b/src/main/resources/images/papirus/mimetypes/application-x-nzb.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-nzb.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-object.png b/src/main/resources/images/papirus/mimetypes/application-x-object.png new file mode 100644 index 0000000..7c0708f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-object.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-openboardview-board.png b/src/main/resources/images/papirus/mimetypes/application-x-openboardview-board.png new file mode 100644 index 0000000..b4e2965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-openboardview-board.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-openboardview-brd-landrex.png b/src/main/resources/images/papirus/mimetypes/application-x-openboardview-brd-landrex.png new file mode 100644 index 0000000..b4e2965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-openboardview-brd-landrex.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-openboardview-brd-r4.png b/src/main/resources/images/papirus/mimetypes/application-x-openboardview-brd-r4.png new file mode 100644 index 0000000..b4e2965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-openboardview-brd-r4.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-openboardview-lst.png b/src/main/resources/images/papirus/mimetypes/application-x-openboardview-lst.png new file mode 100644 index 0000000..b4e2965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-openboardview-lst.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-osm+xml.png b/src/main/resources/images/papirus/mimetypes/application-x-osm+xml.png new file mode 100644 index 0000000..756f137 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-osm+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-pak.png b/src/main/resources/images/papirus/mimetypes/application-x-pak.png new file mode 100644 index 0000000..ad8e607 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-pak.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-partial-download.png b/src/main/resources/images/papirus/mimetypes/application-x-partial-download.png new file mode 100644 index 0000000..e546bde Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-partial-download.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-patch.png b/src/main/resources/images/papirus/mimetypes/application-x-patch.png new file mode 100644 index 0000000..ef2d241 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-patch.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-pc-engine-rom.png b/src/main/resources/images/papirus/mimetypes/application-x-pc-engine-rom.png new file mode 100644 index 0000000..29d7da3 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-pc-engine-rom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-pcapng.png b/src/main/resources/images/papirus/mimetypes/application-x-pcapng.png new file mode 100644 index 0000000..7c0708f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-pcapng.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-pem-file.png b/src/main/resources/images/papirus/mimetypes/application-x-pem-file.png new file mode 100644 index 0000000..822ad4b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-pem-file.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-pem-key.png b/src/main/resources/images/papirus/mimetypes/application-x-pem-key.png new file mode 100644 index 0000000..822ad4b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-pem-key.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-perl.png b/src/main/resources/images/papirus/mimetypes/application-x-perl.png new file mode 100644 index 0000000..48dbb51 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-perl.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-phatch.png b/src/main/resources/images/papirus/mimetypes/application-x-phatch.png new file mode 100644 index 0000000..4d5d8a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-phatch.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-php.png b/src/main/resources/images/papirus/mimetypes/application-x-php.png new file mode 100644 index 0000000..4d31252 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-php.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-pkcs12.png b/src/main/resources/images/papirus/mimetypes/application-x-pkcs12.png new file mode 100644 index 0000000..a6ed6e4 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-pkcs12.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-pkcs7-certificates.png b/src/main/resources/images/papirus/mimetypes/application-x-pkcs7-certificates.png new file mode 100644 index 0000000..a6ed6e4 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-pkcs7-certificates.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-planner.png b/src/main/resources/images/papirus/mimetypes/application-x-planner.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-planner.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-plasma.png b/src/main/resources/images/papirus/mimetypes/application-x-plasma.png new file mode 100644 index 0000000..b8ee56f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-plasma.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-project.png b/src/main/resources/images/papirus/mimetypes/application-x-project.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-project.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-ptoptimizer-script.png b/src/main/resources/images/papirus/mimetypes/application-x-ptoptimizer-script.png new file mode 100644 index 0000000..47be445 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-ptoptimizer-script.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-python-bytecode.png b/src/main/resources/images/papirus/mimetypes/application-x-python-bytecode.png new file mode 100644 index 0000000..5205d85 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-python-bytecode.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-qemu-disk.png b/src/main/resources/images/papirus/mimetypes/application-x-qemu-disk.png new file mode 100644 index 0000000..cae5e4b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-qemu-disk.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-quanta.png b/src/main/resources/images/papirus/mimetypes/application-x-quanta.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-quanta.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-quattropro.png b/src/main/resources/images/papirus/mimetypes/application-x-quattropro.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-quattropro.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-radcom.png b/src/main/resources/images/papirus/mimetypes/application-x-radcom.png new file mode 100644 index 0000000..7c0708f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-radcom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-rar.png b/src/main/resources/images/papirus/mimetypes/application-x-rar.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-rar.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-raw-disk-image-xz-compressed.png b/src/main/resources/images/papirus/mimetypes/application-x-raw-disk-image-xz-compressed.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-raw-disk-image-xz-compressed.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-raw-disk-image.png b/src/main/resources/images/papirus/mimetypes/application-x-raw-disk-image.png new file mode 100644 index 0000000..3f7e9a0 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-raw-disk-image.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-remote-connection.png b/src/main/resources/images/papirus/mimetypes/application-x-remote-connection.png new file mode 100644 index 0000000..3f8fa74 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-remote-connection.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-riff.png b/src/main/resources/images/papirus/mimetypes/application-x-riff.png new file mode 100644 index 0000000..2635436 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-riff.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-rpm.png b/src/main/resources/images/papirus/mimetypes/application-x-rpm.png new file mode 100644 index 0000000..5528449 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-rpm.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-rsdf-container.png b/src/main/resources/images/papirus/mimetypes/application-x-rsdf-container.png new file mode 100644 index 0000000..e546bde Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-rsdf-container.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-ruby.png b/src/main/resources/images/papirus/mimetypes/application-x-ruby.png new file mode 100644 index 0000000..5b4d897 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-ruby.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-sami.png b/src/main/resources/images/papirus/mimetypes/application-x-sami.png new file mode 100644 index 0000000..aea2fd5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-sami.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-sega-pico-rom.png b/src/main/resources/images/papirus/mimetypes/application-x-sega-pico-rom.png new file mode 100644 index 0000000..0ba66a3 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-sega-pico-rom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-shar.png b/src/main/resources/images/papirus/mimetypes/application-x-shar.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-shar.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-sharedlib.png b/src/main/resources/images/papirus/mimetypes/application-x-sharedlib.png new file mode 100644 index 0000000..2635436 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-sharedlib.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-shellscript.png b/src/main/resources/images/papirus/mimetypes/application-x-shellscript.png new file mode 100644 index 0000000..47be445 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-shellscript.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-shockwave-flash.png b/src/main/resources/images/papirus/mimetypes/application-x-shockwave-flash.png new file mode 100644 index 0000000..313cfb2 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-shockwave-flash.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-siag.png b/src/main/resources/images/papirus/mimetypes/application-x-siag.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-siag.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-smb-server.png b/src/main/resources/images/papirus/mimetypes/application-x-smb-server.png new file mode 100644 index 0000000..dfe3adc Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-smb-server.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-smb-workgroup.png b/src/main/resources/images/papirus/mimetypes/application-x-smb-workgroup.png new file mode 100644 index 0000000..dfe3adc Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-smb-workgroup.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-snoop.png b/src/main/resources/images/papirus/mimetypes/application-x-snoop.png new file mode 100644 index 0000000..7c0708f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-snoop.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-source-rpm.png b/src/main/resources/images/papirus/mimetypes/application-x-source-rpm.png new file mode 100644 index 0000000..9c49861 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-source-rpm.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-spkac+base64.png b/src/main/resources/images/papirus/mimetypes/application-x-spkac+base64.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-spkac+base64.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-spkac.png b/src/main/resources/images/papirus/mimetypes/application-x-spkac.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-spkac.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-spss-por.png b/src/main/resources/images/papirus/mimetypes/application-x-spss-por.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-spss-por.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-spss-sav.png b/src/main/resources/images/papirus/mimetypes/application-x-spss-sav.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-spss-sav.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-sqlite2.png b/src/main/resources/images/papirus/mimetypes/application-x-sqlite2.png new file mode 100644 index 0000000..7296d70 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-sqlite2.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-sqlite3.png b/src/main/resources/images/papirus/mimetypes/application-x-sqlite3.png new file mode 100644 index 0000000..7296d70 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-sqlite3.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-srt.png b/src/main/resources/images/papirus/mimetypes/application-x-srt.png new file mode 100644 index 0000000..aea2fd5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-srt.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-srtrip.png b/src/main/resources/images/papirus/mimetypes/application-x-srtrip.png new file mode 100644 index 0000000..aea2fd5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-srtrip.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-st-disk-image.png b/src/main/resources/images/papirus/mimetypes/application-x-st-disk-image.png new file mode 100644 index 0000000..10a07e8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-st-disk-image.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-stuffit.png b/src/main/resources/images/papirus/mimetypes/application-x-stuffit.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-stuffit.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-stx-disk-image.png b/src/main/resources/images/papirus/mimetypes/application-x-stx-disk-image.png new file mode 100644 index 0000000..10a07e8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-stx-disk-image.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-subrip.png b/src/main/resources/images/papirus/mimetypes/application-x-subrip.png new file mode 100644 index 0000000..aea2fd5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-subrip.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-superkaramba.png b/src/main/resources/images/papirus/mimetypes/application-x-superkaramba.png new file mode 100644 index 0000000..7726b56 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-superkaramba.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-tar.png b/src/main/resources/images/papirus/mimetypes/application-x-tar.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-tar.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-tarz.png b/src/main/resources/images/papirus/mimetypes/application-x-tarz.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-tarz.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-tektronix-rf5.png b/src/main/resources/images/papirus/mimetypes/application-x-tektronix-rf5.png new file mode 100644 index 0000000..7c0708f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-tektronix-rf5.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-tex-gf.png b/src/main/resources/images/papirus/mimetypes/application-x-tex-gf.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-tex-gf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-tex-pk.png b/src/main/resources/images/papirus/mimetypes/application-x-tex-pk.png new file mode 100644 index 0000000..ad8e607 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-tex-pk.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-texgzdvi.png b/src/main/resources/images/papirus/mimetypes/application-x-texgzdvi.png new file mode 100644 index 0000000..ad8e607 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-texgzdvi.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-tgif.png b/src/main/resources/images/papirus/mimetypes/application-x-tgif.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-tgif.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-theme.png b/src/main/resources/images/papirus/mimetypes/application-x-theme.png new file mode 100644 index 0000000..7726b56 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-theme.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-tiled.png b/src/main/resources/images/papirus/mimetypes/application-x-tiled.png new file mode 100644 index 0000000..3a6fb6b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-tiled.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-trash.png b/src/main/resources/images/papirus/mimetypes/application-x-trash.png new file mode 100644 index 0000000..bd3590b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-trash.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-trig.png b/src/main/resources/images/papirus/mimetypes/application-x-trig.png new file mode 100644 index 0000000..1bfca94 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-trig.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-troff-man.png b/src/main/resources/images/papirus/mimetypes/application-x-troff-man.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-troff-man.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-tuberling.png b/src/main/resources/images/papirus/mimetypes/application-x-tuberling.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-tuberling.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-turtle.png b/src/main/resources/images/papirus/mimetypes/application-x-turtle.png new file mode 100644 index 0000000..1bfca94 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-turtle.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-tzo.png b/src/main/resources/images/papirus/mimetypes/application-x-tzo.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-tzo.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-uml.png b/src/main/resources/images/papirus/mimetypes/application-x-uml.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-uml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vdi-disk.png b/src/main/resources/images/papirus/mimetypes/application-x-vdi-disk.png new file mode 100644 index 0000000..39f926f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vdi-disk.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vhd-disk.png b/src/main/resources/images/papirus/mimetypes/application-x-vhd-disk.png new file mode 100644 index 0000000..dd85852 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vhd-disk.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-virtual-boy-rom.png b/src/main/resources/images/papirus/mimetypes/application-x-virtual-boy-rom.png new file mode 100644 index 0000000..211f004 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-virtual-boy-rom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-hdd.png b/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-hdd.png new file mode 100644 index 0000000..7fdbf84 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-hdd.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-ova.png b/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-ova.png new file mode 100644 index 0000000..12ff8f8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-ova.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-ovf.png b/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-ovf.png new file mode 100644 index 0000000..fde1a14 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-ovf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-vbox-extpack.png b/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-vbox-extpack.png new file mode 100644 index 0000000..3126177 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-vbox-extpack.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-vbox.png b/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-vbox.png new file mode 100644 index 0000000..82ab47a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-vbox.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-vdi.png b/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-vdi.png new file mode 100644 index 0000000..39f926f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-vdi.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-vhd.png b/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-vhd.png new file mode 100644 index 0000000..dd85852 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-vhd.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-vmdk.png b/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-vmdk.png new file mode 100644 index 0000000..5a9d581 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-virtualbox-vmdk.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-visualnetworks.png b/src/main/resources/images/papirus/mimetypes/application-x-visualnetworks.png new file mode 100644 index 0000000..7c0708f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-visualnetworks.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vmdk-disk.png b/src/main/resources/images/papirus/mimetypes/application-x-vmdk-disk.png new file mode 100644 index 0000000..cae5e4b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vmdk-disk.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vmware-easter-egg.png b/src/main/resources/images/papirus/mimetypes/application-x-vmware-easter-egg.png new file mode 100644 index 0000000..05804b5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vmware-easter-egg.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vmware-snapshot.png b/src/main/resources/images/papirus/mimetypes/application-x-vmware-snapshot.png new file mode 100644 index 0000000..d500c22 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vmware-snapshot.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vmware-team.png b/src/main/resources/images/papirus/mimetypes/application-x-vmware-team.png new file mode 100644 index 0000000..f0cc8ae Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vmware-team.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vmware-vm-clone.png b/src/main/resources/images/papirus/mimetypes/application-x-vmware-vm-clone.png new file mode 100644 index 0000000..f68c64b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vmware-vm-clone.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vmware-vm-legacy.png b/src/main/resources/images/papirus/mimetypes/application-x-vmware-vm-legacy.png new file mode 100644 index 0000000..d0f7012 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vmware-vm-legacy.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vmware-vm.png b/src/main/resources/images/papirus/mimetypes/application-x-vmware-vm.png new file mode 100644 index 0000000..006d1c4 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vmware-vm.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vmware-vmdisk.png b/src/main/resources/images/papirus/mimetypes/application-x-vmware-vmdisk.png new file mode 100644 index 0000000..cae5e4b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vmware-vmdisk.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vmware-vmfoundry.png b/src/main/resources/images/papirus/mimetypes/application-x-vmware-vmfoundry.png new file mode 100644 index 0000000..8178146 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vmware-vmfoundry.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vnc.png b/src/main/resources/images/papirus/mimetypes/application-x-vnc.png new file mode 100644 index 0000000..3f8fa74 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vnc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vnd.akonadi.calendar.event.png b/src/main/resources/images/papirus/mimetypes/application-x-vnd.akonadi.calendar.event.png new file mode 100644 index 0000000..2622d42 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vnd.akonadi.calendar.event.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vnd.akonadi.calendar.freebusy.png b/src/main/resources/images/papirus/mimetypes/application-x-vnd.akonadi.calendar.freebusy.png new file mode 100644 index 0000000..2622d42 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vnd.akonadi.calendar.freebusy.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vnd.akonadi.calendar.journal.png b/src/main/resources/images/papirus/mimetypes/application-x-vnd.akonadi.calendar.journal.png new file mode 100644 index 0000000..2622d42 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vnd.akonadi.calendar.journal.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vnd.akonadi.calendar.todo.png b/src/main/resources/images/papirus/mimetypes/application-x-vnd.akonadi.calendar.todo.png new file mode 100644 index 0000000..2622d42 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vnd.akonadi.calendar.todo.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vnd.akonadi.collection.virtual.png b/src/main/resources/images/papirus/mimetypes/application-x-vnd.akonadi.collection.virtual.png new file mode 100644 index 0000000..2622d42 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vnd.akonadi.collection.virtual.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vnd.akonadi.note.png b/src/main/resources/images/papirus/mimetypes/application-x-vnd.akonadi.note.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vnd.akonadi.note.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.alarm.active.png b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.alarm.active.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.alarm.active.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.alarm.archived.png b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.alarm.archived.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.alarm.archived.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.alarm.png b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.alarm.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.alarm.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.alarm.template.png b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.alarm.template.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.alarm.template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.contactgroup.png b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.contactgroup.png new file mode 100644 index 0000000..080d1bd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.contactgroup.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.kplato.png b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.kplato.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.kplato.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.kplato.work.png b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.kplato.work.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.kplato.work.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.kugar.mixed.png b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.kugar.mixed.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.kugar.mixed.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.notes.png b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.notes.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.notes.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.plan.png b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.plan.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.plan.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.plan.work.png b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.plan.work.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-vnd.kde.plan.work.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-wbfs.png b/src/main/resources/images/papirus/mimetypes/application-x-wbfs.png new file mode 100644 index 0000000..156b043 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-wbfs.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-webarchive.png b/src/main/resources/images/papirus/mimetypes/application-x-webarchive.png new file mode 100644 index 0000000..466fe09 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-webarchive.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-wia.png b/src/main/resources/images/papirus/mimetypes/application-x-wia.png new file mode 100644 index 0000000..156b043 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-wia.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-wii-iso-image.png b/src/main/resources/images/papirus/mimetypes/application-x-wii-iso-image.png new file mode 100644 index 0000000..156b043 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-wii-iso-image.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-wii-rom.png b/src/main/resources/images/papirus/mimetypes/application-x-wii-rom.png new file mode 100644 index 0000000..156b043 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-wii-rom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-wii-wad.png b/src/main/resources/images/papirus/mimetypes/application-x-wii-wad.png new file mode 100644 index 0000000..ebff8aa Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-wii-wad.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-windows-themepack.png b/src/main/resources/images/papirus/mimetypes/application-x-windows-themepack.png new file mode 100644 index 0000000..7726b56 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-windows-themepack.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-wine-extension-cpl.png b/src/main/resources/images/papirus/mimetypes/application-x-wine-extension-cpl.png new file mode 100644 index 0000000..5361eea Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-wine-extension-cpl.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-wine-extension-inf.png b/src/main/resources/images/papirus/mimetypes/application-x-wine-extension-inf.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-wine-extension-inf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-wine-extension-its.png b/src/main/resources/images/papirus/mimetypes/application-x-wine-extension-its.png new file mode 100644 index 0000000..5361eea Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-wine-extension-its.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-wine-extension-msp.png b/src/main/resources/images/papirus/mimetypes/application-x-wine-extension-msp.png new file mode 100644 index 0000000..c748a8d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-wine-extension-msp.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-wine-extension-vbs.png b/src/main/resources/images/papirus/mimetypes/application-x-wine-extension-vbs.png new file mode 100644 index 0000000..5361eea Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-wine-extension-vbs.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-wonderswan-color-rom.png b/src/main/resources/images/papirus/mimetypes/application-x-wonderswan-color-rom.png new file mode 100644 index 0000000..7466a4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-wonderswan-color-rom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-wonderswan-rom.png b/src/main/resources/images/papirus/mimetypes/application-x-wonderswan-rom.png new file mode 100644 index 0000000..73dc2eb Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-wonderswan-rom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-world-of-goo-addin.png b/src/main/resources/images/papirus/mimetypes/application-x-world-of-goo-addin.png new file mode 100644 index 0000000..b1ba450 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-world-of-goo-addin.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-x509-ca-cert.png b/src/main/resources/images/papirus/mimetypes/application-x-x509-ca-cert.png new file mode 100644 index 0000000..a6ed6e4 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-x509-ca-cert.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-x509-user-cert.png b/src/main/resources/images/papirus/mimetypes/application-x-x509-user-cert.png new file mode 100644 index 0000000..a6ed6e4 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-x509-user-cert.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-xliff.png b/src/main/resources/images/papirus/mimetypes/application-x-xliff.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-xliff.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-xoj.png b/src/main/resources/images/papirus/mimetypes/application-x-xoj.png new file mode 100644 index 0000000..c2fabd4 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-xoj.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-xojpp.png b/src/main/resources/images/papirus/mimetypes/application-x-xojpp.png new file mode 100644 index 0000000..f185869 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-xojpp.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-xopp.png b/src/main/resources/images/papirus/mimetypes/application-x-xopp.png new file mode 100644 index 0000000..f185869 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-xopp.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-xopt.png b/src/main/resources/images/papirus/mimetypes/application-x-xopt.png new file mode 100644 index 0000000..f185869 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-xopt.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-xpinstall.png b/src/main/resources/images/papirus/mimetypes/application-x-xpinstall.png new file mode 100644 index 0000000..39ffd39 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-xpinstall.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-xz-compressed-tar.png b/src/main/resources/images/papirus/mimetypes/application-x-xz-compressed-tar.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-xz-compressed-tar.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-xz-pkg.png b/src/main/resources/images/papirus/mimetypes/application-x-xz-pkg.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-xz-pkg.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-xzpdf.png b/src/main/resources/images/papirus/mimetypes/application-x-xzpdf.png new file mode 100644 index 0000000..9f33646 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-xzpdf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-yaml.png b/src/main/resources/images/papirus/mimetypes/application-x-yaml.png new file mode 100644 index 0000000..a7888cd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-yaml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-yarock.png b/src/main/resources/images/papirus/mimetypes/application-x-yarock.png new file mode 100644 index 0000000..2581d49 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-yarock.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-zerosize.png b/src/main/resources/images/papirus/mimetypes/application-x-zerosize.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-zerosize.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-zip-compressed-fb2.png b/src/main/resources/images/papirus/mimetypes/application-x-zip-compressed-fb2.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-zip-compressed-fb2.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-zoo.png b/src/main/resources/images/papirus/mimetypes/application-x-zoo.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-zoo.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x-zoom.png b/src/main/resources/images/papirus/mimetypes/application-x-zoom.png new file mode 100644 index 0000000..3671aa1 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x-zoom.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x.allegorithmic.package+xml.png b/src/main/resources/images/papirus/mimetypes/application-x.allegorithmic.package+xml.png new file mode 100644 index 0000000..aa2a03d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x.allegorithmic.package+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x.allegorithmic.spp.png b/src/main/resources/images/papirus/mimetypes/application-x.allegorithmic.spp.png new file mode 100644 index 0000000..4daf4cd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x.allegorithmic.spp.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-x.allegorithmic.substance.png b/src/main/resources/images/papirus/mimetypes/application-x.allegorithmic.substance.png new file mode 100644 index 0000000..d2c94f9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-x.allegorithmic.substance.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-xhtml+xml.png b/src/main/resources/images/papirus/mimetypes/application-xhtml+xml.png new file mode 100644 index 0000000..466fe09 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-xhtml+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-xliff+xml.png b/src/main/resources/images/papirus/mimetypes/application-xliff+xml.png new file mode 100644 index 0000000..f0960ba Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-xliff+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-xml.png b/src/main/resources/images/papirus/mimetypes/application-xml.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-xsd.png b/src/main/resources/images/papirus/mimetypes/application-xsd.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-xsd.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-xslt+xml.png b/src/main/resources/images/papirus/mimetypes/application-xslt+xml.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-xslt+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-xspf+xml.png b/src/main/resources/images/papirus/mimetypes/application-xspf+xml.png new file mode 100644 index 0000000..76c4570 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-xspf+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/application-zip.png b/src/main/resources/images/papirus/mimetypes/application-zip.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/application-zip.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-ac3.png b/src/main/resources/images/papirus/mimetypes/audio-ac3.png new file mode 100644 index 0000000..9e9d3d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-ac3.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-flac.png b/src/main/resources/images/papirus/mimetypes/audio-flac.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-flac.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-m4a.png b/src/main/resources/images/papirus/mimetypes/audio-m4a.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-m4a.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-midi.png b/src/main/resources/images/papirus/mimetypes/audio-midi.png new file mode 100644 index 0000000..9e9d3d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-midi.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-mp2.png b/src/main/resources/images/papirus/mimetypes/audio-mp2.png new file mode 100644 index 0000000..9e9d3d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-mp2.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-mp3.png b/src/main/resources/images/papirus/mimetypes/audio-mp3.png new file mode 100644 index 0000000..9e9d3d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-mp3.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-mp4.png b/src/main/resources/images/papirus/mimetypes/audio-mp4.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-mp4.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-mpeg.png b/src/main/resources/images/papirus/mimetypes/audio-mpeg.png new file mode 100644 index 0000000..9e9d3d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-mpeg.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-prs.sid.png b/src/main/resources/images/papirus/mimetypes/audio-prs.sid.png new file mode 100644 index 0000000..9e9d3d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-prs.sid.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-shn.png b/src/main/resources/images/papirus/mimetypes/audio-shn.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-shn.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-vn.rn-realmedia.png b/src/main/resources/images/papirus/mimetypes/audio-vn.rn-realmedia.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-vn.rn-realmedia.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-vnd.rn-realvideo.png b/src/main/resources/images/papirus/mimetypes/audio-vnd.rn-realvideo.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-vnd.rn-realvideo.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-vnd.wave.png b/src/main/resources/images/papirus/mimetypes/audio-vnd.wave.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-vnd.wave.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-adpcm.png b/src/main/resources/images/papirus/mimetypes/audio-x-adpcm.png new file mode 100644 index 0000000..9e9d3d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-adpcm.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-aiff.png b/src/main/resources/images/papirus/mimetypes/audio-x-aiff.png new file mode 100644 index 0000000..9e9d3d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-aiff.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-caf.png b/src/main/resources/images/papirus/mimetypes/audio-x-caf.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-caf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-flac+ogg.png b/src/main/resources/images/papirus/mimetypes/audio-x-flac+ogg.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-flac+ogg.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-flac.png b/src/main/resources/images/papirus/mimetypes/audio-x-flac.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-flac.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-generic.png b/src/main/resources/images/papirus/mimetypes/audio-x-generic.png new file mode 100644 index 0000000..9e9d3d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-generic.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-m4a.png b/src/main/resources/images/papirus/mimetypes/audio-x-m4a.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-m4a.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-monkey.png b/src/main/resources/images/papirus/mimetypes/audio-x-monkey.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-monkey.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-monkeys-audio.png b/src/main/resources/images/papirus/mimetypes/audio-x-monkeys-audio.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-monkeys-audio.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-mp2.png b/src/main/resources/images/papirus/mimetypes/audio-x-mp2.png new file mode 100644 index 0000000..9e9d3d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-mp2.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-mp3-playlist.png b/src/main/resources/images/papirus/mimetypes/audio-x-mp3-playlist.png new file mode 100644 index 0000000..76c4570 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-mp3-playlist.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-mpeg.png b/src/main/resources/images/papirus/mimetypes/audio-x-mpeg.png new file mode 100644 index 0000000..9e9d3d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-mpeg.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-mpegurl.png b/src/main/resources/images/papirus/mimetypes/audio-x-mpegurl.png new file mode 100644 index 0000000..76c4570 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-mpegurl.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-ms-wax.png b/src/main/resources/images/papirus/mimetypes/audio-x-ms-wax.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-ms-wax.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-ms-wma.png b/src/main/resources/images/papirus/mimetypes/audio-x-ms-wma.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-ms-wma.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-ofr.png b/src/main/resources/images/papirus/mimetypes/audio-x-ofr.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-ofr.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-pn-realaudio.png b/src/main/resources/images/papirus/mimetypes/audio-x-pn-realaudio.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-pn-realaudio.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-scpls.png b/src/main/resources/images/papirus/mimetypes/audio-x-scpls.png new file mode 100644 index 0000000..76c4570 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-scpls.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-speex+ogg.png b/src/main/resources/images/papirus/mimetypes/audio-x-speex+ogg.png new file mode 100644 index 0000000..9e9d3d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-speex+ogg.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-tta.png b/src/main/resources/images/papirus/mimetypes/audio-x-tta.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-tta.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-vorbis+ogg.png b/src/main/resources/images/papirus/mimetypes/audio-x-vorbis+ogg.png new file mode 100644 index 0000000..9e9d3d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-vorbis+ogg.png differ diff --git a/src/main/resources/images/papirus/mimetypes/audio-x-wav.png b/src/main/resources/images/papirus/mimetypes/audio-x-wav.png new file mode 100644 index 0000000..d32b591 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/audio-x-wav.png differ diff --git a/src/main/resources/images/papirus/mimetypes/djvu.png b/src/main/resources/images/papirus/mimetypes/djvu.png new file mode 100644 index 0000000..fb9427b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/djvu.png differ diff --git a/src/main/resources/images/papirus/mimetypes/drawing-dwg.png b/src/main/resources/images/papirus/mimetypes/drawing-dwg.png new file mode 100644 index 0000000..087397b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/drawing-dwg.png differ diff --git a/src/main/resources/images/papirus/mimetypes/font-collection.png b/src/main/resources/images/papirus/mimetypes/font-collection.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/font-collection.png differ diff --git a/src/main/resources/images/papirus/mimetypes/font-otf.png b/src/main/resources/images/papirus/mimetypes/font-otf.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/font-otf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/font-ttf.png b/src/main/resources/images/papirus/mimetypes/font-ttf.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/font-ttf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/font-woff.png b/src/main/resources/images/papirus/mimetypes/font-woff.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/font-woff.png differ diff --git a/src/main/resources/images/papirus/mimetypes/font-woff2.png b/src/main/resources/images/papirus/mimetypes/font-woff2.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/font-woff2.png differ diff --git a/src/main/resources/images/papirus/mimetypes/font-x-generic.png b/src/main/resources/images/papirus/mimetypes/font-x-generic.png new file mode 100644 index 0000000..dccea0b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/font-x-generic.png differ diff --git a/src/main/resources/images/papirus/mimetypes/fonts-package.png b/src/main/resources/images/papirus/mimetypes/fonts-package.png new file mode 100644 index 0000000..b34cf38 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/fonts-package.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-fs-regular.png b/src/main/resources/images/papirus/mimetypes/gnome-fs-regular.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-fs-regular.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.openxmlformats-officedocument.presentationml.slideshow.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.openxmlformats-officedocument.presentationml.slideshow.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.openxmlformats-officedocument.presentationml.slideshow.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.rn-realmedia-secure.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.rn-realmedia-secure.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.rn-realmedia-secure.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.rn-realmedia-vbr.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.rn-realmedia-vbr.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.rn-realmedia-vbr.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.rn-realmedia.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.rn-realmedia.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.rn-realmedia.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.wolfram.cdf.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.wolfram.cdf.png new file mode 100644 index 0000000..b71c929 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.wolfram.cdf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.wolfram.mathematica.package.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.wolfram.mathematica.package.png new file mode 100644 index 0000000..ee1632f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.wolfram.mathematica.package.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.wolfram.nb.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.wolfram.nb.png new file mode 100644 index 0000000..6ec4117 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.wolfram.nb.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.wolfram.player.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.wolfram.player.png new file mode 100644 index 0000000..b71c929 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.wolfram.player.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.wolfram.wl.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.wolfram.wl.png new file mode 100644 index 0000000..ee1632f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.wolfram.wl.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.wolfram.wls.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.wolfram.wls.png new file mode 100644 index 0000000..ee1632f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-vnd.wolfram.wls.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-deb.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-deb.png new file mode 100644 index 0000000..c73e56d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-deb.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-killustrator.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-killustrator.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-killustrator.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-lhz.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-lhz.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-lhz.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-nero-disc-image.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-nero-disc-image.png new file mode 100644 index 0000000..3f7e9a0 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-nero-disc-image.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-nero-linux-compilation.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-nero-linux-compilation.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-nero-linux-compilation.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-referencer.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-referencer.png new file mode 100644 index 0000000..8bf527d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-referencer.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-remote-connection.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-remote-connection.png new file mode 100644 index 0000000..3f8fa74 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-remote-connection.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-shockwave-flash.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-shockwave-flash.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-shockwave-flash.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-vnc.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-vnc.png new file mode 100644 index 0000000..3f8fa74 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-vnc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-xoj.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-xoj.png new file mode 100644 index 0000000..c2fabd4 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-xoj.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-xopp.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-xopp.png new file mode 100644 index 0000000..f185869 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-xopp.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-xopt.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-xopt.png new file mode 100644 index 0000000..f185869 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-application-x-xopt.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-image-x-cmu-raster.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-image-x-cmu-raster.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-image-x-cmu-raster.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-image-x-xpixmap.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-image-x-xpixmap.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-image-x-xpixmap.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-image.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-image.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-image.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-text-vnd.wap.wml.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-text-vnd.wap.wml.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-text-vnd.wap.wml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-text-x-vcalendar.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-text-x-vcalendar.png new file mode 100644 index 0000000..2622d42 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-text-x-vcalendar.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-video-x-ms-asf.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-video-x-ms-asf.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-video-x-ms-asf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-video-x-ms-wmv.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-video-x-ms-wmv.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-video-x-ms-wmv.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-mime-video.png b/src/main/resources/images/papirus/mimetypes/gnome-mime-video.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-mime-video.png differ diff --git a/src/main/resources/images/papirus/mimetypes/gnome-unknown.png b/src/main/resources/images/papirus/mimetypes/gnome-unknown.png new file mode 100644 index 0000000..586fc44 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/gnome-unknown.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-bmp.png b/src/main/resources/images/papirus/mimetypes/image-bmp.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-bmp.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-gif.png b/src/main/resources/images/papirus/mimetypes/image-gif.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-gif.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-jpeg.png b/src/main/resources/images/papirus/mimetypes/image-jpeg.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-jpeg.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-png.png b/src/main/resources/images/papirus/mimetypes/image-png.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-png.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-svg+xml-compressed.png b/src/main/resources/images/papirus/mimetypes/image-svg+xml-compressed.png new file mode 100644 index 0000000..7d463f1 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-svg+xml-compressed.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-svg+xml.png b/src/main/resources/images/papirus/mimetypes/image-svg+xml.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-svg+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-tiff.png b/src/main/resources/images/papirus/mimetypes/image-tiff.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-tiff.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-vnd.adobe.photoshop.png b/src/main/resources/images/papirus/mimetypes/image-vnd.adobe.photoshop.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-vnd.adobe.photoshop.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-vnd.djvu.png b/src/main/resources/images/papirus/mimetypes/image-vnd.djvu.png new file mode 100644 index 0000000..fb9427b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-vnd.djvu.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-vnd.dwg.png b/src/main/resources/images/papirus/mimetypes/image-vnd.dwg.png new file mode 100644 index 0000000..087397b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-vnd.dwg.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-vnd.dxf.png b/src/main/resources/images/papirus/mimetypes/image-vnd.dxf.png new file mode 100644 index 0000000..c22950f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-vnd.dxf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-vnd.microsoft.icon.png b/src/main/resources/images/papirus/mimetypes/image-vnd.microsoft.icon.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-vnd.microsoft.icon.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-x-3ds.png b/src/main/resources/images/papirus/mimetypes/image-x-3ds.png new file mode 100644 index 0000000..d214839 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-x-3ds.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-x-adobe-dng.png b/src/main/resources/images/papirus/mimetypes/image-x-adobe-dng.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-x-adobe-dng.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-x-compressed-xcf.png b/src/main/resources/images/papirus/mimetypes/image-x-compressed-xcf.png new file mode 100644 index 0000000..f4ad00e Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-x-compressed-xcf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-x-djvu.png b/src/main/resources/images/papirus/mimetypes/image-x-djvu.png new file mode 100644 index 0000000..fb9427b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-x-djvu.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-x-dwg.png b/src/main/resources/images/papirus/mimetypes/image-x-dwg.png new file mode 100644 index 0000000..087397b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-x-dwg.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-x-emf.png b/src/main/resources/images/papirus/mimetypes/image-x-emf.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-x-emf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-x-eps.png b/src/main/resources/images/papirus/mimetypes/image-x-eps.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-x-eps.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-x-generic.png b/src/main/resources/images/papirus/mimetypes/image-x-generic.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-x-generic.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-x-krita.png b/src/main/resources/images/papirus/mimetypes/image-x-krita.png new file mode 100644 index 0000000..37caf61 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-x-krita.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-x-portable-bitmap.png b/src/main/resources/images/papirus/mimetypes/image-x-portable-bitmap.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-x-portable-bitmap.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-x-svg+xml.png b/src/main/resources/images/papirus/mimetypes/image-x-svg+xml.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-x-svg+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-x-tga.png b/src/main/resources/images/papirus/mimetypes/image-x-tga.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-x-tga.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-x-win-bitmap.png b/src/main/resources/images/papirus/mimetypes/image-x-win-bitmap.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-x-win-bitmap.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-x-wmf.png b/src/main/resources/images/papirus/mimetypes/image-x-wmf.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-x-wmf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-x-xcf.png b/src/main/resources/images/papirus/mimetypes/image-x-xcf.png new file mode 100644 index 0000000..f4ad00e Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-x-xcf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image-x-xfig.png b/src/main/resources/images/papirus/mimetypes/image-x-xfig.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image-x-xfig.png differ diff --git a/src/main/resources/images/papirus/mimetypes/image.png b/src/main/resources/images/papirus/mimetypes/image.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/image.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-blockdevice.png b/src/main/resources/images/papirus/mimetypes/inode-blockdevice.png new file mode 100644 index 0000000..b12aec9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-blockdevice.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-chardevice.png b/src/main/resources/images/papirus/mimetypes/inode-chardevice.png new file mode 100644 index 0000000..f2bcfa0 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-chardevice.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-fifo.png b/src/main/resources/images/papirus/mimetypes/inode-fifo.png new file mode 100644 index 0000000..784144d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-fifo.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-mount-point.png b/src/main/resources/images/papirus/mimetypes/inode-mount-point.png new file mode 100644 index 0000000..a6ad769 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-mount-point.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-socket.png b/src/main/resources/images/papirus/mimetypes/inode-socket.png new file mode 100644 index 0000000..55231ee Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-socket.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-symlink.png b/src/main/resources/images/papirus/mimetypes/inode-symlink.png new file mode 100644 index 0000000..3c847e0 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-symlink.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.imap.png b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.imap.png new file mode 100644 index 0000000..c748a8d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.imap.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.kbattleship.png b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.kbattleship.png new file mode 100644 index 0000000..c748a8d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.kbattleship.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.ntp.png b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.ntp.png new file mode 100644 index 0000000..c748a8d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.ntp.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.pop3.png b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.pop3.png new file mode 100644 index 0000000..c748a8d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.pop3.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.unknown.png b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.unknown.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.unknown.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.HVAC1.png b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.HVAC1.png new file mode 100644 index 0000000..c748a8d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.HVAC1.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.LightingControls1.png b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.LightingControls1.png new file mode 100644 index 0000000..c748a8d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.LightingControls1.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.RAClient1.png b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.RAClient1.png new file mode 100644 index 0000000..c748a8d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.RAClient1.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.RADiscoveryAgent1.png b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.RADiscoveryAgent1.png new file mode 100644 index 0000000..c748a8d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.RADiscoveryAgent1.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.RAServer1.png b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.RAServer1.png new file mode 100644 index 0000000..c748a8d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.RAServer1.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.RemoteUIClientDevice1.png b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.RemoteUIClientDevice1.png new file mode 100644 index 0000000..c748a8d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.RemoteUIClientDevice1.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.RemoteUIServerDevice1.png b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.RemoteUIServerDevice1.png new file mode 100644 index 0000000..c748a8d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.RemoteUIServerDevice1.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.SolarProtectionBlind1.png b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.SolarProtectionBlind1.png new file mode 100644 index 0000000..c748a8d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.SolarProtectionBlind1.png differ diff --git a/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.Unknown.png b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.Unknown.png new file mode 100644 index 0000000..7d1f965 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/inode-vnd.kde.service.upnp.Unknown.png differ diff --git a/src/main/resources/images/papirus/mimetypes/javascript.png b/src/main/resources/images/papirus/mimetypes/javascript.png new file mode 100644 index 0000000..3c0ab6c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/javascript.png differ diff --git a/src/main/resources/images/papirus/mimetypes/jd-container.png b/src/main/resources/images/papirus/mimetypes/jd-container.png new file mode 100644 index 0000000..e546bde Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/jd-container.png differ diff --git a/src/main/resources/images/papirus/mimetypes/media-audio.png b/src/main/resources/images/papirus/mimetypes/media-audio.png new file mode 100644 index 0000000..9e9d3d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/media-audio.png differ diff --git a/src/main/resources/images/papirus/mimetypes/media-image.png b/src/main/resources/images/papirus/mimetypes/media-image.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/media-image.png differ diff --git a/src/main/resources/images/papirus/mimetypes/media-video.png b/src/main/resources/images/papirus/mimetypes/media-video.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/media-video.png differ diff --git a/src/main/resources/images/papirus/mimetypes/message-news.png b/src/main/resources/images/papirus/mimetypes/message-news.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/message-news.png differ diff --git a/src/main/resources/images/papirus/mimetypes/message-partial.png b/src/main/resources/images/papirus/mimetypes/message-partial.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/message-partial.png differ diff --git a/src/main/resources/images/papirus/mimetypes/message-rfc822.png b/src/main/resources/images/papirus/mimetypes/message-rfc822.png new file mode 100644 index 0000000..e75dd0c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/message-rfc822.png differ diff --git a/src/main/resources/images/papirus/mimetypes/message-x-gnu-rmail.png b/src/main/resources/images/papirus/mimetypes/message-x-gnu-rmail.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/message-x-gnu-rmail.png differ diff --git a/src/main/resources/images/papirus/mimetypes/model-stl.png b/src/main/resources/images/papirus/mimetypes/model-stl.png new file mode 100644 index 0000000..bc5c85f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/model-stl.png differ diff --git a/src/main/resources/images/papirus/mimetypes/multipart-alternative.png b/src/main/resources/images/papirus/mimetypes/multipart-alternative.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/multipart-alternative.png differ diff --git a/src/main/resources/images/papirus/mimetypes/multipart-appledouble.png b/src/main/resources/images/papirus/mimetypes/multipart-appledouble.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/multipart-appledouble.png differ diff --git a/src/main/resources/images/papirus/mimetypes/multipart-digest.png b/src/main/resources/images/papirus/mimetypes/multipart-digest.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/multipart-digest.png differ diff --git a/src/main/resources/images/papirus/mimetypes/multipart-encrypted.png b/src/main/resources/images/papirus/mimetypes/multipart-encrypted.png new file mode 100644 index 0000000..f3ac1c7 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/multipart-encrypted.png differ diff --git a/src/main/resources/images/papirus/mimetypes/multipart-mixed.png b/src/main/resources/images/papirus/mimetypes/multipart-mixed.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/multipart-mixed.png differ diff --git a/src/main/resources/images/papirus/mimetypes/multipart-related.png b/src/main/resources/images/papirus/mimetypes/multipart-related.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/multipart-related.png differ diff --git a/src/main/resources/images/papirus/mimetypes/multipart-report.png b/src/main/resources/images/papirus/mimetypes/multipart-report.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/multipart-report.png differ diff --git a/src/main/resources/images/papirus/mimetypes/multipart-signed.png b/src/main/resources/images/papirus/mimetypes/multipart-signed.png new file mode 100644 index 0000000..822ad4b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/multipart-signed.png differ diff --git a/src/main/resources/images/papirus/mimetypes/multipart-x-mixed-replace.png b/src/main/resources/images/papirus/mimetypes/multipart-x-mixed-replace.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/multipart-x-mixed-replace.png differ diff --git a/src/main/resources/images/papirus/mimetypes/nero-disc-image.png b/src/main/resources/images/papirus/mimetypes/nero-disc-image.png new file mode 100644 index 0000000..3f7e9a0 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/nero-disc-image.png differ diff --git a/src/main/resources/images/papirus/mimetypes/nero-linux-compilation.png b/src/main/resources/images/papirus/mimetypes/nero-linux-compilation.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/nero-linux-compilation.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-database.png b/src/main/resources/images/papirus/mimetypes/openoffice4-database.png new file mode 100644 index 0000000..f7f57e9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-database.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-drawing-template.png b/src/main/resources/images/papirus/mimetypes/openoffice4-drawing-template.png new file mode 100644 index 0000000..1e04031 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-drawing-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-drawing.png b/src/main/resources/images/papirus/mimetypes/openoffice4-drawing.png new file mode 100644 index 0000000..1e04031 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-drawing.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-extension.png b/src/main/resources/images/papirus/mimetypes/openoffice4-extension.png new file mode 100644 index 0000000..39ffd39 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-extension.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-formula.png b/src/main/resources/images/papirus/mimetypes/openoffice4-formula.png new file mode 100644 index 0000000..63c11ed Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-formula.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-master-document.png b/src/main/resources/images/papirus/mimetypes/openoffice4-master-document.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-master-document.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-database.png b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-database.png new file mode 100644 index 0000000..f7f57e9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-database.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-drawing-template.png b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-drawing-template.png new file mode 100644 index 0000000..1e04031 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-drawing-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-drawing.png b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-drawing.png new file mode 100644 index 0000000..1e04031 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-drawing.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-formula.png b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-formula.png new file mode 100644 index 0000000..63c11ed Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-formula.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-master-document.png b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-master-document.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-master-document.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-presentation-template.png b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-presentation-template.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-presentation-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-presentation.png b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-presentation.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-presentation.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-spreadsheet-template.png b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-spreadsheet-template.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-spreadsheet-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-spreadsheet.png b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-spreadsheet.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-spreadsheet.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-text-template.png b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-text-template.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-text-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-text.png b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-text.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-text.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-web-template.png b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-web-template.png new file mode 100644 index 0000000..466fe09 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-oasis-web-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-presentation-template.png b/src/main/resources/images/papirus/mimetypes/openoffice4-presentation-template.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-presentation-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-presentation.png b/src/main/resources/images/papirus/mimetypes/openoffice4-presentation.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-presentation.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-spreadsheet-template.png b/src/main/resources/images/papirus/mimetypes/openoffice4-spreadsheet-template.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-spreadsheet-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-spreadsheet.png b/src/main/resources/images/papirus/mimetypes/openoffice4-spreadsheet.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-spreadsheet.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-text-template.png b/src/main/resources/images/papirus/mimetypes/openoffice4-text-template.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-text-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/openoffice4-text.png b/src/main/resources/images/papirus/mimetypes/openoffice4-text.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/openoffice4-text.png differ diff --git a/src/main/resources/images/papirus/mimetypes/package-x-generic.png b/src/main/resources/images/papirus/mimetypes/package-x-generic.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/package-x-generic.png differ diff --git a/src/main/resources/images/papirus/mimetypes/pgmodeler-dbm.png b/src/main/resources/images/papirus/mimetypes/pgmodeler-dbm.png new file mode 100644 index 0000000..417c11a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/pgmodeler-dbm.png differ diff --git a/src/main/resources/images/papirus/mimetypes/playlist.png b/src/main/resources/images/papirus/mimetypes/playlist.png new file mode 100644 index 0000000..76c4570 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/playlist.png differ diff --git a/src/main/resources/images/papirus/mimetypes/qgis-asc.png b/src/main/resources/images/papirus/mimetypes/qgis-asc.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/qgis-asc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/qgis-ddf.png b/src/main/resources/images/papirus/mimetypes/qgis-ddf.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/qgis-ddf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/qgis-dem.png b/src/main/resources/images/papirus/mimetypes/qgis-dem.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/qgis-dem.png differ diff --git a/src/main/resources/images/papirus/mimetypes/qgis-dt0.png b/src/main/resources/images/papirus/mimetypes/qgis-dt0.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/qgis-dt0.png differ diff --git a/src/main/resources/images/papirus/mimetypes/qgis-dxf.png b/src/main/resources/images/papirus/mimetypes/qgis-dxf.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/qgis-dxf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/qgis-gml.png b/src/main/resources/images/papirus/mimetypes/qgis-gml.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/qgis-gml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/qgis-img.png b/src/main/resources/images/papirus/mimetypes/qgis-img.png new file mode 100644 index 0000000..2e7d59a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/qgis-img.png differ diff --git a/src/main/resources/images/papirus/mimetypes/qgis-mldata.png b/src/main/resources/images/papirus/mimetypes/qgis-mldata.png new file mode 100644 index 0000000..7c0708f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/qgis-mldata.png differ diff --git a/src/main/resources/images/papirus/mimetypes/qgis-qgs.png b/src/main/resources/images/papirus/mimetypes/qgis-qgs.png new file mode 100644 index 0000000..d495f1a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/qgis-qgs.png differ diff --git a/src/main/resources/images/papirus/mimetypes/qgis-qlr.png b/src/main/resources/images/papirus/mimetypes/qgis-qlr.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/qgis-qlr.png differ diff --git a/src/main/resources/images/papirus/mimetypes/qgis-qml.png b/src/main/resources/images/papirus/mimetypes/qgis-qml.png new file mode 100644 index 0000000..92b8815 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/qgis-qml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/qgis-qpt.png b/src/main/resources/images/papirus/mimetypes/qgis-qpt.png new file mode 100644 index 0000000..008d117 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/qgis-qpt.png differ diff --git a/src/main/resources/images/papirus/mimetypes/qgis-shp.png b/src/main/resources/images/papirus/mimetypes/qgis-shp.png new file mode 100644 index 0000000..b7f49a8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/qgis-shp.png differ diff --git a/src/main/resources/images/papirus/mimetypes/qgis-sqlite.png b/src/main/resources/images/papirus/mimetypes/qgis-sqlite.png new file mode 100644 index 0000000..7296d70 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/qgis-sqlite.png differ diff --git a/src/main/resources/images/papirus/mimetypes/rpm.png b/src/main/resources/images/papirus/mimetypes/rpm.png new file mode 100644 index 0000000..5528449 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/rpm.png differ diff --git a/src/main/resources/images/papirus/mimetypes/sound.png b/src/main/resources/images/papirus/mimetypes/sound.png new file mode 100644 index 0000000..9e9d3d9 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/sound.png differ diff --git a/src/main/resources/images/papirus/mimetypes/source-playlist.png b/src/main/resources/images/papirus/mimetypes/source-playlist.png new file mode 100644 index 0000000..76c4570 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/source-playlist.png differ diff --git a/src/main/resources/images/papirus/mimetypes/source-smart-playlist.png b/src/main/resources/images/papirus/mimetypes/source-smart-playlist.png new file mode 100644 index 0000000..76c4570 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/source-smart-playlist.png differ diff --git a/src/main/resources/images/papirus/mimetypes/stock_unknown.png b/src/main/resources/images/papirus/mimetypes/stock_unknown.png new file mode 100644 index 0000000..586fc44 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/stock_unknown.png differ diff --git a/src/main/resources/images/papirus/mimetypes/tar.png b/src/main/resources/images/papirus/mimetypes/tar.png new file mode 100644 index 0000000..8785e4d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/tar.png differ diff --git a/src/main/resources/images/papirus/mimetypes/template_source.png b/src/main/resources/images/papirus/mimetypes/template_source.png new file mode 100644 index 0000000..5c58e23 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/template_source.png differ diff --git a/src/main/resources/images/papirus/mimetypes/tex-x-nim-project.png b/src/main/resources/images/papirus/mimetypes/tex-x-nim-project.png new file mode 100644 index 0000000..848af2f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/tex-x-nim-project.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-calendar.png b/src/main/resources/images/papirus/mimetypes/text-calendar.png new file mode 100644 index 0000000..2622d42 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-calendar.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-csharp.png b/src/main/resources/images/papirus/mimetypes/text-csharp.png new file mode 100644 index 0000000..547580d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-csharp.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-css.png b/src/main/resources/images/papirus/mimetypes/text-css.png new file mode 100644 index 0000000..1a2a17b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-css.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-csv.png b/src/main/resources/images/papirus/mimetypes/text-csv.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-csv.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-enriched.png b/src/main/resources/images/papirus/mimetypes/text-enriched.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-enriched.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-html.png b/src/main/resources/images/papirus/mimetypes/text-html.png new file mode 100644 index 0000000..466fe09 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-html.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-markdown.png b/src/main/resources/images/papirus/mimetypes/text-markdown.png new file mode 100644 index 0000000..50572e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-markdown.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-n3.png b/src/main/resources/images/papirus/mimetypes/text-n3.png new file mode 100644 index 0000000..1bfca94 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-n3.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-org.png b/src/main/resources/images/papirus/mimetypes/text-org.png new file mode 100644 index 0000000..92e7f71 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-org.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-plain.png b/src/main/resources/images/papirus/mimetypes/text-plain.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-plain.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-r.png b/src/main/resources/images/papirus/mimetypes/text-r.png new file mode 100644 index 0000000..190f5fa Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-r.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-rdf+xml.png b/src/main/resources/images/papirus/mimetypes/text-rdf+xml.png new file mode 100644 index 0000000..1bfca94 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-rdf+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-rdf.png b/src/main/resources/images/papirus/mimetypes/text-rdf.png new file mode 100644 index 0000000..1bfca94 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-rdf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-richtext.png b/src/main/resources/images/papirus/mimetypes/text-richtext.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-richtext.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-rust.png b/src/main/resources/images/papirus/mimetypes/text-rust.png new file mode 100644 index 0000000..5d63de3 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-rust.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-sgml.png b/src/main/resources/images/papirus/mimetypes/text-sgml.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-sgml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-spreadsheet.png b/src/main/resources/images/papirus/mimetypes/text-spreadsheet.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-spreadsheet.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-tab-separated-values.png b/src/main/resources/images/papirus/mimetypes/text-tab-separated-values.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-tab-separated-values.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-troff.png b/src/main/resources/images/papirus/mimetypes/text-troff.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-troff.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-turtle.png b/src/main/resources/images/papirus/mimetypes/text-turtle.png new file mode 100644 index 0000000..1bfca94 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-turtle.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-vbscript.png b/src/main/resources/images/papirus/mimetypes/text-vbscript.png new file mode 100644 index 0000000..f84b3e0 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-vbscript.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-vcalendar.png b/src/main/resources/images/papirus/mimetypes/text-vcalendar.png new file mode 100644 index 0000000..2622d42 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-vcalendar.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-vcard.png b/src/main/resources/images/papirus/mimetypes/text-vcard.png new file mode 100644 index 0000000..1ae25aa Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-vcard.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-vnd-wap-wml.png b/src/main/resources/images/papirus/mimetypes/text-vnd-wap-wml.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-vnd-wap-wml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-vnd.abc.png b/src/main/resources/images/papirus/mimetypes/text-vnd.abc.png new file mode 100644 index 0000000..9c8d28a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-vnd.abc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-vnd.qt.linguist.png b/src/main/resources/images/papirus/mimetypes/text-vnd.qt.linguist.png new file mode 100644 index 0000000..5f900d7 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-vnd.qt.linguist.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-vnd.rn-realtext.png b/src/main/resources/images/papirus/mimetypes/text-vnd.rn-realtext.png new file mode 100644 index 0000000..aea2fd5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-vnd.rn-realtext.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-vnd.trolltech.linguist.png b/src/main/resources/images/papirus/mimetypes/text-vnd.trolltech.linguist.png new file mode 100644 index 0000000..5f900d7 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-vnd.trolltech.linguist.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-vnd.wap.wml.png b/src/main/resources/images/papirus/mimetypes/text-vnd.wap.wml.png new file mode 100644 index 0000000..466fe09 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-vnd.wap.wml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-vnd.wap.wmlscript.png b/src/main/resources/images/papirus/mimetypes/text-vnd.wap.wmlscript.png new file mode 100644 index 0000000..132f448 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-vnd.wap.wmlscript.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-adasrc.png b/src/main/resources/images/papirus/mimetypes/text-x-adasrc.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-adasrc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-arduino.png b/src/main/resources/images/papirus/mimetypes/text-x-arduino.png new file mode 100644 index 0000000..2ecccd1 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-arduino.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-asm.png b/src/main/resources/images/papirus/mimetypes/text-x-asm.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-asm.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-authors.png b/src/main/resources/images/papirus/mimetypes/text-x-authors.png new file mode 100644 index 0000000..080d1bd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-authors.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-bibtex.png b/src/main/resources/images/papirus/mimetypes/text-x-bibtex.png new file mode 100644 index 0000000..fd29f62 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-bibtex.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-c++hdr.png b/src/main/resources/images/papirus/mimetypes/text-x-c++hdr.png new file mode 100644 index 0000000..4ad26ec Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-c++hdr.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-c++src.png b/src/main/resources/images/papirus/mimetypes/text-x-c++src.png new file mode 100644 index 0000000..2695b87 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-c++src.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-changelog.png b/src/main/resources/images/papirus/mimetypes/text-x-changelog.png new file mode 100644 index 0000000..fa28f04 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-changelog.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-chdr.png b/src/main/resources/images/papirus/mimetypes/text-x-chdr.png new file mode 100644 index 0000000..4ad26ec Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-chdr.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-cmake.png b/src/main/resources/images/papirus/mimetypes/text-x-cmake.png new file mode 100644 index 0000000..41efa7f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-cmake.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-cobol.png b/src/main/resources/images/papirus/mimetypes/text-x-cobol.png new file mode 100644 index 0000000..d79d0cb Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-cobol.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-common-lisp.png b/src/main/resources/images/papirus/mimetypes/text-x-common-lisp.png new file mode 100644 index 0000000..79f6a06 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-common-lisp.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-copying.png b/src/main/resources/images/papirus/mimetypes/text-x-copying.png new file mode 100644 index 0000000..6576b29 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-copying.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-credits.png b/src/main/resources/images/papirus/mimetypes/text-x-credits.png new file mode 100644 index 0000000..080d1bd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-credits.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-csharp.png b/src/main/resources/images/papirus/mimetypes/text-x-csharp.png new file mode 100644 index 0000000..547580d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-csharp.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-csrc.png b/src/main/resources/images/papirus/mimetypes/text-x-csrc.png new file mode 100644 index 0000000..8a878a1 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-csrc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-diff.png b/src/main/resources/images/papirus/mimetypes/text-x-diff.png new file mode 100644 index 0000000..41f8e6d Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-diff.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-dsssl.png b/src/main/resources/images/papirus/mimetypes/text-x-dsssl.png new file mode 100644 index 0000000..1a2a17b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-dsssl.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-eiffel.png b/src/main/resources/images/papirus/mimetypes/text-x-eiffel.png new file mode 100644 index 0000000..fee23b6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-eiffel.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-elixir.png b/src/main/resources/images/papirus/mimetypes/text-x-elixir.png new file mode 100644 index 0000000..713daa8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-elixir.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-emacs-lisp.png b/src/main/resources/images/papirus/mimetypes/text-x-emacs-lisp.png new file mode 100644 index 0000000..aa20210 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-emacs-lisp.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-erlang.png b/src/main/resources/images/papirus/mimetypes/text-x-erlang.png new file mode 100644 index 0000000..54abe97 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-erlang.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-fortran.png b/src/main/resources/images/papirus/mimetypes/text-x-fortran.png new file mode 100644 index 0000000..e8b8659 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-fortran.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-generic-template.png b/src/main/resources/images/papirus/mimetypes/text-x-generic-template.png new file mode 100644 index 0000000..5c58e23 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-generic-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-generic.png b/src/main/resources/images/papirus/mimetypes/text-x-generic.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-generic.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-gettext-translation.png b/src/main/resources/images/papirus/mimetypes/text-x-gettext-translation.png new file mode 100644 index 0000000..6b35a20 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-gettext-translation.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-go.png b/src/main/resources/images/papirus/mimetypes/text-x-go.png new file mode 100644 index 0000000..afa2724 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-go.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-gradle.png b/src/main/resources/images/papirus/mimetypes/text-x-gradle.png new file mode 100644 index 0000000..060bb25 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-gradle.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-haskell.png b/src/main/resources/images/papirus/mimetypes/text-x-haskell.png new file mode 100644 index 0000000..219e248 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-haskell.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-hex.png b/src/main/resources/images/papirus/mimetypes/text-x-hex.png new file mode 100644 index 0000000..7c0708f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-hex.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-install.png b/src/main/resources/images/papirus/mimetypes/text-x-install.png new file mode 100644 index 0000000..e546bde Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-install.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-java-source.png b/src/main/resources/images/papirus/mimetypes/text-x-java-source.png new file mode 100644 index 0000000..b10e170 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-java-source.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-java.png b/src/main/resources/images/papirus/mimetypes/text-x-java.png new file mode 100644 index 0000000..b10e170 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-java.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-javascript.png b/src/main/resources/images/papirus/mimetypes/text-x-javascript.png new file mode 100644 index 0000000..3c0ab6c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-javascript.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-katefilelist.png b/src/main/resources/images/papirus/mimetypes/text-x-katefilelist.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-katefilelist.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-kotlin.png b/src/main/resources/images/papirus/mimetypes/text-x-kotlin.png new file mode 100644 index 0000000..3624a07 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-kotlin.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-kvc.png b/src/main/resources/images/papirus/mimetypes/text-x-kvc.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-kvc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-kvt.png b/src/main/resources/images/papirus/mimetypes/text-x-kvt.png new file mode 100644 index 0000000..10d3650 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-kvt.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-ldif.png b/src/main/resources/images/papirus/mimetypes/text-x-ldif.png new file mode 100644 index 0000000..080d1bd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-ldif.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-lilypond.png b/src/main/resources/images/papirus/mimetypes/text-x-lilypond.png new file mode 100644 index 0000000..9c8d28a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-lilypond.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-log.png b/src/main/resources/images/papirus/mimetypes/text-x-log.png new file mode 100644 index 0000000..ba280eb Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-log.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-lua.png b/src/main/resources/images/papirus/mimetypes/text-x-lua.png new file mode 100644 index 0000000..51c0e6a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-lua.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-lyx.png b/src/main/resources/images/papirus/mimetypes/text-x-lyx.png new file mode 100644 index 0000000..cf9ae97 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-lyx.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-makefile.png b/src/main/resources/images/papirus/mimetypes/text-x-makefile.png new file mode 100644 index 0000000..41efa7f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-makefile.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-markdown.png b/src/main/resources/images/papirus/mimetypes/text-x-markdown.png new file mode 100644 index 0000000..50572e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-markdown.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-matlab.png b/src/main/resources/images/papirus/mimetypes/text-x-matlab.png new file mode 100644 index 0000000..8929799 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-matlab.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-maxima-out.png b/src/main/resources/images/papirus/mimetypes/text-x-maxima-out.png new file mode 100644 index 0000000..6fd5fff Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-maxima-out.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-maximasession.png b/src/main/resources/images/papirus/mimetypes/text-x-maximasession.png new file mode 100644 index 0000000..6fd5fff Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-maximasession.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-microdvd.png b/src/main/resources/images/papirus/mimetypes/text-x-microdvd.png new file mode 100644 index 0000000..aea2fd5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-microdvd.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-mo.png b/src/main/resources/images/papirus/mimetypes/text-x-mo.png new file mode 100644 index 0000000..c1a812f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-mo.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-modelica.png b/src/main/resources/images/papirus/mimetypes/text-x-modelica.png new file mode 100644 index 0000000..ff523fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-modelica.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-mpsub.png b/src/main/resources/images/papirus/mimetypes/text-x-mpsub.png new file mode 100644 index 0000000..aea2fd5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-mpsub.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-ms-regedit.png b/src/main/resources/images/papirus/mimetypes/text-x-ms-regedit.png new file mode 100644 index 0000000..9e4be50 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-ms-regedit.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-nfo.png b/src/main/resources/images/papirus/mimetypes/text-x-nfo.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-nfo.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-nim.png b/src/main/resources/images/papirus/mimetypes/text-x-nim.png new file mode 100644 index 0000000..848af2f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-nim.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-objchdr.png b/src/main/resources/images/papirus/mimetypes/text-x-objchdr.png new file mode 100644 index 0000000..4ad26ec Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-objchdr.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-objcsrc.png b/src/main/resources/images/papirus/mimetypes/text-x-objcsrc.png new file mode 100644 index 0000000..2695b87 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-objcsrc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-ocaml.png b/src/main/resources/images/papirus/mimetypes/text-x-ocaml.png new file mode 100644 index 0000000..d394879 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-ocaml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-octave.png b/src/main/resources/images/papirus/mimetypes/text-x-octave.png new file mode 100644 index 0000000..8929799 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-octave.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-opml+xml.png b/src/main/resources/images/papirus/mimetypes/text-x-opml+xml.png new file mode 100644 index 0000000..2aac3f1 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-opml+xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-pascal.png b/src/main/resources/images/papirus/mimetypes/text-x-pascal.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-pascal.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-patch.png b/src/main/resources/images/papirus/mimetypes/text-x-patch.png new file mode 100644 index 0000000..ef2d241 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-patch.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-perl.png b/src/main/resources/images/papirus/mimetypes/text-x-perl.png new file mode 100644 index 0000000..47be445 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-perl.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-plain.png b/src/main/resources/images/papirus/mimetypes/text-x-plain.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-plain.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-po.png b/src/main/resources/images/papirus/mimetypes/text-x-po.png new file mode 100644 index 0000000..6b35a20 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-po.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-preview.png b/src/main/resources/images/papirus/mimetypes/text-x-preview.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-preview.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-python.png b/src/main/resources/images/papirus/mimetypes/text-x-python.png new file mode 100644 index 0000000..5205d85 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-python.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-python3.png b/src/main/resources/images/papirus/mimetypes/text-x-python3.png new file mode 100644 index 0000000..5205d85 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-python3.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-qml.png b/src/main/resources/images/papirus/mimetypes/text-x-qml.png new file mode 100644 index 0000000..92b8815 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-qml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-r-source.png b/src/main/resources/images/papirus/mimetypes/text-x-r-source.png new file mode 100644 index 0000000..190f5fa Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-r-source.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-r.png b/src/main/resources/images/papirus/mimetypes/text-x-r.png new file mode 100644 index 0000000..190f5fa Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-r.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-readme.png b/src/main/resources/images/papirus/mimetypes/text-x-readme.png new file mode 100644 index 0000000..c7a9564 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-readme.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-rpm-spec.png b/src/main/resources/images/papirus/mimetypes/text-x-rpm-spec.png new file mode 100644 index 0000000..e546bde Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-rpm-spec.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-ruby.png b/src/main/resources/images/papirus/mimetypes/text-x-ruby.png new file mode 100644 index 0000000..5b4d897 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-ruby.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-rust.png b/src/main/resources/images/papirus/mimetypes/text-x-rust.png new file mode 100644 index 0000000..5d63de3 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-rust.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-sass.png b/src/main/resources/images/papirus/mimetypes/text-x-sass.png new file mode 100644 index 0000000..1a2a17b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-sass.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-scala.png b/src/main/resources/images/papirus/mimetypes/text-x-scala.png new file mode 100644 index 0000000..7b36901 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-scala.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-scheme.png b/src/main/resources/images/papirus/mimetypes/text-x-scheme.png new file mode 100644 index 0000000..8f46f84 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-scheme.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-script.png b/src/main/resources/images/papirus/mimetypes/text-x-script.png new file mode 100644 index 0000000..47be445 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-script.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-scss.png b/src/main/resources/images/papirus/mimetypes/text-x-scss.png new file mode 100644 index 0000000..1a2a17b Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-scss.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-sql.png b/src/main/resources/images/papirus/mimetypes/text-x-sql.png new file mode 100644 index 0000000..7296d70 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-sql.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-ssa.png b/src/main/resources/images/papirus/mimetypes/text-x-ssa.png new file mode 100644 index 0000000..aea2fd5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-ssa.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-subviewer.png b/src/main/resources/images/papirus/mimetypes/text-x-subviewer.png new file mode 100644 index 0000000..aea2fd5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-subviewer.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-systemd-unit.png b/src/main/resources/images/papirus/mimetypes/text-x-systemd-unit.png new file mode 100644 index 0000000..91f09a2 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-systemd-unit.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-tcl.png b/src/main/resources/images/papirus/mimetypes/text-x-tcl.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-tcl.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-tex.png b/src/main/resources/images/papirus/mimetypes/text-x-tex.png new file mode 100644 index 0000000..fd29f62 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-tex.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-texinfo.png b/src/main/resources/images/papirus/mimetypes/text-x-texinfo.png new file mode 100644 index 0000000..fd29f62 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-texinfo.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-texmacs.png b/src/main/resources/images/papirus/mimetypes/text-x-texmacs.png new file mode 100644 index 0000000..442b1db Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-texmacs.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-twig.png b/src/main/resources/images/papirus/mimetypes/text-x-twig.png new file mode 100644 index 0000000..5c58e23 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-twig.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-vala.png b/src/main/resources/images/papirus/mimetypes/text-x-vala.png new file mode 100644 index 0000000..ee06ffa Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-vala.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-vbscript.png b/src/main/resources/images/papirus/mimetypes/text-x-vbscript.png new file mode 100644 index 0000000..f84b3e0 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-vbscript.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-wxmathml.png b/src/main/resources/images/papirus/mimetypes/text-x-wxmathml.png new file mode 100644 index 0000000..6fd5fff Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-wxmathml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-wxmaxima-batch.png b/src/main/resources/images/papirus/mimetypes/text-x-wxmaxima-batch.png new file mode 100644 index 0000000..6fd5fff Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-wxmaxima-batch.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-xges.png b/src/main/resources/images/papirus/mimetypes/text-x-xges.png new file mode 100644 index 0000000..833f369 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-xges.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-x-xslfo.png b/src/main/resources/images/papirus/mimetypes/text-x-xslfo.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-x-xslfo.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-xmcd.png b/src/main/resources/images/papirus/mimetypes/text-xmcd.png new file mode 100644 index 0000000..c81c1a5 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-xmcd.png differ diff --git a/src/main/resources/images/papirus/mimetypes/text-xml.png b/src/main/resources/images/papirus/mimetypes/text-xml.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/text-xml.png differ diff --git a/src/main/resources/images/papirus/mimetypes/unknown.png b/src/main/resources/images/papirus/mimetypes/unknown.png new file mode 100644 index 0000000..586fc44 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/unknown.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-mlt-playlist.png b/src/main/resources/images/papirus/mimetypes/video-mlt-playlist.png new file mode 100644 index 0000000..76c4570 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-mlt-playlist.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-mp2t.png b/src/main/resources/images/papirus/mimetypes/video-mp2t.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-mp2t.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-mp4.png b/src/main/resources/images/papirus/mimetypes/video-mp4.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-mp4.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-vivo.png b/src/main/resources/images/papirus/mimetypes/video-vivo.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-vivo.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-vnd.rn-realvideo.png b/src/main/resources/images/papirus/mimetypes/video-vnd.rn-realvideo.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-vnd.rn-realvideo.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-wavelet.png b/src/main/resources/images/papirus/mimetypes/video-wavelet.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-wavelet.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-webm.png b/src/main/resources/images/papirus/mimetypes/video-webm.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-webm.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-x-anim.png b/src/main/resources/images/papirus/mimetypes/video-x-anim.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-x-anim.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-x-flic.png b/src/main/resources/images/papirus/mimetypes/video-x-flic.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-x-flic.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-x-flv.png b/src/main/resources/images/papirus/mimetypes/video-x-flv.png new file mode 100644 index 0000000..313cfb2 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-x-flv.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-x-generic.png b/src/main/resources/images/papirus/mimetypes/video-x-generic.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-x-generic.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-x-google-vlc-plugin.png b/src/main/resources/images/papirus/mimetypes/video-x-google-vlc-plugin.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-x-google-vlc-plugin.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-x-javafx.png b/src/main/resources/images/papirus/mimetypes/video-x-javafx.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-x-javafx.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-x-matroska.png b/src/main/resources/images/papirus/mimetypes/video-x-matroska.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-x-matroska.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-x-mng.png b/src/main/resources/images/papirus/mimetypes/video-x-mng.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-x-mng.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-x-ms-asf.png b/src/main/resources/images/papirus/mimetypes/video-x-ms-asf.png new file mode 100644 index 0000000..76c4570 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-x-ms-asf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-x-ms-wmp.png b/src/main/resources/images/papirus/mimetypes/video-x-ms-wmp.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-x-ms-wmp.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-x-ms-wmv.png b/src/main/resources/images/papirus/mimetypes/video-x-ms-wmv.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-x-ms-wmv.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-x-msvideo.png b/src/main/resources/images/papirus/mimetypes/video-x-msvideo.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-x-msvideo.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-x-ogm+ogg.png b/src/main/resources/images/papirus/mimetypes/video-x-ogm+ogg.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-x-ogm+ogg.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-x-theora+ogg.png b/src/main/resources/images/papirus/mimetypes/video-x-theora+ogg.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-x-theora+ogg.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video-x-wmv.png b/src/main/resources/images/papirus/mimetypes/video-x-wmv.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video-x-wmv.png differ diff --git a/src/main/resources/images/papirus/mimetypes/video.png b/src/main/resources/images/papirus/mimetypes/video.png new file mode 100644 index 0000000..8363d4c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/video.png differ diff --git a/src/main/resources/images/papirus/mimetypes/virtualbox-hdd.png b/src/main/resources/images/papirus/mimetypes/virtualbox-hdd.png new file mode 100644 index 0000000..7fdbf84 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/virtualbox-hdd.png differ diff --git a/src/main/resources/images/papirus/mimetypes/virtualbox-ova.png b/src/main/resources/images/papirus/mimetypes/virtualbox-ova.png new file mode 100644 index 0000000..12ff8f8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/virtualbox-ova.png differ diff --git a/src/main/resources/images/papirus/mimetypes/virtualbox-ovf.png b/src/main/resources/images/papirus/mimetypes/virtualbox-ovf.png new file mode 100644 index 0000000..fde1a14 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/virtualbox-ovf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/virtualbox-vbox-extpack.png b/src/main/resources/images/papirus/mimetypes/virtualbox-vbox-extpack.png new file mode 100644 index 0000000..3126177 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/virtualbox-vbox-extpack.png differ diff --git a/src/main/resources/images/papirus/mimetypes/virtualbox-vbox.png b/src/main/resources/images/papirus/mimetypes/virtualbox-vbox.png new file mode 100644 index 0000000..82ab47a Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/virtualbox-vbox.png differ diff --git a/src/main/resources/images/papirus/mimetypes/virtualbox-vdi.png b/src/main/resources/images/papirus/mimetypes/virtualbox-vdi.png new file mode 100644 index 0000000..39f926f Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/virtualbox-vdi.png differ diff --git a/src/main/resources/images/papirus/mimetypes/virtualbox-vhd.png b/src/main/resources/images/papirus/mimetypes/virtualbox-vhd.png new file mode 100644 index 0000000..dd85852 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/virtualbox-vhd.png differ diff --git a/src/main/resources/images/papirus/mimetypes/virtualbox-vmdk.png b/src/main/resources/images/papirus/mimetypes/virtualbox-vmdk.png new file mode 100644 index 0000000..5a9d581 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/virtualbox-vmdk.png differ diff --git a/src/main/resources/images/papirus/mimetypes/wps-office-doc.png b/src/main/resources/images/papirus/mimetypes/wps-office-doc.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/wps-office-doc.png differ diff --git a/src/main/resources/images/papirus/mimetypes/wps-office-dot.png b/src/main/resources/images/papirus/mimetypes/wps-office-dot.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/wps-office-dot.png differ diff --git a/src/main/resources/images/papirus/mimetypes/wps-office-dps.png b/src/main/resources/images/papirus/mimetypes/wps-office-dps.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/wps-office-dps.png differ diff --git a/src/main/resources/images/papirus/mimetypes/wps-office-dpt.png b/src/main/resources/images/papirus/mimetypes/wps-office-dpt.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/wps-office-dpt.png differ diff --git a/src/main/resources/images/papirus/mimetypes/wps-office-et.png b/src/main/resources/images/papirus/mimetypes/wps-office-et.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/wps-office-et.png differ diff --git a/src/main/resources/images/papirus/mimetypes/wps-office-ett.png b/src/main/resources/images/papirus/mimetypes/wps-office-ett.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/wps-office-ett.png differ diff --git a/src/main/resources/images/papirus/mimetypes/wps-office-pot.png b/src/main/resources/images/papirus/mimetypes/wps-office-pot.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/wps-office-pot.png differ diff --git a/src/main/resources/images/papirus/mimetypes/wps-office-ppt.png b/src/main/resources/images/papirus/mimetypes/wps-office-ppt.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/wps-office-ppt.png differ diff --git a/src/main/resources/images/papirus/mimetypes/wps-office-wps.png b/src/main/resources/images/papirus/mimetypes/wps-office-wps.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/wps-office-wps.png differ diff --git a/src/main/resources/images/papirus/mimetypes/wps-office-wpt.png b/src/main/resources/images/papirus/mimetypes/wps-office-wpt.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/wps-office-wpt.png differ diff --git a/src/main/resources/images/papirus/mimetypes/wps-office-xls.png b/src/main/resources/images/papirus/mimetypes/wps-office-xls.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/wps-office-xls.png differ diff --git a/src/main/resources/images/papirus/mimetypes/wps-office-xlt.png b/src/main/resources/images/papirus/mimetypes/wps-office-xlt.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/wps-office-xlt.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-content-audio-cdda.png b/src/main/resources/images/papirus/mimetypes/x-content-audio-cdda.png new file mode 100644 index 0000000..7cf40d7 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-content-audio-cdda.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-content-audio-dvd.png b/src/main/resources/images/papirus/mimetypes/x-content-audio-dvd.png new file mode 100644 index 0000000..7cf40d7 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-content-audio-dvd.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-content-audio-player.png b/src/main/resources/images/papirus/mimetypes/x-content-audio-player.png new file mode 100644 index 0000000..7cf40d7 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-content-audio-player.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-content-blank-bd.png b/src/main/resources/images/papirus/mimetypes/x-content-blank-bd.png new file mode 100644 index 0000000..6d5acef Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-content-blank-bd.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-content-blank-cd.png b/src/main/resources/images/papirus/mimetypes/x-content-blank-cd.png new file mode 100644 index 0000000..6d5acef Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-content-blank-cd.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-content-blank-dvd.png b/src/main/resources/images/papirus/mimetypes/x-content-blank-dvd.png new file mode 100644 index 0000000..6d5acef Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-content-blank-dvd.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-content-blank-hddvd.png b/src/main/resources/images/papirus/mimetypes/x-content-blank-hddvd.png new file mode 100644 index 0000000..6d5acef Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-content-blank-hddvd.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-content-ebook-reader.png b/src/main/resources/images/papirus/mimetypes/x-content-ebook-reader.png new file mode 100644 index 0000000..8510be8 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-content-ebook-reader.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-content-image-dcf.png b/src/main/resources/images/papirus/mimetypes/x-content-image-dcf.png new file mode 100644 index 0000000..feb40e1 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-content-image-dcf.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-content-image-picturecd.png b/src/main/resources/images/papirus/mimetypes/x-content-image-picturecd.png new file mode 100644 index 0000000..feb40e1 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-content-image-picturecd.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-content-software.png b/src/main/resources/images/papirus/mimetypes/x-content-software.png new file mode 100644 index 0000000..10efbbf Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-content-software.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-content-unix-software.png b/src/main/resources/images/papirus/mimetypes/x-content-unix-software.png new file mode 100644 index 0000000..10efbbf Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-content-unix-software.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-content-video-bluray.png b/src/main/resources/images/papirus/mimetypes/x-content-video-bluray.png new file mode 100644 index 0000000..04e5472 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-content-video-bluray.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-content-video-dvd.png b/src/main/resources/images/papirus/mimetypes/x-content-video-dvd.png new file mode 100644 index 0000000..04e5472 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-content-video-dvd.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-content-video-hddvd.png b/src/main/resources/images/papirus/mimetypes/x-content-video-hddvd.png new file mode 100644 index 0000000..04e5472 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-content-video-hddvd.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-content-video-svcd.png b/src/main/resources/images/papirus/mimetypes/x-content-video-svcd.png new file mode 100644 index 0000000..04e5472 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-content-video-svcd.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-content-video-vcd.png b/src/main/resources/images/papirus/mimetypes/x-content-video-vcd.png new file mode 100644 index 0000000..04e5472 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-content-video-vcd.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-content-win32-software.png b/src/main/resources/images/papirus/mimetypes/x-content-win32-software.png new file mode 100644 index 0000000..5361eea Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-content-win32-software.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-gambasserverpage.png b/src/main/resources/images/papirus/mimetypes/x-gambasserverpage.png new file mode 100644 index 0000000..dbd69ad Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-gambasserverpage.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-office-calendar.png b/src/main/resources/images/papirus/mimetypes/x-office-calendar.png new file mode 100644 index 0000000..2622d42 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-office-calendar.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-office-document-template.png b/src/main/resources/images/papirus/mimetypes/x-office-document-template.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-office-document-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-office-document.png b/src/main/resources/images/papirus/mimetypes/x-office-document.png new file mode 100644 index 0000000..1ae3244 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-office-document.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-office-presentation-template.png b/src/main/resources/images/papirus/mimetypes/x-office-presentation-template.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-office-presentation-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-office-presentation.png b/src/main/resources/images/papirus/mimetypes/x-office-presentation.png new file mode 100644 index 0000000..414a7e6 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-office-presentation.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-office-spreadsheet-template.png b/src/main/resources/images/papirus/mimetypes/x-office-spreadsheet-template.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-office-spreadsheet-template.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-office-spreadsheet.png b/src/main/resources/images/papirus/mimetypes/x-office-spreadsheet.png new file mode 100644 index 0000000..55c33fd Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-office-spreadsheet.png differ diff --git a/src/main/resources/images/papirus/mimetypes/x-package-repository.png b/src/main/resources/images/papirus/mimetypes/x-package-repository.png new file mode 100644 index 0000000..e2ad11c Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/x-package-repository.png differ diff --git a/src/main/resources/images/papirus/mimetypes/xoj.png b/src/main/resources/images/papirus/mimetypes/xoj.png new file mode 100644 index 0000000..c2fabd4 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/xoj.png differ diff --git a/src/main/resources/images/papirus/mimetypes/xopt.png b/src/main/resources/images/papirus/mimetypes/xopt.png new file mode 100644 index 0000000..f185869 Binary files /dev/null and b/src/main/resources/images/papirus/mimetypes/xopt.png differ diff --git a/src/main/resources/images/papirus/places/folder-blue.png b/src/main/resources/images/papirus/places/folder-blue.png new file mode 100644 index 0000000..55b06a0 Binary files /dev/null and b/src/main/resources/images/papirus/places/folder-blue.png differ diff --git a/src/main/resources/images/papirus/places/folder-paleorange.png b/src/main/resources/images/papirus/places/folder-paleorange.png new file mode 100644 index 0000000..5c979dd Binary files /dev/null and b/src/main/resources/images/papirus/places/folder-paleorange.png differ diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index abc5348..af3900c 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -3,9 +3,10 @@ - + - + diff --git a/src/main/resources/static/pboc/pboc.exe b/src/main/resources/static/pboc/pboc.exe deleted file mode 100644 index 953bef8..0000000 Binary files a/src/main/resources/static/pboc/pboc.exe and /dev/null differ