pax_global_header00006660000000000000000000000064145554311650014523gustar00rootroot0000000000000052 comment=821f2ea84710c220e46dc0785b4a5567bc4cf7aa lomiri-ui-extras-0.6.3/000077500000000000000000000000001455543116500147435ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/.gitignore000066400000000000000000000010461455543116500167340ustar00rootroot00000000000000*.qmlproject.user CMakeCache.txt CMakeLists.txt.user CMakeFiles/ cmake_install.cmake cmake_uninstall.cmake Makefile install_manifest.txt CTestTestfile.cmake Testing/ *.moc moc_*.cpp *_automoc.cpp tests/unittests/tst_QmlTests tests/unittests/tst_CommandLineParserTests tests/unittests/tst_HistoryModelTests tests/unittests/tst_HistoryMatchesModelTests tests/unittests/tst_TabsModelTests po/*.gmo obj-* debian/files debian/tmp/ debian/qml-module-lomiri-components-extras/ debian/*.debhelper debian/*.debhelper.log debian/*.substvars debian/stamp-* lomiri-ui-extras-0.6.3/AUTHORS000066400000000000000000000023001455543116500160060ustar00rootroot00000000000000Aashrut Abdullah AL Shohag Advocatux Ahmed Suliman Aitzol Berasategi Allan Nordhøy Andrew Hayzen Anne Onyme Anonymous Arthur Mello Aurelio Cilia Bill Filler Bittin1ddc447d824349b2 Cflep Dalton Durst Dan Dano6 Ege Öz Ennio Lavagnini Enolp Eugene Florian Boucault Florian Leeber Gallegonovato Gnu-ewm Guenter Schwann Guido Berhoerster Heimen Stoffels Hosted Weblate HSN80 Hussain Hashem Aljafri Ierihon Ivo Xavier Jan Sprinz Jaume Angrill Jiri Grönroos Joan CiberSheep Jonas G Drange Jonatan Hatakeyama Zeidler Jozef Mlich Ken VanDine Louies Louies0623 Łukasz 'sil2100' Zemczak Luna Jernberg Lxdb Marius Gripsgard Mike Mike Gabriel Milan Korecky Milan Korecký Moo M Sugahara Muhammad Neutrum N NPL Øjvind Fritjof Arnfred Omer Akram OPNA2608 Pavel Borecki P_E_T_O P -H Lin Phlostically Ratchanan Srirattanamet Ricardo Salveti De Araujo Riccardo Riccio Rodney Rodney Dawes Rodrigo Benedito Rúben Carneiro Rudra Harsh V Singh Ryan Argente Sami Törmänen Samson Sander Sebastien Bacher Sergii Horichenko SongInseo Stefan Stefan Weng StefWe Sylke Vicious Temuri Doghonadze Thanakit Srisearmpok Timo Jyrinki Timothy G Tom Dom Tom Rausner Ugo Riboni Vinícius F Walter Garcia-Fontes Weblate Yasser Lotfy 不朽正义 lomiri-ui-extras-0.6.3/CMakeLists.txt000066400000000000000000000020651455543116500175060ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.5) project(lomiri-ui-extras VERSION 0.6.3) # Standard install paths include(GNUInstallDirs) option(ENABLE_TESTS "Build test programs" ON) # enable QML debugging if(CMAKE_BUILD_TYPE MATCHES DEBUG OR CMAKE_BUILD_TYPE MATCHES "Debug") add_definitions(-DQT_QML_DEBUG) endif() find_package(Qt5Core REQUIRED) find_package(Qt5Widgets REQUIRED) find_package(Qt5Quick REQUIRED) find_package(Qt5DBus REQUIRED) find_package(Qt5Xml REQUIRED) find_package(Qt5Test) add_definitions(-DQT_NO_KEYWORDS) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) # make non compiled files visible in qtcreator file(GLOB_RECURSE NON_COMPILED_FILES *.qml *.js *.py *.svg *.png *.in *.json *.desktop *.pot qmldir) add_custom_target(NON_COMPILED_TARGET ALL SOURCES ${NON_COMPILED_FILES}) # for dh_translations to extract the domain # (regarding syntax consistency, see http://pad.lv/1181187) set (GETTEXT_PACKAGE "lomiri-ui-extras") add_subdirectory(modules) if(ENABLE_TESTS) enable_testing() add_subdirectory(tests) endif() add_subdirectory(po) lomiri-ui-extras-0.6.3/COPYING000066400000000000000000001045131455543116500160020ustar00rootroot00000000000000 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 . lomiri-ui-extras-0.6.3/ChangeLog000066400000000000000000002425471455543116500165330ustar00rootroot000000000000002024-01-28 Mike Gabriel * Release 0.6.3 (HEAD -> main, tag: 0.6.3) 2023-12-31 phlostically * Translated using Weblate (Esperanto) (9fadfeb) 2023-12-27 Weblate * Added translation using Weblate (Chinese (Simplified) (zh_LATN@pinyin)) (f754a7a) * Added translation using Weblate (Tamil (Sri Lanka)) (6a8d3f6) * Added translation using Weblate (German (Walser)) (4325a5f) * Added translation using Weblate (Meadow Mari) (4c610c4) * Added translation using Weblate (Crimean Tatar) (2c7bf99) * Added translation using Weblate (Chuvash) (f8f4f40) * Added translation using Weblate (Silesian) (4f67e50) * Added translation using Weblate (Latin) (58115d5) * Added translation using Weblate (Venetian) (7391fcf) * Added translation using Weblate (Ossetian) (117065a) * Added translation using Weblate (Sami (Northern)) (ca527ab) * Added translation using Weblate (Greenlandic) (5079ff7) * Added translation using Weblate (Assamese) (1f77fb0) * Added translation using Weblate (Haitian) (884fd5f) * Added translation using Weblate (Cornish) (2628443) * Added translation using Weblate (Frisian) (0a1b4b3) * Added translation using Weblate (Kashubian) (b6c154e) * Added translation using Weblate (Aragonese) (5f06373) * Added translation using Weblate (Tibetan) (dbcbf8e) * Added translation using Weblate (Filipino) (1d2215e) * Added translation using Weblate (Tigrinya) (c2cd1f0) * Added translation using Weblate (Tatar) (de494df) 2023-12-26 Weblate * Added translation using Weblate (Italian (it_CARES)) (b61191e) 2023-12-22 NPL * Translated using Weblate (Japanese) (34d1e0c) 2023-12-17 Mike Gabriel * Merge branch 'fix/lessExactQmltestrunnerFinding' into 'main' (59f7f56) 2023-12-16 OPNA2608 * Find qmltestrunner without PATHS hint (0e55d4f) 2023-11-22 OPNA2608 * tests/qml/CMakeLists.txt: Don't insist on finding qmltestrunner only at hardcoded guess (b0c4901) 2023-11-15 Ratchanan Srirattanamet * Merge branch 'fix/qt5_use_modules' into 'main' (df506e7) 2023-11-15 OPNA2608 * Move added find_package() calls to top-level CMakeLists.txt (1c06bda) 2023-11-14 OPNA2608 * Stop using qt5_use_modules (87540af) 2023-11-15 Ratchanan Srirattanamet * Merge branch 'fix/newerExiv2Compat' into 'main' (f337cee) 2023-11-14 OPNA2608 * plugin/photoeditor: Add version guards to new Exiv2 code (ef767c5) * plugin/photoeditor: Fix for Exiv2 0.28.0 (74bb579) 2023-10-18 Weblate * Added translation using Weblate (Xhosa) (5301c98) * Added translation using Weblate (Manx) (9c59981) * Added translation using Weblate (Corsican) (a96ea22) * Added translation using Weblate (Chechen) (22f36c3) * Added translation using Weblate (Wolof) (0574437) * Added translation using Weblate (Kurdish (Central)) (2358bd3) * Added translation using Weblate (Uzbek) (58848fe) * Added translation using Weblate (Kyrgyz) (36acb42) * Added translation using Weblate (Sotho (Southern)) (22319d2) * Added translation using Weblate (Kazakh) (7d2e5b8) * Added translation using Weblate (Norwegian Nynorsk) (97c8288) * Added translation using Weblate (Swahili) (b351358) * Added translation using Weblate (Odia) (b1f6c79) * Added translation using Weblate (Bengali) (6f9f2e4) * Added translation using Weblate (Irish) (8309a18) 2023-10-15 Mike Gabriel * Release 0.6.2 (f14880d) (tag: 0.6.2) * Merge branch 'personal/sunweaver/cmake-CMP0048' into 'main' (3edd5c1) * CMakeLists.txt: Bump cmake_minimum_required to 3.5. (c6ce76e) * CMakeLists.txt: Set cmake_minimum_required() before using the project() function. (9366ba4) * Release 0.6.1 (c695853) (tag: 0.6.1) 2023-09-06 bittin1ddc447d824349b2 * Translated using Weblate (Swedish) (357add3) 2023-08-13 Abdullah AL Shohag * Translated using Weblate (Bengali (Bangladesh)) (d7ac673) 2023-07-28 Milan Korecky * Translated using Weblate (Czech) (7217414) 2023-06-30 Rudra Harsh V.Singh * Translated using Weblate (Sanskrit) (1b53c05) 2023-06-30 Weblate * Added translation using Weblate (Sanskrit) (a25bcd7) 2023-04-12 Temuri Doghonadze * Translated using Weblate (Georgian) (810944f) 2023-04-11 Temuri Doghonadze * Translated using Weblate (Georgian) (ff63e1f) * Translated using Weblate (Georgian) (cd5635e) 2023-04-04 gallegonovato * Translated using Weblate (Spanish) (282216d) 2023-03-31 Sylke Vicious * Translated using Weblate (Italian) (0ebc843) 2023-03-31 Jozef Mlich * Translated using Weblate (Czech) (474cfff) 2023-03-30 Sylke Vicious * Translated using Weblate (Italian) (926bd10) 2023-02-27 Heimen Stoffels * Translated using Weblate (Dutch) (bd45d52) 2023-02-26 Luna Jernberg * Translated using Weblate (Swedish) (8b6509e) 2023-02-22 Heimen Stoffels * Translated using Weblate (Dutch) (52b260f) 2023-02-16 phlostically * Translated using Weblate (Esperanto) (8030520) 2023-01-31 Mike Gabriel * Translated using Weblate (German) (61053c7) 2023-01-30 Sergii Horichenko * Translated using Weblate (Russian) (a3a15d1) 2023-01-24 gnu-ewm * Translated using Weblate (Polish) (acdff16) 2023-01-14 Dan * Translated using Weblate (Ukrainian) (9653a72) 2023-01-13 Sergii Horichenko * Translated using Weblate (Russian) (de7acc1) 2023-01-13 Ivo Xavier * Translated using Weblate (Portuguese) (17cf8ea) 2023-01-13 Timothy G * Translated using Weblate (French) (f302487) 2023-01-11 Dan * Translated using Weblate (Ukrainian) (e9af1ed) 2023-01-11 Marius Gripsgard * Release 0.6.0 (d6b15f0) (tag: 0.6.0) 2023-01-04 Anonymous * Translated using Weblate (Chinese (Min Nan)) (606072b) * Translated using Weblate (Kurdish (Southern)) (cd2ee5f) * Translated using Weblate (French (Switzerland)) (48dba36) * Translated using Weblate (Kurdish (Northern)) (3906b82) * Translated using Weblate (Shan) (09b3b3d) * Translated using Weblate (Bemba) (3897a6c) * Translated using Weblate (Oromo) (f845ed5) * Translated using Weblate (Dhivehi) (7830a1f) * Translated using Weblate (Nyanja) (e4c7995) * Translated using Weblate (Lojban) (6c59027) * Translated using Weblate (Macedonian) (dc5265c) * Translated using Weblate (Maori) (d0d48d0) * Translated using Weblate (Malayalam) (7a7d090) * Translated using Weblate (Friulian) (3518aa1) * Translated using Weblate (Pashto) (e2bb46b) * Translated using Weblate (Telugu) (4dba48f) * Translated using Weblate (Turkmen) (d60bb6d) * Translated using Weblate (Ido) (9f59b32) * Translated using Weblate (Tetum) (b8435fa) * Translated using Weblate (Scots) (110d630) * Translated using Weblate (Franco-Provençal) (427c356) * Translated using Weblate (Sindhi) (a86ebc5) * Translated using Weblate (Tajik) (f52065d) * Translated using Weblate (Pampanga) (938e9eb) * Translated using Weblate (Nepali) (c77c967) * Translated using Weblate (Burmese) (fb86777) * Translated using Weblate (Marathi) (eb956a2) * Translated using Weblate (Malagasy) (e778b41) * Translated using Weblate (Lao) (214ae89) * Translated using Weblate (Lingala) (cc367d1) * Translated using Weblate (Luxembourgish) (bc319c6) * Translated using Weblate (Kabyle) (9edf5bf) * Translated using Weblate (Icelandic) (457021e) * Translated using Weblate (Estonian) (a6deaf9) * Translated using Weblate (Bulgarian) (080da6c) 2023-01-05 Mike Gabriel * Revert "Deleted translation using Weblate (Chinese (Traditional, Hong Kong))" (e552546) * Revert "Added translation using Weblate (Chinese (Traditional, Hong Kong))" (4670011) 2023-01-04 Weblate * Added translation using Weblate (Chinese (Traditional, Hong Kong)) (8e74047) 2023-01-04 Allan Nordhøy * Translated using Weblate (Norwegian Bokmål) (3a3037c) 2023-01-04 Mike Gabriel * Deleted translation using Weblate (Chinese (Traditional, Hong Kong)) (09e8bd8) 2023-01-04 Weblate * Added translation using Weblate (Chinese (Min Nan)) (03a68ec) * Added translation using Weblate (Kurdish (Southern)) (79789ae) * Added translation using Weblate (French (Switzerland)) (1ae25b6) * Added translation using Weblate (Kurdish (Northern)) (7592b87) * Added translation using Weblate (Shan) (f3a8f6d) * Added translation using Weblate (Bemba) (457268c) * Added translation using Weblate (Oromo) (34a0d4b) * Added translation using Weblate (Dhivehi) (ea35ab9) * Added translation using Weblate (Nyanja) (5802d2e) * Added translation using Weblate (English (Canada)) (646566b) * Added translation using Weblate (Lojban) (262f908) * Added translation using Weblate (Georgian) (77ce9f5) * Added translation using Weblate (Macedonian) (7ec9cd9) * Added translation using Weblate (Maori) (a835e0b) * Added translation using Weblate (Malayalam) (2fc9fd4) * Added translation using Weblate (Friulian) (9560c08) * Added translation using Weblate (Hindi) (a83b16d) * Added translation using Weblate (Armenian) (c657728) * Added translation using Weblate (Pashto) (9cc9670) * Added translation using Weblate (Telugu) (7959c1f) * Added translation using Weblate (Turkmen) (7573a39) 2023-01-03 Muhammad * Translated using Weblate (Urdu) (86b9312) 2023-01-03 Weblate * Added translation using Weblate (Urdu) (db38797) * Added translation using Weblate (Ido) (c80c22d) * Added translation using Weblate (Tetum) (efd1fad) * Added translation using Weblate (Scots) (5fc6862) * Added translation using Weblate (Franco-Provençal) (fa76400) * Added translation using Weblate (Sindhi) (db0867b) 2023-01-03 Hosted Weblate * Update translation files (09aa22c) 2022-11-23 Mike Gabriel * Merge branch 'personal/mariogrip/focal_-_qtdepriwarn' into 'main' (33115fb) 2022-11-22 Marius Gripsgard * Set missing default constructor and copy (6a9d2db) * src: Use Qt::SkipEmptyParts for qt version 5.14 and up (dda1f50) * ‘QString::null’ is deprecated: use QString() (dadefc2) 2022-10-27 Mike Gabriel * Merge branch 'keep-tabsbar' into 'main' (4d6758d) 2022-10-27 Guido Berhoerster * Revert "Move TabsBar component to morph-browser" (a4b54bb) 2022-10-13 Ratchanan Srirattanamet * Merge branch 'remove-tabsbar' into 'main' (12bfa9a) 2022-08-02 Guido Berhoerster * Move TabsBar component to morph-browser (709b922) 2022-09-08 Ratchanan Srirattanamet * Merge branch 'fix-service-name' into 'main' (01204b3) 2022-09-07 Guido Berhoerster * Fix incorrect Lomiri greeter DBus service name in PamAuthentication qml plugin (310bb6d) 2022-07-18 Ratchanan Srirattanamet * Merge branch 'import-app-subpackages' into 'main' (9de19d0) 2022-07-15 Guido Berhoerster * Switch to /com/lomiri/LomiriGreeter service (c66c248) * Restore use of QT_NO_KEYWORDS and replace keywords with macros (27a64aa) 2022-07-12 Guido Berhoerster * Add Lomiri.Components.Extras.PamAuthentication qml module (6e76664) 2022-03-08 Ratchanan Srirattanamet * Merge branch 'mr/unify-copyright-holdership-for-Canonical' into 'main' (8ad53d4) 2022-03-03 Mike Gabriel * Use unified spelling for copyright holdership by Canonical Ltd. (no comma between Canonical and Ltd.). (9a4d90e) * Use unified spelling for copyright holdership by Canonical Ltd. ('Ltd.' needs a full-stop at its end). (c7643a1) 2022-03-04 Mike Gabriel * Release 0.5 (6777d57) (tag: 0.5) 2021-08-31 Marius Gripsgard * Merge branch 'github/fork/nanu-c/xenial' into 'main' (3b73842) 2021-08-23 Ratchanan Srirattanamet * d/copyright: update metadata (b8bf9d3) * Rename UbuntuAnimation to LomiriAnimation (04f991c) 2021-08-20 Ratchanan Srirattanamet * Merge branch 'ubports/xenial' into focal (0145917) 2021-08-19 Ratchanan Srirattanamet * Move Jenkinsfile to debian/ per the new guideline (594f9d4) * d/changelog: fixup versioning and update changelog (43e9d42) * po: update and rename pot file (2fe1b15) * tests/qml: migrate to Lomiri.Test (6a53541) * tests/qml: re-enable tests (9a2b6f7) * tests/qml: enforce xcb QPA (c7936e8) * .gitignore: update the binary package name (a492ee4) * Rename .bzrignore to .gitignore (09e0167) * Remove obsolete .bzr-builddeb/ (95c058f) * d/control: update homepage due to GitLab migration (adf1c0e) * d/control: remove unneeded Provides/Conflicts/Replaces (cb4d753) * d/control: correct the binary package name (ad647c6) * Fix the link in README (0bdb119) 2021-08-18 Florian Leeber * Merge pull request #72 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (77ce537) 2021-07-29 Weblate * Translated by Ivo Xavier using Weblate (Portuguese) - 100.0% (22 of 22 strings) (0a17113) 2021-07-18 aaron@nanu-c.org * move to lomiri (bc21c08) 2021-07-17 aaron@nanu-c.org * rename to qml-module-lomiri-ui-extras (d6a3893) * rename to UbuntuShape to LomiriShape (61974dc) 2021-07-13 aaron@nanu-c.org * rename to lomiri-ui-extras + focal support (2f33c32) 2021-06-15 Rodney * Merge pull request #71 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (70ffb86) 2021-06-15 Weblate * Translated by Milan Korecký using Weblate (Czech) - 100.0% (22 of 22 strings) (1f9e0c8) 2021-05-24 Rodney * Merge pull request #70 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (b619bbf) 2021-05-23 Weblate * Translated by Wannaphong Phatthiyaphaibun using Weblate (Thai) - 40.9% (9 of 22 strings) (f74993a) 2021-03-26 Rodney * Merge pull request #69 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (6f5fc35) 2021-03-26 Weblate * Translated by vokaliz using Weblate (Russian) - 100.0% (22 of 22 strings) (e75bb41) 2021-03-25 Rodney * Merge pull request #68 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (4d3e912) 2021-03-25 Weblate * Translated by vokaliz using Weblate (Russian) - 100.0% (22 of 22 strings) (723e6b5) 2021-03-21 Florian Leeber * Merge pull request #67 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (4380e69) 2021-03-19 Weblate * Translated by c4pp4 using Weblate (Czech) - 100.0% (22 of 22 strings) (50fd0a6) 2021-01-08 Marius Gripsgard * Merge pull request #66 from ubports/xenial_-_qt-5-12 (798a881) 2020-10-13 Rodney Dawes * Fix some QML warnings. (40ff30d) 2020-11-30 Dalton Durst * Merge pull request #64 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (773785f) 2020-11-23 Weblate * Translated by Jiri Grönroos using Weblate (Finnish) - 100.0% (22 of 22 strings) (25c5fd0) 2020-11-15 Florian Leeber * Merge pull request #63 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (78b5616) 2020-11-13 Weblate * Translated by abidin using Weblate (Arabic) - 86.3% (19 of 22 strings) (8fcd80f) 2020-11-12 Rodney * Merge pull request #62 from ubports/xenial_-_jenkinsfile (986a433) 2020-11-12 Rodney Dawes * Update the Jenkinsfile (9c270e9) 2020-11-08 Florian Leeber * Merge pull request #61 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (6184830) 2020-11-06 Weblate * Translated by abidin using Weblate (Arabic) - 81.8% (18 of 22 strings) (4cb34c8) 2020-11-01 Florian Leeber * Merge pull request #60 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (0b24a79) 2020-10-26 Weblate * Translated by Heimen Stoffels using Weblate (Dutch) - 100.0% (22 of 22 strings) (1e887f1) 2020-09-06 Florian Leeber * Merge pull request #59 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (8fecad1) 2020-09-05 Weblate * Translated by tamer dab using Weblate (Hebrew) - 100.0% (22 of 22 strings) (1ecd3d1) 2020-08-26 Florian Leeber * Merge pull request #58 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (4722844) 2020-08-16 Weblate * Translated by Efstathios Iosifidis using Weblate (Greek) - 100.0% (22 of 22 strings) (291de77) 2020-08-16 Florian Leeber * Merge pull request #57 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (8a144a0) 2020-08-08 Weblate * Translated by satriocode using Weblate (Indonesian) - 100.0% (22 of 22 strings) (bc94a5a) 2020-08-03 Florian Leeber * Merge pull request #56 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (02493d6) 2020-08-01 Weblate * Translated by ffsi using Weblate (Portuguese (Brazil)) - 100.0% (22 of 22 strings) (6d86914) 2020-07-20 Weblate * Translated using Weblate (Dutch) (7cedcee) 2020-05-26 Florian Leeber * Merge pull request #55 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (f037ad2) 2020-05-19 Pavel Borecki * Translated using Weblate (Czech) (feb92f3) 2020-05-18 Pavel Borecki * Translated using Weblate (Czech) (b6d4c89) 2020-05-13 Mike * Translated using Weblate (Italian) (e2ad52a) 2020-05-10 Florian Leeber * Merge pull request #54 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (dc9bd0c) 2020-05-08 Ryan Argente * Translated using Weblate (French (Canada)) (7aa615b) 2020-03-30 Florian Leeber * Merge pull request #53 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (c1dc1ca) 2020-03-24 Weblate * Merge branch 'origin/xenial' into Weblate. (c0bf100) 2020-03-24 Florian Leeber * Merge pull request #52 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (3f98fae) 2020-03-21 Ryan Argente * Translated using Weblate (French (Canada)) (50da509) 2020-03-17 cflep * Translated using Weblate (Luxembourgish) (d9b7715) 2020-03-09 Florian Leeber * Merge pull request #51 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (02c86da) 2020-03-06 Neutrum N * Translated using Weblate (Galician) (8faae48) 2020-03-05 Neutrum N * Translated using Weblate (Galician) (127e315) 2020-03-02 Florian Leeber * Merge pull request #50 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (72e94a1) 2020-02-28 Pavel Borecki * Translated using Weblate (Czech) (655f9a0) 2020-02-24 dano6 * Translated using Weblate (Slovak) (d61de77) 2020-02-24 Florian Leeber * Merge pull request #49 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (64368d5) 2020-02-20 Ryan Argente * Translated using Weblate (French (Canada)) (f2652ee) 2020-02-17 Riccardo Riccio * Translated using Weblate (Slovenian) (71b02a9) 2020-02-16 Weblate * Merge branch 'origin/xenial' into Weblate. (1669728) 2020-02-16 dano6 * Translated using Weblate (Slovak) (5d0e526) 2020-02-16 Florian Leeber * Merge pull request #48 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (f1ccf26) 2020-02-15 HSN80 * Translated using Weblate (Persian) (a80f4b7) 2020-02-10 HSN80 * Translated using Weblate (Persian) (877b2db) 2020-02-09 Rodrigo Benedito * Translated using Weblate (Portuguese (Brazil)) (c399f96) 2020-02-09 Florian Leeber * Merge pull request #47 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (4f55994) 2020-02-05 Ege Öz * Translated using Weblate (Turkish) (b762842) 2020-01-27 Florian Leeber * Merge pull request #46 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (476c7a3) 2020-01-22 Weblate * Merge branch 'origin/xenial' into Weblate. (ce3c526) 2020-01-22 Florian Leeber * Merge pull request #45 from cibersheep/ColorAndComponentUpgrade (4746a9b) 2020-01-22 Joan CiberSheep * UbuntuColors to theme palette, update components (302cf4b) 2019-12-20 M.Sugahara * Translated using Weblate (Japanese) (772fd8d) 2019-12-12 Sami Törmänen * Translated using Weblate (Finnish) (3a1783e) 2019-12-20 Eugene * Translated using Weblate (Russian) (3af7912) 2019-11-10 Florian Leeber * Merge pull request #44 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (13f31ae) 2019-11-02 Ege Öz * Translated using Weblate (Turkish) (4b55820) 2019-11-03 Florian Leeber * Merge pull request #43 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (b669706) 2019-10-28 enolp * Translated using Weblate (Asturian) (4b3695f) 2019-10-15 Florian Leeber * Merge pull request #42 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (6f4f7b2) 2019-10-04 Sami Törmänen * Translated using Weblate (Finnish) (f9f11db) 2019-09-30 Florian Leeber * Merge pull request #41 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (a576459) 2019-09-24 Moo * Translated using Weblate (Lithuanian) (0de57f2) 2019-08-08 Florian Leeber * Merge pull request #40 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (73b9e08) 2019-08-01 Moo * Translated using Weblate (Lithuanian) (a42b84f) 2019-07-26 Florian Leeber * Merge pull request #39 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (13935d9) 2019-07-15 Yasser Lotfy * Translated using Weblate (Arabic) (9349443) 2019-07-12 Florian Leeber * Merge pull request #38 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (537e83b) 2019-07-05 Aitzol Berasategi * Translated using Weblate (Basque) (4eb2d81) 2019-06-28 Florian Leeber * Merge pull request #37 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (b11cc57) 2019-06-21 lxdb * Translated using Weblate (English (United States)) (36e4072) 2019-05-07 Florian Leeber * Merge pull request #36 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (8411a55) 2019-05-05 Aurelio Cilia * Translated using Weblate (Italian) (671f88e) 2019-05-04 Florian Leeber * Merge pull request #35 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (bc48e8b) 2019-05-01 louies0623 * Translated using Weblate (Chinese (Traditional)) (b9f2239) 2019-04-29 Joan CiberSheep * Translated using Weblate (Catalan) (d45c7d3) 2019-04-27 Jiri Grönroos * Translated using Weblate (Finnish) (a67a87e) 2019-04-28 Walter Garcia-Fontes * Translated using Weblate (Catalan) (37f66f4) 2019-04-25 Florian Leeber * Merge pull request #34 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (5749d56) 2019-04-25 Vinícius F * Translated using Weblate (Portuguese (Brazil)) (0250e7a) 2019-04-23 不朽正义 * Translated using Weblate (Chinese (Simplified)) (42cfa64) 2019-04-17 Weblate * Merge branch 'origin/xenial' into Weblate (877e7be) 2019-04-17 Florian Leeber * Merge pull request #33 from StefWe/exposeUX (0ccb6a3) 2019-04-17 Stefan * Main action arranged on the right and Cancel now has a neutral color (88cb878) 2019-04-16 Weblate * Merge branch 'origin/xenial' into Weblate (2c7a2fa) 2019-04-16 Florian Leeber * Merge pull request #31 from StefWe/compression (d13416f) 2019-04-15 Stefan * using default compression on saving an edited image (3ade3fb) 2019-04-14 Weblate * Merge branch 'origin/xenial' into Weblate (5c0b3b4) 2019-04-14 Florian Leeber * Merge pull request #29 from StefWe/exposure (925cb3e) 2019-04-12 Stefan Weng * Merge branch 'exposure' of https://github.com/StefWe/ubuntu-ui-extras into exposure (332ed26) 2019-04-12 Stefan * Exposure function activated (efc5bc3) 2019-04-12 Weblate * Merge branch 'origin/xenial' into Weblate (43b7ac4) 2019-04-11 Stefan Weng * Translated using Weblate (German) (c09b577) 2019-04-12 Florian Leeber * Merge pull request #28 from StefWe/issue3 (89ec3e6) 2019-04-12 Stefan * Exposure function activated (1007eb1) 2019-04-11 Aashrut * Translated using Weblate (Gujarati) (c93e16a) * Added translation using Weblate (Gujarati) (827963e) 2019-04-11 Stefan * using i18n.dtr instead of i18n.tr (80d4f68) 2019-04-01 louies0623 * Translated using Weblate (Chinese (Traditional)) (f3ad7eb) 2019-03-26 Tom Dom * Translated using Weblate (Dutch) (7261420) 2019-03-23 Florian Leeber * Merge pull request #27 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (ca9c4ff) 2019-03-12 Rúben Carneiro * Translated using Weblate (Portuguese) (fb2c0cb) 2019-02-11 advocatux * Translated using Weblate (Spanish) (03cc9d6) 2019-03-03 Anne Onyme * Translated using Weblate (French) (6ec7823) 2019-02-12 Milan Korecký * Translated using Weblate (Czech) (18311a3) 2019-02-11 Weblate * Merge branch 'origin/xenial' into Weblate (1d6db53) 2019-02-11 Heimen Stoffels * Translated using Weblate (Dutch) (2fabdb4) 2019-02-11 Florian Leeber * Merge pull request #26 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (772acc6) 2019-01-21 louies0623 * Translated using Weblate (Japanese) (1bd6638) 2019-01-16 Florian Leeber * Merge pull request #25 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (0c1d967) 2019-01-03 Ennio Lavagnini * Translated using Weblate (Italian) (bceea97) 2019-01-01 Jaume Angrill * Translated using Weblate (Catalan) (d36b510) 2018-12-26 Florian Leeber * Merge pull request #24 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (152ad13) 2018-12-19 Hussain Hashem Aljafri * Translated using Weblate (Arabic) (3a12a18) 2018-12-18 Louies * Added translation using Weblate (English (United States)) (bae5440) 2018-12-13 P_E_T_O * Translated using Weblate (Slovak) (b688361) 2018-11-25 Florian Leeber * Merge pull request #23 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (db601ed) 2018-11-18 advocatux * Translated using Weblate (Spanish) (6e46715) 2018-11-22 Louies * Translated using Weblate (Esperanto) (409889d) * Translated using Weblate (Chinese (Traditional)) (31397b7) * Translated using Weblate (Chinese (Hong Kong)) (4334488) 2018-11-11 Samson * Translated using Weblate (Amharic) (0227614) 2018-11-22 Louies * Translated using Weblate (Chinese (Hong Kong)) (a4171d7) 2018-11-11 Florian Leeber * Merge pull request #22 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (689dafd) 2018-11-05 advocatux * Translated using Weblate (Spanish) (6266725) 2018-11-09 Aurelio Cilia * Translated using Weblate (Italian) (3c7328f) 2018-11-05 Anne Onyme * Translated using Weblate (French) (f584447) 2018-11-09 Jiri Grönroos * Translated using Weblate (Finnish) (5e9b11e) 2018-11-05 Louies * Translated using Weblate (Chinese (Traditional)) (4dab997) 2018-11-05 Joan CiberSheep * Translated using Weblate (Catalan) (1cd9a0e) 2018-11-10 Sander * Translated using Weblate (Dutch) (299cead) 2018-11-04 Florian Leeber * Merge pull request #21 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (67ae212) 2018-10-31 ierihon * Translated using Weblate (Русский) (fce7d40) 2018-10-28 Florian Leeber * Merge pull request #20 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (38ebaa6) 2018-10-23 Louies * Translated using Weblate (Esperanto) (5d1d78e) 2018-10-25 Louies * Translated using Weblate (Chinese (Traditional)) (c8fa222) * Translated using Weblate (漢語(正體字)) (fb7f222) 2018-10-25 P.-H. Lin * Translated using Weblate (漢語(正體字)) (c32a7d5) 2018-10-23 Louies * Translated using Weblate (Chinese (Traditional)) (9d77cf9) 2018-10-23 Weblate * Merge branch 'origin/xenial' into Weblate (800a155) 2018-10-22 Louies * Translated using Weblate (Chinese (Traditional)) (db64c0b) 2018-10-23 Florian Leeber * Merge pull request #18 from jonnius/disabletests (aace6fd) 2018-10-21 Florian Leeber * Merge pull request #19 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (9dea716) 2018-10-19 M.Sugahara * Translated using Weblate (Japanese) (24ed6fd) 2018-10-21 Jonatan Hatakeyama Zeidler * Disable tests by default (b3c2534) 2018-10-14 Florian Leeber * Merge pull request #17 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (ca73bfa) 2018-09-08 SongInseo * Translated using Weblate (Koreanisch) (dbdeb84) 2018-10-04 Neutrum N * Translated using Weblate (Galicisch) (3f67a92) 2018-10-05 Milan Korecký * Translated using Weblate (Tschechisch) (5048f60) 2018-09-15 Tom Rausner * Translated using Weblate (Danish) (86fe2cc) 2018-09-02 Jan Sprinz * Merge pull request #16 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (80a3720) 2018-09-01 Weblate * Merge remote-tracking branch 'origin/xenial' into xenial (bdfc7cf) 2018-08-23 P_E_T_O * Translated using Weblate (Slovak) (a0dff66) 2018-08-19 Jiri Grönroos * Translated using Weblate (Finnish) (69c8517) 2018-08-26 Øjvind Fritjof Arnfred * Translated using Weblate (Danish) (71f811a) 2018-08-27 Ahmed Suliman * Translated using Weblate (Arabic) (994a891) 2018-09-01 Florian Leeber * Merge pull request #15 from ubports-weblate/weblate-ubports-ubuntu-ui-extras (b127390) 2018-09-01 Weblate * Merge branch 'xenial' of https://github.com/ubports/ubuntu-ui-extras into xenial (d07d053) 2018-08-19 Tom Rausner * Translated using Weblate (Danish) (b90a7db) * Translated using Weblate (Danish) (c475e51) 2018-08-12 ubports-weblate * Update from Weblate. (#14) (3bcf5cd) 2018-08-08 ierihon * Translated using Weblate (Belarusian) (cc95f23) * Translated using Weblate (Belarusian) (9b0aa1d) 2018-07-30 thanakit srisearmpok * Translated using Weblate (Thai) (935c36d) 2018-08-05 Tom Rausner * Translated using Weblate (Danish) (d52f92b) 2018-07-29 Tom Rausner * Translated using Weblate (Danish) (979eeab) 2018-08-05 ubports-weblate * Translated using Weblate (German) (#13) (1ad6daa) 2018-07-21 ubports-weblate * Update from Weblate. (#12) (0be8140) 2018-05-13 ubports-weblate * Update from Weblate. (#11) (a720356) 2018-05-11 Florian Leeber * Seriously? (76b3845) * And it happened again, removing excess " (8f17393) 2018-05-11 ubports-weblate * Update from Weblate. (#10) (488a0a2) 2018-05-11 StefWe * Did some manually fix in the translation .po files (#8) (3db65af) 2018-05-11 ubports-weblate * Update from Weblate. (#9) (a47d1f6) 2018-05-10 ubports-weblate * Update POT (#7) (86ac70d) * Update from Weblate. (#6) (390dcaa) * Update from Weblate. (#5) (35b7e49) 2018-05-06 ubports-weblate * Update from Weblate. (#4) (c7a578f) 2018-05-02 Florian Leeber * Merge pull request #2 from StefWe/xenial (b5da30e) 2018-05-02 Stefan Weng * Merge branch 'xenial' of https://github.com/StefWe/ubuntu-ui-extras into xenial (ecfaee0) * combined "Revert to original" and "Revert to Original" so only one must be translated (311ccf2) 2018-05-02 Stefan * cmake-extra added (56bb9ab) * made a list of all dependencies for faster setup next time (235c093) 2018-01-07 Marius Gripsgard * Imported to UBports (13dd817) 2017-04-04 Jonas G. Drange * sets a default printer on provisioning if there is none (49a4f0d) * ensures that there are no races in provisioning a printer (82ae8d4) 2017-04-03 Andrew Hayzen * Fix changing of printer not loading defaults and add a tes. Improve colorModel struct to != when name or colorModelType are different (fa487d1) 2017-04-03 Jonas G. Drange * sets a default printer on provisioning if there is none (ae71c28) 2017-04-03 Andrew Hayzen * Update comments (a21b9ca) * Rebase on staging (39739e3) * Fix changing of printer not loading defaults and add a tes. Improve colorModel struct to != when name or colorModelType are different (d618253) 2017-03-31 Andrew Hayzen * Set m_copies when using updateFrom and add test for updateFrom (3e505ba) * Remove debug line (0094fb7) * Add test for updateFrom (7f5fdac) * Set m_copies when using updateFrom (e46878e) 2017-03-23 Bileto Bot * Releasing 0.3+17.04.20170323-0ubuntu1 (786095c) * Adds devices as an model on Printers, and re-instates remote printer model on Printers.; makes sure the backend is refreshed on enable/disable; If printerAdded is called ensure there is always a proxy printer corrects thread affinity for printerloaded printers, as well as any qobject children it might have; Remove PrinterQueue.qml example and add missing job methods to Printers.qml example, so we have only one example; improves the deviceName by dropping the CMD (note that the full string remains accessible from device.id); Connect job-impressions-completed from cups to PrinterJob::impressionsCompleted(); In the job model listen to printerStateChanged as changes t job-impressions-completed causes that signal; Improve the PrinterSignalHandler to limit the maximum wait time of unprocessed signals to four times the timeout; Add unit test for SignalRateLimiter to check it does perform a flush; Rename PrinterSignalHandler to SignalRateLimite. Add a JobLoader for loading a specific jobId for a printer and loading the extended attributes; Move the loading of creationTime, completedTime, processingTime, size and user to extended attributes as signals don't give us thos. Add method for PrinterBackend for getting a specific jo. Split up JobModel::update so there is jobCreated, jobState and jobCompleted which then call addJob, removeJob and updateJob; Improve Printer::updateFrom to not call loadAttributes as this results in a possible UI bloc. Add missing comparisions for PrinterJob deepCompare and updateFrom; Change PrinterJob::setPrinter to not call loadDefaults and instead explicitly call it; Change Printers to trigger requestJobExtendedAttributes which triggers a background thread rather than doing in foreground; exposes copies attribute on the printe. includes cups/adminutils.h into which the cups device callback was moved in >= libcups2-dev 2.2.2; allows browsing on local and remote printers; Add filters for active, paused and queued; Add sorting by creationTime and then falling back to id; Change time related roles in JobModel to return QDateTime, not QString, so sorting doesn't break; Update tests; Change printerGetJobAttributes to use printer-uri and job-id (the same as holdJob and releaseJob; Give printerGetJobAttributes printerName so we can ensure we get the correct job; adds read/write of the shared property; adds extended attribute fetching (IppClient::printerGetAttributes); refactors attribute retrieval from cups; implements deviceUri and lastMessage on Printer; adds Printers.printTestPage; Add tests for JobModel roles; Add tests for make and location in Printer; Fix JobModel color and quality roles to use fallback if no text; Add tests for all roles in PrinterModel; Remove PdfRole it is not used (IsPdfRole instead); Add holdJob and releaseJob methods to Printers * Add HeldRole to JobModel; Add tests for hold and releasing a job; Update example to show how hold and release work; Update StateRole to return just the state, not text; Remove PrinterJob friends and make setters public as they aren't exposed to QML anyway; adds make and location to printermodel and printer; Pull of trun. Remove use of bitewise or as it fails in CI; guards against excessive loading of printers and drivers; adds loadPrinter method on Printers; drops a lot of code that was not used, and some TODOS/FIXMES that aren't necessary * Fix/add commented or empty tests; Implement tests that had QSKIP; removes empty brackets; adds cmake extras, required by printer stuff; Remove remaining fixme'. Rename UbuntuSettingsComponentsPrintersPlugin to UbuntuComponentsExtrasPrintersPlugin; Remove import Ubuntu.Settings.Components 0.1 from example qml import. Rename definition UBUNTUSETTINGSPRINTERS_LIBRARY to UBUNTUCOMPONENTSEXTRASPRINTERS_LIBRARY; Rename UbuntuSettingsPrintersQml to UbuntuComponentsExtrasPrintersQml; Rename translation domain to ubuntu-ui-extras; Fix for printsupport being build-depends rather than depends (c6427e0) 2017-03-23 Jonas G. Drange * Adds second phase of printer components. (d61bd82) 2017-03-22 Jonas G. Drange * bumps version (d37d9e8) * syncs with trunk (eca81e8) * updates changelog (320292b) * Adds devices as an model on Printers, and re-instates remote printer model on Printers. (8c777c8) * makes sure the backend is refreshed on enable/disable (e6e66b8) * move example to use devices instead of remotePrinters (ce1b061) 2017-03-21 Jonas G. Drange * adds devices as an model, and re-instates remote printers model (cd8b489) * makes sure the backend is refreshed on enable/disable (44c00f2) 2017-03-20 Jonas G. Drange * bumps version (cf87d5d) * syncs with trunk (f7330be) 2017-03-20 Andrew Hayzen * If printerAdded is called ensure there is always a proxy printer (4241e3d) 2017-03-20 Jonas G. Drange * corrects thread affinity for printerloaded printers, as well as any qobject children it might have (c51e797) * corrects thread affinity for printerloaded printers, as well as any qobject children it might have (936dcdc) 2017-03-20 Andrew Hayzen * If printerAdded is called ensure there is always a proxy printer * Update printerLoaded to use getPrinterByName to improve DRY (29d6194) * Remove PrinterQueue.qml example and add missing job methods to Printers.qml example, so we have only one example (94094b0) 2017-03-20 Jonas G. Drange * improves the deviceName by dropping the CMD (note that the full string remains accessible from device.id) (7aaa68e) 2017-03-19 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (e4df768) 2017-03-16 Andrew Hayzen * Pull of upstream (66a675e) * Connect job-impressions-completed from cups to PrinterJob::impressionsCompleted(); In the job model listen to printerStateChanged as changes t job-impressions-completed causes that signal; Improve the PrinterSignalHandler to limit the maximum wait time of unprocessed signals to four times the timeout; Add unit test for SignalRateLimiter to check it does perform a flush; Rename PrinterSignalHandler to SignalRateLimiter (ee44cae) 2017-03-16 Jonas G. Drange * removes CMD from MDL (e18eece) 2017-03-16 Andrew Hayzen * Add a JobLoader for loading a specific jobId for a printer and loading the extended attributes; Move the loading of creationTime, completedTime, processingTime, size and user to extended attributes as signals don't give us thos. Add method for PrinterBackend for getting a specific jo. Split up JobModel::update so there is jobCreated, jobState and jobCompleted which then call addJob, removeJob and updateJob; Improve Printer::updateFrom to not call loadAttributes as this results in a possible UI bloc. Add missing comparisions for PrinterJob deepCompare and updateFrom; Change PrinterJob::setPrinter to not call loadDefaults and instead explicitly call it; Change Printers to trigger requestJobExtendedAttributes which triggers a background thread rather than doing in foreground (c046f7e) * Set timezone after time_t (f39231c) * Fix timezones, internally use UTC then when exposing to QML set as local timezone (c2589c0) 2017-03-15 Andrew Hayzen * Pull of upstream (f21711d) * Set timezone for completedTime, creationTime, processingTime in PrinterJob (53fbdb8) * Pull of upstream; Fix tests (emulation in MockBackend::printerGetJobAttributes) (b74ec77) * Change JobLoader to only respond with a QMap of attributes and not a PrinterJob; Change Printers to directly call JobModel::updateJobPrinter; Remove headers we don't need in JobLoader; Change FIXME to TODO; Update tests (595bcc9) 2017-03-14 Andrew Hayzen * Try to use job-media-sheets-completed first (eafb0e3) * Pull of upstream (cc94670) * Use tryLock instead of lock and print a warning (936f36f) * Fix missed renames; Fix failing tests; Actually set the printer from JobLoader to the PrinterJob in JobModel, even if it isn't loaded to keep the reference up to date; Improve emulation to be closer to real (94526e0) * Pull of upstream (9dd873e) * Rename m_activeRequests to m_activePrinterRequests; Update JobModel::updateJob description (55915ce) * Remove MockPrinters and use Printers directly (41bd73a) * Resolve failing tests with new JobLoader changes; Add comments (c57d1bf) 2017-03-14 Jonas G. Drange * exposes copies attribute on the printer (5203df2) * address andrew's comment (243b451) 2017-03-13 Andrew Hayzen * Use job-state from extendedJobAttributes so that when there is a signal flood the state is correct (e61e076) 2017-03-13 Jonas G. Drange * includes cups/adminutils.h into which the cups device callback was moved in >= libcups2-dev 2.2.2 (037f886) * includes adminutils (87781cf) 2017-03-13 Andrew Hayzen * Pull of upstream (d8b82ac) * Add QMutex to IppClient::printerGetAttributes to make it thread safe; Reuse the same Printer backend in JobLoader; Don't worry about having not Printer in PrinterJob::loadDefaults * Remove some debug (46dd20c) 2017-03-13 Jonas G. Drange * address comment from andrew (beb8ee9) 2017-03-13 Andrew Hayzen * Rebase ontop of lp:~ahayzen/ubuntu-ui-extras/job-model-split-update (ed554cf) * Remove move methods in models they aren't used anymore (filters instead); Add initial code in JobLoader to only load a printer if an unloaded one is given; Remove commented code (625dd5c) * First iteration of improvements for loading jobs in a background thread; Add a JobLoader for loading a specific jobId for a printer and loading the extended attributes; Move the loading of creationTime, completedTime, processingTime, size and user to extended attributes as signals don't give us those; Add method for PrinterBackend for getting a specific job; Split up JobModel::update so there is jobCreated, jobState and jobCompleted which then call addJob, removeJob and updateJob; Improve Printer::updateFrom to not call loadAttributes as this results in a possible UI block; Add missing comparisions for PrinterJob deepCompare and updateFrom; Change PrinterJob::setPrinter to not call loadDefaults and instead explicitly call it; Change Printers to trigger requestJobExtendedAttributes which triggers a background thread rather than doing in foreground (a7295dc) 2017-03-10 Jonas G. Drange * conforms to APS (64a6bd5) * syncs with printer-staging (9f1be0b) * implements the behaviour andrew laid out in MP (aea0047) 2017-03-10 Andrew Hayzen * Merge of upstream (74df5fd) * Merge of upstream (80592cc) 2017-03-10 Jonas G. Drange * allows browsing on local and remote printers (4820c66) 2017-03-09 Andrew Hayzen * Remove PrinterQueue.qml example and add missing job methods to Printers.qml example, so we have only one example (ce698a1) 2017-03-09 Jonas G. Drange * avoids unecessary sort (6cf7bcf) 2017-03-09 Andrew Hayzen * Show impressions in the PrinterQueue.qml (2117444) 2017-03-09 Jonas G. Drange * show indicator while loading (eba9e4d) 2017-03-09 Andrew Hayzen * Add unit test for SignalRateLimiter to check it does perform a flush (1427d9d) * Rename PrinterSignalHandler to SignalRateLimiter (444011a) 2017-03-09 Jonas G. Drange * expose what protocol it is (1b661b7) * use device uri if it exists (d8fc09e) 2017-03-09 Andrew Hayzen * Connect job-impressions-completed from cups to PrinterJob::impressionsCompleted(); In the job model listen to printerStateChanged as changes t job-impressions-completed causes that signal; Improve the PrinterSignalHandler to limit the maximum wait time of unprocessed signals to four times the timeout (9bf5790) 2017-03-09 Jonas G. Drange * clarify the id splitting (27ba039) 2017-03-08 Jonas G. Drange * removes commented code (2425e09) * finish example addition of network printers (0d7ac24) * implements type in device (24a05ab) * tests devicemodel (85f4796) * merges in printer-getdevices (f44c5a5) * implements devicesearcher (ba5c6a4) 2017-03-07 Jonas G. Drange * adds testing of copies (42dadae) * add visible test of local/remote printers (a46c722) 2017-03-06 Jonas G. Drange * lazily initialize remote/local filters (9960f6b) * syncs with trunk (b8301f6) * syncs with trunk (8b290c6) * adds remote semantics (0440242) 2017-03-06 Andrew Hayzen * Add filters for active, paused and queued; Add sorting by creationTime and then falling back to id; Change time related roles in JobModel to return QDateTime, not QString, so sorting doesn't break; Update tests (44ce9e0) * Change QList to QSet; Add qHash for JobState; Make Q_INVOKABLE methods Q_SLOTS; Add comment about QML ownership (2f71d68) * Add filters for active, paused and queued; Add sorting by creationTime and then falling back to id; Change time related roles in JobModel to return QDateTime, not QString, so sorting doesn't break; Update tests (883e833) 2017-03-03 Andrew Hayzen * Change printerGetJobAttributes to use printer-uri and job-id (the same as holdJob and releaseJob; Give printerGetJobAttributes printerName so we can ensure we get the correct job (d84be79) * Change printerGetJobAttributes to use printer-uri and job-id (the same as holdJob and releaseJob; Give printerGetJobAttributes printerName so we can ensure we get the correct job (66acd74) 2017-03-03 Jonas G. Drange * adds read/write of the shared property (617330d) * end to end copies (8b0fea6) * adds copy delegate (4b54f58) * adds delegate for shared (f38a81e) * adds role, small refactor in backend (db1c3f8) * define api for copy (489e1e8) * allow read/write of shared (72da119) 2017-03-02 Jonas G. Drange * adds extended attribute fetching (IppClient::printerGetAttributes); refactors attribute retrieval from cups; implements deviceUri and lastMessage on Printer (43c6cb6) * lols (c9b6083) * deepcompare must consider deviceUri (2cab0cf) * adds new printer attributes to example, and fixes some rendering issues in said thing (abbe9ae) * comment on smelly C array stuff, implement laststatemessage (2f7dc5d) * adds tests (3b6cd4f) * drops some whitespace (181b4bd) * sync with trunk (7669df9) * adds Printers.printTestPage (aa32d99) * refactors the way we ask for extended attributes so as to ask for them maximum once (b780f42) * adds device uri (f370d93) 2017-03-02 Andrew Hayzen * Add tests for JobModel roles; Add tests for make and location in Printer; Fix JobModel color and quality roles to use fallback if no text; Add tests for all roles in PrinterModel; Remove PdfRole it is not used (IsPdfRole instead) (5ad98e3) * Rebase onto lp:~phablet-team/ubuntu-ui-extras/printer-staging (465737d) * Add tests for JobModel roles; Add tests for make and location in Printer; Fix JobModel color and quality roles to use fallback if no text (141687a) 2017-03-02 Jonas G. Drange * adds Printers.printTestPage (7dd7ab3) 2017-03-02 Andrew Hayzen * Add holdJob and releaseJob methods to Printers; Add HeldRole to JobModel; Add tests for hold and releasing a job; Update example to show how hold and release work; Update StateRole to return just the state, not text; Remove PrinterJob friends and make setters public as they aren't exposed to QML anyway (91ad465) 2017-03-02 Jonas G. Drange * adds make and location to printermodel and printer (a679819) 2017-03-01 Bileto Bot * Releasing 0.2+17.04.20170301.2-0ubuntu1 (8ef72a7) 2017-03-01 Andrew Hayzen * Add printer-components from ubuntu-settings-components to ubuntu-ui-extras (original branch https://code.launchpad.net/~phablet-team/ubuntu-settings-components/printer-components) * Add plugin module to Extras/Printers; Add translation support for cpp/h; Add tests for Printers; Add debian depends (c6aef79) * Add tests for two new roles from lp:~jonas-drange/ubuntu-ui-extras/make-and-location (a734f2e) * Rebase on lp:~jonas-drange/ubuntu-ui-extras/make-and-location so we can add tests :-) (eb52e76) * Add tests for all roles in PrinterModel; Remove PdfRole it is not used (IsPdfRole instead) (bd2901e) 2017-03-01 Jonas G. Drange * adds make and location to printermodel and printer (844076c) * drop qwarning (1d1e8e5) * syncs with trunk (0143434) * refactors attribute retrieval from cups, adds extended attribute fetching (4c12675) 2017-03-01 Andrew Hayzen * Remove PrinterJob friends and make setters public as they aren't exposed to QML anyway (0ca7237) * Fix typo in example (9c087d1) * Add holdJob and releaseJob methods to Printers; Add HeldRole to JobModel; Add tests for hold and releasing a job; Update example to show how hold and release work; Update StateRole to return just the state, not text (7eb4f2e) 2017-02-28 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (5f8e31c) 2017-02-24 Andrew Hayzen * Pull of trunk (8b6e478) * Remove use of bitewise or as it fails in CI (632279a) * Remove use of bitewise or as it fails in CI (717cf38) 2017-02-24 Jonas G. Drange * guards against excessive loading of printers and drivers (cbb284b) * adds loadPrinter method on Printers (22be218) * qlist->qset (c5b6131) * guard against excessive driver loading (cb6c8dc) * adds loadPrinter method on Printers (5abf557) * adds logic for only requesting non-requested printers (080973c) 2017-02-23 Jonas G. Drange * drops a lot of code that was not used, and some TODOS/FIXMES that aren't necessary (e7c5fe9) * syncs with trunk (6fef709) * drops a lot of code that was not used, and some TODOS/FIXMES that aren't necessary (32f5e1d) 2017-02-23 Andrew Hayzen * Fix/add commented or empty tests (9ea055d) * Remove Q_UNUSED on parameters that are now used :-) (8624723) * Pull of upstream (6539c0e) * Fix/add commented or empty tests (a1f2fbb) * Implement tests that had QSKIP (d3296a9) 2017-02-23 Jonas G. Drange * removes empty brackets (f38b713) 2017-02-23 Andrew Hayzen * Implement tests that had QSKIP (e44fabc) 2017-02-22 Jonas G. Drange * removes {} which caused a non-printer to always be loaded if no default (a6d264a) * adds cmake extras, required by printer stuff (955163a) * adds required dep (f74fb87) 2017-02-22 Bileto Bot * Releasing 0.2+17.04.20170222-0ubuntu1 (916d829) 2017-02-22 Andrew Hayzen * Add qtdeclarative5-dev-tools, qml-module-ubuntu-test and xvfb as build-deps; Order build-deps alphabetically (LP: #1666556) (c73447c) * When the tab is being destroyed unset the source of the TabIcon Loader (35f7d67) * Add qml-module-qtqml-models2 as a depends, as it was missing (a0c9da2) * Add qtdeclarative5-dev-tools, qml-module-ubuntu-test and xvfb as build-deps; Order build-deps alphabetically (3703946) 2017-02-21 Andrew Hayzen * Remove remaining fixme's (abf2e94) * Rename UbuntuSettingsComponentsPrintersPlugin to UbuntuComponentsExtrasPrintersPlugin; Remove import Ubuntu.Settings.Components 0.1 from example qml imports (abaaab7) * Rename definition UBUNTUSETTINGSPRINTERS_LIBRARY to UBUNTUCOMPONENTSEXTRASPRINTERS_LIBRARY (98f1939) * Rename UbuntuSettingsPrintersQml to UbuntuComponentsExtrasPrintersQml; Rename translation domain to ubuntu-ui-extras; Fix for printsupport being build-depends rather than depends (3651371) * Add printer-components from ubuntu-settings-components to ubuntu-ui-extras (original branch https://code.launchpad.net/~phablet-team/ubuntu-settings-components/printer-components) * Add plugin module to Extras/Printers; Add translation support for cpp/h; Add tests for Printers; Add debian depends (36859b6) 2017-02-15 Andrew Hayzen * When the tab is being destroyed unset the source of the TabIcon Loader (d2a9d57) 2017-02-13 Andrew Hayzen * Add qml-module-qtqml-models2 as a depends, as it was missing (b06c10e) 2017-02-02 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (4e6ef43) 2017-02-01 Bileto Bot * Resync trunk. (5e9d16b) 2017-01-30 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (126a9c0) 2017-01-16 Bileto Bot * Releasing 0.2+17.04.20170116-0ubuntu1 (4d169b3) 2017-01-16 Florian Boucault * New component: TabsBar (8f4edf1) * Support transparent background colors. (d8c0620) 2017-01-09 Andrew Hayzen * Add drag and drop support to tabs component (f98e9aa) 2017-01-06 Andrew Hayzen * Add removeTabWithoutDestroying; Change behaviour of dimmed rectangle to always undim when inside the droparea (19f050e) 2017-01-03 Andrew Hayzen * Resolve issue with type being inside qualified namespace; Clean some code comments (80dd38a) * Remove use of singleton and add "dimmed" property instead (024f2f6) 2016-12-21 Andrew Hayzen * Add objectName for listview (5d2d66e) * Add drag and drop support to tabs component (d7cb181) 2016-12-09 Florian Boucault * Removed unused tab PNGs. (655325c) 2016-12-08 Florian Boucault * Introduce TabsBar in 0.3 (92053b8) * New component: TabsBar (1ae7df6) 2016-10-04 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (07ea98a) 2016-10-03 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (48753c8) 2016-10-02 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (341dda7) 2016-09-20 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (d3823d5) 2016-08-31 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (5df566b) 2016-08-24 Bileto Bot * Releasing 0.2+16.10.20160824.1-0ubuntu1 (2c14ce8) 2016-08-24 Timo Jyrinki * Stop depending on transitional packages. (LP: #1583079) (LP: #1583079) (5c189bb) 2016-08-24 Florian Boucault * Fix image orientation in photo image provider for Qt>=5.5 (596094b) * Fixed corresponding unit test (23edf87) * For Qt5.5 and above, manually rotate images with orientation tags set when applying any transformation. (e16d94b) 2016-08-23 Florian Boucault * Fix image orientation in photo image provider for Qt>=5.5. (2754677) 2016-08-22 Florian Boucault * Photo editor: mirrored icon for rotation action. (21065c0) 2016-07-20 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (b05160e) 2016-07-14 Bileto Bot * Releasing 0.2+16.10.20160714-0ubuntu1 (ebaf8f0) 2016-07-14 Florian Boucault * Fixes for crossbuilding. (ecb3f08) 2016-07-11 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (b401f2b) 2016-07-06 Florian Boucault * Fixes for crossbuilding. (afa041d) 2016-07-04 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (a28b490) 2016-06-26 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (819d218) 2016-06-17 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (6452d0c) 2016-06-09 Bileto Bot * Releasing 0.2+16.10.20160609.1-0ubuntu1 (b400461) 2016-06-09 Arthur Mello * Specify the domain "ubuntu-ui-extras" for i18n messages (LP: #1521222) (246629a) 2016-06-09 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (a49b02d) 2016-06-07 Arthur Mello * Merge with trunk (a0e67a4) 2016-06-06 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (b57b9d0) 2016-06-05 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (f8d4f1e) 2016-05-18 Timo Jyrinki * Stop depending on transitional packages. (LP: #1583079) (15b963a) 2016-05-11 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (580886a) 2016-05-03 CI Train Bot * Releasing 0.2+16.04.20160503-0ubuntu1 (34cc5e0) 2016-05-03 Florian Boucault * Qt now takes into account the EXIF orientation data when loading pictures; the rotation workaround is no longer necessary. Approved by: PS Jenkins bot, Ugo Riboni (51d7463) 2016-04-29 Arthur Mello * Specify the domain "ubuntu-ui-extras" for i18n messages (b13cf5b) 2016-04-27 Florian Boucault * Qt now takes into account the EXIF orientation data when loading pictures; the rotation workaround is no longer necessary. (dbdea4b) 2016-04-26 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (26e4169) 2016-03-27 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (534acf1) 2016-03-23 CI Train Bot * Releasing 0.2+16.04.20160323.1-0ubuntu1 (60d21b3) 2016-03-23 Arthur Mello * Do not remove files during photo editor's copy process Fixes: #1549991 Approved by: PS Jenkins bot (f22b354) 2016-03-23 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (b34290f) 2016-03-15 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (d468d72) 2016-03-01 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (9404d89) 2016-02-29 CI Train Bot * Resync trunk. (150483b) 2016-02-28 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (6dcf6c0) 2016-02-25 CI Train Bot * Releasing 0.2+16.04.20160225-0ubuntu1 (28e0158) 2016-02-25 Florian Boucault * When rotating pictures during edit, write the EXIF orientation tag with the right type (unsigned short) instead of signed long. PhotoImageProvider: change its behaviour to only rectify the EXIF orientation tag type when necessary (removes all other behaviours: caching, etc.) Fixes: #1541210 Approved by: PS Jenkins bot, Arthur Mello (b221433) 2016-02-25 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (f7d23f8) 2016-02-23 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (afafaf0) 2016-02-16 Arthur Mello * Remove original file after renaming process (faaf81e) * Do not remove files during photo editor's copy process (ca093c4) 2016-02-13 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (b4b7714) 2016-02-11 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (ddaf8aa) 2016-02-10 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (b8367cb) 2016-02-09 Launchpad Translations on behalf of phablet-team * Launchpad automatic translations update. (37a1f9c) 2016-01-12 Arthur Mello * Update pot files (a790cdd) 2016-01-05 CI Train Bot * Releasing 0.2+16.04.20160105-0ubuntu1 (c8ddb38) 2016-01-05 Arthur Mello * Fix po/CMakeLists.txt command to update pot files Fixes: #1521222 Approved by: PS Jenkins bot (3a6e5fa) * Fix po/CMakeLists.txt command to update pot files (7e22aac) 2015-12-21 CI Train Bot * Releasing 0.2+16.04.20151221-0ubuntu1 (9aad292) 2015-12-21 Bill Filler * remove uneeded runtime dep on libexiv2-13 Approved by: PS Jenkins bot (86ded62) 2015-12-21 Arthur Mello * After editing a photo modify the original file instead of removing/moving it Fixes: #1524973 Approved by: PS Jenkins bot (2b5a99a) 2015-12-21 Bill Filler * updated changelog (3f54d6a) * update changelog (5996753) * remove uneeded runtime dep on libexiv2-13 (3ca6d17) 2015-12-11 Arthur Mello * After editing a photo modify the original file instead of removing/moving it (30c2955) 2015-06-10 Florian Boucault * Further simplifications of unit tests. (cb03c8e) 2015-04-29 Florian Boucault * PhotoImageProvider: change its behaviour to only rectify the EXIF orientation tag type if necessary. (607f281) 2015-03-11 CI Train Bot * Releasing 0.2+15.04.20150311-0ubuntu1 (fe66edf) 2015-03-11 Arthur Mello * Add QML tests to PhotoEditor's components Approved by: PS Jenkins bot (8f419ca) * Changes made on Gallery version of the editor to fix build and AP tests Approved by: PS Jenkins bot (6c3a902) 2015-03-10 Arthur Mello * Removed unused test (f725448) * Add QML test for CropDragArea (d98259e) * Add QML Test for BusyIndicator Component (65ac313) * Add another test to ActionsBar (12f1c58) * Add ActionsBar QML tests (83ec7ee) * Fix on CMakeLists.txt (8e4a115) * Add basic structure for building qml tests (63a205b) 2015-03-02 Arthur Mello * Changes made on Gallery version of the editor to fix build and AP tests (a177c6a) 2015-02-12 CI Train Bot * Releasing 0.2+15.04.20150212.3-0ubuntu1 (37bfe36) 2015-02-12 Bill Filler * remove slow actions, bump the version of the component Fixes: #1368787 Approved by: PS Jenkins bot (2b38bca) 2015-02-12 Ugo Riboni * Add debian tags to force replacing the old package with the new (4c0abdd) 2015-02-11 Bill Filler * remove the changelog bump as this is done automatically by CI (c4e3907) 2015-02-11 Ugo Riboni * Simplify the actions bar to just use an AbstractButton (0830eee) * Remove enhance and exposure actions for now, as they are too slow (9c721f9) * Bump the version to 0.2 to enable detection of PhotoEditor by apps (b39fa2b) 2015-02-04 CI Train Bot * Releasing 0.1+15.04.20150204-0ubuntu1 (0357a46) 2015-02-04 Ugo Riboni * Add a photo editor component, partially based on the Gallery photo editor Fixes: #1368787 Approved by: PS Jenkins bot (a71f800) * Make the busy indicator more obvious only for enhance, without it being too much in your face anyway (a38e884) * Fix incorrect handling of the revert action availability (69d79ae) 2015-02-03 Ugo Riboni * Add a more visible busy indicator when applying the super slow enhance filter (203ac05) * Update with new icons from design and correctly disable revert action (0fa60d5) 2015-01-28 Ugo Riboni * Replace the thumbnail in the EXIF after editing (ff10056) 2015-01-15 Ugo Riboni * Code style fix. No functionality change. (35153c7) * Disable the QML cache in the cropper, so that only the photo image provider cache is used (55688df) 2014-12-16 Ugo Riboni * Use a better icon for the revert to original action (25a5c98) 2014-12-15 Ugo Riboni * When cropping from a smaller area to a larger one update the crop frame as we drag, to make it easier to extend the crop area without having to drop several times. (a5b1a57) * Add a confirmation dialog before reverting to original (f3687d8) * Disable undo/redo actions while in crop or exposure mode or while performing an operation on the image pixels. (2ef9957) * Disable QML cache on the exposure adjuster image so that it correctly uses the photo image provider cache when reloading (122f7fd) * Fix a bug where dragging the crop rectangle would activate the brightness adjustment (05468ce) 2014-12-09 Ugo Riboni * Update imports to use the latests version of QtQuick and the UI components (cd0bbf5) * Add missing copyright headers (2c95db5) * Limit the size of the images to the size of the screen (c70a631) * More removal of Share (56c7126) * Remove more things needed to remove the Share component (34142b4) * Remove dependencies for the share component which has been removed (e9d08ca) * Remove the Share component as it is not used by anything and has been superseded (07d4914) * Fix a bug in the CMakeLists.txt (0db765f) 2014-12-03 Ugo Riboni * Further simplify (d7e8fa7) * Further simplify the image provider (344dd26) * Simplify and refactor code a bit (b36380f) * Prevent the image editor to load empty pictures before it is started (cb4365e) * Add more crop tests and ensure the crop rectangle is always within bounds (360f39c) * Add tests for cropping (73c3f5c) * Add tests for the PhotoData class (b4a41f3) * Remove more dead code (b986e5f) 2014-12-02 Ugo Riboni * Simplify the code, fix a bug where requestedSize was not honored, and add tests for the cache using different requested sizes (3295464) * Expose some signals helping track the status of the cache, and write some initial tests for the cache. Fix a bug resulting from these tests. (d57666c) * Remove support for color balance since it is not used. We can pull it back in later if needed. (0cc23be) * Remove dead code (5c4f4dd) * Largely simplify things by not storing original orientation and size and applying the crop rectangle directly to the correctly rotated image in the editing thread. (4a82844) 2014-12-01 Ugo Riboni * Fix but in crop component preventing it from appearing (559e494) * Fix an image provider test and start adding tests for the PhotoData class (24d0e85) * Fix previous commit and add more image provider tests (f6ec274) * Add unit tests for the photo image provider (8e979a6) 2014-11-25 Ugo Riboni * Prevent file operations on empty paths (9341c97) * Rename the Photo class to PhotoData (0616034) 2014-11-24 Ugo Riboni * Fix package dependencies and installation (f38e0cb) * Reload the cropper every time (fb661bf) * Preserve metadata when performing pixel manipulation operations (84bb141) * Fix revert to original and allow the option of not saving when finishing an editing session (26baa1c) 2014-11-19 Ugo Riboni * Add a first draft of the PhotoEditor component (which also includes the image://photo/ provider) (3606e69) * Ignore generated CMakeLists.txt.user (499c136) 2014-11-10 CI bot * Releasing 0.1+15.04.20141110-0ubuntu1 (a34a091) 2014-11-10 Sebastien Bacher * Update the translations template during the build, to use for langpacks Fixes: 1391200 Approved by: Martin Pitt, PS Jenkins bot (d7e34cc) 2014-11-10 Ricardo Salveti de Araujo * No-change rebuild for shlib changes in qtbase and qtdeclarative. (5772e03) 2014-11-10 Sebastien Bacher * don't use dh_translations, it's not needed (43dfbb7) * Update the translations template during the build, to use for langpacks (74963b9) 2014-03-31 CI bot * Releasing 0.1+14.04.20140331-0ubuntu1 (95e711c) 2014-03-31 Ken VanDine * Fixed deprecations, refactored a bit for simplicity. Use an Item instead of a Rectangle to be more consistent with the toolkit. (d28fdd0) 2014-03-06 CI bot * Releasing 0.1+14.04.20140306-0ubuntu1 (7fde449) * No change rebuild against Qt 5.2.1. (a354ba5) 2014-02-28 Ken VanDine * Switch the Item back to a Rectangle, makes the input fields easier to read. (81b5bdb) 2014-02-27 CI bot * Releasing 0.1+14.04.20140227-0ubuntu1 (43849fe) * release trunk (1f1a3c6) 2014-02-24 Ken VanDine * Merged trunk (daac42b) 2014-02-24 Arthur Mello * fix facebook icon not appearing. (1b1a796) 2014-02-20 Ken VanDine * Fixed deprecations, refactored a bit. Use an Item instead of a Rectangle to be more consistent with the toolkit. (8da9f6f) * Fixed deprecations, refactored a bit for simplicity. Also filter accounts by provider, limiting the model to just Facebook. This lets us remove all the conditionals for facebook. (c01337b) 2014-02-20 Arthur Mello * Fix share provider icon source (147c5c3) 2013-10-21 Guenter Schwann * Use lazy loading for facebook id and name. Fixes: https://bugs.launchpad.net/bugs/1221266. (0a2d0b6) 2013-10-18 Guenter Schwann * Use lazy loading for facebook id and name (d3812b1) 2013-10-16 Ugo Riboni * Allow checking if the Facebook account has been configured or removed. Fixes: https://bugs.launchpad.net/bugs/1240145. (f4ccb9b) * Add the ability to verify if a Facebook account has been created or deleted (e2ce3b6) 2013-08-29 Automatic PS uploader * Releasing 0.1+13.10.20130829-0ubuntu1 (revision 52 from lp:ubuntu-ui-extras). (a0b12b7) * Releasing 0.1+13.10.20130829-0ubuntu1, based on r52 (8cb4768) 2013-08-29 Ken VanDine * Updated for qtdeclarative5-friends0.2 . (8d9f98e) * Updated for qtdeclarative5-friends0.2 (9567bdb) 2013-08-21 Automatic PS uploader * Releasing 0.1+13.10.20130821.1-0ubuntu1 (revision 50 from lp:ubuntu-ui-extras). (78e985f) * Releasing 0.1+13.10.20130821.1-0ubuntu1, based on r50 (fc0f725) 2013-08-21 Ugo Riboni * Add a SharePopover component that apps can use to let the user chose to which service to share. (576a3fe) * Merge changes from trunk (97370d7) 2013-08-21 Automatic PS uploader * Releasing 0.1+13.10.20130821-0ubuntu1 (revision 48 from lp:ubuntu-ui-extras). (d9349bb) * Releasing 0.1+13.10.20130821-0ubuntu1, based on r48 (7945dd5) 2013-08-21 Łukasz 'sil2100' Zemczak * Rename the source package name to ubuntu-ui-extras, change the binary package name to the new standard: qtdeclarative5-ubuntu-ui-extras0.1 (version number attached). (43e7127) * Tweak the description a bit (a92e722) * Remove libnotify4 dep as we use shlibs anyway (7b6c917) * As requested by seb, change the name of the binary package to have the version in the name (760c9c7) * Add additional info to copyright (c02abaa) * Eeek, changelog (946f810) * Wrong source package name (44f58ba) 2013-08-20 Ugo Riboni * Remove the autopilot test and package, since they do nothing for now. (8aa62bf) 2013-08-20 Łukasz 'sil2100' Zemczak * Packaging review, bootstrapping for daily-release. (ad658f0) * We don't need the install files anymore (30c5f9e) 2013-08-20 Ugo Riboni * Remove the autopilot tests package as well (7a0725d) * Remove autopilot tests which at the moment do nothing (52b280b) 2013-08-20 Łukasz 'sil2100' Zemczak * Packaging review (8f28d4c) 2013-08-20 Ugo Riboni * Add a SharePopover component that applications can use to let the user choose to which service to share (901439e) * Add a qmlproject file, for convenience (f9ae4dd) 2013-08-19 Ugo Riboni * Move most of the share-app code into a component as part of Ubuntu.Components.Extras. (470e7d9) * Add new unit tests for the share component, fix and enable the existing ones (54cca25) * Adjust the xgettext command line while building the .pot file (469f312) * Use the correct domain when loading translated strings (8a516fb) * Add initial translation to italian (acd2068) * Add comma at end of dependency list for consistency (f6a6406) * Forgot to update 2 copyright headers (2a67e1b) * Simplify the code (2c62e3e) * Remove unneeded dependency that should've gone away with the previous dead code removal (7535565) * Update copyright as part of the code is from 2012 (159aa48) 2013-08-13 Ugo Riboni * Remove dead code (ca0e22f) * Add initial i18n support (71f4608) * Add missing runtime dependency (1c712ad) * Remove unneeded use of wildcards (db94cf8) * Adjust some minor inconsistencies in the anchoring and size of the thumbnail (285a581) * Remove unused class that only made sense inside share-app (61c331f) * Update the copyright date (20ce03c) * Update copyright (1cff87f) * Internally rename the component and provide it with a standard background color (54da6c7) * Add more missing dependencies (88aa391) * Add missing dependency on pkg-config (2ff830b) 2013-08-12 Ugo Riboni * Add back assets (96d7736) * Add back a dependency that was mistakenly removed (467e6c7) * Add missing dependency on Ubuntu.Accounts QML plugin (68242a1) * Componentize more properly, including passing parameters through properties and sending events instead of quitting (66f541c) * Adding the share app as a component as part of this library. Builds but otherwise untested and unfinished. (da6ffd7) 2013-08-07 Ugo Riboni * Initial commit. (1c464e4) 2013-07-02 Ugo Riboni * Remove all browser work and leave only an example component and skeleton build system (8e877d6) 2013-07-01 Ugo Riboni * Backport revision 189 from webbrowser-app (4862241) * Backport revision 187 from webbrowser-app (2483918) * Backport revision 181 from webbrowser-app (68d59cc) * Backport revision 180 from webbrowser-app (2a97980) * Backport revision 176 from webbroser-app (8d81dd1) 2013-06-26 Ugo Riboni * Backport revision 174 from the app (01f2dbb) * Backport revision 173 from the app (a7ace10) * Fix a test failing because it clicks outside of the application (4716694) * Fix a previous mistake preventing correct detection of when to run locally or installed (f556ea7) * Backport revision 170 from the app (6fa2280) * Backport revision 170 from the app (88c30a8) * Backport revision 169 from the app (df107b6) * Backport rev 168 from app (f421774) * Backport rev 167 from the app (20a0772) * Refactor test cases (rev 164 from webbrowser-app) (0271833) * Merge changes from branch (7fce4ac) * Fix tests so that they run when installed (5d0e93a) * Fix the runner so that it creates an initial tab just like the webbrowser-app would at startup (f18ef9c) * Revert parts of new files that were mistakenly taken from later commits (ecb18ee) 2013-06-25 Ugo Riboni * Add and ajust autopilot tests for tabs support (ef5cc63) * Merge changes to Browser.qml related to tabs support, except autopilot tests. (4eefad2) 2013-06-25 Omer Akram * fix runner.qml location in autopilot tests (a1cc2c5) * fix license header (44227a3) 2013-06-24 Ugo Riboni * Fix the autopilot tests so that they can run uninstalled (d9881e1) * Move the qml binary plugin into a separate directory to match SDK standards (b8ff353) * Rename src directory to modules to match sdk conventions for plugins (3f07c05) 2013-06-19 Ugo Riboni * Properly install all needed files (dae781a) 2013-06-18 Ugo Riboni * Remove spurious install command that was causing the package build to fail (d63d578) * Fix the installation of the autopilot tests (4027f08) * Use the correct location for finding tests uninstalled (7dd3d00) * Remove tests that are specific to webbrowser-app and not to the component (000cc86) * Remove commented out code that isn't useful anymore (80a1bab) * Move browser autopilot tests one level down the tree and install them correctly (ef74cff) * Merge autopilot tests fixes (1037ed2) 2013-06-17 Omer Akram * fix autopilot tests for the browser component (35acfc9) 2013-06-17 Ugo Riboni * Properly copy builld products to the unit tests dir so that the unit tests can run successfully (bd40b6a) 2013-06-11 Ugo Riboni * Try to fix the unit tests (d0587fb) 2013-06-10 Ugo Riboni * Fix unit tests (b7c930a) * Remove some debug code in autopilot tests (645cc3a) * Fix the imports in autopilot tests (79b262a) * Fix the runner and name for autopilot tests (be1def0) * Fix packaging and add translations (e1abafb) * Fix unit tests (0ce6c71) * Initial commit of autopilot tests (1c77679) 2013-06-05 Ugo Riboni * Add unit tests (5388c33) * Initial commit, only plugin, no tests, no translations (1f7de31) lomiri-ui-extras-0.6.3/README000066400000000000000000000021031455543116500156170ustar00rootroot00000000000000Lomiri exta components are a collection of components that does not have the necessary level of quality for inclusion in the toolkit (https://gitlab.com/ubports/core/lomiri-ui-toolkit): - lack of documentation - lack of automated tests = Dependencies = $ apt-get install qtcore5-dev qtbase5-dev qtdeclarative5-dev libexiv2-dev libcups2-dev install the cmake-extras from the ubports github = Building = The build system uses cmake. To compile, simply invoke cmake and then make: $ cmake . $ make = Unit tests = To run the unit tests, you can use the commands below: $ make test - or - $ ctest = Automated UI tests = We use autopilot (https://launchpad.net/autopilot) to test the UI. To run the tests, you will need to install python-autopilot and libautopilot-qt. Then do the following: $ cd tests/autopilot/ $ autopilot run lomiri_ui_extras You can get a list of all available tests with the following command: $ autopilot list lomiri_ui_extras lomiri-ui-extras-0.6.3/debian/000077500000000000000000000000001455543116500161655ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/debian/Jenkinsfile000066400000000000000000000001011455543116500203410ustar00rootroot00000000000000@Library('ubports-build-tools') _ buildAndProvideDebianPackage() lomiri-ui-extras-0.6.3/debian/changelog000066400000000000000000000331371455543116500200460ustar00rootroot00000000000000lomiri-ui-extras (0.6.3) unstable; urgency=medium * Upstream-provided Debian package for lomiri-ui-extras. See upstream ChangeLog for recent changes. -- UBports developers Sun, 28 Jan 2024 11:54:45 +0100 lomiri-ui-extras (0.6.2) unstable; urgency=medium * Upstream-provided Debian package for lomiri-ui-extras. See upstream ChangeLog for recent changes. -- UBports developers Sun, 15 Oct 2023 13:36:12 +0200 lomiri-ui-extras (0.6.1) unstable; urgency=medium * Upstream-provided Debian package for lomiri-ui-extras. See upstream ChangeLog for recent changes. -- UBports developers Sun, 15 Oct 2023 09:17:17 +0200 lomiri-ui-extras (0.6.0) unstable; urgency=medium [ Guido Berhoerster ] * Import qml-module-pamauthentication0.1 subpackage from terminal-app/filemanager-app [ UBports developers ] * Upstream-provided Debian package for lomiri-ui-extras. See upstream ChangeLog for recent changes. -- UBports developers Wed, 11 Jan 2023 00:00:18 +0100 lomiri-ui-extras (0.5) unstable; urgency=medium * Upstream-provided Debian package for lomiri-ui-extras. See upstream ChangeLog for recent changes. -- UBports developers Fri, 04 Mar 2022 19:34:53 +0100 ubuntu-ui-extras (0.4+ubports) xenial; urgency=medium * Imported to UBports -- UBports auto importer Sun, 07 Jan 2018 23:38:30 +0100 ubuntu-ui-extras (0.3+17.04.20170323-0ubuntu1) zesty; urgency=medium [ Andrew Hayzen, Jonas G. Drange ] * Adds devices as an model on Printers, and re-instates remote printer model on Printers. * makes sure the backend is refreshed on enable/disable * If printerAdded is called ensure there is always a proxy printer corrects thread affinity for printerloaded printers, as well as any qobject children it might have * Remove PrinterQueue.qml example and add missing job methods to Printers.qml example, so we have only one example * improves the deviceName by dropping the CMD (note that the full string remains accessible from device.id) * Connect job-impressions-completed from cups to PrinterJob::impressionsCompleted() * In the job model listen to printerStateChanged as changes t job-impressions-completed causes that signal * Improve the PrinterSignalHandler to limit the maximum wait time of unprocessed signals to four times the timeout * Add unit test for SignalRateLimiter to check it does perform a flush * Rename PrinterSignalHandler to SignalRateLimiter * Add a JobLoader for loading a specific jobId for a printer and loading the extended attributes * Move the loading of creationTime, completedTime, processingTime, size and user to extended attributes as signals don't give us those * Add method for PrinterBackend for getting a specific job * Split up JobModel::update so there is jobCreated, jobState and jobCompleted which then call addJob, removeJob and updateJob * Improve Printer::updateFrom to not call loadAttributes as this results in a possible UI block * Add missing comparisions for PrinterJob deepCompare and updateFrom * Change PrinterJob::setPrinter to not call loadDefaults and instead explicitly call it * Change Printers to trigger requestJobExtendedAttributes which triggers a background thread rather than doing in foreground * exposes copies attribute on the printer * includes cups/adminutils.h into which the cups device callback was moved in >= libcups2-dev 2.2.2 * allows browsing on local and remote printers * Add filters for active, paused and queued * Add sorting by creationTime and then falling back to id * Change time related roles in JobModel to return QDateTime, not QString, so sorting doesn't break * Update tests * Change printerGetJobAttributes to use printer-uri and job-id (the same as holdJob and releaseJob * Give printerGetJobAttributes printerName so we can ensure we get the correct job * adds read/write of the shared property * adds extended attribute fetching (IppClient::printerGetAttributes) * refactors attribute retrieval from cups * implements deviceUri and lastMessage on Printer * adds Printers.printTestPage * Add tests for JobModel roles * Add tests for make and location in Printer * Fix JobModel color and quality roles to use fallback if no text * Add tests for all roles in PrinterModel * Remove PdfRole it is not used (IsPdfRole instead) * Add holdJob and releaseJob methods to Printers * Add HeldRole to JobModel * Add tests for hold and releasing a job * Update example to show how hold and release work * Update StateRole to return just the state, not text * Remove PrinterJob friends and make setters public as they aren't exposed to QML anyway * adds make and location to printermodel and printer * Pull of trunk * Remove use of bitewise or as it fails in CI * guards against excessive loading of printers and drivers * adds loadPrinter method on Printers * drops a lot of code that was not used, and some TODOS/FIXMES that aren't necessary * Fix/add commented or empty tests * Implement tests that had QSKIP * removes empty brackets * adds cmake extras, required by printer stuff * Remove remaining fixme's * Rename UbuntuSettingsComponentsPrintersPlugin to UbuntuComponentsExtrasPrintersPlugin * Remove import Ubuntu.Settings.Components 0.1 from example qml imports * Rename definition UBUNTUSETTINGSPRINTERS_LIBRARY to UBUNTUCOMPONENTSEXTRASPRINTERS_LIBRARY * Rename UbuntuSettingsPrintersQml to UbuntuComponentsExtrasPrintersQml * Rename translation domain to ubuntu-ui-extras * Fix for printsupport being build-depends rather than depends -- Andrew Hayzen Thu, 23 Mar 2017 12:54:43 +0000 ubuntu-ui-extras (0.2+17.04.20170301.2-0ubuntu1) zesty; urgency=medium [ Andrew Hayzen, Jonas G. Drange ] * Add printer-components from ubuntu-settings-components to ubuntu-ui- extras (original branch https://code.launchpad.net/~phablet- team/ubuntu-settings-components/printer-components) -- Andrew Hayzen Wed, 01 Mar 2017 22:24:08 +0000 ubuntu-ui-extras (0.2+17.04.20170222-0ubuntu1) zesty; urgency=medium [ Andrew Hayzen ] * Add qml-module-qtqml-models2 as a depends, as it was missing * When the tab is being destroyed unset the source of the TabIcon Loader * Add qtdeclarative5-dev-tools, qml-module-ubuntu-test and xvfb as build-deps (LP: #1666556) -- Olivier Tilloy Wed, 22 Feb 2017 10:52:03 +0000 ubuntu-ui-extras (0.2+17.04.20170116-0ubuntu1) zesty; urgency=medium [ Florian Boucault ] * New component: TabsBar -- Kaleo Mon, 16 Jan 2017 16:02:24 +0000 ubuntu-ui-extras (0.2+16.10.20160824.1-0ubuntu1) yakkety; urgency=medium [ Florian Boucault ] * Fix image orientation in photo image provider for Qt>=5.5 [ Timo Jyrinki ] * Stop depending on transitional packages. (LP: #1583079) (LP: #1583079) -- Kaleo Wed, 24 Aug 2016 15:47:28 +0000 ubuntu-ui-extras (0.2+16.10.20160714-0ubuntu1) yakkety; urgency=medium [ Florian Boucault ] * Fixes for crossbuilding. -- Kaleo Thu, 14 Jul 2016 12:45:37 +0000 ubuntu-ui-extras (0.2+16.10.20160609.1-0ubuntu1) yakkety; urgency=medium [ Arthur Mello ] * Specify the domain "ubuntu-ui-extras" for i18n messages (LP: #1521222) -- Arthur Renato Mello Thu, 09 Jun 2016 18:09:38 +0000 ubuntu-ui-extras (0.2+16.04.20160503-0ubuntu1) xenial; urgency=medium * Qt now takes into account the EXIF orientation data when loading pictures; the rotation workaround is no longer necessary. -- Florian Boucault Tue, 03 May 2016 13:31:24 +0000 ubuntu-ui-extras (0.2+16.04.20160323.1-0ubuntu1) xenial; urgency=medium [ Arthur Mello ] * Do not remove files during photo editor's copy process (LP: #1549991) [ CI Train Bot ] * Resync trunk. -- Arthur Mello Wed, 23 Mar 2016 18:03:21 +0000 ubuntu-ui-extras (0.2+16.04.20160225-0ubuntu1) xenial; urgency=medium [ Arthur Mello ] * Update pot files [ Florian Boucault ] * When rotating pictures during edit, write the EXIF orientation tag with the right type (unsigned short) instead of signed long. PhotoImageProvider: change its behaviour to only rectify the EXIF orientation tag type when necessary (removes all other behaviours: caching, etc.) (LP: #1541210) -- Florian Boucault Thu, 25 Feb 2016 15:11:48 +0000 ubuntu-ui-extras (0.2+16.04.20160105-0ubuntu1) xenial; urgency=medium [ Arthur Mello ] * Fix po/CMakeLists.txt command to update pot files (LP: #1521222) -- Bill Filler Tue, 05 Jan 2016 21:37:21 +0000 ubuntu-ui-extras (0.2+16.04.20151221-0ubuntu1) xenial; urgency=medium [ Arthur Mello ] * After editing a photo modify the original file instead of removing/moving it (LP: #1524973) -- Bill Filler Mon, 21 Dec 2015 14:24:50 +0000 ubuntu-ui-extras (0.2+15.04.20150311-0ubuntu4) wily; urgency=medium * No-change rebuild against libexiv2-14. -- Martin Pitt Thu, 06 Aug 2015 08:05:25 +0200 ubuntu-ui-extras (0.2+15.04.20150311-0ubuntu3) wily; urgency=medium * Drop hard-coded dependency on libexiv2-13. -- Steve Langasek Sun, 02 Aug 2015 19:49:44 +0000 ubuntu-ui-extras (0.2+15.04.20150311-0ubuntu2) wily; urgency=medium * No-change rebuild against libexiv2-13v5 -- Steve Langasek Sun, 02 Aug 2015 09:22:10 +0000 ubuntu-ui-extras (0.2+15.04.20150311-0ubuntu2~gcc5.1) wily; urgency=medium * No-change test rebuild for g++5 ABI transition -- Steve Langasek Wed, 15 Jul 2015 16:22:37 +0000 ubuntu-ui-extras (0.2+15.04.20150311-0ubuntu1) vivid; urgency=medium [ Arthur Mello ] * Add QML tests to PhotoEditor's components * Changes made on Gallery version of the editor to fix build and AP tests [ CI Train Bot ] * New rebuild forced. -- CI Train Bot Wed, 11 Mar 2015 18:38:04 +0000 ubuntu-ui-extras (0.2+15.04.20150212.3-0ubuntu1) vivid; urgency=medium [ Bill Filler ] * remove slow actions, bump the version of the component (LP: #1368787) [ Ubuntu daily release ] * New rebuild forced [ Ugo Riboni ] * remove slow actions, bump the version of the component (LP: #1368787) -- Ubuntu daily release Thu, 12 Feb 2015 17:40:46 +0000 ubuntu-ui-extras (0.1+15.04.20150204-0ubuntu1) vivid; urgency=medium [ Ubuntu daily release ] * New rebuild forced [ Ugo Riboni ] * Add a photo editor component, partially based on the Gallery photo editor (LP: #1368787) -- Ubuntu daily release Wed, 04 Feb 2015 20:33:53 +0000 ubuntu-ui-extras (0.1+15.04.20141110-0ubuntu1) vivid; urgency=low [ Sebastien Bacher ] * Update the translations template during the build, to use for langpacks (LP: #1391200) [ Ubuntu daily release ] * New rebuild forced -- Ubuntu daily release Mon, 10 Nov 2014 16:07:47 +0000 ubuntu-ui-extras (0.1+14.04.20140331-0ubuntu2) trusty; urgency=medium * No-change rebuild for shlib changes in qtbase and qtdeclarative. -- Ricardo Salveti de Araujo Mon, 14 Apr 2014 15:39:59 -0300 ubuntu-ui-extras (0.1+14.04.20140331-0ubuntu1) trusty; urgency=low [ Ken VanDine ] * Fixed deprecations, refactored a bit for simplicity. Use an Item instead of a Rectangle to be more consistent with the toolkit. Filter accounts by provider, limiting the model to just Facebook. This lets us remove all the conditionals for facebook. -- Ubuntu daily release Mon, 31 Mar 2014 17:49:59 +0000 ubuntu-ui-extras (0.1+14.04.20140306-0ubuntu1) trusty; urgency=low * New rebuild forced -- Ubuntu daily release Thu, 06 Mar 2014 10:33:55 +0000 ubuntu-ui-extras (0.1+14.04.20140227-0ubuntu1) trusty; urgency=low [ Arthur Mello ] * fix facebook icon not appearing. [ Ugo Riboni ] * Allow checking if the Facebook account has been configured or removed. (LP: #1240145) [ Guenter Schwann ] * Use lazy loading for facebook id and name. (LP: #1221266) [ CI bot ] * release trunk -- Ubuntu daily release Thu, 27 Feb 2014 02:23:40 +0000 ubuntu-ui-extras (0.1+13.10.20130829-0ubuntu1) saucy; urgency=low [ Ken VanDine ] * Updated for qtdeclarative5-friends0.2 . [ Ubuntu daily release ] * Automatic snapshot from revision 52 -- Ubuntu daily release Thu, 29 Aug 2013 15:21:34 +0000 ubuntu-ui-extras (0.1+13.10.20130821.1-0ubuntu1) saucy; urgency=low [ Ugo Riboni ] * Add a SharePopover component that apps can use to let the user chose to which service to share. [ Ubuntu daily release ] * Automatic snapshot from revision 50 -- Ubuntu daily release Wed, 21 Aug 2013 16:18:58 +0000 ubuntu-ui-extras (0.1+13.10.20130821-0ubuntu1) saucy; urgency=low [ Ugo Riboni ] * Initial Release [ Łukasz 'sil2100' Zemczak ] * Automatic snapshot from revision 45 (bootstrap) [ Ugo Riboni ] * Remove the autopilot test and package, since they do nothing for now. [ Łukasz 'sil2100' Zemczak ] * Remove the autopilot test and package, since they do nothing for now. [ Ubuntu daily release ] * Automatic snapshot from revision 48 -- Ubuntu daily release Wed, 21 Aug 2013 09:04:11 +0000 lomiri-ui-extras-0.6.3/debian/compat000066400000000000000000000000021455543116500173630ustar00rootroot000000000000009 lomiri-ui-extras-0.6.3/debian/control000066400000000000000000000024641455543116500175760ustar00rootroot00000000000000Source: lomiri-ui-extras Section: x11 Priority: optional Maintainer: UBports Developers Build-Depends: cmake (>= 2.8.9), cmake-extras (>= 0.10), debhelper (>= 9), gettext, libcups2-dev, libexiv2-dev, libpam0g-dev, pkg-config, python:any, qt5-default, qtbase5-dev, qtdeclarative5-dev, qtdeclarative5-dev-tools, qml-module-qtquick2, qml-module-qttest, qml-module-lomiri-components, qml-module-lomiri-test, xvfb, Standards-Version: 3.9.4 Homepage: https://gitlab.com/ubports/core/lomiri-ui-extras X-Ubuntu-Use-Langpack: yes Package: qml-module-lomiri-components-extras Architecture: any Depends: ${misc:Depends}, ${shlibs:Depends}, libqt5printsupport5, qml-module-qtqml-models2, qml-module-qtquick2, qml-module-lomiri-components, qml-module-qtquick-window2, Description: Lomiri UI Extra Components A collection of UI components that for various reasons can't be included in the main Lomiri UI toolkit - mostly because of the level of quality, lack of documentation and/or lack of automated tests. lomiri-ui-extras-0.6.3/debian/copyright000066400000000000000000000016731455543116500201270ustar00rootroot00000000000000Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: lomiri-ui-extras Source: https://gitlab.com/ubports/core/lomiri-ui-extras Files: * Copyright: 2013 Canonical Ltd. License: GPL-3 License: GPL-3 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, version 3 of the License. . 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 . . On Debian systems, the full text of the GNU General Public License version 3 can be found in the file /usr/share/common-licenses/GPL-3. lomiri-ui-extras-0.6.3/debian/rules000077500000000000000000000007251455543116500172510ustar00rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 export QT_SELECT := qt5 export DPKG_GENSYMBOLS_CHECK_LEVEL=4 ifneq (,$(findstring nocheck,$(DEB_BUILD_OPTIONS))) CONFIGURE_OPTS += -DENABLE_TESTS=OFF endif %: dh $@ --parallel --fail-missing override_dh_auto_configure: dh_auto_configure -- \ $(CONFIGURE_OPTS) override_dh_auto_build: dh_auto_build $(MAKE) -C obj-$(DEB_HOST_GNU_TYPE) lomiri-ui-extras.pot lomiri-ui-extras-0.6.3/lomiri-ui-extras.qmlproject000066400000000000000000000004321455543116500222560ustar00rootroot00000000000000import QmlProject 1.1 Project { QmlFiles { directory: "modules" } JavaScriptFiles { directory: "modules" } Files { filter: ["modules/Lomiri/Components/Extras/qmldir", "modules/Lomiri/Components/Extras/PamAuthentication/qmldir"] } } lomiri-ui-extras-0.6.3/modules/000077500000000000000000000000001455543116500164135ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/CMakeLists.txt000066400000000000000000000000311455543116500211450ustar00rootroot00000000000000add_subdirectory(Lomiri) lomiri-ui-extras-0.6.3/modules/Lomiri/000077500000000000000000000000001455543116500176465ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/Lomiri/CMakeLists.txt000066400000000000000000000000351455543116500224040ustar00rootroot00000000000000add_subdirectory(Components) lomiri-ui-extras-0.6.3/modules/Lomiri/Components/000077500000000000000000000000001455543116500217735ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/Lomiri/Components/CMakeLists.txt000066400000000000000000000000311455543116500245250ustar00rootroot00000000000000add_subdirectory(Extras) lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/000077500000000000000000000000001455543116500232415ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/CMakeLists.txt000066400000000000000000000012251455543116500260010ustar00rootroot00000000000000file(GLOB QML_FILES *.qml qmldir) set(QT_IMPORTS_DIR "${CMAKE_INSTALL_LIBDIR}/qt5/qml") set(PLUGIN_DIR ${QT_IMPORTS_DIR}/Lomiri/Components/Extras) install(FILES ${QML_FILES} DESTINATION ${PLUGIN_DIR}) # copy qml files over to build dir to be able to import them in tests foreach(qmlFile ${QML_FILES} Example.qml PhotoEditor.qml TabsBar.qml Example PhotoEditor TabsBar) file(COPY ${qmlFile} DESTINATION ${CMAKE_BINARY_DIR}/tests/unittests/Lomiri/Components/Extras/) endforeach(qmlFile) add_subdirectory(plugin) add_subdirectory(Example) add_subdirectory(PamAuthentication) add_subdirectory(PhotoEditor) add_subdirectory(Printers) add_subdirectory(TabsBar) lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Example.qml000066400000000000000000000015671455543116500253600ustar00rootroot00000000000000/* * Copyright 2013 Canonical Ltd. * * This file is part of lomiri-ui-extras. * * ubuntu-ui-extras 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; version 3. * * ubuntu-ui-extras 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 . */ import QtQuick 2.3 import Lomiri.Components 1.1 import Lomiri.Components.Extras 0.2 import "Example" ListView { model: ExampleModel { } delegate: ExampleDelegate { text: model.text } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Example/000077500000000000000000000000001455543116500246345ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Example/CMakeLists.txt000066400000000000000000000001311455543116500273670ustar00rootroot00000000000000file(GLOB QML_FILES *.qml) install(FILES ${QML_FILES} DESTINATION ${PLUGIN_DIR}/Example) lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Example/ExampleDelegate.qml000066400000000000000000000013421455543116500303750ustar00rootroot00000000000000/* * Copyright 2013 Canonical Ltd. * * This file is part of ubuntu-ui-extras * * ubuntu-ui-extras 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; version 3. * * ubuntu-ui-extras 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 . */ import QtQuick 2.3 import Lomiri.Components 1.1 Label { } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Example/Printers.qml000066400000000000000000000706061455543116500271660ustar00rootroot00000000000000/* * Copyright 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authored by Jonas G. Drange */ import QtQuick 2.4 import QtQuick.Layouts 1.1 import Lomiri.Components 1.3 import Lomiri.Components.Popups 1.3 import Lomiri.Components.ListItems 1.3 as ListItems import Lomiri.Components.Extras.Printers 0.1 MainView { width: units.gu(50) height: units.gu(90) Component { id: printerPage Page { visible: false property var printer header: PageHeader { id: printerPageHeader title: printer.name flickable: printerFlickable } Component { id: printerPageNotYetLoaded Item { anchors.fill: parent ActivityIndicator { anchors.centerIn: parent running: true } } } Flickable { id: printerFlickable anchors.fill: parent contentHeight: contentItem.childrenRect.height Loader { id: printerPageBitsLoader anchors { left: parent.left right: parent.right } sourceComponent: printer.isLoaded ? printerPageLoaded : printerPageNotYetLoaded } } Component { id: printerPageLoaded Column { height: childrenRect.height + anchors.topMargin anchors { top: parent.top topMargin: units.gu(2) left: parent.left right: parent.right } ListItems.Standard { anchors { left: parent.left right: parent.right } text: "Enabled" control: Switch { checked: printer.printerEnabled onCheckedChanged: printer.printerEnabled = checked } } ListItems.SingleValue { anchors { left: parent.left right: parent.right } text: "Status" value: { var state; if (printer.state == PrinterEnum.IdleState) { state = i18n.tr("Idle"); } else if (printer.state == PrinterEnum.AbortedState) { state = i18n.tr("Aborted"); } else if (printer.state == PrinterEnum.ActiveState) { state = i18n.tr("Active"); } else if (printer.state == PrinterEnum.ErrorState) { state = i18n.tr("Stopped"); } return "%1 — %2" .arg(state) .arg(printer.lastMessage ? printer.lastMessage : i18n.tr("No messages")); } } ListItems.Standard { anchors { left: parent.left right: parent.right } text: "Accepting jobs" control: Switch { checked: printer.acceptJobs onCheckedChanged: printer.acceptJobs = checked } } ListItems.Standard { anchors { left: parent.left right: parent.right } text: "Shared" control: Switch { checked: printer.shared onCheckedChanged: printer.shared = checked } } ListItems.Standard { anchors { left: parent.left right: parent.right } text: "Jobs" progression: true onClicked: pageStack.push(jobPage, { printer: printer }) } ListItems.Standard { anchors { left: parent.left right: parent.right } text: "Description" control: TextField { anchors { margins: units.gu(1) left: parent.left right: parent.right } text: printer.description onTextChanged: printer.description = text } } ListItems.Standard { anchors { left: parent.left right: parent.right } text: "Copies" control: TextField { id: copiesField inputMethodHints: Qt.ImhDigitsOnly text: printer.copies validator: IntValidator { bottom: 1 top: 999 } width: units.gu(10) onTextChanged: printer.copies = text } } ListItems.ValueSelector { anchors { left: parent.left right: parent.right } enabled: values.length > 1 text: "Duplex" values: printer.supportedDuplexModes onSelectedIndexChanged: printer.duplexMode = selectedIndex Component.onCompleted: { if (enabled) { selectedIndex = printer.duplexMode } } } ListItems.ValueSelector { anchors { left: parent.left right: parent.right } text: "Page size" values: printer.supportedPageSizes onSelectedIndexChanged: printer.pageSize = selectedIndex Component.onCompleted: selectedIndex = printer.supportedPageSizes.indexOf(printer.pageSize) } ListItems.ValueSelector { anchors { left: parent.left right: parent.right } visible: printer.supportedColorModels.length text: "Color model" values: printer.supportedColorModels enabled: values.length > 1 onSelectedIndexChanged: printer.colorModel = selectedIndex Component.onCompleted: { if (enabled) selectedIndex = printer.colorModel } } ListItems.ValueSelector { anchors { left: parent.left right: parent.right } visible: printer.supportedPrintQualities.length text: "Quality" values: printer.supportedPrintQualities enabled: values.length > 1 onSelectedIndexChanged: printer.printQuality = selectedIndex Component.onCompleted: { if (enabled) selectedIndex = printer.printQuality } } ListItems.SingleControl { anchors { left: parent.left right: parent.right } control: Button { text: "Print test page" onClicked: Printers.printTestPage(printer.name) } } ListItems.SingleValue { anchors { left: parent.left right: parent.right } text: "Device URI" value: printer.deviceUri } } } } } Component { id: jobDelegate ListItem { height: modelLayout.height + (divider.visible ? divider.height : 0) trailingActions: ListItemActions { actions: [ Action { iconName: model.held ? "media-playback-start" : "media-playback-pause" text: model.held ? "Release" : "Hold" onTriggered: { if (model.held) { Printers.releaseJob(model.printerName, model.id); } else { Printers.holdJob(model.printerName, model.id); } } }, Action { iconName: "cancel" text: "Cancel" onTriggered: Printers.cancelJob(model.printerName, model.id); } ] } ListItemLayout { id: modelLayout title.text: displayName subtitle.text: "Printing " + model.impressionsCompleted + " pages" + "\n" + model.printerName subtitle.wrapMode: Text.WrapAtWordBoundaryOrAnywhere subtitle.maximumLineCount: 3 } } } Component { id: jobPage Page { property var printer header: PageHeader { id: jobPageHeader title: "%1 (%2 jobs)".arg(printer.name).arg(jobList.count) flickable: jobList } ListView { id: jobList anchors.fill: parent model: printer.jobs delegate: jobDelegate } } } Component { id: allJobsPage Page { header: PageHeader { id: allJobsHeader title: "Printer jobs" flickable: jobsList } ListView { id: jobsList anchors.fill: parent model: Printers.printJobs delegate: jobDelegate } } } PageStack { id: pageStack Component.onCompleted: push(printersPage) Page { id: printersPage header: PageHeader { title: "Printers" flickable: printerList trailingActionBar { actions: [ Action { iconName: "add" text: "Add printer" onTriggered: pageStack.push(addPrinterPageComponent) }, Action { iconName: "document-print" text: "Printer jobs" onTriggered: pageStack.push(allJobsPage) } ] } } visible: false ListView { id: printerList anchors { fill: parent } model: Printers.allPrintersWithPdf delegate: ListItem { height: modelLayout.height + (divider.visible ? divider.height : 0) trailingActions: ListItemActions { actions: [ Action { iconName: "delete" onTriggered: { if (!Printers.removePrinter(model.name)) { console.error('failed to remove printer', Printers.lastMessage); } } }, Action { iconName: model.default ? "starred" : "non-starred" enabled: !model.default onTriggered: Printers.defaultPrinterName = model.name } ] } ListItemLayout { id: modelLayout title.text: displayName title.font.bold: model.default Icon { id: icon width: height height: units.gu(2.5) name: "printer-symbolic" SlotsLayout.position: SlotsLayout.First } ProgressionSlot {} } onClicked: { Printers.loadPrinter(model.name); pageStack.push(printerPage, { printer: model }); } } } Label { anchors.centerIn: parent visible: printerList.count === 0 text: "No printers found" } } } Component { id: addPrinterPageComponent Page { id: addPrinterPage states: [ State { name: "success" PropertyChanges { target: okAction enabled: false } PropertyChanges { target: closeAction enabled: false } PropertyChanges { target: addPrinterCol enabled: false } StateChangeScript { script: okTimer.start() } }, State { name: "failure" PropertyChanges { target: errorMessageContainer visible: true } } ] header: PageHeader { title: "Add printer" flickable: addPrinterFlickable leadingActionBar.actions: [ Action { id: closeAction iconName: "close" text: "Abort" onTriggered: pageStack.pop() } ] trailingActionBar { actions: [ Action { id: okAction iconName: "ok" text: "Complete" onTriggered: { var ret; if (driverSelector.selectedIndex == 0) { ret = Printers.addPrinter( printerName.text, driversView.selectedDriver, printerUri.text, printerDescription.text, printerLocation.text ); } else { ret = Printers.addPrinterWithPpdFile( printerName.text, printerPpd.text, printerUri.text, printerDescription.text, printerLocation.text ); } if (ret) { addPrinterPage.state = "success" } else { errorMessage.text = Printers.lastMessage; addPrinterPage.state = "failure" } } } ] } } Component.onCompleted: Printers.prepareToAddPrinter() Timer { id: okTimer interval: 2000 onTriggered: pageStack.pop(); } Flickable { id: addPrinterFlickable anchors.fill: parent contentHeight: contentItem.childrenRect.height Column { id: addPrinterCol property bool enabled: true anchors { left: parent.left; right: parent.right } Item { id: errorMessageContainer visible: false anchors { left: parent.left right: parent.right margins: units.gu(2) } height: units.gu(6) Label { id: errorMessage anchors { top: parent.top topMargin: units.gu(2) horizontalCenter: parent.horizontalCenter } } } ListItems.Standard { text: "Device URI" control: TextField { id: printerUri placeholderText: "ipp://server.local/my-queue" } enabled: parent.enabled } ListItems.ValueSelector { id: driverSelector anchors { left: parent.left; right: parent.right } text: "Choose driver" values: [ "Select printer from database", "Provide PPD file" ] enabled: parent.enabled } ListItems.Standard { anchors { left: parent.left; right: parent.right } text: "Filter drivers" control: TextField { id: driverFilter onTextChanged: Printers.driverFilter = text } visible: driverSelector.selectedIndex == 0 enabled: parent.enabled } ListView { id: driversView property string selectedDriver property bool loading: true visible: driverSelector.selectedIndex == 0 model: Printers.drivers anchors { left: parent.left; right: parent.right } height: units.gu(30) clip: true enabled: parent.enabled highlightFollowsCurrentItem: false highlight: Rectangle { z: 0 y: driversView.currentItem.y width: driversView.currentItem.width height: driversView.currentItem.height color: theme.palette.selected.background } delegate: ListItem { height: driverLayout.height + (divider.visible ? divider.height : 0) ListItemLayout { id: driverLayout title.text: displayName subtitle.text: name summary.text: deviceId } onClicked: { driversView.selectedDriver = name driversView.currentIndex = index } } ActivityIndicator { anchors.centerIn: parent running: parent.loading } Connections { target: driversView onCountChanged: { target = null; driversView.loading = false; } } } ListItems.Standard { text: "PPD File" visible: driverSelector.selectedIndex == 1 control: TextField { id: printerPpd placeholderText: "/usr/share/cups/foo.ppd" } enabled: parent.enabled } ListItems.Standard { anchors { left: parent.left; right: parent.right } text: "Printer name" control: TextField { id: printerName placeholderText: "laserjet" } enabled: parent.enabled } ListItems.Standard { anchors { left: parent.left; right: parent.right } text: "Description (optional)" control: TextField { id: printerDescription placeholderText: "HP Laserjet with Duplexer" } enabled: parent.enabled } ListItems.Standard { anchors { left: parent.left; right: parent.right } text: "Location (optional)" control: TextField { id: printerLocation placeholderText: "Lab 1" } enabled: parent.enabled } } Label { id: remotePrintersLabel anchors { left: parent.left right: parent.right margins: units.gu(2) top: addPrinterCol.bottom } text: "Other printers" ActivityIndicator { id: remotePrintersSearchIndicator anchors { right: parent.right verticalCenter: parent.verticalCenter } property var target Component.onCompleted: target = Printers.devices running: target.searching } } ListView { id: remotePrintersList anchors { left: parent.left right: parent.right top: remotePrintersLabel.bottom topMargin: units.gu(2) } height: contentItem.childrenRect.height model: Printers.devices delegate: ListItem { height: modelLayout.height + (divider.visible ? divider.height : 0) ListItemLayout { id: modelLayout title.text: displayName subtitle.text: { if (type == PrinterEnum.LPDType) return "LPD"; if (type == PrinterEnum.IppSType) return "IppS"; if (type == PrinterEnum.Ipp14Type) return "Ipp14"; if (type == PrinterEnum.HttpType) return "Http"; if (type == PrinterEnum.BehType) return "Beh"; if (type == PrinterEnum.SocketType) return "Socket"; if (type == PrinterEnum.HttpsType) return "Https"; if (type == PrinterEnum.IppType) return "Ipp"; if (type == PrinterEnum.HPType) return "HP"; if (type == PrinterEnum.USBType) return "USB"; if (type == PrinterEnum.HPFaxType) return "HPFax"; if (type == PrinterEnum.DNSSDType) return "DNSSD"; else return "Unknown protocol"; } Icon { id: icon width: height height: units.gu(2.5) name: "network-printer-symbolic" SlotsLayout.position: SlotsLayout.First } Button { text: "Select printer" onClicked: { var suggestedPrinterName = (" " + displayName).slice(1); suggestedPrinterName = suggestedPrinterName.replace(/\ /g, "\-"); printerUri.text = uri; printerName.text = suggestedPrinterName; printerDescription.text = info; printerLocation.text = location; } } } } } Label { anchors { left: parent.left right: parent.right top: remotePrintersLabel.bottom topMargin: units.gu(2) } text: "No other printers found" visible: !remotePrintersSearchIndicator.running && remotePrintersList.count == 0 } } } } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PamAuthentication/000077500000000000000000000000001455543116500266565ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PamAuthentication/CMakeLists.txt000066400000000000000000000030431455543116500314160ustar00rootroot00000000000000include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ) set(QT_IMPORTS_DIR "${CMAKE_INSTALL_LIBDIR}/qt5/qml") set(BARE_PLUGIN_DIR Lomiri/Components/Extras/PamAuthentication) set(PLUGIN_DIR ${QT_IMPORTS_DIR}/${BARE_PLUGIN_DIR}) set(pamauthentication_SRCS pamauthentication.cpp pamauthentication.h pamauthentication_plugin.cpp pamauthentication_plugin.h ) add_library(PamAuthentication MODULE ${pamauthentication_SRCS} ) target_link_libraries(PamAuthentication pam Qt5::Gui Qt5::Qml Qt5::Quick Qt5::Widgets Qt5::DBus ) # Copy the plugin, the qmldir file and other assets to the build dir for running in QtCreator if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") add_custom_command(TARGET PamAuthentication POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/../${BARE_PLUGIN_DIR} COMMENT "Creating plugin directory layout in the build directory" COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/qmldir ${CMAKE_CURRENT_BINARY_DIR}/../${BARE_PLUGIN_DIR} COMMENT "Copying the qmldir file to the build directory" COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_CURRENT_BINARY_DIR}/../${BARE_PLUGIN_DIR} COMMENT "Copying the plugin binary to the build directory" ) endif(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") # Install plugin file install(TARGETS PamAuthentication DESTINATION ${PLUGIN_DIR}) install(FILES qmldir DESTINATION ${PLUGIN_DIR}) lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PamAuthentication/pamauthentication.cpp000066400000000000000000000123011455543116500330740ustar00rootroot00000000000000/* * Copyright (C) 2014 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Author : Arto Jalkanen */ #include "pamauthentication.h" #include #include #include #define UNITYGREETER_SERVICE "com.lomiri.LomiriGreeter" #define UNITYGREETER_PATH "/com/lomiri/LomiriGreeter/list" #define UNITYGREETER_INTERFACE "com.lomiri.LomiriGreeter.List" #define UNITYGREETER_PROPERTY_ENTRY_IS_LOCKED "EntryIsLocked" PamAuthentication::PamAuthentication(QObject *parent) : QObject(parent) { m_userLogin = qgetenv("USER"); } PamAuthentication::~PamAuthentication() { } void PamAuthentication::setServiceName(const QString &serviceName) { if (serviceName != m_serviceName) { m_serviceName = serviceName; Q_EMIT serviceNameChanged(); } } bool PamAuthentication::requireAuthentication() { QDBusInterface dbus_iface(UNITYGREETER_SERVICE, UNITYGREETER_PATH, UNITYGREETER_INTERFACE); qDebug() << Q_FUNC_INFO << "Querying if authentication required"; if (!dbus_iface.isValid()) { qDebug() << Q_FUNC_INFO << "Not a valid dbus interface"; qDebug() << Q_FUNC_INFO << "Last error: " + dbus_iface.lastError().message(); // By default be cautious and require authentication return true; } QVariant isLockedVariant = dbus_iface.property(UNITYGREETER_PROPERTY_ENTRY_IS_LOCKED); if (isLockedVariant.isValid()) { bool replyValue = isLockedVariant.toBool(); qDebug() << Q_FUNC_INFO << "Return value" << replyValue; return replyValue; } else { qDebug() << Q_FUNC_INFO << "Failed getting value for EntryIsLocked property"; } // By default be cautious and require authentication return true; } bool PamAuthentication::validatePasswordToken(const QString &token) { pam_handle *pamHandle = 0; if (!initPam(&pamHandle)) { qDebug() << Q_FUNC_INFO << "Pam init failed"; return false; } m_passwordToken = token; int status = pam_authenticate(pamHandle, 0); qDebug() << Q_FUNC_INFO << "Pam authenticate status" << status << pam_strerror(pamHandle, status); if (status == PAM_SUCCESS) { status = validateAccount(pamHandle); } pam_end(pamHandle, status); m_passwordToken.clear(); return status == PAM_SUCCESS; } int PamAuthentication::validateAccount(pam_handle *pamHandle) { // This makes sure account and password are still valid int status = pam_acct_mgmt(pamHandle, 0); qDebug() << Q_FUNC_INFO << "pam_acct_mgmt: " << status << pam_strerror(pamHandle, status); // Placeholders for some common errors // IMPROVE: it'd be good to let user know reason for failure switch (status) { case PAM_SUCCESS: break; case PAM_USER_UNKNOWN: break; case PAM_ACCT_EXPIRED: break; case PAM_NEW_AUTHTOK_REQD: break; } return status; } bool PamAuthentication::initPam(pam_handle **pamHandle) { pam_conv conversation; conversation.conv = ConversationFunction; conversation.appdata_ptr = static_cast(this); return pam_start(m_serviceName.toLocal8Bit().data(), m_userLogin.toLocal8Bit().data(), &conversation, pamHandle) == PAM_SUCCESS; } int PamAuthentication::ConversationFunction(int num_msg, const pam_message **msg, pam_response **resp, void *appdata_ptr) { if (num_msg <= 0) { return PAM_CONV_ERR; } *resp = static_cast(calloc(num_msg, sizeof(pam_response))); PamAuthentication *self = static_cast(appdata_ptr); for (int count = 0; count < num_msg; ++count) { switch (msg[count]->msg_style) { case PAM_PROMPT_ECHO_ON: { qDebug() << Q_FUNC_INFO << "PAM_PROMPT_ECHO_ON received"; resp[count]->resp = strdup(self->m_passwordToken.toLocal8Bit().data()); resp[count]->resp_retcode = 0; break; } case PAM_PROMPT_ECHO_OFF: { qDebug() << Q_FUNC_INFO << "PAM_PROMPT_ECHO_OFF received"; resp[count]->resp = strdup(self->m_passwordToken.toLocal8Bit().data()); resp[count]->resp_retcode = 0; break; } case PAM_TEXT_INFO: { QString message(msg[count]->msg); qDebug() << Q_FUNC_INFO << "PAM_TEXT_INFO received" << message; break; } case PAM_AUTHTOK: { qDebug() << Q_FUNC_INFO << "PAM_AUTHTOK received"; break; } default: { qDebug() << Q_FUNC_INFO << "Other PAM msg received: " << msg[count]->msg_style; } } } return PAM_SUCCESS; } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PamAuthentication/pamauthentication.h000066400000000000000000000105011455543116500325410ustar00rootroot00000000000000/* * Copyright (C) 2014 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Author : Arto Jalkanen */ #ifndef PAMAUTHENTICATION_H #define PAMAUTHENTICATION_H #include #include #include #include // Forward declarations struct pam_handle; struct pam_message; struct pam_response; /** * QML plugin to query if authentication is required and do authentication. * * At the moment the plugin is expected to be used as follows: * * - Ask if authentication is required (requireAuthentication() function). This will * return true if Ubuntu Touch user has selected some unlocking security (PIN code or password). * - If so, the application should provide a dialog to ask for the PIN code/password and * call validatePasswordToken(provided password) function. * - If validatePasswordToken() function returns true for given token, then user was authenticated, * otherwise failed to authenticate. * * Caveats: * * - If user failed to authenticate, it doesn't necessarily mean password was invalid. Failure * can also be because of account being locked or password being expired or because of some other * reason in the underlying pam library. The exact reason is not currently available to QML, as practically * for normal users the only reason is password mismatch. If the user has done advanced modifications * the exact reason for failure can be seen in application's logs. * - Currently the application using this module will have to provide the dialogs asking for * for PIN/password and an error dialog. This will most likely change in future, but there's no * concrete plans yet. Discussion at https://code.launchpad.net/~ubuntu-filemanager-dev/ubuntu-filemanager-app/require-screenlock-password/+merge/230058 * can be seen for some background information. * * Simplified skeleton QML code example that asks for authentication if required at start-up of application (specific dialogs omitted): * * import Lomiri.Components.Extras.PamAuthentication 0.1 * * MainView { * PamAuthentication { * id: pamAuthentication * serviceName: "applicationName" * } * * Component.onCompleted: { * if (pamAuthentication.requireAuthentication()) { * var passwordToken = queryPasswordInputDialog() * if (!pamAuthentication.validatePasswordToken(passwordToken) { * // Successs... * } else { * showAuthenticationFailedDialog() * } * } * } * } * */ class PamAuthentication : public QObject { Q_OBJECT public: explicit PamAuthentication(QObject *parent = 0); ~PamAuthentication(); /** * \brief returns true if current user has password or PIN code set for unlocking lockscreen */ Q_INVOKABLE bool requireAuthentication(); /** * \brief returns true if current user can be authenticated with given password token (be it PIN code or password) */ Q_INVOKABLE bool validatePasswordToken(const QString &token); /** * \brief Should be set to the application's name in lowercase. For example, for FileManager it would be "filemanager". */ Q_PROPERTY(QString serviceName READ serviceName WRITE setServiceName NOTIFY serviceNameChanged) inline const QString &serviceName() const { return m_serviceName; } void setServiceName(const QString &serviceName); Q_SIGNALS: void serviceNameChanged(); public Q_SLOTS: private: static int ConversationFunction(int num_msg, const pam_message **msg, pam_response **resp, void *appdata_ptr); bool initPam(pam_handle **pamHandle); int validateAccount(pam_handle *pamHandle); QString m_passwordToken; QString m_serviceName; QString m_userLogin; }; #endif // PAMAUTHENTICATION_H pamauthentication_plugin.cpp000066400000000000000000000021631455543116500344000ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PamAuthentication/* * Copyright (C) 2014 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Author : Arto Jalkanen */ #include #include #include "pamauthentication_plugin.h" #include "pamauthentication.h" void BackendPlugin::registerTypes(const char *uri) { Q_ASSERT(uri == QLatin1String("Lomiri.Components.Extras.PamAuthentication")); qmlRegisterType(uri, 0, 1, "PamAuthentication"); } void BackendPlugin::initializeEngine(QQmlEngine *engine, const char *uri) { QQmlExtensionPlugin::initializeEngine(engine, uri); } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PamAuthentication/pamauthentication_plugin.h000066400000000000000000000021241455543116500341210ustar00rootroot00000000000000/* * Copyright (C) 2014 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Author : Arto Jalkanen */ #ifndef PAMAUTHENTICATION_PLUGIN_H #define PAMAUTHENTICATION_PLUGIN_H #include #include class BackendPlugin : public QQmlExtensionPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") public: void registerTypes(const char *uri); void initializeEngine(QQmlEngine *engine, const char *uri); }; #endif // PAMAUTHENTICATION_PLUGIN_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PamAuthentication/qmldir000066400000000000000000000001131455543116500300640ustar00rootroot00000000000000module Lomiri.Components.Extras.PamAuthentication plugin PamAuthentication lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PhotoEditor.qml000066400000000000000000000164611455543116500262240ustar00rootroot00000000000000/* * Copyright (C) 2014 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . */ import QtQuick 2.9 import Lomiri.Components 1.3 import Lomiri.Components.Popups 1.3 import Lomiri.Components.Extras 0.2 import "PhotoEditor" Item { id: editor property string photo property bool modified: stack.modified signal closed(bool photoWasModified) property list actions actions: [stack.undoAction, stack.redoAction] EditStack { id: stack data: photoData actionsEnabled: !exposureSelector.visible && !cropper.visible && !photoData.busy onRevertRequested: PopupUtils.open(revertPromptComponent) } property list toolActions: [ Action { objectName: "cropButton" text: i18n.dtr("lomiri-ui-extras", "Crop") iconSource: Qt.resolvedUrl("PhotoEditor/assets/edit_crop.png") onTriggered: { photoData.isLongOperation = false; cropper.start("image://photo/" + photoData.path); } }, Action { objectName: "rotateButton" text: i18n.dtr("lomiri-ui-extras", "Rotate") iconSource: Qt.resolvedUrl("PhotoEditor/assets/edit_rotate_right.png") onTriggered: { photoData.isLongOperation = false; photoData.rotateRight() } }, Action { objectName: "exposureButton" text: i18n.tr("Exposure") iconSource: Qt.resolvedUrl("PhotoEditor/assets/edit_exposure.png") onTriggered: { photoData.isLongOperation = false; exposureSelector.start("image://photo/" + photoData.path); } } ] function close(saveIfModified) { stack.endEditingSession(saveIfModified); editor.closed(editor.modified); } function open(photo) { editor.photo = photo; stack.startEditingSession(photo); photoData.path = stack.currentFile; image.source = "image://photo/" + photoData.path; } Rectangle { color: "black" anchors.fill: parent } Image { id: image anchors.fill: parent asynchronous: true cache: false source: photoData.path ? "image://photo/" + photoData.path : "" fillMode: Image.PreserveAspectFit sourceSize { width: image.width height: image.height } function reload() { image.asynchronous = false; image.source = ""; image.asynchronous = true; image.source = "image://photo/" + photoData.path; } } PhotoData { id: photoData onDataChanged: image.reload() property bool isLongOperation: false onEditFinished: { console.log("Edit finished") // If we are editing exposure we don't need to checkpoint at every // edit, and the exposure UI will checkpoint when the user confirms. if (exposureSelector.opacity > 0) exposureSelector.reload() else stack.checkpoint() } } Loader { id: cropper anchors.fill: parent opacity: 0.0 visible: opacity > 0 Behavior on opacity { LomiriNumberAnimation { } } Connections { target: cropper.item ignoreUnknownSignals: true onCropped: { var qtRect = Qt.rect(rect.x, rect.y, rect.width, rect.height); photoData.crop(qtRect); cropper.opacity = 0.0; cropper.source = "" } onCanceled: { cropper.opacity = 0.0; cropper.source = "" } } function start(target) { source = "PhotoEditor/CropInteractor.qml"; item.targetPhoto = target; } onLoaded: opacity = 1.0 } ExposureAdjuster { id: exposureSelector anchors.fill: parent opacity: 0.0 enabled: !photoData.busy onExposureChanged: { // Restore the starting version of the image, otherwise we will // accumulate compensations over the previous ones. stack.restoreSnapshot(stack.level) photoData.exposureCompensation(exposure) } onConfirm: { stack.checkpoint(); exposureSelector.opacity = 0.0 } onCancel: { stack.restoreSnapshot(stack.level) exposureSelector.opacity = 0.0 } visible: opacity > 0 } ActionsBar { id: actionsBar objectName: "editorActionsBar" anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right visible: opacity > 0.0 opacity: (exposureSelector.opacity == 0 && cropper.opacity == 0) ? 1.0 : 0.0 enabled: !photoData.busy toolActions: { // This is necessary because QML does not let us declare a list with // mixed component declarations and identifiers, like this: // property list foo: { Action{}, someOtherAction } var list = []; for (var i = 0; i < editor.toolActions.length; i++) list.push(editor.toolActions[i]); list.push(stack.revertAction); return list; } Behavior on opacity { LomiriNumberAnimation {} } } Component { id: revertPromptComponent Dialog { id: revertPrompt objectName: "revertPromptDialog" title: i18n.dtr("lomiri-ui-extras", "Revert to original") text: i18n.dtr("lomiri-ui-extras", "This will undo all edits, including those from previous sessions.") Row { id: row width: parent.width spacing: units.gu(1) Button { objectName: "cancelRevertButton" width: parent.width/2 text: i18n.dtr("lomiri-ui-extras", "Cancel") onClicked: PopupUtils.close(revertPrompt) } Button { objectName: "confirmRevertButton" width: parent.width/2 text: i18n.dtr("lomiri-ui-extras", "Revert Photo") color: theme.palette.normal.negative onClicked: { PopupUtils.close(revertPrompt) stack.revertToPristine() } } } } } BusyIndicator { id: busyIndicator anchors.centerIn: parent text: i18n.dtr("lomiri-ui-extras", "Enhancing photo...") running: photoData.busy longOperation: photoData.isLongOperation } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PhotoEditor/000077500000000000000000000000001455543116500255015ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PhotoEditor/ActionsBar.qml000066400000000000000000000047621455543116500302520ustar00rootroot00000000000000/* * Copyright (C) 2014 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . */ import QtQuick 2.9 import Lomiri.Components 1.3 import Lomiri.Components.ListItems 1.3 as ListItem Column { id: bar property list toolActions property list filterActions property bool enabled height: (filtersBar.visible) ? units.gu(20) : units.gu(6) Item { anchors.left: parent.left anchors.right: parent.right height: units.gu(6) Rectangle { anchors.fill: parent color: "black" opacity: 0.6 } ListView { id: toolsBar anchors.fill: parent orientation: ListView.Horizontal model: toolActions delegate: AbstractButton { width: units.gu(8) anchors.top: parent.top anchors.bottom: parent.bottom action: modelData enabled: bar.enabled Icon { anchors.centerIn: parent name: modelData.iconName source: modelData.iconSource width: units.gu(3) height: units.gu(3) opacity: modelData.enabled && parent.enabled ? 1.0 : 0.5 } } } } Rectangle { anchors.left: parent.left anchors.right: parent.right height: units.gu(14) color: "black" ListView { id: filtersBar objectName: "filtersBar" visible: filterActions.length > 0 orientation: ListView.Horizontal model: filterActions delegate: ListItem.Standard { width: parent.height anchors.top: parent.top anchors.bottom: parent.bottom action: modelData iconFrame: false enabled: bar.enabled } } } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PhotoEditor/BusyIndicator.qml000066400000000000000000000031561455543116500310000ustar00rootroot00000000000000/* * Copyright (C) 2015 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . */ import QtQuick 2.9 import Lomiri.Components 1.3 Item { id: busy property alias text: label.text property alias running: spinner.running property bool longOperation: false visible: running LomiriShape { id: busyLomiriShape objectName: "busyLomiriShape" backgroundColor: theme.palette.normal.background anchors.centerIn: parent width: parent.width + units.gu(4) height: parent.height + units.gu(4) opacity: longOperation ? 0.75 : 0 } Column { id: busyColumn objectName: "busyColumn" anchors.centerIn: parent spacing: units.gu(2) ActivityIndicator { id: spinner anchors.horizontalCenter: parent.horizontalCenter } Label { id: label objectName: "busyLabel" anchors.horizontalCenter: parent.horizontalCenter horizontalAlignment: Text.AlignHCenter visible: longOperation } } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PhotoEditor/CMakeLists.txt000066400000000000000000000002421455543116500302370ustar00rootroot00000000000000file(GLOB QML_FILES *.qml *.js) install(FILES ${QML_FILES} DESTINATION ${PLUGIN_DIR}/PhotoEditor) install(DIRECTORY assets DESTINATION ${PLUGIN_DIR}/PhotoEditor) lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PhotoEditor/CropCorner.qml000066400000000000000000000030711455543116500302710ustar00rootroot00000000000000/* * Copyright (C) 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authors: * Charles Lindsay */ import QtQuick 2.9 import Lomiri.Components 1.3 // A corner of a CropFrame. Item { id: cropCorner /*! */ signal dragged(real dx, real dy) /*! */ signal dragStarted() /*! */ signal dragCompleted() /*! */ property bool isLeft: true /*! */ property bool isTop: true x: isLeft ? -(width/2) : parent.width - (width/2) y: isTop ? -(width/2) : parent.height - (width/2) width: handle.width height: handle.height Image { id: handle anchors.centerIn: parent source: Qt.resolvedUrl("assets/crop-handle.png") } CropDragArea { anchors.centerIn: parent width: handle.width + units.gu(2) height: handle.height + units.gu(2) onDragged: cropCorner.dragged(dx, dy) onDragStarted: cropCorner.dragStarted() onDragCompleted: cropCorner.dragCompleted() } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PhotoEditor/CropDragArea.qml000066400000000000000000000025601455543116500305110ustar00rootroot00000000000000/* * Copyright (C) 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authors: * Charles Lindsay */ import QtQuick 2.9 // A MouseArea meant to drag a corner/edge of a crop area. MouseArea { id: cropDragArea /*! */ signal dragged(real dx, real dy) /*! */ signal dragStarted() /*! */ signal dragCompleted() // Since we're usually moving this area with the mouse in response to // dragging, we don't need to capture the last x/y, just where it was // grabbed. property real grabX: -1 /*! */ property real grabY: -1 onPressed: { dragStarted(); grabX = mouse.x; grabY = mouse.y; } onReleased: { dragCompleted(); } onPositionChanged: cropDragArea.dragged(mouse.x - grabX, mouse.y - grabY) } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PhotoEditor/CropInteractor.qml000066400000000000000000000076631455543116500311660ustar00rootroot00000000000000/* * Copyright (C) 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authors: * Charles Lindsay * Lucas Beeler */ import QtQuick 2.9 import Lomiri.Components 1.3 import "GraphicsRoutines.js" as GraphicsRoutines /*! */ Rectangle { id: cropInteractor objectName: "cropInteractor" color: "black" property alias targetPhoto: original.source property string matteColor: "black" property real matteOpacity: 0.6 // Note: each element of the cropped rect will be in the range [0,1], since // in the UI we aren't using direct photo pixel values. signal cropped(variant rect) signal canceled() function computeRectSet() { var actualImage = Qt.rect( (original.width - original.paintedWidth) / 2.0, (original.height - original.paintedHeight) / 2.0, original.paintedWidth, original.paintedHeight ); var photoPreview = GraphicsRoutines.fitRect(viewport, actualImage); var unfitCrop = Qt.rect(0, 0, photoPreview.width, photoPreview.height); var cropFrame = GraphicsRoutines.fitRect(viewport, unfitCrop); var photoExtent = Qt.rect(cropFrame.x, cropFrame.y, cropFrame.scaleFactor * photoPreview.width, cropFrame.scaleFactor * photoPreview.height); return { photoPreview: photoPreview, cropFrame: cropFrame, photoExtent: photoExtent, photoExtentScale: cropFrame.scaleFactor }; } Item { id: viewport anchors.fill: parent anchors.margins: units.gu(6) z: 1 } CropOverlay { id: overlay objectName: "cropOverlay" property real minSize: units.gu(4) anchors.fill: parent; visible: false; photo: original viewport: viewport matteColor: cropInteractor.matteColor matteOpacity: cropInteractor.matteOpacity z: 16 onMatteRegionPressed: { cropInteractor.canceled(); } onCropButtonPressed: { original.visible = false; overlay.visible = false; original.scale = 1.0; var r = overlay.getRelativeFrameRect() cropInteractor.cropped(overlay.getRelativeFrameRect()); } } Image { id: original x: viewport.x y: viewport.y width: viewport.width height: viewport.height transformOrigin: Item.TopLeft fillMode: Image.PreserveAspectFit cache: false sourceSize { width: original.width height: original.height } onStatusChanged: { if (status == Image.Ready) { var rects = computeRectSet(); overlay.initialFrameX = rects.cropFrame.x; overlay.initialFrameY = rects.cropFrame.y; overlay.initialFrameWidth = rects.cropFrame.width; overlay.initialFrameHeight = rects.cropFrame.height; overlay.resetFor(rects); overlay.visible = true; x = rects.photoExtent.x; y = rects.photoExtent.y; width = rects.photoPreview.width; height = rects.photoPreview.height; scale = rects.photoExtentScale; } } } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml000066400000000000000000000423101455543116500304610ustar00rootroot00000000000000/* * Copyright (C) 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authors: * Charles Lindsay * Lucas Beeler */ import QtQuick 2.9 import Lomiri.Components 1.3 import "GraphicsRoutines.js" as GraphicsRoutines /* A CropOverlay is a semi-transparent surface that floats over the photo. It * serves two purposes. First, it provides visual cueing as to what region of * the photo's surface will be preserved when the crop operation is applied. * The preserved region is the region that falls inside of the CropOverlay's * frame. Second, the CropOverlay allows the user to manipulate the * geometry of the crop frame, to chage its location, width, and height. The * geometry of the crop frame is reinforced by a key visual cue: the region of * the photo outside of the crop frame is drawn with a semi-transparent, smoked * matte on top of it. This matte surrounds the crop frame. */ Item { id: cropOverlay // public properties /*! */ property Item viewport /*! */ property Item photo /*! */ property string matteColor: "red" /*! */ property real matteOpacity: 0.85 /*! */ property int initialFrameX: -1 /*! */ property int initialFrameY: -1 /*! */ property int initialFrameWidth: -1 /*! */ property int initialFrameHeight: -1 // private properties -- Frame Fit Animation parameters property real interpolationFactor: 1.0 /*! */ property variant startFrame /*! */ property variant endFrame /*! */ property variant startPhoto /*! */ property real referencePhotoWidth: -1 /*! */ property real referencePhotoHeight: -1 /*! */ property real endPhotoX /*! */ property real endPhotoY /*! */ property real endPhotoWidth /*! */ property real endPhotoHeight /*! */ signal userAlteredFrame() /*! */ signal runFrameFitAnimation() /*! */ signal matteRegionPressed() /*! */ signal cropButtonPressed() /*! */ function resetFor(rectSet) { if (initialFrameX != -1 && initialFrameY != -1 && initialFrameWidth != -1 && initialFrameHeight != -1) { frame.x = rectSet.cropFrame.x; frame.y = rectSet.cropFrame.y; frame.width = rectSet.cropFrame.width; frame.height = rectSet.cropFrame.height; photoExtent.x = rectSet.photoExtent.x; photoExtent.y = rectSet.photoExtent.y; photoExtent.width = rectSet.photoExtent.width; photoExtent.height = rectSet.photoExtent.height; referencePhotoWidth = rectSet.photoPreview.width; referencePhotoHeight = rectSet.photoPreview.height; } } /* Return the (x, y) position and the width and height of the viewport */ function getViewportExtentRect() { return GraphicsRoutines.cloneRect(viewport); } /* Return the (x, y) position and the width and height of the photoExtent. * The photoExtent is the on-screen region that holds the original photo * preview. */ function getPhotoExtentRect() { return GraphicsRoutines.cloneRect(photoExtent); } /*! */ function getRelativeFrameRect() { return GraphicsRoutines.getRelativeRect(frame.getExtentRect(), getPhotoExtentRect()); } anchors.fill: parent Item { id: photoExtent property real panStartX property real panStartY function startPan() { panStartX = x; panStartY = y; } // 'deltaX' and 'deltaY' are offsets relative to the pan start point function updatePan(deltaX, deltaY) { var newX = panStartX + deltaX; var newY = panStartY + deltaY; x = GraphicsRoutines.clamp(newX, frame.x + frame.width - photoExtent.width, frame.x); y = GraphicsRoutines.clamp(newY, frame.y + frame.height - photoExtent.height, frame.y); } function stopPan() { } x: initialFrameX y: initialFrameY width: initialFrameWidth height: initialFrameHeight z: 1 onXChanged: { if (photo) photo.x = x; } onYChanged: { if (photo) photo.y = y; } onWidthChanged: { if (photo && referencePhotoWidth > 0) photo.scale = width / referencePhotoWidth; } onHeightChanged: { if (photo && referencePhotoHeight > 0) photo.scale = height / referencePhotoHeight; } } // // The following four Rectangles are used to "matte out" the area of the photo // preview that falls outside the frame. This "matting out" visual cue is // accomplished by darkening the matted-out area with a translucent, smoked // overlay. // Rectangle { id: leftMatte color: cropOverlay.matteColor opacity: cropOverlay.matteOpacity anchors.top: topMatte.bottom anchors.bottom: frame.bottom anchors.left: parent.left anchors.right: frame.left MouseArea { anchors.fill: parent; onPressed: cropOverlay.matteRegionPressed(); } } Rectangle { id: topMatte color: cropOverlay.matteColor opacity: cropOverlay.matteOpacity anchors.top: parent.top anchors.bottom: frame.top anchors.left: parent.left anchors.right: parent.right MouseArea { anchors.fill: parent; onPressed: cropOverlay.matteRegionPressed(); } } Rectangle { id: rightMatte color: cropOverlay.matteColor opacity: cropOverlay.matteOpacity anchors.top: topMatte.bottom anchors.bottom: bottomMatte.top anchors.left: frame.right anchors.right: parent.right MouseArea { anchors.fill: parent; onPressed: cropOverlay.matteRegionPressed(); } } Rectangle { id: bottomMatte color: cropOverlay.matteColor opacity: cropOverlay.matteOpacity anchors.top: frame.bottom anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right MouseArea { anchors.fill: parent; onPressed: cropOverlay.matteRegionPressed(); } } // // The frame is a grey rectangle with associated drag corners that // frames the region of the photo that will remain when the crop operation is // applied. // // NB: the frame can be in two states, although the QML state mechanism // isn't sufficiently expressive to describe them. The frame can be // in the FIT state, in which case it is optimally fit inside the // frame constraint region (see getFrameConstraintRect( ) above for // a description of the frame constraint region). Or, the frame can // be in the USER state. In the user state, the user has the mouse button // held down and is actively performing a drag operation to change the // geometry of the frame. // Rectangle { id: frame signal resizedX(bool left, real dx) signal resizedY(bool top, real dy) property variant dragStartRect function getExtentRect() { var result = { }; result.x = x; result.y = y; result.width = width; result.height = height; return result; } x: cropOverlay.initialFrameX y: cropOverlay.initialFrameY width: cropOverlay.initialFrameWidth height: cropOverlay.initialFrameHeight color: "transparent" border.width: units.gu(0.2) border.color: "#19B6EE" MouseArea { id: panArea property int dragStartX; property int dragStartY; anchors.fill: parent anchors.margins: 2 onPressed: { dragStartX = mouse.x; dragStartY = mouse.y; photoExtent.startPan(); } onReleased: { photoExtent.stopPan(); } onPositionChanged: { photoExtent.updatePan(mouse.x - dragStartX, mouse.y - dragStartY); } } Button { objectName: "centerCropIcon" anchors.centerIn: parent text: i18n.dtr("lomiri-ui-extras", "Crop") color: frame.border.color opacity: 0.9 onClicked: cropOverlay.cropButtonPressed() } // Left drag bar. CropDragArea { x: -units.gu(2) width: units.gu(3) anchors.verticalCenter: parent.center height: parent.height - units.gu(2) onDragged: { frame.resizedX(true, dx); frame.updateOnAltered(false); } onDragStarted: frame.dragStartRect = frame.getExtentRect(); onDragCompleted: frame.updateOnAltered(true); } // Top drag bar. CropDragArea { y: -units.gu(2) height: units.gu(3) anchors.horizontalCenter: parent.center width: parent.width - units.gu(2) onDragged: { frame.resizedY(true, dy); frame.updateOnAltered(false); } onDragStarted: frame.dragStartRect = frame.getExtentRect(); onDragCompleted: frame.updateOnAltered(true); } // Right drag bar. CropDragArea { x: parent.width - units.gu(1) width: units.gu(3) anchors.verticalCenter: parent.center height: parent.height - units.gu(2) onDragged: { frame.resizedX(false, dx); frame.updateOnAltered(false); } onDragStarted: frame.dragStartRect = frame.getExtentRect(); onDragCompleted: frame.updateOnAltered(true); } // Bottom drag bar. CropDragArea { y: parent.height - units.gu(1) height: units.gu(3) anchors.horizontalCenter: parent.center width: parent.width - units.gu(2) onDragged: { frame.resizedY(false, dy); frame.updateOnAltered(false); } onDragStarted: frame.dragStartRect = frame.getExtentRect(); onDragCompleted: frame.updateOnAltered(true); } // Top-left corner. CropCorner { objectName: "topLeftCropCorner" isLeft: true isTop: true onDragged: { frame.resizedX(isLeft, dx); frame.resizedY(isTop, dy); frame.updateOnAltered(false); } onDragStarted: frame.dragStartRect = frame.getExtentRect(); onDragCompleted: frame.updateOnAltered(true); } // Top-right corner. CropCorner { objectName: "topRightCropCorner" isLeft: false isTop: true onDragged: { frame.resizedX(isLeft, dx); frame.resizedY(isTop, dy); frame.updateOnAltered(false); } onDragStarted: frame.dragStartRect = frame.getExtentRect(); onDragCompleted: frame.updateOnAltered(true); } // Bottom-left corner. CropCorner { objectName: "bottonLeftCropCorner" isLeft: true isTop: false onDragged: { frame.resizedX(isLeft, dx); frame.resizedY(isTop, dy); frame.updateOnAltered(false); } onDragStarted: frame.dragStartRect = frame.getExtentRect(); onDragCompleted: frame.updateOnAltered(true); } // Bottom-right corner. CropCorner { id: bottomRightCrop objectName: "bottomRightCropCorner" isLeft: false isTop: false onDragged: { frame.resizedX(isLeft, dx); frame.resizedY(isTop, dy); frame.updateOnAltered(false); } onDragStarted: frame.dragStartRect = frame.getExtentRect(); onDragCompleted: frame.updateOnAltered(true); } // This handles resizing in both dimensions. first is whether we're // resizing the "first" edge, e.g. left or top (in which case we // adjust both position and span) vs. right or bottom (where we just // adjust the span). position should be either "x" or "y", and span // is either "width" or "height". This is a little complicated, and // coule probably be optimized with a little more thought. function resizeFrame(first, delta, position, span) { var constraintRegion = cropOverlay.getPhotoExtentRect(); if (first) { // Left/top side. if (frame[position] + delta < constraintRegion[position]) delta = constraintRegion[position] - frame[position] if (frame[span] - delta < minSize) delta = frame[span] - minSize; frame[position] += delta; frame[span] -= delta; } else { // Right/bottom side. if (frame[span] + delta < minSize) delta = minSize - frame[span]; if ((frame[position] + frame[span] + delta) > (constraintRegion[position] + constraintRegion[span])) delta = constraintRegion[position] + constraintRegion[span] - frame[position] - frame[span]; frame[span] += delta; } } onResizedX: resizeFrame(left, dx, "x", "width") onResizedY: resizeFrame(top, dy, "y", "height") function updateOnAltered(finalUpdate) { var start = frame.dragStartRect; var end = frame.getExtentRect(); if (!GraphicsRoutines.areEqual(end, start)) { if (finalUpdate || (end.width * end.height >= start.width * start.height)) { cropOverlay.userAlteredFrame(); cropOverlay.runFrameFitAnimation(); } } } } /* Invoked when the user has changed the geometry of the frame by dragging * one of its corners or edges. Expressed in terms of the states of the * frame described above, the userAlteredFrame signal is fired * when the user stops dragging. This triggers a change of the frame * from the USER state to the FIT state */ onUserAlteredFrame: { // since the geometry of the frame in the FIT state depends on both // how the user resized the frame when it was in the USER state as well // as the size of the frame constraint region, we have to recompute the // geometry of of the frame for the FIT state every time. startFrame = GraphicsRoutines.cloneRect(frame); endFrame = GraphicsRoutines.fitRect(getViewportExtentRect(), frame.getExtentRect()); startPhoto = GraphicsRoutines.cloneRect(photoExtent); var frameRelativeToPhoto = getRelativeFrameRect(); var scaleFactor = endFrame.width / frame.width; endPhotoWidth = photoExtent.width * scaleFactor; endPhotoHeight = photoExtent.height * scaleFactor; endPhotoX = endFrame.x - (frameRelativeToPhoto.x * endPhotoWidth); endPhotoY = endFrame.y - (frameRelativeToPhoto.y * endPhotoHeight) photo.transformOrigin = Item.TopLeft; } onRunFrameFitAnimation: NumberAnimation { target: cropOverlay; property: "interpolationFactor"; from: 0.0; to: 1.0 } onInterpolationFactorChanged: { var endPhotoRect = { }; endPhotoRect.x = endPhotoX; endPhotoRect.y = endPhotoY; endPhotoRect.width = endPhotoWidth; endPhotoRect.height = endPhotoHeight; var interpolatedRect = GraphicsRoutines.interpolateRect(startFrame, endFrame, interpolationFactor); GraphicsRoutines.sizeToRect(interpolatedRect, frame); interpolatedRect = GraphicsRoutines.interpolateRect(startPhoto, endPhotoRect, interpolationFactor); GraphicsRoutines.sizeToRect(interpolatedRect, photoExtent); } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml000066400000000000000000000111041455543116500300640ustar00rootroot00000000000000/* * Copyright (C) 2014 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . */ import QtQuick 2.9 import Lomiri.Components 1.3 import Lomiri.Components.Extras 0.2 Item { property PhotoData data property bool actionsEnabled: true property var items: [] property int level: 0 property string editingSessionPath property string currentFile property string originalFile property string pristineFile property bool modified: level > 0 || _revertedInThisSession property bool _revertedInThisSession property bool _pristineFileExists signal revertRequested function startEditingSession(original) { var originalFileName = FileUtils.nameFromPath(original); var baseName = FileUtils.parentDirectory(original) + "/.photo_editing." + originalFileName + "."; editingSessionPath = FileUtils.createTemporaryDirectory(baseName); if (editingSessionPath == "") return false; originalFile = original; currentFile = editingSessionPath + "/current"; pristineFile = FileUtils.parentDirectory(original) + "/.original/" + originalFileName _revertedInThisSession = false; _pristineFileExists = FileUtils.exists(pristineFile) FileUtils.copy(originalFile, currentFile) items = [createSnapshot(0)]; level = 0; return true; } function endEditingSession(saveIfModified) { if (saveIfModified && modified) { // file modified // if we don't have a copy of the very first original, create one if (!_pristineFileExists) { FileUtils.createDirectory(FileUtils.parentDirectory(pristineFile)); FileUtils.copy(originalFile, pristineFile); } else { // if we reverted to original (and made no other changes) // we don't need to keep the pristine copy around if (_revertedInThisSession && level <= 0) { FileUtils.remove(pristineFile); } } FileUtils.copy(currentFile, originalFile); // actually save } FileUtils.removeDirectory(editingSessionPath, true); // clear editing cache editingSessionPath = originalFile = pristineFile = currentFile = ""; } function createSnapshot(name) { var snapshotFile = editingSessionPath + "/edit." + name; FileUtils.copy(currentFile, snapshotFile); return snapshotFile; } function restoreSnapshot(name) { var snapshotFile = editingSessionPath + "/edit." + name; FileUtils.copy(snapshotFile, currentFile); data.refreshFromDisk(); } function checkpoint() { level++; items = items.slice(0, level); items.push(createSnapshot(items.length)); } function revertToPristine() { if (!FileUtils.exists(pristineFile)) { restoreSnapshot(0); items = items.slice(0, 1); level = 0; } else { FileUtils.copy(pristineFile, currentFile); data.refreshFromDisk(); items = []; checkpoint(); level = 0; _revertedInThisSession = true; } } property Action undoAction: Action { text: i18n.dtr("lomiri-ui-extras", "Undo") iconName: "undo" enabled: items.length > 0 && level > 0 && actionsEnabled onTriggered: restoreSnapshot(--level); } property Action redoAction: Action { text: i18n.dtr("lomiri-ui-extras", "Redo") iconName: "redo" enabled: level < items.length - 1 && actionsEnabled onTriggered: restoreSnapshot(++level); } property Action revertAction: Action { text: i18n.dtr("lomiri-ui-extras", "Revert to original") iconSource: Qt.resolvedUrl("assets/edit_revert.png") enabled: actionsEnabled && (level > 0 || (!_revertedInThisSession && _pristineFileExists)) onTriggered: revertRequested() } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml000066400000000000000000000056231455543116500315360ustar00rootroot00000000000000/* * Copyright (C) 2014 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . */ import QtQuick 2.9 import Lomiri.Components 1.3 import Lomiri.Components.Extras 0.2 // When the photo editor uses a proper PageStack this will switch back to being // an Item as it will not need to cover what is below it. Rectangle { id: adjuster color:"black" property alias exposure: exposureSelector.value property bool enabled signal confirm() signal cancel() Image { id: targetImage anchors.fill: parent fillMode: Image.PreserveAspectFit asynchronous: true cache: false sourceSize { width: targetImage.width height: targetImage.height } } Column { anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom anchors.margins: units.gu(2) spacing: units.gu(2) Slider { id: exposureSelector live: false minimumValue: -1.0 maximumValue: +1.0 value: 0.0 enabled: adjuster.enabled anchors.left: parent.left anchors.right: parent.right height: units.gu(2) function formatValue(value) { return (Math.round(value * 100) / 100).toString() } } Row { anchors.horizontalCenter: parent.horizontalCenter spacing: units.gu(2) Button { text: i18n.dtr("lomiri-ui-extras", "Cancel") enabled: adjuster.enabled onTriggered: { targetImage.source = ""; cancel(); } } Button { text: i18n.dtr("lomiri-ui-extras", "Done") color: theme.palette.normal.positive enabled: adjuster.enabled onTriggered: { targetImage.source = ""; confirm(); } } } } function start(target) { targetImage.source = target; exposure = 0.0; opacity = 1.0; } function reload() { var path = targetImage.source; targetImage.asynchronous = false; targetImage.source = ""; targetImage.asynchronous = true; targetImage.source = path; } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PhotoEditor/GraphicsRoutines.js000066400000000000000000000064001455543116500313300ustar00rootroot00000000000000/* * Copyright (C) 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authors: * Lucas Beeler */ /* Given 'input', constrain the value of 'input' to range between * 'lowConstraint' and 'highConstraint', inclusive. Return the constrained * value without modifying 'input'. */ function clamp(input, lowConstraint, highConstraint) { if (input < lowConstraint) return lowConstraint; else if (input > highConstraint) return highConstraint; else return input; } function cloneRect(source) { var ret = { }; ret.x = source.x; ret.y = source.y; ret.width = source.width; ret.height = source.height; return ret; } function interpolateRect(start, end, factor) { var result = { }; result.x = start.x + factor * (end.x - start.x); result.y = start.y + factor * (end.y - start.y); result.width = start.width + factor * (end.width - start.width); result.height = start.height + factor * (end.height - start.height); return result; } /* Forces Geometry object 'item' to fit centered inside Geometry object * 'viewport', preserving the aspect of ratio of 'item' but potentially scaling * and translating it so that it snugly fits centered inside of 'viewport'. * Return the new scaled-up and translated Geometry for 'item'. */ function fitRect(viewport, item) { if (item.width == 0 || item.height == 0) { return viewport; } var itemAspectRatio = item.width / item.height; var viewportAspectRatio = viewport.width / viewport.height; var result = { }; if (itemAspectRatio > viewportAspectRatio) { var scaleFactor = viewport.width / item.width; result.width = viewport.width; result.height = item.height * scaleFactor } else { scaleFactor = viewport.height / item.height; result.width = item.width * scaleFactor result.height = viewport.height; } result.width = clamp(result.width, 0, viewport.width); result.height = clamp(result.height, 0, viewport.height); result.x = viewport.x + (viewport.width - result.width) / 2; result.y = viewport.y + (viewport.height - result.height) / 2; result.scaleFactor = scaleFactor; return result; } function getRelativeRect(geom, relativeTo) { var result = { }; result.x = (geom.x - relativeTo.x) / relativeTo.width; result.y = (geom.y - relativeTo.y) / relativeTo.height; result.width = geom.width / relativeTo.width; result.height = geom.height / relativeTo.height; return result; } function sizeToRect(rect, qmlItem) { qmlItem.x = rect.x; qmlItem.y = rect.y; qmlItem.width = rect.width; qmlItem.height = rect.height; } function areEqual(geom1, geom2) { return (geom1.x === geom2.x && geom1.y === geom2.y && geom1.width === geom2.width && geom1.height === geom2.height); } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PhotoEditor/assets/000077500000000000000000000000001455543116500270035ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PhotoEditor/assets/crop-handle@20.png000066400000000000000000000061011455543116500321450ustar00rootroot00000000000000PNG  IHDR<<:rtEXtSoftwareAdobe ImageReadyqe<$iTXtXML:com.adobe.xmp 61NIDATx[iG>kv׻;l✾#6 0(&@!p"-A ۲C^vvGUvMoPfPa8!6$ [je,pґڙǞDËr'p'ªD6oOaJ\e3D?nq}:Fwu?~○BX|?`cB'Iߥ G8$l <Qnشޡ{GGʶ LV[w솘h6gmٵ[!r,a5G7DGې[֢nMb4ev|A~%viE- $CRs)-(ӓK(0Σ! XIaNҶB¦'n!R"XQG&}iq;n<+`67mCFjNᛊi]NJ1qA }ã8dC8vVKauF'ٞBZ&ނB6QaL/v}+!Χv"vMA )lڙ4.fYŝۖIUhXӭI`4cqRuшfq&a1|8g}3%xphs]Rž8iMK$-ѧ3{ n N3[N-_gQvSo0`o_fqVW,1 YRA˷Xtۖ%RuoKTĒb8܂ Js bxOs&cXn@mp!, *yaګen*lʇc$&uAPJzDa@EZ 9]ExܴxZgVCY(kzJj_# .z/=q =O@.`vIENDB`lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PhotoEditor/assets/edit_autocorrect@27.png000077500000000000000000000035401455543116500333260ustar00rootroot00000000000000PNG  IHDR>>sDtEXtSoftwareAdobe ImageReadyqe<(iTXtXML:com.adobe.xmp mIDATxܚMh1gۢXTCAY.K`"QAT MU8ԋ7,I- K*?0;d>;ۗI~LT\vlp1#uNB1[bΘ[<c4Ux[|/}fL՝NXpQ31h#-"𝞺{=GᕧnwA?KT VgX CbYVwE-4hͧhNOxV~SЪbz }4WHs#nNT%k+u(k%h aHnGwVH_DC=Hm jg5 e}6=dB=^C=}.kB;O+:)6+;UuџPT:=Tgi6D'U\# !Y]i3:=- D)͆ƂV8$-}~Ǯ8*Ld~ЎFTݧ.p?< |Z HTf4IA& \~DU75$\>{~nhAubox{e ze LQm2%jԸaA_me{^Ա sמCkmc{,z:( , (4:& ?&n".: k :NK+؎B= ?c +PCbSOG(kFe~wu2'~NF /㼉{5^QoCwOUrKt /6?0Ed ^1"N <x[6pm6k<4|ƱF~~Y?ncdr #S $IDATx1jPTD<[zݼO\co(_Qh^-K PuCTy:`F@ $H$Hf|}-/Qqߢ2)jT$ȼ帖$HO}q_f=mUu ~fp\,7{$H $H AI A $H$H A$ A ȸñ(^zO_ Ӣŗ ]"U\UBr'A4)@Z&i.fO $H $HGe+4 IENDB`lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PhotoEditor/assets/edit_exposure@27.png000077500000000000000000000051561455543116500326530ustar00rootroot00000000000000PNG  IHDRLLǗQ+tEXtSoftwareAdobe ImageReadyqe<(iTXtXML:com.adobe.xmp =IDATx\klE^JBB-Xւ G@PD)!WE JDUR0(ZIcb+hcRJZ,J M9ߦ;;۹ww/޽|;sLa"#ۢ "(X!v#1|Ω'.%.!n=#S?%*/"KhGRq ^cbI2k%5?in.ی!Vm6ܱ*\ӊѸ Vb0ql%1#, 4_Kهw9^L(ѼWZs82d+8~!F:}ˉ?<^-J%42I&i~mvbv'`q~nZD0U6&ؑwas34g=LģB> 4-6z8SL I -M)X!XbrBRhե|!a1IfU eA֨ݬa C4I+|w Z,6Qr#zK%⌅ǮbDհ#U>wm P,X#/ r% R "~_`a=Kk<\#WY$6`o8wm0?& fjAqU2mhX'vfƝQVHVwc.ۮ! VLmVo9Saou9cõ:m=¯-DVԎW]y_7Ӡ$nָ 6]ȷBpO524rF F1= 2Qq 0i5^IENDB`lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PhotoEditor/assets/edit_revert@27.png000066400000000000000000000015571455543116500323060ustar00rootroot00000000000000PNG  IHDR??W_sBIT|d pHYs sctEXtSoftwarewww.inkscape.org<IDAThOU.Jlr!9?MB \"h$$Dѐ %]I--AAPt1;AOa8B\{μ9sFA ہ~ROZ|S*TŧJY-+~! lo/N`WQB)B|o_.^e?-+ճXK,4:~1]:\m/ϝjoدQ|S-ďslȗ$~ Nic>q3~|V-3p߉#a-E&5y8F8TX\xҪɩh=\ÊVvqhŵE{{ ZG0[ c8|1V]>sBYek᷐.,BC3~͆鶶xW|v3bt?Ѿcml^M}uW7؄xZcU0;m=oq`oZl5HU1QoG79mEVϿPTW.N,b֞qч7иbiƗ2꧊>h1KPF3R8? x>mY|O.Gx q+%VvDn8KA}'f#Ni(VE*_sLf񥘭 Y{kS6RŧJ->UjROmS,]IENDB`lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/PhotoEditor/assets/edit_rotate_right@27.png000066400000000000000000000032601455543116500334630ustar00rootroot00000000000000PNG  IHDR??W_bKGD pHYs sctIME7=IDAThkUU3N!'BWf3~( 3 @ Qb"F2MKSSQ3asΕYsZ{ط@-DhA*lG[I@AkpP L͵=- >E_s|+m>EUFSokj`O$;_tn Vq<5[~CswxI3Ғ!6(7T'iJ\x7 C:'^̾JK-IeKz^ #Ic\ %ГfKAGX%$$I;JMcyI $u'˒IH/$Jc I7FЕ zI BI; m4cp:(_q{ND7J/W~F/ I#r :a<m?`}Lr^<8- V`kG~@c cJJ`~~B\H=&ܝ|gڡy %gqiM8Lu譊[R[OcKZ1[%($a{7ݞkQnI[_ZF}7) 0 wX 7}:6cc+s\z,y|\RuM<.ufO~G&4G,/ ,=τݬO~|,Plȝ6ocV |Cv-)&r}ah)$M/|̼n(_aFÑۮVdxAQGXx5ʲQ>,Je^SLѐ}Qi*0 3g񘳆 RT t )Ϥ/ ՘;f0˾.?3e␲MLs0r.H*`HZIjFo:hëpK&=dJYL6ʴ q{x}CWEؐv%gx93f)zi|KK<@)o{? A0fm!o3}9:jƎL/I!i}4Yi/7Z*;nfR K\ARer/Jӧ\8dՖ۟^4Idb^u4jII&7iliY4K߽n&K~.E3[XÕPBK=>q1Ha?cI3QŐrǬ4^7_|yUc^|2\G1zD,¶ $"ᦀPngMQq'Wl/U#IENDB`lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/000077500000000000000000000000001455543116500250475ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/CMakeLists.txt000066400000000000000000000033321455543116500276100ustar00rootroot00000000000000project(LomiriComponentsExtrasPrintersQml) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-permissive -pedantic -Wall -Wextra") add_definitions(-DUBUNTUCOMPONENTSEXTRASPRINTERS_LIBRARY) include(FindCups) include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CUPS_INCLUDE_DIR}) find_package(Qt5Gui REQUIRED) find_package(Qt5PrintSupport REQUIRED) find_package(Qt5Qml REQUIRED) find_package(Qt5DBus REQUIRED) find_package(Qt5Concurrent REQUIRED) if(NOT CUPS_FOUND) message(FATAL_ERROR "Could not find cups.") endif() qt5_add_dbus_interface( GEN_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/org.cups.cupsd.Notifier.xml cupsdnotifier) add_library(LomiriComponentsExtrasPrintersQml SHARED ${GEN_SOURCES} backend/backend.cpp backend/backend_cups.cpp backend/backend_pdf.cpp cups/devicesearcher.cpp cups/ippclient.cpp cups/jobloader.cpp cups/printerdriverloader.cpp cups/printerloader.cpp models/devicemodel.cpp models/drivermodel.cpp models/jobmodel.cpp models/printermodel.cpp printer/printer.cpp printer/printerjob.cpp printer/signalratelimiter.cpp printers/printers.cpp enums.h i18n.cpp plugin.cpp structs.h utils.h ) target_link_libraries(LomiriComponentsExtrasPrintersQml Qt5::DBus Qt5::Gui Qt5::PrintSupport Qt5::Qml Qt5::Concurrent ${CUPS_LIBRARIES} ) find_package(QmlPlugins) macro(add_plugin PLUGIN VERSION PATH) export_qmlfiles(${PLUGIN} ${PATH} DESTINATION ${QT_IMPORTS_DIR} ${ARGN}) export_qmlplugin(${PLUGIN} ${VERSION} ${PATH} DESTINATION ${QT_IMPORTS_DIR} ${ARGN}) endmacro() add_plugin(Lomiri.Components.Extras.Printers 0.1 Lomiri/Components/Extras/Printers TARGETS LomiriComponentsExtrasPrintersQml) lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/backend/000077500000000000000000000000001455543116500264365ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/backend/backend.cpp000066400000000000000000000160631455543116500305370ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "backend/backend.h" PrinterBackend::PrinterBackend(const QString &printerName, QObject *parent) : QObject(parent) , m_printerName(printerName) , m_type(PrinterEnum::PrinterType::ProxyType) { } PrinterBackend::~PrinterBackend() { } bool PrinterBackend::holdsDefinition() const { return false; } QString PrinterBackend::printerAdd(const QString &name, const QString &uri, const QString &ppdFile, const QString &info, const QString &location) { Q_UNUSED(name); Q_UNUSED(uri); Q_UNUSED(ppdFile); Q_UNUSED(info); Q_UNUSED(location); return QString(); } QString PrinterBackend::printerAddWithPpd(const QString &name, const QString &uri, const QString &ppdFileName, const QString &info, const QString &location) { Q_UNUSED(name); Q_UNUSED(uri); Q_UNUSED(ppdFileName); Q_UNUSED(info); Q_UNUSED(location); return QString(); } QString PrinterBackend::printerDelete(const QString &name) { Q_UNUSED(name); return QString(); } QString PrinterBackend::printerSetDefault(const QString &name) { Q_UNUSED(name); return QString(); } QString PrinterBackend::printerSetEnabled(const QString &name, const bool enabled) { Q_UNUSED(name); Q_UNUSED(enabled); return QString(); } QString PrinterBackend::printerSetAcceptJobs( const QString &name, const bool enabled, const QString &reason) { Q_UNUSED(name); Q_UNUSED(enabled); Q_UNUSED(reason); return QString(); } QString PrinterBackend::printerSetCopies(const QString &name, const int &copies) { Q_UNUSED(name); Q_UNUSED(copies); return QString(); } QString PrinterBackend::printerSetShared(const QString &name, const bool shared) { Q_UNUSED(name); Q_UNUSED(shared); return QString(); } QString PrinterBackend::printerSetInfo(const QString &name, const QString &info) { Q_UNUSED(name); Q_UNUSED(info); return QString(); } QString PrinterBackend::printerAddOption(const QString &name, const QString &option, const QStringList &values) { Q_UNUSED(name); Q_UNUSED(option); Q_UNUSED(values); return QString(); } QVariant PrinterBackend::printerGetOption(const QString &name, const QString &option) const { Q_UNUSED(name); Q_UNUSED(option); return QVariant(); } QMap PrinterBackend::printerGetOptions( const QString &name, const QStringList &options) const { Q_UNUSED(name); Q_UNUSED(options); return QMap(); } cups_dest_t* PrinterBackend::makeDest(const QString &name, const PrinterJob *options) { Q_UNUSED(name); Q_UNUSED(options); return Q_NULLPTR; } void PrinterBackend::cancelJob(const QString &name, const int jobId) { Q_UNUSED(jobId); Q_UNUSED(name); } void PrinterBackend::holdJob(const QString &name, const int jobId) { Q_UNUSED(jobId); Q_UNUSED(name); } void PrinterBackend::releaseJob(const QString &name, const int jobId) { Q_UNUSED(jobId); Q_UNUSED(name); } int PrinterBackend::printFileToDest(const QString &filepath, const QString &title, const cups_dest_t *dest) { Q_UNUSED(filepath); Q_UNUSED(title); Q_UNUSED(dest); return -1; } QList> PrinterBackend::printerGetJobs() { return QList>{}; } QSharedPointer PrinterBackend::printerGetJob( const QString &printerName, const int jobId) { Q_UNUSED(printerName); Q_UNUSED(jobId); return QSharedPointer(Q_NULLPTR); } QMap PrinterBackend::printerGetJobAttributes( const QString &name, const int jobId) { Q_UNUSED(name); Q_UNUSED(jobId); return QMap(); } QString PrinterBackend::printerName() const { return m_printerName; } QString PrinterBackend::description() const { return QString(); } QString PrinterBackend::location() const { return QString(); } QString PrinterBackend::makeAndModel() const { return QString(); } bool PrinterBackend::isRemote() const { return false; } PrinterEnum::State PrinterBackend::state() const { return PrinterEnum::State::IdleState; } QList PrinterBackend::supportedPageSizes() const { return QList(); } QPageSize PrinterBackend::defaultPageSize() const { return QPageSize(); } bool PrinterBackend::supportsCustomPageSizes() const { return false; } QPageSize PrinterBackend::minimumPhysicalPageSize() const { return QPageSize(); } QPageSize PrinterBackend::maximumPhysicalPageSize() const { return QPageSize(); } QList PrinterBackend::supportedResolutions() const { return QList(); } PrinterEnum::DuplexMode PrinterBackend::defaultDuplexMode() const { return PrinterEnum::DuplexMode::DuplexNone; } QList PrinterBackend::supportedDuplexModes() const { return QList(); } QList> PrinterBackend::availablePrinters() { return QList>(); } QStringList PrinterBackend::availablePrinterNames() { return QStringList(); } QSharedPointer PrinterBackend::getPrinter(const QString &printerName) { Q_UNUSED(printerName); return QSharedPointer(Q_NULLPTR); } QString PrinterBackend::defaultPrinterName() { return QString(); } void PrinterBackend::requestJobExtendedAttributes( QSharedPointer printer, QSharedPointer job) { Q_UNUSED(printer); Q_UNUSED(job); } void PrinterBackend::requestPrinterDrivers() { } void PrinterBackend::requestPrinter(const QString &printerName) { Q_UNUSED(printerName); } PrinterEnum::PrinterType PrinterBackend::type() const { return m_type; } void PrinterBackend::setPrinterNameInternal(const QString &printerName) { m_printerName = printerName; } void PrinterBackend::refresh() { } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/backend/backend.h000066400000000000000000000171351455543116500302050ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_PRINTERS_BACKEND_H #define USC_PRINTERS_BACKEND_H #include "printer/printer.h" #include "printer/printerjob.h" // TODO: remove cups specific things from this API #include #include #include #include #include #include class Printer; class PrinterJob; class PRINTERS_DECL_EXPORT PrinterBackend : public QObject { Q_OBJECT public: explicit PrinterBackend(QObject *parent = Q_NULLPTR); explicit PrinterBackend(const QString &printerName, QObject *parent = Q_NULLPTR); virtual ~PrinterBackend(); virtual bool holdsDefinition() const; // Add a printer using an already existing ppd. virtual QString printerAdd(const QString &name, const QString &uri, const QString &ppdFile, const QString &info, const QString &location); // Add a printer and provide a ppd file. virtual QString printerAddWithPpd(const QString &name, const QString &uri, const QString &ppdFileName, const QString &info, const QString &location); virtual QString printerDelete(const QString &name); virtual QString printerSetDefault(const QString &name); virtual QString printerSetEnabled(const QString &name, const bool enabled); virtual QString printerSetAcceptJobs( const QString &name, const bool accept, const QString &reason = QString()); virtual QString printerSetCopies(const QString &name, const int &copies); virtual QString printerSetShared(const QString &name, const bool shared); virtual QString printerSetInfo(const QString &name, const QString &info); virtual QString printerAddOption(const QString &name, const QString &option, const QStringList &values); virtual QVariant printerGetOption(const QString &name, const QString &option) const; virtual QMap printerGetOptions( const QString &name, const QStringList &options) const; virtual cups_dest_t* makeDest(const QString &name, const PrinterJob *options); virtual void cancelJob(const QString &name, const int jobId); virtual void holdJob(const QString &name, const int jobId); virtual void releaseJob(const QString &name, const int jobId); virtual int printFileToDest(const QString &filepath, const QString &title, const cups_dest_t *dest); virtual QList> printerGetJobs(); virtual QSharedPointer printerGetJob(const QString &printerName, const int jobId); virtual QMap printerGetJobAttributes( const QString &name, const int jobId); virtual QString printerName() const; virtual QString description() const; virtual QString location() const; virtual QString makeAndModel() const; virtual bool isRemote() const; virtual PrinterEnum::State state() const; virtual QList supportedPageSizes() const; virtual QPageSize defaultPageSize() const; virtual bool supportsCustomPageSizes() const; virtual QPageSize minimumPhysicalPageSize() const; virtual QPageSize maximumPhysicalPageSize() const; virtual QList supportedResolutions() const; virtual PrinterEnum::DuplexMode defaultDuplexMode() const; virtual QList supportedDuplexModes() const; virtual QList> availablePrinters(); virtual QStringList availablePrinterNames(); virtual QSharedPointer getPrinter(const QString &printerName); virtual QString defaultPrinterName(); virtual void requestJobExtendedAttributes(QSharedPointer printer, QSharedPointer job); virtual void requestPrinterDrivers(); virtual void requestPrinter(const QString &printerName); virtual PrinterEnum::PrinterType type() const; virtual void setPrinterNameInternal(const QString &printerName); public Q_SLOTS: virtual void refresh(); Q_SIGNALS: void printerDriversLoaded(const QList &drivers); void printerDriversFailedToLoad(const QString &errorMessage); void jobLoaded(QString, int, QMap); void printerLoaded(QSharedPointer printers); void deviceFound(const Device &device); void deviceSearchFinished(); void jobCompleted( const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs, uint jobId, uint jobState, const QString &jobStateReason, const QString &job_name, uint jobImpressionsCompleted ); void jobCreated( const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs, uint jobId, uint jobState, const QString &jobStateReason, const QString &job_name, uint jobImpressionsCompleted ); void jobState( const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs, uint jobId, uint jobState, const QString &jobStateReason, const QString &job_name, uint jobImpressionsCompleted ); void printerAdded( const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs ); void printerDeleted( const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs ); void printerModified( const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs ); void printerStateChanged( const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs ); protected: QString m_printerName; PrinterEnum::PrinterType m_type; }; #endif // USC_PRINTERS_BACKEND_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/backend/backend_cups.cpp000066400000000000000000000754401455543116500315750ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "backend/backend_cups.h" #include "cups/devicesearcher.h" #include "cups/jobloader.h" #include "cups/printerdriverloader.h" #include "cups/printerloader.h" #include "utils.h" #include #include #include #include #include #include #define __CUPS_ADD_OPTION(dest, name, value) dest->num_options = \ cupsAddOption(name, value, dest->num_options, &dest->options); #define __CUPS_ATTR_EXISTS(map, attr, type) map.contains(attr) \ && map.value(attr).canConvert() PrinterCupsBackend::PrinterCupsBackend(IppClient *client, QPrinterInfo info, OrgCupsCupsdNotifierInterface *notifier, QObject *parent) : PrinterBackend(info.printerName(), parent) , m_knownQualityOptions({ "Quality", "PrintQuality", "HPPrintQuality", "StpQuality", "OutputMode",}) , m_extendedAttributeNames({ QStringLiteral("StateMessage"), QStringLiteral("DeviceUri"), QStringLiteral("IsShared"), QStringLiteral("Copies"), }) , m_client(client) , m_info(info) , m_notifier(notifier) , m_cupsSubscriptionId(-1) { m_type = PrinterEnum::PrinterType::CupsType; connect(m_notifier, SIGNAL(JobCompleted(const QString&, const QString&, const QString&, uint, const QString&, bool, uint, uint, const QString&, const QString&, uint)), this, SIGNAL(jobCompleted(const QString&, const QString&, const QString&, uint, const QString&, bool, uint, uint, const QString&, const QString&, uint))); connect(m_notifier, SIGNAL(JobCreated(const QString&, const QString&, const QString&, uint, const QString&, bool, uint, uint, const QString&, const QString&, uint)), this, SIGNAL(jobCreated(const QString&, const QString&, const QString&, uint, const QString&, bool, uint, uint, const QString&, const QString&, uint))); connect(m_notifier, SIGNAL(JobState(const QString&, const QString&, const QString&, uint, const QString&, bool, uint, uint, const QString&, const QString&, uint)), this, SIGNAL(jobState(const QString&, const QString&, const QString&, uint, const QString&, bool, uint, uint, const QString&, const QString&, uint))); connect(m_notifier, SIGNAL(PrinterAdded(const QString&, const QString&, const QString&, uint, const QString&, bool)), this, SIGNAL(printerAdded(const QString&, const QString&, const QString&, uint, const QString&, bool))); connect(m_notifier, SIGNAL(PrinterDeleted(const QString&, const QString&, const QString&, uint, const QString&, bool)), this, SIGNAL(printerDeleted(const QString&, const QString&, const QString&, uint, const QString&, bool))); connect(m_notifier, SIGNAL(PrinterModified(const QString&, const QString&, const QString&, uint, const QString&, bool)), this, SIGNAL(printerModified(const QString&, const QString&, const QString&, uint, const QString&, bool))); connect(m_notifier, SIGNAL(PrinterStateChanged(const QString&, const QString&, const QString&, uint, const QString&, bool)), this, SIGNAL(printerStateChanged(const QString&, const QString&, const QString&, uint, const QString&, bool))); } PrinterCupsBackend::~PrinterCupsBackend() { Q_FOREACH(auto dest, m_dests) { if (dest) cupsFreeDests(1, dest); } Q_FOREACH(auto ppd, m_ppds) { if (ppd) ppdClose(ppd); } cancelSubscription(); Q_EMIT cancelWorkers(); } QString PrinterCupsBackend::printerAdd(const QString &name, const QString &uri, const QString &ppdFile, const QString &info, const QString &location) { if (!m_client->printerAdd(name, uri, ppdFile, info, location)) { return m_client->getLastError(); } return QString(); } QString PrinterCupsBackend::printerAddWithPpd(const QString &name, const QString &uri, const QString &ppdFileName, const QString &info, const QString &location) { if (!m_client->printerAddWithPpdFile(name, uri, ppdFileName, info, location)) { return m_client->getLastError(); } return QString(); } bool PrinterCupsBackend::holdsDefinition() const { return !m_info.isNull(); } QString PrinterCupsBackend::printerDelete(const QString &name) { if (!m_client->printerDelete(name)) { return m_client->getLastError(); } return QString(); } QString PrinterCupsBackend::printerSetDefault(const QString &name) { if (!m_client->printerSetDefault(name)) { return m_client->getLastError(); } return QString(); } QString PrinterCupsBackend::printerSetEnabled(const QString &name, const bool enabled) { if (!m_client->printerSetEnabled(name, enabled)) { return m_client->getLastError(); } return QString(); } QString PrinterCupsBackend::printerSetAcceptJobs( const QString &name, const bool accept, const QString &reason) { if (!m_client->printerSetAcceptJobs(name, accept, reason)) { return m_client->getLastError(); } return QString(); } QString PrinterCupsBackend::printerSetCopies(const QString &name, const int &copies) { if (!m_client->printerSetCopies(name, copies)) { return m_client->getLastError(); } return QString(); } QString PrinterCupsBackend::printerSetShared(const QString &name, const bool shared) { if (!m_client->printerSetShared(name, shared)) { return m_client->getLastError(); } return QString(); } QString PrinterCupsBackend::printerSetInfo(const QString &name, const QString &info) { if (!m_client->printerClassSetInfo(name, info)) { return m_client->getLastError(); } return QString(); } QString PrinterCupsBackend::printerAddOption(const QString &name, const QString &option, const QStringList &values) { if (!m_client->printerClassSetOption(name, option, values)) { return m_client->getLastError(); } return QString(); } QVariant PrinterCupsBackend::printerGetOption(const QString &name, const QString &option) const { auto res = printerGetOptions(name, QStringList({option})); return res[option]; } QMap PrinterCupsBackend::printerGetOptions( const QString &name, const QStringList &options) const { QMap ret; cups_dest_t *dest = getDest(name); ppd_file_t* ppd = getPpd(name); // Used to store extended attributes, which we should request maximum once. QMap extendedAttributesResults; /* Goes through known extended attributes. If one is being asked for, ask for all of them right away. */ Q_FOREACH(const QString &extendedOption, m_extendedAttributeNames) { if (options.contains(extendedOption)) { extendedAttributesResults = m_client->printerGetAttributes( name, QStringList({ QStringLiteral("device-uri"), QStringLiteral("printer-uri-supported"), QStringLiteral("printer-state-message"), QStringLiteral("copies-default"), }) ); break; } } Q_FOREACH(const QString &option, options) { if (option == QStringLiteral("DefaultColorModel") && ppd) { ColorModel model; ppd_option_t *ppdColorModel = ppdFindOption(ppd, "ColorModel"); if (ppdColorModel) { ppd_choice_t* def = ppdFindChoice(ppdColorModel, ppdColorModel->defchoice); if (def) { model = Utils::parsePpdColorModel(def->choice, def->text, "ColorModel"); } } ret[option] = QVariant::fromValue(model); } else if (option == QStringLiteral("DefaultPrintQuality") && ppd) { PrintQuality quality; Q_FOREACH(const QString opt, m_knownQualityOptions) { ppd_option_t *ppdQuality = ppdFindOption(ppd, opt.toUtf8()); if (ppdQuality) { ppd_choice_t* def = ppdFindChoice(ppdQuality, ppdQuality->defchoice); if (def) { quality = Utils::parsePpdPrintQuality(def->choice, def->text, opt); } } } ret[option] = QVariant::fromValue(quality); } else if (option == QStringLiteral("SupportedPrintQualities") && ppd) { QList qualities; Q_FOREACH(const QString &opt, m_knownQualityOptions) { ppd_option_t *qualityOpt = ppdFindOption(ppd, opt.toUtf8()); if (qualityOpt) { for (int i = 0; i < qualityOpt->num_choices; ++i) { qualities.append( Utils::parsePpdPrintQuality( qualityOpt->choices[i].choice, qualityOpt->choices[i].text, opt ) ); } } } ret[option] = QVariant::fromValue(qualities); } else if (option == QStringLiteral("SupportedColorModels") && ppd) { QList models; ppd_option_t *colorModels = ppdFindOption(ppd, "ColorModel"); if (colorModels) { for (int i = 0; i < colorModels->num_choices; ++i) { models.append( Utils::parsePpdColorModel( colorModels->choices[i].choice, colorModels->choices[i].text, QStringLiteral("ColorModel") ) ); } } ret[option] = QVariant::fromValue(models); } else if (option == QStringLiteral("AcceptJobs") && dest) { // "true" if the destination is accepting new jobs, "false" if not. QString res = cupsGetOption("printer-is-accepting-jobs", dest->num_options, dest->options); ret[option] = res.contains("true"); } else if (option == QStringLiteral("StateReasons") && dest) { ret[option] = cupsGetOption("printer-state-reasons", dest->num_options, dest->options); } else if (option == QStringLiteral("StateMessage")) { ret[option] = extendedAttributesResults["printer-state-message"]; } else if (option == QStringLiteral("DeviceUri")) { auto res = extendedAttributesResults; if (!res["printer-uri-supported"].toString().isEmpty()) { ret[option] = res["printer-uri-supported"]; } if (!res["device-uri"].toString().isEmpty()) { ret[option] = res["device-uri"]; } } else if (option == QStringLiteral("Copies")) { ret[option] = extendedAttributesResults[QStringLiteral("copies-default")]; } else if (option == QStringLiteral("Shared") && dest) { ret[option] = cupsGetOption("printer-is-shared", dest->num_options, dest->options); } } return ret; } cups_dest_t* PrinterCupsBackend::makeDest(const QString &name, const PrinterJob *options) { cups_dest_t *dest = getDest(name); if (options->collate()) { __CUPS_ADD_OPTION(dest, "Collate", "True"); } else { __CUPS_ADD_OPTION(dest, "Collate", "False"); } __CUPS_ADD_OPTION(dest, "copies", QString::number(options->copies()).toLocal8Bit()); __CUPS_ADD_OPTION(dest, "ColorModel", options->getColorModel().name.toLocal8Bit()); __CUPS_ADD_OPTION(dest, "Duplex", Utils::duplexModeToPpdChoice(options->getDuplexMode()).toLocal8Bit()); if (options->landscape()) { __CUPS_ADD_OPTION(dest, "landscape", ""); } if (options->printRangeMode() == PrinterEnum::PrintRange::PageRange && !options->printRange().isEmpty()) { __CUPS_ADD_OPTION(dest, "page-ranges", options->printRange().toLocal8Bit()); } PrintQuality quality = options->getPrintQuality(); __CUPS_ADD_OPTION(dest, quality.originalOption.toLocal8Bit(), quality.name.toLocal8Bit()); if (options->reverse()) { __CUPS_ADD_OPTION(dest, "OutputOrder", "Reverse"); } else { __CUPS_ADD_OPTION(dest, "OutputOrder", "Normal"); } // Always scale to fit the page for now __CUPS_ADD_OPTION(dest, "fit-to-page", "True"); return dest; } void PrinterCupsBackend::cancelJob(const QString &name, const int jobId) { int ret = cupsCancelJob(name.toLocal8Bit(), jobId); if (!ret) { qWarning() << "Failed to cancel job:" << jobId << "for" << name; } } void PrinterCupsBackend::holdJob(const QString &name, const int jobId) { if (!m_client->printerHoldJob(name, jobId)) { qWarning() << "Failed to hold job:" << jobId << "for" << name; } } void PrinterCupsBackend::releaseJob(const QString &name, const int jobId) { if (!m_client->printerReleaseJob(name, jobId)) { qWarning() << "Failed to release job:" << jobId << "for" << name; } } int PrinterCupsBackend::printFileToDest(const QString &filepath, const QString &title, const cups_dest_t *dest) { qDebug() << "Printing:" << filepath << title << dest->name << dest->num_options; return cupsPrintFile(dest->name, filepath.toLocal8Bit(), title.toLocal8Bit(), dest->num_options, dest->options); } QList PrinterCupsBackend::getCupsJobs(const QString &name) { QList list; cups_job_t *jobs; // Get a list of the jobs that are 'mine' and only active ones // https://www.cups.org/doc/api-cups.html#cupsGetJobs int count; if (name.isEmpty()) { count = cupsGetJobs(&jobs, NULL, 1, CUPS_WHICHJOBS_ACTIVE); } else { count = cupsGetJobs(&jobs, name.toLocal8Bit(), 1, CUPS_WHICHJOBS_ACTIVE); } for (int i=0; i < count; i++) { list.append(&jobs[i]); } return list; } QMap PrinterCupsBackend::printerGetJobAttributes( const QString &name, const int jobId) { Q_UNUSED(name); QMap rawMap = m_client->printerGetJobAttributes(name, jobId); QMap map; // Filter attributes to know values // Do this here so we can use things such as m_knownQualityOptions if (__CUPS_ATTR_EXISTS(rawMap, "Collate", bool)) { map.insert("Collate", rawMap.value("Collate")); } else { map.insert("Collate", QVariant(true)); } if (__CUPS_ATTR_EXISTS(rawMap, "copies", int)) { map.insert("copies", rawMap.value("copies")); } else { map.insert("copies", QVariant(1)); } if (__CUPS_ATTR_EXISTS(rawMap, "ColorModel", QString)) { map.insert("ColorModel", rawMap.value("ColorModel")); } else { map.insert("ColorModel", QVariant("")); } if (__CUPS_ATTR_EXISTS(rawMap, "date-time-at-completed", QDateTime)) { map.insert("CompletedTime", rawMap.value("date-time-at-completed")); } else { map.insert("CompletedTime", QVariant(QDateTime())); } if (__CUPS_ATTR_EXISTS(rawMap, "date-time-at-creation", QDateTime)) { map.insert("CreationTime", rawMap.value("date-time-at-creation")); } else { map.insert("CreationTime", QVariant(QDateTime())); } if (__CUPS_ATTR_EXISTS(rawMap, "Duplex", QString)) { map.insert("Duplex", rawMap.value("Duplex")); } else { map.insert("Duplex", QVariant("")); } // Try job-media-sheets-completed first as it should include duplex // if it doesn't exist fallback to job-impressions-completed if (__CUPS_ATTR_EXISTS(rawMap, "job-media-sheets-completed", int)) { map.insert("impressionsCompleted", rawMap.value("job-media-sheets-completed")); } else if (__CUPS_ATTR_EXISTS(rawMap, "job-impressions-completed", int)) { map.insert("impressionsCompleted", rawMap.value("job-impressions-completed")); } else { map.insert("impressionsCompleted", QVariant(0)); } if (__CUPS_ATTR_EXISTS(rawMap, "landscape", bool)) { map.insert("landscape", rawMap.value("landscape")); } else { map.insert("landscape", QVariant(false)); } if (__CUPS_ATTR_EXISTS(rawMap, "page-ranges", QList)) { QList range = rawMap.value("page-ranges").toList(); QStringList rangeStrings; Q_FOREACH(QVariant var, range) { rangeStrings << var.toString(); } map.insert("page-ranges", QVariant(rangeStrings)); } else { map.insert("page-ranges", QVariant(QStringList())); } if (__CUPS_ATTR_EXISTS(rawMap, "date-time-at-processing", QDateTime)) { map.insert("ProcessingTime", rawMap.value("date-time-at-processing")); } else { map.insert("ProcessingTime", QVariant(QDateTime())); } Q_FOREACH(QString qualityOption, m_knownQualityOptions) { if (rawMap.contains(qualityOption) && rawMap.value(qualityOption).canConvert()) { map.insert("quality", rawMap.value(qualityOption).toString()); } } if (!map.contains("quality")) { map.insert("quality", QVariant("")); } if (__CUPS_ATTR_EXISTS(rawMap, "OutputOrder", QString)) { map.insert("OutputOrder", rawMap.value("OutputOrder")); } else { map.insert("OutputOrder", "Normal"); } if (__CUPS_ATTR_EXISTS(rawMap, "job-k-octets", int)) { map.insert("Size", rawMap.value("job-k-octets")); } else { map.insert("Size", QVariant(0)); } // If there is a state then get it, as there could have been a signal // flood. Which then means a forceJobRefresh is able to update the state if (__CUPS_ATTR_EXISTS(rawMap, "job-state", int)) { map.insert("State", rawMap.value("job-state").toInt()); } if (__CUPS_ATTR_EXISTS(rawMap, "job-originating-user-name", QString)) { map.insert("User", rawMap.value("job-originating-user-name")); } else { map.insert("User", QVariant("")); } // Generate a list of messages // TODO: for now just using job-printer-state-message, are there others? QStringList messages; if (__CUPS_ATTR_EXISTS(rawMap, "job-printer-state-message", QString)) { messages << rawMap.value("job-printer-state-message").toString(); } map.insert("messages", QVariant(messages)); return map; } QList> PrinterCupsBackend::printerGetJobs() { auto jobs = getCupsJobs(); QList> list; Q_FOREACH(auto job, jobs) { // Note: extended attributes are not loaded here // they are loaded in JobLoader auto newJob = QSharedPointer( new PrinterJob(QString::fromUtf8(job->dest), this, job->id) ); newJob->setState(static_cast(job->state)); newJob->setTitle(QString::fromLocal8Bit(job->title)); list.append(newJob); } if (!list.isEmpty()) cupsFreeJobs(list.size(), jobs.first()); return list; } QSharedPointer PrinterCupsBackend::printerGetJob( const QString &printerName, const int jobId) { auto jobs = getCupsJobs(printerName); cups_job_t *cupsJob = Q_NULLPTR; QSharedPointer job(Q_NULLPTR); for (int i=0; i < jobs.size(); i++) { if (jobs.at(i)->id == jobId) { cupsJob = jobs.at(i); break; } } if (cupsJob) { job = QSharedPointer( new PrinterJob(QString::fromUtf8(cupsJob->dest), this, cupsJob->id) ); job->setState(static_cast(cupsJob->state)); job->setTitle(QString::fromLocal8Bit(cupsJob->title)); } if (!jobs.size()) cupsFreeJobs(jobs.size(), jobs.first()); return job; } QString PrinterCupsBackend::printerName() const { return m_printerName; } QString PrinterCupsBackend::description() const { return m_info.description(); } QString PrinterCupsBackend::location() const { return m_info.location(); } QString PrinterCupsBackend::makeAndModel() const { return m_info.makeAndModel(); } bool PrinterCupsBackend::isRemote() const { return m_info.isRemote(); } PrinterEnum::State PrinterCupsBackend::state() const { switch (m_info.state()) { case QPrinter::Active: return PrinterEnum::State::ActiveState; case QPrinter::Aborted: return PrinterEnum::State::AbortedState; case QPrinter::Error: return PrinterEnum::State::ErrorState; case QPrinter::Idle: default: return PrinterEnum::State::IdleState; } } QList PrinterCupsBackend::supportedPageSizes() const { return m_info.supportedPageSizes(); } QPageSize PrinterCupsBackend::defaultPageSize() const { return m_info.defaultPageSize(); } bool PrinterCupsBackend::supportsCustomPageSizes() const { return m_info.supportsCustomPageSizes(); } QPageSize PrinterCupsBackend::minimumPhysicalPageSize() const { return m_info.minimumPhysicalPageSize(); } QPageSize PrinterCupsBackend::maximumPhysicalPageSize() const { return m_info.maximumPhysicalPageSize(); } QList PrinterCupsBackend::supportedResolutions() const { return m_info.supportedResolutions(); } PrinterEnum::DuplexMode PrinterCupsBackend::defaultDuplexMode() const { return Utils::qDuplexModeToDuplexMode(m_info.defaultDuplexMode()); } QList PrinterCupsBackend::supportedDuplexModes() const { QList list; Q_FOREACH(const QPrinter::DuplexMode mode, m_info.supportedDuplexModes()) { if (mode != QPrinter::DuplexAuto) { list.append(Utils::qDuplexModeToDuplexMode(mode)); } } if (list.isEmpty()) list.append(PrinterEnum::DuplexMode::DuplexNone); return list; } QList> PrinterCupsBackend::availablePrinters() { return QList>(); } QStringList PrinterCupsBackend::availablePrinterNames() { return QPrinterInfo::availablePrinterNames(); } QSharedPointer PrinterCupsBackend::getPrinter(const QString &printerName) { QPrinterInfo info = QPrinterInfo::printerInfo(printerName); return QSharedPointer(new Printer(new PrinterCupsBackend(m_client, info, m_notifier))); } QString PrinterCupsBackend::defaultPrinterName() { return QPrinterInfo::defaultPrinterName(); } void PrinterCupsBackend::requestJobExtendedAttributes( QSharedPointer printer, QSharedPointer job) { QPair pair(printer->name(), job->jobId()); if (m_activeJobRequests.contains(pair)) { return; } auto thread = new QThread; auto loader = new JobLoader(this, printer->name(), job->jobId()); loader->moveToThread(thread); connect(thread, SIGNAL(started()), loader, SLOT(load())); connect(loader, SIGNAL(finished()), thread, SLOT(quit())); connect(loader, SIGNAL(finished()), loader, SLOT(deleteLater())); connect(loader, SIGNAL(loaded(QString, int, QMap)), this, SIGNAL(jobLoaded(QString, int, QMap))); connect(loader, SIGNAL(loaded(QString, int, QMap)), this, SLOT(onJobLoaded(QString, int, QMap))); connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); m_activeJobRequests << pair; thread->start(); } void PrinterCupsBackend::requestPrinter(const QString &printerName) { if (m_activePrinterRequests.contains(printerName)) { return; } auto thread = new QThread; auto loader = new PrinterLoader(printerName, m_client, m_notifier); loader->moveToThread(thread); connect(thread, SIGNAL(started()), loader, SLOT(load())); connect(loader, SIGNAL(finished()), thread, SLOT(quit())); connect(loader, SIGNAL(finished()), loader, SLOT(deleteLater())); connect(loader, SIGNAL(loaded(QSharedPointer)), this, SIGNAL(printerLoaded(QSharedPointer))); connect(loader, SIGNAL(loaded(QSharedPointer)), this, SLOT(onPrinterLoaded(QSharedPointer))); connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); m_activePrinterRequests << printerName; thread->start(); } void PrinterCupsBackend::requestPrinterDrivers() { auto thread = new QThread; auto loader = new PrinterDriverLoader(); loader->moveToThread(thread); connect(loader, SIGNAL(error(const QString&)), this, SIGNAL(printerDriversFailedToLoad(const QString&))); connect(this, SIGNAL(requestPrinterDriverCancel()), loader, SLOT(cancel())); connect(thread, SIGNAL(started()), loader, SLOT(process())); connect(loader, SIGNAL(finished()), thread, SLOT(quit())); connect(loader, SIGNAL(finished()), loader, SLOT(deleteLater())); connect(loader, SIGNAL(loaded(const QList&)), this, SIGNAL(printerDriversLoaded(const QList&))); connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); thread->start(); } void PrinterCupsBackend::cancelPrinterDriverRequest() { Q_EMIT requestPrinterDriverCancel(); } void PrinterCupsBackend::searchForDevices() { auto thread = new QThread; auto searcher = new DeviceSearcher(); searcher->moveToThread(thread); connect(thread, SIGNAL(started()), searcher, SLOT(load())); connect(searcher, SIGNAL(finished()), thread, SLOT(quit())); connect(searcher, SIGNAL(finished()), searcher, SLOT(deleteLater())); connect(searcher, SIGNAL(finished()), this, SIGNAL(deviceSearchFinished())); connect(searcher, SIGNAL(loaded(const Device&)), this, SIGNAL(deviceFound(const Device&))); connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); thread->start(); } void PrinterCupsBackend::refresh() { if (m_printerName.isEmpty()) { throw std::invalid_argument("Trying to refresh unnamed printer."); } else { m_info = QPrinterInfo::printerInfo(m_printerName); } } void PrinterCupsBackend::createSubscription() { m_cupsSubscriptionId = m_client->createSubscription();; } void PrinterCupsBackend::cancelSubscription() { if (m_cupsSubscriptionId > 0) m_client->cancelSubscription(m_cupsSubscriptionId); } QString PrinterCupsBackend::getPrinterInstance(const QString &name) const { const auto parts = name.splitRef(QLatin1Char('/')); QString instance; if (parts.size() > 1) instance = parts.at(1).toString(); return instance; } QString PrinterCupsBackend::getPrinterName(const QString &name) const { return name.splitRef(QLatin1Char('/')).first().toString(); } cups_dest_t* PrinterCupsBackend::getDest(const QString &name) const { QString printerName = getPrinterName(name); QString instance = getPrinterInstance(name); if (m_dests.contains(name)) { return m_dests[name]; } else { m_dests[name] = m_client->getDest(printerName, instance); return m_dests[name]; } } ppd_file_t* PrinterCupsBackend::getPpd(const QString &name) const { QString printerName = getPrinterName(name); QString instance = getPrinterInstance(name); if (m_ppds.contains(name)) { return m_ppds[name]; } else { m_ppds[name] = m_client->getPpdFile(printerName, instance); return m_ppds[name]; } } bool PrinterCupsBackend::isExtendedAttribute(const QString &attributeName) const { return m_extendedAttributeNames.contains(attributeName); } void PrinterCupsBackend::onJobLoaded(QString printerName, int jobId, QMap attributes) { Q_UNUSED(attributes); QPair pair(printerName, jobId); m_activeJobRequests.remove(pair); } void PrinterCupsBackend::onPrinterLoaded(QSharedPointer printer) { m_activePrinterRequests.remove(printer->name()); } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/backend/backend_cups.h000066400000000000000000000155541455543116500312420ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_PRINTERS_CUPS_BACKEND_H #define USC_PRINTERS_CUPS_BACKEND_H #include "backend/backend.h" #include "cups/ippclient.h" #include "cupsdnotifier.h" // Note: this file was generated. #include #include #include class PRINTERS_DECL_EXPORT PrinterCupsBackend : public PrinterBackend { Q_OBJECT public: explicit PrinterCupsBackend(IppClient *client, QPrinterInfo info, OrgCupsCupsdNotifierInterface* notifier, QObject *parent = Q_NULLPTR); virtual ~PrinterCupsBackend() override; virtual bool holdsDefinition() const override; virtual QString printerAdd(const QString &name, const QString &uri, const QString &ppdFile, const QString &info, const QString &location) override; virtual QString printerAddWithPpd(const QString &name, const QString &uri, const QString &ppdFileName, const QString &info, const QString &location) override; virtual QString printerDelete(const QString &name) override; virtual QString printerSetDefault(const QString &name) override; virtual QString printerSetEnabled(const QString &name, const bool enabled) override; virtual QString printerSetAcceptJobs( const QString &name, const bool accept, const QString &reason = QString()) override; virtual QString printerSetCopies( const QString &name, const int &copies) override; virtual QString printerSetShared(const QString &name, const bool shared) override; virtual QString printerSetInfo(const QString &name, const QString &info) override; virtual QString printerAddOption(const QString &name, const QString &option, const QStringList &values) override; virtual QVariant printerGetOption(const QString &name, const QString &option) const override; virtual QMap printerGetOptions( const QString &name, const QStringList &options ) const override; // FIXME: maybe have a PrinterDest iface that has a CupsDest impl? virtual cups_dest_t* makeDest(const QString &name, const PrinterJob *options) override; virtual void cancelJob(const QString &name, const int jobId) override; virtual void holdJob(const QString &name, const int jobId) override; virtual void releaseJob(const QString &name, const int jobId) override; virtual int printFileToDest(const QString &filepath, const QString &title, const cups_dest_t *dest) override; virtual QList> printerGetJobs() override; virtual QSharedPointer printerGetJob( const QString &printerName, const int jobId) override; virtual QString printerName() const override; virtual QString description() const override; virtual QString location() const override; virtual QString makeAndModel() const override; virtual bool isRemote() const override; virtual PrinterEnum::State state() const override; virtual QList supportedPageSizes() const override; virtual QPageSize defaultPageSize() const override; virtual bool supportsCustomPageSizes() const override; virtual QPageSize minimumPhysicalPageSize() const override; virtual QPageSize maximumPhysicalPageSize() const override; virtual QList supportedResolutions() const override; virtual PrinterEnum::DuplexMode defaultDuplexMode() const override; virtual QList supportedDuplexModes() const override; virtual QList> availablePrinters() override; virtual QStringList availablePrinterNames() override; virtual QSharedPointer getPrinter(const QString &printerName) override; virtual QString defaultPrinterName() override; virtual void requestJobExtendedAttributes( QSharedPointer printer, QSharedPointer job) override; virtual void requestPrinterDrivers() override; virtual void requestPrinter(const QString &printerName) override; virtual QMap printerGetJobAttributes( const QString &name, const int jobId) override; public Q_SLOTS: virtual void refresh() override; void createSubscription(); /* Starts a search for devices. Devices are synonymous with network devices that may potentially be queues. This search will take at minimum 5 seconds, normally longer. */ void searchForDevices(); Q_SIGNALS: void cancelWorkers(); void printerDriversLoaded(const QList &drivers); void printerDriversFailedToLoad(const QString &errorMessage); void requestPrinterDriverCancel(); private: void cancelSubscription(); void cancelPrinterDriverRequest(); QList getCupsJobs(const QString &name = QStringLiteral()); QString getPrinterName(const QString &name) const; QString getPrinterInstance(const QString &name) const; cups_dest_t* getDest(const QString &name) const; ppd_file_t* getPpd(const QString &name) const; bool isExtendedAttribute(const QString &attributeName) const; const QStringList m_knownQualityOptions; const QStringList m_extendedAttributeNames; IppClient *m_client; QPrinterInfo m_info; OrgCupsCupsdNotifierInterface *m_notifier; int m_cupsSubscriptionId; mutable QMap m_dests; // Printer name, dest. mutable QMap m_ppds; // Printer name, ppd. QSet m_activePrinterRequests; QSet> m_activeJobRequests; private Q_SLOTS: void onJobLoaded(QString printerName, int jobId, QMap attributes); void onPrinterLoaded(QSharedPointer printer); }; #endif // USC_PRINTERS_CUPS_BACKEND_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp000066400000000000000000000075711455543116500313740ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "i18n.h" #include "backend/backend_pdf.h" PrinterPdfBackend::PrinterPdfBackend(const QString &printerName, QObject *parent) : PrinterBackend(printerName, parent) { m_type = PrinterEnum::PrinterType::PdfType; } QVariant PrinterPdfBackend::printerGetOption(const QString &name, const QString &option) const { auto res = printerGetOptions(name, QStringList({option})); return res[option]; } QMap PrinterPdfBackend::printerGetOptions( const QString &name, const QStringList &options) const { Q_UNUSED(name); QMap ret; ColorModel rgb; rgb.colorType = PrinterEnum::ColorModelType::ColorType; rgb.name = "RGB"; rgb.text = __("Color"); PrintQuality quality; quality.name = __("Normal"); Q_FOREACH(const QString &option, options) { if (option == QLatin1String("DefaultColorModel")) { ret[option] = QVariant::fromValue(rgb); } else if (option == QLatin1String("DefaultPrintQuality")) { ret[option] = QVariant::fromValue(quality); } else if (option == QLatin1String("SupportedPrintQualities")) { auto qualities = QList({quality}); ret[option] = QVariant::fromValue(qualities); } else if (option == QLatin1String("SupportedColorModels")) { auto models = QList{rgb}; ret[option] = QVariant::fromValue(models); } else if (option == QLatin1String("AcceptJobs")) { ret[option] = true; } else if (option == QLatin1String("StateReasons")) { ret[option] = QLatin1String(""); } else if (option == QLatin1String("StateMessage")) { ret[option] = QLatin1String(""); } else if (option == QLatin1String("DeviceUri")) { ret[option] = QLatin1String(""); } else if (option == QLatin1String("Copies")) { ret[option] = 0; } else if (option == QLatin1String("Shared")) { ret[option] = false; } else { throw std::invalid_argument("Invalid value for PDF printer: " + option.toStdString()); } } return ret; } QString PrinterPdfBackend::printerName() const { return m_printerName; } PrinterEnum::State PrinterPdfBackend::state() const { return PrinterEnum::State::IdleState; } QList PrinterPdfBackend::supportedPageSizes() const { return QList{QPageSize(QPageSize::A4)}; } QPageSize PrinterPdfBackend::defaultPageSize() const { return QPageSize(QPageSize::A4); } bool PrinterPdfBackend::supportsCustomPageSizes() const { return false; } QPageSize PrinterPdfBackend::minimumPhysicalPageSize() const { return QPageSize(QPageSize::A4); } QPageSize PrinterPdfBackend::maximumPhysicalPageSize() const { return QPageSize(QPageSize::A4); } QList PrinterPdfBackend::supportedResolutions() const { return QList{}; } PrinterEnum::DuplexMode PrinterPdfBackend::defaultDuplexMode() const { return PrinterEnum::DuplexMode::DuplexNone; } QList PrinterPdfBackend::supportedDuplexModes() const { return QList{PrinterEnum::DuplexMode::DuplexNone}; } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.h000066400000000000000000000035461455543116500310370ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_PRINTERS_PDF_BACKEND_H #define USC_PRINTERS_PDF_BACKEND_H #include "backend/backend.h" class PRINTERS_DECL_EXPORT PrinterPdfBackend : public PrinterBackend { public: explicit PrinterPdfBackend(const QString &printerName, QObject *parent = Q_NULLPTR); virtual QVariant printerGetOption(const QString &name, const QString &option) const override; virtual QMap printerGetOptions( const QString &name, const QStringList &options ) const override; virtual QString printerName() const override; virtual PrinterEnum::State state() const override; virtual QList supportedPageSizes() const override; virtual QPageSize defaultPageSize() const override; virtual bool supportsCustomPageSizes() const override; virtual QPageSize minimumPhysicalPageSize() const override; virtual QPageSize maximumPhysicalPageSize() const override; virtual QList supportedResolutions() const override; virtual PrinterEnum::DuplexMode defaultDuplexMode() const override; virtual QList supportedDuplexModes() const override; }; #endif // USC_PRINTERS_PDF_BACKEND_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/cups/000077500000000000000000000000001455543116500260215ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/cups/devicesearcher.cpp000066400000000000000000000034321455543116500315030ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "cups/ippclient.h" #include "devicesearcher.h" #include DeviceSearcher::DeviceSearcher(IppClient *client, QObject *parent) : QObject(parent) , m_client(client) { } DeviceSearcher::~DeviceSearcher() { delete m_client; } void DeviceSearcher::load() { if (!m_client->getDevices(&DeviceSearcher::deviceCallBack, this)) { Q_EMIT failed(cupsLastErrorString()); } Q_EMIT finished(); } void DeviceSearcher::deviceCallBack( const char *deviceClass, const char *deviceId, const char *deviceInfo, const char *deviceMakeAndModel, const char *deviceUri, const char *deviceLocation, void *context) { auto searcher = qobject_cast(static_cast(context)); if (!searcher) { qWarning() << Q_FUNC_INFO << "context was not a DeviceSearcher."; return; } Device d; d.cls = deviceClass; d.id = deviceId; d.info = deviceInfo; d.makeModel = deviceMakeAndModel; d.uri = deviceUri; d.location = deviceLocation; searcher->deviceFound(d); } void DeviceSearcher::deviceFound(const Device &device) { Q_EMIT loaded(device); } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/cups/devicesearcher.h000066400000000000000000000031661455543116500311540ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_PRINTERS_CUPS_DEVICESEARCHER_H #define USC_PRINTERS_CUPS_DEVICESEARCHER_H #include "cups/ippclient.h" #include "structs.h" #include #include /* Class representing a device search. It is a worker object due to the time such a search takes (minimum 10 seconds). */ class DeviceSearcher : public QObject { Q_OBJECT IppClient *m_client; public: explicit DeviceSearcher(IppClient *client = new IppClient, QObject *parent = Q_NULLPTR); ~DeviceSearcher(); public Q_SLOTS: void load(); private: static void deviceCallBack( const char *cls, const char *id, const char *info, const char *makeAndModel, const char *uri, const char *location, void *context); void deviceFound(const Device &device); Q_SIGNALS: void loaded(const Device &device); void failed(const QString &errorMessage); void finished(); }; #endif // USC_PRINTERS_CUPS_DEVICESEARCHER_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/cups/ippclient.cpp000066400000000000000000001037571455543116500305310ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * Copyright (C) 2014 John Layt * Copyright (C) 2002, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014 Red Hat, Inc. * Copyright (C) 2008 Novell, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "cups/ippclient.h" #include #include #include #include #include #include #include #include IppClient::IppClient() : m_connection(httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption())) { if (!m_connection) { qCritical("Failed to connect to cupsd"); } else { qDebug("Successfully connected to cupsd."); } } IppClient::~IppClient() { if (m_connection) httpClose(m_connection); } bool IppClient::printerDelete(const QString &printerName) { return sendNewSimpleRequest(CUPS_DELETE_PRINTER, printerName.toUtf8(), CupsResource::CupsResourceAdmin); } bool IppClient::printerAdd(const QString &printerName, const QString &printerUri, const QString &ppdFile, const QString &info, const QString &location) { ipp_t *request; if (!isPrinterNameValid(printerName)) { setInternalStatus(QString("%1 is not a valid printer name.").arg(printerName)); return false; } if (!isStringValid(info)) { setInternalStatus(QString("%1 is not a valid description.").arg(info)); return false; } if (!isStringValid(location)) { setInternalStatus(QString("%1 is not a valid location.").arg(location)); return false; } if (!isStringValid(ppdFile)) { setInternalStatus(QString("%1 is not a valid ppd file.").arg(ppdFile)); return false; } if (!isStringValid(printerUri)) { setInternalStatus(QString("%1 is not a valid printer uri.").arg(printerUri)); return false; } request = ippNewRequest (CUPS_ADD_MODIFY_PRINTER); addPrinterUri(request, printerName); addRequestingUsername(request, NULL); ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "printer-name", NULL, printerName.toUtf8()); if (!ppdFile.isEmpty()) { ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "ppd-name", NULL, ppdFile.toUtf8()); } if (!printerUri.isEmpty()) { ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL, printerUri.toUtf8()); } if (!info.isEmpty()) { ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info", NULL, info.toUtf8()); } if (!location.isEmpty()) { ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location", NULL, location.toUtf8()); } return sendRequest(request, CupsResourceAdmin); } bool IppClient::printerAddWithPpdFile(const QString &printerName, const QString &printerUri, const QString &ppdFileName, const QString &info, const QString &location) { ipp_t *request; if (!isPrinterNameValid(printerName)) { setInternalStatus(QString("%1 is not a valid printer name.").arg(printerName)); return false; } if (!isStringValid(info)) { setInternalStatus(QString("%1 is not a valid description.").arg(info)); return false; } if (!isStringValid(location)) { setInternalStatus(QString("%1 is not a valid location.").arg(location)); return false; } if (!isStringValid(ppdFileName)) { setInternalStatus(QString("%1 is not a valid ppd file name.").arg(ppdFileName)); return false; } if (!isStringValid(printerUri)) { setInternalStatus(QString("%1 is not a valid printer uri.").arg(printerUri)); return false; } request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER); addPrinterUri(request, printerName); addRequestingUsername(request, NULL); ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "printer-name", NULL, printerName.toUtf8()); /* In this specific case of ADD_MODIFY, the URI can be NULL/empty since * we provide a complete PPD. And cups fails if we pass an empty * string. */ if (!printerUri.isEmpty()) { ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL, printerUri.toUtf8()); } if (!info.isEmpty()) { ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info", NULL, info.toUtf8()); } if (!location.isEmpty()) { ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location", NULL, location.toUtf8()); } return postRequest(request, ppdFileName.toUtf8(), CupsResourceAdmin); } bool IppClient::printerHoldJob(const QString &printerName, const int jobId) { ipp_t *request = ippNewRequest(IPP_HOLD_JOB); addPrinterUri(request, printerName); addRequestingUsername(request, NULL); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", jobId); return sendRequest(request, CupsResourceJobs); } bool IppClient::printerReleaseJob(const QString &printerName, const int jobId) { ipp_t *request = ippNewRequest(IPP_RELEASE_JOB); addPrinterUri(request, printerName); addRequestingUsername(request, NULL); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", jobId); return sendRequest(request, CupsResourceJobs); } bool IppClient::printerSetDefault(const QString &printerName) { return sendNewSimpleRequest(CUPS_SET_DEFAULT, printerName.toUtf8(), CupsResource::CupsResourceAdmin); } bool IppClient::printerSetEnabled(const QString &printerName, const bool enabled) { ipp_op_t op; op = enabled ? IPP_RESUME_PRINTER : IPP_PAUSE_PRINTER; return sendNewSimpleRequest(op, printerName, CupsResourceAdmin); } /* reason must be empty if accept is true */ bool IppClient::printerSetAcceptJobs(const QString &printerName, const bool accept, const QString &reason) { ipp_t *request; if (accept && !reason.isEmpty()) { setInternalStatus("Accepting jobs does not take a reason."); return false; } if (!isPrinterNameValid(printerName)) { setInternalStatus(QString("%1 is not a valid printer name.").arg(printerName)); return false; } if (!isStringValid(reason)) { setInternalStatus(QString("%1 is not a valid reason.").arg(reason)); return false; } if (accept) { return sendNewSimpleRequest(CUPS_ACCEPT_JOBS, printerName.toUtf8(), CupsResourceAdmin); } else { request = ippNewRequest(CUPS_REJECT_JOBS); addPrinterUri(request, printerName); addRequestingUsername(request, NULL); if (!reason.isEmpty()) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, "printer-state-message", NULL, reason.toUtf8()); return sendRequest(request, CupsResourceAdmin); } } bool IppClient::printerSetCopies(const QString &printerName, const int &copies) { ipp_t *request; if (!isPrinterNameValid(printerName)) { setInternalStatus(QString("%1 is not a valid printer name.").arg(printerName)); return false; } request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER); addPrinterUri(request, printerName); addRequestingUsername(request, NULL); ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "copies-default", copies); /* TODO: The request will fail if this was a printer class, and it should be retried. */ return sendRequest(request, CupsResourceAdmin); } bool IppClient::printerSetShared(const QString &printerName, const bool shared) { ipp_t *request; if (!isPrinterNameValid(printerName)) { setInternalStatus(QString("%1 is not a valid printer name.").arg(printerName)); return false; } request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER); addPrinterUri(request, printerName); addRequestingUsername(request, NULL); ippAddBoolean(request, IPP_TAG_OPERATION, "printer-is-shared", shared ? 1 : 0); /* TODO: The request will fail if this was a printer class, and it should be retried. */ return sendRequest(request, CupsResourceAdmin); } bool IppClient::printerClassSetInfo(const QString &name, const QString &info) { if (!isPrinterNameValid(name)) { setInternalStatus(QString("%1 is not a valid printer name.").arg(name)); return false; } if (!isStringValid(info)) { setInternalStatus(QString("%1 is not a valid description.").arg(info)); return false; } return sendNewPrinterClassRequest(name, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info", info); } bool IppClient::printerClassSetOption(const QString &name, const QString &option, const QStringList &values) { bool isClass; int length = 0; ipp_t *request; ipp_attribute_t *attr; QString newPpdFile; bool retval; if (!isPrinterNameValid(name)) { setInternalStatus(QString("%1 is not a valid printer name.").arg(name)); return false; } if (!isStringValid(option)) { setInternalStatus(QString("%1 is not a valid option.").arg(option)); return false; } Q_FOREACH(const QString &val, values) { if (!isStringValid(val)) { setInternalStatus(QString("%1 is not a valid value.").arg(val)); return false; } length++; } if (length == 0) { setInternalStatus("No valid values."); return false; } isClass = printerIsClass(name); /* We permit only one value to change in PPD file because we are setting * default value in it. */ if (!isClass && length == 1) { cups_option_t *options = NULL; int numOptions = 0; QString ppdfile; numOptions = cupsAddOption(option.toUtf8(), values[0].toUtf8(), numOptions, &options); ppdfile = QString(cupsGetPPD(name.toUtf8())); newPpdFile = preparePpdForOptions(ppdfile.toUtf8(), options, numOptions).toLatin1().data(); unlink(ppdfile.toUtf8()); cupsFreeOptions(numOptions, options); } if (isClass) { request = ippNewRequest(CUPS_ADD_MODIFY_CLASS); addClassUri(request, name); } else { request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER); addPrinterUri(request, name); } addRequestingUsername(request, NULL); if (length == 1) { ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, option.toUtf8(), NULL, values[0].toUtf8()); } else { int i; attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_NAME, option.toUtf8(), length, NULL, NULL); for (i = 0; i < length; i++) ippSetString(request, &attr, i, values[i].toUtf8()); } if (!newPpdFile.isEmpty()) { retval = postRequest(request, newPpdFile, CupsResourceAdmin); unlink(newPpdFile.toUtf8()); // TODO: fix leak here. } else { retval = sendRequest(request, CupsResourceAdmin); } return retval; } QMap IppClient::printerGetAttributes( const QString &printerName, const QStringList &attributes) { QMap result; QList attrByteArrays; ipp_t *request; ipp_attribute_t *attr; if (attributes.isEmpty()) { return result; } int i; size_t n = attributes.size(); char **attrs; attrs = (char**) malloc ((n + 1) * sizeof (char *)); /* This is some trickery to compensate for a lack of C array/pointer skills. The VLA attrs gets the underlying data structure of a QByterArray on the heap. When cups is done with it, and in the end of this method, the QByteArrays are deleted, and attrs is freed. */ for (i = 0; i < ((int) n); i++) { QByteArray *array = new QByteArray(attributes.value(i).toLocal8Bit()); attrByteArrays << array; attrs[i] = array->data(); } attrs[n] = NULL; request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); addPrinterUri(request, printerName); addRequestingUsername(request, QString()); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", attributes.size(), NULL, attrs); auto resource = getResource(CupsResource::CupsResourceRoot); ipp_t *reply; reply = cupsDoRequest(m_connection, request, resource.toUtf8()); if (!isReplyOk(reply, false)) { qWarning() << Q_FUNC_INFO << "failed to get attributes" << attributes << "for printer" << printerName; } else { for (attr = ippFirstAttribute(reply); attr; attr = ippNextAttribute(reply)) { while (attr && ippGetGroupTag(attr) != IPP_TAG_PRINTER) attr = ippNextAttribute(reply); if (!attr) break; for (; attr && ippGetGroupTag(attr) == IPP_TAG_PRINTER; attr = ippNextAttribute(reply)) { /* TODO: Here we need to take into account that the returned attributes could be lists and other things. */ result[ippGetName(attr)] = getAttributeValue(attr); if (!attr) break; } } } if (reply) ippDelete(reply); qDeleteAll(attrByteArrays); free(attrs); return result; } QMap IppClient::printerGetJobAttributes(const QString &printerName, const int jobId) { ipp_t *request; QMap map; // Try to get the lock, if we can't after 5 seconds then fail and return if (!m_thread_lock.tryLock(5000)) { qWarning() << "Unable to get lock for IppClient::printerGetJobAttributes." << "Unable to load attributes for job:" << jobId << " for " << printerName; return map; } // Construct request request = ippNewRequest(IPP_GET_JOB_ATTRIBUTES); addPrinterUri(request, printerName); addRequestingUsername(request, NULL); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", jobId); // Send request and construct reply ipp_t *reply; const QString resourceChar = getResource(CupsResourceRoot); reply = cupsDoRequest(m_connection, request, resourceChar.toUtf8()); // Check if the reply is OK if (isReplyOk(reply, false)) { // Loop through the attributes ipp_attribute_t *attr; for (attr = ippFirstAttribute(reply); attr; attr = ippNextAttribute(reply)) { QVariant value = getAttributeValue(attr); map.insert(ippGetName(attr), value); } } else { qWarning() << "Not able to get attributes of job:" << jobId << " for " << printerName; } // Destruct the reply if valid if (reply) { ippDelete(reply); } m_thread_lock.unlock(); return map; } /* This function sets given options to specified values in file 'ppdfile'. * This needs to be done because of applications which use content of PPD files * instead of IPP attributes. * CUPS doesn't do this automatically (but hopefully will starting with 1.6) */ QString IppClient::preparePpdForOptions(const QString &ppdfile, cups_option_t *options, int numOptions) { auto ppdfile_c = ppdfile.toUtf8(); ppd_file_t *ppd; bool ppdchanged = false; QString result; QString error; char newppdfile[PATH_MAX]; cups_file_t *in = NULL; cups_file_t *out = NULL; char line[CPH_STR_MAXLEN]; char keyword[CPH_STR_MAXLEN]; char *keyptr; ppd_choice_t *choice; QString value; QLatin1String defaultStr("*Default"); ppd = ppdOpenFile(ppdfile_c); if (!ppd) { error = QString("Unable to open PPD file \"%1\": %2") .arg(ppdfile).arg(strerror(errno)); setInternalStatus(error); goto out; } in = cupsFileOpen(ppdfile_c, "r"); if (!in) { error = QString("Unable to open PPD file \"%1\": %2") .arg(ppdfile).arg(strerror(errno)); setInternalStatus(error); goto out; } out = cupsTempFile2(newppdfile, sizeof(newppdfile)); if (!out) { setInternalStatus("Unable to create temporary file"); goto out; } /* Mark default values and values of options we are changing. */ ppdMarkDefaults(ppd); cupsMarkOptions(ppd, numOptions, options); while (cupsFileGets(in, line, sizeof(line))) { QString line_qs(line); if (!line_qs.startsWith(defaultStr)) { cupsFilePrintf(out, "%s\n", line); } else { /* This part parses lines with *Default on their * beginning. For instance: * "*DefaultResolution: 1200dpi" becomes: * - keyword: Resolution * - keyptr: 1200dpi */ strncpy(keyword, line + defaultStr.size(), sizeof(keyword)); for (keyptr = keyword; *keyptr; keyptr++) if (*keyptr == ':' || isspace (*keyptr & 255)) break; *keyptr++ = '\0'; while (isspace (*keyptr & 255)) keyptr++; QString keyword_sq(keyword); QString keyptr_qs(keyptr); /* We have to change PageSize if any of PageRegion, * PageSize, PaperDimension or ImageableArea changes. * We change PageRegion if PageSize is not available. */ if (keyword_sq == "PageRegion" || keyword_sq == "PageSize" || keyword_sq == "PaperDimension" || keyword_sq == "ImageableArea") { choice = ppdFindMarkedChoice(ppd, "PageSize"); if (!choice) choice = ppdFindMarkedChoice(ppd, "PageRegion"); } else { choice = ppdFindMarkedChoice(ppd, keyword); } QString choice_qs; if (choice) { choice_qs = choice->choice; } if (choice && choice_qs != keyptr_qs) { /* We have to set the value in PPD manually if * a custom value was passed in: * cupsMarkOptions() marks the choice as * "Custom". We want to set this value with our * input. */ if (choice_qs != "Custom") { cupsFilePrintf(out, "*Default%s: %s\n", keyword, choice->choice); ppdchanged = true; } else { value = cupsGetOption(keyword, numOptions, options); if (!value.isEmpty()) { cupsFilePrintf(out, "*Default%s: %s\n", keyword, value.toStdString().c_str()); ppdchanged = true; } else { cupsFilePrintf(out, "%s\n", line); } } } else { cupsFilePrintf(out, "%s\n", line); } } } if (ppdchanged) result = QString::fromUtf8(newppdfile); else unlink(newppdfile); out: if (in) cupsFileClose(in); if (out) cupsFileClose(out); if (ppd) ppdClose(ppd); return result; } bool IppClient::sendNewPrinterClassRequest(const QString &printerName, ipp_tag_t group, ipp_tag_t type, const QString &name, const QString &value) { ipp_t *request; request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER); addPrinterUri(request, printerName); addRequestingUsername(request, QString()); ippAddString(request, group, type, name.toUtf8(), NULL, value.toUtf8()); if (sendRequest(request, CupsResource::CupsResourceAdmin)) return true; // it failed, maybe it was a class? if (m_lastStatus != IPP_NOT_POSSIBLE) { return false; } // TODO: implement class modification . return false; } void IppClient::addPrinterUri(ipp_t *request, const QString &name) { QUrl uri(QString("ipp://localhost/printers/%1").arg(name)); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri.toEncoded().data()); } void IppClient::addRequestingUsername(ipp_t *request, const QString &username) { if (!username.isEmpty()) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, username.toUtf8()); else ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); } QString IppClient::getLastError() const { return m_internalStatus; } const QString IppClient::getResource(const IppClient::CupsResource &resource) { switch (resource) { case CupsResourceRoot: return "/"; case CupsResourceAdmin: return "/admin/"; case CupsResourceJobs: return "/jobs/"; default: qCritical("Asking for a resource with no match."); return "/"; } } bool IppClient::isPrinterNameValid(const QString &name) { int i; int len; /* Quoting the lpadmin man page: * CUPS allows printer names to contain any printable character * except SPACE, TAB, "/", or "#". * On top of that, validate_name() in lpadmin.c (from cups) checks that * the string is 127 characters long, or shorter. */ /* no empty string */ if (name.isEmpty()) return false; len = name.size(); /* no string that is too long; see comment at the beginning of the * validation code block */ if (len > 127) return false; /* only printable characters, no space, no /, no # */ for (i = 0; i < len; i++) { const QChar c = name.at(i); if (!c.isPrint()) return false; if (c.isSpace()) return false; if (c == '/' || c == '#') return false; } return true; } bool IppClient::isStringValid(const QString &string, const bool checkNull, const int maxLength) { if (isStringPrintable(string, checkNull, maxLength)) return true; return false; } bool IppClient::isStringPrintable(const QString &string, const bool checkNull, const int maxLength) { int i; int len; /* no null string */ if (string.isNull()) return !checkNull; len = string.size(); if (maxLength > 0 && len > maxLength) return false; /* only printable characters */ for (i = 0; i < len; i++) { const QChar c = string.at(i); if (!c.isPrint()) return false; } return true; } void IppClient::setInternalStatus(const QString &status) { if (!m_internalStatus.isNull()) { m_internalStatus = QString(); } if (status.isNull()) { m_internalStatus = QString(); } else { m_internalStatus = status; // Only used for errors for now. qCritical() << status; } } bool IppClient::postRequest(ipp_t *request, const QString &file, const CupsResource &resource) { ipp_t *reply; QString resourceChar; resourceChar = getResource(resource); if (!file.isEmpty()) reply = cupsDoFileRequest(m_connection, request, resourceChar.toUtf8(), file.toUtf8()); else reply = cupsDoFileRequest(m_connection, request, resourceChar.toUtf8(), NULL); return handleReply(reply); } bool IppClient::sendRequest(ipp_t *request, const CupsResource &resource) { ipp_t *reply; const QString resourceChar = getResource(resource); reply = cupsDoRequest(m_connection, request, resourceChar.toUtf8()); return handleReply(reply); } bool IppClient::sendNewSimpleRequest(ipp_op_t op, const QString &printerName, const IppClient::CupsResource &resource) { ipp_t *request; if (!isPrinterNameValid(printerName)) return false; request = ippNewRequest(op); addPrinterUri(request, printerName); addRequestingUsername(request, NULL); return sendRequest(request, resource); } bool IppClient::handleReply(ipp_t *reply) { bool retval; retval = isReplyOk(reply, false); if (reply) ippDelete(reply); return retval; } bool IppClient::isReplyOk(ipp_t *reply, bool deleteIfReplyNotOk) { /* reset the internal status: we'll use the cups status */ m_lastStatus = IPP_STATUS_CUPS_INVALID; if (reply && ippGetStatusCode(reply) <= IPP_OK_CONFLICT) { m_lastStatus = IPP_OK; return true; } else { setErrorFromReply(reply); qWarning() << Q_FUNC_INFO << "Cups HTTP error:" << cupsLastErrorString(); if (deleteIfReplyNotOk && reply) ippDelete(reply); return false; } } void IppClient::setErrorFromReply(ipp_t *reply) { if (reply) m_lastStatus = ippGetStatusCode(reply); else m_lastStatus = cupsLastError(); } bool IppClient::printerIsClass(const QString &name) { const char * const attrs[1] = { "member-names" }; ipp_t *request; QString resource; ipp_t *reply; bool retval; // Class/Printer name validation is equal. if (!isPrinterNameValid(name)) { setInternalStatus(QString("%1 is not a valid printer name.").arg(name)); return false; } request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); addClassUri(request, name); addRequestingUsername(request, QString()); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", 1, NULL, attrs); resource = getResource(CupsResource::CupsResourceRoot); reply = cupsDoRequest(m_connection, request, resource.toUtf8()); if (!isReplyOk(reply, true)) return true; /* Note: we need to look if the attribute is there, since we get a * reply if the name is a printer name and not a class name. The * attribute is the only way to distinguish the two cases. */ retval = ippFindAttribute(reply, attrs[0], IPP_TAG_NAME) != NULL; if (reply) ippDelete(reply); return retval; } void IppClient::addClassUri(ipp_t *request, const QString &name) { QUrl uri(QString("ipp://localhost/printers/%1").arg(name)); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri.toEncoded().data()); } ppd_file_t* IppClient::getPpdFile(const QString &name, const QString &instance) const { Q_UNUSED(instance); ppd_file_t* file = 0; const char *ppdFile = cupsGetPPD(name.toUtf8()); if (ppdFile) { file = ppdOpenFile(ppdFile); unlink(ppdFile); } if (file) { ppdMarkDefaults(file); } else { file = 0; } return file; } cups_dest_t* IppClient::getDest(const QString &name, const QString &instance) const { cups_dest_t *dest = 0; if (instance.isEmpty()) { dest = cupsGetNamedDest(m_connection, name.toUtf8(), NULL); } else { dest = cupsGetNamedDest(m_connection, name.toUtf8(), instance.toUtf8()); } return dest; } ipp_t* IppClient::createPrinterDriversRequest( const QString &deviceId, const QString &language, const QString &makeModel, const QString &product, const QStringList &includeSchemes, const QStringList &excludeSchemes ) { Q_UNUSED(includeSchemes); Q_UNUSED(excludeSchemes); ipp_t *request; request = ippNewRequest(CUPS_GET_PPDS); if (!deviceId.isEmpty()) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, "ppd-device-id", NULL, deviceId.toUtf8()); if (!language.isEmpty()) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "ppd-language", NULL, language.toUtf8()); if (!makeModel.isEmpty()) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, "ppd-make-and-model", NULL, makeModel.toUtf8()); if (!product.isEmpty()) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, "ppd-product", NULL, product.toUtf8()); // Do the request and get return the response. const QString resourceChar = getResource(CupsResourceRoot); return cupsDoRequest(m_connection, request, resourceChar.toUtf8()); } int IppClient::createSubscription() { ipp_t *req; ipp_t *resp; ipp_attribute_t *attr; int subscriptionId = -1; req = ippNewRequest(IPP_CREATE_PRINTER_SUBSCRIPTION); ippAddString(req, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "/"); ippAddString(req, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, "notify-events", NULL, "all"); ippAddString(req, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, "notify-recipient-uri", NULL, "dbus://"); ippAddInteger(req, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, "notify-lease-duration", 0); resp = cupsDoRequest(m_connection, req, getResource(CupsResourceRoot).toUtf8()); if (!isReplyOk(resp, true)) { return subscriptionId; } attr = ippFindAttribute(resp, "notify-subscription-id", IPP_TAG_INTEGER); if (!attr) { qWarning() << "ipp-create-printer-subscription response doesn't" " contain subscription id."; } else { subscriptionId = ippGetInteger(attr, 0); } ippDelete (resp); return subscriptionId; } void IppClient::cancelSubscription(const int &subscriptionId) { ipp_t *req; ipp_t *resp; if (subscriptionId <= 0) { return; } req = ippNewRequest(IPP_CANCEL_SUBSCRIPTION); ippAddString(req, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "/"); ippAddInteger(req, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "notify-subscription-id", subscriptionId); resp = cupsDoRequest(m_connection, req, getResource(CupsResourceRoot).toUtf8()); if (!isReplyOk(resp, true)) { return; } ippDelete(resp); } QVariant IppClient::getAttributeValue(ipp_attribute_t *attr, int index) const { QVariant var; if (ippGetCount(attr) > 1 && index < 0) { QList list; for (int i=0; i < ippGetCount(attr); i++) { list.append(getAttributeValue(attr, i)); } var = QVariant::fromValue>(list); } else { if (index == -1) { index = 0; } switch (ippGetValueTag(attr)) { case IPP_TAG_NAME: case IPP_TAG_TEXT: case IPP_TAG_KEYWORD: case IPP_TAG_URI: case IPP_TAG_CHARSET: case IPP_TAG_MIMETYPE: case IPP_TAG_LANGUAGE: var = QVariant::fromValue(ippGetString(attr, index, NULL)); break; case IPP_TAG_INTEGER: case IPP_TAG_ENUM: var = QVariant::fromValue(ippGetInteger(attr, index)); break; case IPP_TAG_BOOLEAN: var = QVariant::fromValue(ippGetBoolean(attr, index)); break; case IPP_TAG_RANGE: { QString range; int upper; int lower = ippGetRange(attr, index, &upper); // Build a string similar to "1-3" "5-" "8" "-4" if (lower != INT_MIN) { range += QString::number(lower); } if (lower != upper) { range += QStringLiteral("-"); if (upper != INT_MAX) { range += QString::number(upper); } } var = QVariant(range); break; } case IPP_TAG_NOVALUE: var = QVariant(); break; case IPP_TAG_DATE: { time_t time = ippDateToTime(ippGetDate(attr, index)); QDateTime datetime; datetime.setTime_t(time); datetime.setTimeZone(QTimeZone::utc()); var = QVariant::fromValue(datetime); break; } default: qWarning() << "Unknown IPP value tab 0x" << ippGetValueTag(attr); break; } } return var; } bool IppClient::getDevices(cups_device_cb_t callback, void *context) const { auto reply = cupsGetDevices(m_connection, CUPS_TIMEOUT_DEFAULT, CUPS_INCLUDE_ALL, CUPS_EXCLUDE_NONE, callback, context); return reply == IPP_OK; } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/cups/ippclient.h000066400000000000000000000126451455543116500301710ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_PRINTERS_CUPS_IPPCLIENT_H #define USC_PRINTERS_CUPS_IPPCLIENT_H #include "structs.h" #include #include #include #include #include #include #include #include /* From https://bugzilla.novell.com/show_bug.cgi?id=447444#c5 * We need to define a maximum length for strings to avoid cups * thinking there are multiple lines. */ #define CPH_STR_MAXLEN 512 class IppClient { public: explicit IppClient(); ~IppClient(); bool printerDelete(const QString &printerName); bool printerAdd(const QString &printerName, const QString &printerUri, const QString &ppdFile, const QString &info, const QString &location); bool printerAddWithPpdFile(const QString &printerName, const QString &printerUri, const QString &ppdFileName, const QString &info, const QString &location); bool printerHoldJob(const QString &printerName, const int jobId); bool printerReleaseJob(const QString &printerName, const int jobId); bool printerSetDefault(const QString &printerName); bool printerSetEnabled(const QString &printerName, const bool enabled); bool printerSetAcceptJobs(const QString &printerName, const bool accept, const QString &reason); bool printerSetCopies(const QString &printerName, const int &copies); bool printerSetShared(const QString &printerName, const bool shared); bool printerClassSetInfo(const QString &name, const QString &info); bool printerClassSetOption(const QString &name, const QString &option, const QStringList &values); ppd_file_t* getPpdFile(const QString &name, const QString &instance) const; cups_dest_t* getDest(const QString &name, const QString &instance) const; // Fetch more attributes, as normally just a small subset is fetched. QMap printerGetAttributes(const QString &printerName, const QStringList &attributes); QMap printerGetJobAttributes(const QString &printerName, const int jobId); QString getLastError() const; // Note: This response needs to be free by the caller. ipp_t* createPrinterDriversRequest( const QString &deviceId, const QString &language, const QString &makeModel, const QString &product, const QStringList &includeSchemes, const QStringList &excludeSchemes ); int createSubscription(); void cancelSubscription(const int &subscriptionId); bool getDevices(cups_device_cb_t callback, void *context) const; private: enum CupsResource { CupsResourceRoot = 0, CupsResourceAdmin, CupsResourceJobs, }; bool sendNewPrinterClassRequest(const QString &printerName, ipp_tag_t group, ipp_tag_t type, const QString &name, const QString &value); static void addPrinterUri(ipp_t *request, const QString &name); static void addRequestingUsername(ipp_t *request, const QString &username); static const QString getResource(const CupsResource &resource); static bool isPrinterNameValid(const QString &name); static void addClassUri(ipp_t *request, const QString &name); static bool isStringValid(const QString &string, const bool checkNull = false, const int maxLength = 512); static bool isStringPrintable(const QString &string, const bool checkNull, const int maxLength); QString preparePpdForOptions(const QString &ppdfile, cups_option_t *options, int numOptions); bool printerIsClass(const QString &name); void setInternalStatus(const QString &status); bool postRequest(ipp_t *request, const QString &file, const CupsResource &resource); bool sendRequest(ipp_t *request, const CupsResource &resource); bool sendNewSimpleRequest(ipp_op_t op, const QString &printerName, const CupsResource &resource); bool handleReply(ipp_t *reply); bool isReplyOk(ipp_t *reply, bool deleteIfReplyNotOk); void setErrorFromReply(ipp_t *reply); QVariant getAttributeValue(ipp_attribute_t *attr, int index=-1) const; http_t *m_connection; ipp_status_t m_lastStatus = IPP_OK; mutable QString m_internalStatus = QString(); QMutex m_thread_lock; }; #endif // USC_PRINTERS_CUPS_IPPCLIENT_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/cups/jobloader.cpp000066400000000000000000000024511455543116500304700ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "jobloader.h" #include "backend/backend.h" #include "printers/printers.h" #include #include class PrinterCupsBackend; JobLoader::JobLoader(PrinterBackend *backend, QString printerName, int jobId, QObject *parent) : QObject(parent) , m_backend(backend) , m_job_id(jobId) , m_printer_name(printerName) { } JobLoader::~JobLoader() { } void JobLoader::load() { QMap map = m_backend->printerGetJobAttributes( m_printer_name, m_job_id ); Q_EMIT loaded(m_printer_name, m_job_id, map); Q_EMIT finished(); } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/cups/jobloader.h000066400000000000000000000024571455543116500301430ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_PRINTERS_CUPS_JOBLOADER_H #define USC_PRINTERS_CUPS_JOBLOADER_H #include "printer/printer.h" #include "printer/printerjob.h" #include #include #include class JobLoader : public QObject { Q_OBJECT PrinterBackend *m_backend; int m_job_id; QString m_printer_name; public: explicit JobLoader(PrinterBackend *backend, QString printerName, int jobId, QObject *parent = Q_NULLPTR); ~JobLoader(); public Q_SLOTS: void load(); Q_SIGNALS: void finished(); void loaded(QString, int, QMap); }; #endif // USC_PRINTERS_CUPS_JOBLOADER_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/cups/printerdriverloader.cpp000066400000000000000000000074251455543116500326230ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "printerdriverloader.h" PrinterDriverLoader::PrinterDriverLoader( const QString &deviceId, const QString &language, const QString &makeModel, const QString &product, const QStringList &includeSchemes, const QStringList &excludeSchemes) : m_deviceId(deviceId) , m_language(language) , m_makeModel(makeModel) , m_product(product) , m_includeSchemes(includeSchemes) , m_excludeSchemes(excludeSchemes) { } PrinterDriverLoader::~PrinterDriverLoader() { } void PrinterDriverLoader::process() { m_running = true; ipp_t* response = client.createPrinterDriversRequest( m_deviceId, m_language, m_makeModel, m_product, m_includeSchemes, m_excludeSchemes ); // Note: if the response somehow fails, we return. if (!response || ippGetStatusCode(response) > IPP_OK_CONFLICT) { QString err(cupsLastErrorString()); qWarning() << Q_FUNC_INFO << "Cups HTTP error:" << err; if (response) ippDelete(response); Q_EMIT error(err); Q_EMIT finished(); return; } ipp_attribute_t *attr; QByteArray ppdDeviceId; QByteArray ppdLanguage; QByteArray ppdMakeModel; QByteArray ppdName; QList drivers; for (attr = ippFirstAttribute(response); attr != NULL && m_running; attr = ippNextAttribute(response)) { while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER) attr = ippNextAttribute(response); if (attr == NULL) break; // Pull the needed attributes from this PPD... ppdDeviceId = "NONE"; ppdLanguage.clear(); ppdMakeModel.clear(); ppdName.clear(); while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_PRINTER) { if (!strcmp(ippGetName(attr), "ppd-device-id") && ippGetValueTag(attr) == IPP_TAG_TEXT) { ppdDeviceId = ippGetString(attr, 0, NULL); } else if (!strcmp(ippGetName(attr), "ppd-natural-language") && ippGetValueTag(attr) == IPP_TAG_LANGUAGE) { ppdLanguage = ippGetString(attr, 0, NULL); } else if (!strcmp(ippGetName(attr), "ppd-make-and-model") && ippGetValueTag(attr) == IPP_TAG_TEXT) { ppdMakeModel = ippGetString(attr, 0, NULL); } else if (!strcmp(ippGetName(attr), "ppd-name") && ippGetValueTag(attr) == IPP_TAG_NAME) { ppdName = ippGetString(attr, 0, NULL); } attr = ippNextAttribute(response); } // See if we have everything needed... if (ppdLanguage.isEmpty() || ppdMakeModel.isEmpty() || ppdName.isEmpty()) { if (attr == NULL) break; else continue; } PrinterDriver m; m.name = ppdName; m.deviceId = ppdDeviceId; m.makeModel = ppdMakeModel; m.language = ppdLanguage; drivers.append(m); } ippDelete(response); Q_EMIT loaded(drivers); Q_EMIT finished(); } void PrinterDriverLoader::cancel() { m_running = false; } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/cups/printerdriverloader.h000066400000000000000000000033041455543116500322600ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_PRINTERS_CUPS_DRIVERLOADER_H #define USC_PRINTERS_CUPS_DRIVERLOADER_H #include "ippclient.h" #include "structs.h" #include #include #include class PrinterDriverLoader : public QObject { Q_OBJECT public: PrinterDriverLoader( const QString &deviceId = "", const QString &language = "", const QString &makeModel = "", const QString &product = "", const QStringList &includeSchemes = QStringList(), const QStringList &excludeSchemes = QStringList()); ~PrinterDriverLoader(); public Q_SLOTS: void process(); void cancel(); Q_SIGNALS: void finished(); void loaded(const QList &drivers); void error(const QString &error); private: QString m_deviceId = QString(); QString m_language = QString(); QString m_makeModel = QString(); QString m_product = QString(); QStringList m_includeSchemes; QStringList m_excludeSchemes; bool m_running = false; IppClient client; }; #endif // USC_PRINTERS_CUPS_DRIVERLOADER_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/cups/printerloader.cpp000066400000000000000000000032371455543116500314040ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "backend/backend_pdf.h" #include "backend/backend_cups.h" #include "printerloader.h" #include #include class PrinterCupsBackend; PrinterLoader::PrinterLoader(const QString &printerName, IppClient *client, OrgCupsCupsdNotifierInterface* notifier, QObject *parent) : QObject(parent) , m_printerName(printerName) , m_client(client) , m_notifier(notifier) { } PrinterLoader::~PrinterLoader() { } void PrinterLoader::load() { QPrinterInfo info = QPrinterInfo::printerInfo(m_printerName); auto backend = new PrinterCupsBackend(m_client, info, m_notifier); // Dest or PPD was null, but we know it's name so we will use it. if (info.printerName().isEmpty()) { backend->setPrinterNameInternal(m_printerName); } auto p = QSharedPointer(new Printer(backend)); p->moveToThread(QApplication::instance()->thread()); Q_EMIT loaded(p); Q_EMIT finished(); } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/cups/printerloader.h000066400000000000000000000027301455543116500310460ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_PRINTERS_CUPS_PRINTERLOADER_H #define USC_PRINTERS_CUPS_PRINTERLOADER_H #include "cups/ippclient.h" #include "cupsdnotifier.h" // Note: this file was generated. #include "printer/printer.h" #include #include #include class PrinterLoader : public QObject { Q_OBJECT const QString m_printerName; IppClient *m_client; OrgCupsCupsdNotifierInterface *m_notifier; public: explicit PrinterLoader(const QString &printerName, IppClient *client, OrgCupsCupsdNotifierInterface* notifier, QObject *parent = Q_NULLPTR); ~PrinterLoader(); public Q_SLOTS: void load(); Q_SIGNALS: void finished(); void loaded(QSharedPointer printer); }; #endif // USC_PRINTERS_CUPS_PRINTERLOADER_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/enums.h000066400000000000000000000050361455543116500263530ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_PRINTERS_ENUMS_H #define USC_PRINTERS_ENUMS_H #include "printers_global.h" #include class PRINTERS_DECL_EXPORT PrinterEnum { Q_GADGET public: enum class AccessControl { AccessAllow = 0, AccessDeny, }; Q_ENUM(AccessControl) enum class ColorModelType { GrayType = 0, ColorType, UnknownType, }; Q_ENUM(ColorModelType) enum class DuplexMode { DuplexNone = 0, DuplexLongSide, DuplexShortSide, }; Q_ENUM(DuplexMode) enum class ErrorPolicy { RetryOnError = 0, AbortOnError, StopPrinterOnError, RetryCurrentOnError, }; Q_ENUM(ErrorPolicy) // Match enums from ipp_jstate_t enum class JobState { Pending = 3, Held, Processing, Stopped, Canceled, Aborted, Complete, }; Q_ENUM(JobState) enum class OperationPolicy { DefaultOperation = 0, AuthenticatedOperation, }; Q_ENUM(OperationPolicy) enum class PrintRange { AllPages = 0, PageRange, }; Q_ENUM(PrintRange) enum class State { IdleState = 0, ActiveState, AbortedState, ErrorState, }; Q_ENUM(State) enum class PrinterType { ProxyType = 0, // Represents a printer not yet loaded. CupsType, PdfType, }; Q_ENUM(PrinterType) enum class DeviceType { UnknownType = 0, LPDType, IppSType, Ipp14Type, HttpType, BehType, SocketType, HttpsType, IppType, HPType, USBType, HPFaxType, DNSSDType, }; Q_ENUM(DeviceType) }; inline uint qHash(const PrinterEnum::JobState &state, uint seed) { return qHash((int) state, seed); } #endif // USC_PRINTERS_ENUMS_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/i18n.cpp000066400000000000000000000024101455543116500263270ustar00rootroot00000000000000/* * Copyright (C) 2014, 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authored by: Ken VanDine * Andrew Hayzen */ #define NO_TR_OVERRIDE #include "i18n.h" #include const char *thisDomain = ""; void initTr(const char *domain, const char *localeDir) { // Don't bind the domain or set textdomain as it changes the Apps domain // as well. Instead store the domain and use it in the lookups Q_UNUSED(localeDir); thisDomain = domain; } QString __(const char *text, const char *domain) { Q_UNUSED(domain); // Use the stored domain return QString::fromUtf8(dgettext(thisDomain, text)); } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/i18n.h000066400000000000000000000017031455543116500260000ustar00rootroot00000000000000/* * Copyright (C) 2014, 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authored by: Ken VanDine * Andrew Hayzen */ #ifndef I18N_H #define I18N_H #include void initTr(const char *domain, const char *localeDir); QString __(const char *text, const char *domain = 0); #endif // I18N_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/models/000077500000000000000000000000001455543116500263325ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/models/devicemodel.cpp000066400000000000000000000073071455543116500313250ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "backend/backend_cups.h" #include "models/devicemodel.h" #include DeviceModel::DeviceModel(PrinterBackend *backend, QObject *parent) : QAbstractListModel(parent) , m_backend(backend) , m_isSearching(false) { connect(m_backend, SIGNAL(deviceFound(const Device&)), this, SLOT(deviceLoaded(const Device&))); connect(m_backend, SIGNAL(deviceSearchFinished()), this, SLOT(deviceSearchFinished())); } DeviceModel::~DeviceModel() { } int DeviceModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); return m_devices.size(); } int DeviceModel::count() const { return rowCount(); } QVariant DeviceModel::data(const QModelIndex &index, int role) const { QVariant ret; if ((0 <= index.row()) && (index.row() < m_devices.size())) { auto device = m_devices[index.row()]; switch (role) { case Qt::DisplayRole: ret = device.toString(); break; case IdRole: ret = device.id; break; case InfoRole: ret = device.info; break; case UriRole: ret = device.uri; break; case LocationRole: ret = device.location; break; case TypeRole: ret = QVariant::fromValue(device.type()); break; case MakeModelRole: ret = device.makeModel; break; } } return ret; } QHash DeviceModel::roleNames() const { static QHash names; if (Q_UNLIKELY(names.empty())) { names[Qt::DisplayRole] = "displayName"; names[IdRole] = "id"; names[InfoRole] = "info"; names[UriRole] = "uri"; names[LocationRole] = "location"; names[TypeRole] = "type"; names[MakeModelRole] = "makeModel"; } return names; } void DeviceModel::deviceLoaded(const Device &device) { if (!deviceWanted(device)) { return; } if (!m_devices.contains(device)) { int i = m_devices.size(); beginInsertRows(QModelIndex(), i, i); m_devices.append(device); endInsertRows(); Q_EMIT countChanged(); } } bool DeviceModel::deviceWanted(const Device &device) { #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) auto parts = device.uri.split(":", Qt::SkipEmptyParts); #else auto parts = device.uri.split(":", QString::SkipEmptyParts); #endif return parts.size() > 1; } void DeviceModel::clear() { beginResetModel(); m_devices.clear(); endResetModel(); } void DeviceModel::load() { if (m_isSearching) { qWarning() << Q_FUNC_INFO << "Ignoring load request as search is ongoing."; } else { clear(); if (m_backend->type() == PrinterEnum::PrinterType::CupsType) { ((PrinterCupsBackend*) m_backend)->searchForDevices(); m_isSearching = true; Q_EMIT searchingChanged(); } } } void DeviceModel::deviceSearchFinished() { m_isSearching = false; Q_EMIT searchingChanged(); } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/models/devicemodel.h000066400000000000000000000042241455543116500307650ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_PRINTER_DEVICEMODEL_H #define USC_PRINTER_DEVICEMODEL_H #include "printers_global.h" #include "structs.h" #include #include #include #include #include class PRINTERS_DECL_EXPORT DeviceModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(bool searching MEMBER m_isSearching NOTIFY searchingChanged) public: explicit DeviceModel(PrinterBackend *backend, QObject *parent = Q_NULLPTR); ~DeviceModel(); enum Roles { // Qt::DisplayRole holds device name ClassRole = Qt::UserRole, IdRole, InfoRole, UriRole, LocationRole, TypeRole, MakeModelRole, LastRole = MakeModelRole, }; virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; virtual QHash roleNames() const override; int count() const; void load(); void clear(); private Q_SLOTS: void deviceLoaded(const Device &device); void deviceSearchFinished(); Q_SIGNALS: void countChanged(); void searchingChanged(); private: /* Checks if we want it in the list or not. Wanted is intentionally ambiguous. */ bool deviceWanted(const Device &device); PrinterBackend *m_backend; QList m_devices; bool m_isSearching; }; #endif // USC_PRINTER_DEVICEMODEL_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/models/drivermodel.cpp000066400000000000000000000102651455543116500313560ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "backend/backend_cups.h" #include "models/drivermodel.h" #include #include DriverModel::DriverModel(PrinterBackend *backend, QObject *parent) : QAbstractListModel(parent) , m_backend(backend) { connect(m_backend, SIGNAL(printerDriversLoaded(const QList&)), this, SLOT(printerDriversLoaded(const QList&))); QObject::connect(&m_watcher, &QFutureWatcher::finished, this, &DriverModel::filterFinished); } DriverModel::~DriverModel() { cancel(); } int DriverModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); return m_drivers.size(); } int DriverModel::count() const { return rowCount(); } QVariant DriverModel::data(const QModelIndex &index, int role) const { QVariant ret; if ((0 <= index.row()) && (index.row() < m_drivers.size())) { auto driver = m_drivers[index.row()]; switch (role) { case Qt::DisplayRole: ret = driver.toString(); break; case NameRole: ret = driver.name; break; case DeviceIdRole: ret = driver.deviceId; break; case LanguageRole: ret = driver.language; break; case MakeModelRole: ret = driver.makeModel; break; } } return ret; } QHash DriverModel::roleNames() const { static QHash names; if (Q_UNLIKELY(names.empty())) { names[Qt::DisplayRole] = "displayName"; names[NameRole] = "name"; names[DeviceIdRole] = "deviceId"; names[LanguageRole] = "language"; names[MakeModelRole] = "makeModel"; } return names; } void DriverModel::setFilter(const QString& pattern) { QList needles; Q_FOREACH(const QString patternPart, pattern.toLower().split(" ")) { needles.append(patternPart.toUtf8()); } QList list; if (m_watcher.isRunning()) m_watcher.cancel(); if (pattern.isEmpty()) { setModel(m_originalDrivers); m_filter = pattern; return; } if (!m_filter.isEmpty() && !m_drivers.isEmpty() && pattern.startsWith(m_filter)) list = m_drivers; // search in the smaller list else list = m_originalDrivers; //search in the whole list m_filter = pattern; QFuture future(QtConcurrent::filtered(list, [needles] (const PrinterDriver &driver) { QByteArray haystack = driver.makeModel.toLower(); Q_FOREACH(const QByteArray needle, needles) { if (!haystack.contains(needle)) { return false; } } return true; } ) ); Q_EMIT filterBegin(); m_watcher.setFuture(future); } QString DriverModel::filter() const { return m_filter; } void DriverModel::filterFinished() { setModel(m_watcher.future().results()); } void DriverModel::load() { m_backend->requestPrinterDrivers(); } void DriverModel::cancel() { if (m_watcher.isRunning()) m_watcher.cancel(); } void DriverModel::printerDriversLoaded(const QList &drivers) { m_originalDrivers = drivers; setModel(m_originalDrivers); } void DriverModel::setModel(const QList &drivers) { beginResetModel(); m_drivers = drivers; endResetModel(); Q_EMIT filterComplete(); } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/models/drivermodel.h000066400000000000000000000043661455543116500310300ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_PRINTER_DRIVERMODEL_H #define USC_PRINTER_DRIVERMODEL_H #include "printers_global.h" #include "structs.h" #include #include #include #include #include class PRINTERS_DECL_EXPORT DriverModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(int count READ count NOTIFY countChanged) public: explicit DriverModel(PrinterBackend *backend, QObject *parent = Q_NULLPTR); ~DriverModel(); enum Roles { // Qt::DisplayRole holds driver name NameRole = Qt::UserRole, DeviceIdRole, LanguageRole, MakeModelRole, LastRole = MakeModelRole, }; virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; virtual QHash roleNames() const override; int count() const; QString filter() const; void setFilter(const QString& pattern); public Q_SLOTS: // Start loading the model. void load(); // Cancel loading of the model. void cancel(); private Q_SLOTS: void printerDriversLoaded(const QList &drivers); void filterFinished(); Q_SIGNALS: void countChanged(); void filterBegin(); void filterComplete(); private: void setModel(const QList &drivers); PrinterBackend *m_backend; QList m_drivers; QList m_originalDrivers; QString m_filter; QFutureWatcher m_watcher; }; #endif // USC_PRINTER_DRIVERMODEL_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/models/jobmodel.cpp000066400000000000000000000371301455543116500306350ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "utils.h" #include "backend/backend_cups.h" #include "models/jobmodel.h" #include JobModel::JobModel(QObject *parent) : QAbstractListModel(parent) { } JobModel::JobModel(PrinterBackend *backend, QObject *parent) : QAbstractListModel(parent) , m_backend(backend) { QObject::connect(m_backend, &PrinterBackend::jobCreated, this, &JobModel::jobCreated); QObject::connect(m_backend, &PrinterBackend::jobState, this, &JobModel::jobState); QObject::connect(m_backend, &PrinterBackend::jobCompleted, this, &JobModel::jobCompleted); connect(m_backend, SIGNAL(jobLoaded(QString, int, QMap)), this, SLOT(updateJob(QString, int, QMap))); // Impressions completed happens via printer state changed QObject::connect(m_backend, &PrinterBackend::printerStateChanged, &m_signalHandler, &SignalRateLimiter::onPrinterStateChanged); QObject::connect(&m_signalHandler, SIGNAL(printerModified(const QString&)), this, SLOT(jobSignalPrinterModified(const QString&))); // Add already existing jobs // TODO: even this should probably be in a background thread? // so that it doesn't block startup? Q_FOREACH(auto job, m_backend->printerGetJobs()) { addJob(job); } } JobModel::~JobModel() { } void JobModel::jobCreated( const QString &text, const QString &printer_uri, const QString &printer_name, uint printer_state, const QString &printer_state_reasons, bool printer_is_accepting_jobs, uint job_id, uint job_state, const QString &job_state_reasons, const QString &job_name, uint job_impressions_completed) { Q_UNUSED(text); // "Job Created" Q_UNUSED(printer_uri); Q_UNUSED(printer_state); Q_UNUSED(printer_state_reasons); Q_UNUSED(printer_is_accepting_jobs); Q_UNUSED(job_state_reasons); QSharedPointer job = QSharedPointer( new PrinterJob(printer_name, m_backend, job_id) ); job->setImpressionsCompleted(job_impressions_completed); job->setState(static_cast(job_state)); job->setTitle(job_name); // Printers listens to rowInserted and spawns a JobLoader to set the // printer of the job, which triggers the extended attributes to be loaded // once complete this triggers JobModel::updateJob addJob(job); } void JobModel::jobState( const QString &text, const QString &printer_uri, const QString &printer_name, uint printer_state, const QString &printer_state_reasons, bool printer_is_accepting_jobs, uint job_id, uint job_state, const QString &job_state_reasons, const QString &job_name, uint job_impressions_completed) { Q_UNUSED(text); Q_UNUSED(printer_uri); Q_UNUSED(printer_state); Q_UNUSED(printer_state_reasons); Q_UNUSED(printer_is_accepting_jobs); Q_UNUSED(job_state_reasons); Q_UNUSED(job_name); QSharedPointer job = getJob(printer_name, job_id); if (job) { job->setImpressionsCompleted(job_impressions_completed); job->setState(static_cast(job_state)); updateJob(job); } else { qWarning() << "JobModel::jobState for unknown job: " << job_name << " (" << job_id << ") for " << printer_name; } } void JobModel::jobCompleted( const QString &text, const QString &printer_uri, const QString &printer_name, uint printer_state, const QString &printer_state_reasons, bool printer_is_accepting_jobs, uint job_id, uint job_state, const QString &job_state_reasons, const QString &job_name, uint job_impressions_completed) { Q_UNUSED(text); Q_UNUSED(printer_uri); Q_UNUSED(printer_state); Q_UNUSED(printer_state_reasons); Q_UNUSED(printer_is_accepting_jobs); Q_UNUSED(job_state); Q_UNUSED(job_state_reasons); Q_UNUSED(job_name); Q_UNUSED(job_impressions_completed); auto job = getJob(printer_name, job_id); if (job) { removeJob(job); } else { qWarning() << "JobModel::jobCompleted for unknown job: " << job_name << " (" << job_id << ") for " << printer_name; } } void JobModel::jobSignalPrinterModified(const QString &printerName) { // Find the active or pending job and force a refresh // We force refresh pending jobs incase there is a flood of signals // meaning that the jobStateChanged signal might not have happened yet Q_FOREACH(auto job, m_jobs) { if (job->printerName() == printerName && (job->state() == PrinterEnum::JobState::Processing || job->state() == PrinterEnum::JobState::Pending)) { Q_EMIT forceJobRefresh(printerName, job->jobId()); } } } void JobModel::addJob(QSharedPointer job) { int i = m_jobs.size(); beginInsertRows(QModelIndex(), i, i); m_jobs.append(job); endInsertRows(); Q_EMIT countChanged(); } void JobModel::removeJob(QSharedPointer job) { int i = m_jobs.indexOf(job); beginRemoveRows(QModelIndex(), i, i); m_jobs.removeAt(i); endRemoveRows(); Q_EMIT countChanged(); } // This is used by JobModel::jobState as it has modified an existing job void JobModel::updateJob(QSharedPointer job) { int i = m_jobs.indexOf(job); QModelIndex idx = index(i); Q_EMIT dataChanged(idx, idx); } // This is used by JobLoader as it gives us the oldJob and a newJob which has // the extended attributes loaded. We then load the data from this newJob. void JobModel::updateJob(QString printerName, int jobId, QMap attributes) { QSharedPointer job = getJob(printerName, jobId); int i = m_jobs.indexOf(job); QModelIndex idx = index(i); if (i > -1) { job->loadAttributes(attributes); Q_EMIT dataChanged(idx, idx); } else { qWarning() << "Tried to updateJob which doesn't exist:" << printerName << jobId; } } void JobModel::updateJobPrinter(QSharedPointer job, QSharedPointer printer) { int i = m_jobs.indexOf(job); QModelIndex idx = index(i); if (i > -1) { job->setPrinter(printer); Q_EMIT dataChanged(idx, idx); } else { qWarning() << "Tried to updateJobPrinter which doesn't exist:" << printer->name() << job->jobId(); } } int JobModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); return m_jobs.size(); } int JobModel::count() const { return rowCount(); } QVariant JobModel::data(const QModelIndex &index, int role) const { QVariant ret; if ((0<=index.row()) && (index.row()collate(); break; case ColorModelRole: { if (job->printer()) { ColorModel m = job->printer()->supportedColorModels().at(job->colorModel()); ret = m.text.isEmpty() ? m.name : m.text; } else { qWarning() << "Printer is undefined, no colorModel"; ret = ""; } break; } case CompletedTimeRole: ret = job->completedTime().toLocalTime(); break; case CopiesRole: ret = job->copies(); break; case CreationTimeRole: ret = job->creationTime().toLocalTime(); break; case DuplexRole: { if (job->printer()) { ret = job->printer()->supportedDuplexStrings().at(job->duplexMode()); } else { qWarning() << "Printer is undefined, no duplexMode"; ret = ""; } break; } case IdRole: ret = job->jobId(); break; case HeldRole: ret = job->state() == PrinterEnum::JobState::Held; break; case ImpressionsCompletedRole: ret = job->impressionsCompleted(); break; case LandscapeRole: ret = job->landscape(); break; case MessagesRole: ret = job->messages(); break; case PrinterNameRole: ret = job->printerName(); break; case PrintRangeRole: ret = job->printRange(); break; case PrintRangeModeRole: ret = QVariant::fromValue(job->printRangeMode()); break; case ProcessingTimeRole: ret = job->processingTime().toLocalTime(); break; case QualityRole: { if (job->printer()) { PrintQuality q = job->printer()->supportedPrintQualities().at(job->quality()); ret = q.text.isEmpty() ? q.name : q.text; } else { qWarning() << "Printer is undefined, no quality"; ret = ""; } break; } case ReverseRole: ret = job->reverse(); break; case SizeRole: ret = job->size(); break; case StateRole: ret = QVariant::fromValue(job->state()); break; case Qt::DisplayRole: case TitleRole: ret = job->title(); break; case UserRole: ret = job->user(); break; case LastStateMessageRole: { if (job->printer()) { ret = job->printer()->lastMessage(); } else { ret = ""; } break; } } } return ret; } QHash JobModel::roleNames() const { static QHash names; if (Q_UNLIKELY(names.empty())) { names[Qt::DisplayRole] = "displayName"; names[IdRole] = "id"; names[CollateRole] = "collate"; names[ColorModelRole] = "colorModel"; names[CompletedTimeRole] = "completedTime"; names[CopiesRole] = "copies"; names[CreationTimeRole] = "creationTime"; names[DuplexRole] = "duplexMode"; names[ImpressionsCompletedRole] = "impressionsCompleted"; names[HeldRole] = "held"; names[LandscapeRole] = "landscape"; names[MessagesRole] = "messages"; names[PrinterNameRole] = "printerName"; names[PrintRangeRole] = "printRange"; names[PrintRangeModeRole] = "printRangeMode"; names[ProcessingTimeRole] = "processingTime"; names[QualityRole] = "quality"; names[ReverseRole] = "reverse"; names[SizeRole] = "size"; names[StateRole] = "state"; names[TitleRole] = "title"; names[UserRole] = "user"; names[LastStateMessageRole] = "lastStateMessage"; } return names; } QVariantMap JobModel::get(const int row) const { QHashIterator iterator(roleNames()); QVariantMap result; QModelIndex modelIndex = index(row, 0); while (iterator.hasNext()) { iterator.next(); result[iterator.value()] = modelIndex.data(iterator.key()); } return result; } QSharedPointer JobModel::getJob(const QString &printerName, const int &id) { Q_FOREACH(auto job, m_jobs) { if (job->printerName() == printerName && job->jobId() == id) { return job; } } return QSharedPointer(Q_NULLPTR); } JobFilter::JobFilter(QObject *parent) : QSortFilterProxyModel(parent) { connect(this, SIGNAL(sourceModelChanged()), SLOT(onSourceModelChanged())); } JobFilter::~JobFilter() { } QVariantMap JobFilter::get(const int row) const { QHashIterator iterator(roleNames()); QVariantMap result; QModelIndex modelIndex = index(row, 0); while (iterator.hasNext()) { iterator.next(); result[iterator.value()] = modelIndex.data(iterator.key()); } return result; } void JobFilter::onSourceModelChanged() { connect((JobModel*) sourceModel(), SIGNAL(countChanged()), this, SIGNAL(countChanged())); } void JobFilter::onSourceModelCountChanged() { Q_EMIT countChanged(); } int JobFilter::count() const { return rowCount(); } void JobFilter::filterOnActive() { m_activeStates = QSet{ PrinterEnum::JobState::Processing, }; m_activeFilterEnabled = true; invalidate(); } void JobFilter::filterOnPaused() { m_pausedStates = QSet{ PrinterEnum::JobState::Held, }; m_pausedFilterEnabled = true; invalidate(); } void JobFilter::filterOnQueued() { m_queuedStates = QSet{ PrinterEnum::JobState::Pending, }; m_queuedFilterEnabled = true; invalidate(); } void JobFilter::filterOnPrinterName(const QString &name) { m_printerName = name; m_printerNameFilterEnabled = true; invalidate(); } bool JobFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { bool accepts = true; QModelIndex childIndex = sourceModel()->index(sourceRow, 0, sourceParent); if (accepts && m_printerNameFilterEnabled) { QString printerName = childIndex.model()->data( childIndex, JobModel::PrinterNameRole).toString(); accepts = m_printerName == printerName; } if (accepts && m_activeFilterEnabled) { PrinterEnum::JobState state = childIndex.model()->data( childIndex, JobModel::StateRole ).value(); accepts = m_activeStates.contains(state); } if (accepts && m_pausedFilterEnabled) { PrinterEnum::JobState state = childIndex.model()->data( childIndex, JobModel::StateRole ).value(); accepts = m_pausedStates.contains(state); } if (accepts && m_queuedFilterEnabled) { PrinterEnum::JobState state = childIndex.model()->data( childIndex, JobModel::StateRole ).value(); accepts = m_queuedStates.contains(state); } return accepts; } bool JobFilter::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const { QVariant leftData = sourceModel()->data(source_left, sortRole()); QVariant rightData = sourceModel()->data(source_right, sortRole()); if (sortRole() == (int) JobModel::CreationTimeRole) { // If creationDateTime is the same, fallback to Id if (leftData.toDateTime() == rightData.toDateTime()) { int leftId = sourceModel()->data(source_left, JobModel::IdRole).toInt(); int rightId = sourceModel()->data(source_right, JobModel::IdRole).toInt(); return leftId < rightId; } else { return leftData.toDateTime() < rightData.toDateTime(); } } else { return leftData < rightData; } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/models/jobmodel.h000066400000000000000000000126471455543116500303100ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_JOB_MODEL_H #define USC_JOB_MODEL_H #include "printers_global.h" #include "backend/backend.h" #include "printer/printerjob.h" #include "printer/signalratelimiter.h" #include #include #include #include #include #include #include #include class PrinterBackend; class PrinterJob; class PRINTERS_DECL_EXPORT JobModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(int count READ count NOTIFY countChanged) public: explicit JobModel(QObject *parent = Q_NULLPTR); explicit JobModel(PrinterBackend *backend, QObject *parent = Q_NULLPTR); ~JobModel(); enum Roles { // Qt::DisplayRole holds job title IdRole = Qt::UserRole, CollateRole, ColorModelRole, CompletedTimeRole, CopiesRole, CreationTimeRole, DuplexRole, HeldRole, ImpressionsCompletedRole, LandscapeRole, MessagesRole, PrinterNameRole, PrintRangeRole, PrintRangeModeRole, ProcessingTimeRole, QualityRole, ReverseRole, SizeRole, StateRole, TitleRole, UserRole, LastStateMessageRole, LastRole = LastStateMessageRole, }; virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; virtual QHash roleNames() const override; int count() const; Q_INVOKABLE QVariantMap get(const int row) const; QSharedPointer getJob(const QString &printerName, const int &id); void updateJobPrinter(QSharedPointer job, QSharedPointer printer); private: void addJob(QSharedPointer job); void removeJob(QSharedPointer job); void updateJob(QSharedPointer Job); PrinterBackend *m_backend; QList> m_jobs; SignalRateLimiter m_signalHandler; private Q_SLOTS: void jobCreated(const QString &text, const QString &printer_uri, const QString &printer_name, uint printer_state, const QString &printer_state_reasons, bool printer_is_accepting_jobs, uint job_id, uint job_state, const QString &job_state_reasons, const QString &job_name, uint job_impressions_completed); void jobState(const QString &text, const QString &printer_uri, const QString &printer_name, uint printer_state, const QString &printer_state_reasons, bool printer_is_accepting_jobs, uint job_id, uint job_state, const QString &job_state_reasons, const QString &job_name, uint job_impressions_completed); void jobCompleted(const QString &text, const QString &printer_uri, const QString &printer_name, uint printer_state, const QString &printer_state_reasons, bool printer_is_accepting_jobs, uint job_id, uint job_state, const QString &job_state_reasons, const QString &job_name, uint job_impressions_completed); void jobSignalPrinterModified(const QString &printerName); void updateJob(QString printerName, int jobId, QMap attributes); Q_SIGNALS: void countChanged(); void forceJobRefresh(const QString &printerName, const int jobId); }; class PRINTERS_DECL_EXPORT JobFilter : public QSortFilterProxyModel { Q_OBJECT Q_PROPERTY(int count READ count NOTIFY countChanged) public: explicit JobFilter(QObject *parent = Q_NULLPTR); ~JobFilter(); void filterOnPrinterName(const QString &name); int count() const; public Q_SLOTS: QVariantMap get(const int row) const; void filterOnActive(); void filterOnQueued(); void filterOnPaused(); protected: virtual bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent) const override; virtual bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const; Q_SIGNALS: void countChanged(); private Q_SLOTS: void onSourceModelChanged(); void onSourceModelCountChanged(); private: QString m_printerName = QString(); bool m_printerNameFilterEnabled = false; bool m_activeFilterEnabled = false; QSet m_activeStates; bool m_queuedFilterEnabled = false; QSet m_queuedStates; bool m_pausedFilterEnabled = false; QSet m_pausedStates; }; #endif // USC_JOB_MODEL_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp000066400000000000000000000410721455543116500315460ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "backend/backend_cups.h" #include "backend/backend_pdf.h" #include "i18n.h" #include "models/jobmodel.h" #include "models/printermodel.h" #include "utils.h" #include #include PrinterModel::PrinterModel(PrinterBackend *backend, QObject *parent) : QAbstractListModel(parent) , m_backend(backend) { QObject::connect(m_backend, &PrinterBackend::printerAdded, this, &PrinterModel::printerAdded); QObject::connect(m_backend, &PrinterBackend::printerModified, &m_signalHandler, &SignalRateLimiter::onPrinterModified); QObject::connect(m_backend, &PrinterBackend::printerStateChanged, &m_signalHandler, &SignalRateLimiter::onPrinterModified); QObject::connect(m_backend, &PrinterBackend::printerDeleted, this, &PrinterModel::printerDeleted); connect(&m_signalHandler, SIGNAL(printerModified(const QString&)), this, SLOT(printerModified(const QString&))); connect(m_backend, SIGNAL(printerLoaded(QSharedPointer)), this, SLOT(printerLoaded(QSharedPointer))); // Create printer proxies for every printerName. Q_FOREACH(auto printerName, m_backend->availablePrinterNames()) { auto p = QSharedPointer(new Printer(new PrinterBackend(printerName))); addPrinter(p, CountChangeSignal::Defer); } // Add a PDF printer. auto pdfPrinter = QSharedPointer( new Printer(new PrinterPdfBackend(__("Create PDF"))) ); addPrinter(pdfPrinter, CountChangeSignal::Defer); Q_EMIT countChanged(); } PrinterModel::~PrinterModel() { } void PrinterModel::printerLoaded(QSharedPointer printer) { // If there is an existing printer then get it QSharedPointer oldPrinter = getPrinterByName(printer->name()); if (oldPrinter) { // Check if the existing printer needs updating if (!oldPrinter->deepCompare(printer)) { updatePrinter(oldPrinter, printer); } } else { // There isn't an existing printer so add it addPrinter(printer, CountChangeSignal::Emit); } } void PrinterModel::printerModified(const QString &printerName) { // These signals might be emitted of a now deleted printer. if (getPrinterByName(printerName)) m_backend->requestPrinter(printerName); } void PrinterModel::printerAdded( const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs) { Q_UNUSED(text); Q_UNUSED(printerUri); Q_UNUSED(printerState); Q_UNUSED(printerStateReason); Q_UNUSED(acceptingJobs); // If there isn't an existing printer then add a proxy printer if (!getPrinterByName(printerName)) { auto p = QSharedPointer(new Printer(new PrinterBackend(printerName))); addPrinter(p); } m_backend->requestPrinter(printerName); } void PrinterModel::printerDeleted( const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs) { Q_UNUSED(text); Q_UNUSED(printerUri); Q_UNUSED(printerState); Q_UNUSED(printerStateReason); Q_UNUSED(acceptingJobs); auto printer = getPrinterByName(printerName); if (printer) { removePrinter(printer, CountChangeSignal::Emit); } } QSharedPointer PrinterModel::getPrinterByName(const QString &printerName) { Q_FOREACH(auto p, m_printers) { if (p->name() == printerName) return p; } return QSharedPointer(Q_NULLPTR); } void PrinterModel::removePrinter(QSharedPointer printer, const CountChangeSignal ¬ify) { int idx = m_printers.indexOf(printer); beginRemoveRows(QModelIndex(), idx, idx); m_printers.removeAt(idx); endRemoveRows(); if (notify == CountChangeSignal::Emit) Q_EMIT countChanged(); } void PrinterModel::updatePrinter(QSharedPointer old, QSharedPointer newPrinter) { int i = m_printers.indexOf(old); QModelIndex idx = index(i); old->updateFrom(newPrinter); Q_EMIT dataChanged(idx, idx); } void PrinterModel::addPrinter(QSharedPointer printer, const CountChangeSignal ¬ify) { int i = m_printers.size(); beginInsertRows(QModelIndex(), i, i); m_printers.append(printer); endInsertRows(); if (notify == CountChangeSignal::Emit) Q_EMIT countChanged(); } int PrinterModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); return m_printers.size(); } int PrinterModel::count() const { return rowCount(); } QVariant PrinterModel::data(const QModelIndex &index, int role) const { QVariant ret; if ((0<=index.row()) && (index.row()type() == PrinterEnum::PrinterType::ProxyType) { switch (role) { case Qt::DisplayRole: case NameRole: case DefaultPrinterRole: case PrinterRole: case IsPdfRole: case IsLoadedRole: break; // All of these can be inferred from the name (lazily). default: m_backend->requestPrinter(printer->name()); } } switch (role) { case NameRole: case Qt::DisplayRole: ret = printer->name(); break; case DeviceUriRole: ret = printer->deviceUri(); break; case HostNameRole: ret = QUrl(printer->deviceUri()).host(); break; case MakeRole: ret = printer->make(); break; case ColorModelRole: ret = printer->supportedColorModels().indexOf(printer->defaultColorModel()); break; case SupportedColorModelsRole: { QStringList models; Q_FOREACH(const ColorModel &m, printer->supportedColorModels()) { models.append(m.text.isEmpty() ? m.name : m.text); } ret = models; } break; case DefaultPrinterRole: ret = printer->name() == m_backend->defaultPrinterName(); break; case DuplexRole: ret = printer->supportedDuplexModes().indexOf(printer->defaultDuplexMode()); break; case SupportedDuplexModesRole: ret = printer->supportedDuplexStrings(); break; case PrintQualityRole: ret = printer->supportedPrintQualities().indexOf(printer->defaultPrintQuality()); break; case SupportedPrintQualitiesRole: { QStringList qualities; Q_FOREACH(const PrintQuality &q, printer->supportedPrintQualities()) { qualities.append(q.text.isEmpty() ? q.name : q.text); } ret = qualities; } break; case DescriptionRole: ret = printer->description(); break; case LocationRole: ret = printer->location(); break; case PageSizeRole: ret = printer->defaultPageSize().name(); break; case SupportedPageSizesRole: { QStringList sizes; Q_FOREACH(const QPageSize &s, printer->supportedPageSizes()) { sizes << s.name(); } ret = sizes; } break; case StateRole: ret = QVariant::fromValue(printer->state()); break; case PrinterRole: ret = QVariant::fromValue(printer); break; case IsPdfRole: ret = printer->type() == PrinterEnum::PrinterType::PdfType; break; case IsLoadedRole: ret = printer->type() != PrinterEnum::PrinterType::ProxyType; break; case IsRawRole: ret = !printer->holdsDefinition(); break; case IsRemoteRole: ret = printer->isRemote(); break; case LastMessageRole: ret = printer->lastMessage(); break; case JobRole: ret = QVariant::fromValue(printer->jobs()); break; case CopiesRole: ret = printer->copies(); break; case EnabledRole: ret = printer->enabled(); break; case AcceptJobsRole: ret = printer->acceptJobs(); break; case SharedRole: ret = printer->shared(); break; } } return ret; } bool PrinterModel::setData(const QModelIndex &index, const QVariant &value, int role) { if ((0<=index.row()) && (index.row()supportedColorModels(); if (index >= 0 && modes.size() > index) { printer->setDefaultColorModel(modes.at(index)); } } break; case DescriptionRole: printer->setDescription(value.toString()); break; case DuplexRole: { int index = value.toInt(); auto modes = printer->supportedDuplexModes(); if (index >= 0 && modes.size() > index) { printer->setDefaultDuplexMode(modes.at(index)); } } break; case PageSizeRole: { int index = value.toInt(); QList sizes = printer->supportedPageSizes(); if (index >= 0 && sizes.size() > index) { printer->setDefaultPageSize(sizes.at(index)); } } break; case PrintQualityRole: { int index = value.toInt(); QList quals = printer->supportedPrintQualities(); if (index >= 0 && quals.size() > index) { printer->setDefaultPrintQuality(quals.at(index)); } } break; case EnabledRole: printer->setEnabled(value.toBool()); break; case AcceptJobsRole: printer->setAcceptJobs(value.toBool()); break; case CopiesRole: printer->setCopies(value.toInt()); case SharedRole: printer->setShared(value.toBool()); break; } } return true; } QHash PrinterModel::roleNames() const { static QHash names; if (Q_UNLIKELY(names.empty())) { names[Qt::DisplayRole] = "displayName"; names[ColorModelRole] = "colorModel"; names[SupportedColorModelsRole] = "supportedColorModels"; names[DefaultPrinterRole] = "default"; names[DuplexRole] = "duplexMode"; names[SupportedDuplexModesRole] = "supportedDuplexModes"; names[NameRole] = "name"; names[DeviceUriRole] = "deviceUri"; names[HostNameRole] = "hostname"; names[MakeRole] = "make"; names[EnabledRole] = "printerEnabled"; names[AcceptJobsRole] = "acceptJobs"; names[SharedRole] = "shared"; names[PrintQualityRole] = "printQuality"; names[SupportedPrintQualitiesRole] = "supportedPrintQualities"; names[DescriptionRole] = "description"; names[LocationRole] = "location"; names[PageSizeRole] = "pageSize"; names[SupportedPageSizesRole] = "supportedPageSizes"; names[StateRole] = "state"; names[PrinterRole] = "printer"; names[IsPdfRole] = "isPdf"; names[IsLoadedRole] = "isLoaded"; names[IsRawRole] = "isRaw"; names[IsRemoteRole] = "isRemote"; names[LastMessageRole] = "lastMessage"; names[CopiesRole] = "copies"; names[JobRole] = "jobs"; } return names; } QVariantMap PrinterModel::get(const int row) const { QHashIterator iterator(roleNames()); QVariantMap result; QModelIndex modelIndex = index(row, 0); while (iterator.hasNext()) { iterator.next(); result[iterator.value()] = modelIndex.data(iterator.key()); } return result; } PrinterFilter::PrinterFilter(QObject *parent) : QSortFilterProxyModel(parent) { connect(this, SIGNAL(sourceModelChanged()), SLOT(onSourceModelChanged())); } PrinterFilter::~PrinterFilter() { } QVariantMap PrinterFilter::get(const int row) const { QHashIterator iterator(roleNames()); QVariantMap result; QModelIndex modelIndex = index(row, 0); while (iterator.hasNext()) { iterator.next(); result[iterator.value()] = modelIndex.data(iterator.key()); } return result; } void PrinterFilter::onSourceModelChanged() { connect((PrinterModel*) sourceModel(), SIGNAL(countChanged()), this, SIGNAL(countChanged())); } void PrinterFilter::onSourceModelCountChanged() { Q_EMIT countChanged(); } int PrinterFilter::count() const { return rowCount(); } void PrinterFilter::filterOnState(const PrinterEnum::State &state) { Q_UNUSED(state); } void PrinterFilter::filterOnRecent(const bool recent) { Q_UNUSED(recent); } void PrinterFilter::filterOnPdf(const bool pdf) { m_pdfEnabled = true; m_pdf = pdf; } void PrinterFilter::filterOnRemote(const bool remote) { m_remoteEnabled = true; m_remote = remote; invalidate(); } bool PrinterFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { bool accepts = true; QModelIndex childIndex = sourceModel()->index(sourceRow, 0, sourceParent); if (accepts && m_recentEnabled) { // TODO: implement recent } // If pdfEnabled is false we only want real printers if (accepts && m_pdfEnabled) { bool isPdf = (bool) childIndex.model()->data( childIndex, PrinterModel::IsPdfRole).toBool(); accepts = isPdf == m_pdf; } if (accepts && m_stateEnabled) { const PrinterEnum::State state = (PrinterEnum::State) childIndex.model()->data( childIndex, PrinterModel::StateRole ).toInt(); accepts = m_state == state; } // If m_remote is true, we only show remote printers. if (accepts && m_remoteEnabled) { const bool isRemote = childIndex.model()->data( childIndex, PrinterModel::IsRemoteRole ).toBool(); accepts = m_remote == isRemote; } return accepts; } bool PrinterFilter::lessThan(const QModelIndex &left, const QModelIndex &right) const { QVariant leftData = sourceModel()->data(left, sortRole()); QVariant rightData = sourceModel()->data(right, sortRole()); if ((QMetaType::Type) leftData.type() == QMetaType::Bool) { // FIXME: hack to put Pdf printer at the bottom if (leftData.toInt() == rightData.toInt()) { int leftPdf = sourceModel()->data(left, PrinterModel::IsPdfRole).toInt(); int rightPdf = sourceModel()->data(right, PrinterModel::IsPdfRole).toInt(); // If Pdf is also same then sort by name if (leftPdf == rightPdf) { QString leftName = sourceModel()->data(left, PrinterModel::NameRole).toString(); QString rightName = sourceModel()->data(right, PrinterModel::NameRole).toString(); return leftName > rightName; } else { return leftPdf > rightPdf; } } else { return leftData.toInt() < rightData.toInt(); } } else { return leftData < rightData; } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/models/printermodel.h000066400000000000000000000117441455543116500312160ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_PRINTER_MODEL_H #define USC_PRINTER_MODEL_H #include "printers_global.h" #include "models/jobmodel.h" #include "printer/printer.h" #include "printer/signalratelimiter.h" #include #include #include #include #include #include class PRINTERS_DECL_EXPORT PrinterModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(int count READ count NOTIFY countChanged) public: explicit PrinterModel(PrinterBackend *backend, QObject *parent = Q_NULLPTR); ~PrinterModel(); enum Roles { // Qt::DisplayRole holds device name ColorModelRole = Qt::UserRole, SupportedColorModelsRole, DefaultPrinterRole, DuplexRole, SupportedDuplexModesRole, NameRole, DeviceUriRole, HostNameRole, MakeRole, LocationRole, EnabledRole, AcceptJobsRole, SharedRole, PrintQualityRole, SupportedPrintQualitiesRole, DescriptionRole, PageSizeRole, SupportedPageSizesRole, StateRole, PrinterRole, /* Indicates that this printer is a pseudo printer used to create PDF files. */ IsPdfRole, /* Indicates whether or not this printer has been fully loaded. If not fully loaded, basically only its name will be accessible. */ IsLoadedRole, /* Indicates that this printers has no associated PPD. */ IsRawRole, IsRemoteRole, LastMessageRole, CopiesRole, JobRole, LastRole = JobRole, }; virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; virtual QHash roleNames() const override; int count() const; Q_INVOKABLE QVariantMap get(const int row) const; QSharedPointer getPrinterByName(const QString &printerName); private: enum class CountChangeSignal { Defer, Emit, }; void addPrinter(QSharedPointer printer, const CountChangeSignal ¬ify = CountChangeSignal::Defer); void removePrinter(QSharedPointer printer, const CountChangeSignal ¬ify = CountChangeSignal::Defer); void updatePrinter(QSharedPointer old, QSharedPointer newPrinter); PrinterBackend *m_backend; QList> m_printers; SignalRateLimiter m_signalHandler; private Q_SLOTS: void printerLoaded(QSharedPointer printer); void printerModified(const QString &printerName); void printerAdded(const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs); void printerDeleted(const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs); Q_SIGNALS: void countChanged(); }; class PRINTERS_DECL_EXPORT PrinterFilter : public QSortFilterProxyModel { Q_OBJECT Q_PROPERTY(int count READ count NOTIFY countChanged) public: explicit PrinterFilter(QObject *parent = Q_NULLPTR); ~PrinterFilter(); Q_INVOKABLE QVariantMap get(const int row) const; void filterOnState(const PrinterEnum::State &state); void filterOnRecent(const bool recent); void filterOnPdf(const bool pdf); void filterOnRemote(const bool remote); int count() const; protected: virtual bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent) const override; virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; Q_SIGNALS: void countChanged(); private Q_SLOTS: void onSourceModelChanged(); void onSourceModelCountChanged(); private: PrinterEnum::State m_state = PrinterEnum::State::IdleState; bool m_stateEnabled = false; bool m_recent = false; bool m_recentEnabled = false; bool m_pdfEnabled = false; bool m_pdf = false; bool m_remoteEnabled = false; bool m_remote = false; }; #endif // USC_PRINTER_MODEL_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/org.cups.cupsd.Notifier.xml000066400000000000000000000127721455543116500322350ustar00rootroot00000000000000 lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/plugin.cpp000066400000000000000000000036251455543116500270570ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "plugin.h" #include "enums.h" #include "i18n.h" #include "structs.h" // #include "models/printermodel.h" #include "printer/printer.h" #include "printer/printerjob.h" #include "printers/printers.h" #include #include #define I18N_DOMAIN "lomiri-ui-extras" static QObject* p_singletonprovider(QQmlEngine *engine, QJSEngine *scriptEngine) { Q_UNUSED(engine) Q_UNUSED(scriptEngine) return new Printers; } void LomiriComponentsExtrasPrintersPlugin::registerTypes(const char *uri) { initTr(I18N_DOMAIN, NULL); qmlRegisterSingletonType( uri, 0, 1, "Printers", p_singletonprovider ); qmlRegisterUncreatableType( uri, 0, 1, "Printer", "use Printers to get a list of Printers." ); qmlRegisterUncreatableType(uri, 0, 1, "PrinterJob", "use Printers to create jobs."); qmlRegisterUncreatableType(uri, 0, 1, "PrinterEnum", "Is an enum"); qRegisterMetaType>("QList"); qRegisterMetaType>("QSharedPointer"); qRegisterMetaType>>("QList>"); qRegisterMetaType("Device"); } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/plugin.h000066400000000000000000000021261455543116500265170ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef UBUNTU_COMPONENTS_EXTRAS_PRINTERS_PLUGIN_H #define UBUNTU_COMPONENTS_EXTRAS_PRINTERS_PLUGIN_H #include "printers_global.h" #include class PRINTERS_DECL_EXPORT LomiriComponentsExtrasPrintersPlugin : public QQmlExtensionPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") public: void registerTypes(const char *uri); }; #endif // UBUNTU_COMPONENTS_EXTRAS_PRINTERS_PLUGIN_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/printer/000077500000000000000000000000001455543116500265325ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/printer/printer.cpp000066400000000000000000000262651455543116500307340ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "i18n.h" #include "utils.h" #include "printer.h" #include #include #include Printer::Printer(PrinterBackend *backend, QObject *parent) : QObject(parent) , m_backend(backend) { loadAttributes(); m_jobs.setParent(this); m_jobs.filterOnPrinterName(name()); QObject::connect(m_backend, &PrinterBackend::printerStateChanged, this, &Printer::onPrinterStateChanged); } Printer::~Printer() { m_backend->deleteLater(); } void Printer::setJobModel(JobModel* jobModel) { if (!m_jobs.sourceModel()) { m_jobs.setSourceModel(jobModel); } } void Printer::updateAcceptJobs(const QMap &serverAttrs) { m_acceptJobs = serverAttrs.value(QStringLiteral("AcceptJobs")).toBool(); } void Printer::updateColorModel(const QMap &serverAttrs) { auto defModel = QStringLiteral("DefaultColorModel"); auto models = QStringLiteral("SupportedColorModels"); m_defaultColorModel = serverAttrs.value(defModel).value(); m_supportedColorModels = serverAttrs.value(models).value>(); if (m_supportedColorModels.size() == 0) { m_supportedColorModels.append(m_defaultColorModel); } } void Printer::updatePrintQualities(const QMap &serverAttrs) { auto defQuality = QStringLiteral("DefaultPrintQuality"); auto qualities = QStringLiteral("SupportedPrintQualities"); m_supportedPrintQualities = serverAttrs.value(qualities).value>(); m_defaultPrintQuality = serverAttrs.value(defQuality).value(); if (m_supportedPrintQualities.size() == 0) { m_supportedPrintQualities.append(m_defaultPrintQuality); } } void Printer::updateLastMessage(const QMap &serverAttrs) { m_stateMessage = serverAttrs.value(QStringLiteral("StateMessage")).toString(); } void Printer::updateDeviceUri(const QMap &serverAttrs) { m_deviceUri = serverAttrs.value(QStringLiteral("DeviceUri")).toString(); } void Printer::updateCopies(const QMap &serverAttrs) { m_copies = serverAttrs.value(QStringLiteral("Copies")).toInt(); if (m_copies <= 0) m_copies = 1; } void Printer::updateShared(const QMap &serverAttrs) { m_shared = serverAttrs.value(QStringLiteral("Shared")).toBool(); } void Printer::loadAttributes() { auto opts = QStringList({ QStringLiteral("AcceptJobs"), QStringLiteral("DefaultColorModel"), QStringLiteral("SupportedColorModels"), QStringLiteral("DefaultPrintQuality"), QStringLiteral("SupportedPrintQualities"), QStringLiteral("StateMessage"), QStringLiteral("DeviceUri"), QStringLiteral("Copies"), QStringLiteral("Shared"), }); auto result = m_backend->printerGetOptions(name(), opts); updateAcceptJobs(result); updateColorModel(result); updatePrintQualities(result); updateLastMessage(result); updateDeviceUri(result); updateCopies(result); updateShared(result); } ColorModel Printer::defaultColorModel() const { return m_defaultColorModel; } QList Printer::supportedColorModels() const { return m_supportedColorModels; } PrintQuality Printer::defaultPrintQuality() const { return m_defaultPrintQuality; } QList Printer::supportedPrintQualities() const { return m_supportedPrintQualities; } QList Printer::supportedDuplexModes() const { return m_backend->supportedDuplexModes(); } QStringList Printer::supportedDuplexStrings() const { QStringList list; Q_FOREACH(const PrinterEnum::DuplexMode &mode, supportedDuplexModes()) { list << Utils::duplexModeToUIString(mode); } return list; } PrinterEnum::DuplexMode Printer::defaultDuplexMode() const { return m_backend->defaultDuplexMode(); } int Printer::printFile(const QString &filepath, const PrinterJob *options) { auto dest = m_backend->makeDest(name(), options); // options could be QMap ? qDebug() << "Going to print:" << filepath << options->title(); return m_backend->printFileToDest(filepath, options->title(), dest); } QString Printer::name() const { return m_backend->printerName(); } QString Printer::deviceUri() const { return m_deviceUri; } QString Printer::make() const { return m_backend->makeAndModel(); } QString Printer::description() const { return m_backend->description(); } QString Printer::location() const { return m_backend->location(); } QPageSize Printer::defaultPageSize() const { return m_backend->defaultPageSize(); } QList Printer::supportedPageSizes() const { return m_backend->supportedPageSizes(); } PrinterEnum::AccessControl Printer::accessControl() const { return PrinterEnum::AccessControl::AccessAllow; } PrinterEnum::ErrorPolicy Printer::errorPolicy() const { return PrinterEnum::ErrorPolicy::RetryOnError; } bool Printer::enabled() const { return state() != PrinterEnum::State::ErrorState; } PrinterEnum::State Printer::state() const { return m_backend->state(); } bool Printer::shared() const { return m_shared; } bool Printer::acceptJobs() const { return m_acceptJobs; } bool Printer::holdsDefinition() const { return m_backend->holdsDefinition(); } bool Printer::isRemote() const { return m_backend->isRemote(); } PrinterEnum::PrinterType Printer::type() const { return m_backend->type(); } int Printer::copies() const { return m_copies; } void Printer::setDefaultColorModel(const ColorModel &colorModel) { if (defaultColorModel() == colorModel) { return; } if (!supportedColorModels().contains(colorModel)) { qWarning() << Q_FUNC_INFO << "color model not supported"; return; } QStringList vals({colorModel.name}); m_backend->printerAddOption(name(), "ColorModel", vals); } void Printer::setDescription(const QString &description) { if (this->description() != description) { m_backend->printerSetInfo(name(), description); } } void Printer::setDefaultDuplexMode(const PrinterEnum::DuplexMode &duplexMode) { if (defaultDuplexMode() == duplexMode) { return; } if (!m_backend->supportedDuplexModes().contains(duplexMode)) { qWarning() << Q_FUNC_INFO << "duplex mode not supported" << duplexMode; return; } QStringList vals({Utils::duplexModeToPpdChoice(duplexMode)}); m_backend->printerAddOption(name(), "Duplex", vals); } void Printer::setEnabled(const bool enabled) { if (this->enabled() != enabled) { QString reply = m_backend->printerSetEnabled(name(), enabled); if (!reply.isEmpty()) { qWarning() << Q_FUNC_INFO << "failed to set enabled:" << reply; } m_backend->refresh(); } } void Printer::setAcceptJobs(const bool accepting) { if (this->acceptJobs() != accepting) { QString reply = m_backend->printerSetAcceptJobs(name(), accepting); if (!reply.isEmpty()) { qWarning() << Q_FUNC_INFO << "failed to set accepting:" << reply; } } } void Printer::setShared(const bool shared) { if (this->shared() != shared) { QString reply = m_backend->printerSetShared(name(), shared); if (!reply.isEmpty()) { qWarning() << Q_FUNC_INFO << "failed to set shared:" << reply; } } } void Printer::setDefaultPrintQuality(const PrintQuality &quality) { if (defaultPrintQuality() == quality) { return; } if (!supportedPrintQualities().contains(quality)) { qWarning() << Q_FUNC_INFO << "quality not supported."; return; } QStringList vals({quality.name}); m_backend->printerAddOption(name(), quality.originalOption, vals); } void Printer::setDefaultPageSize(const QPageSize &pageSize) { if (defaultPageSize() == pageSize) { return; } if (!m_backend->supportedPageSizes().contains(pageSize)) { qWarning() << Q_FUNC_INFO << "pagesize not supported."; return; } if (pageSize.key().isEmpty()) { qWarning() << Q_FUNC_INFO << "pagesize does not expose a ppd key."; return; } QStringList vals({pageSize.key()}); m_backend->printerAddOption(name(), "PageSize", vals); m_backend->refresh(); } void Printer::setCopies(const int &copies) { if (this->copies() == copies) { return; } m_backend->printerSetCopies(name(), copies); } QString Printer::lastMessage() const { return m_stateMessage; } QAbstractItemModel* Printer::jobs() { auto ret = &m_jobs; QQmlEngine::setObjectOwnership(ret, QQmlEngine::CppOwnership); return ret; } bool Printer::deepCompare(QSharedPointer other) const { // Return true if they are the same return defaultColorModel() == other->defaultColorModel() && defaultPrintQuality() == other->defaultPrintQuality() && description() == other->description() && defaultDuplexMode() == other->defaultDuplexMode() && defaultPageSize() == other->defaultPageSize() && type() == other->type() && acceptJobs() == other->acceptJobs() && enabled() == other->enabled() && state() == other->state() && lastMessage() == other->lastMessage() && deviceUri() == other->deviceUri() && shared() == other->shared() && copies() == other->copies() && isRemote() == other->isRemote(); } void Printer::updateFrom(QSharedPointer other) { PrinterBackend *tmp = m_backend; // Copy values from other printer which has been loaded in another thread // Note: do not use loadAttributes otherwise can cause UI block m_acceptJobs = other->m_acceptJobs; m_backend = other->m_backend; m_copies = other->m_copies; m_defaultColorModel = other->m_defaultColorModel; m_defaultPrintQuality = other->m_defaultPrintQuality; m_deviceUri = other->m_deviceUri; m_shared = other->m_shared; m_stateMessage = other->m_stateMessage; m_supportedColorModels = other->m_supportedColorModels; m_supportedPrintQualities = other->m_supportedPrintQualities; other->m_backend = tmp; } void Printer::onPrinterStateChanged( const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs) { Q_UNUSED(printerUri); Q_UNUSED(printerState); Q_UNUSED(printerStateReason); Q_UNUSED(acceptingJobs); if (name() == printerName) { m_stateMessage = text; } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/printer/printer.h000066400000000000000000000100141455543116500303620ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_PRINTERS_PRINTER_H #define USC_PRINTERS_PRINTER_H #include "printers_global.h" #include "backend/backend.h" #include "enums.h" #include "models/jobmodel.h" #include "printer/printerjob.h" #include "structs.h" #include #include #include #include #include #include #include class PrinterBackend; class PrinterJob; class PRINTERS_DECL_EXPORT Printer : public QObject { Q_OBJECT public: explicit Printer(PrinterBackend *backend, QObject *parent = nullptr); ~Printer(); bool enabled() const; ColorModel defaultColorModel() const; QList supportedColorModels() const; QList supportedDuplexModes() const; QStringList supportedDuplexStrings() const; PrinterEnum::DuplexMode defaultDuplexMode() const; QString name() const; QString deviceUri() const; QString make() const; PrintQuality defaultPrintQuality() const; QList supportedPrintQualities() const; QString description() const; QString location() const; QPageSize defaultPageSize() const; QList supportedPageSizes() const; PrinterEnum::AccessControl accessControl() const; PrinterEnum::ErrorPolicy errorPolicy() const; PrinterEnum::State state() const; bool shared() const; bool acceptJobs() const; bool holdsDefinition() const; bool isRemote() const; QString lastMessage() const; QAbstractItemModel* jobs(); int copies() const; PrinterEnum::PrinterType type() const; void setDefaultColorModel(const ColorModel &colorModel); void setDescription(const QString &description); void setDefaultDuplexMode(const PrinterEnum::DuplexMode &duplexMode); void setEnabled(const bool enabled); void setAcceptJobs(const bool accepting); void setShared(const bool shared); void setDefaultPrintQuality(const PrintQuality &quality); void setDefaultPageSize(const QPageSize &pageSize); void setJobModel(JobModel* jobModel); void setCopies(const int &copies); bool deepCompare(QSharedPointer other) const; void updateFrom(QSharedPointer other); public Q_SLOTS: int printFile(const QString &filepath, const PrinterJob *options); private Q_SLOTS: void onPrinterStateChanged( const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs ); private: void updateAcceptJobs(const QMap &serverAttrs); void updateColorModel(const QMap &serverAttrs); void updatePrintQualities(const QMap &serverAttrs); void updateLastMessage(const QMap &serverAttrs); void updateDeviceUri(const QMap &serverAttrs); void updateCopies(const QMap &serverAttrs); void updateShared(const QMap &serverAttrs); void loadAttributes(); JobFilter m_jobs; PrinterBackend *m_backend; ColorModel m_defaultColorModel; QList m_supportedColorModels; PrintQuality m_defaultPrintQuality; QList m_supportedPrintQualities; bool m_acceptJobs; bool m_shared; QString m_deviceUri; int m_copies; QString m_stateMessage; }; #endif // USC_PRINTERS_PRINTER_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/printer/printerjob.cpp000066400000000000000000000345671455543116500314330ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #include #include "backend/backend_cups.h" #include "models/printermodel.h" #include "printer/printerjob.h" #include "utils.h" PrinterJob::PrinterJob(QString printerName, PrinterBackend *backend, QObject *parent) : PrinterJob(printerName, backend, -1, parent) { } PrinterJob::PrinterJob(QString printerName, PrinterBackend *backend, int jobId, QObject *parent) : QObject(parent) , m_collate(true) , m_color_model(0) , m_completed_time(QDateTime()) , m_copies(1) , m_creation_time(QDateTime()) , m_backend(backend) , m_printerName(printerName) , m_duplex_mode(0) , m_impressions_completed(0) , m_is_two_sided(false) , m_job_id(jobId) , m_messages(QStringList()) , m_printer(QSharedPointer(Q_NULLPTR)) , m_print_range(QStringLiteral("")) , m_print_range_mode(PrinterEnum::PrintRange::AllPages) , m_processing_time(QDateTime()) , m_quality(0) , m_reverse(false) , m_size(0) , m_state(PrinterEnum::JobState::Pending) , m_title(QStringLiteral("")) , m_user("") { connect(this, SIGNAL(printerAboutToChange(QSharedPointer, QSharedPointer)), this, SLOT(onPrinterAboutToChange(QSharedPointer, QSharedPointer))); } PrinterJob::~PrinterJob() { } bool PrinterJob::collate() const { return m_collate; } int PrinterJob::colorModel() const { return m_color_model; } PrinterEnum::ColorModelType PrinterJob::colorModelType() const { return getColorModel().colorType; } QDateTime PrinterJob::completedTime() const { return m_completed_time; } int PrinterJob::copies() const { return m_copies; } QDateTime PrinterJob::creationTime() const { return m_creation_time; } int PrinterJob::duplexMode() const { return m_duplex_mode; } int PrinterJob::impressionsCompleted() const { return m_impressions_completed; } ColorModel PrinterJob::getColorModel() const { if (m_printer && colorModel() > -1 && colorModel() < m_printer->supportedColorModels().count()) { return m_printer->supportedColorModels().at(colorModel()); } else { return ColorModel(); } } PrintQuality PrinterJob::getPrintQuality() const { PrintQuality ret; if (m_printer && quality() > -1 && quality() < m_printer->supportedPrintQualities().count()) { ret = m_printer->supportedPrintQualities().at(quality()); } return ret; } PrinterEnum::DuplexMode PrinterJob::getDuplexMode() const { if (m_printer && duplexMode() > -1 && duplexMode() < m_printer->supportedDuplexModes().count()) { return m_printer->supportedDuplexModes().at(duplexMode()); } else { return PrinterEnum::DuplexMode::DuplexNone; } } bool PrinterJob::isTwoSided() const { return m_is_two_sided; } int PrinterJob::jobId() const { return m_job_id; } bool PrinterJob::landscape() const { return m_landscape; } void PrinterJob::loadAttributes(const QMap &attributes) { // Load the extra attributes for the job // NOTE: we don't need to type check them as they have been filtered for us setCollate(attributes.value("Collate").toBool()); setCopies(attributes.value("copies").toInt()); // No colorModel will result in PrinterJob using defaultColorModel QString colorModel = attributes.value("ColorModel").toString(); for (int i=0; i < m_printer->supportedColorModels().length(); i++) { if (m_printer->supportedColorModels().at(i).name == colorModel) { setColorModel(i); } } setCompletedTime(attributes.value("CompletedTime").toDateTime()); setCreationTime(attributes.value("CreationTime").toDateTime()); // No duplexMode will result in PrinterJob using defaultDuplexMode QString duplex = attributes.value("Duplex").toString(); PrinterEnum::DuplexMode duplexMode = Utils::ppdChoiceToDuplexMode(duplex); for (int i=0; i < m_printer->supportedDuplexModes().length(); i++) { if (m_printer->supportedDuplexModes().at(i) == duplexMode) { setDuplexMode(i); } } setImpressionsCompleted(attributes.value("impressionsCompleted").toInt()); setLandscape(attributes.value("landscape").toBool()); setMessages(attributes.value("messages").toStringList()); QStringList pageRanges = attributes.value("page-ranges").toStringList(); if (pageRanges.isEmpty()) { setPrintRangeMode(PrinterEnum::PrintRange::AllPages); setPrintRange(QStringLiteral("")); } else { setPrintRangeMode(PrinterEnum::PrintRange::PageRange); // Use groupSeparator as createSeparatedList adds "and" into the string setPrintRange(pageRanges.join(QLocale::system().groupSeparator())); } setProcessingTime(attributes.value("ProcessingTime").toDateTime()); // No quality will result in PrinterJob using defaultPrintQuality QString quality = attributes.value("quality").toString(); for (int i=0; i < m_printer->supportedPrintQualities().length(); i++) { if (m_printer->supportedPrintQualities().at(i).name == quality) { setQuality(i); } } setReverse(attributes.value("OutputOrder").toString() == "Reverse"); // If there was a state then set it if (attributes.contains("State")) { setState(static_cast(attributes.value("State").toInt())); } setSize(attributes.value("Size").toInt()); setUser(attributes.value("User").toString()); } void PrinterJob::loadDefaults() { if (!m_printer) { qWarning() << Q_FUNC_INFO << "Job can't load defaults from null printer."; return; } // Only load the defaults if this isn't a job in the queue (one which has a // jobId) as this is when user is making a job and has changed the printer if (jobId() <= 0) { setColorModel(m_printer->supportedColorModels().indexOf(m_printer->defaultColorModel())); setDuplexMode(m_printer->supportedDuplexModes().indexOf(m_printer->defaultDuplexMode())); setQuality(m_printer->supportedPrintQualities().indexOf(m_printer->defaultPrintQuality())); } } QStringList PrinterJob::messages() const { return m_messages; } QSharedPointer PrinterJob::printer() const { return m_printer; } QString PrinterJob::printerName() const { return m_printerName; } void PrinterJob::printFile(const QUrl &url) { if (m_printer) { m_job_id = m_printer->printFile(url.toLocalFile(), this); } else { qWarning() << "No valid printer in PrinterJob"; } } QString PrinterJob::printRange() const { return m_print_range; } PrinterEnum::PrintRange PrinterJob::printRangeMode() const { return m_print_range_mode; } QDateTime PrinterJob::processingTime() const { return m_processing_time; } int PrinterJob::quality() const { return m_quality; } bool PrinterJob::reverse() const { return m_reverse; } int PrinterJob::size() const { return m_size; } PrinterEnum::JobState PrinterJob::state() const { return m_state; } void PrinterJob::setCollate(const bool collate) { if (m_collate != collate) { m_collate = collate; Q_EMIT collateChanged(); } } void PrinterJob::setColorModel(const int colorModel) { if (m_color_model != colorModel) { m_color_model = colorModel; Q_EMIT colorModelChanged(); } // Always emit colorModeType changed, as the underlying model could have // changed but the int maybe the same // eg if it was RGB, KGray and m_color_model was 1, then changing to // KGray, RGB with m_color_model as 1, results in no change but colorModelType does. Q_EMIT colorModelTypeChanged(); } void PrinterJob::setCompletedTime(const QDateTime &completedTime) { if (m_completed_time != completedTime) { m_completed_time = completedTime; Q_EMIT completedTimeChanged(); } } void PrinterJob::setCopies(const int copies) { if (m_copies != copies) { if (copies > 0) { m_copies = copies; Q_EMIT copiesChanged(); } else { qWarning() << "Copies should be greater than 0."; } } } void PrinterJob::setCreationTime(const QDateTime &creationTime) { if (m_creation_time != creationTime) { m_creation_time = creationTime; Q_EMIT creationTimeChanged(); } } void PrinterJob::setDuplexMode(const int duplexMode) { if (m_duplex_mode != duplexMode) { m_duplex_mode = duplexMode; Q_EMIT duplexModeChanged(); } // Always try to set the duplexMode as this was an int and the underlying // model may be in a different order resulting in the same int being given setIsTwoSided(getDuplexMode() != PrinterEnum::DuplexMode::DuplexNone); } void PrinterJob::setIsTwoSided(const bool isTwoSided) { if (m_is_two_sided != isTwoSided) { m_is_two_sided = isTwoSided; Q_EMIT isTwoSidedChanged(); } } void PrinterJob::setImpressionsCompleted(const int &impressionsCompleted) { if (m_impressions_completed != impressionsCompleted) { m_impressions_completed = impressionsCompleted; Q_EMIT impressionsCompletedChanged(); } } void PrinterJob::setLandscape(const bool landscape) { if (m_landscape != landscape) { m_landscape = landscape; Q_EMIT landscapeChanged(); } } void PrinterJob::setMessages(const QStringList &messages) { if (m_messages != messages) { m_messages = messages; Q_EMIT messagesChanged(); } } void PrinterJob::setPrinter(QSharedPointer printer) { if (m_printer != printer) { Q_EMIT printerAboutToChange(m_printer, printer); m_printer = printer; if (printer->name() != m_printerName) { m_printerName = printer->name(); Q_EMIT printerNameChanged(); } // When the printer changes ensure we update any defaults loadDefaults(); Q_EMIT printerChanged(); } } void PrinterJob::setPrintRange(const QString &printRange) { if (m_print_range != printRange) { m_print_range = printRange; Q_EMIT printRangeChanged(); } } void PrinterJob::setPrintRangeMode(const PrinterEnum::PrintRange printRangeMode) { if (m_print_range_mode != printRangeMode) { m_print_range_mode = printRangeMode; Q_EMIT printRangeModeChanged(); } } void PrinterJob::setProcessingTime(const QDateTime &processingTime) { if (m_processing_time != processingTime) { m_processing_time = processingTime; Q_EMIT processingTimeChanged(); } } void PrinterJob::setQuality(const int quality) { if (m_quality != quality) { m_quality = quality; Q_EMIT qualityChanged(); } } void PrinterJob::setReverse(const bool reverse) { if (m_reverse != reverse) { m_reverse = reverse; Q_EMIT reverseChanged(); } } void PrinterJob::setSize(const int size) { if (m_size != size) { m_size = size; Q_EMIT sizeChanged(); } } void PrinterJob::setState(const PrinterEnum::JobState &state) { if (m_state != state) { m_state = state; Q_EMIT stateChanged(); } } void PrinterJob::setTitle(const QString &title) { if (m_title != title) { m_title = title; Q_EMIT titleChanged(); } } void PrinterJob::setUser(const QString &user) { if (m_user != user) { m_user = user; Q_EMIT userChanged(); } } QString PrinterJob::title() const { return m_title; } bool PrinterJob::deepCompare(QSharedPointer other) const { // jobId and printerName will be the same // Return true if they are the same return collate() == other->collate() && colorModel() == other->colorModel() && completedTime() == other->completedTime() && copies() == other->copies() && creationTime() == other->creationTime() && duplexMode() == other->duplexMode() && impressionsCompleted() == other->impressionsCompleted() && landscape() == other->landscape() && messages() == other->messages() && printRange() == other->printRange() && printRangeMode() == other->printRangeMode() && processingTime() == other->processingTime() && quality() == other->quality() && reverse() == other->reverse() && size() == other->size() && state() == other->state() && title() == other->title() && user() == other->user(); } void PrinterJob::updateFrom(QSharedPointer other) { setCollate(other->collate()); setColorModel(other->colorModel()); setCompletedTime(other->completedTime()); setCopies(other->copies()); setCreationTime(other->creationTime()); setDuplexMode(other->duplexMode()); setImpressionsCompleted(other->impressionsCompleted()); setLandscape(other->landscape()); setMessages(other->messages()); setPrintRange(other->printRange()); setPrintRangeMode(other->printRangeMode()); setProcessingTime(other->processingTime()); setQuality(other->quality()); setReverse(other->reverse()); setSize(other->size()); setState(other->state()); setTitle(other->title()); setUser(other->user()); } QString PrinterJob::user() const { return m_user; } void PrinterJob::onPrinterAboutToChange(QSharedPointer old, QSharedPointer replacement) { /* If we have an old printer, and the current copies value matches that of the old printer's, we'll use the new printer's copy value. The second case is if there was no old printer. */ bool haveOld = old && replacement && (copies() == old->copies()); bool noOld = !old && replacement; if (haveOld || noOld) { setCopies(replacement->copies()); } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/printer/printerjob.h000066400000000000000000000154441455543116500310710ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_PRINTERS_PRINTERJOB_H #define USC_PRINTERS_PRINTERJOB_H #include "printers_global.h" #include "enums.h" #include "structs.h" #include "backend/backend.h" #include "printer/printer.h" #include #include #include class Printer; class PrinterBackend; class PRINTERS_DECL_EXPORT PrinterJob : public QObject { Q_OBJECT Q_PROPERTY(bool collate READ collate WRITE setCollate NOTIFY collateChanged) Q_PROPERTY(int colorModel READ colorModel WRITE setColorModel NOTIFY colorModelChanged) Q_PROPERTY(PrinterEnum::ColorModelType colorModelType READ colorModelType NOTIFY colorModelTypeChanged) Q_PROPERTY(QDateTime completedTime READ completedTime NOTIFY completedTimeChanged) Q_PROPERTY(int copies READ copies WRITE setCopies NOTIFY copiesChanged) Q_PROPERTY(QDateTime creationTime READ creationTime NOTIFY creationTimeChanged) Q_PROPERTY(int duplexMode READ duplexMode WRITE setDuplexMode NOTIFY duplexModeChanged) Q_PROPERTY(int impressionsCompleted READ impressionsCompleted NOTIFY impressionsCompletedChanged) Q_PROPERTY(bool isTwoSided READ isTwoSided NOTIFY isTwoSidedChanged) Q_PROPERTY(bool landscape READ landscape WRITE setLandscape NOTIFY landscapeChanged) Q_PROPERTY(QStringList messages READ messages NOTIFY messagesChanged) Q_PROPERTY(QSharedPointer printer READ printer WRITE setPrinter NOTIFY printerChanged) Q_PROPERTY(QString printerName READ printerName NOTIFY printerNameChanged) Q_PROPERTY(QString printRange READ printRange WRITE setPrintRange NOTIFY printRangeChanged) Q_PROPERTY(PrinterEnum::PrintRange printRangeMode READ printRangeMode WRITE setPrintRangeMode NOTIFY printRangeModeChanged) Q_PROPERTY(QDateTime processingTime READ processingTime NOTIFY processingTimeChanged) Q_PROPERTY(int quality READ quality WRITE setQuality NOTIFY qualityChanged) Q_PROPERTY(bool reverse READ reverse WRITE setReverse NOTIFY reverseChanged) Q_PROPERTY(int size READ size NOTIFY sizeChanged) Q_PROPERTY(PrinterEnum::JobState state READ state NOTIFY stateChanged) Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged) Q_PROPERTY(QString user READ user NOTIFY userChanged) public: explicit PrinterJob(QString dest, PrinterBackend *backend, QObject *parent=Q_NULLPTR); explicit PrinterJob(QString dest, PrinterBackend *backend, int jobId, QObject *parent=Q_NULLPTR); ~PrinterJob(); bool collate() const; int colorModel() const; PrinterEnum::ColorModelType colorModelType() const; QDateTime completedTime() const; int copies() const; QDateTime creationTime() const; int duplexMode() const; int impressionsCompleted() const; bool isTwoSided() const; int jobId() const; bool landscape() const; QStringList messages() const; QSharedPointer printer() const; QString printerName() const; QString printRange() const; PrinterEnum::PrintRange printRangeMode() const; QDateTime processingTime() const; int quality() const; bool reverse() const; int size() const; PrinterEnum::JobState state() const; QString title() const; QString user() const; bool deepCompare(QSharedPointer other) const; public Q_SLOTS: PrinterEnum::DuplexMode getDuplexMode() const; ColorModel getColorModel() const; PrintQuality getPrintQuality() const; void loadAttributes(const QMap& attributes); void loadDefaults(); Q_INVOKABLE void printFile(const QUrl &url); void setCollate(const bool collate); void setColorModel(const int colorModel); void setCompletedTime(const QDateTime &completedTime); void setCopies(const int copies); void setCreationTime(const QDateTime &creationTime); void setDuplexMode(const int duplexMode); void setImpressionsCompleted(const int &impressionsCompleted); void setIsTwoSided(const bool isTwoSided); void setLandscape(const bool landscape); void setMessages(const QStringList &messages); void setPrinter(QSharedPointer printer); void setPrintRange(const QString &printRange); void setPrintRangeMode(const PrinterEnum::PrintRange printRangeMode); void setProcessingTime(const QDateTime &processingTime); void setQuality(const int quality); void setReverse(const bool reverse); void setSize(const int size); void setState(const PrinterEnum::JobState &state); void setTitle(const QString &title); void setUser(const QString &user); void updateFrom(QSharedPointer other); private Q_SLOTS: void onPrinterAboutToChange(QSharedPointer old, QSharedPointer replacement); Q_SIGNALS: void collateChanged(); void colorModelChanged(); void colorModelTypeChanged(); void completedTimeChanged(); void copiesChanged(); void creationTimeChanged(); void duplexModeChanged(); void impressionsCompletedChanged(); void isTwoSidedChanged(); void landscapeChanged(); void messagesChanged(); void printerAboutToChange(QSharedPointer old, QSharedPointer replacement); void printerChanged(); void printerNameChanged(); void printRangeChanged(); void printRangeModeChanged(); void processingTimeChanged(); void qualityChanged(); void reverseChanged(); void sizeChanged(); void stateChanged(); void titleChanged(); void userChanged(); private: bool m_collate; int m_color_model; QDateTime m_completed_time; int m_copies; QDateTime m_creation_time; PrinterBackend *m_backend; QString m_printerName; int m_duplex_mode; int m_impressions_completed; bool m_is_two_sided; int m_job_id; bool m_landscape; QStringList m_messages; QSharedPointer m_printer; QString m_print_range; PrinterEnum::PrintRange m_print_range_mode; QDateTime m_processing_time; int m_quality; bool m_reverse; int m_size; PrinterEnum::JobState m_state; QString m_title; QString m_user; }; #endif // USC_PRINTERS_PRINTERJOB_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/printer/signalratelimiter.cpp000066400000000000000000000054261455543116500327640ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "signalratelimiter.h" SignalRateLimiter::SignalRateLimiter(int triggerEventDelay, QObject *parent) : QObject(parent) { m_timer.setInterval(triggerEventDelay); connect(&m_timer, SIGNAL(timeout()), this, SLOT(process())); } SignalRateLimiter::~SignalRateLimiter() { } void SignalRateLimiter::process() { Q_FOREACH(auto printer, m_unprocessed) { Q_EMIT printerModified(printer); } m_unprocessed.clear(); m_timer.stop(); } void SignalRateLimiter::onPrinterModified( const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs) { Q_UNUSED(text); Q_UNUSED(printerUri); Q_UNUSED(printerState); Q_UNUSED(printerStateReason); Q_UNUSED(acceptingJobs); // Track when the first item was added to the unprocessed queue if (m_unprocessed.count() == 0) { m_unprocessed_time = QDateTime::currentDateTime(); } m_unprocessed << printerName; m_timer.start(); // Ensure that process is fired if we have reached four times // longer than the timer, this is due to many signals coming in rapidly if (m_unprocessed_time.msecsTo(QDateTime::currentDateTime()) > m_timer.interval() * 4) { process(); } } void SignalRateLimiter::onPrinterStateChanged( const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs) { Q_UNUSED(text); Q_UNUSED(printerUri); Q_UNUSED(printerState); Q_UNUSED(printerStateReason); Q_UNUSED(acceptingJobs); // Track when the first item was added to the unprocessed queue if (m_unprocessed.count() == 0) { m_unprocessed_time = QDateTime::currentDateTime(); } m_unprocessed << printerName; m_timer.start(); // Ensure that process is fired if we have reached four times // longer than the timer, this is due to many signals coming in rapidly if (m_unprocessed_time.msecsTo(QDateTime::currentDateTime()) > m_timer.interval() * 4) { process(); } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/printer/signalratelimiter.h000066400000000000000000000033011455543116500324170ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_SIGNAL_RATE_LIMITER_H #define USC_SIGNAL_RATE_LIMITER_H #include "printers_global.h" #include #include #include #include class PRINTERS_DECL_EXPORT SignalRateLimiter : public QObject { Q_OBJECT QTimer m_timer; QSet m_unprocessed; QDateTime m_unprocessed_time; public: explicit SignalRateLimiter(int triggerEventDelay = 500, QObject *parent = Q_NULLPTR); ~SignalRateLimiter(); public Q_SLOTS: void onPrinterModified( const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs ); void onPrinterStateChanged( const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs ); private Q_SLOTS: void process(); Q_SIGNALS: void printerModified(const QString &printerName); }; #endif // USC_SIGNAL_RATE_LIMITERR_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/printers/000077500000000000000000000000001455543116500267155ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/printers/printers.cpp000066400000000000000000000267271455543116500313050ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "backend/backend_cups.h" #include "i18n.h" #include "printers/printers.h" #include "cupsdnotifier.h" // Note: this file was generated. #include #include #include Printers::Printers(QObject *parent) : Printers(new PrinterCupsBackend(new IppClient(), QPrinterInfo(), new OrgCupsCupsdNotifierInterface("", CUPSD_NOTIFIER_DBUS_PATH, QDBusConnection::systemBus())), parent) { } Printers::Printers(PrinterBackend *backend, QObject *parent) : QObject(parent) , m_backend(backend) , m_devices(backend) , m_drivers(backend) , m_model(backend) , m_jobs(backend) { m_allPrinters.setSourceModel(&m_model); m_allPrinters.setSortRole(PrinterModel::Roles::DefaultPrinterRole); m_allPrinters.filterOnPdf(false); m_allPrinters.sort(0, Qt::DescendingOrder); m_allPrintersWithPdf.setSourceModel(&m_model); m_allPrintersWithPdf.setSortRole(PrinterModel::Roles::DefaultPrinterRole); m_allPrintersWithPdf.sort(0, Qt::DescendingOrder); // Let Qt be in charge of RAII. m_backend->setParent(this); connect(&m_drivers, SIGNAL(filterComplete()), this, SIGNAL(driverFilterChanged())); connect(&m_jobs, &QAbstractItemModel::rowsInserted, [this]( const QModelIndex &parent, int first, int) { int jobId = m_jobs.data(m_jobs.index(first, 0, parent), JobModel::Roles::IdRole).toInt(); QString printerName = m_jobs.data( m_jobs.index(first, 0, parent), JobModel::Roles::PrinterNameRole ).toString(); jobAdded(m_jobs.getJob(printerName, jobId)); }); // If the jobModel forces a refresh, load extended attributes for the job connect(&m_jobs, &JobModel::forceJobRefresh, [this]( const QString &printerName, const int jobId) { jobAdded(m_jobs.getJob(printerName, jobId)); }); connect(&m_model, &QAbstractItemModel::rowsInserted, [this]( const QModelIndex &parent, int first, int) { auto printer = m_model.data( m_model.index(first, 0, parent), PrinterModel::Roles::PrinterRole ).value>(); printerAdded(printer); }); // Assign jobmodels to printers right away. for (int i = 0; i < m_model.rowCount(); i++) { printerAdded(m_model.data( m_model.index(i, 0), PrinterModel::Roles::PrinterRole ).value>() ); } // Ensure existing jobs have been added, incase some were added before // the connect to rowsInserted was done for (int i = 0; i < m_jobs.rowCount(); i++) { jobAdded( m_jobs.getJob( m_jobs.data(m_jobs.index(i), JobModel::Roles::PrinterNameRole).toString(), m_jobs.data(m_jobs.index(i), JobModel::IdRole).toInt() ) ); } if (m_backend->type() == PrinterEnum::PrinterType::CupsType) { ((PrinterCupsBackend*) m_backend)->createSubscription(); } // Eagerly load the default printer. if (!m_backend->defaultPrinterName().isEmpty()) m_backend->requestPrinter(m_backend->defaultPrinterName()); } Printers::~Printers() { } QAbstractItemModel* Printers::allPrinters() { auto ret = &m_allPrinters; QQmlEngine::setObjectOwnership(ret, QQmlEngine::CppOwnership); return ret; } QAbstractItemModel* Printers::allPrintersWithPdf() { auto ret = &m_allPrintersWithPdf; QQmlEngine::setObjectOwnership(ret, QQmlEngine::CppOwnership); return ret; } QAbstractItemModel* Printers::remotePrinters() { /* Lazily initialize this model. Local printers are discerned from remotes by checking if they are remote. */ if (!m_remotePrinters.sourceModel()) { m_remotePrinters.setSourceModel(&m_model); m_remotePrinters.filterOnRemote(true); m_remotePrinters.filterOnPdf(false); m_remotePrinters.invalidate(); m_remotePrinters.sort(0, Qt::DescendingOrder); } auto ret = &m_remotePrinters; QQmlEngine::setObjectOwnership(ret, QQmlEngine::CppOwnership); return ret; } QAbstractItemModel* Printers::localPrinters() { /* Lazily initialize this model. Local printers are discerned from remotes by checking if they are remote. */ if (!m_localPrinters.sourceModel()) { m_localPrinters.setSourceModel(&m_model); m_localPrinters.filterOnRemote(false); m_localPrinters.filterOnPdf(false); m_localPrinters.setSortRole(PrinterModel::Roles::DefaultPrinterRole); m_localPrinters.invalidate(); m_localPrinters.sort(0, Qt::DescendingOrder); } auto ret = &m_localPrinters; QQmlEngine::setObjectOwnership(ret, QQmlEngine::CppOwnership); return ret; } QAbstractItemModel* Printers::printJobs() { auto ret = &m_jobs; QQmlEngine::setObjectOwnership(ret, QQmlEngine::CppOwnership); return ret; } QAbstractItemModel* Printers::drivers() { auto ret = &m_drivers; QQmlEngine::setObjectOwnership(ret, QQmlEngine::CppOwnership); return ret; } QAbstractItemModel* Printers::devices() { m_devices.load(); auto ret = &m_devices; QQmlEngine::setObjectOwnership(ret, QQmlEngine::CppOwnership); return ret; } QString Printers::driverFilter() const { return m_drivers.filter(); } void Printers::setDriverFilter(const QString &filter) { m_drivers.setFilter(filter); } QString Printers::defaultPrinterName() const { return m_backend->defaultPrinterName(); } QString Printers::lastMessage() const { return m_lastMessage; } PrinterJob* Printers::createJob(const QString &printerName) { // Note: If called by QML, it gains ownership of this job. return new PrinterJob(printerName, m_backend); } QAbstractItemModel* Printers::createJobFilter() { // Note: If called by QML, it gains ownership of the job filter. JobFilter *filter = new JobFilter(); filter->setSourceModel(&m_jobs); filter->setSortRole(JobModel::Roles::CreationTimeRole); filter->sort(0, Qt::AscendingOrder); return filter; } void Printers::cancelJob(const QString &printerName, const int jobId) { m_backend->cancelJob(printerName, jobId); } void Printers::holdJob(const QString &printerName, const int jobId) { m_backend->holdJob(printerName, jobId); } void Printers::releaseJob(const QString &printerName, const int jobId) { m_backend->releaseJob(printerName, jobId); } void Printers::setDefaultPrinterName(const QString &name) { QString reply = m_backend->printerSetDefault(name); if (!reply.isEmpty()) { m_lastMessage = reply; } } void Printers::prepareToAddPrinter() { if (m_drivers.rowCount() == 0) { m_drivers.load(); } } void Printers::searchForDevices() { m_devices.load(); } bool Printers::addPrinter(const QString &name, const QString &ppd, const QString &device, const QString &description, const QString &location) { bool setAsDefault = m_allPrinters.count() == 0; QString reply = m_backend->printerAdd(name, device, ppd, description, location); if (!reply.isEmpty()) { m_lastMessage = reply; return false; } provisionPrinter(name, setAsDefault); return true; } bool Printers::addPrinterWithPpdFile(const QString &name, const QString &ppdFileName, const QString &device, const QString &description, const QString &location) { bool setAsDefault = m_allPrinters.count() == 0; QString reply = m_backend->printerAddWithPpd(name, device, ppdFileName, description, location); if (!reply.isEmpty()) { m_lastMessage = reply; return false; } provisionPrinter(name, setAsDefault); return true; } void Printers::provisionPrinter(const QString &name, const bool setAsDefault) { // We mimic what System Config Printer does here. m_backend->printerSetEnabled(name, true); m_backend->printerSetAcceptJobs(name, true); if (setAsDefault) { setDefaultPrinterName(name); } } bool Printers::removePrinter(const QString &name) { QString reply = m_backend->printerDelete(name); if (!reply.isEmpty()) { m_lastMessage = reply; return false; } return true; } void Printers::jobAdded(QSharedPointer job) { auto printer = m_model.getPrinterByName(job->printerName()); // Check if we have a valid printer, does not need to be loaded as JobLoader // creates it's own Backend. if (printer && job) { // TODO: this printer may not be fully loaded // Which has the side affect of colorModel, duplex, quality not working // in PrinterJob as Printer::supportedColorModels etc fail // Potentially trigger loadPrinter and listen for the new printer? // Set the printer to the job m_jobs.updateJobPrinter(job, printer); // Trigger JobLoader to load extended attributes in the background m_backend->requestJobExtendedAttributes(printer, job); } } void Printers::printerAdded(QSharedPointer printer) { printer->setJobModel(&m_jobs); // Loop through jobs and associate a printer with it. for (int i = 0; i < m_jobs.rowCount(); i++) { QModelIndex idx = m_jobs.index(i, 0); QString printerName = m_jobs.data( idx, JobModel::Roles::PrinterNameRole ).toString(); int jobId = m_jobs.data(idx, JobModel::Roles::IdRole).toInt(); auto job = m_jobs.getJob(printerName, jobId); if (printerName == printer->name() && !job->printer()) { jobAdded(job); } } } void Printers::loadPrinter(const QString &name) { auto printer = m_model.getPrinterByName(name); if (!printer) { qWarning() << Q_FUNC_INFO << "no known printer named" << name; return; } if (printer->type() == PrinterEnum::PrinterType::ProxyType) { m_backend->requestPrinter(name); } } void Printers::printTestPage(const QString &name) { auto printer = m_model.getPrinterByName(name); if (!printer) { qWarning() << Q_FUNC_INFO << "no known printer named" << name; return; } auto page = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "cups/data/default-testpage.pdf", QStandardPaths::LocateFile); if (page.isEmpty()) { qCritical() << Q_FUNC_INFO << "Could not find test page."; return; } auto job = new PrinterJob(name, m_backend); job->setPrinter(printer); job->setTitle(__("Test page")); job->printFile(QUrl::fromLocalFile(page)); job->deleteLater(); } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/printers/printers.h000066400000000000000000000110171455543116500307340ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_PRINTERS_H #define USC_PRINTERS_H #include "printers_global.h" #include "models/devicemodel.h" #include "models/drivermodel.h" #include "models/printermodel.h" #include "printer/printer.h" #include #include #include #include #include #define CUPSD_NOTIFIER_DBUS_PATH "/org/cups/cupsd/Notifier" class PRINTERS_DECL_EXPORT Printers : public QObject { Q_OBJECT Q_PROPERTY(QAbstractItemModel* allPrinters READ allPrinters CONSTANT) Q_PROPERTY(QAbstractItemModel* allPrintersWithPdf READ allPrintersWithPdf CONSTANT) Q_PROPERTY(QAbstractItemModel* remotePrinters READ remotePrinters CONSTANT) Q_PROPERTY(QAbstractItemModel* localPrinters READ localPrinters CONSTANT) Q_PROPERTY(QAbstractItemModel* printJobs READ printJobs CONSTANT) Q_PROPERTY(QAbstractItemModel* drivers READ drivers CONSTANT) Q_PROPERTY(QAbstractItemModel* devices READ devices CONSTANT) Q_PROPERTY(QString driverFilter READ driverFilter WRITE setDriverFilter NOTIFY driverFilterChanged) Q_PROPERTY(QString defaultPrinterName READ defaultPrinterName WRITE setDefaultPrinterName NOTIFY defaultPrinterNameChanged) Q_PROPERTY(QString lastMessage READ lastMessage CONSTANT) public: explicit Printers(QObject *parent = Q_NULLPTR); // Note: Printers takes ownership of backend. explicit Printers(PrinterBackend *backend, QObject *parent = Q_NULLPTR); ~Printers(); QAbstractItemModel* allPrinters(); QAbstractItemModel* allPrintersWithPdf(); QAbstractItemModel* remotePrinters(); QAbstractItemModel* localPrinters(); QAbstractItemModel* printJobs(); QAbstractItemModel* drivers(); QAbstractItemModel* devices(); QString driverFilter() const; QString defaultPrinterName() const; QString lastMessage() const; void setDefaultPrinterName(const QString &name); void setDriverFilter(const QString &filter); public Q_SLOTS: PrinterJob* createJob(const QString &printerName); QAbstractItemModel* createJobFilter(); void cancelJob(const QString &printerName, const int jobId); void holdJob(const QString &printerName, const int jobId); void releaseJob(const QString &printerName, const int jobId); /* Instructs us to start loading drivers and what have you. In most cases, the user is likely to merely configure existing printers/jobs. Loading (at least) 12.000 drivers isn't relevant to those scenarios, so in order to add printers, this method should be called first. */ void prepareToAddPrinter(); // Starts a search for devices on local and remote resources. void searchForDevices(); bool addPrinter(const QString &name, const QString &ppd, const QString &device, const QString &description, const QString &location); bool addPrinterWithPpdFile(const QString &name, const QString &ppdFileName, const QString &device, const QString &description, const QString &location); bool removePrinter(const QString &name); // Instruct us to start (eagerly) loading a printer. void loadPrinter(const QString &name); void printTestPage(const QString &name); private Q_SLOTS: void jobAdded(QSharedPointer job); void printerAdded(QSharedPointer printer); Q_SIGNALS: void defaultPrinterNameChanged(); void driverFilterChanged(); private: void provisionPrinter(const QString &name, const bool setAsDefault); PrinterBackend *m_backend; DeviceModel m_devices; DriverModel m_drivers; PrinterModel m_model; JobModel m_jobs; PrinterFilter m_allPrinters; PrinterFilter m_allPrintersWithPdf; PrinterFilter m_remotePrinters; PrinterFilter m_localPrinters; PrinterFilter m_recentPrinters; QString m_lastMessage; }; #endif // USC_PRINTERS_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/printers_global.h000066400000000000000000000015021455543116500304040ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #if defined(UBUNTUCOMPONENTSEXTRASPRINTERS_LIBRARY) # define PRINTERS_DECL_EXPORT Q_DECL_EXPORT #else # define PRINTERS_DECL_EXPORT Q_DECL_IMPORT #endif lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/qmldir000066400000000000000000000001221455543116500262550ustar00rootroot00000000000000module Lomiri.Components.Extras.Printers plugin LomiriComponentsExtrasPrintersQml lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/structs.h000066400000000000000000000134021455543116500267270ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_PRINTERS_STRUCTS_H #define USC_PRINTERS_STRUCTS_H #include "enums.h" #include "i18n.h" #include #include #include struct ColorModel { public: QString name = QString(); // Gray, RGB, CMYK or anything [1], really. QString text = QString(); PrinterEnum::ColorModelType colorType = PrinterEnum::ColorModelType::UnknownType; QString originalOption = QString(); ColorModel() = default; ColorModel(const ColorModel&) = default; bool operator==(const ColorModel& a) const { return (name == a.name && originalOption == a.originalOption && text == a.text && colorType == a.colorType); } bool operator!=(const ColorModel& a) const { return !(*this == a); } void operator=(const ColorModel &m) { colorType = m.colorType; name = m.name; text = m.text; originalOption = m.originalOption; } }; // [1] https://www.cups.org/doc/ppd-compiler.html#COLOR struct PrintQuality { public: QString name = QString(); QString text = QString(); // PrintQuality, StpQuality, HPPrintQuality, etc. QString originalOption = QString(); bool operator==(const PrintQuality& a) const { return (name == a.name && originalOption == a.originalOption); } bool operator !=(const PrintQuality& a) const { return !(operator ==(a)); } }; struct PrinterDriver { public: QByteArray name; QByteArray deviceId; QByteArray language; QByteArray makeModel; QString toString() const { return QString("%1 [%2]").arg(QString::fromUtf8(makeModel)) .arg(QString::fromUtf8(language)); } }; struct Device { public: QString cls; QString id; QString info; QString makeModel; QString uri; QString location; PrinterEnum::DeviceType type() { #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) auto parts = uri.split(":", Qt::SkipEmptyParts); #else auto parts = uri.split(":", QString::SkipEmptyParts); #endif QString scheme = parts.size() > 0 ? parts[0] : QStringLiteral(""); if (scheme == QStringLiteral("dnssd")) return PrinterEnum::DeviceType::DNSSDType; else if (scheme == QStringLiteral("lpd")) return PrinterEnum::DeviceType::LPDType; else if (scheme == QStringLiteral("ipps")) return PrinterEnum::DeviceType::IppSType; else if (scheme == QStringLiteral("ipp14")) return PrinterEnum::DeviceType::Ipp14Type; else if (scheme == QStringLiteral("http")) return PrinterEnum::DeviceType::HttpType; else if (scheme == QStringLiteral("beh")) return PrinterEnum::DeviceType::BehType; else if (scheme == QStringLiteral("socket")) return PrinterEnum::DeviceType::SocketType; else if (scheme == QStringLiteral("https")) return PrinterEnum::DeviceType::HttpsType; else if (scheme == QStringLiteral("ipp")) return PrinterEnum::DeviceType::IppType; else if (scheme == QStringLiteral("hp")) return PrinterEnum::DeviceType::HPType; else if (scheme == QStringLiteral("usb")) return PrinterEnum::DeviceType::USBType; else if (scheme == QStringLiteral("hpfax")) return PrinterEnum::DeviceType::HPFaxType; else return PrinterEnum::DeviceType::UnknownType; } QString toString() const { /* 1. Split the id, which is of format "KEY:VAL; … KEYN:VALN;" into ["KEY:VAL", …, "KEYN:VALN"] 2. Split each pair into ["KEY", "VAL"] … ["KEYN", "VALN"]*/ QMap idMap; auto pairs = id.split(";"); Q_FOREACH(const QString &pair, pairs) { auto keyValue = pair.split(":"); /* Sometimes key,val pairs are not terminated by ";". We just use the first value in that case. E.g.: "MFG:HP MDL:Laserfjert;" Will give "HP" as MFG, and "" as MDL. */ if (keyValue.size() >= 2) { idMap[keyValue[0]] = keyValue[1]; } } auto mfg = idMap.value("MFG", ""); auto mdl = idMap.value("MDL", ""); /* If the MDL field contains CMD, somebody forgot to terminate, and we remove it. */ if (mdl.contains("CMD")) { mdl = mdl.split("CMD")[0]; } return QString("%1 %2").arg(mfg).arg(mdl); } bool operator==(const Device &other) { return ((cls == other.cls) && (id == other.id) && (info == other.info) && (makeModel == other.makeModel) && (uri == other.uri) && (location == other.location)); } }; Q_DECLARE_TYPEINFO(ColorModel, Q_PRIMITIVE_TYPE); Q_DECLARE_METATYPE(ColorModel) Q_DECLARE_TYPEINFO(PrintQuality, Q_PRIMITIVE_TYPE); Q_DECLARE_METATYPE(PrintQuality) Q_DECLARE_TYPEINFO(PrinterDriver, Q_MOVABLE_TYPE); Q_DECLARE_METATYPE(PrinterDriver) Q_DECLARE_METATYPE(QList) Q_DECLARE_TYPEINFO(Device, Q_MOVABLE_TYPE); Q_DECLARE_METATYPE(Device) #endif // USC_PRINTERS_STRUCTS_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/Printers/utils.h000066400000000000000000000066361455543116500263730ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_PRINTERS_UTILS_H #define USC_PRINTERS_UTILS_H #include "enums.h" #include "i18n.h" #include "structs.h" #include #include #include class Utils { public: static PrinterEnum::DuplexMode ppdChoiceToDuplexMode(const QString &choice) { if (choice == "DuplexTumble") return PrinterEnum::DuplexMode::DuplexShortSide; else if (choice == "DuplexNoTumble") return PrinterEnum::DuplexMode::DuplexLongSide; else return PrinterEnum::DuplexMode::DuplexNone; } static const QString duplexModeToPpdChoice(const PrinterEnum::DuplexMode &mode) { switch (mode) { case PrinterEnum::DuplexMode::DuplexShortSide: return "DuplexTumble"; case PrinterEnum::DuplexMode::DuplexLongSide: return "DuplexNoTumble"; case PrinterEnum::DuplexMode::DuplexNone: default: return "None"; } } static const QString duplexModeToUIString(const PrinterEnum::DuplexMode &mode) { switch (mode) { case PrinterEnum::DuplexMode::DuplexShortSide: return __("Short Edge (Flip)"); case PrinterEnum::DuplexMode::DuplexLongSide: return __("Long Edge (Standard)"); case PrinterEnum::DuplexMode::DuplexNone: default: return __("One Sided"); } } static PrinterEnum::DuplexMode qDuplexModeToDuplexMode(const QPrinter::DuplexMode &mode) { switch(mode) { case QPrinter::DuplexAuto: case QPrinter::DuplexLongSide: return PrinterEnum::DuplexMode::DuplexLongSide; case QPrinter::DuplexShortSide: return PrinterEnum::DuplexMode::DuplexShortSide; case QPrinter::DuplexNone: default: return PrinterEnum::DuplexMode::DuplexNone; } } static ColorModel parsePpdColorModel(const QString &name, const QString &text, const QString &optionName) { ColorModel ret; ret.name = name; ret.text = text; ret.originalOption = optionName; if (ret.name.contains("Gray") || ret.name.contains("Black")) { ret.colorType = PrinterEnum::ColorModelType::GrayType; } else { ret.colorType = PrinterEnum::ColorModelType::ColorType; } return ret; } static PrintQuality parsePpdPrintQuality(const QString &choice, const QString &text, const QString &optionName) { PrintQuality quality; quality.name = choice; quality.text = text; quality.originalOption = optionName; return quality; } }; #endif // USC_PRINTERS_UTILS_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/TabsBar.qml000066400000000000000000000421631455543116500253000ustar00rootroot00000000000000/* * Copyright (C) 2016, 2017 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authored-by: Florian Boucault * Andrew Hayzen */ import QtQuick 2.4 import QtQml.Models 2.2 import QtQuick.Window 2.2 import Lomiri.Components 1.3 import "TabsBar" as LocalTabs import Lomiri.Components.Extras 0.3 Item { id: tabsBar implicitWidth: units.gu(60) implicitHeight: units.gu(3) property color color: "white" property color backgroundColor: "white" property color foregroundColor: "black" property color contourColor: Qt.rgba(0.0, 0.0, 0.0, 0.2) property color actionColor: "black" property color highlightColor: Qt.rgba(actionColor.r, actionColor.g, actionColor.b, 0.1) /* 'model' needs to have the following members: property int selectedIndex function addExistingTab(var tab) function selectTab(int index) function removeTab(int index) function removeTabWithoutDestroying(int index) function moveTab(int from, int to) removeTabWithoutDestroying is useful when a tab is being removed due to moving, so you don't want the content to be destroyed */ property var model property list actions property bool dimmed: false /* To enable drag and drop set to enabled * * Use expose to set any information you need the DropArea to access * Then use drag.source.expose.myproperty * * Set mimeType to one of the keys in the DropArea's you want to accept * * Set a function for previewUrlFromIndex which is given the index * and returns a url to an image, which will be shown in the handle */ readonly property alias dragAndDrop: dragAndDropImpl LocalTabs.DragAndDropSettings { id: dragAndDropImpl } property string fallbackIcon: "" property Component windowFactory: null property var windowFactoryProperties: ({}) // any addition properties such as height, width signal contextMenu(var tabDelegate, int index) function iconNameFromModelItem(modelItem, index) { return ""; } function iconSourceFromModelItem(modelItem, index) { return ""; } function titleFromModelItem(modelItem) { return modelItem.title; } Rectangle { id: backgroundLeft anchors { left: parent.left top: parent.top bottom: parent.bottom } width: bottomContourLeft.width color: tabsBar.color } Rectangle { id: backgroundRight anchors { right: parent.right top: parent.top bottom: parent.bottom } width: bottomContourRight.width color: tabsBar.color } LocalTabs.TabStepper { id: leftStepper anchors { top: parent.top bottom: parent.bottom left: parent.left } layoutDirection: Qt.LeftToRight foregroundColor: tabsBar.foregroundColor contourColor: tabsBar.contourColor highlightColor: tabsBar.highlightColor counter: tabs.indexFirstVisibleItem active: tabs.overflow onClicked: { var nextInvisibleItem = tabs.indexFirstVisibleItem - 1; tabs.animatedPositionAtIndex(nextInvisibleItem); } } LocalTabs.TabStepper { id: rightStepper anchors { top: parent.top bottom: parent.bottom right: actions.left } layoutDirection: Qt.RightToLeft foregroundColor: tabsBar.foregroundColor contourColor: tabsBar.contourColor highlightColor: tabsBar.highlightColor counter: tabs.count - tabs.indexLastVisibleItem - 1 active: tabs.overflow onClicked: { var nextInvisibleItem = tabs.indexLastVisibleItem + 1; tabs.animatedPositionAtIndex(nextInvisibleItem); } } ListView { id: tabs anchors { top: parent.top bottom: parent.bottom left: tabs.overflow ? leftStepper.right : parent.left leftMargin: tabs.overflow ? 0 : units.gu(1) right: tabs.overflow ? rightStepper.left : actions.left } interactive: false objectName: "tabListView" orientation: ListView.Horizontal clip: true highlightMoveDuration: LomiriAnimation.FastDuration LomiriNumberAnimation { id: scrollAnimation; target: tabs; property: "contentX" } function animatedPositionAtIndex(index) { scrollAnimation.running = false; var pos = tabs.contentX; var destPos; tabs.positionViewAtIndex(index, ListView.Contain); destPos = tabs.contentX; scrollAnimation.from = pos; scrollAnimation.to = destPos; scrollAnimation.running = true; } property int indexFirstVisibleItem: indexAt(contentX+1, height / 2) property int indexLastVisibleItem: indexAt(contentX+width-1, height / 2) property real minimumTabWidth: units.gu(15) property int maximumTabsCount: Math.floor((tabsBar.width - actions.width - units.gu(1)) / minimumTabWidth) property real availableWidth: tabsBar.width - actions.width - units.gu(1) property real maximumTabWidth: availableWidth / tabs.count property bool overflow: tabs.count > maximumTabsCount displaced: Transition { LomiriNumberAnimation { property: "x" } } currentIndex: tabsBar.model.selectedIndex model: tabsBar.model delegate: MouseArea { id: tabMouseArea objectName: "tabDelegate" acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton width: tab.width height: tab.height drag { target: (tabs.count > 1 || dragAndDrop.enabled) && tab.isFocused ? tab : null axis: dragAndDrop.enabled ? Drag.XAndYAxis : Drag.XAxis minimumX: tab.isDragged ? -tab.width/2 : -Infinity maximumX: tab.isDragged ? tabs.width - tab.width/2 : Infinity } z: tab.isFocused ? 1 : 0 readonly property int tabIndex: index // for autopilot Binding { target: tabsBar property: "selectedTabX" value: tabs.x + tab.x + (tab.isDragged ? 0 : tabMouseArea.x - tabs.contentX) when: tab.isFocused } Binding { target: tabsBar property: "selectedTabWidth" value: tab.width when: tab.isFocused } NumberAnimation { id: resetVerticalAnimation target: tab duration: 250 property: "y" to: 0 } onPressed: { if (mouse.button === Qt.LeftButton) { tabsBar.model.selectTab(index) } else if (mouse.button === Qt.RightButton) { tabsBar.contextMenu(tabMouseArea, index) } else if (mouse.button === Qt.MiddleButton) { tabsBar.model.removeTab(index) } } onReleased: resetVerticalAnimation.start() onWheel: { if (wheel.angleDelta.y >= 0) { tabsBar.model.selectTab(tabsBar.model.selectedIndex - 1); } else { tabsBar.model.selectTab(tabsBar.model.selectedIndex + 1); } } hoverEnabled: true LocalTabs.Tab { id: tab objectName: "tabItem" anchors.left: tabMouseArea.left implicitWidth: tabs.availableWidth / 2 width: tabs.overflow ? tabs.availableWidth / tabs.maximumTabsCount : Math.min(tabs.maximumTabWidth, implicitWidth) height: tabs.height // Reference the tab and window so that the dropArea can determine what to do readonly property var thisTab: tabsBar.model.get(index) readonly property var thisWindow: dragAndDrop.thisWindow property bool isDragged: tabMouseArea.drag.active Drag.active: tab.isDragged Drag.source: tabMouseArea Drag.hotSpot.x: width / 2 Drag.hotSpot.y: height / 2 states: State { name: "dragging" when: tab.isDragged ParentChange { target: tab; parent: tabs } AnchorChanges { target: tab; anchors.left: undefined } } transitions: Transition { from: "dragging" ParentAnimation { NumberAnimation { property: "x" duration: LomiriAnimation.FastDuration easing: LomiriAnimation.StandardEasing } } AnchorAnimation { duration: LomiriAnimation.FastDuration easing: LomiriAnimation.StandardEasing } } fallbackIcon: tabsBar.fallbackIcon iconName: tabsBar.iconNameFromModelItem(typeof(modelData) === "undefined" ? model : modelData, index) iconSource: tabsBar.iconSourceFromModelItem(typeof(modelData) === "undefined" ? model : modelData, index) isHovered: tabMouseArea.containsMouse isFocused: tabsBar.model.selectedIndex == index isBeforeFocusedTab: index == tabsBar.model.selectedIndex - 1 title: tabsBar.titleFromModelItem(typeof(modelData) === "undefined" ? model : modelData) outsideColor: tabsBar.color backgroundColor: tabsBar.backgroundColor foregroundColor: tabsBar.foregroundColor contourColor: tabsBar.contourColor actionColor: tabsBar.actionColor highlightColor: tabsBar.highlightColor onClose: tabsBar.model.removeTab(index) } DropArea { anchors.fill: parent onEntered: { tabsBar.model.moveTab(drag.source.DelegateModel.itemsIndex, tabMouseArea.DelegateModel.itemsIndex) if (tabMouseArea.DelegateModel.itemsIndex == tabs.indexLastVisibleItem) { tabs.animatedPositionAtIndex(tabs.indexLastVisibleItem + 1); } else if (tabMouseArea.DelegateModel.itemsIndex == tabs.indexFirstVisibleItem) { tabs.animatedPositionAtIndex(tabs.indexFirstVisibleItem - 1); } } } DragHelper { id: dragHelper expectedAction: dragAndDrop.expectedAction mimeType: dragAndDrop.mimeType previewBorderWidth: dragAndDrop.previewBorderWidth previewSize: dragAndDrop.previewSize previewTopCrop: dragAndDrop.previewTopCrop previewUrl: dragAndDrop.previewUrlFromIndex(index) source: tab } onPositionChanged: { if (!dragAndDrop.enabled || !tabMouseArea.drag.active) { return; } // Keep the visual tab within maxYDiff of starting point when // dragging vertically so that it doesn't cover other elements // or appear to be detached tab.y = Math.abs(tab.y) > dragAndDrop.maxYDiff ? (tab.y > 0 ? 1 : -1) * dragAndDrop.maxYDiff : tab.y // Initiate drag and drop if mouse y has gone further than the height from the object if (mouse.y > height * 2 || mouse.y < -height) { // Reset visual position of tab delegate resetVerticalAnimation.start(); var dropAction = dragHelper.execDrag(index); // IgnoreAction - no DropArea accepted so New Window // MoveAction - DropArea accept but different window // CopyAction - DropArea accept but same window if (dropAction === Qt.MoveAction) { // Moved into another window // Just remove from model and do not destroy // as webview is used in other window tabsBar.model.removeTabWithoutDestroying(index); } else if (dropAction === Qt.CopyAction) { // Moved into the same window // So no action } else if (dropAction === Qt.IgnoreAction) { // Moved outside of any window // Create new window and add existing tab var window = windowFactory.createObject(null, windowFactoryProperties); window.model.addExistingTab(tab.thisTab); window.model.selectTab(window.model.count - 1); window.show(); // Just remove from model and do not destroy // as webview is used in other window tabsBar.model.removeTabWithoutDestroying(index); } else { // Unknown state console.debug("Unknown drop action:", dropAction); } } } } } property real selectedTabX property real selectedTabWidth Rectangle { id: bottomContourLeft anchors { left: parent.left bottom: parent.bottom } width: MathUtils.clamp(selectedTabX, leftStepper.width, parent.width - (actions.width + rightStepper.width)) height: units.dp(1) color: tabsBar.contourColor } Rectangle { id: bottomContourRight anchors { right: parent.right bottom: parent.bottom } width: MathUtils.clamp(parent.width - selectedTabX - selectedTabWidth, actions.width + rightStepper.width, parent.width - leftStepper.width) height: units.dp(1) color: tabsBar.contourColor } Row { id: actions anchors { top: parent.top bottom: parent.bottom right: parent.right } property real actionsSpacing: units.gu(1) property real sideMargins: units.gu(1) Repeater { id: actionsRepeater model: tabsBar.actions LocalTabs.TabButton { objectName: modelData.objectName iconColor: tabsBar.actionColor iconSource: modelData.iconSource onClicked: modelData.trigger() leftMargin: index == 0 ? actions.sideMargins : actions.actionsSpacing / 2.0 rightMargin: index == actionsRepeater.count - 1 ? actions.sideMargins : actions.actionsSpacing / 2.0 } } } Rectangle { anchors.fill: parent color: backgroundColor opacity: 0.4 visible: !Window.active || (dimmed && !dropArea.containsDrag) } DropArea { id: dropArea anchors { fill: parent } keys: [dragAndDrop.mimeType] onDropped: { // IgnoreAction - no DropArea accepted so New Window // MoveAction - DropArea accept but different window // CopyAction - DropArea accept but same window if (drag.source.thisWindow === dragAndDrop.thisWindow) { // Dropped in same window drop.accept(Qt.CopyAction); } else { // Dropped in new window, moving tab tabsBar.model.addExistingTab(drag.source.thisTab); tabsBar.model.selectTab(tabsBar.model.count - 1); drop.accept(Qt.MoveAction); } } onEntered: { thisWindow.raise() thisWindow.requestActivate(); } onPositionChanged: { if (drag.source.thisWindow === dragAndDrop.thisWindow) { // tab drag is within same window and in chrome // so reorder tabs by setting tab x position drag.source.x = drag.x - (drag.source.width / 2); } } } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/TabsBar/000077500000000000000000000000001455543116500245575ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/TabsBar/CMakeLists.txt000066400000000000000000000001441455543116500273160ustar00rootroot00000000000000file(GLOB QML_FILES *.qml *.js *.png) install(FILES ${QML_FILES} DESTINATION ${PLUGIN_DIR}/TabsBar) lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/TabsBar/DragAndDropSettings.qml000066400000000000000000000023321455543116500311400ustar00rootroot00000000000000/* * Copyright (C) 2016 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authored-by: Andrew Hayzen */ import QtQuick 2.4 QtObject { property bool enabled: false property var expectedAction: Qt.IgnoreAction | Qt.CopyAction | Qt.MoveAction property int maxYDiff: parent.height / 16 property string mimeType: "x-tabsbar/tab" property real previewBorderWidth: units.gu(1) property var previewSize: Qt.size(units.gu(35), units.gu(22.5)) property real previewTopCrop: 0 property var previewUrlFromIndex: function(index) { return ""; } property var thisWindow: null // Qt 5.7 retrieve from attached property } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/TabsBar/Tab.qml000066400000000000000000000116431455543116500260050ustar00rootroot00000000000000/* * Copyright (C) 2016 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authored-by: Florian Boucault * Andrew Hayzen */ import QtQuick 2.4 import Lomiri.Components 1.3 Item { id: tab property color outsideColor property color backgroundColor: "white" property color foregroundColor: "black" property color contourColor property color actionColor property color highlightColor property string title property bool isFocused property bool isBeforeFocusedTab property bool isHovered: false property string iconName: "" property url iconSource: "" property string fallbackIcon: "" signal close implicitHeight: units.gu(3) implicitWidth: units.gu(27) Rectangle { id: hoverFeedback anchors { fill: parent leftMargin: -tabSeparator.width } color: tab.highlightColor visible: tab.isHovered && !tab.isFocused opacity: visible ? 1.0 : 0.0 Behavior on opacity { LomiriNumberAnimation { duration: LomiriAnimation.FastDuration } } } Rectangle { anchors { top: parent.top bottom: tabContour.top left: parent.left right: parent.right } color: tab.outsideColor visible: tab.isFocused } TabContour { id: tabContour anchors { fill: parent topMargin: units.dp(2) } visible: tab.isFocused backgroundColor: tab.backgroundColor contourColor: tab.contourColor outsideColor: tab.outsideColor } Rectangle { id: tabSeparator anchors { right: parent.right verticalCenter: parent.verticalCenter } width: units.dp(1) height: units.gu(2) color: tab.contourColor visible: !tab.isFocused && !tab.isBeforeFocusedTab } MouseArea { id: tabCloseButton objectName: "tabCloseButton" anchors { top: parent.top bottom: parent.bottom left: parent.left } width: units.gu(3) hoverEnabled: true onClicked: tab.close() Rectangle { anchors.centerIn: parent property real size: units.gu(2) width: size height: size radius: size color: tab.highlightColor visible: tabCloseButton.containsMouse || tabCloseButton.pressed opacity: visible ? 1.0 : 0.0 Behavior on opacity { LomiriNumberAnimation { duration: LomiriAnimation.FastDuration } } } Icon { width: units.gu(1) height: width anchors.centerIn: parent asynchronous: true name: "close" color: tab.actionColor } } Loader { id: iconContainer active: iconName !== "" || iconSource.toString() !== "" || fallbackIcon !== "" anchors { left: tabCloseButton.right verticalCenter: parent.verticalCenter } asynchronous: true height: parent.height - units.gu(1) width: height visible: status === Loader.Ready Component.onCompleted: { setSource( Qt.resolvedUrl("TabIcon.qml"), { "iconName": Qt.binding(function() { return iconName; }), "iconSource": Qt.binding(function() { return iconSource; }), "fallbackIcon": Qt.binding(function() { return fallbackIcon; }) } ) } // When the tab is destroyed (as it is out of view) set the source // to empty, otherwise if the loader is still loading // the context doesn't exist and errors occur in the console Component.onDestruction: source = ""; } Label { textSize: Label.Small anchors { left: iconContainer.visible ? iconContainer.right : tabCloseButton.right leftMargin: iconContainer.visible ? units.gu(0.5) : 0 verticalCenter: parent.verticalCenter right: parent.right rightMargin: units.gu(0.5) } elide: Text.ElideRight text: tab.title color: tab.foregroundColor } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/TabsBar/TabButton.qml000066400000000000000000000034711455543116500272010ustar00rootroot00000000000000/* * Copyright (C) 2016 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authored-by: Florian Boucault */ import QtQuick 2.4 import Lomiri.Components 1.3 MouseArea { id: tabButton property alias iconName: icon.name property alias iconSource: icon.source property alias iconColor: icon.color property real iconSize: units.gu(2) property real leftMargin: 0 property real rightMargin: 0 anchors { top: parent.top bottom: parent.bottom } width: units.gu(3) + leftMargin + rightMargin Rectangle { anchors { top: parent.top bottom: parent.bottom horizontalCenter: icon.horizontalCenter } width: icon.width + Math.max(leftMargin, rightMargin) * 2.0 color: tabsBar.highlightColor visible: tabButton.pressed opacity: visible ? 1.0 : 0.0 Behavior on opacity { LomiriNumberAnimation { duration: LomiriAnimation.FastDuration } } } Icon { id: icon width: tabButton.iconSize height: tabButton.iconSize anchors { centerIn: parent horizontalCenterOffset: (leftMargin - rightMargin) / 2.0 } asynchronous: true } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/TabsBar/TabContour.qml000066400000000000000000000031051455543116500273510ustar00rootroot00000000000000/* * Copyright (C) 2016 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authored-by: Florian Boucault */ import QtQuick 2.4 import Lomiri.Components 1.3 Item { id: tabContour property color backgroundColor property color contourColor property color outsideColor TabContourHalf { anchors { top: parent.top bottom: parent.bottom left: parent.left } width: parent.width / 2 backgroundColor: tabContour.backgroundColor contourColor: tabContour.contourColor outsideColor: tabContour.outsideColor } TabContourHalf { anchors { top: parent.top bottom: parent.bottom right: parent.right } width: parent.width / 2 transform: Scale { origin.x: width/4; origin.y: 0; xScale: -1.0} backgroundColor: tabContour.backgroundColor contourColor: tabContour.contourColor outsideColor: tabContour.outsideColor } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/TabsBar/TabContourHalf.qml000066400000000000000000000042051455543116500301460ustar00rootroot00000000000000/* * Copyright (C) 2016 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authored-by: Florian Boucault */ import QtQuick 2.4 import Lomiri.Components 1.3 ShaderEffect { id: tabContour property Image source: Image { width: tabContour.width height: tabContour.height source: "tab_contour.png" fillMode: Image.Pad horizontalAlignment: Image.AlignLeft verticalAlignment: Image.AlignTop visible: false cache: true asynchronous: true } property color backgroundColor property color contourColor property color outsideColor property real sourceWidth: source.paintedWidth / tabContour.width property real sourceHeight: source.paintedHeight / tabContour.height fragmentShader: " varying highp vec2 qt_TexCoord0; uniform sampler2D source; uniform highp vec4 backgroundColor; uniform highp vec4 contourColor; uniform highp vec4 outsideColor; uniform lowp float qt_Opacity; uniform lowp float sourceWidth; uniform lowp float sourceHeight; void main() { lowp vec4 sourceColor = texture2D(source, vec2(qt_TexCoord0.x / sourceWidth, qt_TexCoord0.y / sourceHeight)); lowp vec4 backgroundMix = backgroundColor * sourceColor.r; lowp vec4 contourMix = contourColor * sourceColor.g; lowp vec4 outsideMix = outsideColor * sourceColor.b; gl_FragColor = (contourMix + backgroundMix * (1.0 - contourMix.a) + outsideMix * (1.0 - contourMix.a)) * qt_Opacity; }" } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/TabsBar/TabIcon.qml000066400000000000000000000031121455543116500266060ustar00rootroot00000000000000/* * Copyright (C) 2016 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authored-by: Florian Boucault * Andrew Hayzen */ import QtQuick 2.4 import Lomiri.Components 1.3 Item { id: tabIcon property string iconName property alias iconSource: image.source property alias fallbackIcon: fallbackIcon.name implicitHeight: units.gu(2) implicitWidth: units.gu(2) Component.onCompleted: image.completed = true Image { id: image anchors.fill: parent asynchronous: true fillMode: Image.PreserveAspectFit source: completed && tabIcon.iconName ? "image://theme/%1".arg(tabIcon.name) : "" sourceSize { height: tabIcon.height width: tabIcon.width } property bool completed: false } Icon { id: fallbackIcon anchors.fill: parent asynchronous: true visible: (image.status !== Image.Ready) || !image.source.toString() } }lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/TabsBar/TabStepper.qml000066400000000000000000000055211455543116500273460ustar00rootroot00000000000000/* * Copyright (C) 2016 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authored-by: Florian Boucault */ import QtQuick 2.4 import Lomiri.Components 1.3 AbstractButton { id: stepper property color backgroundColor property color foregroundColor property color contourColor property color highlightColor property int counter property int layoutDirection: Qt.LeftToRight property bool active enabled: counter > 0 opacity: active ? 1.0 : 0.0 width: active ? row.width + row.anchors.leftMargin + row.anchors.rightMargin : 0 Behavior on opacity { LomiriNumberAnimation { duration: LomiriAnimation.FastDuration } } Behavior on width { LomiriNumberAnimation { duration: LomiriAnimation.FastDuration } } activeFocusOnPress: false Timer { id: repeatClickTimer interval: 100 running: stepper.pressed repeat: true onTriggered: stepper.clicked() } Rectangle { anchors { top: parent.top bottom: parent.bottom } width: stepper.width color: stepper.highlightColor visible: stepper.pressed opacity: visible ? 1.0 : 0.0 Behavior on opacity { LomiriNumberAnimation { duration: LomiriAnimation.FastDuration } } } Row { id: row anchors { top: parent.top bottom: parent.bottom left: parent.left leftMargin: units.gu(1) } spacing: units.gu(1) LayoutMirroring.enabled: stepper.layoutDirection == Qt.RightToLeft LayoutMirroring.childrenInherit: true Icon { anchors.verticalCenter: parent.verticalCenter source: Qt.resolvedUrl("tab_stepper.png") color: enabled ? stepper.foregroundColor : stepper.contourColor scale: LayoutMirroring.enabled ? -1.0 : 1.0 asynchronous: true width: units.gu(1) } Label { anchors.verticalCenter: parent.verticalCenter textSize: Label.Small text: stepper.counter color: enabled ? stepper.foregroundColor : stepper.contourColor } Item { width: 1 height: 1 } } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/TabsBar/tab_contour@24.png000066400000000000000000000006271455543116500300570ustar00rootroot00000000000000PNG  IHDRw=bKGD pHYs  tIME3y$IDATH1JAɪk( `',Z\+VXxX-V!B҅t &>Ax0fa"|.lj^%Bρ@%Mt:_f!p~>tEwT}ш`<&HS(L+"\ HfSk|j.8.VK^Z\\CmlOFX[mg. > [sh8v 80Mu0p 6Ji@nV&u@< ޒ?,p ^9#FIENDB`lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/TabsBar/tab_stepper@27.png000066400000000000000000000010121455543116500300400ustar00rootroot00000000000000PNG  IHDR5sRGBIDATH cd"(,,涸yj[PP X4SfpYY/a* G\!''4h&@t@L555^@L Cmpmm)u llWUUI5'16C4877 êXf|bX 6aaajçYYY<"""e@ ȍO#!9@WZ]9&bYiU@ \h"F lbSZxB10GMސ&|@G9LQkk?~-@ɯ0qri $c`ϼ{ ( "bd2W*+`.&h0P#F0N}$ `y 3""P:hz_|eN/)Q1ElC_nFa +IENDB`lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/000077500000000000000000000000001455543116500245375ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/CMakeLists.txt000066400000000000000000000033211455543116500272760ustar00rootroot00000000000000include(FindPkgConfig) pkg_check_modules(EXIV2 REQUIRED exiv2) # photoeditor set(PLUGIN_SRC components.cpp ) set(EXAMPLE_PLUGIN_SRC example/example-model.cpp ) set(PHOTO_EDITOR_PLUGIN_SRC photoeditor/file-utils.cpp photoeditor/orientation.cpp photoeditor/photo-data.cpp photoeditor/photo-image-provider.cpp photoeditor/photo-metadata.cpp photoeditor/imaging.cpp photoeditor/photo-edit-thread.cpp ) set(TABS_BAR_PLUGIN_SRC tabsbar/drag-helper.cpp ) include_directories( ${CMAKE_BINARY_DIR} ) add_library(lomiri-ui-extras-plugin SHARED ${PLUGIN_SRC} ${PLUGIN_HDRS} ${EXAMPLE_PLUGIN_SRC} ${PHOTO_EDITOR_PLUGIN_SRC} ${TABS_BAR_PLUGIN_SRC}) target_link_libraries(lomiri-ui-extras-plugin ${EXIV2_LIBRARIES} Qt5::Core Qt5::Qml Qt5::Quick Qt5::Xml Qt5::Widgets ) set(QT_IMPORTS_DIR "${CMAKE_INSTALL_LIBDIR}/qt5/qml") set(PLUGIN_DIR ${QT_IMPORTS_DIR}/Lomiri/Components/Extras) install(TARGETS lomiri-ui-extras-plugin DESTINATION ${PLUGIN_DIR}) # copy the product of the build (plugin binary) to the test directory before # unit tests are run, so it can be loaded by them. # Also copy it one directory up so it can be loaded by autopilot tests when # running them uninstalled. add_custom_command( TARGET lomiri-ui-extras-plugin POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_BINARY_DIR}/tests/unittests/Lomiri/Components/Extras/) add_custom_command( TARGET lomiri-ui-extras-plugin POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ ../) lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/components.cpp000066400000000000000000000034471455543116500274400ustar00rootroot00000000000000/* * Copyright (C) 2012-2013, 2016 Canonical Ltd. * * 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; version 3. * * 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 . */ #include #include "components.h" #include "example/example-model.h" #include "photoeditor/photo-data.h" #include "photoeditor/photo-image-provider.h" #include "photoeditor/file-utils.h" #include "tabsbar/drag-helper.h" void Components::registerTypes(const char *uri) { // Example component qmlRegisterType(uri, 0, 2, "ExampleModel"); // PhotoEditor component qmlRegisterType(uri, 0, 2, "PhotoData"); qmlRegisterSingletonType(uri, 0, 2, "FileUtils", exportFileUtilsSingleton); // TabsBar component qmlRegisterType(uri, 0, 3, "DragHelper"); } void Components::initializeEngine(QQmlEngine *engine, const char *uri) { QQmlExtensionPlugin::initializeEngine(engine, uri); PhotoImageProvider* provider = new PhotoImageProvider(); engine->addImageProvider(PhotoImageProvider::PROVIDER_ID, provider); } QObject* Components::exportFileUtilsSingleton(QQmlEngine *engine, QJSEngine *scriptEngine) { Q_UNUSED(engine); Q_UNUSED(scriptEngine); return new FileUtils(); } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/components.h000066400000000000000000000021731455543116500271000ustar00rootroot00000000000000/* * Copyright (C) 2012-2013, 2016 Canonical Ltd. * * 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; version 3. * * 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 . */ #ifndef COMPONENTS_H #define COMPONENTS_H #include #include class Components : public QQmlExtensionPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") public: void registerTypes(const char *uri); void initializeEngine(QQmlEngine *engine, const char *uri); static QObject* exportFileUtilsSingleton(QQmlEngine *engine, QJSEngine *scriptEngine); }; #endif // COMPONENTS_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/example/000077500000000000000000000000001455543116500261725ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/example/example-model.cpp000066400000000000000000000030771455543116500314360ustar00rootroot00000000000000/* * Copyright 2013 Canonical Ltd. * * This file is part of lomiri-ui-extras. * * ubuntu-ui-extras 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; version 3. * * ubuntu-ui-extras 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 . */ #include "example-model.h" // Qt #include /*! \class Example Model \brief Example list model with a fixed number of items It's just an example of something implemented in c++ and exposed by a plugin. */ ExampleModel::ExampleModel(QObject* parent) : QAbstractListModel(parent) { } ExampleModel::~ExampleModel() { } QHash ExampleModel::roleNames() const { static QHash roles; if (roles.isEmpty()) { roles[Text] = "text"; } return roles; } int ExampleModel::rowCount(const QModelIndex& parent) const { Q_UNUSED(parent); return 3; } QVariant ExampleModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) { return QVariant(); } int row = index.row(); switch (role) { case Text: return QString("%1").arg(row); default: return QVariant(); } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/example/example-model.h000066400000000000000000000025511455543116500310770ustar00rootroot00000000000000/* * Copyright 2013 Canonical Ltd. * * This file is part of lomiri-ui-extras. * * ubuntu-ui-extras 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; version 3. * * ubuntu-ui-extras 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 . */ #ifndef __EXAMPLE_MODEL_H__ #define __EXAMPLE_MODEL_H__ // Qt #include #include class QQuickItem; class ExampleModel : public QAbstractListModel { Q_OBJECT Q_ENUMS(Roles) Q_PROPERTY(int count READ rowCount NOTIFY countChanged) public: ExampleModel(QObject* parent=0); ~ExampleModel(); enum Roles { Text = Qt::UserRole + 1 }; // reimplemented from QAbstractListModel QHash roleNames() const; int rowCount(const QModelIndex& parent=QModelIndex()) const; QVariant data(const QModelIndex& index, int role) const; Q_SIGNALS: void countChanged() const; }; #endif // __EXAMPLE_MODEL_H__ lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/photoeditor/000077500000000000000000000000001455543116500270775ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/photoeditor/file-utils.cpp000066400000000000000000000061541455543116500316660ustar00rootroot00000000000000/* * Copyright (C) 2014 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . */ #include "file-utils.h" #include #include #include #include #include FileUtils::FileUtils(QObject *parent) : QObject(parent) { } bool FileUtils::createDirectory(QString path) const { if (path.isEmpty()) return false; return QDir(path).mkpath("."); } QString FileUtils::createTemporaryDirectory(QString pathTemplate) const { QTemporaryDir dir(pathTemplate); if (!dir.isValid()) return QString(); dir.setAutoRemove(false); return dir.path(); } bool FileUtils::removeDirectory(QString path, bool recursive) const { if (path.isEmpty()) return false; QDir dir(path); return (recursive) ? dir.removeRecursively() : dir.rmdir("."); } bool FileUtils::remove(QString path) const { if (path.isEmpty()) return false; return QFile::remove(path); } bool FileUtils::copy(QString sourceFile, QString destinationFile) const { if (sourceFile.isEmpty() || destinationFile.isEmpty()) return false; if (QFileInfo(destinationFile).exists()) { QFile src(sourceFile); QFile dst(destinationFile); if (!src.open(QIODevice::ReadOnly) || !dst.open(QIODevice::WriteOnly)) { return false; } if (dst.write(src.readAll()) < 0) { return false; } src.close(); dst.close(); return true; } return QFile::copy(sourceFile, destinationFile); } bool FileUtils::rename(QString sourceFile, QString destinationFile) const { if (sourceFile.isEmpty() || destinationFile.isEmpty()) return false; if (QFileInfo(destinationFile).exists()) { QFile src(sourceFile); QFile dst(destinationFile); if (!src.open(QIODevice::ReadOnly) || !dst.open(QIODevice::WriteOnly)) { return false; } if (dst.write(src.readAll()) < 0) { return false; } src.close(); dst.close(); return QFile::remove(sourceFile); } return QFile::rename(sourceFile, destinationFile); } QString FileUtils::parentDirectory(QString path) const { if (QFileInfo(path).isDir()) { QDir dir(path); dir.cdUp(); return dir.absolutePath(); } else { return QFileInfo(path).dir().absolutePath(); } } QString FileUtils::nameFromPath(QString path) const { QString name = QFileInfo(path).fileName(); if (name.isEmpty()) name = QDir(path).dirName(); return name; } bool FileUtils::exists(QString path) const { return QFileInfo::exists(path); } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/photoeditor/file-utils.h000066400000000000000000000026111455543116500313250ustar00rootroot00000000000000/* * Copyright (C) 2014 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . */ #ifndef PHOTOUTILS_H #define PHOTOUTILS_H #include class FileUtils : public QObject { Q_OBJECT public: explicit FileUtils(QObject *parent = 0); Q_INVOKABLE bool createDirectory(QString path) const; Q_INVOKABLE bool removeDirectory(QString path, bool recursive = false) const; Q_INVOKABLE QString createTemporaryDirectory(QString pathTemplate) const; Q_INVOKABLE bool remove(QString path) const; Q_INVOKABLE bool copy(QString sourceFile, QString destinationFile) const; Q_INVOKABLE bool rename(QString sourceFile, QString destinationFile) const; Q_INVOKABLE QString parentDirectory(QString path) const; Q_INVOKABLE QString nameFromPath(QString path) const; Q_INVOKABLE bool exists(QString path) const; }; #endif // PHOTOUTILS_H lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/photoeditor/imaging.cpp000066400000000000000000000256341455543116500312300ustar00rootroot00000000000000/* * Copyright (C) 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authors: * Lucas Beeler */ #include #include #include "imaging.h" /*! * \brief HSVTransformation::transformPixel * \param pixel_color * \return */ QColor HSVTransformation::transformPixel(const QColor &pixel_color) const { QColor result; int h, s, v; pixel_color.getHsv(&h, &s, &v); v = remap_table_[v]; result.setHsv(h, s, v); return result; } /*! * \brief IntensityHistogram::IntensityHistogram * \param basis_image */ IntensityHistogram::IntensityHistogram(const QImage& basis_image) { for (int i = 0; i < 256; i++) m_counts[i] = 0; int width = basis_image.width(); int height = basis_image.height(); for (int j = 0; j < height; j++) { QApplication::processEvents(); for (int i = 0; i < width; i++) { QColor c = QColor(basis_image.pixel(i, j)); int intensity = c.value(); m_counts[intensity]++; } } float pixel_count = (float)(width * height); float accumulator = 0.0f; for (int i = 0; i < 256; i++) { m_probabilities[i] = ((float) m_counts[i]) / pixel_count; accumulator += m_probabilities[i]; m_cumulativeProbabilities[i] = accumulator; } } /*! * \brief IntensityHistogram::getCumulativeProbability * \param level * \return */ float IntensityHistogram::getCumulativeProbability(int level) { return m_cumulativeProbabilities[level]; } const float ToneExpansionTransformation::DEFAULT_LOW_DISCARD_MASS = 0.02f; const float ToneExpansionTransformation::DEFAULT_HIGH_DISCARD_MASS = 0.98f; /*! * \brief ToneExpansionTransformation::ToneExpansionTransformation * \param h * \param low_discard_mass * \param high_discard_mass */ ToneExpansionTransformation::ToneExpansionTransformation(IntensityHistogram h, float low_discard_mass, float high_discard_mass) { if (low_discard_mass == -1.0f) low_discard_mass = DEFAULT_LOW_DISCARD_MASS; if (high_discard_mass == -1.0f) high_discard_mass = DEFAULT_HIGH_DISCARD_MASS; m_lowDiscardMass = low_discard_mass; m_highDiscardMass = high_discard_mass; m_lowKink = 0; m_highKink = 255; while (h.getCumulativeProbability(m_lowKink) < low_discard_mass) m_lowKink++; while (h.getCumulativeProbability(m_highKink) > high_discard_mass) m_highKink--; m_lowKink = clampi(m_lowKink, 0, 255); m_highKink = clampi(m_highKink, 0, 255); buildRemapTable(); } /*! * \brief ToneExpansionTransformation::isIdentity * \return */ bool ToneExpansionTransformation::isIdentity() const { return ((m_lowKink == 0) && (m_highKink == 255)); } /*! * \brief ToneExpansionTransformation::buildRemapTable */ void ToneExpansionTransformation::buildRemapTable() { float low_kink_f = ((float) m_lowKink) / 255.0f; float high_kink_f = ((float) m_highKink) / 255.0f; float slope = 1.0f / (high_kink_f - low_kink_f); float intercept = -(low_kink_f / (high_kink_f - low_kink_f)); int i = 0; for ( ; i <= m_lowKink; i++) remap_table_[i] = 0; for ( ; i < m_highKink; i++) remap_table_[i] = (int) ((255.0f * (slope * (((float) i) / 255.0f) + intercept)) + 0.5); for ( ; i < 256; i++) remap_table_[i] = 255; } /*! * \brief ToneExpansionTransformation::lowDiscardMass * \return */ float ToneExpansionTransformation::lowDiscardMass() const { return m_lowDiscardMass; } /*! * \brief ToneExpansionTransformation::highDiscardMass * \return */ float ToneExpansionTransformation::highDiscardMass() const { return m_highDiscardMass; } /*! * \brief HermiteGammaApproximationFunction::HermiteGammaApproximationFunction * \param user_interval_upper */ HermiteGammaApproximationFunction::HermiteGammaApproximationFunction( float user_interval_upper) { m_nonzeroIntervalUpper = clampf(user_interval_upper, 0.1f, 1.0f); m_xScale = 1.0f / m_nonzeroIntervalUpper; } /*! * \brief HermiteGammaApproximationFunction::evaluate * \param x * \return */ float HermiteGammaApproximationFunction::evaluate(float x) { if (x < 0.0f) return 0.0f; else if (x > m_nonzeroIntervalUpper) return 0.0f; else { float indep_var = m_xScale * x; float dep_var = 6.0f * ((indep_var * indep_var * indep_var) - (2.0f * (indep_var * indep_var)) + (indep_var)); return clampf(dep_var, 0.0f, 1.0f); } } const float ShadowDetailTransformation::MAX_EFFECT_SHIFT = 0.5f; const float ShadowDetailTransformation::MIN_TONAL_WIDTH = 0.1f; const float ShadowDetailTransformation::MAX_TONAL_WIDTH = 1.0f; const float ShadowDetailTransformation::TONAL_WIDTH = 1.0f; /*! * \brief ShadowDetailTransformation::ShadowDetailTransformation * \param intensity */ ShadowDetailTransformation::ShadowDetailTransformation(float intensity) { m_intensity = intensity; float effect_shift = MAX_EFFECT_SHIFT * intensity; HermiteGammaApproximationFunction func = HermiteGammaApproximationFunction(TONAL_WIDTH); for (int i = 0; i < 256; i++) { float x = ((float) i) / 255.0f; float weight = func.evaluate(x); int remapped = (int) ((255.0f * (weight * (x + effect_shift)) + ((1.0f - weight) * x)) + 0.5f); remap_table_[i] = clampi(remapped, i, 255); } } /*! * \brief ShadowDetailTransformation::isIdentity * \return */ bool ShadowDetailTransformation::isIdentity() const { return (m_intensity == 0.0f); } const int AutoEnhanceTransformation::SHADOW_DETECT_MIN_INTENSITY = 2; const int AutoEnhanceTransformation::SHADOW_DETECT_MAX_INTENSITY = 90; const int AutoEnhanceTransformation::SHADOW_DETECT_INTENSITY_RANGE = AutoEnhanceTransformation::SHADOW_DETECT_MAX_INTENSITY - AutoEnhanceTransformation::SHADOW_DETECT_MIN_INTENSITY; const int AutoEnhanceTransformation::EMPIRICAL_DARK = 40; const float AutoEnhanceTransformation::SHADOW_AGGRESSIVENESS_MUL = 0.45f; /*! * \brief AutoEnhanceTransformation::AutoEnhanceTransformation * \param basis */ AutoEnhanceTransformation::AutoEnhanceTransformation(const QImage& basis) : m_shadowTransform(0), m_toneExpansionTransform(0) { IntensityHistogram histogram = IntensityHistogram(basis); /* compute the percentage of pixels in the image that fall into the shadow range -- this measures "of the pixels in the image, how many of them are in shadow?" */ float pct_in_range = 100.0f * (histogram.getCumulativeProbability(SHADOW_DETECT_MAX_INTENSITY) - histogram.getCumulativeProbability(SHADOW_DETECT_MIN_INTENSITY)); /* compute the mean intensity of the pixels that are in the shadow range -- this measures "of those pixels that are in shadow, just how dark are they?" */ float sh_prob_mu = (histogram.getCumulativeProbability(SHADOW_DETECT_MIN_INTENSITY) + histogram.getCumulativeProbability(SHADOW_DETECT_MAX_INTENSITY)) * 0.5f; int sh_intensity_mu = SHADOW_DETECT_MIN_INTENSITY; for ( ; sh_intensity_mu <= SHADOW_DETECT_MAX_INTENSITY; sh_intensity_mu++) { if (histogram.getCumulativeProbability(sh_intensity_mu) >= sh_prob_mu) break; } /* if more than 30 percent of the pixels in the image are in the shadow detection range, or if the mean intensity within the shadow range is less than an empirically determined threshold below which pixels appear very dark, regardless of the percent of pixels in it, then perform shadow detail enhancement. Otherwise, skip shadow detail enhancement and perform contrast expansion only */ if ((pct_in_range > 30.0f) || ((pct_in_range > 10.0f) && (sh_intensity_mu < EMPIRICAL_DARK))) { float shadow_trans_effect_size = ((((float) SHADOW_DETECT_MAX_INTENSITY) - ((float) sh_intensity_mu)) / ((float) SHADOW_DETECT_INTENSITY_RANGE)); shadow_trans_effect_size *= SHADOW_AGGRESSIVENESS_MUL; m_shadowTransform = new ShadowDetailTransformation(shadow_trans_effect_size); QImage shadow_corrected_image = QImage(basis); // Can't write into indexed images, due to a limitation in Qt. if (shadow_corrected_image.format() == QImage::Format_Indexed8) shadow_corrected_image = shadow_corrected_image.convertToFormat( QImage::Format_RGB32); for (int j = 0; j < shadow_corrected_image.height(); j++) { QApplication::processEvents(); for (int i = 0; i < shadow_corrected_image.width(); i++) { QColor px = m_shadowTransform->transformPixel( QColor(shadow_corrected_image.pixel(i, j))); shadow_corrected_image.setPixel(i, j, px.rgb()); } } m_toneExpansionTransform = new ToneExpansionTransformation( IntensityHistogram(shadow_corrected_image), 0.005f, 0.995f); } else { m_toneExpansionTransform = new ToneExpansionTransformation( IntensityHistogram(basis)); } } /*! * \brief AutoEnhanceTransformation::~AutoEnhanceTransformation */ AutoEnhanceTransformation::~AutoEnhanceTransformation() { if (m_shadowTransform) delete m_shadowTransform; delete m_toneExpansionTransform; } /*! * \brief AutoEnhanceTransformation::transformPixel * \param pixel_color * \return */ QColor AutoEnhanceTransformation::transformPixel( const QColor& pixel_color) const { QColor px = pixel_color; if (m_shadowTransform) px = m_shadowTransform->transformPixel(px); px = m_toneExpansionTransform->transformPixel(px); /* if tone expansion occurs, boost saturation to compensate for boosted dynamic range */ if (!m_toneExpansionTransform->isIdentity()) { int h, s, v; px.getHsv(&h, &s, &v); float compensation_multiplier = (m_toneExpansionTransform->lowDiscardMass() < 0.01f) ? 1.02f : 1.10f; s = (int) (((float) s) * compensation_multiplier); s = clampi(s, 0, 255); px.setHsv(h, s, v); } return px; } bool AutoEnhanceTransformation::isIdentity() const { return false; } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/photoeditor/imaging.h000066400000000000000000000074701455543116500306730ustar00rootroot00000000000000/* * Copyright (C) 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authors: * Lucas Beeler */ #ifndef GALLERY_UTIL_IMAGING_H_ #define GALLERY_UTIL_IMAGING_H_ #include #include #include /*! * \brief clampi * \param i * \param min * \param max * \return */ inline int clampi(int i, int min, int max) { return (i < min) ? min : ((i > max) ? max : i); } /*! * \brief clampf * \param x * \param min * \param max * \return */ inline float clampf(float x, float min, float max) { return (x < min) ? min : ((x > max) ? max : x); } /*! * \brief The HSVTransformation class */ class HSVTransformation { public: HSVTransformation() { } virtual ~HSVTransformation() { } virtual QColor transformPixel(const QColor& pixel_color) const; virtual bool isIdentity() const = 0; protected: int remap_table_[256]; }; /*! * \brief The IntensityHistogram class */ class IntensityHistogram { public: IntensityHistogram(const QImage& basis_image); virtual ~IntensityHistogram() { } float getCumulativeProbability(int level); private: int m_counts[256]; float m_probabilities[256]; float m_cumulativeProbabilities[256]; }; /*! * \brief The ToneExpansionTransformation class */ class ToneExpansionTransformation : public virtual HSVTransformation { static const float DEFAULT_LOW_DISCARD_MASS; static const float DEFAULT_HIGH_DISCARD_MASS; public: ToneExpansionTransformation(IntensityHistogram h, float lowDiscardMass = -1.0f, float highDiscardMass = -1.0f); virtual ~ToneExpansionTransformation() { } bool isIdentity() const; float lowDiscardMass() const; float highDiscardMass() const; private: void buildRemapTable(); int m_lowKink; int m_highKink; float m_lowDiscardMass; float m_highDiscardMass; }; /*! * \brief The HermiteGammaApproximationFunction class */ class HermiteGammaApproximationFunction { public: HermiteGammaApproximationFunction(float user_interval_upper); virtual ~HermiteGammaApproximationFunction() { } float evaluate(float x); private: float m_xScale; float m_nonzeroIntervalUpper; }; /*! * \brief The ShadowDetailTransformation class */ class ShadowDetailTransformation : public virtual HSVTransformation { static const float MAX_EFFECT_SHIFT; static const float MIN_TONAL_WIDTH; static const float MAX_TONAL_WIDTH; static const float TONAL_WIDTH; public: ShadowDetailTransformation(float intensity); bool isIdentity() const; private: float m_intensity; }; /*! * \brief The AutoEnhanceTransformation class */ class AutoEnhanceTransformation : public virtual HSVTransformation { static const int SHADOW_DETECT_MIN_INTENSITY; static const int SHADOW_DETECT_MAX_INTENSITY; static const int SHADOW_DETECT_INTENSITY_RANGE; static const int EMPIRICAL_DARK; static const float SHADOW_AGGRESSIVENESS_MUL; public: AutoEnhanceTransformation(const QImage& basis_image); virtual ~AutoEnhanceTransformation(); QColor transformPixel(const QColor& pixel_color) const; bool isIdentity() const; private: ShadowDetailTransformation* m_shadowTransform; ToneExpansionTransformation* m_toneExpansionTransform; }; #endif // GALLERY_UTIL_IMAGING_H_ lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/photoeditor/orientation.cpp000066400000000000000000000100411455543116500321320ustar00rootroot00000000000000/* * Copyright (C) 2011 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authors: * Lucas Beeler */ #include #include "orientation.h" /*! * \brief OrientationCorrection::fromOrientation * \param o * \return */ OrientationCorrection OrientationCorrection::fromOrientation(Orientation o) { double rotation_angle = 0.0; double horizontal_scale_factor = 1.0; switch (o) { case TOP_RIGHT_ORIGIN: horizontal_scale_factor = -1.0; break; case BOTTOM_RIGHT_ORIGIN: rotation_angle = 180.0; break; case BOTTOM_LEFT_ORIGIN: horizontal_scale_factor = -1.0; rotation_angle = 180.0; break; case LEFT_TOP_ORIGIN: horizontal_scale_factor = -1.0; rotation_angle = -90.0; break; case RIGHT_TOP_ORIGIN: rotation_angle = 90.0; break; case RIGHT_BOTTOM_ORIGIN: horizontal_scale_factor = -1.0; rotation_angle = 90.0; break; case LEFT_BOTTOM_ORIGIN: rotation_angle = -90.0; break; default: ; // do nothing break; } return OrientationCorrection(rotation_angle, horizontal_scale_factor); } /*! * \brief OrientationCorrection::identity * \return */ OrientationCorrection OrientationCorrection::identity() { return OrientationCorrection(0.0, 1.0); } /*! * \brief OrientationCorrection::rotateOrientation * \param orientation * \param left * \return */ Orientation OrientationCorrection::rotateOrientation(Orientation orientation, bool left) { QVector sequence_a; QVector sequence_b; sequence_a << TOP_LEFT_ORIGIN << LEFT_BOTTOM_ORIGIN << BOTTOM_RIGHT_ORIGIN << RIGHT_TOP_ORIGIN; sequence_b << TOP_RIGHT_ORIGIN << RIGHT_BOTTOM_ORIGIN << BOTTOM_LEFT_ORIGIN << LEFT_TOP_ORIGIN; const QVector& sequence = ( sequence_a.contains(orientation) ? sequence_a : sequence_b); int current = sequence.indexOf(orientation); int jump = (left ? 1 : sequence.count() - 1); int next = (current + jump) % sequence.count(); return sequence[next]; } /*! * \brief OrientationCorrection::toTransform * Returns the correction as a QTransform. * \return Returns the correction as a QTransform. */ QTransform OrientationCorrection::toTransform() const { QTransform result; result.scale(m_horizontalScaleFactor, 1.0); result.rotate(m_rotationAngle); return result; } /*! * \brief OrientationCorrection::isFlippedFrom * Returns whether the two orientations are flipped relative to each other. * Ignores rotation_angle; only checks horizontal_scale_factor_. * \param other * \return */ bool OrientationCorrection::isFlippedFrom( const OrientationCorrection& other) const { return (m_horizontalScaleFactor != other.m_horizontalScaleFactor); } /*! * \brief OrientationCorrection::getNormalizedRotationDifference * Returns the rotation difference in degrees (this - other), normalized to * 0, 90, 180, or 270. Ignores the horizontal_scale_factor_. * \param other * \return */ int OrientationCorrection::getNormalizedRotationDifference( const OrientationCorrection& other) const { int degrees_rotation = (int)m_rotationAngle - (int)other.m_rotationAngle; if (degrees_rotation < 0) degrees_rotation += 360; Q_ASSERT(degrees_rotation == 0 || degrees_rotation == 90 || degrees_rotation == 180 || degrees_rotation == 270); return degrees_rotation; } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/photoeditor/orientation.h000066400000000000000000000035021455543116500316030ustar00rootroot00000000000000/* * Copyright (C) 2011 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authors: * Lucas Beeler */ #ifndef GALLERY_ORIENTATION_H_ #define GALLERY_ORIENTATION_H_ #include enum Orientation { ORIGINAL_ORIENTATION = 0, MIN_ORIENTATION = 1, TOP_LEFT_ORIGIN = 1, TOP_RIGHT_ORIGIN = 2, BOTTOM_RIGHT_ORIGIN = 3, BOTTOM_LEFT_ORIGIN = 4, LEFT_TOP_ORIGIN = 5, RIGHT_TOP_ORIGIN = 6, RIGHT_BOTTOM_ORIGIN = 7, LEFT_BOTTOM_ORIGIN = 8, MAX_ORIENTATION = 8 }; /*! * \brief The OrientationCorrection struct */ class OrientationCorrection { public: static OrientationCorrection fromOrientation(Orientation o); static OrientationCorrection identity(); static Orientation rotateOrientation(Orientation orientation, bool left); QTransform toTransform() const; bool isFlippedFrom(const OrientationCorrection& other) const; int getNormalizedRotationDifference(const OrientationCorrection& other) const; private: OrientationCorrection(double rotation_angle, double horizontal_scale_factor) : m_rotationAngle(rotation_angle), m_horizontalScaleFactor(horizontal_scale_factor) { } const double m_rotationAngle; const double m_horizontalScaleFactor; }; #endif // GALLERY_ORIENTATION_H_ lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/photoeditor/photo-caches.cpp000066400000000000000000000103731455543116500321640ustar00rootroot00000000000000/* * Copyright (C) 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authors: * Charles Lindsay */ #include "photo-caches.h" #include #include const QString PhotoCaches::ORIGINAL_DIR = ".original"; const QString PhotoCaches::ENHANCED_DIR = ".enhanced"; /*! * \brief PhotoCaches::PhotoCaches * \param file */ PhotoCaches::PhotoCaches(const QFileInfo& file) : m_file(file), m_originalFile(file.dir(), QString("%1/%2").arg(ORIGINAL_DIR).arg(file.fileName())), m_enhancedFile(file.dir(), QString("%1/%2").arg(ENHANCED_DIR).arg(file.fileName())) { // We always want our file checks to hit the disk. m_file.setCaching(false); m_originalFile.setCaching(false); m_enhancedFile.setCaching(false); } /*! * \brief PhotoCaches::hasCachedOriginal * \return */ bool PhotoCaches::hasCachedOriginal() const { return m_originalFile.exists(); } /*! * \brief PhotoCaches::hasCachedEnhanced * \return */ bool PhotoCaches::hasCachedEnhanced() const { return m_enhancedFile.exists(); } /*! * \brief PhotoCaches::originalFile * \return */ const QFileInfo& PhotoCaches::originalFile() const { return m_originalFile; } /*! * \brief PhotoCaches::enhancedFile * \return */ const QFileInfo& PhotoCaches::enhancedFile() const { return m_enhancedFile; } /*! * \brief PhotoCaches::pristineFile * Returns original_file() if it exists; otherwise, returns the file passed * to the constructor. * \return */ const QFileInfo& PhotoCaches::pristineFile() const { return (hasCachedOriginal() ? m_originalFile : m_file); } /*! * \brief PhotoCaches::cacheOriginal * Moves the pristine file into .original so we don't mess it up. Note that * this potentially removes the main file, so it must be followed by a copy * from original (or elsewhere) back to the file. * \return */ bool PhotoCaches::cacheOriginal() { if (hasCachedOriginal()) { return true; } m_file.dir().mkdir(ORIGINAL_DIR); return rename(m_file, m_originalFile); } /*! * \brief PhotoCaches::restoreOriginal * Moves the file out of .original, overwriting the main file. Note that * this removes the .original file. * \return */ bool PhotoCaches::restoreOriginal() { if (!hasCachedOriginal()) { return true; } remove(m_file); // touch the file so that the thumbnails will correctly regenerate utime(m_originalFile.absoluteFilePath().toUtf8(), NULL); return rename(m_originalFile, m_file); } /*! * \brief PhotoCaches::cacheEnhancedFromOriginal * Copies the file in .original to .enhanced so it can then be enhanced. * \return */ bool PhotoCaches::cacheEnhancedFromOriginal() { m_file.dir().mkdir(ENHANCED_DIR); // If called subsequently, the previously cached version is replaced. remove(m_enhancedFile); return copy(pristineFile(), m_enhancedFile); } /*! * \brief PhotoCaches::overwriteFromCache * Tries to overwrite the file from one of its cached versions. * \param preferEnhanced * \return */ bool PhotoCaches::overwriteFromCache(bool preferEnhanced) { if (preferEnhanced && hasCachedEnhanced()) { remove(m_file); return copy(m_enhancedFile, m_file); } else if (hasCachedOriginal()) { remove(m_file); return copy(m_originalFile, m_file); } else { return true; } } /*! * \brief PhotoCaches::discardCachedOriginal */ void PhotoCaches::discardCachedOriginal() { remove(m_originalFile); } /*! * \brief PhotoCaches::discardCachedEnhanced */ void PhotoCaches::discardCachedEnhanced() { remove(m_enhancedFile); } /*! * \brief PhotoCaches::discardAll */ void PhotoCaches::discardAll() { discardCachedOriginal(); discardCachedEnhanced(); } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/photoeditor/photo-caches.h000066400000000000000000000044411455543116500316300ustar00rootroot00000000000000/* * Copyright (C) 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authors: * Charles Lindsay */ #ifndef GALLERY_PHOTO_CACHES_H_ #define GALLERY_PHOTO_CACHES_H_ #include #include #include /*! * \brief The PhotoCaches class * * An abstraction around the various files we keep in addition to the photo * file itself: the original, the pristine version of the file without any * applied edits; and the enhanced, a version of the original with auto-enhance * applied to it (necessary because of how slow auto-enhance is). */ class PhotoCaches { public: static const QString ORIGINAL_DIR; static const QString ENHANCED_DIR; PhotoCaches(); // FIXME: remove this class and only deal with a stack of temporary rollback files PhotoCaches(const QFileInfo& file); bool hasCachedOriginal() const; bool hasCachedEnhanced() const; const QFileInfo& originalFile() const; const QFileInfo& enhancedFile() const; const QFileInfo& pristineFile() const; bool cacheOriginal(); bool restoreOriginal(); bool cacheEnhancedFromOriginal(); bool overwriteFromCache(bool preferEnhanced); void discardCachedOriginal(); void discardCachedEnhanced(); void discardAll(); private: static bool remove(const QFileInfo& file) { return QFile::remove(file.filePath()); } static bool rename(const QFileInfo& oldName, const QFileInfo& newName) { return QFile::rename(oldName.filePath(), newName.filePath()); } static bool copy(const QFileInfo& oldName, const QFileInfo& newName) { return QFile::copy(oldName.filePath(), newName.filePath()); } QFileInfo m_file; QFileInfo m_originalFile; QFileInfo m_enhancedFile; }; #endif lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/photoeditor/photo-data.cpp000066400000000000000000000153031455543116500316450ustar00rootroot00000000000000/* * Copyright (C) 2011-2014 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authors: * Jim Nelson * Lucas Beeler * Charles Lindsay * Eric Gregory * Clint Rogers * Ugo Riboni */ #include "photo-data.h" #include "photo-edit-command.h" #include "photo-edit-thread.h" // medialoader #include "photo-metadata.h" // util #include "imaging.h" #include #include #include #include #include #include #include #include #include /*! * \brief Photo::isValid * \param file * \return */ bool PhotoData::isValid(const QFileInfo& file) { QImageReader reader(file.filePath()); QByteArray format = reader.format(); if (QString(format).toLower() == "tiff") { // QImageReader.canRead() will detect some raw files as readable TIFFs, // though QImage will fail to load them. QString extension = file.suffix().toLower(); if (extension != "tiff" && extension != "tif") return false; } PhotoMetadata* tmp = PhotoMetadata::fromFile(file); if (tmp == NULL) return false; delete tmp; return reader.canRead() && QImageWriter::supportedImageFormats().contains(reader.format()); } /*! * \brief Photo::Photo * \param file */ PhotoData::PhotoData() : QObject(), m_editThread(0), m_busy(false), m_orientation(TOP_LEFT_ORIGIN) { } void PhotoData::setPath(QString path) { if (QFileInfo(path).absoluteFilePath() != m_file.absoluteFilePath()) { QFileInfo newFile(path); if (newFile.exists() && newFile.isFile()) { QByteArray format = QImageReader(newFile.absoluteFilePath()).format(); m_fileFormat = QString(format).toLower(); if (m_fileFormat == "jpg") // Why does Qt expose two different names here? m_fileFormat = "jpeg"; m_file = newFile; Q_EMIT pathChanged(); if (fileFormatHasMetadata()) { PhotoMetadata* metadata = PhotoMetadata::fromFile(newFile.absoluteFilePath()); m_orientation = metadata->orientation(); delete metadata; Q_EMIT orientationChanged(); } } } } QString PhotoData::path() const { return m_file.absoluteFilePath(); } QFileInfo PhotoData::file() const { return m_file; } /*! * \brief Photo::~Photo */ PhotoData::~PhotoData() { if (m_editThread) { m_editThread->wait(); finishEditing(); } } /*! * \brief Photo::orientation * \return */ Orientation PhotoData::orientation() const { return m_orientation; } void PhotoData::refreshFromDisk() { if (fileFormatHasMetadata()) { PhotoMetadata* metadata = PhotoMetadata::fromFile(m_file.absoluteFilePath()); qDebug() << "Refreshing orient." << m_orientation << "to" << metadata->orientation(); m_orientation = metadata->orientation(); delete metadata; Q_EMIT orientationChanged(); } Q_EMIT dataChanged(); } /*! * \brief Photo::rotateRight */ void PhotoData::rotateRight() { Orientation current = fileFormatHasOrientation() ? orientation() : TOP_LEFT_ORIGIN; Orientation rotated = OrientationCorrection::rotateOrientation(current, false); qDebug() << " Rotate from orientation " << current << "to" << rotated; PhotoEditCommand command; command.type = EDIT_ROTATE; command.orientation = rotated; asyncEdit(command); } /*! * \brief Photo::autoEnhance */ void PhotoData::autoEnhance() { PhotoEditCommand command; command.type = EDIT_ENHANCE; asyncEdit(command); } /*! * \brief Photo::exposureCompensation Changes the brightnes of the image * \param value Value for the compensation. -1.0 moves the image into total black. * +1.0 to total white. 0.0 leaves it as it is. */ void PhotoData::exposureCompensation(qreal value) { PhotoEditCommand command; command.type = EDIT_COMPENSATE_EXPOSURE; command.exposureCompensation = value; asyncEdit(command); } /*! * \brief Photo::crop * Specify all coords in [0.0, 1.0], where 1.0 is the full size of the image. * They will be clamped to this range if you don't. * \param vrect the rectangle specifying the region to be cropped */ void PhotoData::crop(QVariant vrect) { PhotoEditCommand command; command.type = EDIT_CROP; command.crop_rectangle = vrect.toRectF(); asyncEdit(command); } /*! * \brief Photo::asyncEdit does edit the photo according to the given command * in a background thread. * \param The command defining the edit operation to perform. */ void PhotoData::asyncEdit(const PhotoEditCommand& command) { if (m_busy) { qWarning() << "Can't start edit operation while another one is running."; return; } m_busy = true; Q_EMIT busyChanged(); m_editThread = new PhotoEditThread(this, command); connect(m_editThread, SIGNAL(finished()), this, SLOT(finishEditing())); m_editThread->start(); } /*! * \brief Photo::finishEditing do all the updates once the editing is done */ void PhotoData::finishEditing() { if (!m_editThread || m_editThread->isRunning()) return; m_editThread->deleteLater(); m_editThread = 0; m_busy = false; refreshFromDisk(); Q_EMIT busyChanged(); Q_EMIT editFinished(); } /*! * \brief Photo::fileFormat returns the file format as QString * \return */ const QString &PhotoData::fileFormat() const { return m_fileFormat; } /*! * \brief Photo::fileFormatHasMetadata * \return */ bool PhotoData::fileFormatHasMetadata() const { return (m_fileFormat == "jpeg" || m_fileFormat == "tiff" || m_fileFormat == "png"); } /*! * \brief Photo::fileFormatHasOrientation * \return */ bool PhotoData::fileFormatHasOrientation() const { return (m_fileFormat == "jpeg"); } /*! * \brief Photo::busy return true if there is an editing operation in progress * \return */ bool PhotoData::busy() const { return m_busy; } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/photoeditor/photo-data.h000066400000000000000000000043231455543116500313120ustar00rootroot00000000000000/* * Copyright (C) 2011-2014 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authors: * Jim Nelson * Lucas Beeler * Charles Lindsay * Ugo Riboni */ #ifndef PHOTO_DATA_H_ #define PHOTO_DATA_H_ // util #include "orientation.h" // QT #include #include class PhotoEditCommand; class PhotoEditThread; /*! * \brief The Photo class */ class PhotoData : public QObject { Q_OBJECT Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged) Q_PROPERTY(int orientation READ orientation NOTIFY orientationChanged) Q_PROPERTY(bool busy READ busy NOTIFY busyChanged) public: explicit PhotoData(); virtual ~PhotoData(); static bool isValid(const QFileInfo& file); QString path() const; void setPath(QString path); QFileInfo file() const; bool busy() const; virtual Orientation orientation() const; Q_INVOKABLE void refreshFromDisk(); Q_INVOKABLE void rotateRight(); Q_INVOKABLE void autoEnhance(); Q_INVOKABLE void exposureCompensation(qreal value); Q_INVOKABLE void crop(QVariant vrect); const QString &fileFormat() const; bool fileFormatHasMetadata() const; bool fileFormatHasOrientation() const; Q_SIGNALS: void pathChanged(); void orientationChanged(); void busyChanged(); void editFinished(); void dataChanged(); private Q_SLOTS: void finishEditing(); private: void asyncEdit(const PhotoEditCommand& state); QString m_fileFormat; PhotoEditThread *m_editThread; QFileInfo m_file; bool m_busy; Orientation m_orientation; }; #endif // PHOTO_DATA_H_ lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/photoeditor/photo-edit-command.h000066400000000000000000000027041455543116500327430ustar00rootroot00000000000000/* * Copyright (C) 2014 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . */ #ifndef GALLERY_PHOTO_EDIT_STATE_H_ #define GALLERY_PHOTO_EDIT_STATE_H_ // util #include "orientation.h" #include #include enum EditType { EDIT_NONE = 0, EDIT_ROTATE = 1, EDIT_CROP = 2, EDIT_ENHANCE = 3, EDIT_COMPENSATE_EXPOSURE = 4 }; /*! * \brief The PhotoEditCommand class * * A single edit that will be applied to a photo. */ class PhotoEditCommand { public: EditType type; Orientation orientation; QRectF crop_rectangle; qreal exposureCompensation; /// The color balance parameters are stored here in the order: /// brightness (x), contrast(y), saturation(z), hue(w) QVector4D colorBalance_; PhotoEditCommand() : type(EDIT_NONE), orientation(ORIGINAL_ORIENTATION), crop_rectangle(), exposureCompensation(0.0) { } }; #endif lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/photoeditor/photo-edit-thread.cpp000066400000000000000000000147451455543116500331370ustar00rootroot00000000000000/* * Copyright (C) 2013-2014 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . */ #include "photo-edit-thread.h" #include "photo-data.h" // medialoader #include "photo-metadata.h" // util #include "imaging.h" #include /*! * \brief PhotoEditThread::PhotoEditThread */ PhotoEditThread::PhotoEditThread(PhotoData *photo, const PhotoEditCommand &command) : QThread(), m_photo(photo), m_command(command) { } /*! * \brief PhotoEditThread::command resturns the editing command used for this processing * \return */ const PhotoEditCommand &PhotoEditThread::command() const { return m_command; } /*! * \brief PhotoEditThread::run \reimp */ void PhotoEditThread::run() { // The only operation in which we don't have to work on the actual image // pixels is image rotation in the case where we can simply change the // metadata rotation field. if (m_command.type == EDIT_ROTATE && m_photo->fileFormatHasOrientation()) { handleSimpleMetadataRotation(m_command); return; } // In all other cases we load the image, do the work, and save it back. QImage image(m_photo->file().filePath(), m_photo->fileFormat().toStdString().c_str()); if (image.isNull()) { qWarning() << "Error loading" << m_photo->file().filePath() << "for editing"; return; } // Copy all metadata from the original image so that we can save it to the // new one after modifying the pixels. PhotoMetadata* original = PhotoMetadata::fromFile(m_photo->file()); #if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)) // If the photo was previously rotated through metadata and we are editing // the actual pixels, first rotate the image to match the orientation so // that the correct pixels are edited. // Obviously don't do this in the case we have been asked to do a rotation // operation on the pixels, as we would do it later as the operation itself. // // Using QImage::setAutoTransform() would be better if it existed: // https://bugreports.qt.io/browse/QTBUG-48271 if (m_photo->fileFormatHasOrientation() && m_command.type != EDIT_ROTATE) { Orientation orientation = m_photo->orientation(); QTransform transform = OrientationCorrection::fromOrientation(orientation).toTransform(); image = image.transformed(transform); } #endif if (m_command.type == EDIT_ROTATE) { QTransform transform = OrientationCorrection::fromOrientation(m_command.orientation).toTransform(); image = image.transformed(transform); } else if (m_command.type == EDIT_CROP) { QRect rect; rect.setX(qBound(0.0, m_command.crop_rectangle.x(), 1.0) * image.width()); rect.setY(qBound(0.0, m_command.crop_rectangle.y(), 1.0) * image.height()); rect.setWidth(qBound(0.0, m_command.crop_rectangle.width(), 1.0) * image.width()); rect.setHeight(qBound(0.0, m_command.crop_rectangle.height(), 1.0) * image.height()); image = image.copy(rect); } else if (m_command.type == EDIT_ENHANCE) { image = enhanceImage(image); } else if (m_command.type == EDIT_COMPENSATE_EXPOSURE) { image = compensateExposure(image, m_command.exposureCompensation); } else { qWarning() << "Edit thread running with unknown or no operation."; return; } bool saved = image.save(m_photo->file().filePath(), m_photo->fileFormat().toStdString().c_str(), -1); if (!saved) qWarning() << "Error saving edited" << m_photo->file().filePath(); PhotoMetadata* copy = PhotoMetadata::fromFile(m_photo->file()); original->copyTo(copy); copy->setOrientation(TOP_LEFT_ORIGIN); // reset previous orientation copy->updateThumbnail(image); copy->save(); delete original; delete copy; } /*! * \brief PhotoEditThread::handleSimpleMetadataRotation * Handler for the case of an image whose only change is to its * orientation; used to skip re-encoding of JPEGs. * \param state */ void PhotoEditThread::handleSimpleMetadataRotation(const PhotoEditCommand& state) { PhotoMetadata* metadata = PhotoMetadata::fromFile(m_photo->file()); metadata->setOrientation(state.orientation); metadata->save(); delete(metadata); } /*! * \brief PhotoEditThread::enhanceImage */ QImage PhotoEditThread::enhanceImage(const QImage& image) { int width = image.width(); int height = image.height(); QImage sample_img = (image.width() > 400) ? image.scaledToWidth(400) : image; AutoEnhanceTransformation enhance = AutoEnhanceTransformation(sample_img); QImage::Format dest_format = image.format(); // Can't write into indexed images, due to a limitation in Qt. if (dest_format == QImage::Format_Indexed8) dest_format = QImage::Format_RGB32; QImage enhanced_image(width, height, dest_format); for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { QColor px = enhance.transformPixel( QColor(image.pixel(i, j))); enhanced_image.setPixel(i, j, px.rgb()); } } return enhanced_image; } /*! * \brief PhotoEditThread::compensateExposure Compensates the exposure * Compensating the exposure is a change in brightnes * \param image Image to change the brightnes * \param compansation -1.0 is total dark, +1.0 is total bright * \return The image with adjusted brightnes */ QImage PhotoEditThread::compensateExposure(const QImage &image, qreal compensation) { int shift = qBound(-255, (int)(255*compensation), 255); QImage result(image.width(), image.height(), image.format()); for (int j = 0; j < image.height(); j++) { for (int i = 0; i . */ #ifndef GALLERY_PHOTO_EDIT_THREAD_H_ #define GALLERY_PHOTO_EDIT_THREAD_H_ #include "photo-caches.h" #include "photo-edit-command.h" // util #include "orientation.h" #include #include #include class PhotoData; /*! * \brief The PhotoEditThread class */ class PhotoEditThread: public QThread { Q_OBJECT public: PhotoEditThread(PhotoData *photo, const PhotoEditCommand& command); const PhotoEditCommand& command() const; protected: void run() Q_DECL_OVERRIDE; private: QImage enhanceImage(const QImage& image); QImage compensateExposure(const QImage& image, qreal compansation); QImage doColorBalance(const QImage& image, qreal brightness, qreal contrast, qreal saturation, qreal hue); void handleSimpleMetadataRotation(const PhotoEditCommand& state); PhotoData *m_photo; PhotoEditCommand m_command; }; #endif lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/photoeditor/photo-image-provider.cpp000066400000000000000000000056521455543116500336540ustar00rootroot00000000000000/* * Copyright (C) 2015 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authors: * Florian Boucault */ #include "photo-image-provider.h" #include #include #include #include const char* PhotoImageProvider::PROVIDER_ID = "photo"; const char* EXIF_ORIENTATION_KEY = "Exif.Image.Orientation"; PhotoImageProvider::PhotoImageProvider() : QQuickImageProvider(QQuickImageProvider::Image) { } PhotoImageProvider::~PhotoImageProvider() { } QImage PhotoImageProvider::requestImage(const QString& id, QSize* size, const QSize& requestedSize) { QUrl url(id); QString filePath = url.path(); QFileInfo fileInfo(filePath); QString original = fileInfo.path() + "/.original/" + fileInfo.fileName(); if (QFileInfo::exists(original)) { #if EXIV2_TEST_VERSION(0,28,0) Exiv2::Image::UniquePtr exivImage; #else Exiv2::Image::AutoPtr exivImage; #endif try { exivImage = Exiv2::ImageFactory::open(filePath.toStdString()); exivImage->readMetadata(); Exiv2::ExifData& exifData = exivImage->exifData(); if (exifData[EXIF_ORIENTATION_KEY].typeId() == Exiv2::signedLong) { #if EXIV2_TEST_VERSION(0,28,0) exifData[EXIF_ORIENTATION_KEY] = (Exiv2::UShortValue)exifData[EXIF_ORIENTATION_KEY].toInt64(); #else exifData[EXIF_ORIENTATION_KEY] = (Exiv2::UShortValue)exifData[EXIF_ORIENTATION_KEY].toLong(); #endif exivImage->writeMetadata(); } #if EXIV2_TEST_VERSION(0,28,0) } catch (Exiv2::Error& e) { #else } catch (Exiv2::AnyError& e) { #endif } } QImageReader reader(filePath); #if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)) reader.setAutoTransform(true); #endif QSize fullSize = reader.size(); QSize loadSize(fullSize); if (fullSize.isValid() && (requestedSize.width() > 0 || requestedSize.height() > 0)) { loadSize.scale(requestedSize, Qt::KeepAspectRatio); if (loadSize.width() > fullSize.width() || loadSize.height() > fullSize.height()) { loadSize = fullSize; } } if (loadSize != fullSize) { reader.setScaledSize(loadSize); } QImage image = reader.read(); if (size != NULL) { *size = image.size(); } return image; } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/photoeditor/photo-image-provider.h000066400000000000000000000022621455543116500333130ustar00rootroot00000000000000/* * Copyright (C) 2015 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authors: * Florian Boucault */ #ifndef PHOTO_IMAGE_PROVIDER_H_ #define PHOTO_IMAGE_PROVIDER_H_ #include #include #include #include class PhotoImageProvider : public QQuickImageProvider { public: static const char* PROVIDER_ID; PhotoImageProvider(); virtual ~PhotoImageProvider(); virtual QImage requestImage(const QString& id, QSize* size, const QSize& requestedSize); }; #endif // PHOTO_IMAGE_PROVIDER_H_ lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/photoeditor/photo-metadata.cpp000066400000000000000000000207631455543116500325220ustar00rootroot00000000000000/* * Copyright (C) 2011 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authors: * Lucas Beeler */ #include "photo-metadata.h" #include #include namespace { const Orientation DEFAULT_ORIENTATION = TOP_LEFT_ORIGIN; const char* EXIF_ORIENTATION_KEY = "Exif.Image.Orientation"; const char* EXIF_DATETIMEDIGITIZED_KEY = "Exif.Photo.DateTimeDigitized"; const char* EXPOSURE_TIME_KEYS[] = { "Exif.Photo.DateTimeOriginal", "Xmp.exif.DateTimeOriginal", "Xmp.xmp.CreateDate", "Exif.Photo.DateTimeDigitized", "Xmp.exif.DateTimeDigitized", "Exif.Image.DateTime" }; const size_t NUM_EXPOSURE_TIME_KEYS = 6; const char* EXIF_DATE_FORMATS[] = { "%d:%d:%d %d:%d:%d", // for Minolta DiMAGE E223 (colon, instead of space, separates day from // hour in exif) "%d:%d:%d:%d:%d:%d", // for Samsung NV10 (which uses a period instead of colons for the date // and two spaces between date and time) "%d.%d.%d %d:%d:%d" }; const size_t NUM_EXIF_DATE_FORMATS = 3; const float THUMBNAIL_SCALE = 8.5; const char* get_first_matched(const char* keys[], size_t n_keys, const QSet& in) { for (size_t i = 0; i < n_keys; i++) { if (in.contains(keys[i])) return keys[i]; } return NULL; } bool is_xmp_key(const char* key) { return (key != NULL) ? (std::strncmp("Xmp.", key, 4) == 0) : false; } bool is_exif_key(const char* key) { return (key != NULL) ? (std::strncmp("Exif.", key, 5) == 0) : false; } // caller should test if 's' could be successfully parsed by invoking the // isValid() method on the returned QDateTime instance; if isValid() == false, // 's' couldn't be parsed QDateTime parse_xmp_date_string(const char* s) { return QDateTime::fromString(s, Qt::ISODate); } // caller should test if 's' could be successfully parsed by invoking the // isValid() method on the returned QDateTime instance; if isValid() == false, // 's' couldn't be parsed QDateTime parse_exif_date_string(const char* s) { for (size_t i = 0; i < NUM_EXIF_DATE_FORMATS; i++) { int year, month, day, hour, minute, second; if (std::sscanf(s, EXIF_DATE_FORMATS[i], &year, &month, &day, &hour, &minute, &second) == 6) { // no need to check year, month, day, hour, minute and second variables // for bogus values before using them -- if the values are bogus, the // resulting QDateTime will be invalid, which is exactly what we want return QDateTime(QDate(year, month, day), QTime(hour, minute, second)); } } // the no argument QDateTime constructor produces an invalid QDateTime, // which is what we want return QDateTime(); } } // namespace /*! * \brief PhotoMetadata::PhotoMetadata * \param filepath */ PhotoMetadata::PhotoMetadata(const char* filepath) : m_fileSourceInfo(filepath) { m_image = Exiv2::ImageFactory::open(filepath); m_image->readMetadata(); } /*! * \brief PhotoMetadata::fromFile * \param filepath * \return */ PhotoMetadata* PhotoMetadata::fromFile(const char* filepath) { PhotoMetadata* result = NULL; try { result = new PhotoMetadata(filepath); if (!result->m_image->good()) { qDebug("Invalid image metadata in %s", filepath); delete result; return NULL; } Exiv2::ExifData& exif_data = result->m_image->exifData(); Exiv2::ExifData::const_iterator end = exif_data.end(); for (Exiv2::ExifData::const_iterator i = exif_data.begin(); i != end; i++) result->m_keysPresent.insert(QString(i->key().c_str())); Exiv2::XmpData& xmp_data = result->m_image->xmpData(); Exiv2::XmpData::const_iterator end1 = xmp_data.end(); for (Exiv2::XmpData::const_iterator i = xmp_data.begin(); i != end1; i++) result->m_keysPresent.insert(QString(i->key().c_str())); return result; #if EXIV2_TEST_VERSION(0,28,0) } catch (Exiv2::Error& e) { #else } catch (Exiv2::AnyError& e) { #endif qDebug("Error loading image metadata: %s", e.what()); delete result; return NULL; } } /*! * \brief PhotoMetadata::fromFile * \param file * \return */ PhotoMetadata* PhotoMetadata::fromFile(const QFileInfo &file) { return PhotoMetadata::fromFile(file.absoluteFilePath().toStdString().c_str()); } /*! * \brief PhotoMetadata::orientation * \return */ Orientation PhotoMetadata::orientation() const { Exiv2::ExifData& exif_data = m_image->exifData(); if (exif_data.empty()) return DEFAULT_ORIENTATION; if (m_keysPresent.find(EXIF_ORIENTATION_KEY) == m_keysPresent.end()) return DEFAULT_ORIENTATION; #if EXIV2_TEST_VERSION(0,28,0) long long orientation_code = exif_data[EXIF_ORIENTATION_KEY].toInt64(); #else long orientation_code = exif_data[EXIF_ORIENTATION_KEY].toLong(); #endif if (orientation_code < MIN_ORIENTATION || orientation_code > MAX_ORIENTATION) return DEFAULT_ORIENTATION; return static_cast(orientation_code); } /*! * \brief PhotoMetadata::exposureTime * \return */ QDateTime PhotoMetadata::exposureTime() const { const char* matched = get_first_matched(EXPOSURE_TIME_KEYS, NUM_EXPOSURE_TIME_KEYS, m_keysPresent); if (matched == NULL) return QDateTime(); if (is_exif_key(matched)) return parse_exif_date_string(m_image->exifData()[matched].toString().c_str()); if (is_xmp_key(matched)) return parse_xmp_date_string(m_image->xmpData()[matched].toString().c_str()); // No valid/known tag for exposure date/time return QDateTime(); } /*! * \brief PhotoMetadata::orientationCorrection * \return */ OrientationCorrection PhotoMetadata::orientationCorrection() const { return OrientationCorrection::fromOrientation(orientation()); } /*! * \brief PhotoMetadata::orientationTransform * \return */ QTransform PhotoMetadata::orientationTransform() const { return orientationCorrection().toTransform(); } /*! * \brief PhotoMetadata::setOrientation * \param orientation */ void PhotoMetadata::setOrientation(Orientation orientation) { Exiv2::ExifData& exif_data = m_image->exifData(); exif_data[EXIF_ORIENTATION_KEY] = (Exiv2::UShortValue)orientation; if (!m_keysPresent.contains(EXIF_ORIENTATION_KEY)) m_keysPresent.insert(EXIF_ORIENTATION_KEY); } /*! * \brief PhotoMetadata::setDateTimeDigitized * \param digitized */ void PhotoMetadata::setDateTimeDigitized(const QDateTime& digitized) { try { if (!m_image->good()) { qDebug("Do not set DateTimeDigitized, invalid image metadata."); return; } Exiv2::ExifData& exif_data = m_image->exifData(); exif_data[EXIF_DATETIMEDIGITIZED_KEY] = digitized.toString("yyyy:MM:dd hh:mm:ss").toStdString(); if (!m_keysPresent.contains(EXIF_DATETIMEDIGITIZED_KEY)) m_keysPresent.insert(EXIF_DATETIMEDIGITIZED_KEY); #if EXIV2_TEST_VERSION(0,28,0) } catch (Exiv2::Error& e) { #else } catch (Exiv2::AnyError& e) { #endif qDebug("Do not set DateTimeDigitized, error reading image metadata; %s", e.what()); return; } } /*! * \brief PhotoMetadata::save * \return */ bool PhotoMetadata::save() const { try { m_image->writeMetadata(); return true; #if EXIV2_TEST_VERSION(0,28,0) } catch (Exiv2::Error& e) { #else } catch (Exiv2::AnyError& e) { #endif return false; } } void PhotoMetadata::copyTo(PhotoMetadata *other) const { other->m_image->setMetadata(*m_image); } void PhotoMetadata::updateThumbnail(QImage image) { QImage scaled = image.scaled(image.width() / THUMBNAIL_SCALE, image.height() / THUMBNAIL_SCALE); QBuffer jpeg; jpeg.open(QIODevice::WriteOnly); scaled.save(&jpeg, "jpeg"); Exiv2::ExifThumb thumb(m_image->exifData()); thumb.setJpegThumbnail((Exiv2::byte*) jpeg.data().constData(), jpeg.size()); } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/photoeditor/photo-metadata.h000066400000000000000000000034521455543116500321630ustar00rootroot00000000000000/* * Copyright (C) 2011 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * 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 . * * Authors: * Lucas Beeler */ #ifndef GALLERY_PHOTO_METADATA_H_ #define GALLERY_PHOTO_METADATA_H_ // util #include "orientation.h" #include #include #include #include #include #include #include #include /*! * \brief The PhotoMetadata class */ class PhotoMetadata : public QObject { Q_OBJECT public: static PhotoMetadata* fromFile(const char* filepath); static PhotoMetadata* fromFile(const QFileInfo& file); QDateTime exposureTime() const; Orientation orientation() const; QTransform orientationTransform() const; OrientationCorrection orientationCorrection() const; void setOrientation(Orientation orientation); void setDateTimeDigitized(const QDateTime& digitized); void updateThumbnail(QImage image); void copyTo(PhotoMetadata* other) const; bool save() const; private: PhotoMetadata(const char* filepath); #if EXIV2_TEST_VERSION(0,28,0) Exiv2::Image::UniquePtr m_image; #else Exiv2::Image::AutoPtr m_image; #endif QSet m_keysPresent; QFileInfo m_fileSourceInfo; }; #endif // GALLERY_PHOTO_METADATA_H_ lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/tabsbar/000077500000000000000000000000001455543116500261555ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/tabsbar/drag-helper.cpp000066400000000000000000000126101455543116500310530ustar00rootroot00000000000000/* * Copyright 2016 Canonical Ltd. * * This file is part of webbrowser-app. * * webbrowser-app 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; version 3. * * webbrowser-app 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 . * * Authored-by: Andrew Hayzen */ #include "drag-helper.h" #include #include #include #include #include #include #include #include #include #include DragHelper::DragHelper() : QObject(), m_active(false), m_dragging(false), m_expected_action(Qt::IgnoreAction), m_mime_type(QStringLiteral("x-tabsbar/tab")), m_preview_border_width(8), m_preview_size(QSizeF(200, 150)), m_preview_top_crop(0), m_preview_url(""), m_source(Q_NULLPTR) { } QPixmap DragHelper::drawPixmapWithBorder(QPixmap pixmap, int borderWidth, QColor color) { // Create a transparent pixmap to draw to QPixmap output(pixmap.width() + borderWidth * 2, pixmap.height() + borderWidth * 2); output.fill(QColor(0, 0, 0, 0)); // Draw the pixmap with space around the edge for a border QPainter borderPainter(&output); borderPainter.setRenderHint(QPainter::Antialiasing); borderPainter.drawPixmap(borderWidth, borderWidth, pixmap); // Define a pen to use for the border QPen borderPen; borderPen.setColor(color); borderPen.setJoinStyle(Qt::MiterJoin); borderPen.setStyle(Qt::SolidLine); borderPen.setWidth(borderWidth); // Set the pen and draw the border borderPainter.setPen(borderPen); borderPainter.drawRect(borderWidth / 2, borderWidth / 2, output.width() - borderWidth, output.height() - borderWidth); return output; } Qt::DropAction DragHelper::execDrag(QString tabId) { QDrag *drag = new QDrag(m_source); // Create a mimedata object to use for the drag QMimeData *mimeData = new QMimeData; mimeData->setData(mimeType(), tabId.toLatin1()); // Get a bordered pixmap of the previewUrl QSize size = previewSize().toSize(); QPixmap pixmap = drawPixmapWithBorder(getPreviewUrlAsPixmap(size.width(), size.height()), previewBorderWidth(), QColor(205, 205, 205, 255 * 0.6)); // #cdcdcd // Setup the drag and then execute it drag->setHotSpot(QPoint(size.width() * 0.1, size.height() * 0.1)); drag->setMimeData(mimeData); drag->setPixmap(pixmap); setDragging(true); Qt::DropAction action = drag->exec(expectedAction()); setDragging(false); return action; } QPixmap DragHelper::getPreviewUrlAsPixmap(int width, int height) { QSize pixmapSize(width, height); QPixmap pixmap(previewUrl()); if (pixmap.isNull()) { // If loading pixmap failed, draw a white rectangle pixmap = QPixmap(pixmapSize); QPainter painter(&pixmap); painter.eraseRect(0, 0, pixmapSize.width(), pixmapSize.height()); painter.fillRect(0, 0, pixmapSize.width(), pixmapSize.height(), QColor(255, 255, 255, 255)); } else { // Crop transparent part off the top of the image pixmap = pixmap.copy(0, previewTopCrop(), pixmap.width(), pixmap.height() - previewTopCrop()); // Scale image to fit the expected size pixmap = pixmap.scaled(pixmapSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); } return pixmap; } void DragHelper::setActive(bool active) { if (m_active != active) { m_active = active; Q_EMIT activeChanged(); } } void DragHelper::setDragging(bool dragging) { if (m_dragging != dragging) { m_dragging = dragging; Q_EMIT draggingChanged(); } } void DragHelper::setExpectedAction(Qt::DropAction expectedAction) { if (m_expected_action != expectedAction) { m_expected_action = expectedAction; Q_EMIT expectedActionChanged(); } } void DragHelper::setMimeType(QString mimeType) { if (m_mime_type != mimeType) { m_mime_type = mimeType; Q_EMIT mimeTypeChanged(); } } void DragHelper::setPreviewBorderWidth(int previewBorderWidth) { if (m_preview_border_width != previewBorderWidth) { m_preview_border_width = previewBorderWidth; Q_EMIT previewBorderWidthChanged(); } } void DragHelper::setPreviewSize(QSizeF previewSize) { if (m_preview_size != previewSize) { m_preview_size = previewSize; Q_EMIT previewSizeChanged(); } } void DragHelper::setPreviewTopCrop(int previewTopCrop) { if (m_preview_top_crop != previewTopCrop) { m_preview_top_crop = previewTopCrop; Q_EMIT previewTopCropChanged(); } } void DragHelper::setPreviewUrl(QString previewUrl) { if (m_preview_url != previewUrl) { m_preview_url = previewUrl; Q_EMIT previewUrlChanged(); } } void DragHelper::setSource(QQuickItem *source) { if (m_source != source) { m_source = source; Q_EMIT sourceChanged(); } } lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/plugin/tabsbar/drag-helper.h000066400000000000000000000067031455543116500305260ustar00rootroot00000000000000/* * Copyright 2016 Canonical Ltd. * * This file is part of webbrowser-app. * * webbrowser-app 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; version 3. * * webbrowser-app 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 . * * Authored-by: Andrew Hayzen */ #ifndef __DRAGHELPER_H__ #define __DRAGHELPER_H__ #include #include #include #include #include class QQuickItem; class DragHelper : public QObject { Q_OBJECT Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged) Q_PROPERTY(bool dragging READ dragging NOTIFY draggingChanged) Q_PROPERTY(Qt::DropAction expectedAction READ expectedAction WRITE setExpectedAction NOTIFY expectedActionChanged) Q_PROPERTY(QString mimeType READ mimeType WRITE setMimeType NOTIFY mimeTypeChanged) Q_PROPERTY(int previewBorderWidth READ previewBorderWidth WRITE setPreviewBorderWidth NOTIFY previewBorderWidthChanged) Q_PROPERTY(QSizeF previewSize READ previewSize WRITE setPreviewSize NOTIFY previewSizeChanged) Q_PROPERTY(int previewTopCrop READ previewTopCrop WRITE setPreviewTopCrop NOTIFY previewTopCropChanged) Q_PROPERTY(QString previewUrl READ previewUrl WRITE setPreviewUrl NOTIFY previewUrlChanged) Q_PROPERTY(QQuickItem* source READ source WRITE setSource NOTIFY sourceChanged) public: DragHelper(); bool active() { return m_active; } bool dragging() { return m_dragging; } Qt::DropAction expectedAction() { return m_expected_action; } QString mimeType() { return m_mime_type; } int previewBorderWidth() { return m_preview_border_width; } QSizeF previewSize() { return m_preview_size; } int previewTopCrop() { return m_preview_top_crop; } QString previewUrl() { return m_preview_url; } QQuickItem *source() { return m_source; } Q_SIGNALS: void activeChanged(); void draggingChanged(); void expectedActionChanged(); void mimeTypeChanged(); void previewBorderWidthChanged(); void previewSizeChanged(); void previewTopCropChanged(); void previewUrlChanged(); void sourceChanged(); public Q_SLOTS: Q_INVOKABLE Qt::DropAction execDrag(QString tabId); void setActive(bool active); void setExpectedAction(Qt::DropAction expectedAction); void setMimeType(QString mimeType); void setPreviewBorderWidth(int previewBorderWidth); void setPreviewSize(QSizeF previewSize); void setPreviewTopCrop(int previewTopCrop); void setPreviewUrl(QString previewUrl); void setSource(QQuickItem *source); private: QPixmap drawPixmapWithBorder(QPixmap pixmap, int borderWidth, QColor color); QPixmap getPreviewUrlAsPixmap(int width, int height); void setDragging(bool dragging); bool m_active; bool m_dragging; Qt::DropAction m_expected_action; QString m_mime_type; int m_preview_border_width; QSizeF m_preview_size; int m_preview_top_crop; QString m_preview_url; QQuickItem *m_source; }; #endif // __DRAGHELPER_H__ lomiri-ui-extras-0.6.3/modules/Lomiri/Components/Extras/qmldir000066400000000000000000000002171455543116500244540ustar00rootroot00000000000000module Lomiri.Components.Extras plugin lomiri-ui-extras-plugin Example 0.2 Example.qml PhotoEditor 0.2 PhotoEditor.qml TabsBar 0.3 TabsBar.qml lomiri-ui-extras-0.6.3/po/000077500000000000000000000000001455543116500153615ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/po/CMakeLists.txt000066400000000000000000000025511455543116500201240ustar00rootroot00000000000000project(lomiri-ui-extras-translations) include(FindGettext) find_program(GETTEXT_XGETTEXT_EXECUTABLE xgettext) file(GLOB_RECURSE I18N_SRC_FILES RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/modules/*.qml ${CMAKE_SOURCE_DIR}/modules/*.cpp ${CMAKE_SOURCE_DIR}/modules/*.h) set(DOMAIN ${GETTEXT_PACKAGE}) set(POT_FILE ${DOMAIN}.pot) file(GLOB PO_FILES *.po) add_custom_target(${POT_FILE} ALL COMMAND ${GETTEXT_XGETTEXT_EXECUTABLE} -o ${POT_FILE} -s -p ${CMAKE_CURRENT_SOURCE_DIR} -D ${CMAKE_SOURCE_DIR} --from-code=UTF-8 --c++ --qt --add-comments=TRANSLATORS --keyword=dtr:2 --keyword=dtr:2,3 --keyword=tr --keyword=tr:1,2 --keyword=__ --package-name=lomiri-ui-extras --copyright-holder='Canonical Ltd.' ${I18N_SRC_FILES}) foreach(PO_FILE ${PO_FILES}) get_filename_component(LANG ${PO_FILE} NAME_WE) gettext_process_po_files(${LANG} ALL PO_FILES ${PO_FILE}) set(INSTALL_DIR ${CMAKE_INSTALL_LOCALEDIR}/${LANG}/LC_MESSAGES) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${LANG}.gmo DESTINATION ${INSTALL_DIR} RENAME ${DOMAIN}.mo) endforeach(PO_FILE) lomiri-ui-extras-0.6.3/po/aa.po000066400000000000000000000062141455543116500163050ustar00rootroot00000000000000# Afar translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-01-31 22:48+0000\n" "Last-Translator: Charif AYFARAH \n" "Language-Team: Afar \n" "Language: aa\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Bayis" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Ceesiy" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Gaba kaleh" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Taswiir aysiisiyya..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Eydeb" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Taswiir uyduur" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Aslih uduur" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Meekis" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Duma tekke daffeynaani edde anuk, wadir yaduureenim fakut tanim inkih wadir " "gacse le." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Eybex" lomiri-ui-extras-0.6.3/po/af.po000066400000000000000000000057371455543116500163230ustar00rootroot00000000000000# Afrikaans translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-06-08 09:38+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Afrikaans \n" "Language: af\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/am.po000066400000000000000000000071231455543116500163210ustar00rootroot00000000000000# Amharic translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2018-11-25 00:00+0000\n" "Last-Translator: Samson \n" "Language-Team: Amharic \n" "Language: am\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 3.1.1\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "ተቋርጧል" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "ንቁ" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "መሰረዣ" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "ቀለም" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "ፒዲኤፍ መፍጠሪያ" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "መከርከሚያ" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "ጨርሷል" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "የ ፎቶ ጥራት መጨመሪያ..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "ረጅም ጠርዝ (መደበኛ)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "መልእክት የለም" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "መደበኛ" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "በ አንድ በኩል" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "እንደገና መስሪያ" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "ፎቶ እንደ ነበር መመለሻ" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "ወደ ነበረበት መመለሻ" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "ማዞሪያ" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "አጭር ጠርዝ (መገልበጫ)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "ተቋርጧል" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "መሞከሪያ ገጽ" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "ይህ ሁሉንም እርማት ይተዋል: ቀደም ያለውንም ክፍለ ጊዜ ያካትታል" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "መተው" lomiri-ui-extras-0.6.3/po/an.po000066400000000000000000000055041455543116500163230ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: an\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/ar.po000066400000000000000000000067231455543116500163330ustar00rootroot00000000000000# Arabic translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2020-11-13 19:53+0000\n" "Last-Translator: abidin \n" "Language-Team: Arabic \n" "Language: ar\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" "X-Generator: Weblate 3.11.3\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "أُلغي" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "نشط" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "ألغ" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "اللون" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "انشئ PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "قص" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "تم" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "يحسن الصورة…" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "ساكن" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "لا رسائل" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "عادي" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "أعِد" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "اعكس الصورة" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "استعِد الحالة الأصلية" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "أدر" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "متوقف" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "صفحة الاختبار" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "هذا سيلغي كل التغييرات، حتى التي تمت في الجلسات السابقة." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "تراجع" lomiri-ui-extras-0.6.3/po/as.po000066400000000000000000000055041455543116500163300ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: as\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/ast.po000066400000000000000000000061101455543116500165060ustar00rootroot00000000000000# Asturian translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2019-10-30 01:36+0000\n" "Last-Translator: enolp \n" "Language-Team: Asturian \n" "Language: ast\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.8\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Encaboxar" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/az.po000066400000000000000000000057431455543116500163440ustar00rootroot00000000000000# Azerbaijani translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-03-22 12:36+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Azerbaijani \n" "Language: az\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/be.po000066400000000000000000000073771455543116500163250ustar00rootroot00000000000000# Belarusian translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2020-12-26 13:26+0000\n" "Last-Translator: Zmicer \n" "Language-Team: Belarusian \n" "Language: be\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 3.11.3\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Перарвана" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Актыўны" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Скасаваць" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Колер" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Стварыць PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Абрэзаць" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Завершана" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Паляпшэнне фотаздымка…" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Бяздзейнічае" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Доўгі край (стандарт)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Няма паведамленняў" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Звычайны" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Аднабаковы" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Паўтарыць" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Аднавіць фотаздымак" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Вярнуцца да арыгінала" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Павярнуць" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Кароткі край (гартанне)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Спынены" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Тэставая старонка" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "Гэта скасуе ўсе змены, уключаючы змены з папярэдніх сеансаў." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Адрабіць" lomiri-ui-extras-0.6.3/po/bem.po000066400000000000000000000057641455543116500165000ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Bemba \n" "Language: bem\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/bg.po000066400000000000000000000061251455543116500163150ustar00rootroot00000000000000# Bulgarian translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Bulgarian \n" "Language: bg\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/bn.po000066400000000000000000000055041455543116500163240ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: bn\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/bn_BD.po000066400000000000000000000061321455543116500166670ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-08-20 08:04+0000\n" "Last-Translator: Abdullah AL Shohag \n" "Language-Team: Bengali (Bangladesh) \n" "Language: bn_BD\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.0-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "বাতিল" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "সম্পন্ন" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "পুনরায়" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "পূর্বাবস্থা" lomiri-ui-extras-0.6.3/po/bo.po000066400000000000000000000055041455543116500163250ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: bo\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/br.po000066400000000000000000000062271455543116500163330ustar00rootroot00000000000000# Breton translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-02-22 12:44+0000\n" "Last-Translator: Fohanno Thierry \n" "Language-Team: Breton \n" "Language: br\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Nullañ" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Krennañ" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Graet eo" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Gwellaat ar skeudenn..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Adober" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Assevel ar skeudenn" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Distreiñ d'ar stumm orin" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Treiñ" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "Nullet e vo an holl gemmoù, re an dalc'hoù a-raok hag all." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Dizober" lomiri-ui-extras-0.6.3/po/bs.po000066400000000000000000000062001455543116500163230ustar00rootroot00000000000000# Bosnian translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-01-11 23:20+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Bosnian \n" "Language: bs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Izrezati" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Gotovo" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Poboljšanje fotografije..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Ponoviti" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Vratiti sliku" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Vratiti na original" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Rotiraj" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "Ovo će vratiti sva editovanja,uključujći i ona iz prošlih sesija." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Poništi" lomiri-ui-extras-0.6.3/po/ca.po000066400000000000000000000066271455543116500163170ustar00rootroot00000000000000# Catalan translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2019-05-03 21:03+0000\n" "Last-Translator: Joan CiberSheep \n" "Language-Team: Catalan \n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.6.1\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Aturada" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Actiu" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Cancel·la" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Color" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Crea un PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Escapça" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Fet" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "S'està millorant la fotografia..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Inactiva" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Cantó llarg (estàndard)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Cap missatge" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "De mida normal" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "D'una cara" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Refés" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Torna a l'original" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Reverteix a l'original" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Gira" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Cantó curt (capgirat)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Aturada" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Pàgina de prova" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Això desfarà totes les modificacions, incloent-hi les de sessions anteriors." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Desfés" lomiri-ui-extras-0.6.3/po/ca@valencia.po000066400000000000000000000057721455543116500201220ustar00rootroot00000000000000# Catalan (Valencian) translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-01-11 23:20+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Catalan (Valencian) \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/ce.po000066400000000000000000000055041455543116500163140ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: ce\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/ckb.po000066400000000000000000000055051455543116500164650ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: ckb\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/co.po000066400000000000000000000055041455543116500163260ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: co\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/crh.po000066400000000000000000000055051455543116500165020ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: crh\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/cs.po000066400000000000000000000067161455543116500163400ustar00rootroot00000000000000# Czech translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-08-04 18:04+0000\n" "Last-Translator: Milan Korecky \n" "Language-Team: Czech \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" "X-Generator: Weblate 5.0-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Přerušeno" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Aktivní" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Zrušit" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Barva" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Vytvořit PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Oříznout" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Hotovo" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Vylepšování fotografie…" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "Vystavení" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Nečinná" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Dlouhá strana (standard)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Žádné zprávy" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normální" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Jednostranná" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Znovu" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Vrátit zpět fotku" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Vrátit do původního stavu" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Otočit" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Krátká strana (převrátit)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Zastaveno" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Testovací stránka" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "Toto odstraní všechny úpravy, včetně těch z předchozích sezení." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Vrátit" lomiri-ui-extras-0.6.3/po/csb.po000066400000000000000000000055051455543116500164750ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: csb\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/cv.po000066400000000000000000000055041455543116500163350ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: cv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/cy.po000066400000000000000000000062361455543116500163430ustar00rootroot00000000000000# Welsh translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-02-24 15:50+0000\n" "Last-Translator: Owen Llywelyn \n" "Language-Team: Welsh \n" "Language: cy\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Diddymu" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Tocio" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Cwblhawyd" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Yn gwella'r llun..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Ailwneud" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Dychwelyd Llun i'r Gwreiddiol" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Dychwelyd i'r gwreiddiol" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Cylchdroi" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "Bydd hyn yn dadwneud y golygu i gyd gan gynnwys sesiynau blaenorol." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Dadwneud" lomiri-ui-extras-0.6.3/po/da.po000066400000000000000000000065451455543116500163170ustar00rootroot00000000000000# Danish translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2018-09-18 12:39+0000\n" "Last-Translator: Tom Rausner \n" "Language-Team: Danish \n" "Language: da\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 2.20\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Afbrudt" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Aktiv" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Annullér" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Farve" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Opret PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Beskær" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Færdig" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Forbedrer foto..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Tomgang" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Lang Kant (Standart)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Ingen meddelelser" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normal" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Enkeltsidet" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Omgør" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Gendan foto" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Gendan originalen" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Rotér" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Kort Kant (Endevende)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Stoppet" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Testside" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Dette vil ophæve alle ændringer, inklusiv ændringer fra tidligere sessioner." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Fortryd" lomiri-ui-extras-0.6.3/po/de.po000066400000000000000000000066411455543116500163200ustar00rootroot00000000000000# German translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-02-01 20:49+0000\n" "Last-Translator: Mike Gabriel \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.16-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Abgebrochen" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Aktiv" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Abbrechen" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Farbe" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "PDF erstellen" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Zuschneiden" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Fertig" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Foto wird verbessert…" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "Belichtung" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Leerlauf" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Lange Seite (Standard)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Keine Nachrichten" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normal" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Einseitig" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Wiederholen" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Fortsetzen" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Original wiederherstellen" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Drehen" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Kurze Seite (Gedreht)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Angehalten" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Testseite" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Hiermit werden alle Änderungen verworfen, auch die aus vorherigen Sitzungen." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Rückgängig" lomiri-ui-extras-0.6.3/po/dv.po000066400000000000000000000057641455543116500163460ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Dhivehi \n" "Language: dv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/el.po000066400000000000000000000074021455543116500163240ustar00rootroot00000000000000# Greek translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2020-08-16 08:17+0000\n" "Last-Translator: Efstathios Iosifidis \n" "Language-Team: Greek \n" "Language: el\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.11.3\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Ματαιώθηκε" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Ενεργό" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Ακύρωση" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Χρώμα" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Δημιουργία PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Περικοπή" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Ολοκλήρωση" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Βελτίωση φωτογραφίας..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Αδρανή" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Μακρύ άκρο (κανονικό)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Κανένα μήνυμα" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Κανονικό" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Μονής όψης" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Επανάληψη" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Επαναφορά φωτογραφίας" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Επαναφορά στην αρχική" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Περιστροφή" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Βραχύ άκρο (αναστροφή)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Διακόπηκε" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Δοκιμαστική σελίδα" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Αυτή η ενέργεια θα αναιρέσει όλες τις αλλαγές, συμπεριλαμβανομένων και αυτών " "από προηγούμενες συνεδρίες." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Αναίρεση" lomiri-ui-extras-0.6.3/po/en_AU.po000066400000000000000000000062101455543116500167070ustar00rootroot00000000000000# English (Australia) translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-02-12 23:21+0000\n" "Last-Translator: Joel Addison \n" "Language-Team: English (Australia) \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Crop" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Done" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Enhancing photo..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Redo" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Revert Photo" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Revert to original" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Rotate" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "This will undo all edits, including those from previous sessions." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Undo" lomiri-ui-extras-0.6.3/po/en_CA.po000066400000000000000000000055071455543116500166750ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: en_CA\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/en_GB.po000066400000000000000000000065401455543116500167000ustar00rootroot00000000000000# English (United Kingdom) translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2018-07-05 21:08+0000\n" "Last-Translator: konrad \n" "Language-Team: English (United Kingdom) \n" "Language: en_GB\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 2.15\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Aborted" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Active" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Colour" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Create PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Crop" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Done" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Enhancing photo..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Idle" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Long Edge (Standard)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "No messages" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normal" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "One Sided" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Redo" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Revert Photo" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Revert to original" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Rotate" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Short Edge (Flip)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Stopped" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Test page" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "This will undo all edits, including those from previous sessions." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Undo" lomiri-ui-extras-0.6.3/po/en_US.po000066400000000000000000000057751455543116500167500ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2019-06-22 15:04+0000\n" "Last-Translator: lxdb \n" "Language-Team: English (United States) \n" "Language: en_US\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.6.1\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/eo.po000066400000000000000000000065561455543116500163400ustar00rootroot00000000000000# Esperanto translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2024-01-04 16:35+0000\n" "Last-Translator: phlostically \n" "Language-Team: Esperanto \n" "Language: eo\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.4-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Abortigita" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Aktiva" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Nuligi" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Koloro" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Krei PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Eltondi" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Farite" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Plibonigante foton..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "Ekspono" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Senokupa" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Longa rando (Defaŭlta)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Ne mesaĝoj" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normala" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Unuflanka" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Refari" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Turni foton" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Turni al originalo" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Rotacii" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Mallonga rando" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Haltita" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Testo-paĝo" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "Ĉi tio malfaros ĉiujn redaktojn, inkludante tiujn de antaŭaj seancoj." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Malfari" lomiri-ui-extras-0.6.3/po/es.po000066400000000000000000000065741455543116500163440ustar00rootroot00000000000000# Spanish translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-04-06 21:55+0000\n" "Last-Translator: gallegonovato \n" "Language-Team: Spanish \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.17-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Abortado" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Activa" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Cancelar" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Color" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Crear PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Recortar" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Hecho" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Mejorando foto..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "Exposición" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Inactiva" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Borde largo (Estándar)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Ningún mensaje" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normal" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Una cara" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Rehacer" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Revertir foto" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Revertir al original" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Rotar" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Borde corto (voltear)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Parada" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Página de prueba" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Esto deshace todos los cambios, incluidos los de las sesiones anteriores." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Deshacer" lomiri-ui-extras-0.6.3/po/et.po000066400000000000000000000061231455543116500163330ustar00rootroot00000000000000# Estonian translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Estonian \n" "Language: et\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/eu.po000066400000000000000000000064041455543116500163360ustar00rootroot00000000000000# Basque translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2019-07-06 22:48+0000\n" "Last-Translator: Aitzol Berasategi \n" "Language-Team: Basque \n" "Language: eu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.6.1\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Aktibo" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Utzi" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Kolorez" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Sortu PDF-a" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Moztu" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Egina" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Argazkia hobetzen..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Berregin" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Leheneratu argazkia" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Leheneratu jatorrizkora" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Biratu" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "Honek aldaketa guztiak desegingo ditu, baita aurreko saioetakoak ere." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Desegin" lomiri-ui-extras-0.6.3/po/fa.po000066400000000000000000000066021455543116500163130ustar00rootroot00000000000000# Persian translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2020-02-16 01:21+0000\n" "Last-Translator: HSN80 \n" "Language-Team: Persian \n" "Language: fa\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 3.8\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "فعال" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "انصراف" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "رنگ" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "بریدن" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "انجام شد" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "بهبود عکس…" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "انجام دوباره" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "برگرداندن عکس" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "برگرداندن به اصلی" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "چرخاندن" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "این کار تمام ویرایش‌ها را، شامل ویرایش‌های نشست‌های پیشین برمی‌گرداند." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "بر‌گرداندن" lomiri-ui-extras-0.6.3/po/fi.po000066400000000000000000000065771455543116500163360ustar00rootroot00000000000000# Finnish translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2020-11-23 18:30+0000\n" "Last-Translator: Jiri Grönroos \n" "Language-Team: Finnish \n" "Language: fi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.11.3\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Keskeytetty" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Aktiivinen" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Peru" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Väri" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Luo PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Rajaa" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Valmis" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Parannetaan kuvaa..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Jouten" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Pitkä reuna (standardi)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Ei viestejä" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normaali" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Yksipuoleinen" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Tee uudelleen" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Palauta kuva" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Palauta alkuperäinen" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Kierrä" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Lyhyt reuna (kääntö)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Pysäytetty" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Testisivu" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Tämä toiminto kumoaa kaikki muokkaukset, myös aiemmin tehdyt muokkaukset." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Kumoa" lomiri-ui-extras-0.6.3/po/fil.po000066400000000000000000000055051455543116500165000ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: fil\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/fo.po000066400000000000000000000057331455543116500163350ustar00rootroot00000000000000# Faroese translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-01-11 23:20+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Faroese \n" "Language: fo\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/fr.po000066400000000000000000000066711455543116500163420ustar00rootroot00000000000000# French translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-15 17:49+0000\n" "Last-Translator: Timothy G. <22472919+GTimothy@users.noreply.github.com>\n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.15.1-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Interrompu" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Actif" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Annuler" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Couleur" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Créer un fichier PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Recadrer" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Terminé" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Amélioration de la photo..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "Exposition" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Inactif" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Bord long (standard)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Pas de messages" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normal" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Recto" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Rétablir" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Restaurer la photo" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Restaurer l'original" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Faire pivoter" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Bord court (pivoté)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Arrêté" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Page de test" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Ceci annulera toutes les modifications, y compris celles des sessions " "précédentes." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Annuler" lomiri-ui-extras-0.6.3/po/fr_CA.po000066400000000000000000000066501455543116500167020ustar00rootroot00000000000000# French (Canada) translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2020-05-09 21:23+0000\n" "Last-Translator: Ryan Argente \n" "Language-Team: French (Canada) \n" "Language: fr_CA\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 3.8\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Interrompu" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Actif" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Annuler" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Couleur" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Créer un fichier PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Rogner" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Terminé" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Amélioration de la photo..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Inactif" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Bord long (standard)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Aucun message" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normal" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Recto" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Refaire" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Rétablir la photo" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Revenir à l'original" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Rotation" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Bord court (pivoté)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Arrêté" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Page de test" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Ceci annulera toutes les modifications, y compris celles des sessions " "précédentes." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Annuler" lomiri-ui-extras-0.6.3/po/fr_CH.po000066400000000000000000000060061455543116500167040ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: French (Switzerland) \n" "Language: fr_CH\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/frp.po000066400000000000000000000057771455543116500165300ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Franco-Provençal \n" "Language: frp\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/fur.po000066400000000000000000000057671455543116500165340ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Friulian \n" "Language: fur\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/fy.po000066400000000000000000000055041455543116500163430ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: fy\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/ga.po000066400000000000000000000055041455543116500163140ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: ga\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/gd.po000066400000000000000000000063061455543116500163200ustar00rootroot00000000000000# Gaelic; Scottish translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-01-16 14:54+0000\n" "Last-Translator: GunChleoc \n" "Language-Team: Gaelic; Scottish \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Sguir dheth" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Bearr" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Deiseil" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "A' leasachadh an deilbh..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Ath-dhèan" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Till an dealbh" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Till dhan tionndadh tùsail" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Cuairtich" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Neo-dhèanaidh seo a h-uile atharrachadh, a' ghabhail a-steach an fheadhainn " "on na seiseanan roimhe." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Neo-dhèan" lomiri-ui-extras-0.6.3/po/gl.po000066400000000000000000000065551455543116500163360ustar00rootroot00000000000000# Galician translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2020-03-07 11:22+0000\n" "Last-Translator: Neutrum N \n" "Language-Team: Galician \n" "Language: gl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.8\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Abortado" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Activo" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Cancelar" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Cor" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Crear PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Recortar" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Feito" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Mellorando a foto..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Inactivo" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Beira longa (estándar)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Sen mensaxes" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normal" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Unha cara" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Refacer" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Reverter foto" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Reverter ao orixinal" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Rotar" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Beira curta (voltear)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Parado" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Páxina de proba" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Isto desfará todas as modificacións, incluídas as de sesións anteriores." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Desfacer" lomiri-ui-extras-0.6.3/po/gu.po000066400000000000000000000073611455543116500163430ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2019-04-11 17:24+0000\n" "Last-Translator: Aashrut \n" "Language-Team: Gujarati \n" "Language: gu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 3.1.1\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "રદ કરેલું" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "સક્રિય" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "રદ કરો" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "રંગ" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "PDF બનાવવો" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "ક્રોપ" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "પૂર્ણ થયું" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "ફોટો સુધારી રહ્યા છીએ..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "નિષ્ક્રિય" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "લાંબી એજ(પ્રમાણિત)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "કોઇ સંદેશાઓ નથી" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "સામાન્ય" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "એક બાજુવાળું" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "ફરીથી કરો" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "ફોટો પાછો ફેરવો" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "મૂળ સ્વરૂપે પાછા ફેરવો" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "ફેરવો" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "ટૂંકી એજ (ફેરવો)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "અટકી ગયું" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "પરીક્ષણ પૃષ્ઠ" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "આ બધા સુધારા પૂર્વરત્ કરશે, અગાઉના સત્રના સમાવેશ સાથે." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "પૂર્વરત્ કરો" lomiri-ui-extras-0.6.3/po/gv.po000066400000000000000000000055041455543116500163410ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: gv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/he.po000066400000000000000000000070211455543116500163150ustar00rootroot00000000000000# Hebrew translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2020-12-25 08:26+0000\n" "Last-Translator: Yaron Shahrabani \n" "Language-Team: Hebrew \n" "Language: he\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && " "n % 10 == 0) ? 2 : 3));\n" "X-Generator: Weblate 3.11.3\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "בוטל" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "פעיל" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "ביטול" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "צבע" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "יצירת PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "חיתוך" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "סיום" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "התמונה משתפרת…" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "ldle" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "קצה ארוך (סטנדרטי)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "אין הודעות" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "רגיל" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "חד צדדי" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "ביצוע חוזר" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "שחזור התמונה" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "שחזור למקור" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "סיבוב" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "קצה קצר (הפוך)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "עצר" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "דף בדיקה" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "פעולה זו תבטל את כל העריכות, לרבות אלו מההפעלות הקודמות." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "החזרה" lomiri-ui-extras-0.6.3/po/hi.po000066400000000000000000000055041455543116500163250ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: hi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/hr.po000066400000000000000000000063251455543116500163400ustar00rootroot00000000000000# Croatian translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-01-11 23:20+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Croatian \n" "Language: hr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Boja" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Stvori PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Obreži" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Završeno" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Povećanje fotografije..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Dugom stranom (standardno)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normalno" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Jednostrano" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Ponovi" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Izvorna fotografija" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Vrati na izvorno" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Zakreni" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Kratkom stranom (okrenuto)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "Ovo će poništiti sve promjene, uključujući one iz prve sesije." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Poništi" lomiri-ui-extras-0.6.3/po/ht.po000066400000000000000000000055041455543116500163400ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: ht\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/hu.po000066400000000000000000000063731455543116500163460ustar00rootroot00000000000000# Hungarian translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2021-01-28 19:27+0000\n" "Last-Translator: Adam \n" "Language-Team: Hungarian \n" "Language: hu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.11.3\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Mégsem" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Levágás" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Kész" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Fotó feljavítása…" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Újra" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Visszaállítás" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Visszatérés az eredetihez" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Forgatás" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "Ez minden szerkesztést visszavon, beleértve a korábban történteket is." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Visszavonás" lomiri-ui-extras-0.6.3/po/hy.po000066400000000000000000000055041455543116500163450ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: hy\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/ia.po000066400000000000000000000062251455543116500163170ustar00rootroot00000000000000# Interlingua translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-01-18 00:16+0000\n" "Last-Translator: karm \n" "Language-Team: Interlingua \n" "Language: ia\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Cancellar" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Tonder" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Facite" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Melioramento de photo..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Refacer" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Reverter le photo" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Reverter al original" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Rotar" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Isto disfacera tote le modificationes, includente illos per previe sessiones." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Disfacer" lomiri-ui-extras-0.6.3/po/id.po000066400000000000000000000065751455543116500163320ustar00rootroot00000000000000# Indonesian translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2020-08-08 18:44+0000\n" "Last-Translator: satriocode \n" "Language-Team: Indonesian \n" "Language: id\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 3.11.3\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Batalkan" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Aktif" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Batal" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Warna" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Buat PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Crop" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Selesai" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Memperbagus foto..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Diam" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Pinggiran Panjang (Standar)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Tak ada pesan" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normal" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Satu sisi" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Lakukan lagi (Redo)" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Kembalikan foto" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Kembalikan ke orisinal" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Putar" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Pinggiran Pendek (Dibalik)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Berhenti" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Halaman tes" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "Ini akan mengembalikan semua perubahan, termasuk dari sesi sebelumnya." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Batal (undo)" lomiri-ui-extras-0.6.3/po/io.po000066400000000000000000000057601455543116500163400ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Ido \n" "Language: io\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/is.po000066400000000000000000000065031455543116500163400ustar00rootroot00000000000000# Icelandic translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Icelandic \n" "Language: is\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n % 10 != 1 || n % 100 == 11;\n" "X-Generator: Weblate 4.15.1-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Utansníða" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Búið" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Bæti ljósmynd..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Endurgera" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Færa mynd aftur í upprunalegt horf" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Færa aftur í upprunalegt horf" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Snúa" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Þetta mun afturkalla allar breytingar, þar með taldar breytingar úr fyrri " "setum." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Afturkalla" lomiri-ui-extras-0.6.3/po/it.po000066400000000000000000000065521455543116500163450ustar00rootroot00000000000000# Italian translations for ubuntu-ui-extras package. # Copyright (C) 2013 Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # Ugo , 2013. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-04-02 03:46+0000\n" "Last-Translator: Sylke Vicious \n" "Language-Team: Italian \n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.17-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Annullato" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Attiva" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Annulla" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Colore" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Crea PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Ritaglia" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Fatto" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Miglioramento foto..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "Esposizione" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Inattiva" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Lato lungo" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Nessun messaggio" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normale" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Unilaterale" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Ripeti" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Ripristina foto" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Ripristina l'originale" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Ruota" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Lato corto" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Bloccata" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Pagina di prova" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Questo annullerà tutte le modifiche, incluse quelle delle precedenti " "sessioni." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Annulla" lomiri-ui-extras-0.6.3/po/it_CARES.po000066400000000000000000000055121455543116500172550ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: it_CARES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/ja.po000066400000000000000000000066211455543116500163200ustar00rootroot00000000000000# Japanese translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-12-26 12:06+0000\n" "Last-Translator: NPL \n" "Language-Team: Japanese \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 5.4-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "アクティブ" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "キャンセル" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "カラー" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "PDFを作成" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "トリミング" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "完了" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "画像を補正しています..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "メッセージなし" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "やり直す" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "写真をオリジナルに戻す" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "オリジナルに戻す" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "回転" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "この操作を行うと全ての編集操作(以前のセッションで編集されたものを含む)が取り" "消されます。" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "戻る" lomiri-ui-extras-0.6.3/po/jbo.po000066400000000000000000000057601455543116500165030ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Lojban \n" "Language: jbo\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/ka.po000066400000000000000000000063251455543116500163220ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-04-13 05:14+0000\n" "Last-Translator: Temuri Doghonadze \n" "Language-Team: Georgian \n" "Language: ka\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.17-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "აქტიური" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "გაუქმება" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "ფერი" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "ამოჭრა" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "დასრულებულია" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "ექსპოზიცია" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "გამეორება" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "დატრიალება" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "დაბრუნება" lomiri-ui-extras-0.6.3/po/kab.po000066400000000000000000000061201455543116500164550ustar00rootroot00000000000000# Kabyle translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Kabyle \n" "Language: kab\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.15.1-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/kk.po000066400000000000000000000055041455543116500163320ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: kk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/kl.po000066400000000000000000000055041455543116500163330ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: kl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/km.po000066400000000000000000000057251455543116500163410ustar00rootroot00000000000000# Khmer translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-01-11 23:20+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Khmer \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/kmr.po000066400000000000000000000060011455543116500165070ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Kurdish (Northern) \n" "Language: kmr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/kn.po000066400000000000000000000062111455543116500163310ustar00rootroot00000000000000# Kannada translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-03-26 09:46+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Kannada \n" "Language: kn\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "ರದ್ದುಗೊಳಿಸು" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "ಕತ್ತರಿಸು" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "ಮುಗಿಯಿತು" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "ಮತ್ತೆ ಮಾಡು" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "ಮೂಲಕ್ಕೆ ಮರಳಿಸು" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "ತಿರುಗಿಸು" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/ko.po000066400000000000000000000064251455543116500163410ustar00rootroot00000000000000# Korean translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2020-07-30 23:33+0000\n" "Last-Translator: Young Kim \n" "Language-Team: Korean \n" "Language: ko\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 3.11.3\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "취소" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "PDF 만들기" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "잘라내기" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "완료" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "사진 개선 중..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "다시 실행" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "사진 되돌리기" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "원래 이미지로 돌려놓기" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "회전" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "이전 세션에서 한 것을 포함해 모든 편집 작업을 취소합니다." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "실행 취소" lomiri-ui-extras-0.6.3/po/ku.po000066400000000000000000000060161455543116500163430ustar00rootroot00000000000000# Kurdish translation for ubuntu-ui-extras # Copyright (c) 2017 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2017. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2017-01-29 12:07+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Kurdish \n" "Language: ku\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Betal bike" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Bibire" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Xelas" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Dîsa bike" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Bizivirîne" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Vegerîne" lomiri-ui-extras-0.6.3/po/kw.po000066400000000000000000000055041455543116500163460ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: kw\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/ky.po000066400000000000000000000055041455543116500163500ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: ky\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/la.po000066400000000000000000000055041455543116500163210ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: la\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/lb.po000066400000000000000000000066421455543116500163260ustar00rootroot00000000000000# Luxembourgish translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Luxembourgish \n" "Language: lb\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Ofgebrach" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Aktiv" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Fuerw" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "PDF erstellen" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Zouschneiden" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Fäerdeg" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Fotto gëtt verbessert …" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Inaktiv" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Laang Säit (Standard)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Keng Noriichten" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normal" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Eesäiteg" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Widderhuelen" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Fotto zerécksetzen" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Original rëm hierstellen" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Dréinen" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Kuerz Säit (gedréint)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Gestoppt" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Testsäit" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "Heimadder ginn all Ännerunge verworf, och déi vu vireschte Sëtzungen." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Réckgängeg" lomiri-ui-extras-0.6.3/po/ln.po000066400000000000000000000063701455543116500163400ustar00rootroot00000000000000# Lingala translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Lingala \n" "Language: ln\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.15.1-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Kolíya kolíya" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Esálémí" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Bobakisi fɔtɔ́..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Zóngela" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Zonga na fɔtɔ́" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Zonga na ebandeli" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Balusa" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "Eko bwákisa manso o sali, na mpe ya baye ya sesio ya kala." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Bwákisa" lomiri-ui-extras-0.6.3/po/lo.po000066400000000000000000000061041455543116500163340ustar00rootroot00000000000000# Lao translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Lao \n" "Language: lo\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.15.1-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/lomiri-ui-extras.pot000066400000000000000000000055371455543116500213310ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/lt.po000066400000000000000000000067071455543116500163520ustar00rootroot00000000000000# Lithuanian translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2019-09-25 20:51+0000\n" "Last-Translator: Moo \n" "Language-Team: Lithuanian \n" "Language: lt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n % 10 == 1 && (n % 100 < 11 || n % 100 > " "19)) ? 0 : ((n % 10 >= 2 && n % 10 <= 9 && (n % 100 < 11 || n % 100 > 19)) ? " "1 : 2);\n" "X-Generator: Weblate 3.8\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Nutraukta" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Aktyvus" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Atsisakyti" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Spalva" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Sukurti PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Apkirpti" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Atlikta" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Tobulinama nuotrauka..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Neveiklus" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Grąžinti" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Sugrąžinti nuotrauką" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Sugrąžinti į pradinę" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Pasukti" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Sustabdytas" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Tai atšauks visus redagavimus, įskaitant tuos, kurie buvo atlikti " "ankstesniuose seansuose." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Atšaukti" lomiri-ui-extras-0.6.3/po/lv.po000066400000000000000000000062201455543116500163420ustar00rootroot00000000000000# Latvian translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-01-11 23:20+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Latvian \n" "Language: lv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Kadrēt" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Pabeigts" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Uzlabo fotogrāfiju..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Atatsaukt" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Atjaunot fotogrāfiju" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Atjaunot uz oriģinālu" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Pagriezt" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "Tas atsauks visus rediģējumus, tai skaitā iepriekšējā sesijā veiktos." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Atsaukt" lomiri-ui-extras-0.6.3/po/mg.po000066400000000000000000000061221455543116500163250ustar00rootroot00000000000000# Malagasy translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Malagasy \n" "Language: mg\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.15.1-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/mhr.po000066400000000000000000000055051455543116500165140ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: mhr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/mi.po000066400000000000000000000057611455543116500163370ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Maori \n" "Language: mi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/mk.po000066400000000000000000000060101455543116500163250ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Macedonian \n" "Language: mk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n==1 || n%10==1 ? 0 : 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/ml.po000066400000000000000000000057661455543116500163470ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Malayalam \n" "Language: ml\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/mr.po000066400000000000000000000070311455543116500163400ustar00rootroot00000000000000# Marathi translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Marathi \n" "Language: mr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "कापा" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "पूर्ण झाले" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "फोटो वर्धन करीत आहे ..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "पुन्हा करा" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "फोटो परत होता तसा करा" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "मूळ स्थितीत आणा" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "गोल फिरवा" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "हे, मागील सत्रातून समाविष्ट संपादनांसहित सर्व संपादने पूर्ववत करेल." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "पूर्ववत करा" lomiri-ui-extras-0.6.3/po/ms.po000066400000000000000000000062071455543116500163450ustar00rootroot00000000000000# Malay translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-02-04 14:10+0000\n" "Last-Translator: dequan \n" "Language-Team: Malay \n" "Language: ms\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Batal" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Kerat" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Selesai" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Mempertingkatkan foto...." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Buat Semula" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Kembalikan Foto" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Kembali ke asal" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Putar" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Ini akan membuat asal semua suntingan, termasuklah dari sesi sebelum ini." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Buat Asal" lomiri-ui-extras-0.6.3/po/my.po000066400000000000000000000061141455543116500163500ustar00rootroot00000000000000# Burmese translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Burmese \n" "Language: my\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.15.1-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/nan.po000066400000000000000000000060001455543116500164710ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Chinese (Min Nan) \n" "Language: nan\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/nb.po000066400000000000000000000066041455543116500163260ustar00rootroot00000000000000# Norwegian Bokmal translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-04 08:07+0000\n" "Last-Translator: Allan Nordhøy \n" "Language-Team: Norwegian Bokmål \n" "Language: nb\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Avbrutt" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Aktiv" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Avbryt" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Farge" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Opprett PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Beskjær" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Ferdig" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Forbedrer bilde …" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "Lukketid" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Inaktiv" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Lang kant (forvalg)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Ingen meldinger" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normal" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Ensidig" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Gjenta" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Tilbakestill bilde" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Forkast endringer" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Roter" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Kort kant (vend)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Stoppet" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Testside" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Dette tilbakestiller alle endringer, inkludert endringer fra tidligere økter." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Angre" lomiri-ui-extras-0.6.3/po/ne.po000066400000000000000000000072431455543116500163310ustar00rootroot00000000000000# Nepali translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Nepali \n" "Language: ne\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "काटछाँट गर्नुहोस्" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "गरियो" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "तस्विर सुधारिदै छ..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "फेरि गर्नुहोस्" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "तस्विर परिवर्तन उल्टाउनुहोस" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "मुल तस्विरमा उल्टाउनुहोस" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "घुमाउनुहोस्" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "यसले अघिल्लो सत्र सहित सबै सम्पादनहरु हटाएर पुर्वस्थितिमा फर्काउनेछ।" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "पुर्वस्थितिमा फर्काउनुहोस्" lomiri-ui-extras-0.6.3/po/nl.po000066400000000000000000000066461455543116500163460ustar00rootroot00000000000000# Dutch translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-02-28 20:38+0000\n" "Last-Translator: Heimen Stoffels \n" "Language-Team: Dutch \n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.16-rc\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Afgebroken" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Actief" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Annuleren" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Kleur" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Pdf-bestand maken" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Bijsnijden" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Sluiten" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Bezig met verbeteren van foto…" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "Belichting" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Inactief" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Lange kant (standaard)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Er zijn geen berichten" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normaal" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Enkelzijdig" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Opnieuw" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Origineel herstellen" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Herstel het origineel" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Draaien" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Korte kant (omdraaien)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Gestopt" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Testpagina" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "Dit maakt alle bewerkingen ongedaan, inclusief die van vorige sessies." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Ongedaan maken" lomiri-ui-extras-0.6.3/po/nn.po000066400000000000000000000055041455543116500163400ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: nn\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/ny.po000066400000000000000000000057631455543116500163620ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Nyanja \n" "Language: ny\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/oc.po000066400000000000000000000062621455543116500163300ustar00rootroot00000000000000# Occitan (post 1500) translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-01-11 23:20+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Occitan (post 1500) \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Retalhar" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Acabat" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Melhorament de la fòto..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Restablir" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Restablir la fòto" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Restablir l'original" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Far pivotar" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Aquò anullarà totas las modificacions, inclusas las de las sessions " "precedentas." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Anullar" lomiri-ui-extras-0.6.3/po/om.po000066400000000000000000000057621455543116500163460ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Oromo \n" "Language: om\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/or.po000066400000000000000000000055041455543116500163450ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: or\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/os.po000066400000000000000000000055041455543116500163460ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: os\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/pa.po000066400000000000000000000057331455543116500163310ustar00rootroot00000000000000# Punjabi translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-01-11 23:20+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Punjabi \n" "Language: pa\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/pam.po000066400000000000000000000061261455543116500165030ustar00rootroot00000000000000# Pampangan translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Pampanga \n" "Language: pam\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/pl.po000066400000000000000000000067451455543116500163500ustar00rootroot00000000000000# Polish translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-25 21:48+0000\n" "Last-Translator: gnu-ewm \n" "Language-Team: Polish \n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.16-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Przerwano" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Aktywny" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Anuluj" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Kolor" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Utwórz PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Przytnij" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Gotowe" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Poprawianie zdjęcia..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "Ekspozycja" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Bezczynny" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Długa krawędź (standardowa)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Brak wiadomości" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normalna" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Jednostronny" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Ponów" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Przywróć zdjęcie" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Przywróć oryginał" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Obrót" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Krótka krawędź (przerzucanie)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Zatrzymany" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Strona testowa" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Wszystkie zmiany, również te dokonane w poprzednich sesjach, zostaną " "anulowane." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Cofnij" lomiri-ui-extras-0.6.3/po/ps.po000066400000000000000000000057631455543116500163560ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Pashto \n" "Language: ps\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/pt.po000066400000000000000000000065771455543116500163630ustar00rootroot00000000000000# Portuguese translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-15 17:49+0000\n" "Last-Translator: Ivo Xavier \n" "Language-Team: Portuguese \n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.15.1-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Abortado" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Ativo" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Cancelar" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Cor" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Criar PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Cortar" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Feito" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Melhorando foto..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "Exposição" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Inativo" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Margem longa (Omissão)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Sem mensagens" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normal" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Um lado" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Refazer" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Reverter foto" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Reverter para a original" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Rodar" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Margem curta (Girar)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Parado" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Página de teste" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Isto vai desfazer todas as edições, incluíndo as de sessões anteriores." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Desfazer" lomiri-ui-extras-0.6.3/po/pt_BR.po000066400000000000000000000066321455543116500167360ustar00rootroot00000000000000# Brazilian Portuguese translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2020-08-01 01:22+0000\n" "Last-Translator: ffsi \n" "Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 3.11.3\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Interrompido" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Ativo" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Cancelar" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Cor" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Criar PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Cortar" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Concluído" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Aprimorando imagem . . ." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Ociosa" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Borda larga (Simples)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Sem mensagens" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normal" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Unilateral" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Refazer" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Reverter foto" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Reverter para o original" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Girar" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Borda Estreita (Flip)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Parada" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Página de teste" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Isto irá desfazer todas as edições, incluindo aquelas das sessões anteriores." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Desfazer" lomiri-ui-extras-0.6.3/po/ro.po000066400000000000000000000065001455543116500163420ustar00rootroot00000000000000# Romanian translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2020-11-04 10:38+0000\n" "Last-Translator: Mihai \n" "Language-Team: Romanian \n" "Language: ro\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < " "20)) ? 1 : 2;\n" "X-Generator: Weblate 3.11.3\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Anulează" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Culoare" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Decupare" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Terminat" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Se îmbunătățește imaginea..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Refă" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Restabilire fotografie" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Revenire la original" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Rotire" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "Aceasta va anula toate modificările, inclusiv cele efectuate anterior" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Anulare" lomiri-ui-extras-0.6.3/po/ru.po000066400000000000000000000074071455543116500163570ustar00rootroot00000000000000# Russian translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-31 12:43+0000\n" "Last-Translator: Sergii Horichenko \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.16-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Отменено" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Активный" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Отмена" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Цвет" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Создать PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Кадрировать" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Сделано" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Улучшение снимка..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "Экспозиция" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Простаивает" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Длинный край (стандартный)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Нет сообщений" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Нормальный" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Односторонний" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Повторить" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Восстановить снимок" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Вернуться к оригиналу" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Вращать" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Короткий край (флип)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Остановлен" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Пробная страница" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "Это отменит все изменения, включая изменения из предыдущих сеансов." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Отменить" lomiri-ui-extras-0.6.3/po/sa.po000066400000000000000000000060321455543116500163250ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-07-07 11:49+0000\n" "Last-Translator: \"Rudra Harsh V.Singh\" \n" "Language-Team: Sanskrit \n" "Language: sa\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;\n" "X-Generator: Weblate 5.0-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "निरसयतु" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/sc.po000066400000000000000000000064741455543116500163410ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2018-05-29 11:37+0000\n" "Last-Translator: Flavia \n" "Language-Team: Sardinian \n" "Language: sc\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 2.15\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Annulladu" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Ativa" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Annulla" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Colore" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Crea PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Sega" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Fatu" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Megiorende sa fotografia..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Inativa" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Ala longa (Istandard)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Perunu messàgiu" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normale" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "A un'ala" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Torra a fàghere" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Riprìstina sa fotografia" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Riprìstina a s'originale" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Gira" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Ala curtza (Acovecada)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Blocada" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Pàgina de proa" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Custu at a iscontzare totus is modìficas, puru cussas de is sessiones " "pretzedentes." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Iscontza" lomiri-ui-extras-0.6.3/po/sco.po000066400000000000000000000057641455543116500165210ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Scots \n" "Language: sco\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/sd.po000066400000000000000000000057631455543116500163420ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Sindhi \n" "Language: sd\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/sdh.po000066400000000000000000000060011455543116500164740ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Kurdish (Southern) \n" "Language: sdh\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/se.po000066400000000000000000000055041455543116500163340ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: se\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/shn.po000066400000000000000000000057631455543116500165240ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Shan \n" "Language: shn\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/si.po000066400000000000000000000057771455543116500163540ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2021-03-04 00:27+0000\n" "Last-Translator: helabasa \n" "Language-Team: Sinhala \n" "Language: si\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 3.11.3\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "අවලංගු" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "වර්ණය" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/sk.po000066400000000000000000000066731455543116500163520ustar00rootroot00000000000000# Slovak translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2020-02-25 16:21+0000\n" "Last-Translator: dano6 \n" "Language-Team: Slovak \n" "Language: sk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" "X-Generator: Weblate 3.8\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Zrušená" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Aktívna" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Zrušiť" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Farba" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Vytvoriť PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Orezať" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Hotovo" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Vylepšujem fotografie..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Nečinná" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Dlhá hrana (štandardné)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Žiadne správy" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normálny" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Jednostranný" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Opakovať" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Vrátiť fotografiu" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Vrátiť do pôvodného stavu" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Otočiť" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Krátka hrana (obrátené)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Zastavená" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Testovacia stránka" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "Vráti späť všetky úpravy, vrátane tých z predchádzajúcich relácií." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Späť" lomiri-ui-extras-0.6.3/po/sl.po000066400000000000000000000065731455543116500163520ustar00rootroot00000000000000# Slovenian translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2020-02-18 17:21+0000\n" "Last-Translator: Riccardo Riccio \n" "Language-Team: Slovenian \n" "Language: sl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n" "%100==4 ? 2 : 3;\n" "X-Generator: Weblate 3.8\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 #, fuzzy msgid "Active" msgstr "Aktivno" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Prekliči" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Barva" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 #, fuzzy msgid "Create PDF" msgstr "Ustvarite PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Obreži" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Končano" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Izboljševanje fotografije ..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Ni sporočil" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Ponovno uveljavi" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Povrni fotografijo" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Povrni na izvirnik" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Zavrti" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "To bo razveljavilo vsa urejanja, vključno s tistimi iz prejšnjih sej." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Razveljavi" lomiri-ui-extras-0.6.3/po/sq.po000066400000000000000000000066351455543116500163560ustar00rootroot00000000000000# Albanian translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2020-12-18 18:26+0000\n" "Last-Translator: Enkli Ylli \n" "Language-Team: Albanian \n" "Language: sq\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.11.3\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "I ndërprerë" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Aktiv" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Anullo" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Ngjyra" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Krijo PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Preje" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Përfundoi" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Duke rregulluar foton..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Në neutral" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Ana e gjatë (standarde)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Nuk ka mesazhe" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normal" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "I njëanshëm" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Përsëritje" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Rikthe foton" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Rikthe në original" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Rrotullo" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Ana e shkurtër (rrotulluar)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Ndalur" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Faqe testi" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Kjo do ti zhbëjë të gjitha modifikimet, duke përfshirë ato nga seksione të " "mëparshme." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Zhbëjë" lomiri-ui-extras-0.6.3/po/sr.po000066400000000000000000000064021455543116500163470ustar00rootroot00000000000000# Serbian translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-01-21 22:28+0000\n" "Last-Translator: Bojan Bogdanović \n" "Language-Team: Serbian \n" "Language: sr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Откажи" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Опсеци" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Урађено" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Унапређујем слику..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Поврати" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Поврати слику" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Врати на изворно" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Заокрени" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "Ово ће поништити све измене, укључујући и оне из претходне сесије." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Опозови" lomiri-ui-extras-0.6.3/po/st.po000066400000000000000000000055041455543116500163530ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: st\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/sv.po000066400000000000000000000065641455543116500163640ustar00rootroot00000000000000# Swedish translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-09-07 04:54+0000\n" "Last-Translator: bittin1ddc447d824349b2 \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.0.1-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Avbruten" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Aktiv" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Avbryt" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Färg" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Skapa PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Beskär" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Klart" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Förbättra foto..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "Exponering" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Inaktiv" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Långkant (standard)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Inga meddelanden" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Normal" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Ensidig" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Gör om" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Återställ foto" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Återgå till original" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Rotera" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Kortkant (vänd)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Stoppad" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Testsida" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Detta kommer ångra alla redigeringar, inklusive de från tidigare sessioner." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Ångra" lomiri-ui-extras-0.6.3/po/sw.po000066400000000000000000000055041455543116500163560ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: sw\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/szl.po000066400000000000000000000055051455543116500165360ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: szl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/ta.po000066400000000000000000000100701455543116500163230ustar00rootroot00000000000000# Tamil translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2021-01-05 23:27+0000\n" "Last-Translator: GK \n" "Language-Team: Tamil \n" "Language: ta\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.11.3\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "முறிவுற்றது" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "செயலில்" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "தவிர்க்க" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "நிறம்" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "PDF-ஐ உருவாக்குக" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "செதுக்கு" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "முடிந்தது" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "நிழற்படத்தை மேம்படுத்துகிறது…" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "விளைவற்ற" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "நீண்ட விளிம்பு (செந்தரம்)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "செய்திகள் இல்லை" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "இயல்பான" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "ஒருதலையான" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "மீண்டும் செய்க" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "நிழற்படத்தை மீட்டமை" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "மூலபடவம்போல் மாற்று" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "சுழற்று" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "குறுகிய விளிம்பு (புரட்டு)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "நின்றது" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "சோதனைப் பக்கம்" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "இந்த செயல் இதற்கு முந்தய அமர்வையும் சேர்த்து, அனைத்து திருத்தங்களையும் நீக்கிவிடும்." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "செய்ததைத் தவிர்" lomiri-ui-extras-0.6.3/po/ta_LK.po000066400000000000000000000055071455543116500167220ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: ta_LK\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/te.po000066400000000000000000000057631455543116500163440ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Telugu \n" "Language: te\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/tet.po000066400000000000000000000057641455543116500165310ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Tetum \n" "Language: tet\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/tg.po000066400000000000000000000061101455543116500163310ustar00rootroot00000000000000# Tajik translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Tajik \n" "Language: tg\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.15.1-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/th.po000066400000000000000000000063741455543116500163460ustar00rootroot00000000000000# Thai translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2021-05-23 05:10+0000\n" "Last-Translator: Wannaphong Phatthiyaphaibun \n" "Language-Team: Thai \n" "Language: th\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 3.11.3\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "ยกเลิก" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "สี" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "สร้าง PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "เสร็จสิ้น" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "ไม่มีข้อความ" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "ปกติ" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "หมุน" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "หน้าทดสอบ" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "ถอยหลัง" lomiri-ui-extras-0.6.3/po/ti.po000066400000000000000000000055041455543116500163410ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: ti\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/tk.po000066400000000000000000000057641455543116500163530ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-05 10:54+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Turkmen \n" "Language: tk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 #, fuzzy msgid "Cancel" msgstr "Cancel" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/tr.po000066400000000000000000000063721455543116500163560ustar00rootroot00000000000000# Turkish translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2020-02-06 20:21+0000\n" "Last-Translator: Ege Öz \n" "Language-Team: Turkish \n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.8\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Aktif" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "İptal" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Renk" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Kırp" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Tamamlandı" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Fotoğraf iyileştiriliyor..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Yinele" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Fotoğrafı geri al" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Aslına döndür" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Döndür" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "Önceki oturumlarında dahil olacak şekilde tüm düzenlemeleri geri al." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Geri Al" lomiri-ui-extras-0.6.3/po/tt.po000066400000000000000000000055041455543116500163540ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: tt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/ug.po000066400000000000000000000064131455543116500163400ustar00rootroot00000000000000# Uyghur translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2016-01-11 23:20+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Uyghur \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" "X-Generator: Launchpad (build 18332)\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "قىرقى" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "تامام" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "سۈرەتنى ياخشىلاۋاتىدۇ…" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "قايتىلا" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "سۈرەتنى ئەسلىگە قايتۇر" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "ئەسلىگە قايتۇر" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "چۆرگىلەت" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "ھازىرقى ۋە ئالدىنقى ئەڭگىمەلەردىكى بارلىق تەھرىرلەشلەردىن يېنىۋالىدۇ." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "يېنىۋال" lomiri-ui-extras-0.6.3/po/uk.po000066400000000000000000000075461455543116500163540ustar00rootroot00000000000000# Ukrainian translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-15 17:49+0000\n" "Last-Translator: Dan \n" "Language-Team: Ukrainian \n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.15.1-dev\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Перервано" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Активно" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Скасувати" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Колір" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Створити PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Обрізати" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Готово" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Покращуємо фото…" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "Експозиція" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "Бездіяльність" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "Довгий край (Стандарт)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Немає повідомлень" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Нормальний" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Односторонній" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Повторити" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Повернути старе фото" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Повернутися до початкового" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Обертання" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "Короткий край (Віддзеркалення)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Зупинено" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Тестова сторінка" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Усі результати редагування буде скасовано, зокрема і результати із " "попередніх сеансів роботи." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Скасувати" lomiri-ui-extras-0.6.3/po/ur.po000066400000000000000000000060501455543116500163500ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2023-01-04 00:30+0000\n" "Last-Translator: Muhammad \n" "Language-Team: Urdu \n" "Language: ur\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.1-dev\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "منسوخ کریں" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "ہوگیا" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "دوبارہ کریں" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "کالعدم" lomiri-ui-extras-0.6.3/po/uz.po000066400000000000000000000055041455543116500163630ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: uz\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/vec.po000066400000000000000000000055051455543116500165030ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: vec\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/vi.po000066400000000000000000000066531455543116500163510ustar00rootroot00000000000000# Vietnamese translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2020-06-17 09:25+0000\n" "Last-Translator: Phu1237 \n" "Language-Team: Vietnamese \n" "Language: vi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 3.11.3\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "Đã huỷ bỏ" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "Kích hoạt" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "Huỷ bỏ" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "Màu" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "Tạo PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "Crop" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "Hoàn thành" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "Đang cải thiệt ảnh…" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "Không có tin nhắn" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "Bình thường" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "Một cạnh" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "Làm lại" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "Hoàn tác ảnh" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "Hoàn tác về mặc định" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "Xoay" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "Đã dừng" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "Trang thử nghiệm" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" "Điều này sẽ huỷ bỏ các chỉnh sửa, kể cả những chỉnh sửa từ phiên làm việc " "trước." #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "Hoàn tác" lomiri-ui-extras-0.6.3/po/wae.po000066400000000000000000000055051455543116500165020ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: wae\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/wo.po000066400000000000000000000055041455543116500163520ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: wo\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/xh.po000066400000000000000000000055041455543116500163440ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: xh\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/zh_CN.po000066400000000000000000000065161455543116500167320ustar00rootroot00000000000000# Chinese (Simplified) translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2021-03-05 06:27+0000\n" "Last-Translator: Sam Zhang \n" "Language-Team: Chinese (Simplified) \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 3.11.3\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "终止" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "活动" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "取消" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "颜色" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "创建PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "裁剪" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "完成" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "增强照片……" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "空闲" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "长边(标准)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "没有通知" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "标准" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "单方面" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "重做" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "恢复照片" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "恢复原状" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "旋转" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "短边(翻转)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "停止" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "测试页面" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "这将撤消所有编辑,包括之前的编辑。" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "撤销" lomiri-ui-extras-0.6.3/po/zh_HK.po000066400000000000000000000066331455543116500167340ustar00rootroot00000000000000# Chinese (Hong Kong) translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2018-11-25 00:01+0000\n" "Last-Translator: Louies \n" "Language-Team: Chinese (Hong Kong) \n" "Language: zh_HK\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 3.1.1\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "已中止" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "積極" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "取消" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "顏色" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "創建 PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "裁剪" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "已完成" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "增強照片中..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "閒置" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "長邊 (標準)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "冇訊息" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "正常" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "單方面的" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "重做" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "還原照片" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "恢復原始狀態" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "旋轉" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "短邊 (翻轉)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "已停止" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "測試頁" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "將撤消所有編輯,包括以前會話中編輯。" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "撤銷" #~ msgid "Revert to Original" #~ msgstr "還原至原始狀態" lomiri-ui-extras-0.6.3/po/zh_LATN@pinyin.po000066400000000000000000000055201455543116500205110ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the lomiri-ui-extras package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: zh_LATN@pinyin\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "" lomiri-ui-extras-0.6.3/po/zh_TW.po000066400000000000000000000066001455543116500167560ustar00rootroot00000000000000# Chinese (Traditional) translation for ubuntu-ui-extras # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd. # This file is distributed under the same license as the ubuntu-ui-extras package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: lomiri-ui-extras\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-08-19 16:19+0000\n" "PO-Revision-Date: 2019-05-03 21:03+0000\n" "Last-Translator: louies0623 \n" "Language-Team: Chinese (Traditional) \n" "Language: zh_TW\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 3.6.1\n" "X-Launchpad-Export-Date: 2017-03-19 06:38+0000\n" #: modules/Lomiri/Components/Extras/Example/Printers.qml:106 msgid "Aborted" msgstr "已中止" #: modules/Lomiri/Components/Extras/Example/Printers.qml:108 msgid "Active" msgstr "活躍" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:215 #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:72 msgid "Cancel" msgstr "取消" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:44 msgid "Color" msgstr "色彩" #: modules/Lomiri/Components/Extras/Printers/models/printermodel.cpp:54 msgid "Create PDF" msgstr "建立 PDF" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:43 #: modules/Lomiri/Components/Extras/PhotoEditor/CropOverlay.qml:349 msgid "Crop" msgstr "裁切" #: modules/Lomiri/Components/Extras/PhotoEditor/ExposureAdjuster.qml:80 msgid "Done" msgstr "完成" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:235 msgid "Enhancing photo..." msgstr "強化照片中..." #: modules/Lomiri/Components/Extras/PhotoEditor.qml:61 msgid "Exposure" msgstr "" #: modules/Lomiri/Components/Extras/Example/Printers.qml:104 msgid "Idle" msgstr "閒置" #: modules/Lomiri/Components/Extras/Printers/utils.h:61 msgid "Long Edge (Standard)" msgstr "長邊 (標準)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:115 msgid "No messages" msgstr "沒有訊息" #: modules/Lomiri/Components/Extras/Printers/backend/backend_pdf.cpp:47 msgid "Normal" msgstr "正常" #: modules/Lomiri/Components/Extras/Printers/utils.h:64 msgid "One Sided" msgstr "單方面的" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:121 msgid "Redo" msgstr "重做" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:221 msgid "Revert Photo" msgstr "還原相片" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:205 #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:128 msgid "Revert to original" msgstr "還原至初始狀態" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:52 msgid "Rotate" msgstr "旋轉" #: modules/Lomiri/Components/Extras/Printers/utils.h:59 msgid "Short Edge (Flip)" msgstr "短邊 (翻轉)" #: modules/Lomiri/Components/Extras/Example/Printers.qml:110 msgid "Stopped" msgstr "已停止" #: modules/Lomiri/Components/Extras/Printers/printers/printers.cpp:395 msgid "Test page" msgstr "測試頁面" #: modules/Lomiri/Components/Extras/PhotoEditor.qml:206 msgid "This will undo all edits, including those from previous sessions." msgstr "這會取消所有的編輯動作,包括先前作業階段編輯過的部分。" #: modules/Lomiri/Components/Extras/PhotoEditor/EditStack.qml:114 msgid "Undo" msgstr "復原" lomiri-ui-extras-0.6.3/tests/000077500000000000000000000000001455543116500161055ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/tests/CMakeLists.txt000066400000000000000000000000621455543116500206430ustar00rootroot00000000000000add_subdirectory(qml) add_subdirectory(unittests) lomiri-ui-extras-0.6.3/tests/qml/000077500000000000000000000000001455543116500166765ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/tests/qml/CMakeLists.txt000066400000000000000000000017301455543116500214370ustar00rootroot00000000000000find_program(QMLTESTRUNNER_BIN NAMES qmltestrunner ) find_program(XVFB_RUN_BIN NAMES xvfb-run ) macro(DECLARE_QML_TEST TST_NAME TST_QML_FILE) add_test(NAME ${TST_NAME} WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND ${XVFB_RUN_BIN} -a -s "-screen 0 1024x768x24" ${QMLTESTRUNNER_BIN} --platform xcb -input ${CMAKE_CURRENT_SOURCE_DIR}/${TST_QML_FILE} ) endmacro() if(QMLTESTRUNNER_BIN AND XVFB_RUN_BIN) declare_qml_test("tst_actions_bar" tst_ActionsBar.qml) declare_qml_test("tst_busy_indicator" tst_BusyIndicator.qml) declare_qml_test("tst_crop_drag_area" tst_CropDragArea.qml) else() if (NOT QMLTESTRUNNER_BIN) message(WARNING "Qml tests disabled: qmltestrunner not found") else() message(WARNING "Qml tests disabled: xvfb-run not found") endif() endif() set(QML_TST_FILES tst_ActionsBar.qml tst_BusyIndicator.qml tst_CropDragArea.qml ) add_custom_target(tst_QmlFiles ALL SOURCES ${QML_TST_FILES}) lomiri-ui-extras-0.6.3/tests/qml/tst_ActionsBar.qml000066400000000000000000000045131455543116500223330ustar00rootroot00000000000000/* * Copyright 2015 Canonical Ltd. * * This file is part of dialer-app. * * dialer-app 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; version 3. * * dialer-app 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 . */ import QtQuick 2.3 import QtTest 1.0 import Lomiri.Test 0.1 import Lomiri.Components 1.1 import '../../modules/Lomiri/Components/Extras/PhotoEditor' Item { id: root width: units.gu(40) height: units.gu(60) property list toolActions: [ Action { text: "ToolActions01" }, Action { text: "ToolActions02" } ] property list filterActions: [ Action { text: "FilterActions01" }, Action { text: "FilterActions02" } ] ActionsBar { id: actionsBar toolActions: root.toolActions } LomiriTestCase { id: actionsBarTestCase name: 'actionsBarTestCase' when: windowShown function init() { waitForRendering(actionsBar); } function cleanup() { } function test_actionsBarCheckColumnHeightWhitFilterActions() { actionsBar.filterActions = root.filterActions tryCompare(actionsBar, 'height', units.gu(20)) } function test_actionsBarCheckColumnHeightWhitFilterActionsEmpty() { actionsBar.filterActions = [] tryCompare(actionsBar, 'height', units.gu(6)) } function test_actionsBarCheckFiltersBarVisibleWhitFilterActions() { actionsBar.filterActions = root.filterActions var filtersBar = findChild(actionsBar, 'filtersBar') tryCompare(filtersBar, 'visible', true) } function test_actionsBarCheckFiltersBarNotVisibleWhitFilterActionsEmpty() { actionsBar.filterActions = [] var filtersBar = findChild(actionsBar, 'filtersBar') tryCompare(filtersBar, 'visible', false) } } } lomiri-ui-extras-0.6.3/tests/qml/tst_BusyIndicator.qml000066400000000000000000000052171455543116500230670ustar00rootroot00000000000000/* * Copyright 2015 Canonical Ltd. * * This file is part of dialer-app. * * dialer-app 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; version 3. * * dialer-app 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 . */ import QtQuick 2.3 import QtTest 1.0 import Lomiri.Test 0.1 import Lomiri.Components 1.1 import '../../modules/Lomiri/Components/Extras/PhotoEditor' Item { id: root width: units.gu(40) height: units.gu(60) BusyIndicator { id: busyIndicator text: "BusyIndicatorText" } LomiriTestCase { id: busyIndicatorTestCase name: 'busyIndicatorTestCase' when: windowShown function init() { waitForRendering(busyIndicator); } function cleanup() { } function test_busyIndicatorCheckInvisibleWhenNotRunning() { busyIndicator.running = false tryCompare(busyIndicator, 'visible', false) } function test_busyIndicatorCheckIsVisibleWhenRunning() { busyIndicator.running = true tryCompare(busyIndicator, 'visible', true) } function test_busyIndicatorCheckLabelInvisibleWhenNotLongOperation() { busyIndicator.running = true busyIndicator.longOperation = false var l = findChild(busyIndicator, 'busyLabel') tryCompare(l, 'visible', false) } function test_busyIndicatorCheckLabelIsVisibleWhenLongOperation() { busyIndicator.running = true busyIndicator.longOperation = true var l = findChild(busyIndicator, 'busyLabel') tryCompare(l, 'visible', true) } function test_busyIndicatorCheckLomiriShapeOpacityWhenNotLongOperation() { busyIndicator.running = true busyIndicator.longOperation = false var us = findChild(busyIndicator, 'busyLomiriShape') tryCompare(us, 'opacity', 0) } function test_busyIndicatorCheckLomiriShapeOpacityWhenLongOperation() { busyIndicator.running = true busyIndicator.longOperation = true var us = findChild(busyIndicator, 'busyLomiriShape') tryCompare(us, 'opacity', 0.75) } } } lomiri-ui-extras-0.6.3/tests/qml/tst_CropDragArea.qml000066400000000000000000000053431455543116500226020ustar00rootroot00000000000000/* * Copyright 2015 Canonical Ltd. * * This file is part of dialer-app. * * dialer-app 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; version 3. * * dialer-app 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 . */ import QtQuick 2.3 import QtTest 1.0 import Lomiri.Test 0.1 import Lomiri.Components 1.1 import '../../modules/Lomiri/Components/Extras/PhotoEditor' Item { id: root width: units.gu(40) height: units.gu(60) CropDragArea { id: cropDragArea anchors.fill: parent } SignalSpy { id: draggedSpy target: cropDragArea signalName: 'dragged' } SignalSpy { id: dragStartedSpy target: cropDragArea signalName: 'dragStarted' } SignalSpy { id: dragCompletedSpy target: cropDragArea signalName: 'dragCompleted' } LomiriTestCase { id: cropDragAreaTestCase name: 'cropDragAreaTestCase' when: windowShown function init() { waitForRendering(cropDragArea); } function cleanup() { draggedSpy.clear() dragStartedSpy.clear() dragCompletedSpy.clear() } function test_cropDragAreaCheckDragExecution() { mousePress(cropDragArea, cropDragArea.width / 2, cropDragArea.height / 2) dragStartedSpy.wait() compare(dragStartedSpy.count, 1, 'dragStarted signal was not emitted.') mouseMove(cropDragArea, cropDragArea.width / 2, cropDragArea.height) draggedSpy.wait() compare(draggedSpy.count, 1, 'dragged signal was not emitted.') mouseRelease(cropDragArea, cropDragArea.width / 2, cropDragArea.height) dragCompletedSpy.wait() compare(dragCompletedSpy.count, 1, 'dragCompleted signal was not emitted.') } function test_cropDragAreaCheckClickExecution() { mouseClick(cropDragArea, cropDragArea.width / 2, cropDragArea.height / 2) dragStartedSpy.wait() compare(dragStartedSpy.count, 1, 'dragStarted signal was not emitted.') dragCompletedSpy.wait() compare(dragCompletedSpy.count, 1, 'dragCompleted signal was not emitted.') compare(draggedSpy.count, 0, 'dragged signal was emitted.') } } } lomiri-ui-extras-0.6.3/tests/unittests/000077500000000000000000000000001455543116500201475ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/tests/unittests/CMakeLists.txt000066400000000000000000000022251455543116500227100ustar00rootroot00000000000000include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/modules/Lomiri/Components/Extras/plugin/example/ ${CMAKE_SOURCE_DIR}/modules/Lomiri/Components/Extras/plugin/photoeditor/ ) qt5_add_resources(sampledata_rc_srcs sampledata.qrc) set(plugin-dir ../../modules/Lomiri/Components/Extras/plugin) macro(generate_tests) foreach(test ${ARGN}) add_executable(${test} ${test}.cpp ${plugin-dir}/photoeditor/photo-image-provider.cpp ${sampledata_rc_srcs} ) target_link_libraries(${test} ${TPL_QT5_LIBRARIES} lomiri-ui-extras-plugin Qt5::Core Qt5::Qml Qt5::Quick Qt5::Test ) add_test(${test} ${CMAKE_CURRENT_BINARY_DIR}/${test} -xunitxml -o ${test}.xml ) set_tests_properties(${test} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=minimal" ) endforeach(test) endmacro(generate_tests) generate_tests( tst_ExampleModelTests tst_PhotoEditorPhoto tst_PhotoEditorPhotoImageProvider ) add_subdirectory(Printers) lomiri-ui-extras-0.6.3/tests/unittests/Printers/000077500000000000000000000000001455543116500217555ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/tests/unittests/Printers/CMakeLists.txt000066400000000000000000000054761455543116500245310ustar00rootroot00000000000000set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-permissive -pedantic -Wall -Wextra") include_directories( ${CMAKE_SOURCE_DIR}/modules/Lomiri/Components/Extras/Printers ) find_package(Qt5Gui REQUIRED) find_package(Qt5Test REQUIRED) set(MOCK_SOURCES mockbackend.h ) add_executable(testPrintersPrinter tst_printer.cpp ${MOCK_SOURCES}) target_link_libraries(testPrintersPrinter LomiriComponentsExtrasPrintersQml Qt5::Test Qt5::Gui) add_test(tst_printer testPrintersPrinter) add_executable(testPrintersPrinterJob tst_printerjob.cpp ${MOCK_SOURCES}) target_link_libraries(testPrintersPrinterJob LomiriComponentsExtrasPrintersQml Qt5::Test Qt5::Gui) add_test(tst_printerjob testPrintersPrinterJob) add_executable(testPrintersPrinters tst_printers.cpp ${MOCK_SOURCES}) target_link_libraries(testPrintersPrinters LomiriComponentsExtrasPrintersQml Qt5::Test Qt5::Gui) add_test(tst_printers testPrintersPrinters) set_tests_properties(tst_printers PROPERTIES ENVIRONMENT "XDG_DATA_DIRS=${CMAKE_CURRENT_SOURCE_DIR}/testdata") add_executable(testPrintersPrinterModel tst_printermodel.cpp ${MOCK_SOURCES}) target_link_libraries(testPrintersPrinterModel LomiriComponentsExtrasPrintersQml Qt5::Test Qt5::Gui) add_test(tst_printermodel testPrintersPrinterModel) add_executable(testPrintersPrinterFilter tst_printerfilter.cpp ${MOCK_SOURCES}) target_link_libraries(testPrintersPrinterFilter LomiriComponentsExtrasPrintersQml Qt5::Test Qt5::Gui) add_test(tst_printerfilter testPrintersPrinterFilter) add_executable(testPrintersDriverModel tst_drivermodel.cpp ${MOCK_SOURCES}) target_link_libraries(testPrintersDriverModel LomiriComponentsExtrasPrintersQml Qt5::Test Qt5::Gui) add_test(tst_drivermodel testPrintersDriverModel) add_executable(testPrintersJobModel tst_jobmodel.cpp ${MOCK_SOURCES}) target_link_libraries(testPrintersJobModel LomiriComponentsExtrasPrintersQml Qt5::Test Qt5::Gui) add_test(tst_jobmodel testPrintersJobModel) add_executable(testPrintersJobFilter tst_jobfilter.cpp ${MOCK_SOURCES}) target_link_libraries(testPrintersJobFilter LomiriComponentsExtrasPrintersQml Qt5::Test Qt5::Gui) add_test(tst_jobfilter testPrintersJobFilter) add_executable(testPrintersSignalRateLimiter tst_signalratelimiter.cpp ${MOCK_SOURCES}) target_link_libraries(testPrintersSignalRateLimiter LomiriComponentsExtrasPrintersQml Qt5::Test Qt5::Gui) add_test(tst_signalratelimiter testPrintersSignalRateLimiter) add_executable(testPrintersDevice tst_printerdevice.cpp ${MOCK_SOURCES}) target_link_libraries(testPrintersDevice LomiriComponentsExtrasPrintersQml Qt5::Test Qt5::Gui) add_test(tst_printerdevice testPrintersDevice) add_executable(testPrintersDeviceModel tst_printerdevicemodel.cpp ${MOCK_SOURCES}) target_link_libraries(testPrintersDeviceModel LomiriComponentsExtrasPrintersQml Qt5::Test Qt5::Gui) add_test(tst_printerdevicemodel testPrintersDeviceModel) lomiri-ui-extras-0.6.3/tests/unittests/Printers/mockbackend.h000066400000000000000000000370061455543116500243750ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USC_PRINTERS_MOCK_BACKEND_H #define USC_PRINTERS_MOCK_BACKEND_H #include "backend/backend.h" #include "utils.h" class MockPrinterBackend : public PrinterBackend { Q_OBJECT public: explicit MockPrinterBackend(QObject *parent = Q_NULLPTR) : MockPrinterBackend(QString(), parent) { }; explicit MockPrinterBackend(const QString &printerName, QObject *parent = Q_NULLPTR) : PrinterBackend(printerName, parent) { }; virtual ~MockPrinterBackend() {}; virtual bool holdsDefinition() const override { return m_holdsDefinition; } virtual QString printerAdd(const QString &name, const QString &uri, const QString &ppdFile, const QString &info, const QString &location) override { Q_UNUSED(name); Q_UNUSED(uri); Q_UNUSED(ppdFile); Q_UNUSED(info); Q_UNUSED(location); return returnValue; } virtual QString printerAddWithPpd(const QString &name, const QString &uri, const QString &ppdFileName, const QString &info, const QString &location) override { Q_UNUSED(name); Q_UNUSED(uri); Q_UNUSED(ppdFileName); Q_UNUSED(info); Q_UNUSED(location); return returnValue; } virtual QString printerDelete(const QString &name) override { Q_FOREACH(QSharedPointer p, m_availablePrinters) { if (p->name() == name) { m_availablePrinters.removeOne(p); break; } } return returnValue; } virtual QString printerSetDefault(const QString &name) override { m_defaultPrinterName = name; return returnValue; } virtual QString printerSetEnabled(const QString &name, const bool enabled) override { enableds.insert(name, enabled); return returnValue; } virtual QString printerSetAcceptJobs( const QString &name, const bool accept, const QString &reason = QString()) override { Q_UNUSED(reason); printerOptions[name].insert("AcceptJobs", accept); return returnValue; } virtual QString printerSetCopies(const QString &name, const int &copies) { printerOptions[name].insert("Copies", copies); return returnValue; } virtual QString printerSetShared(const QString &name, const bool shared) override { printerOptions[name].insert("Shared", shared); return returnValue; } virtual QString printerSetInfo(const QString &name, const QString &info) override { infos.insert(name, info); return returnValue; } virtual QString printerAddOption(const QString &name, const QString &option, const QStringList &values) override { printerOptions[name].insert(option, values); return returnValue; } virtual QVariant printerGetOption(const QString &name, const QString &option) const override { return printerOptions[name].value(option); } virtual QMap printerGetOptions( const QString &name, const QStringList &options) const override { QMap opts; Q_FOREACH(const QString &option, options) { opts[option] = printerGetOption(name, option); } return opts; } virtual cups_dest_t* makeDest(const QString &name, const PrinterJob *options) override { Q_UNUSED(name); Q_UNUSED(options); return Q_NULLPTR; } virtual void cancelJob(const QString &name, const int jobId) override { QList toRemove; for (int i=0; i < m_jobs.count(); i++) { QSharedPointer job = m_jobs[i]; if (job->printerName() == name && job->jobId() == jobId) { toRemove << i; } } for (int i=0; i < toRemove.count(); i++) { QSharedPointer job = m_jobs.takeAt(toRemove[i] - i); Q_EMIT jobCompleted(job->title(), "", job->printerName(), 1, "", true, job->jobId(), 1, "", "", 1); } } virtual void holdJob(const QString &printerName, const int jobId) override { // Change the faked job state Q_FOREACH(auto job, m_jobs) { if (job->printerName() == printerName && job->jobId() == jobId) { job->setState(PrinterEnum::JobState::Held); } } Q_EMIT jobState("", "", printerName, 1, "", true, jobId, static_cast(PrinterEnum::JobState::Held), "", "", 1); } virtual void releaseJob(const QString &printerName, const int jobId) override { // Change the faked job state Q_FOREACH(auto job, m_jobs) { if (job->printerName() == printerName && job->jobId() == jobId) { job->setState(PrinterEnum::JobState::Pending); } } Q_EMIT jobState("", "", printerName, 1, "", true, jobId, static_cast(PrinterEnum::JobState::Pending), "", "", 1); } virtual int printFileToDest(const QString &filepath, const QString &title, const cups_dest_t *dest) override { Q_UNUSED(filepath); Q_UNUSED(title); Q_UNUSED(dest); Q_EMIT printToFile(filepath, title); return -1; } virtual QList> printerGetJobs() override { return m_jobs; } virtual QMap printerGetJobAttributes( const QString &name, const int jobId) override { QMap attributes; Q_FOREACH(auto job, m_jobs) { if (job->printerName() == name && job->jobId() == jobId) { // Emulate reverse of PrinterJob::loadAttributes // using local jobs defined in tests attributes.insert("Collate", job->collate()); attributes.insert("copies", job->copies()); attributes.insert("ColorModel", job->getColorModel().name); attributes.insert("CompletedTime", job->completedTime()); attributes.insert("CreationTime", job->creationTime()); attributes.insert("Duplex", Utils::duplexModeToPpdChoice(job->getDuplexMode())); attributes.insert("impressionsCompleted", job->impressionsCompleted()); attributes.insert("landscape", job->landscape()); attributes.insert("messages", job->messages()); if (job->printRangeMode() == PrinterEnum::PrintRange::AllPages) { attributes.insert("page-ranges", QStringList()); } else { attributes.insert("page-ranges", job->printRange().split(QLocale::system().groupSeparator())); } attributes.insert("ProcessingTime", job->processingTime()); attributes.insert("Quality", job->getPrintQuality().name); attributes.insert("OutputOrder", job->reverse() ? "Reverse" : "Normal"); attributes.insert("State", static_cast(job->state())); attributes.insert("Size", job->size()); attributes.insert("User", job->user()); break; } } return attributes; } virtual QString printerName() const override { return m_printerName; } virtual QString description() const override { return m_description; } virtual QString location() const override { return m_location; } virtual QString makeAndModel() const override { return m_makeAndModel; } virtual bool isRemote() const override { return m_remote; } virtual PrinterEnum::State state() const override { return m_state; } virtual QList supportedPageSizes() const override { return m_supportedPageSizes; } virtual QPageSize defaultPageSize() const override { return m_defaultPageSize; } virtual bool supportsCustomPageSizes() const override { return false; } virtual QPageSize minimumPhysicalPageSize() const override { return QPageSize(); } virtual QPageSize maximumPhysicalPageSize() const override { return QPageSize(); } virtual QList supportedResolutions() const override { return QList{}; } virtual PrinterEnum::DuplexMode defaultDuplexMode() const override { auto ppdMode = printerGetOption(printerName(), "Duplex").toString(); return Utils::ppdChoiceToDuplexMode(ppdMode); } virtual QList supportedDuplexModes() const override { return m_supportedDuplexModes; } virtual QList> availablePrinters() override { return m_availablePrinters; } virtual QStringList availablePrinterNames() override { return m_availablePrinterNames; } virtual QSharedPointer getPrinter(const QString &printerName) override { Q_FOREACH(auto p, m_availablePrinters) { if (p->name() == printerName) { return p; } } return QSharedPointer(Q_NULLPTR); } virtual QString defaultPrinterName() override { return m_defaultPrinterName; } virtual void requestPrinter(const QString &printerName) override { m_requestedPrinters << printerName; } virtual void requestJobExtendedAttributes(QSharedPointer printer, QSharedPointer job) override { QMap attributes = printerGetJobAttributes(printer->name(), job->jobId()); Q_EMIT jobLoaded(printer->name(), job->jobId(), attributes); } virtual PrinterEnum::PrinterType type() const override { return m_type; } void mockPrinterAdded( const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs ) { Q_EMIT printerAdded(text, printerUri, printerName, printerState, printerStateReason, acceptingJobs); } void mockPrinterModified( const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs ) { Q_EMIT printerModified(text, printerUri, printerName, printerState, printerStateReason, acceptingJobs); } void mockPrinterDeleted( const QString &text, const QString &printerUri, const QString &printerName, uint printerState, const QString &printerStateReason, bool acceptingJobs ) { Q_EMIT printerDeleted(text, printerUri, printerName, printerState, printerStateReason, acceptingJobs); } void mockJobCreated( const QString &text, const QString &printer_uri, const QString &printer_name, uint printer_state, const QString &printer_state_reasons, bool printer_is_accepting_jobs, uint job_id, uint job_state, const QString &job_state_reasons, const QString &job_name, uint job_impressions_completed ) { Q_EMIT jobCreated( text, printer_uri, printer_name, printer_state, printer_state_reasons, printer_is_accepting_jobs, job_id, job_state, job_state_reasons, job_name, job_impressions_completed ); } void mockJobCompleted( const QString &text, const QString &printer_uri, const QString &printer_name, uint printer_state, const QString &printer_state_reasons, bool printer_is_accepting_jobs, uint job_id, uint job_state, const QString &job_state_reasons, const QString &job_name, uint job_impressions_completed) { Q_EMIT jobCompleted( text, printer_uri, printer_name, printer_state, printer_state_reasons, printer_is_accepting_jobs, job_id, job_state, job_state_reasons, job_name, job_impressions_completed ); } void mockJobState( const QString &text, const QString &printer_uri, const QString &printer_name, uint printer_state, const QString &printer_state_reasons, bool printer_is_accepting_jobs, uint job_id, uint job_state, const QString &job_state_reasons, const QString &job_name, uint job_impressions_completed) { Q_EMIT jobState( text, printer_uri, printer_name, printer_state, printer_state_reasons, printer_is_accepting_jobs, job_id, job_state, job_state_reasons, job_name, job_impressions_completed ); } void mockDriversLoaded(const QList &drivers) { Q_EMIT printerDriversLoaded(drivers); } void mockDriversLoaded(const QString &errorMessage) { Q_EMIT printerDriversFailedToLoad(errorMessage); } void mockPrinterLoaded(QSharedPointer printer) { Q_EMIT printerLoaded(printer); } void mockDeviceFound(const Device &device) { Q_EMIT deviceFound(device); } QString returnValue = QString(); // Map from printer to key/val. QMap> printerOptions; QMap enableds; QMap shareds; QMap infos; QMap locations; QMap errorPolicies; QMap operationPolicies; bool m_holdsDefinition = true; bool m_remote = false; QString m_description = QString(); QString m_location = QString(); QString m_makeAndModel = QString(); QString m_defaultPrinterName = QString(); PrinterEnum::State m_state = PrinterEnum::State::IdleState; QPageSize m_defaultPageSize; QList m_supportedPageSizes; QList m_supportedDuplexModes; QStringList m_availablePrinterNames; QList> m_availablePrinters; QList> m_jobs; QStringList m_requestedPrinters; PrinterEnum::PrinterType m_type = PrinterEnum::PrinterType::ProxyType; Q_SIGNALS: void printToFile(const QString &filepath, const QString &title); }; #endif // USC_PRINTERS_MOCK_BACKEND_H lomiri-ui-extras-0.6.3/tests/unittests/Printers/testdata/000077500000000000000000000000001455543116500235665ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/tests/unittests/Printers/testdata/cups/000077500000000000000000000000001455543116500245405ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/tests/unittests/Printers/testdata/cups/data/000077500000000000000000000000001455543116500254515ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/tests/unittests/Printers/testdata/cups/data/default-testpage.pdf000066400000000000000000000000001455543116500313700ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/tests/unittests/Printers/tst_drivermodel.cpp000066400000000000000000000077021455543116500256750ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "mockbackend.h" #include "backend/backend.h" #include "models/drivermodel.h" #include #include #include #include class TestDriverModel : public QObject { Q_OBJECT private Q_SLOTS: void init() { m_backend = new MockPrinterBackend; m_model = new DriverModel(m_backend); } void cleanup() { QSignalSpy destroyedSpy(m_model, SIGNAL(destroyed(QObject*))); m_model->deleteLater(); QTRY_COMPARE(destroyedSpy.count(), 1); delete m_backend; } void testDrivers_data() { QTest::addColumn>("drivers"); QTest::addColumn("expectedCount"); { QList drivers; QTest::newRow("none") << drivers << 0; } { QList drivers({PrinterDriver(), PrinterDriver()}); QTest::newRow("some") << drivers << 2; } } void testDrivers() { QFETCH(QList, drivers); QFETCH(int, expectedCount); m_model->load(); getBackend()->mockDriversLoaded(drivers); QCOMPARE(m_model->rowCount(), expectedCount); } void testFiltering_data() { QTest::addColumn>("drivers"); QTest::addColumn>("expectedDrivers"); QTest::addColumn("filter"); { QList drivers; QList expectedDrivers; PrinterDriver canon; canon.makeModel = "Canon Foojet"; PrinterDriver hp; hp.makeModel = "HP Laserfjert"; drivers << canon << hp; expectedDrivers << hp; QTest::newRow("filter hp") << drivers << expectedDrivers << "hp"; } { QList drivers; QList expectedDrivers; PrinterDriver canon; canon.makeModel = "Canon 4500 Foojet"; PrinterDriver canon2; canon2.makeModel = "rabble rabble canon 4500 masterjet"; PrinterDriver hp; hp.makeModel = "HP Laserfjert"; drivers << canon << canon2 << hp; expectedDrivers << canon << canon2; QTest::newRow("filter canon 4500 printers") << drivers << expectedDrivers << "canon 4500"; } } void testFiltering() { QFETCH(QList, drivers); QFETCH(QList, expectedDrivers); QFETCH(QString, filter); m_model->load(); getBackend()->mockDriversLoaded(drivers); QSignalSpy filterCompleteSpy(m_model, SIGNAL(filterComplete())); m_model->setFilter(filter); QTRY_COMPARE(filterCompleteSpy.count(), 1); QCOMPARE(m_model->rowCount(), expectedDrivers.size()); for (int i = 0; i < m_model->rowCount(); i++) { QCOMPARE( expectedDrivers.at(i).makeModel, m_model->data(m_model->index(i), DriverModel::Roles::MakeModelRole).toByteArray() ); } } private: PrinterBackend *m_backend; DriverModel *m_model; MockPrinterBackend* getBackend() { return (MockPrinterBackend*) m_backend; } }; QTEST_GUILESS_MAIN(TestDriverModel) #include "tst_drivermodel.moc" lomiri-ui-extras-0.6.3/tests/unittests/Printers/tst_jobfilter.cpp000066400000000000000000000032061455543116500253340ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "mockbackend.h" #include "models/jobmodel.h" #include #include #include #include class TestJobFilter : public QObject { Q_OBJECT private Q_SLOTS: void testFilterOnPrinter() { QScopedPointer backend(new MockPrinterBackend); JobModel model(backend.data()); auto job = QSharedPointer( new PrinterJob("test-printer", backend.data(), 100) ); backend->m_jobs << job; // Trigger update. backend->mockJobCreated("", "", "test-printer", 1, "", true, 100, 3, "", "", 1); JobFilter filter; filter.setSourceModel(&model); QCOMPARE(filter.count(), 1); // Install filter. filter.filterOnPrinterName("other-printer"); QCOMPARE(filter.count(), 0); filter.filterOnPrinterName("test-printer"); QCOMPARE(filter.count(), 1); } }; QTEST_GUILESS_MAIN(TestJobFilter) #include "tst_jobfilter.moc" lomiri-ui-extras-0.6.3/tests/unittests/Printers/tst_jobmodel.cpp000066400000000000000000000556371455543116500251660ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "mockbackend.h" #include "backend/backend.h" #include "models/jobmodel.h" #include "printers/printers.h" #include #include #include #include class TestJobModel : public QObject { Q_OBJECT private Q_SLOTS: void init() { m_backend = new MockPrinterBackend; m_printers = new Printers(m_backend); m_model = static_cast(m_printers->printJobs()); PrinterBackend* backend = new MockPrinterBackend("test-printer"); auto printer = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printer); } void cleanup() { QSignalSpy destroyedSpy(m_printers, SIGNAL(destroyed(QObject*))); m_printers->deleteLater(); QTRY_COMPARE(destroyedSpy.count(), 1); } // Tests for adding/removing/changing things in the model void testInsert() { QSignalSpy countSpy(m_model, SIGNAL(countChanged())); QSignalSpy insertSpy(m_model, SIGNAL(rowsInserted(const QModelIndex&, int, int))); auto job = QSharedPointer(new PrinterJob("test-printer", m_backend)); m_backend->m_jobs << job; // Trigger update. m_backend->mockJobCreated("", "", "", 1, "", true, 100, 1, "", "", 1); QCOMPARE(m_model->count(), 1); QCOMPARE(countSpy.count(), 1); QCOMPARE(insertSpy.count(), 1); } void testRemove() { // Add one. auto job = QSharedPointer(new PrinterJob("test-printer", m_backend)); m_backend->m_jobs << job; m_backend->mockJobCreated("", "", "", 1, "", true, 100, 1, "", "", 1); QCOMPARE(m_model->count(), 1); /* Trigger another update, ignore the signal name here; there's a catchall handler in the model. */ QSignalSpy removeSpy(m_model, SIGNAL(rowsRemoved(const QModelIndex&, int, int))); m_backend->m_jobs.clear(); m_backend->mockJobCompleted("", "", "", 1, "", true, 100, 1, "", "", 1); QCOMPARE(removeSpy.count(), 1); // Check item was removed QList args = removeSpy.at(0); QCOMPARE(args.at(1).toInt(), 0); QCOMPARE(args.at(2).toInt(), 0); } void testModify() { auto jobBefore = QSharedPointer(new PrinterJob("test-printer", m_backend, 1)); int impressions_count = 1; m_backend->m_jobs << jobBefore; m_backend->mockJobCreated("", "", "", 1, "", true, 100, 1, "", "", impressions_count); // Triggers a change. QSignalSpy changedSpy(m_model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector&))); impressions_count = 5; m_backend->mockJobState("", "", "", 1, "", true, 100, 1, "", "", impressions_count); QCOMPARE(changedSpy.count(), 1); } // Tests for the roles in the model exposed to QML void testIdRole() { auto job = QSharedPointer(new PrinterJob("test-printer", m_backend, 100)); m_backend->m_jobs << job; m_backend->mockJobCreated("", "", "", 1, "", true, 100, 1, "", "", 1); QTRY_COMPARE(m_model->count(), 1); QCOMPARE(job->jobId(), 100); QCOMPARE(m_model->data(m_model->index(0), JobModel::IdRole).toInt(), 100); } void testCollateRole() { auto jobA = QSharedPointer(new PrinterJob("test-printer", m_backend, 1)); jobA->setCollate(false); auto jobB = QSharedPointer(new PrinterJob("test-printer", m_backend, 2)); jobB->setCollate(true); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, 1, "", "", 1); m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 2, 1, "", "", 1); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::CollateRole).toBool(), false); QCOMPARE(m_model->data(m_model->index(1), JobModel::CollateRole).toBool(), true); } void testColorModelRole() { // FIXME: read comment in JobModel::updateJob QSKIP("We are ignoring colorModel for now as it requires a loaded Printer for the PrinterJob."); ColorModel a; a.name = "KGray"; a.text = "Gray"; ColorModel b; b.name = "RGB"; b.text = ""; QList models({a, b}); PrinterBackend* backend = new MockPrinterBackend("a-printer"); ((MockPrinterBackend*) backend)->printerOptions["a-printer"].insert( "SupportedColorModels", QVariant::fromValue(models) ); auto printer = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printer); // m_printers->m_printers << printer; auto jobA = QSharedPointer(new PrinterJob("a-printer", backend, 1)); jobA->setPrinter(printer); jobA->loadDefaults(); jobA->setColorModel(models.indexOf(a)); auto jobB = QSharedPointer(new PrinterJob("a-printer", backend, 2)); jobB->setPrinter(printer); jobB->loadDefaults(); jobB->setColorModel(models.indexOf(b)); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "a-printer", 1, "", true, 1, 1, "", "", 1); m_backend->mockJobCreated("", "", "a-printer", 1, "", true, 2, 1, "", "", 1); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::ColorModelRole).toString(), a.text); QCOMPARE(m_model->data(m_model->index(1), JobModel::ColorModelRole).toString(), b.name); } void testCompletedTimeRole() { QDateTime dateTimeA = QDateTime::currentDateTime(); QDateTime dateTimeB = QDateTime::currentDateTime().addSecs(100); auto jobA = QSharedPointer(new PrinterJob("test-printer", m_backend, 1)); jobA->setCompletedTime(dateTimeA); auto jobB = QSharedPointer(new PrinterJob("test-printer", m_backend, 2)); jobB->setCompletedTime(dateTimeB); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, 1, "", "", 1); m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 2, 1, "", "", 1); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::CompletedTimeRole).toDateTime(), dateTimeA); QCOMPARE(m_model->data(m_model->index(1), JobModel::CompletedTimeRole).toDateTime(), dateTimeB); } void testCopiesRole() { auto jobA = QSharedPointer(new PrinterJob("test-printer", m_backend, 1)); jobA->setCopies(2); auto jobB = QSharedPointer(new PrinterJob("test-printer", m_backend, 2)); jobB->setCopies(5); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, 1, "", "", 1); m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 2, 1, "", "", 1); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::CopiesRole).toInt(), 2); QCOMPARE(m_model->data(m_model->index(1), JobModel::CopiesRole).toInt(), 5); } void testCreationTimeRole() { QDateTime dateTimeA = QDateTime::currentDateTime(); QDateTime dateTimeB = QDateTime::currentDateTime().addSecs(100); auto jobA = QSharedPointer(new PrinterJob("test-printer", m_backend, 1)); jobA->setCreationTime(dateTimeA); auto jobB = QSharedPointer(new PrinterJob("test-printer", m_backend, 2)); jobB->setCreationTime(dateTimeB); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, 1, "", "", 1); m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 2, 1, "", "", 1); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::CreationTimeRole).toDateTime(), dateTimeA); QCOMPARE(m_model->data(m_model->index(1), JobModel::CreationTimeRole).toDateTime(), dateTimeB); } void testDuplexRole() { // FIXME: read comment in JobModel::updateJob QSKIP("We are ignoring duplex for now as it requires a loaded Printer for the PrinterJob."); QList modes({ PrinterEnum::DuplexMode::DuplexNone, PrinterEnum::DuplexMode::DuplexLongSide, PrinterEnum::DuplexMode::DuplexShortSide, }); ((MockPrinterBackend*) m_backend)->m_supportedDuplexModes = modes; PrinterBackend* backend = new MockPrinterBackend("test-printer"); ((MockPrinterBackend*) backend)->m_supportedDuplexModes = modes; auto printer = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printer); auto jobA = QSharedPointer(new PrinterJob("test-printer", backend, 1)); jobA->setPrinter(printer); jobA->setDuplexMode(modes.indexOf(PrinterEnum::DuplexMode::DuplexLongSide)); auto jobB = QSharedPointer(new PrinterJob("test-printer", backend, 2)); jobB->setPrinter(printer); jobB->setDuplexMode(modes.indexOf(PrinterEnum::DuplexMode::DuplexNone)); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, 1, "", "", 1); m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 2, 1, "", "", 1); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::DuplexRole).toString(), Utils::duplexModeToUIString(PrinterEnum::DuplexMode::DuplexLongSide)); QCOMPARE(m_model->data(m_model->index(1), JobModel::DuplexRole).toString(), Utils::duplexModeToUIString(PrinterEnum::DuplexMode::DuplexNone)); } void testHeldRole() { auto jobA = QSharedPointer(new PrinterJob("test-printer", m_backend, 1)); jobA->setState(PrinterEnum::JobState::Pending); auto jobB = QSharedPointer(new PrinterJob("test-printer", m_backend, 2)); jobB->setState(PrinterEnum::JobState::Held); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, static_cast(jobA->state()), "", "", 1); m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 2, static_cast(jobB->state()), "", "", 1); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::HeldRole).toBool(), false); QCOMPARE(m_model->data(m_model->index(1), JobModel::HeldRole).toBool(), true); } void testImpressionsCompletedRole() { auto jobA = QSharedPointer(new PrinterJob("test-printer", m_backend, 1)); jobA->setImpressionsCompleted(2); auto jobB = QSharedPointer(new PrinterJob("test-printer", m_backend, 2)); jobB->setImpressionsCompleted(5); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, 1, "", "", jobA->impressionsCompleted()); m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 2, 1, "", "", jobB->impressionsCompleted()); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::ImpressionsCompletedRole).toInt(), 2); QCOMPARE(m_model->data(m_model->index(1), JobModel::ImpressionsCompletedRole).toInt(), 5); } void testLandscapeRole() { auto jobA = QSharedPointer(new PrinterJob("test-printer", m_backend, 1)); jobA->setLandscape(false); auto jobB = QSharedPointer(new PrinterJob("test-printer", m_backend, 2)); jobB->setLandscape(true); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, 1, "", "", 1); m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 2, 1, "", "", 1); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::LandscapeRole).toBool(), false); QCOMPARE(m_model->data(m_model->index(1), JobModel::LandscapeRole).toBool(), true); } void testMessagesRole() { auto jobA = QSharedPointer(new PrinterJob("test-printer", m_backend, 1)); jobA->setMessages(QStringList() << "a-message" << "b-message"); auto jobB = QSharedPointer(new PrinterJob("test-printer", m_backend, 2)); jobB->setMessages(QStringList() << "c-message" << "d-message"); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, 1, "", "", 1); m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 2, 1, "", "", 1); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::MessagesRole).toStringList(), QStringList() << "a-message" << "b-message"); QCOMPARE(m_model->data(m_model->index(1), JobModel::MessagesRole).toStringList(), QStringList() << "c-message" << "d-message"); } void testPrinterNameRole() { auto jobA = QSharedPointer(new PrinterJob("a-printer", m_backend, 1)); auto jobB = QSharedPointer(new PrinterJob("b-printer", m_backend, 2)); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "a-printer", 1, "", true, 1, 1, "", "", 1); m_backend->mockJobCreated("", "", "b-printer", 1, "", true, 2, 1, "", "", 1); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::PrinterNameRole).toString(), QString("a-printer")); QCOMPARE(m_model->data(m_model->index(1), JobModel::PrinterNameRole).toString(), QString("b-printer")); } void testPrintRangeRole() { auto jobA = QSharedPointer(new PrinterJob("test-printer", m_backend, 1)); jobA->setPrintRange("1-3,5"); jobA->setPrintRangeMode(PrinterEnum::PrintRange::PageRange); auto jobB = QSharedPointer(new PrinterJob("test-printer", m_backend, 2)); jobB->setPrintRange("-3,6,10-"); jobB->setPrintRangeMode(PrinterEnum::PrintRange::PageRange); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, 1, "", "", 1); m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 2, 1, "", "", 1); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::PrintRangeRole).toString(), QString("1-3,5")); QCOMPARE(m_model->data(m_model->index(1), JobModel::PrintRangeRole).toString(), QString("-3,6,10-")); } void testPrintRangeModeRole() { auto jobA = QSharedPointer(new PrinterJob("test-printer", m_backend, 1)); jobA->setPrintRangeMode(PrinterEnum::PrintRange::AllPages); auto jobB = QSharedPointer(new PrinterJob("test-printer", m_backend, 2)); jobB->setPrintRange("1-3"); jobB->setPrintRangeMode(PrinterEnum::PrintRange::PageRange); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, 1, "", "", 1); m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 2, 1, "", "", 1); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::PrintRangeModeRole).value(), PrinterEnum::PrintRange::AllPages); QCOMPARE(m_model->data(m_model->index(1), JobModel::PrintRangeModeRole).value(), PrinterEnum::PrintRange::PageRange); } void testProcessingTimeRole() { QDateTime dateTimeA = QDateTime::currentDateTime(); QDateTime dateTimeB = QDateTime::currentDateTime().addSecs(100); auto jobA = QSharedPointer(new PrinterJob("test-printer", m_backend, 1)); jobA->setProcessingTime(dateTimeA); auto jobB = QSharedPointer(new PrinterJob("test-printer", m_backend, 2)); jobB->setProcessingTime(dateTimeB); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, 1, "", "", 1); m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 2, 1, "", "", 1); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::ProcessingTimeRole).toDateTime(), dateTimeA); QCOMPARE(m_model->data(m_model->index(1), JobModel::ProcessingTimeRole).toDateTime(), dateTimeB); } void testQualityRole() { // FIXME: read comment in JobModel::updateJob QSKIP("We are ignoring quality for now as it requires a loaded Printer for the PrinterJob."); PrintQuality a; a.name = "fast-draft"; a.text = "Draft"; PrintQuality b; b.name = "normal"; b.text = ""; QList qualities({a, b}); PrinterBackend *backend = new MockPrinterBackend("a-printer"); ((MockPrinterBackend*) backend)->printerOptions["a-printer"].insert( "SupportedPrintQualities", QVariant::fromValue(qualities) ); auto printer = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printer); auto jobA = QSharedPointer(new PrinterJob("a-printer", backend, 1)); jobA->setPrinter(printer); jobA->setQuality(qualities.indexOf(a)); auto jobB = QSharedPointer(new PrinterJob("a-printer", backend, 2)); jobB->setPrinter(printer); jobB->setQuality(qualities.indexOf(b)); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "a-printer", 1, "", true, 1, 1, "", "", 1); m_backend->mockJobCreated("", "", "a-printer", 1, "", true, 2, 1, "", "", 1); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::QualityRole).toString(), a.text); QCOMPARE(m_model->data(m_model->index(1), JobModel::QualityRole).toString(), b.name); } void testReverseRole() { auto jobA = QSharedPointer(new PrinterJob("test-printer", m_backend, 1)); jobA->setReverse(false); auto jobB = QSharedPointer(new PrinterJob("test-printer", m_backend, 2)); jobB->setReverse(true); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, 1, "", "", 1); m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 2, 1, "", "", 1); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::ReverseRole).toBool(), false); QCOMPARE(m_model->data(m_model->index(1), JobModel::ReverseRole).toBool(), true); } void testSizeRole() { auto jobA = QSharedPointer(new PrinterJob("test-printer", m_backend, 1)); jobA->setSize(32); auto jobB = QSharedPointer(new PrinterJob("test-printer", m_backend, 2)); jobB->setSize(64); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, 1, "", "", 1); m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 2, 1, "", "", 1); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::SizeRole).toInt(), 32); QCOMPARE(m_model->data(m_model->index(1), JobModel::SizeRole).toInt(), 64); } void testStateRole() { auto jobA = QSharedPointer(new PrinterJob("test-printer", m_backend, 1)); jobA->setState(PrinterEnum::JobState::Pending); auto jobB = QSharedPointer(new PrinterJob("test-printer", m_backend, 2)); jobB->setState(PrinterEnum::JobState::Processing); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, static_cast(jobA->state()), "", "", 1); m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 2, static_cast(jobB->state()), "", "", 1); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::StateRole).value(), PrinterEnum::JobState::Pending); QCOMPARE(m_model->data(m_model->index(1), JobModel::StateRole).value(), PrinterEnum::JobState::Processing); } void testTitleRole() { auto jobA = QSharedPointer(new PrinterJob("test-printer", m_backend, 1)); jobA->setTitle("a-job"); auto jobB = QSharedPointer(new PrinterJob("test-printer", m_backend, 2)); jobB->setTitle("b-job"); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, 1, "", jobA->title(), 1); m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 2, 1, "", jobB->title(), 1); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::TitleRole).toString(), QString("a-job")); QCOMPARE(m_model->data(m_model->index(1), JobModel::TitleRole).toString(), QString("b-job")); } void testUserRole() { auto jobA = QSharedPointer(new PrinterJob("test-printer", m_backend, 1)); jobA->setUser("a-user"); auto jobB = QSharedPointer(new PrinterJob("test-printer", m_backend, 2)); jobB->setUser("b-user"); m_backend->m_jobs << jobA << jobB; m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, 1, "", "", 1); m_backend->mockJobCreated("", "", "test-printer", 1, "", true, 2, 1, "", "", 1); QTRY_COMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), JobModel::UserRole).toString(), QString("a-user")); QCOMPARE(m_model->data(m_model->index(1), JobModel::UserRole).toString(), QString("b-user")); } private: MockPrinterBackend *m_backend; JobModel *m_model; Printers *m_printers; }; QTEST_GUILESS_MAIN(TestJobModel) #include "tst_jobmodel.moc" lomiri-ui-extras-0.6.3/tests/unittests/Printers/tst_printer.cpp000066400000000000000000000413751455543116500250500ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "utils.h" #include "mockbackend.h" #include "backend/backend.h" #include "backend/backend_pdf.h" #include "printer/printer.h" #include #include #include #include Q_DECLARE_METATYPE(QList) class TestPrinter : public QObject { Q_OBJECT private Q_SLOTS: void init() { m_backend = new MockPrinterBackend(m_printerName); m_instance = QSharedPointer(new Printer(m_backend)); } void cleanup() { QSignalSpy destroyedSpy(m_instance.data(), SIGNAL(destroyed(QObject*))); m_instance.clear(); QTRY_COMPARE(destroyedSpy.count(), 1); if (m_backend) { delete m_backend; } } void testName() { QCOMPARE(m_backend->printerName(), m_instance->name()); } void testDescription() { m_backend->m_description = "some description"; QCOMPARE(m_backend->description(), m_instance->description()); } void testSetDescription() { QString desc("another description"); m_instance->setDescription(desc); QCOMPARE(m_backend->infos.value(m_printerName), desc); } void testDeviceUri() { MockPrinterBackend *backend = new MockPrinterBackend(m_printerName); backend->printerOptions[m_printerName].insert( "DeviceUri", "/dev/null"); Printer p(backend); QCOMPARE(p.deviceUri(), (QString) "/dev/null"); } void testLastMessage() { MockPrinterBackend *backend = new MockPrinterBackend(m_printerName); backend->printerOptions[m_printerName].insert( "StateMessage", "died"); Printer p(backend); QCOMPARE(p.lastMessage(), (QString) "died"); } void testMakeModel() { m_backend->m_makeAndModel = "make and model"; QCOMPARE(m_instance->make(), m_backend->makeAndModel()); } void testLocation() { m_backend->m_location = "location"; QCOMPARE(m_instance->location(), m_backend->location()); } void testCopies() { MockPrinterBackend *backend = new MockPrinterBackend(m_printerName); backend->printerOptions[m_printerName].insert("Copies", "2"); Printer p(backend); QCOMPARE(p.copies(), 2); } void testSetCopies() { MockPrinterBackend *backend = new MockPrinterBackend(m_printerName); backend->printerOptions[m_printerName].insert("Copies", "2"); Printer p(backend); p.setCopies(5); QCOMPARE(backend->printerOptions[m_printerName].value("Copies").toInt(), 5); } void testRemote() { m_backend->m_remote = false; QCOMPARE(m_instance->isRemote(), m_backend->isRemote()); m_backend->m_remote = true; QCOMPARE(m_instance->isRemote(), m_backend->isRemote()); } void testSupportedDuplexModes_data() { QTest::addColumn>("modes"); QTest::addColumn("strings"); { QList modes({PrinterEnum::DuplexMode::DuplexNone}); QStringList strings({"One Sided"}); QTest::newRow("one") << modes << strings; } { QList modes({PrinterEnum::DuplexMode::DuplexNone, PrinterEnum::DuplexMode::DuplexLongSide}); QStringList strings({"One Sided", "Long Edge (Standard)"}); QTest::newRow("multiple") << modes << strings; } } void testSupportedDuplexModes() { QFETCH(QList, modes); QFETCH(QStringList, strings); m_backend->m_supportedDuplexModes = modes; QCOMPARE(m_instance->supportedDuplexModes(), modes); QCOMPARE(m_instance->supportedDuplexStrings(), strings); } void testDefaultDuplexMode() { QList modes({ PrinterEnum::DuplexMode::DuplexNone, PrinterEnum::DuplexMode::DuplexLongSide, PrinterEnum::DuplexMode::DuplexShortSide}); m_backend->m_supportedDuplexModes = modes; m_instance->setDefaultDuplexMode(PrinterEnum::DuplexMode::DuplexLongSide); QCOMPARE(m_instance->defaultDuplexMode(), PrinterEnum::DuplexMode::DuplexLongSide); m_instance->setDefaultDuplexMode(PrinterEnum::DuplexMode::DuplexNone); QCOMPARE(m_instance->defaultDuplexMode(), PrinterEnum::DuplexMode::DuplexNone); m_instance->setDefaultDuplexMode(PrinterEnum::DuplexMode::DuplexShortSide); QCOMPARE(m_instance->defaultDuplexMode(), PrinterEnum::DuplexMode::DuplexShortSide); } void testSetDefaultDuplexMode() { // Add support QList modes({PrinterEnum::DuplexMode::DuplexNone, PrinterEnum::DuplexMode::DuplexLongSide}); m_backend->m_supportedDuplexModes = modes; m_instance->setDefaultDuplexMode(PrinterEnum::DuplexMode::DuplexLongSide); QVariant duplexVar = m_backend->printerOptions[m_printerName].value("Duplex"); QStringList duplexVals = duplexVar.toStringList(); QCOMPARE( duplexVals.at(0), (QString) Utils::duplexModeToPpdChoice(PrinterEnum::DuplexMode::DuplexLongSide) ); } void testSetDefaultPageSize_data() { QTest::addColumn>("sizes"); QTest::addColumn("size"); QTest::addColumn("expectCupsCommunication"); QTest::addColumn("expectedValue"); { QList sizes; // none supported QPageSize size(QPageSize::A4); QTest::newRow("unsupported") << sizes << size << false << ""; } { QList sizes({QPageSize(QPageSize::A4)}); QPageSize size(QPageSize::A4); QTest::newRow("supported") << sizes << size << true << "A4"; } { QPageSize custom(QSize(100, 100), "foo"); QList sizes({custom}); QTest::newRow("supported, but non-ppd size") << sizes << custom << false << ""; } } void testDefaultPageSize() { auto targetSize = QPageSize(QPageSize::A4); m_backend->m_defaultPageSize = targetSize; QCOMPARE(m_instance->defaultPageSize(), targetSize); } void testSupportedPageSizes_data() { auto supported = QList({QPageSize(QPageSize::A4), QPageSize(QPageSize::Letter)}); m_backend->m_supportedPageSizes = supported; QCOMPARE(m_instance->supportedPageSizes(), supported); } void testSetDefaultPageSize() { QFETCH(QList, sizes); QFETCH(QPageSize, size); QFETCH(bool, expectCupsCommunication); QFETCH(QString, expectedValue); m_backend->m_supportedPageSizes = sizes; m_instance->setDefaultPageSize(size); QVariant pageSizeVar = m_backend->printerOptions[m_printerName].value("PageSize"); QStringList pageSizeVals = pageSizeVar.toStringList(); if (expectCupsCommunication) { QCOMPARE(pageSizeVals.at(0), expectedValue); } } void testDefaultColorMode() { ColorModel colorModel; QCOMPARE(m_instance->defaultColorModel(), colorModel); } void testSupportedColorModels() { ColorModel a; a.text = "Gray"; ColorModel b; b.text = "RBG"; QList models({a, b}); PrinterBackend *backend = new MockPrinterBackend(m_printerName); ((MockPrinterBackend*) backend)->printerOptions[m_printerName].insert( "SupportedColorModels", QVariant::fromValue(models)); Printer p(backend); QCOMPARE(p.supportedColorModels(), models); } void testDefaultPrintQuality() { PrintQuality quality; QCOMPARE(m_instance->defaultPrintQuality(), quality); } void testSupportedQualities() { PrintQuality a; a.name = "Poor"; PrintQuality b; b.name = "Worse"; QList qualities({a, b}); MockPrinterBackend *backend = new MockPrinterBackend(m_printerName); backend->printerOptions[m_printerName].insert( "SupportedPrintQualities", QVariant::fromValue(qualities)); Printer p(backend); QCOMPARE(p.supportedPrintQualities(), qualities); } void testPdfPrinter() { PrinterBackend *backend = new PrinterPdfBackend(m_printerName); Printer p(backend); QCOMPARE(p.defaultColorModel().name, QString("RGB")); QCOMPARE(p.defaultPageSize(), QPageSize(QPageSize::A4)); QCOMPARE(p.defaultDuplexMode(), PrinterEnum::DuplexMode::DuplexNone); QCOMPARE(p.type(), PrinterEnum::PrinterType::PdfType); } void testState() { m_backend->m_state = PrinterEnum::State::AbortedState; QCOMPARE(m_instance->state(), m_backend->m_state); } void testEnabled() { m_backend->m_state = PrinterEnum::State::ErrorState; QCOMPARE(m_instance->enabled(), false); m_backend->m_state = PrinterEnum::State::IdleState; QCOMPARE(m_instance->enabled(), true); } void testSetEnabled() { /* This is needed to make a printer disabled. If it's not disabled, the printer does not attempt to set a new value. */ m_backend->m_state = PrinterEnum::State::ErrorState; m_instance->setEnabled(true); QCOMPARE(m_backend->enableds[m_printerName], true); } void testAcceptJobs() { MockPrinterBackend *backend = new MockPrinterBackend(m_printerName); backend->printerOptions[m_printerName].insert("AcceptJobs", false); Printer p(backend); QVERIFY(!p.acceptJobs()); backend->printerOptions[m_printerName].insert("AcceptJobs", true); Printer p2(backend); QVERIFY(p2.acceptJobs()); } void testSetAcceptJobs() { MockPrinterBackend *backend = new MockPrinterBackend(m_printerName); backend->printerOptions[m_printerName].insert("AcceptJobs", false); Printer p(backend); p.setAcceptJobs(true); QVERIFY(backend->printerOptions[m_printerName]["AcceptJobs"].toBool()); backend->printerOptions[m_printerName].insert("AcceptJobs", true); Printer p2(backend); p2.setAcceptJobs(false); QVERIFY(!backend->printerOptions[m_printerName]["AcceptJobs"].toBool()); } void testShared() { MockPrinterBackend *backend = new MockPrinterBackend(m_printerName); backend->printerOptions[m_printerName].insert("Shared", false); Printer p(backend); QVERIFY(!p.shared()); backend->printerOptions[m_printerName].insert("Shared", true); Printer p2(backend); QVERIFY(p2.shared()); } void testSetShared() { MockPrinterBackend *backend = new MockPrinterBackend(m_printerName); backend->printerOptions[m_printerName].insert("Shared", false); Printer p(backend); p.setShared(true); QVERIFY(backend->printerOptions[m_printerName]["Shared"].toBool()); backend->printerOptions[m_printerName].insert("Shared", true); Printer p2(backend); p2.setShared(false); QVERIFY(!backend->printerOptions[m_printerName]["Shared"].toBool()); } void testJobs() { JobModel jobs; jobs.setObjectName("testjobs"); m_instance->setJobModel(&jobs); QAbstractProxyModel *proxy = qobject_cast( m_instance->jobs() ); QCOMPARE(proxy->sourceModel()->objectName(), jobs.objectName()); } /* There was a bug causing QML thread assertion to fail. The assertion requires all QObjects accessed from QML to be in the same thread as QML. For newly loaded non-proxy printers, this was not the case. This test serves as a regression test, as well as a place where we can make sure every QObject of the Printer API moves thread when the printer itself moves. For POD, this is inconsequential. */ void testPrinterMovesProperlyFromThread() { MockPrinterBackend *backend = new MockPrinterBackend(m_printerName); Printer p(backend); QThread thread; p.moveToThread(&thread); QCOMPARE(p.thread(), &thread); // Ideally, all QObjects in the Printer API needs to be tested here. QCOMPARE(p.jobs()->thread(), &thread); } void testUpdateFrom() { // Setup any variables for flipped values bool newAcceptJobs = !m_instance->acceptJobs(); int newCopies = m_instance->copies() + 1; QString newDeviceUri = m_instance->deviceUri() + "/test"; bool newShared = !m_instance->shared(); QString newLastMessage = m_instance->lastMessage() + "test"; // Setup color model and quality models ColorModel colorA; colorA.text = "ColorA"; ColorModel defaultColorModel; defaultColorModel.text = "ColorB"; QList colorModels({colorA, defaultColorModel}); PrintQuality qualityA; qualityA.name = "QualityA"; PrintQuality defaultPrintQuality; defaultPrintQuality.name = "QualityB"; QList qualities({qualityA, defaultPrintQuality}); QList duplexModes({ PrinterEnum::DuplexMode::DuplexNone, PrinterEnum::DuplexMode::DuplexLongSide, PrinterEnum::DuplexMode::DuplexShortSide, PrinterEnum::DuplexMode::DuplexShortSide }); auto newDefaultDuplexMode = m_instance->defaultDuplexMode() == PrinterEnum::DuplexMode::DuplexNone ? PrinterEnum::DuplexMode::DuplexShortSide : PrinterEnum::DuplexMode::DuplexNone; // Create a printer that has different settings to the default QString printerName = "test-printer-b"; MockPrinterBackend *backend = new MockPrinterBackend(printerName); backend->printerOptions[printerName].insert("AcceptJobs", newAcceptJobs); backend->printerOptions[printerName].insert("Copies", QString::number(newCopies)); backend->printerOptions[printerName].insert("DefaultColorModel", QVariant::fromValue(defaultColorModel)); backend->printerOptions[printerName].insert("DefaultPrintQuality", QVariant::fromValue(defaultPrintQuality)); backend->printerOptions[printerName].insert( "DeviceUri", newDeviceUri); backend->printerOptions[printerName].insert("Shared", newShared); backend->printerOptions[printerName].insert( "StateMessage", newLastMessage); backend->printerOptions[printerName].insert( "SupportedColorModels", QVariant::fromValue(colorModels)); backend->printerOptions[printerName].insert( "SupportedPrintQualities", QVariant::fromValue(qualities)); backend->m_supportedDuplexModes = duplexModes; backend->printerOptions[printerName].insert( "Duplex", Utils::duplexModeToPpdChoice(newDefaultDuplexMode)); QSharedPointer p = QSharedPointer(new Printer(backend)); // Update the default printer from this m_instance->updateFrom(p); // Check we have the new values QCOMPARE(m_instance->acceptJobs(), newAcceptJobs); QCOMPARE(m_instance->copies(), newCopies); QCOMPARE(m_instance->defaultColorModel(), defaultColorModel); QCOMPARE(m_instance->defaultPrintQuality(), defaultPrintQuality); QCOMPARE(m_instance->deviceUri(), newDeviceUri); QCOMPARE(m_instance->shared(), newShared); QCOMPARE(m_instance->lastMessage(), newLastMessage); QCOMPARE(m_instance->supportedColorModels(), colorModels); QCOMPARE(m_instance->supportedPrintQualities(), qualities); // We test that the duplexModes have changed to check that the backend // has changed, as m_backend is private we can't check directly QCOMPARE(m_instance->defaultDuplexMode(), newDefaultDuplexMode); QCOMPARE(m_instance->supportedDuplexModes(), duplexModes); } private: QString m_printerName = "my-printer"; MockPrinterBackend *m_backend = nullptr; QSharedPointer m_instance; }; QTEST_GUILESS_MAIN(TestPrinter) #include "tst_printer.moc" lomiri-ui-extras-0.6.3/tests/unittests/Printers/tst_printerdevice.cpp000066400000000000000000000076101455543116500262220ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "enums.h" #include "structs.h" #include #include #include #include Q_DECLARE_METATYPE(PrinterEnum::DeviceType) class TestDevice : public QObject { Q_OBJECT private Q_SLOTS: void testUriToType_data() { QTest::addColumn("device"); QTest::addColumn("expected"); { Device d; QTest::newRow("UnknownType") << d << PrinterEnum::DeviceType::UnknownType; } { Device d; d.uri = "dnssd"; QTest::newRow("DNSSDType") << d << PrinterEnum::DeviceType::DNSSDType; } { Device d; d.uri = "lpd"; QTest::newRow("LPDType") << d << PrinterEnum::DeviceType::LPDType; } { Device d; d.uri = "ipps"; QTest::newRow("IppSType") << d << PrinterEnum::DeviceType::IppSType; } { Device d; d.uri = "ipp14"; QTest::newRow("Ipp14Type") << d << PrinterEnum::DeviceType::Ipp14Type; } { Device d; d.uri = "http"; QTest::newRow("HttpType") << d << PrinterEnum::DeviceType::HttpType; } { Device d; d.uri = "beh"; QTest::newRow("BehType") << d << PrinterEnum::DeviceType::BehType; } { Device d; d.uri = "socket"; QTest::newRow("SocketType") << d << PrinterEnum::DeviceType::SocketType; } { Device d; d.uri = "https"; QTest::newRow("HttpsType") << d << PrinterEnum::DeviceType::HttpsType; } { Device d; d.uri = "ipp"; QTest::newRow("IppType") << d << PrinterEnum::DeviceType::IppType; } { Device d; d.uri = "hp"; QTest::newRow("HPType") << d << PrinterEnum::DeviceType::HPType; } { Device d; d.uri = "usb"; QTest::newRow("USBType") << d << PrinterEnum::DeviceType::USBType; } { Device d; d.uri = "hpfax"; QTest::newRow("HPFaxType") << d << PrinterEnum::DeviceType::HPFaxType; } } void testUriToType() { QFETCH(Device, device); QFETCH(PrinterEnum::DeviceType, expected); QCOMPARE(device.type(), expected); } void testToString_data() { QTest::addColumn("id"); QTest::addColumn("expected"); { Device d; QTest::newRow("a hp printer (remove CMD)") << "MFG:HP;MDL:Color LaserJet 4500CMD:PDF,PS,JPEG,PNG,PWG,URF" << "HP Color LaserJet 4500"; } { Device d; ; QTest::newRow("Andrew's hp printer") << "MFG:HP;MDL:Officejet 5740 series;CMD:PCL,JPEG,URF,PWG;" << "HP Officejet 5740 series"; } { Device d; ; QTest::newRow("Base case with A as manufacturer, B as model.") << "MFG:A;MDL:B" << "A B"; } } void testToString() { QFETCH(QString, id); QFETCH(QString, expected); Device d; d.id = id; QCOMPARE(d.toString(), expected); } }; QTEST_GUILESS_MAIN(TestDevice) #include "tst_printerdevice.moc" lomiri-ui-extras-0.6.3/tests/unittests/Printers/tst_printerdevicemodel.cpp000066400000000000000000000115411455543116500272410ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "mockbackend.h" #include "backend/backend.h" #include "models/devicemodel.h" #include "structs.h" #include #include #include #include Q_DECLARE_METATYPE(DeviceModel::Roles) class TestDeviceModel : public QObject { Q_OBJECT private Q_SLOTS: void init() { m_backend = new MockPrinterBackend(); m_model = new DeviceModel(m_backend); } void cleanup() { QSignalSpy destroyedSpy(m_model, SIGNAL(destroyed(QObject*))); m_model->deleteLater(); QTRY_COMPARE(destroyedSpy.count(), 1); delete m_backend; } void testAcceptedDevices_data() { QTest::addColumn("device"); QTest::addColumn("accepted"); { Device d; d.uri = "dnssd"; QTest::newRow("empty uri") << d << false; } { Device d; d.uri = "dnssd://foo-bar"; QTest::newRow("non-empty uri") << d << true; } { Device d; d.uri = "dnssd:"; QTest::newRow("non-empty uri, malformed") << d << false; } } void testAcceptedDevices() { QFETCH(Device, device); QFETCH(bool, accepted); m_backend->mockDeviceFound(device); QCOMPARE(m_model->rowCount(), accepted ? 1 : 0); } void testInsert() { QSignalSpy countSpy(m_model, SIGNAL(countChanged())); QSignalSpy insertSpy(m_model, SIGNAL(rowsInserted(const QModelIndex&, int, int))); Device d; d.uri = "dnssd://foo-bar"; m_backend->mockDeviceFound(d); QCOMPARE(m_model->count(), 1); QCOMPARE(countSpy.count(), 1); QCOMPARE(insertSpy.count(), 1); } void testDuplicatesIgnored() { QSignalSpy countSpy(m_model, SIGNAL(countChanged())); QSignalSpy insertSpy(m_model, SIGNAL(rowsInserted(const QModelIndex&, int, int))); Device d; d.uri = "dnssd://foo-bar"; m_backend->mockDeviceFound(d); Device d1; d1.uri = "dnssd://foo-bar"; m_backend->mockDeviceFound(d1); QCOMPARE(m_model->count(), 1); QCOMPARE(countSpy.count(), 1); QCOMPARE(insertSpy.count(), 1); } void testRoles_data() { QTest::addColumn("role"); QTest::addColumn("value"); QTest::addColumn("device"); { Device d; d.uri = "ipp://foo/bar"; d.id = "foo"; DeviceModel::Roles role(DeviceModel::IdRole); QVariant value(d.id); QTest::newRow("DisplayRole") << role << value << d; } { Device d; d.uri = "ipp://foo/bar"; d.info = "foo"; DeviceModel::Roles role(DeviceModel::InfoRole); QVariant value(d.info); QTest::newRow("InfoRole") << role << value << d; } { Device d; d.uri = "ipp://foo/bar"; DeviceModel::Roles role(DeviceModel::UriRole); QVariant value(d.uri); QTest::newRow("UriRole") << role << value << d; } { Device d; d.uri = "ipp://foo/bar"; d.location = "home"; DeviceModel::Roles role(DeviceModel::LocationRole); QVariant value(d.location); QTest::newRow("LocationRole") << role << value << d; } { Device d; d.uri = "ipp://foo/bar"; d.makeModel = "hp"; DeviceModel::Roles role(DeviceModel::MakeModelRole); QVariant value(d.makeModel); QTest::newRow("MakeModelRole") << role << value << d; } { Device d; d.uri = "ipp://foo/bar"; DeviceModel::Roles role(DeviceModel::TypeRole); QVariant value = QVariant::fromValue(d.type()); QTest::newRow("TypeRole") << role << value << d; } } void testRoles() { QFETCH(DeviceModel::Roles, role); QFETCH(QVariant, value); QFETCH(Device, device); m_backend->mockDeviceFound(device); QCOMPARE(m_model->data(m_model->index(0), role), value); } private: MockPrinterBackend *m_backend; DeviceModel *m_model; }; QTEST_GUILESS_MAIN(TestDeviceModel) #include "tst_printerdevicemodel.moc" lomiri-ui-extras-0.6.3/tests/unittests/Printers/tst_printerfilter.cpp000066400000000000000000000132241455543116500262460ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "mockbackend.h" #include "models/printermodel.h" #include #include #include #include Q_DECLARE_METATYPE(PrinterBackend*) Q_DECLARE_METATYPE(PrinterJob*) class TestPrinterFilter : public QObject { Q_OBJECT private Q_SLOTS: void testEmptyCount() { QScopedPointer backend(new MockPrinterBackend); PrinterModel model(backend.data()); PrinterFilter filter; filter.setSourceModel(&model); QCOMPARE(filter.count(), model.count()); } void testNonEmptyCount() { QScopedPointer backend(new MockPrinterBackend); PrinterModel model(backend.data()); PrinterBackend* printerABackend = new MockPrinterBackend("a-printer"); PrinterBackend* printerBBackend = new MockPrinterBackend("b-printer"); auto printerA = QSharedPointer(new Printer(printerABackend)); auto printerB = QSharedPointer(new Printer(printerBBackend)); PrinterFilter filter; filter.setSourceModel(&model); ((MockPrinterBackend*) backend.data())->mockPrinterLoaded(printerA); ((MockPrinterBackend*) backend.data())->mockPrinterLoaded(printerB); QCOMPARE(filter.count(), 3); } void testCountChanged() { QScopedPointer backend(new MockPrinterBackend); PrinterModel model(backend.data()); PrinterBackend* printerABackend = new MockPrinterBackend("a-printer"); auto printerA = QSharedPointer(new Printer(printerABackend)); PrinterFilter filter; filter.setSourceModel(&model); QSignalSpy modelCountSpy(&model, SIGNAL(countChanged())); QSignalSpy filterCountSpy(&filter, SIGNAL(countChanged())); ((MockPrinterBackend*) backend.data())->mockPrinterLoaded(printerA); QCOMPARE(modelCountSpy.count(), 1); QCOMPARE(filterCountSpy.count(), 1); } void testMoveOnPrintersLoaded() { QScopedPointer backend(new MockPrinterBackend); PrinterModel *model = new PrinterModel(backend.data()); // Setup two printers PrinterBackend* printerCBackend = new MockPrinterBackend("c-printer"); auto printerC = QSharedPointer(new Printer(printerCBackend)); PrinterBackend* printerDBackend = new MockPrinterBackend("d-printer"); auto printerD = QSharedPointer(new Printer(printerDBackend)); // Setup a filter PrinterFilter *filter = new PrinterFilter(); filter->setSourceModel(model); filter->setSortRole(PrinterModel::Roles::DefaultPrinterRole); filter->sort(0, Qt::DescendingOrder); // Load the two printers ((MockPrinterBackend*) backend.data())->mockPrinterLoaded(printerC); ((MockPrinterBackend*) backend.data())->mockPrinterLoaded(printerD); QCOMPARE(filter->count(), 3); // Check the printer names before change QCOMPARE(filter->get(0).value("name").toString(), QStringLiteral("c-printer")); QCOMPARE(filter->get(1).value("name").toString(), QStringLiteral("d-printer")); QCOMPARE(filter->get(2).value("name").toString(), QStringLiteral("Create PDF")); // Setup spy QSignalSpy dataSpy(filter, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector&))); // Change the name of the 2nd printer so it is 1st printerDBackend->setPrinterNameInternal("a-printer"); QModelIndex idx = model->index(1); model->dataChanged(idx, idx); QTRY_COMPARE(dataSpy.count(), 1); // Check the printer names after change QCOMPARE(filter->get(0).value("name").toString(), QStringLiteral("a-printer")); QCOMPARE(filter->get(1).value("name").toString(), QStringLiteral("c-printer")); QCOMPARE(filter->get(2).value("name").toString(), QStringLiteral("Create PDF")); delete model; } void testRemoteAndLocal() { QScopedPointer backend(new MockPrinterBackend); PrinterModel *model = new PrinterModel(backend.data()); PrinterFilter locals; locals.setSourceModel(model); locals.filterOnRemote(false); locals.filterOnPdf(false); PrinterFilter remotes; remotes.setSourceModel(model); remotes.filterOnRemote(true); locals.filterOnPdf(false); MockPrinterBackend* backendA = new MockPrinterBackend("a-printer"); backendA->m_remote = true; auto printerA = QSharedPointer(new Printer(backendA)); MockPrinterBackend* backendB = new MockPrinterBackend("b-printer"); backendB->m_remote = false; auto printerB = QSharedPointer(new Printer(backendB)); // Load the two printers backend->mockPrinterLoaded(printerA); backend->mockPrinterLoaded(printerB); QCOMPARE(locals.count(), 1); QCOMPARE(remotes.count(), 1); } }; QTEST_GUILESS_MAIN(TestPrinterFilter) #include "tst_printerfilter.moc" lomiri-ui-extras-0.6.3/tests/unittests/Printers/tst_printerjob.cpp000066400000000000000000000357021455543116500255400ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "utils.h" #include "mockbackend.h" #include "backend/backend.h" #include "printer/printer.h" #include "printer/printerjob.h" #include #include #include #include Q_DECLARE_METATYPE(QList) class TestPrinterJob : public QObject { Q_OBJECT private Q_SLOTS: void init() { m_backend = new MockPrinterBackend(m_printer_name); m_mock_printer = QSharedPointer(new Printer(m_backend)); m_instance = new PrinterJob(m_printer_name, m_backend); m_instance->setPrinter(m_mock_printer); m_instance->loadDefaults(); } void cleanup() { QSignalSpy destroyedJobSpy(m_instance, SIGNAL(destroyed(QObject*))); m_instance->deleteLater(); QTRY_COMPARE(destroyedJobSpy.count(), 1); QSignalSpy destroyedSpy(m_mock_printer.data(), SIGNAL(destroyed(QObject*))); m_mock_printer.clear(); QTRY_COMPARE(destroyedSpy.count(), 1); delete m_backend; } void refreshInstance() { QSignalSpy destroyedSpy(m_instance, SIGNAL(destroyed(QObject*))); m_instance->deleteLater(); QTRY_COMPARE(destroyedSpy.count(), 1); m_instance = new PrinterJob(m_printer_name, m_backend); m_instance->setPrinter(m_mock_printer); m_instance->loadDefaults(); } void refreshInstanceWithBackend(MockPrinterBackend *backend) { QSignalSpy destroyedJobSpy(m_instance, SIGNAL(destroyed(QObject*))); m_instance->deleteLater(); QTRY_COMPARE(destroyedJobSpy.count(), 1); QSignalSpy destroyedSpy(m_mock_printer.data(), SIGNAL(destroyed(QObject*))); m_mock_printer.clear(); QTRY_COMPARE(destroyedSpy.count(), 1); m_backend = backend; m_mock_printer = QSharedPointer(new Printer(m_backend)); m_instance = new PrinterJob(m_printer_name, m_backend); m_instance->setPrinter(m_mock_printer); } void testCollate() { QCOMPARE(m_instance->collate(), true); m_instance->setCollate(false); QCOMPARE(m_instance->collate(), false); } void testColorModel() { ColorModel a; a.colorType = PrinterEnum::ColorModelType::GrayType; a.text = "Gray"; ColorModel b; b.colorType = PrinterEnum::ColorModelType::ColorType; b.text = "RGB"; QList models({a, b}); MockPrinterBackend *backend = new MockPrinterBackend(m_printer_name); ((MockPrinterBackend*) backend)->printerOptions[m_printer_name].insert( "SupportedColorModels", QVariant::fromValue(models)); refreshInstanceWithBackend(backend); // Check the models are the same QCOMPARE(m_mock_printer->supportedColorModels(), models); // Set colorModel to 0 (Gray) m_instance->setColorModel(0); QCOMPARE(m_instance->colorModel(), 0); QCOMPARE(m_instance->getColorModel(), models.at(0)); QCOMPARE(m_instance->colorModelType(), models.at(0).colorType); // Set colorModel to 1 (RGB) m_instance->setColorModel(1); QCOMPARE(m_instance->colorModel(), 1); QCOMPARE(m_instance->getColorModel(), models.at(1)); QCOMPARE(m_instance->colorModelType(), models.at(1).colorType); } void testCopies() { QCOMPARE(m_instance->copies(), 1); m_instance->setCopies(2); QCOMPARE(m_instance->copies(), 2); } void testCopiesLessThanOne() { QCOMPARE(m_instance->copies(), 1); m_instance->setCopies(0); QCOMPARE(m_instance->copies(), 1); m_instance->setCopies(-1); QCOMPARE(m_instance->copies(), 1); } void testDuplex() { QList modes = { PrinterEnum::DuplexMode::DuplexNone, PrinterEnum::DuplexMode::DuplexLongSide, PrinterEnum::DuplexMode::DuplexShortSide }; m_backend->m_supportedDuplexModes = modes; m_mock_printer->setDefaultDuplexMode(PrinterEnum::DuplexMode::DuplexNone); refreshInstance(); QCOMPARE(m_instance->duplexMode(), modes.indexOf(PrinterEnum::DuplexMode::DuplexNone)); QCOMPARE(m_instance->getDuplexMode(), PrinterEnum::DuplexMode::DuplexNone); m_instance->setDuplexMode(modes.indexOf(PrinterEnum::DuplexMode::DuplexLongSide)); QCOMPARE(m_instance->duplexMode(), modes.indexOf(PrinterEnum::DuplexMode::DuplexLongSide)); QCOMPARE(m_instance->getDuplexMode(), PrinterEnum::DuplexMode::DuplexLongSide); m_mock_printer->setDefaultDuplexMode(PrinterEnum::DuplexMode::DuplexShortSide); refreshInstance(); QCOMPARE(m_instance->duplexMode(), modes.indexOf(PrinterEnum::DuplexMode::DuplexShortSide)); QCOMPARE(m_instance->getDuplexMode(), PrinterEnum::DuplexMode::DuplexShortSide); m_instance->setDuplexMode(modes.indexOf(PrinterEnum::DuplexMode::DuplexLongSide)); QCOMPARE(m_instance->duplexMode(), modes.indexOf(PrinterEnum::DuplexMode::DuplexLongSide)); QCOMPARE(m_instance->getDuplexMode(), PrinterEnum::DuplexMode::DuplexLongSide); } void testIsTwoSided() { QList modes = { PrinterEnum::DuplexMode::DuplexNone, PrinterEnum::DuplexMode::DuplexLongSide, PrinterEnum::DuplexMode::DuplexShortSide }; m_backend->m_supportedDuplexModes = modes; m_mock_printer->setDefaultDuplexMode(PrinterEnum::DuplexMode::DuplexNone); refreshInstance(); QCOMPARE(m_instance->duplexMode(), modes.indexOf(PrinterEnum::DuplexMode::DuplexNone)); QCOMPARE(m_instance->getDuplexMode(), PrinterEnum::DuplexMode::DuplexNone); QCOMPARE(m_instance->isTwoSided(), false); m_instance->setDuplexMode(modes.indexOf(PrinterEnum::DuplexMode::DuplexLongSide)); QCOMPARE(m_instance->duplexMode(), modes.indexOf(PrinterEnum::DuplexMode::DuplexLongSide)); QCOMPARE(m_instance->getDuplexMode(), PrinterEnum::DuplexMode::DuplexLongSide); QCOMPARE(m_instance->isTwoSided(), true); m_instance->setDuplexMode(modes.indexOf(PrinterEnum::DuplexMode::DuplexShortSide)); QCOMPARE(m_instance->duplexMode(), modes.indexOf(PrinterEnum::DuplexMode::DuplexShortSide)); QCOMPARE(m_instance->getDuplexMode(), PrinterEnum::DuplexMode::DuplexShortSide); QCOMPARE(m_instance->isTwoSided(), true); } void testPrintFile() { QSignalSpy printFileSpy(m_backend, SIGNAL(printToFile(QString, QString))); QString title = QStringLiteral("Title"); QUrl url("file:///tmp/test.pdf"); m_instance->setTitle(title); m_instance->printFile(url); QTRY_COMPARE(printFileSpy.count(), 1); QList args = printFileSpy.takeFirst(); QCOMPARE(args.at(0).toString(), url.toLocalFile()); QCOMPARE(args.at(1).toString(), title); } void testPrintRange() { QCOMPARE(m_instance->printRange(), QStringLiteral("")); m_instance->setPrintRange("2-5,7,8"); QCOMPARE(m_instance->printRange(), QStringLiteral("2-5,7,8")); } void testPrintRangeMode() { QCOMPARE(m_instance->printRangeMode(), PrinterEnum::PrintRange::AllPages); m_instance->setPrintRangeMode(PrinterEnum::PrintRange::PageRange); QCOMPARE(m_instance->printRangeMode(), PrinterEnum::PrintRange::PageRange); } void testQuality() { PrintQuality a; a.name = "Poor"; PrintQuality b; b.name = "Worse"; QList qualities({a, b}); MockPrinterBackend *backend = new MockPrinterBackend(m_printer_name); backend->printerOptions[m_printer_name].insert( "SupportedPrintQualities", QVariant::fromValue(qualities)); refreshInstanceWithBackend(backend); // Check the models are the same QCOMPARE(m_mock_printer->supportedPrintQualities(), qualities); // Set quality to Poor m_instance->setQuality(0); QCOMPARE(m_instance->quality(), 0); QCOMPARE(m_instance->getPrintQuality(), qualities.at(0)); // Set quality to Worse m_instance->setQuality(1); QCOMPARE(m_instance->quality(), 1); QCOMPARE(m_instance->getPrintQuality(), qualities.at(1)); } void testReverse() { QCOMPARE(m_instance->reverse(), false); m_instance->setReverse(true); QCOMPARE(m_instance->reverse(), true); } void testSetPrinter() { // The following properties should not change when using setPrinter bool collate = !m_instance->collate(); int copies = m_instance->copies() + 1; bool landscape = !m_instance->landscape(); QString printRange = QStringLiteral("2-4,6"); PrinterEnum::PrintRange printRangeMode = PrinterEnum::PrintRange::PageRange; bool reverse = !m_instance->reverse(); QString title = QStringLiteral("my-title"); m_instance->setCollate(collate); m_instance->setCopies(copies); m_instance->setLandscape(landscape); m_instance->setPrintRange(printRange); m_instance->setPrintRangeMode(printRangeMode); m_instance->setReverse(reverse); m_instance->setTitle(title); QCOMPARE(m_instance->collate(), collate); QCOMPARE(m_instance->copies(), copies); QCOMPARE(m_instance->landscape(), landscape); QCOMPARE(m_instance->printRange(), printRange); QCOMPARE(m_instance->printRangeMode(), printRangeMode); QCOMPARE(m_instance->reverse(), reverse); QCOMPARE(m_instance->title(), title); MockPrinterBackend *backend = new MockPrinterBackend(m_printer_name); QSharedPointer printer = QSharedPointer(new Printer(backend)); m_instance->setPrinter(printer); QCOMPARE(m_instance->collate(), collate); QCOMPARE(m_instance->copies(), copies); QCOMPARE(m_instance->landscape(), landscape); QCOMPARE(m_instance->printRange(), printRange); QCOMPARE(m_instance->printRangeMode(), printRangeMode); QCOMPARE(m_instance->reverse(), reverse); QCOMPARE(m_instance->title(), title); } void testSetPrinterLoadDefaults() { ColorModel a; a.colorType = PrinterEnum::ColorModelType::GrayType; a.text = "Gray"; ColorModel b; b.colorType = PrinterEnum::ColorModelType::ColorType; b.text = "RGB"; QList models({a, b}); MockPrinterBackend *backend1 = new MockPrinterBackend("printer1"); backend1->printerOptions["printer1"].insert("SupportedColorModels", QVariant::fromValue(models)); backend1->printerOptions["printer1"].insert("DefaultColorModel", QVariant::fromValue(a)); QSharedPointer printer1 = QSharedPointer(new Printer(backend1)); MockPrinterBackend *backend2 = new MockPrinterBackend("printer2"); backend2->printerOptions["printer2"].insert("SupportedColorModels", QVariant::fromValue(models)); backend2->printerOptions["printer2"].insert("DefaultColorModel", QVariant::fromValue(b)); QSharedPointer printer2 = QSharedPointer(new Printer(backend2)); // Base case m_instance->setPrinter(printer1); qDebug() << m_instance->colorModel() << models.indexOf(a); QCOMPARE(m_instance->colorModel(), models.indexOf(a)); QCOMPARE(m_instance->getColorModel().text, a.text); QCOMPARE(m_instance->colorModelType(), a.colorType); // Change to a different printer and check the default updates m_instance->setPrinter(printer2); qDebug() << m_instance->colorModel() << models.indexOf(b); QCOMPARE(m_instance->colorModel(), models.indexOf(b)); QCOMPARE(m_instance->getColorModel().text, b.text); QCOMPARE(m_instance->colorModelType(), b.colorType); } void testState() { QCOMPARE(m_instance->state(), PrinterEnum::JobState::Pending); } /* Test that the copies value is changed in certain situations: - when the printer changes, and - the current copies value matches the default of the previous printer */ void testSaneCopiesValue() { MockPrinterBackend *backend1 = new MockPrinterBackend("printer1"); backend1->printerOptions["printer1"].insert("Copies", "2"); QSharedPointer printer1 = QSharedPointer(new Printer(backend1)); MockPrinterBackend *backend2 = new MockPrinterBackend("printer2"); backend2->printerOptions["printer2"].insert("Copies", "5"); QSharedPointer printer2 = QSharedPointer(new Printer(backend2)); // Base case m_instance->setPrinter(printer1); QCOMPARE(m_instance->copies(), 2); // We expect the job to assume the copies of the new printer m_instance->setPrinter(printer2); QCOMPARE(m_instance->copies(), 5); // Set a non-default value, change printer. m_instance->setCopies(100); m_instance->setPrinter(printer1); QCOMPARE(m_instance->copies(), 100); // Copies stays the same. // Conform to APS (Andrew Printer Spec) m_instance->setCopies(1); QCOMPARE(m_instance->copies(), 1); } /* If the default printer has a default copies value of say 3. When you load the printing-app it is set to 1. This is because the PrinterJob constructor sets m_copies to 1 and then PrinterJob::onPrinterAboutToChange tries to compare the old copies value with it. Which doesn't work. There has to be a secondary case on PrinterJob::onPrinterAboutToChange to always set the copies from the new printer if the old printer was null. */ void testOldPrinterIsNull() { MockPrinterBackend *backend = new MockPrinterBackend("printer"); backend->printerOptions["printer"].insert("Copies", "5"); QSharedPointer printer = QSharedPointer(new Printer(backend)); auto job = new PrinterJob("printer", backend); QCOMPARE(job->copies(), 1); job->setPrinter(printer); QCOMPARE(job->copies(), 5); } private: PrinterJob *m_instance = nullptr; MockPrinterBackend *m_backend = nullptr; QSharedPointer m_mock_printer; QString m_printer_name = "my-printer"; }; QTEST_GUILESS_MAIN(TestPrinterJob) #include "tst_printerjob.moc" lomiri-ui-extras-0.6.3/tests/unittests/Printers/tst_printermodel.cpp000066400000000000000000000612031455543116500260610ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "mockbackend.h" #include "backend/backend.h" #include "models/printermodel.h" #include "printer/printer.h" #include "printer/printerjob.h" #include #include #include #include Q_DECLARE_METATYPE(PrinterBackend*) Q_DECLARE_METATYPE(PrinterJob*) class TestPrinterModel : public QObject { Q_OBJECT private Q_SLOTS: void init() { m_backend = new MockPrinterBackend(); m_model = new PrinterModel(m_backend); } void cleanup() { QSignalSpy destroyedSpy(m_model, SIGNAL(destroyed(QObject*))); m_model->deleteLater(); QTRY_COMPARE(destroyedSpy.count(), 1); delete m_backend; } // Tests for adding/removing/changing things in the model void testInsertOnPrintersLoaded() { QSignalSpy countSpy(m_model, SIGNAL(countChanged())); QSignalSpy insertSpy(m_model, SIGNAL(rowsInserted(const QModelIndex&, int, int))); PrinterBackend* printerABackend = new MockPrinterBackend("a-printer"); auto printerA = QSharedPointer(new Printer(printerABackend)); m_backend->mockPrinterLoaded(printerA); QCOMPARE(m_model->count(), 2); QCOMPARE(countSpy.count(), 1); QCOMPARE(insertSpy.count(), 1); // Check item was inserted at end QList args = insertSpy.takeFirst(); QCOMPARE(args.at(1).toInt(), 1); QCOMPARE(args.at(2).toInt(), 1); } void testInsertOnPrinterAddedFromNotification() { QSignalSpy countSpy(m_model, SIGNAL(countChanged())); QSignalSpy insertSpy(m_model, SIGNAL(rowsInserted(const QModelIndex&, int, int))); PrinterBackend* printerABackend = new MockPrinterBackend("a-printer"); auto printerA = QSharedPointer(new Printer(printerABackend)); m_backend->mockPrinterLoaded(printerA); QCOMPARE(m_model->count(), 2); QCOMPARE(countSpy.count(), 1); QCOMPARE(insertSpy.count(), 1); // Check item was inserted at end QList args = insertSpy.takeFirst(); QCOMPARE(args.at(1).toInt(), 1); QCOMPARE(args.at(2).toInt(), 1); } void testRemoveOnPrinterDeletedFromNotification() { // Setup two printers PrinterBackend *printerABackend = new MockPrinterBackend("a-printer"); auto printerA = QSharedPointer(new Printer(printerABackend)); PrinterBackend *printerBBackend = new MockPrinterBackend("b-printer"); auto printerB = QSharedPointer(new Printer(printerBBackend)); m_backend->mockPrinterLoaded(printerA); m_backend->mockPrinterLoaded(printerB); QCOMPARE(m_model->count(), 3); // Setup spy and remove a printer QSignalSpy countSpy(m_model, SIGNAL(countChanged())); QSignalSpy removeSpy(m_model, SIGNAL(rowsRemoved(const QModelIndex&, int, int))); m_backend->mockPrinterDeleted("Test removed printer", "", printerB->name(), 0, "", true); QCOMPARE(m_model->count(), 2); QCOMPARE(countSpy.count(), 1); QCOMPARE(removeSpy.count(), 1); // Check item was removed from end QList args = removeSpy.at(0); QCOMPARE(args.at(1).toInt(), 2); QCOMPARE(args.at(2).toInt(), 2); } void testUpdateRemoveMulti() { // Setup four printers MockPrinterBackend *printerABackend = new MockPrinterBackend("a-printer"); auto printerA = QSharedPointer(new Printer(printerABackend)); MockPrinterBackend *printerBBackend = new MockPrinterBackend("b-printer"); auto printerB = QSharedPointer(new Printer(printerBBackend)); MockPrinterBackend *printerCBackend = new MockPrinterBackend("c-printer"); auto printerC = QSharedPointer(new Printer(printerCBackend)); MockPrinterBackend *printerDBackend = new MockPrinterBackend("d-printer"); auto printerD = QSharedPointer(new Printer(printerDBackend)); m_backend->mockPrinterLoaded(printerA); m_backend->mockPrinterLoaded(printerB); m_backend->mockPrinterLoaded(printerC); m_backend->mockPrinterLoaded(printerD); QCOMPARE(m_model->count(), 5); // Setup spy and remove middle two printers QSignalSpy countSpy(m_model, SIGNAL(countChanged())); QSignalSpy removeSpy(m_model, SIGNAL(rowsRemoved(const QModelIndex&, int, int))); m_backend->mockPrinterDeleted("Test removed printer", "", printerB->name(), 0, "", true); m_backend->mockPrinterDeleted("Test removed printer", "", printerC->name(), 0, "", true); QCOMPARE(countSpy.count(), 2); QCOMPARE(m_model->count(), 3); QCOMPARE(removeSpy.count(), 2); // Check items were removed from the middle QList args; args = removeSpy.at(0); QCOMPARE(args.at(1).toInt(), 2); QCOMPARE(args.at(2).toInt(), 2); args = removeSpy.at(1); QCOMPARE(args.at(1).toInt(), 2); QCOMPARE(args.at(2).toInt(), 2); } // Tests for the roles in the model exposed to QML void testColorModelRole() { ColorModel a; a.text = "Gray"; ColorModel b; b.text = "RGB"; QList models({a, b}); PrinterBackend* backend = new MockPrinterBackend("a-printer"); ((MockPrinterBackend*) backend)->printerOptions["a-printer"].insert( "DefaultColorModel", QVariant::fromValue(b) ); ((MockPrinterBackend*) backend)->printerOptions["a-printer"].insert( "SupportedColorModels", QVariant::fromValue(models) ); auto printerA = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printerA); QCOMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::ColorModelRole).toInt(), models.indexOf(b)); } void testSupportedColorModesRole() { ColorModel a; a.name = "KGray"; a.text = "Gray"; ColorModel b; b.name = "RGB"; b.text = ""; QList models({a, b}); PrinterBackend* backend = new MockPrinterBackend("a-printer"); ((MockPrinterBackend*) backend)->printerOptions["a-printer"].insert( "SupportedColorModels", QVariant::fromValue(models) ); auto printerA = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printerA); QCOMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::SupportedColorModelsRole).toStringList(), (QStringList() << a.text << b.name)); } void testDefaultPrinterRole() { PrinterBackend* backendA = new MockPrinterBackend("a-printer"); auto printerA = QSharedPointer(new Printer(backendA)); m_backend->mockPrinterLoaded(printerA); PrinterBackend* backendB = new MockPrinterBackend("b-printer"); auto printerB = QSharedPointer(new Printer(backendB)); m_backend->mockPrinterLoaded(printerB); m_backend->m_defaultPrinterName = "a-printer"; QCOMPARE(m_model->count(), 3); QCOMPARE(m_model->data(m_model->index(0), PrinterModel::DefaultPrinterRole).toBool(), false); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::DefaultPrinterRole).toBool(), true); QCOMPARE(m_model->data(m_model->index(2), PrinterModel::DefaultPrinterRole).toBool(), false); } void testDuplexRole() { QList modes({ PrinterEnum::DuplexMode::DuplexNone, PrinterEnum::DuplexMode::DuplexLongSide, PrinterEnum::DuplexMode::DuplexShortSide, }); PrinterBackend* backend = new MockPrinterBackend("a-printer"); ((MockPrinterBackend*) backend)->m_supportedDuplexModes = modes; ((MockPrinterBackend*) backend)->printerOptions["a-printer"].insert( "Duplex", QVariant::fromValue(Utils::duplexModeToPpdChoice(PrinterEnum::DuplexMode::DuplexLongSide)) ); auto printerA = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printerA); QCOMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::DuplexRole).toInt(), 1); } void testSupportedDuplexModesRole() { QList modes({ PrinterEnum::DuplexMode::DuplexNone, PrinterEnum::DuplexMode::DuplexLongSide, PrinterEnum::DuplexMode::DuplexShortSide, }); PrinterBackend* backend = new MockPrinterBackend("a-printer"); ((MockPrinterBackend*) backend)->m_supportedDuplexModes = modes; auto printerA = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printerA); QCOMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::SupportedDuplexModesRole).toStringList(), QStringList() << Utils::duplexModeToUIString(modes.at(0)) << Utils::duplexModeToUIString(modes.at(1)) << Utils::duplexModeToUIString(modes.at(2))); } void testNameRole() { PrinterBackend* backend = new MockPrinterBackend("a-printer"); auto printer = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printer); QCOMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::NameRole).toString(), QString("a-printer")); } void testMakeRole() { PrinterBackend* backend = new MockPrinterBackend("a-printer"); ((MockPrinterBackend*) backend)->m_makeAndModel = "make-and-model"; auto printer = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printer); QCOMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::MakeRole).toString(), QString("make-and-model")); } void testDeviceUriRole() { MockPrinterBackend* backend = new MockPrinterBackend("a-printer"); backend->printerOptions["a-printer"].insert( "DeviceUri", "/dev/null" ); auto printerA = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printerA); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::DeviceUriRole).toString(), (QString) "/dev/null"); } void testHostNameRole() { MockPrinterBackend* backend = new MockPrinterBackend("a-printer"); backend->printerOptions["a-printer"].insert( "DeviceUri", "ipps://foo.local/bar" ); auto printerA = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printerA); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::HostNameRole).toString(), (QString) "foo.local"); } void testLastMessageRole() { MockPrinterBackend* backend = new MockPrinterBackend("a-printer"); backend->printerOptions["a-printer"].insert( "StateMessage", "died" ); auto printerA = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printerA); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::LastMessageRole).toString(), (QString) "died"); } void testLocationRole() { PrinterBackend* backend = new MockPrinterBackend("a-printer"); ((MockPrinterBackend*) backend)->m_location = "test-location"; auto printer = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printer); QCOMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::LocationRole).toString(), QString("test-location")); } void testIsRemoteRole() { MockPrinterBackend* backend = new MockPrinterBackend("a-printer"); auto printer = QSharedPointer(new Printer(backend)); backend->m_remote = false; m_backend->mockPrinterLoaded(printer); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::IsRemoteRole).toBool(), false); backend->m_remote = true; m_backend->mockPrinterLoaded(printer); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::IsRemoteRole).toBool(), true); } void testEnabledRole() { PrinterBackend* backend = new MockPrinterBackend("a-printer"); ((MockPrinterBackend*) backend)->m_state = PrinterEnum::State::ErrorState; auto printerA = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printerA); QCOMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), PrinterModel::EnabledRole).toBool(), true); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::EnabledRole).toBool(), false); } void testAcceptJobsRole() { PrinterBackend* backendA = new MockPrinterBackend("a-printer"); ((MockPrinterBackend*) backendA)->printerOptions["a-printer"].insert( "AcceptJobs", QVariant::fromValue(false) ); auto printerA = QSharedPointer(new Printer(backendA)); m_backend->mockPrinterLoaded(printerA); PrinterBackend* backendB = new MockPrinterBackend("b-printer"); ((MockPrinterBackend*) backendB)->printerOptions["b-printer"].insert( "AcceptJobs", QVariant::fromValue(true) ); auto printerB = QSharedPointer(new Printer(backendB)); m_backend->mockPrinterLoaded(printerB); QCOMPARE(m_model->count(), 3); QCOMPARE(m_model->data(m_model->index(0), PrinterModel::AcceptJobsRole).toBool(), true); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::AcceptJobsRole).toBool(), false); QCOMPARE(m_model->data(m_model->index(2), PrinterModel::AcceptJobsRole).toBool(), true); } void testSharedRole() { MockPrinterBackend* backendA = new MockPrinterBackend("a-printer"); backendA->printerOptions["a-printer"].insert("Shared", false); auto printerA = QSharedPointer(new Printer(backendA)); m_backend->mockPrinterLoaded(printerA); MockPrinterBackend* backendB = new MockPrinterBackend("b-printer"); backendB->printerOptions["b-printer"].insert("Shared", true); auto printerB = QSharedPointer(new Printer(backendB)); m_backend->mockPrinterLoaded(printerB); QCOMPARE(m_model->data(m_model->index(0), PrinterModel::SharedRole).toBool(), false); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::SharedRole).toBool(), false); QCOMPARE(m_model->data(m_model->index(2), PrinterModel::SharedRole).toBool(), true); } void testPrintQualityRole() { PrintQuality a; a.name = "Poor"; PrintQuality b; b.name = "Worse"; QList qualities({a, b}); PrinterBackend *backend = new MockPrinterBackend("a-printer"); ((MockPrinterBackend*) backend)->printerOptions["a-printer"].insert( "SupportedPrintQualities", QVariant::fromValue(qualities) ); ((MockPrinterBackend*) backend)->printerOptions["a-printer"].insert( "DefaultPrintQuality", QVariant::fromValue(b) ); auto printerA = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printerA); QCOMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::PrintQualityRole).toInt(), qualities.indexOf(b)); } void testSupportedPrintQualitiesRole() { PrintQuality a; a.name = "fast-draft"; a.text = "Draft"; PrintQuality b; b.name = "normal"; b.text = ""; QList qualities({a, b}); PrinterBackend *backend = new MockPrinterBackend("a-printer"); ((MockPrinterBackend*) backend)->printerOptions["a-printer"].insert( "SupportedPrintQualities", QVariant::fromValue(qualities) ); auto printerA = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printerA); QCOMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::SupportedPrintQualitiesRole).toStringList(), (QStringList() << a.text << b.name)); } void testDescriptionRole() { PrinterBackend* backend = new MockPrinterBackend("a-printer"); ((MockPrinterBackend*) backend)->m_description = "test-description"; auto printer = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printer); QCOMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::DescriptionRole).toString(), QString("test-description")); } void testPageSizeRole() { QPageSize size = QPageSize(QPageSize::A4); PrinterBackend *backend = new MockPrinterBackend("a-printer"); ((MockPrinterBackend*) backend)->m_defaultPageSize = size; auto printer = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printer); QCOMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::PageSizeRole).toString(), size.name()); } void testSupportedPageSizesRole() { QList sizes({ QPageSize(QPageSize::A4), QPageSize(QPageSize::A5), }); PrinterBackend *backend = new MockPrinterBackend("a-printer"); ((MockPrinterBackend*) backend)->m_supportedPageSizes = sizes; auto printer = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printer); QCOMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::SupportedPageSizesRole).toStringList(), QStringList() << sizes.at(0).name() << sizes.at(1).name()); } void testStateRole() { PrinterBackend *backend = new MockPrinterBackend("a-printer"); ((MockPrinterBackend*) backend)->m_state = PrinterEnum::State::ActiveState; auto printer = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printer); QCOMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(0), PrinterModel::StateRole).value(), PrinterEnum::State::IdleState); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::StateRole).value(), PrinterEnum::State::ActiveState); } void testPrinterRole() { PrinterBackend *backend = new MockPrinterBackend("a-printer"); auto printer = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printer); QCOMPARE(m_model->count(), 2); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::PrinterRole).value>(), printer); } void testIsPdfRole() { PrinterBackend* backendA = new MockPrinterBackend("a-printer"); ((MockPrinterBackend*) backendA)->m_type = PrinterEnum::PrinterType::PdfType; auto printerA = QSharedPointer(new Printer(backendA)); m_backend->mockPrinterLoaded(printerA); PrinterBackend* backendB = new MockPrinterBackend("b-printer"); ((MockPrinterBackend*) backendB)->m_type = PrinterEnum::PrinterType::CupsType; auto printerB = QSharedPointer(new Printer(backendB)); m_backend->mockPrinterLoaded(printerB); PrinterBackend* backendC = new MockPrinterBackend("c-printer"); ((MockPrinterBackend*) backendC)->m_type = PrinterEnum::PrinterType::ProxyType; auto printerC = QSharedPointer(new Printer(backendC)); m_backend->mockPrinterLoaded(printerC); QCOMPARE(m_model->count(), 4); // First printer is the pdf printer ("Create PDF") QCOMPARE(m_model->data(m_model->index(0), PrinterModel::IsPdfRole).toBool(), true); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::IsPdfRole).toBool(), true); QCOMPARE(m_model->data(m_model->index(2), PrinterModel::IsPdfRole).toBool(), false); QCOMPARE(m_model->data(m_model->index(3), PrinterModel::IsPdfRole).toBool(), false); } void testIsLoadedRole() { PrinterBackend* backendA = new MockPrinterBackend("a-printer"); ((MockPrinterBackend*) backendA)->m_type = PrinterEnum::PrinterType::PdfType; auto printerA = QSharedPointer(new Printer(backendA)); m_backend->mockPrinterLoaded(printerA); PrinterBackend* backendB = new MockPrinterBackend("b-printer"); ((MockPrinterBackend*) backendB)->m_type = PrinterEnum::PrinterType::CupsType; auto printerB = QSharedPointer(new Printer(backendB)); m_backend->mockPrinterLoaded(printerB); PrinterBackend* backendC = new MockPrinterBackend("c-printer"); ((MockPrinterBackend*) backendC)->m_type = PrinterEnum::PrinterType::ProxyType; auto printerC = QSharedPointer(new Printer(backendC)); m_backend->mockPrinterLoaded(printerC); QCOMPARE(m_model->count(), 4); // First printer is the pdf printer ("Create PDF") QCOMPARE(m_model->data(m_model->index(0), PrinterModel::IsLoadedRole).toBool(), true); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::IsLoadedRole).toBool(), true); QCOMPARE(m_model->data(m_model->index(2), PrinterModel::IsLoadedRole).toBool(), true); QCOMPARE(m_model->data(m_model->index(3), PrinterModel::IsLoadedRole).toBool(), false); } void testIsRawRole() { PrinterBackend* backendA = new MockPrinterBackend("a-printer"); ((MockPrinterBackend*) backendA)->m_holdsDefinition = false; auto printerA = QSharedPointer(new Printer(backendA)); m_backend->mockPrinterLoaded(printerA); PrinterBackend* backendB = new MockPrinterBackend("b-printer"); ((MockPrinterBackend*) backendB)->m_holdsDefinition = true; auto printerB = QSharedPointer(new Printer(backendB)); m_backend->mockPrinterLoaded(printerB); QCOMPARE(m_model->count(), 3); QCOMPARE(m_model->data(m_model->index(0), PrinterModel::IsRawRole).toBool(), true); QCOMPARE(m_model->data(m_model->index(1), PrinterModel::IsRawRole).toBool(), true); QCOMPARE(m_model->data(m_model->index(2), PrinterModel::IsRawRole).toBool(), false); } void testJobRole() { PrinterBackend* backend = new MockPrinterBackend("a-printer"); auto printer = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printer); QCOMPARE(m_model->count(), 2); auto job = m_model->data(m_model->index(0), PrinterModel::JobRole).value(); QVERIFY(job != Q_NULLPTR); QCOMPARE(job->rowCount(), 0); } void testCopiesRole() { MockPrinterBackend* backend = new MockPrinterBackend("a-printer"); backend->printerOptions["a-printer"].insert("Copies", "2"); auto printer = QSharedPointer(new Printer(backend)); m_backend->mockPrinterLoaded(printer); auto copies = m_model->data(m_model->index(1), PrinterModel::CopiesRole).toInt(); QCOMPARE(copies, 2); m_model->setData(m_model->index(1), 5, PrinterModel::CopiesRole); QCOMPARE(backend->printerOptions["a-printer"].value("Copies").toInt(), 5); } private: MockPrinterBackend *m_backend; PrinterModel *m_model; }; QTEST_GUILESS_MAIN(TestPrinterModel) #include "tst_printermodel.moc" lomiri-ui-extras-0.6.3/tests/unittests/Printers/tst_printers.cpp000066400000000000000000000313461455543116500252300ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "mockbackend.h" #include "backend/backend.h" #include "printers/printers.h" #include #include #include #include #include Q_DECLARE_METATYPE(PrinterBackend*) Q_DECLARE_METATYPE(QList>) class TestPrinters : public QObject { Q_OBJECT private Q_SLOTS: void testInstantiation_data() { QTest::addColumn("backend"); { PrinterBackend* backend = new MockPrinterBackend; QTest::newRow("no printers") << backend; } } void testInstantiation() { QFETCH(PrinterBackend*, backend); Printers printers(backend); } void testAllPrintersFilter_data() { QTest::addColumn("in"); QTest::addColumn("out"); QTest::addColumn("defaultPrinterName"); { auto in = QStringList({"printer-a", "printer-b"}); auto out = QStringList({"printer-a", "printer-b"}); QTest::newRow("no defaults") << in << out << ""; } { auto in = QStringList({"printer-a", "printer-b"}); auto out = QStringList({"printer-b", "printer-a"}); QTest::newRow("have default") << in << out << "printer-b"; } } void testAllPrintersFilter() { QFETCH(QStringList, in); QFETCH(QStringList, out); QFETCH(QString, defaultPrinterName); MockPrinterBackend* backend = new MockPrinterBackend; backend->m_defaultPrinterName = defaultPrinterName; Q_FOREACH(auto existingPrinter, in) { backend->m_availablePrinterNames << existingPrinter; } Printers printers(backend); auto all = printers.allPrinters(); QCOMPARE(all->rowCount(), out.size()); for (int i = 0; i < all->rowCount(); i++) { QCOMPARE( all->data(all->index(i, 0)).toString(), out.at(i) ); } } void testPrinterDrivers() { QString targetFilter("foo"); Printers printers(new MockPrinterBackend); printers.setDriverFilter(targetFilter); DriverModel *drivers = (DriverModel*) printers.drivers(); QCOMPARE(drivers->filter(), targetFilter); } void testCreateJob() { // Setup the backend with a printer const QString printerName = QStringLiteral("test-printer"); MockPrinterBackend *backend = new MockPrinterBackend; Printers p(backend); MockPrinterBackend *printerBackend = new MockPrinterBackend(printerName); auto printer = QSharedPointer(new Printer(printerBackend)); backend->mockPrinterLoaded(printer); // Create a job PrinterJob *job = p.createJob(printerName); // Check it has a printerName QCOMPARE(job->printerName(), printerName); } void testCancelJob() { MockPrinterBackend *backend = new MockPrinterBackend; JobModel *model = new JobModel(backend); Printers p(backend); // Add one. QSharedPointer job = QSharedPointer(new PrinterJob("test-printer", backend, 1)); backend->m_jobs << job; backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, 1, "", "", 1); // Check it was added QCOMPARE(model->count(), 1); // Setup the spy QSignalSpy removeSpy(model, SIGNAL(rowsRemoved(const QModelIndex&, int, int))); // Cancel the job p.cancelJob(job->printerName(), job->jobId()); // Check item was removed QTRY_COMPARE(removeSpy.count(), 1); QList args = removeSpy.at(0); QCOMPARE(args.at(1).toInt(), 0); QCOMPARE(args.at(2).toInt(), 0); } void testHoldJob() { MockPrinterBackend *backend = new MockPrinterBackend; JobModel *model = new JobModel(backend); Printers p(backend); // Add one. QSharedPointer job = QSharedPointer(new PrinterJob("test-printer", backend, 1)); backend->m_jobs << job; backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, static_cast(PrinterEnum::JobState::Pending), "", "", 1); // Check it was added QCOMPARE(model->count(), 1); QCOMPARE(model->getJob("test-printer", 1)->state(), PrinterEnum::JobState::Pending); // Setup the spy QSignalSpy dataChangedSpy(model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector&))); // Hold the job p.holdJob(job->printerName(), job->jobId()); // Check item was removed QTRY_COMPARE(dataChangedSpy.count(), 1); QCOMPARE(model->getJob("test-printer", 1)->state(), PrinterEnum::JobState::Held); } void testReleaseJob() { MockPrinterBackend *backend = new MockPrinterBackend; JobModel *model = new JobModel(backend); Printers p(backend); // Add one. QSharedPointer job = QSharedPointer(new PrinterJob("test-printer", backend, 1)); backend->m_jobs << job; backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, 1, "", "", 1); p.holdJob(job->printerName(), job->jobId()); // Check it was added and is in held state QCOMPARE(model->count(), 1); QCOMPARE(model->getJob("test-printer", 1)->state(), PrinterEnum::JobState::Held); // Setup the spy QSignalSpy dataChangedSpy(model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector&))); // Release the job p.releaseJob(job->printerName(), job->jobId()); // Check item was removed QTRY_COMPARE(dataChangedSpy.count(), 1); QCOMPARE(model->getJob("test-printer", 1)->state(), PrinterEnum::JobState::Pending); } void testPrinterRemove() { // Load the backend with a printer const QString printerName = QStringLiteral("test-printer"); MockPrinterBackend *backend = new MockPrinterBackend; MockPrinterBackend *printerBackend = new MockPrinterBackend(printerName); auto printer = QSharedPointer(new Printer(printerBackend)); backend->m_availablePrinterNames << printerName; backend->m_availablePrinters << printer; Printers printers(backend); auto all = printers.allPrinters(); // Check the initial printer count QCOMPARE(all->rowCount(), 1); // Setup a spy QSignalSpy removeSpy(all, SIGNAL(rowsRemoved(const QModelIndex&, int, int))); // Remove the item printers.removePrinter(printerName); backend->mockPrinterDeleted("", "", printerName, 1, "", true); // Check item was removed QTRY_COMPARE(removeSpy.count(), 1); QList args = removeSpy.at(0); QCOMPARE(args.at(1).toInt(), 0); QCOMPARE(args.at(2).toInt(), 0); QCOMPARE(all->rowCount(), 0); } void testSetDefault() { const QString defaultPrinterName = QStringLiteral("my-default-printer"); MockPrinterBackend *backend = new MockPrinterBackend; Printers p(backend); QCOMPARE(p.defaultPrinterName(), QString()); p.setDefaultPrinterName(defaultPrinterName); QCOMPARE(p.defaultPrinterName(), defaultPrinterName); } /* Test that Printers successfully assigns printers to jobs whenever they appear, as well as assigning job proxies to printers whenever they appear. */ void testAssignPrinterToJob() { MockPrinterBackend *backend = new MockPrinterBackend; Printers p(backend); MockPrinterBackend *printerBackend = new MockPrinterBackend("test-printer"); auto printer = QSharedPointer(new Printer(printerBackend)); backend->mockPrinterLoaded(printer); auto job = QSharedPointer(new PrinterJob("test-printer", backend, 1)); backend->m_jobs << job; // Setup the spy QSignalSpy jobLoadedSpy(backend, SIGNAL(jobLoaded(QString, int, QMap))); // Trigger update. backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, 1, "", "", 1); QTRY_COMPARE(jobLoadedSpy.count(), 1); // Job now has a shared pointer to printer. JobModel *model = static_cast(p.printJobs()); QCOMPARE(model->getJob(printer->name(), job->jobId())->printer(), printer); QCOMPARE(model->getJob(printer->name(), job->jobId())->printer()->name(), printer->name()); } void testSetPrinterJobFilter() { MockPrinterBackend *backend = new MockPrinterBackend; Printers p(backend); auto job = QSharedPointer(new PrinterJob("test-printer", backend, 1)); backend->m_jobs << job; backend->mockJobCreated("", "", "test-printer", 1, "", true, 1, 1, "", "", 1); MockPrinterBackend *printerBackend = new MockPrinterBackend("test-printer"); auto printer = QSharedPointer(new Printer(printerBackend)); backend->mockPrinterLoaded(printer); QCOMPARE(printer->jobs()->rowCount(), 1); // Need to also get this through a model. auto printerJobs = p.allPrinters()->data(p.allPrinters()->index(0,0), PrinterModel::Roles::JobRole).value(); QCOMPARE(printerJobs->rowCount(), 1); } void testLoadPrinter() { MockPrinterBackend *backend = new MockPrinterBackend; Printers p(backend); // Harmless to request non-existent one. p.loadPrinter("foo"); // Load a printer and request it. MockPrinterBackend *printerBackend = new MockPrinterBackend("printer-a"); auto printer = QSharedPointer(new Printer(printerBackend)); backend->mockPrinterLoaded(printer); p.loadPrinter("printer-a"); QVERIFY(backend->m_requestedPrinters.contains("printer-a")); } void testPrintTestPage() { QStandardPaths::setTestModeEnabled(true); MockPrinterBackend *backend = new MockPrinterBackend; Printers p(backend); // Load a printer and request it. MockPrinterBackend *printerBackend = new MockPrinterBackend("printer-a"); auto printer = QSharedPointer(new Printer(printerBackend)); backend->mockPrinterLoaded(printer); p.loadPrinter("printer-a"); // Set the target url auto target = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "cups/data/default-testpage.pdf", QStandardPaths::LocateFile); QSignalSpy printFileSpy(printerBackend, SIGNAL(printToFile(QString, QString))); p.printTestPage("printer-a"); QCOMPARE(printFileSpy.count(), 1); QList args = printFileSpy.takeFirst(); QCOMPARE(args.at(0).toString(), target); } /* Test that a printer is 1) enabled and 2) set to accepting jobs upon creation. Also, if the printer is the only printer, make it the default. */ void testPrinterProvisioning() { MockPrinterBackend *backend = new MockPrinterBackend; Printers p(backend); p.addPrinter("printer-a", "some-ppd", "ipp://foo/bar", "", ""); // Create the printer, and make it appear in the printer model. MockPrinterBackend *printerBackend = new MockPrinterBackend("printer-a"); auto printer = QSharedPointer(new Printer(printerBackend)); backend->mockPrinterLoaded(printer); p.loadPrinter("printer-a"); QVERIFY(backend->enableds.contains("printer-a")); QVERIFY(backend->printerOptions["printer-a"].value("AcceptJobs").toBool()); QCOMPARE(backend->m_defaultPrinterName, (QString) "printer-a"); p.addPrinter("printer-b", "some-ppd", "ipp://bar/baz", "", ""); QVERIFY(backend->enableds.contains("printer-b")); QVERIFY(backend->printerOptions["printer-b"].value("AcceptJobs").toBool()); QCOMPARE(backend->m_defaultPrinterName, (QString) "printer-a"); } }; QTEST_GUILESS_MAIN(TestPrinters) #include "tst_printers.moc" lomiri-ui-extras-0.6.3/tests/unittests/Printers/tst_signalratelimiter.cpp000066400000000000000000000040361455543116500270750ustar00rootroot00000000000000/* * Copyright (C) 2017 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "printer/signalratelimiter.h" #include #include #include #include #include class TestSignalRateLimiter : public QObject { Q_OBJECT private Q_SLOTS: void testEmptyCount() { SignalRateLimiter handler(500); QSignalSpy modifiedSpy(&handler, SIGNAL(printerModified(const QString&))); for (int i = 0; i < 20; i++) { handler.onPrinterStateChanged("spam!", "ipp://bar/baz", "printer-a", 0, "none", true); } modifiedSpy.wait(1000); QCOMPARE(modifiedSpy.count(), 1); } void testUnprocessedTime() { // Keep sending jobs with no gap for longer than four times the // event delay. Check that two signals are emitted. // One from the forcing of the signal and one as the timer finishes int eventDelay = 200; SignalRateLimiter handler(eventDelay); QSignalSpy modifiedSpy(&handler, SIGNAL(printerModified(const QString&))); QDateTime start = QDateTime::currentDateTime(); while (start.msecsTo(QDateTime::currentDateTime()) < eventDelay * 5) { handler.onPrinterStateChanged("spam!", "ipp://foo/bar", "printer-a", 0, "none", true); } modifiedSpy.wait(eventDelay * 2); QCOMPARE(modifiedSpy.count(), 2); } }; QTEST_GUILESS_MAIN(TestSignalRateLimiter) #include "tst_signalratelimiter.moc" lomiri-ui-extras-0.6.3/tests/unittests/assets/000077500000000000000000000000001455543116500214515ustar00rootroot00000000000000lomiri-ui-extras-0.6.3/tests/unittests/assets/croptest.png000066400000000000000000000005151455543116500240230ustar00rootroot00000000000000PNG  IHDRdd pHYs  tIME  d{OtEXtCommentCreated with GIMPWIDATxA @љE 5 ƍzU#:X`K`S/ֶ8,c ,X ,X ,X` ,X`,X`ڱ2dCX ,X` ,X`,XVo{t' ,X ,X` ,X`,X`%X`K都^tE'c ,X ]) N}/IENDB`lomiri-ui-extras-0.6.3/tests/unittests/assets/testfile.jpg000066400000000000000000012131141455543116500237750ustar00rootroot00000000000000JFIF``C    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222 " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?یӇZ͌Pv#ǰ@4yM.y8 >Ӏ:wǥ.(c ߵ;q)1ڙ/p-; >9$ց48tc8H(K K1ޓ_H=ђ(xX)֓+@s$JmD2sڜF33O'R@d=9a$QלRg Y֒ғ847& SM"@7㎔)t&ASpA=:Ӊ1@mʂuv}(Rq҂&NF{˟ҔrwoZ8eqh:dҜRT is擁8})OcJ0Oi[8&N#uǯhuIfsQWހr (IB g4ךPhK׿ҁ[Qӵ9[ ғ'pz#iP=iFy^M#z~:Ԟh9#hҐ)d@8杞9^}M7jw'a۰ s26҃ҁ=~_ʐ#I㠤o(\v&q{{P8 Q*vuV_\z{F̓rjVxG2GPίceloa%0ˋ+ ȲbR&ovgQRkQs)MS׶?ɬ,t6/ IlWRIdc'~un9%oLv'?Ja0p 1WE:!`|vE^0NI?Ka)Au!Hzg9Q s:U%|S8F&2zpT3@pAzmJ 88M̥+>ٝNstVviLm7I/yynC-Cw)+Y$JV Nޝ*'R\ TcMO]I>AcNvۄ#K9cw#ܰq@$.z|q<0ózA؊ f~^ j#w!T RY䳚&; l5Y@"W8zX٦&M ,0ۿ ."Ff {f=i`I +M:A8TvӝHf%HQYٔDgh$L wj,6nhOr// XTW!f6V1B*D*2 ,@RpA"- z?tmǥE?(;:/PH4f'j9qߵ5ڥƔ-}OcU-T*l`c@O#M8!sJ2ړ E9A8zUy$NzUPSJ#9¬F aے9Tj%x ;i =3Qc?NpsTHӷ57cDY t# $BRuʨ*-hFˆ9FSޤ%*V MRd4,gbqFOjr=j`r^2e=vEpr*GnNN(n)\Fzj 3֞yoۊN#SfMYI%g֩8'4b玵<[|ǏG Za*1@ЉOR7R;Ddq>^hW8>.aāP朌wy'foQsFYXs۟J64:4qHXMP KRdj9JӁJW+D( |@ސ"I|(irIigJI&B!ę٪8?rs+\"Ul0~C'['pSG(s&\V<*4hԭ(#oF;jPN18$4Q(sPFw sޓ'?JnGQ֙W. .8<`Qr]'4cJ{ u8hV إғZA7$ c'# c"NzvѨ'ӎ é1ތ{yx ;Hq|3HGaצh-aO2p8=9isZLe:Ƒ֔zWY=ɤ@98#qNgʗԼI93@a*J byA"?.E1E#h '@1 őMH g=J(}#n 1ӎI`psHyZ@Հ)Oz\wIO=)N1R29JPpH v8>Ԡd IKgD}k +fp?znr 8 `ңLӰ!Lu954WF1뚀l'iǭ4c JIrܺj;$ki 5]Tr =CgH)2K_4QUWC߿z =EObA:Ui@ Q4%o=Mj*6DmPbnS15I@LĿ'*n󣠺tLHOh{U.lBzw^({d,FFzJ\LRgLev j5Y8ư (>sc[;{ӹ+chGjf#|{zg#) LH=sLnCA$19#Qz)t<1ǭ^W{#^ G] }/Ie0+1ɶ9/w dclܱ`1ɫWvE%č*MJ䔝΋$#WuN:K0{J*^+DHdbā5$TD+B@v% &0ˎ7m"qqp8 Mn[ܛH$u$X,89{MKND-ţAAIl6ipP3ǧ5^Ex}zDB5F.Aǥ:q}HMX$QcN)Bld)bau掀EO<WMg9SFwJlI dInM[[uSԨ~n~lL6zs&82q5Zzޔl6qkl09%̲{55ҘTy'a5i AnԕE隹ed|TQ,@"}+ 41ԛO ǂE:y$"9YU c{ך,WYךb#HĜ&I$ڧ?*cb ~a֐%rL*x!pK<䚬y)WZ|1RI˓qOOzhlx==i‡Uǭ>3[~ԂOd8۞3QBAȩ܂q֚)+#Z[%@lW6meKu]^wH+)4.<ÓX 5r{1 >1d~3LɑF`&_wa3`K.ѓV "#򃚔(3Cafi>߮AM xaTmN=@ "9vX%u\{5fuXS /|Mm@1ު.O9~N{{nK5|g}1M+ 㤹wL* .Sipid oJWvȢ 0j2FZbw4 d@;qޠB0s4bˉp*\ z:g 9hWet8<]FsUGW*rpͷNw9Thil61ڐPa; 4'pR*' Q=0*Ga3QUNhɱ$s.GM< I  }6 jL搀Қ[ Mɾ_5Haϭxfɥmva6KRe@#j@}hhj]I\UqQ 22x ܟpPGU'T,2ۭ9nZv*e4Wix<ނr<.JYcdݞ*0O9Zy8MhtQ9R-#mh)"[9T-8V~?ƚ܅dڌmGك@?-6;An)1j 0~SJ$z-)84&h|Ԡ@K(`|sL$ .@dpQA)}Q3@H8sqHzFV(*01B'=iǯO>6q&1j3g(y=8یRњBg 7nrs#֓x1{PIJv8BsԆ|\J2׽ 6u4`pG^zFGKf9=2zfҐ 掣#}3zlb>Zn(C @KzFPzPPcI=sA/xRvK‘=+P AI◧ߥp#$RqzLh ҂3ӠjSvazw'FhsKA펴CJiŽ(#t?*O㰠.x=HH3ױMj.0@.<~T1GxAKi{zL~=+(#E9 ~4G4`&ҋ A!@niwt)[sA6}0'8ҝqH`3Mte"cғp步k0 ·֢=(yd4AF:c6ob]zrjVp#҂zb%-IWtIq֣iH$sZ2E1e;sީb9N$ } !$]6UKF=Oz+JT | [vKuHÜ(iu#[QԁAsH^'bמ >qtf qV!wTp&^yzpQI'#ߊƋ硩U^2uzb(;T9m N*U4%ޚ$Ud;* E(G*WA]0:e92-N ҹc2MkR`gϭsShHoQ@ 9LA! A&Xjd d:+hs*nJ#9"LopzuHa0pjFjFwȧD ǽ !j"ޫP9j1bД;S`+T;Zƒ'e'5FwއapsDrvyhAng\yϥkv"Aidvw6Z ?Z؂=,mS7sҜ.1T$^)N4;ҞnsTbǯQ֭F$5Tp2qh\Ee:#'=)׽f˾=5@$qHw3w6[6 Ү*S$ #oJQA?58 i#4 ^j\G|;S%7$ryc'#<֘'yR0V&5n<: E]4&cɧؓ6(rvvR(pO+jqoOAHX׵2@K87<џPH֣Fi&Y1 aa2)Oi1#]R:(HS9Iӧ>}C9R'hx4gObi̸ws&!U%Hb)M pO_Zsc#1S\49=@&yw;=(bCq^E;#Fz y9FGSڗ83@c΂rG 4"F6=R؎(@.^zޝj gځGa3Kp})7 Zڰ`8@TJAjb؏ƛs֞y4ӎ83׵ Ҕ?$ < A>—Q ֗i z8 㠤i0>d􁾂=@x#Iϭ.1 j)? fv4{P\u4ɧ.9>x>v8?;LWg>Œ`)ܹENoCH9F85z١3L=h?ҁ=E(q(iOl\sN C`HQAV ci͎p=)A8 J=1J3i3@ϭH'֗4 ^i)R)`:tNs܊} 8 g?iFIj@8'=)y{t!q{dr)s0 v4xҐGbiNp>c8409=( pqI8ڃޘAcZrJ.9'֌; C]҂ZBGnJ( &(#&sRyڜ0@bz1ӯZm qHy4ўOjBC8Nc"pyh#1GQ.x|)6F2qɣ?w9)}(ۊ^ }h>4{S @KӧzL(JM:wB3@ @$mގ{Q1Mz?&rG.x+?A?Pxz&8?J\R#4\|iE'lHv|:SH4@{R&2)z/ɣ'ӊhst8XKQO)ځ@1G=? =u(.ƓFy4)E b~T`3Kjb((җAzC4'@:sOnPqGNjF+{q"sQ?.˓FhӀjZg{FsQ^jayu;;<"Yv TWV6#T6v{wW ?fv,f"*ϹsP9ȩw ˞c7O5F pG+RnmZD\2%rE2h±iCy2:13L(|4G p?P`6j%&(WI40):1>us% 3@Ym28#ʹ1xLx;+(S>QilZݼ0&{X"f;0bN囏d0T֡s+ 0׿jK%EQ'R9Aa(YҪcJnHLzo]0*i$w'ryv:ER'Ұmb n*֔)&/EA$G^1]tZ>' *J\jzJ GY7Cuted Ӳ$#[yZCfx-V%:dw4u[(nIҦP$<npsT~q4Cq FF H;ZЀP{ ).rW Pr7Or'4WTv0RrN)YAtInOZbqȨx\B`Մ'.1I۩HS/Jځf,g޴cYjh3~WF sYTCH YN?*#i3V-aEbWԷnqrHY.хj 7O#H5zG򞕛76Uv '"BRBz#g{Էaz=AG ߮jHNくZTg<Ҹ!^O^dtRIڿw:C*9'5 ;uQ&l*Ȟ0O)\^`=*+ہ#ZtJC7VˁW- j=_R&\[ɴIRaܣ>})!ZtR:0ep؜zSFh dqޮ,E->"7 dcF[C 01V}icVQ6HSClj6yYlRrăjbsS84ȫ8=@=juBX@d'o5v|+:bI +ʁT(Sdep{w2sV#+'&`N6A%ڿZ;c&HrMBsJ5 EW6ȭbwXrzSf"nEX̸pzTZj (Z!7wݑ]F:ztՇ;Z ,d 3fjaY)HyHE"pzEg:qP9G/+9H3M?tiA+EbրJQZ~H#;\CёsQǁޟs@CHaHQ} LRNx<'~tX:P-8*CJ?;с!F'g)ÜA] d$l`ѓog R$#)ÈTp{ PCǵ+yLT8"6:j4*6qi&Iǿ3x_ZR~\gc+(sL?0('oӥOQ,&6\.r3By?Z ^doGSj<ڠab8ެF>ڽzԊ28 ?86ᙛQ!ZB@2<,r zl<gXiqA)pN'ځX31~:b 8qLQE=h=#4gщP {Q=)yځq׽ ?ZNI9gZ'OoZ^ )ONрuz'FҒHrF) (*ŒvM?xRcROZ7&c$NNsC 錑Nғ*.M##dcCxo֗9ywAA;sMON3Ko^={QړjN1Ұ($9=Ai曞xK:iÅƝΣނ98E!&7v =(`3ӰLSӯLl]&_nЪ@9=iH')<}(\Z\q1]-Z #sRx@c.I})FHO|58 Ɛ)f[ځ\P@>إAI_Q9 4`Rs@u)6)(<҂IR.2Aqځ&&I.rH@=sh;`t\Z1ܚwUРJ\OjB@Òz?Z88I9>zތt=((*AaL6iO$ѷ =)d={RRPy0v)G='ޕ;sҁҌ'3@0.rA#=#׊Lc(`ҝH˞sۥ ]Nnd,ϘԀyZe<{S1ll."ތz*K=P .!UO<ֽJÜ*I'rirJTk)@b+Y=Ft rIj&+:70sTw#J }O־iἁX]$$-c[#-Zh іz4ټU5cWoNj29h̊P3K1 }y)U7ozRHl$k&2 VַGVFB5yuSNڜzx?35~T#94[Vc[wiOZ9-؞&A9稦WH84;''vڞ9BAy=s@;jPqwƈB6;*wSNj7\2jE%Ҙ9o9sIԖ(={SxUKFSwsS`0RB=sYJfc_k tqt "Ho013֭7Q==+'wЊP s9P_zU>Їcڮl\MĒhf84R 2sHrNzJv8'rjiZ(%jhwpsDIkJ8$*oOaRE\K6@@^ĝ3ޢ1Iq2jG-UqoAlרUjڷ4=]8UlזpĂ9ZcFN9P+vFJEd|R3H XP4" 1T8<O-(GȢ #sP KPq˂<̓rጓcvY 1&C}]A=)NOLҀ\}9qD*UAsYELg > {PƷ/ Ս>p GAcMiZ2HC{֩Xq;v$яBu"uc Si ~3\9@>\jLZ&o\z"- i{":*u"8s*!A( Kܕ +c=iλpJV`Afͽ N3KPdn'jIX3֓vv-ia; 627# {S)FdO PIh^ʪ@ y+籪r#sXU8t|n)=frFr' W)(:ZF iLϖI'UY\֌ոi6=8 [g l-ASNA 8U'F$sjKE$,皆$8_ZP2O9sz՘@j3- >{ڏ ӥI$DtRFSf5i1b)R;/0)b}+tZskEA=+:֐=;竸`n=zS t7+9ZQ='<#yaEk!˜a=IVv R8H~n'hQjq".ubXyMJ~S⠍FA;n#چ#>03ޔnE`zϥ+&}1MrAiI)}Gi‘SBxm9U>Ezalh v%QsJyʁMI \!qSF) 1 1M}i0 bOAyڔP}sHOP 2zqրp 4qѴqO8 1G<i Bv@l*h簣8 i=iH8ȥzcԆ'\qҗӚU!)ܖFdҚO_N@.ך2vM9mrzҌbRt(ǵ/QI}k ҎQF8Rcց! \r) ĂI88~`>AHipr:R䞟&9>ĘlMZSÐ@ÊQ#4g>\P i{ʍ41J3ni:.#IEą=}ʀxGN;bgF)1j^BҁqGCF;0ps<JqJ:@$sI1(=hN+i;bFl/8Mi$2{p(C'8PYpA+|Q}q498s¯ZM'b'!/ۤ$㎠\|0׌YG9 \':#bwI rK ilQI:]67@N =?ȭմS)"IoU ?k7v3$WڛA*M/F~掏?F n&C[4p +E*9xﴤ.ّ\V5WSjoK&MFISGǥdMڵ;iː}IC"[?E:3(MZ-G)W&(UHG*Esi;zVT;PWޝ:w./'Jiw ۰ETPqjiy9ֲm} #B;f Ifc0CJ$$do[,O$3w6Pmp2Ga.x7k #5ƑIHxU+qxwr}*-KS6JJX0 pkq oa-Ha9+[#DP)-ߌfq7r$mQsB*R"؜d6a!XX 0:Fޕ)GC$kw.Ug5f(G`q\vZҴLg'3mҮګbn1MD֠DۉU#,ELzZw2,dHLCT6p6#q`+7s18V8+n;&Gq+,(cԊ79{'N ɦ#( V%2&B3R$)<Ԩc<Cl kGs֠!$,d8Þƚ"SCGA6;`|D,iI*֤@%YxRc5c`G!L| RFR2 Glz]C卜c*O)ѐ*F|khRKvX ),W?4ci >vdl8=/JNJ[[S8 V6ݼ=kE'f4L%XqNI-";?ӚdodP!l:ֽۨ95G# 2Eozķ`8dt pKDT.)p%W*M$.O_ZnKNxgVFȱi^$5jq*ڵTj㱅UҞ9ғ?ZP>n*`uat~*L?z `R+PX1䎇5Q7~n-:⎃W&Tj4ɩ%ޑi  y)p_.{F9WhI .ߛ;q4dӊN$ttQ`qJG 84{Iw^xȡzR^M(юA8 1Gs΀b 4 q@9=;?6@@!;z旧4r80 {rǁA89!`0ϥ&Z\q98*~G=@ZOџJql RH8p9(&yi9+L``gjA4~Ԙ#рFO!zqzLcLHPr@Q4{ps֝zn;q@X+x1HT`y4NqP2A9>  GJ1@zgKUzR~v=) aҜ03F8s4Ϸ֓JV0PNFGQ}hS\V ^{R#1F=4“xs@["ӵ$P> ý LPIPK80݆6ߎFF3QaZ3ǯzR  XpsG'==)@oځ}sғ=)Jix$c2h5OQS94/AގzO8~4;6䞽)O!?t/i^p3)׊z^@!\~t 7iG+0N=܌ҌQasN$z}GiJjP>rq'z@ؽH7{vԹMfU&wE p@'iH VVDݏ1C^LEjU8yzzfcӃF2 K{Ѐx=Q wPIjL 4 QvPjɷT،֭D{"n"0}i$ۇmޙMFvyqֱ g83֍qlJfHn0)H♘gi(5c +o~iYmo$h̥zVb JRWhYYdG8yQnq 1s4L(l{7nЅkg J2zHǿjU85%XUQ׭4jB@ȧq5a'2[+|x:zU2IAkED$rTٽ8u&X3 x⭐PRIUIkM0lO`8!?M=zRja!yz{!{O.XÂީic]*S#516KrVV K i i!:8[%88椌nb;y2Ī:z探d19 N=E\Rx=cklUCS|Sn֛ '0N}j|Pjha3m8F7nyuy\j1*>>sW4Y00=3\-y2z(^4 ?Jl1bĜc9<դz?1nD$t 1-İ#i:uz1)=NsM<:Ldc4 }OP!5+aÐ\wJ'i5fpr#4!$w ?:&6 cU2{ު @cVL#Xx=ȩGS S`Q[FHԫ ~5 $fXٱL@ })9\'>m$P6Ԟؓ 5V]5TLjGd=8'4qҤ?6^F ^HN2iNN)S0ԱNx#i15:ggڞKQ5f%ri#&txHQqtU W. <*idFL>9PD,4 cf1w^0;Ubcpւ9<bj/ "9y4rpIu:8pfssCP8hs.3ӚkXdR0R cp)?Bb7$s֪ Oңe'5h/j'?N Zf2ldi99+zU +1>_ZB9?EQTd.88tL43~Zh`qMl8(^) }=y'ރPHڀ8=E&H 硥F(H ry/Cpތ) WG;A" $捀vL sG=: , .v'ޔIT{t&MSrI<>1SA;=;R(s@wa“R搞=HGLsE頽?'94q ?Қ'dc22GzE=iPqK8ӱn'4J9qҝ}֓vOFXd wP=i@szo9BNhiy'sҀs⃀ޞg#Ǻq)4pTf):g8vH@ASI g4tp( szv\N;I4)ZԴq)N(?)H@y\NS>< L0?*Qq@ 9;hbZA4`֔(V$N1JNp(A7ZxinjzRqC)?ZSO#Q&>oA; N'@>⎤z .4=MIH{O>~lBrsFAQB1S4tcN8p?Z9qK㷯K'jSPRZ sN=F~ vw})\)[?Z ð>9{z tgB@?&HpM)#'lϭc =8xG(?+^ n&p@S {Rn)/UjC ?ZpI'i 4}搮) ^=i{`v1GZ Jc>j@揧AHNzQށi9W1H86ԇ9x1┎ 9G_}w)H @n84i>)i t))9ǥqz(4zF qRu=98qڋ ӊRQۓKГњ3ҐfHcH>Q qڎ9)9sT5^N'eJf3SmÿʠnƷGQ:' 39Qs{ fixÊɘ]݉MF3*6}zT^t tU"O+.IIGxg֜z*2␯qYLsLe;*TRNH"GzkQ8#RwH/{ : ~&*)LHJ_{T֔rJ4ڋgi>ct')z $zRjV?ZnӷJv9֐# =qOuڝz2nLTv*Υcڤ4ݑS"!sEDXu J┮1$ =s D'5=cY@$|}j& а*+R5*UqQā~\E @rV/X ,:iz qI\RF$|%y"yslUKgxjt|Oa`O EE%szdKFN9hM?7*:EYT( (ɋwHɧF q-q: Q+ϷzSfҺ94 BCz܆i"`]wg eE O1#>#p_R< Ð04.09';H8} 82CYfVKՆFhDJ4b7en0qPǕFjr ;Ur=ˀUwRI+TA&U%3Y r}(iqǽ.}?0$@"#*CQFTYqQB]t㯽VpsݬVrxQ u̗q>$a'xN GF*8Rp1[V3zQ; HN>cPl:Ab6 E,@b|:]2 n <\3Z&8%}͔b;sLMyRi:ͼ1֩8j\8t|zLy; uQm㊋vOp:Ut3o5b$usLwg91ݞw&kBUrXb{Ta:9'A=qPɴ$AQ*V@z[`KQwգ GYPH3aY '*3Vekau=3ؿ2{r?8|ǭ 8cMtKMagq@=scҗQE()¨\Jh9'AZ >j>wJ%j إ`c?& ; 1UaIqK sGN r sӥ8sN {4JmDM+siuߚCp9M/Ni܎3J0c'isӹ T2 րF:\pzQqu>P3☠zadJ` p=)Cd( uzRn @hP>)RA'>Z\qc)=)ܛՏH:d*10Hf3N:*qZ8iq/L4űS֭[7GJ"䚚2zR{#qxT$Sԓ#{U%rP3)4@Q8l{$ЌRM,y& g:K?5!$PXrF3oj P=i29/oQHAOƐCp8;Ӊ>Nq:@@ǿz;!zvè4>` {=)14;8!by:R Suzϥ.sq֏!@ E{ BFsZ9^)#>=3JSҎ1Lu9*hF(1N'vsӵ7hVNZNw}(qԥd*4I*Q֏"QcOiha :Qތmfoւzy48(?)} B_z\h-)s܊CZO/Ph<'q`ך1g$pq֙"ɥ ǥ!\?:3ZC:KEޔds@o )8&q4X/wR9(8#=A-|gnJ8ϵy($ZwSId#h?Zo8/!O4x?1^hX@H!G(%i'H[ޔt;1ȧpip3Hw{tjb}.3HzRc71J;Cu.xw(sށx ӏ>ԝ 9a{GG {ҞsHyi}9 )@}(* @@0KF(?/9z)OJvK y{Þ?@z8ڗNh(r(#=z҆PMK3N*̑mZKpǴc8|qMkZH`&k}U+LX5d͚mk W 8rx>*ɝjr&c\s]&̂)6 Ms`t>d9A'q2{_pGjˈnnIQ+Yltp_k`|V[db^ōu@{g HyjbS?Lo#rT5ZЖ.qG\"8;y e!ySL;NzR.6q h s8)ʾC qSppOZv7$:Sw)6{{zRoSJJ@֘fQ9JMNR<Rح}@hIOHX>ԓDq ʁOK CjE=w9';>1:t¯#ӊyA}$;$ښHqEӒ{-]sir(QsKԥdNX>V9JlTm#I9FWJ^皌!Q=>s{2U^#p^'OzxAz^XkEEw  Y'ں4H1خZ邲mqmehUd$-p_=p]֢8r*IFT3u N 09\c2 rzsBwdXY9\cTt{2'ޥN9 0JKnÌ Xf*$ >QҬqyը!2jHKR{qVL`08jۧP1PK >%{QAQ(}ZI'PGyFP{SL2j6@˻H^W]l QC9873ji$1{ ſ{5<kj@O9-P3o$"hngR@)|ڮV"]Trzv0za(WV]:8bFzB# Ym \c¶:iV( w *ޙȨ DCzUHg3A6$I¸\2) ƧYCR$@c5bi@U[?tZ=NԻ:@U[kx$bsPk$ H?LքjFcNZjBH7$՛\қ!s!eϭSz.`3ͅtrko-F߸qT֥'f?\w#U0|VO M0$p &\틷#"ܪ43I#9C'9UT(lq44wKB)zhn2iM&s])NyO4RAl9Pg4P7=PڜGPz^vqLV M{Ԝۭ4u+a6h99n (=L]`ic4p@Aazp0y@ҎޔWО}s'ޓ'=ȡ>4cЁi14P=h9+sN<40ppzQҘz9/u>"5;Ij=Sۚ:-\<=)Ď=AG?9S[QR'>ʶ (P݆)w(Jh]܊ qzS!m)yq$1L(XS攁ɪ(=( zS҂ sHNF14Kq@u#A(2ipJ[=t=G?/\~b;BF>(qM#l׵N2="׵sA@G9E+uP03Դ3$sڎGN(5{c:҅41K3ts֜9'٠cpA ۞֔i s@=p98m%`sIQF.[AV[9gH3wZR8H&JsKGJ"@ )z)֝c$i:ԣC\AR)xZ2@c$ 'c.3Ȥ:4)=)O^OFN  8V$ O$H=q@u(G89r=(d)A@؃#sӷZPIkisߥ 9Ґ/aeIM;<44Ww$rqwNĘ_uc9\hi,I)p@i !1z@ڂxǥ(PNC ӏQqz7qF = \v{l~T)#4 \d@>^x t'>?(~8/~@O^(w <a9!J)6x @coQ`={}zSu!qǨ` RZ ֩;C4t dgiFx :94;?z_S SJ}KaNE)Rn'J:h (#"8s@1.yzҁ:p(a(qԃK Rqց(n6Ҁ;?(FLƎi3p|tA8+P$Gc*\v*F|ֵD`3m霊ƹ*Y1'vW5y]JMNBJƳV5Zw:Fl/uu?gIue,2AT& z/H{<,ߓT^Fl;Ur IFҭrqiRf2NPg\ <ч*~KaGs[Tl6f&`9.̫5藺6{a%ͬ"9 \6G\0K$}ԑXR{jI`(!ݻqKnsNV,sH)|i"Ӗ@=(4ˎJ#qpSaMm`{poҖAҟ+*@<ԉmm:˃#c0ZN2N>FfJ^}MEm I8<{ ]$L ⴅK4\0A uoy5cJ"))\[cG]t-F:k>ьr=*'nrE=HqFw oT}r)؞Ӱ\FzMw͌v`%U GʠzTW;~LsLrdqX̡Izd6=jv"ܼsԾPu r g4@ҢJFyqP0LpId[qփ#Ǘ#r)\j^TX~YXepqS@?8Þi-AA+&=Dh,z:H ]: _ 9\U0ogG c"tꜢ7=%i LNJOdl}:Tbm9 =+c+}8q sӊ̊Kmߌw$WGNϾ ʜc#PކH%yJX{ʻsLWAH#wssM:+"Avsb>V@D9F:J|sN$/5ozvy'1y9>Ԡ0:G=Q ҜBǥӦh fFqdXhz@jM]m4d~xy9׭318'k`}i1(?J{#zPSuH*?S h@B*%5g#rw2+2fLf}F9r#`֑g=Uay2nX2Q؋'ڔ &4 ҙ8"*p^JbLd u.0 @sNp9zPnUzмi3R#=y;R lwsvXNQHB8=:ќ ”dqH/qJR= A(-CXHW(FZ??$JRxU- Ĺ~(ym 7zRU#g;_Py,py*P{IiQ_s)ycSzFGpy [pn[9%sւ:Pp0(fsJW=y4;L))~/:q8'vHR `1$zc) o@:Qq܌K't I:$9^B`F~0뎔}SLvh1wyԟ$(iޗޓ;r9 ޗޔ4(;qHhP8@!9:hEdh8 4@uA)1iI1۽;0)H Hۥ)ϡ&ۭ֝08ƔQM8ӵ!=cy`r)NqށN*I)F32løAМc}ӊU׌PRM(qV~49R.H4FcHzs@zR~ZStR/C=qڕr 0Hz3x i}yOƁbpzq4t<&J\n4qր KiqށX s9I&!z})(f;QqH>J\zH9.N{Sq=3@1Ki'8zĘ$SFA?ʐh9Qf٦.R81_ʗ4JN?KӐ) ;(A 2CJzPvq9`jh=)p1=(cړRc>PG84/+I'899)'9+3H:%1֐:\g1 QIփߊS>Ê39$R)$~@8(940A:8 NoP Q''^qJ[@Nяց4/N3IGGA)Fq֚pS@ʓjqIj{<88(ӊ^PG:A}G$:(#@=)Qޜyw=)IqH2E;jEhސzqH9݄Czc?>1kn'HBnj7" O|5K&da 6ܧNQ(UUmlW%_+8Cکϯkb hQ{IΩ2<+nK+-F͚yU?«mK1X6z妿Y9TL8H(;m{%#rNhU%W}4l1Ka)cl(SҞ@ N9e{;qP񎧭;wC&/z48/-ޞ0oJ8QIJRwzߠءA\z*TL0>buwJ@$WYEl#px5^P+`U4C,5Ykcl7GA&r黌7~ Śr0=ML1{I</LzR탎8ߥ.7tG5%*Jk'S+6:qޕpniU<✣Rq! =jEX9Ҙ0b sޓ9`y20sOy89oߊV&LLq}zUy&g K+@)&f2im~*;׽6L$4{'}*X#$d/.2v[.D#dOқ ȣFzR2ad֦: (Vh3c ;$ߚtv'>r?*sHXU_r1l{+=tzǘ=\ 7+Tc=0vDC 3ޙ<hɭqKNL[ 9>:RސW> ҔN{vTOQ8ݑ֓q~RD HGQЭeE;h xoj^6$0hc==i$І"=AMT i۱~)5qvi*ǿ4pc|yl҇)݈}) 9ʁNrzfzpZQPx>쎔XrE'?(>uP2O#A? ''#ԣ(BOQI=JsuB 攟csC rH4F cNF1@Q &{f>zUHzߦ(i;RRE qc@u#K=h@րpT ތaҗ4)n}@)F !w97ai@4;R`g4悽d994x8auiA֐8=(1j^zQz[nir ЂGHGRqh.rri2rx`3`('<zR3@ 3(1ߟZS㡠wSP9֓8qRs/L~4q007/>t>ԧM'Ҁj'm(ҐAJ@ h?ҁvN3)8-cޣ: (giwd (` h4c=inǯadt4nkF rÕMR !NJLq\\ΫHӼj~myv|և&ĞMF&?eRUI.VK+y,'5޴"KF=k_Y5W< ?ҰwEOb6K~4jpG 27]\p#yV11E+9,W/qBIQV4r(UX}6оtFOOzJ.1v1#QX⤖=Td#ՋO+)E@҆I;glO~:QnRt$sV!i,P:Tw@!yѧD),q)mtRlktZ{e "M6PP%Fyen-ng+$eLF=$)k#,9[6i*)иd49h#.5ԆmU.@k~utgpX3E (!@kW9jhz˶-~#P^5:۸'j#ּ%ݰI܀3JGs#sV Sq o,HHa(pq9%zQHRwAB4Xv=1BINOA5+D!w==* #9GGsGQ2yPҎ4nZ` 991JRG&|r*l5*0bj)N t.vQRVEA] icqdW~yܮ:խO= \ua@t=*E\qHqReJ](_^S@9b,8.@?Zz$曻ozb (fv :d%2:d<Čqϧ80>cj4I* jFO* N qNr68A8E‡=" ޫ\T&Kq<ŏ b*1 4/֝u;sQ,#Qr3mi\z2 zT|Â8Yќ26ݻ'q/$vzT\ڋw"R@PB6Ҡ# ];qHi{ը؁+T9=Kcb<`wR j]IќS;!‡S){׶  zxC*y e*Hʑ$ђr{*_$y'sm>sPؒ3]·5]؜\{iv3N;\q) ^Z+`1R}ң!BT g#j~QSYw!hA"i LT{˯M(8A U0^A8<48O9IքRIUv;A4.@ "GCh*"ݜ]gK[4kLl88 .oUȧTY2'['7H%5?9ǭmj^Myr[?ҵFs̙v 4;pi kB*A';Q)"U*;œ2OR<29@bA4YаVŹ@wa"}xTw2-)jjNITsGJh.'Ԥ}9$djxZ8 ӽOzf8*njtRRܑ6O=zPR1Z98@5.7njF\)'4KLfRr|ӺZ@cϽ1$0{jq)236siÑ߽.i6r};,sz=T|jjEyҜ9SiǓ@9.OL ==S 01@>ȡN3<)Gl C dɉ!%]7@E&ߔyG@T`+yF{Ҕ R^eOJy8dh)_j 1a~R;Bb ?HH:nK@ɤrHN sE149Zhv@Hqɥ@ZSԹʎ9~ݣ=R6N2qۊ@>^Ǹ;*}Ja//*s@OpsHFOՎ)rp;+9@)1zSU؟Jss)01`PTz:zҹV&3AN )ZB}GNEbi$ZuXq@~OL恀G^^&JTizړp#4c~i:ppOxhsP 94qxo#HOjU#cv1H9>4r8^&isLM;4orry4pA~OyJ:Qcڐ8Z+җ ccP8rh8=M(iz (c&NzJ }=i )qNh y:J0KtO(@$ "mZ( ~~ Sz t]i`)1M'󤞣`A⌶Sz:bg9iq8i0Ai xJSsAi bJ(oZ1\Hvsւ2ߥrsJ8l NҀAsI8=vGiOΗJ3(90(9t=q@8P8@<7`~ F&xzP0=Ozq1җ)G$A@$ ^L`֗PA4?:g=)z >g҆+zB;b3'#=⎇ ܟZ={Q֌4 RA0P>wx1 LqNPOZh9RqҜ2:rhc@A鶎RC #3>jy6ܪkmٍN yt3e9'ڸ+S\] 4a48k9cd$ū;/|)r+)wzfay58GYt-}9)UV^ݵoė53ظԾ|9%/!`B3\sF$`6_Aifl cwq}<)= *qaRc z>Vz# \ #q8:|B]4gfuT?EV0AL^|w3޻6*>Mخf!#χVEZVr7)ϥ"62TyAbs]w-[|ŵN*9" ÞƬ[x5N$4ĈOʹⶴ쌤XԌr+s@'cӊkDsw>adq*,3<Ei$h\⹧+5aLp[41Mj} >prky}*y,f^"GXO_KoZY6pG uw$?95]@Hx'mIݗ#&-F]͸p1TW(lS)˩uu9fǸ3 >dy4A?9!YLzY2>PJEvj&A:'u*HFMV#V,8'@ǽ h6v: 9ZC#qg KIn?xbirI%xYڹCxTp \`SwR8$`f"/,5n;UnZ –#JpePɘl浡rYV$mP~$' )  V4\23eXA"Y΁F9) bnԚy`Ƭ$'(J%?@$=S}yc~t4ӑTy"yo1G=˔^H,UFzK"9)篥9 v \bS,yeI!ܧ${WuG5H!(T;jGi2=ƥs"@g5/B(/I⺂A繠MjyfC"aSbd?sZ[cbHՖ-y R$d'SN8X*:,3TͰ0GKȣs+4#Q1P{NsL䓊hNF)h"Ox@9\~5YqWFCpqMqC:0>Zޝ*Bw )D|~vIp}e0:nd`s]?f.k6 +"'?YIY5\\ڶVMf|pXW2-D) zTIqNf<.:Xg =+.%9>PO<*E= w8q-\rGZ[~w2P(80H}*DU j.SάϥNE 9Nr"0$}i8J%E.ɱ\Q0~KA˜ȶ`FνB:i.[4ޥ?(\ޙ֐ԛȤ LZ 1^M#$cTAGKP܋ҘT[##N;riFFxz2"P rh#8 B=8#n4d㎔qҜP:R|jPg;j!3An3>o^ K 9惁֗ u 'Fr=t'Ac) rE#Zoqi?`{9Q$QN#+XrASpwy)͎3I/'> 1Ly7ؒG&;R*g5s@>I\;\nF=ho( N\8 IuG.qBI@Ɠ۵9K3䎔⠜8"kQzW^sJ#i)[82v>Hq֥ :T,B` x[֔gހH9CҢGOc֦?,*)-t<)<}) BO;86=GyҗaHzfD)zRSߐ=Rt8ZhS7j{8lc# ($x7zQaJC G&1 {pizztx5z^u99!'ҐcR(cyR7@h Ըf4ÐAQ3t{i1W=)98tzC9 NCɠB>Ҏ u$L҂vړ֐vr=}3b>8h%2ڂ穠[ғ Hv>cJCNNz^j!g֓>KF y#ҞpqHr} +?JSF^Ԡz4R=i9l=)qJy#8 c7g(pis5ACI6a/H:sJ@ց9u^x7QzsMzRt#Tڐ74=hI4i P@&2sKyiq>h84qn)N6Ҕ P0JS iq84 }N:POAO\zQ@ƜzU)zPG" z3إ!JqHO(#k-)$ u!]! G g8s">VpvKV~EfR`Wi4 Ȕɶ޳HI :IOhgCl$Wq,?8%A5uWNjG,r;(@ןjsP6m?ƱW 9]_-̊Fx%{V%Zq%mTksI3.C*@UVV a9y}$~\Jc'9]׽k =쮋z]m$@65]^:h~^Mq SzC rƜr0Hbtڿ)Br0tcSvB0H8-*ޱJ>oϵ7$=)'qR.k[j/@9m5>fxI H} ?He{uAaqz^f.2up)aHdh;;4ӭ1~2<;GG=1DF'jsG,:J<&GNmAH&+G~azԹ p#Ijv&ZuǛr2u)F4$`3w U2U@ o"UFz`uG,f*N @ոOF3u?:[{7`eSHX 4S'9U\ipej6d 皊)Z2G4QP20M9JIҘ!0UGsR)}')9㷭1B<74#ӱqt5W39ۿ;cs-gRM$sj"9MH0x9J%bG ҳ=: e8rэ8lqpzeiNX6X+2G)GJFuMRg<\#c@<lsX[@7EJWAI !Vj)J.k3&B1NzUQKTRXlv2\lVeeqP>Z/ HF8ZjdOˮN0zbe$MHZ :椸$A(1MO* %Q\4`=$k[|>e޺>gֲmP sx| 8օ["qN;wZRSbJb<ڜ#Ãަ>4_Zq?ZMRj^v֣$ dSD\Q}E.r0TK2)23ޝޙI4b?OjcG=('zg*CdZc18(.D=zPr8Bzf9T`Jʘ[wBȠW)84M'ޔ>pip#qL=FO&xɦ+x=zP4F)@'RW6峟jB19cޓN 9cARqKmF*2)jU8:sPާl=jĮ?J3 `t0R̜p=p9Ѹ|ڐqt&N8Ԥ`gUob[8)}84gPG0`x7朠 Ijzu A9 z҂FhюۓޓhQڂN7Q{.&O8wǭ`>ڜ03Z{ -=(2:SpN)#HLpuqFއ<q@z zQAH1Q:C騹.?*\cB49#WM[qJT,GO^)8*@^AQbvwZjA2OqI(?Iy#J~=Jr[l 'd }}3o~n:ԖC6HNyɡbjk&:M +A L`cwOJ« IwIcMP:xXRqکjJP# #RB7O5vЛ݊G=)26NnTgҚE9&ip1RiG \ @9> jwNHq;!ݻ"8<!PĘwg0X p}izOB>ڄ \|2;q'%Pz1Fyց/ӭ/+Znií pv}EܜRqC1lH/9(Lq@ ߇4{=4SH >\P^qKƁ G$R);fPM4']EJ1֌8@1AE/O5tNO4)# =i =3HƄ){PqzClRy# z\ Ҍs}(%;PA/~NўUҎM7"n ZpϮZ@{֌r)(zpS('hzG-E; I-FIV@W$. >9QXG@RqPo4D\sID*, 2eX e?R*UTpH"ٍݠ֍.ֳRuqW 6MR)2w@*<6951Ciҝʱ T@< RcSPҸC3Ͻ4G[81ޢGf%OnH ݌հ봌EU@TI2Zj1$qL~#6hcl;TˆL{E|05閫d(~+#֝,jdMw8yz⹂2q52L<ұњ4?Zsl9+ 8hBdrGTFІ~dPx=ةm.KR5i ˌzWO z[Ky@vs,&&pww5i4*`e-Rp|ĸ۞;Vⲹˁ RK+Te%y\}zKoY 5q$~u, `37*fM̾†BGWnQ*8bVp kaҤ!޵\ jzڶ,x=A/Q:AVpzvIg{QWbUH4T!qv`ҞTW# ¼*^Jn2qwDdb) ӥFTnD2{u&w\\\z >"3}Gb}E%POҐ۾98=j8T Pp?֕ArzPNqJ  ќ$vOJ4rH`:{Rzb$6\P{9@9o8( 05/_o G4dj]F=Pi[*zQ8Ӱ=zRJEgNqKЎ)@u4ǿZkS(>^(?.}{Rgk.sר.duq)3;pN;(~.rZ/j@'$( QҘܻ})x #h èsItHb4s(J\F{Hv8F{zRzs:kyoyہ\1' 2dIax0OrAo 8I)*ˑnII&O@ Ys3Ko֧(ו[Pw!*+&qK x|ʰ\Ր$$c.KtRM2_ ; O%T$4{{cQ1=aFV5י3qnWml-aYņVͲ G#AQn ڵ Ynj^"Xm'=M;oR{bՙ8^i;)vL1OLcjbtq柁ID1ԌLe2ZЌpiqZҚ3d\`'*FF{3'eG_Υ8O0{S2jh$`ր@9pځݩ9"&G\R0\Jh1@uȥ3HNpRC-H#=?E$֔t)F0Nx(1@ qc(?E44 ||Қ7)9np3ӱ $gUiUv<CDJIJ <9 0͓ړ9\SqF0+[Mnp9esߚ]6OZ)d79{cA($[8?CMݸsCמq6(8pG_OJh98(`g'zpe*{Q&LQ\y4y4d&8O/ 0;bw"Qi +aY@)!'I?ШrGaV$899ɰziq'KXsH3ΌpxM q814 tҷ'SWOnmQ1D>1K1psM fJJ@03۱uGCN1=TIRN9R~T@q@ "Ilv=9N)x֐$AK[ n@AcҞW <}(‘JLJpy@9bd'4J_CQفdh4h#ng) $s#Dgt dF+DҜ:t:0@G_ozN攜`Q4u zh6)N}9R$)8JpGmoq2(~z AaZpǮ)0F ('^1+E M83ҍ`p( rqqAzdzS)H4 -7 !=(#ր#eEҌx4F8&ry(My9F1'ތM9pHHdPxϦ)ǽ7lbNp{8y4l81H~\63Zr֐&J9@s:$4ێZ\c^'U悬/jⓜ}i@WqIy#<҃6$7>p9iH*4cxJSZ\ A9@kwO[ (`@I Z3))A;M(L{I08PW4r~'֌˜&`r)Fs@ Q4})áƐН{g4g4{ @N29ǭ'ցAIH=h# =F( 0#b9~N2(]ԘeH%qUe,4gCfk~ nݥFm +5&ks3Nk/L2C h1|`+ЗK0#eKWڸaRP(cZZXR ?Zk{VղfW^ WfV0Ĩ=i&9N` ;T8!hLcq7\}D`^:qґqǭ6O Ozc7 J?Z^ y"4 b.&'Aɤ gҞp1ysץzRp:wHpy;y? `@rsJȦ8(89Lwpr)*S{PH#.; 뎔m&=(--H,3uF5c?n6t[43[W ֟_9f$֫953 g"5-AiU'l+ka3 FU$qZpgr Rq=bYM!c94sfN=\T% ZN pβW+J̻ 18ƠV$/cުKj*R؛W6F瑏@j ZXuZk1t j[rnryh +H9LޡHFabbIljA80VV"TF4M"v8֤e*S_##V9̓LGcޘGSRs 晛"66 t&N+eԬc zѳǭJɞAz҅Q8RO J#H֥XSp\'w@쐁AcK 4' 3Lvs֜đF\җƒas!Áѿ=QA_Ҙ3uC+N}c"gLg|ͩ#p: -҂H 7D $c'~.NOAڣ2:[Cc\kp H#;R9ێ3+D̚#9r: 8r3Lduh  Qzg֚%?o)]FzS #;w[$GN#oHFh*r: N9ϵ s::`T '9194IՏ!g9S=h:1)TsIR1AW ABW2ph2?J(?.9R#:cސ| i:d wN9h?664}ӂsNzG4:01@ 9 g=M${P H,82ix_OasEar1Ai`:}s҅3Ƞw8q`2b ;ԢO"..BVW Ub!Ċyj{e N:XSEpv4BYВzp}9d :KPG\SqSSRADəPɨ2}Rr├zN sR(#<Ӷd@'=)+S.Iu ӱuS32M!7|8Fyu=K(F9@vb q;b\UF('#:>$>ݏ` fyϥ"tA ='=i?J څw zQ Hc=.03֐m#ҀV3?ZRQϽ(Aށ-D8ɧR{{zHFz-};␓צ)I ''AN#$b[ځ18u/<Q@^?Z#2:Ma)s^OJ=ñLiG=hL|zSAq^zSrx8F)Sy y"m=(Ҏ/2HSA`E@JNzvoAiI!(h{ ;_{ a@.iGSM?pjPFsL4<{P  =7qސ<>cwЪ杴`PA<{с:Z\d@ xc9.{;֣I>pu'$g(~RuҜpBN@c鼁J^y`O]E GN٥`py[ Sk_ot&J?gtV` Z$@H8U!t=@5B+6!Dx'Z(ye#v2'ycё)[Tk_k)AdcAڲg)f'I" $rgKmpj$e39tKorW6ǧ=k.d (z7PSi(Nn=FZqF8kM~x!ን`kp3$XcZ?Dv6E%W9T(iZZ-$+ Fƛc+<{U܃I)<xb_z[ eJB?P/=');ҘڹfFadf cky-0)|'FĴfE*BD`J|pFrڜP`}jC11O-wsHB_1, ڢtW~$Յ~1'489Fsu)8צj=.weq?_6h,# uq8]=zZ[ʜ4-D*@IrBC"(5!qvEoƚኀ s]B$`S =+pی}+o:H>宦fj@PŰz1{ g zW[.ۉ91tqqzsX1a*3W.~PHB8ĄzֽyD~edTZr#kz+^BUk`ۦ+F0j,j#c֯یq3W"p:f"ĘڝIFB;{W*qd ) czSy+ #ךMqƔN\D61qP sLnGJ`8mqY2*:H\&3S dugq֓#2 l=J0A8' sǵ34C'nHnI.ri\ ID=*&@9Ng}dlR})g&:I ) y@n3SB"|sҒ02h; xKRNԁI!#?745RDj+aqAh/bz* y2 jPivb1c֎qRiOl3.HLM4'c֔m$:R1Jn01ߊBZ? TP~C=hQf.N9P's6JzCAhSJ{LG\wE;[_zkSzNaM8u"R}(HzI 8c?/b(HАg E( L3Hq8t“)qíg);)=8ځsҀAGAڌ g'ב@l x9qI1Kn[,Nn@9qրcy'#*)=N*G!\|Ԙ#;9ǵ1$p1F@2s ێq@r39J3+@ vL`zӰ29@-gPrґWw;G)ngg>tdPpcbb 4QӜZCZC(ޗ9ցl/nO=Ҏ3LW;r8E(ni3isKp+@a{=< I/"AҀ{9Aޔ@!N1< ^@Ҍ< @N8cҁ8H2 hɥi6KҘX ddQwȥHK94~ y>sGHP@#>Ԡc=HhsJ3ސb"Zh4gmpyityRb8)֗ bwH2 Q}=GJ@K dBbG\tcI;4;uOJ rh v2;Ё.1=h҃ܜҀA>h( \^9 gؾǭc\})$c@ iq(F(qڀzh+w֘N\1@ drQ.1l[bؼ/~41;'$֬zp8$uzۖDcmp6AUX6TB.1Aqӽ-*F89#VqC7dQAix0$A F:u=)ws? 3pha>lnyE.iA7 g^`9 APp8tfY[֢J}K /+ q* Hbc+F{U)cw̋+ hPZZRm&ugdV!tS6 uBS3YյvV]ZBE^3.z {ܟƹ >#%J:gzWCup")U}Jjq˒@lSuWpIsC1稪ۙ.^C)9Sx =KKQZl6:Y/09ޞb= lhbH$*ƗuF׉!NH52bȗ $b]q۵UCvаq5Ba'k>V3Tvmhq2 緵R-@0@֤ӎƵJsKF6z|=+ӭg6M"6֦%0G9  s@ɃRgT)wBvt0mHy DKZ2A#xq7sERFsޘsjQmۆ:RF2>_LU9H:` Qe0I~P>S6; ".&ܜQ+FG5) 623FS#{c*p3B="xz{ڒ4E8vr<ІK$8uyPH5^ZLTj`b Rqh' Yy@I*b5 *[3eҩG$ ;VbL`kЮդd6\>¸iv98Rh9Hob㩱dSqTC܈jךFˈۻ5Q4Ɏ"(li,%GnsOT,zۥW)[E]vm~7  AFӥ;7b9Ҁ˻JxNVQ*9m側Sߟn 1dqi9Jý<'ҕNV8&ݠ~GZw&?J@PNy 9 sD1#oQM︍ʓؚMXc$v46g34'4usBAP8;\8T4g&2npx!~48_y? >Nku#ڝsϵ%r?*ތcьtd$9)O89:RZz\mk7/;@Zcn/82h@ 32~|ĀiCg zQސn4wȣ6{x=y4O&}S@Ђ (8(8xqhyNv҂p!9$dE.pzJh@#{ ㎽Hd>wȧgLvGNE@FӞ)AOJށu){⎍ N'“ ('֓H\J3F24  .z@tǥr9:FGNxGnb㠣n'҂ ;L/wKz L&)9<1R|@1O@J3q@ ' 8w $sL^BqG$!QEN4sEvzbzRFG9TAcFAON ɤ$q h"2y7 ǵ1!H;M(ph)Ҏ:Ru){~9.gc>;sF bHi֌P4; LaRc sGס=)/8x4iQ)T#@{t;`)8l@iqHs:ѸX_ÚS)=(N9$RyOQ?sQ,0<{SԄ(ӥIv❆—qIz@GJ\c'=/\ OB9JA^> i:h"G8hϧFrRؤLHaaXҹ+TTY9E1ր! U^6iw-m4JQްY%11BM5J!\{'`5C y~`Ī##i ٻKI-ːaY,SNLŅ5ȭHN[&ך2",g94 *}iEO+j*+$4cp:]20xEGCm⾳3B<JFI\;<$s堕_D$vWqPqM'Z61D2*$ʨcJW- aQdCؙD&AIZ$f؀0p*MQNy<Ӛ*Swi^ǰ"ҁ㡤9=UHīNsҀW䞣1M=iH#8RW'$ py Rc qJ2\ԄuO*Zy#z Ji#upGG :CTqMF#4LE1gQ0;:Sw4>R0AN To/;}iF7^+>RT#anj |zUN͎(EV33mF'wnG`í2=NmGKcV\t8,f"M޺;$\sqI=)KII6ٲ}m^ %3H#@,ON+>y݁[3;2mX[аhK9..Qg`{f52s$YUȮz\mUSfQ23X淬;fa+GwjZ(J2gCw P2yaVh\u oc׆ ,ill"GOf{YBd(<-c;17TD&$)AJ1Vb7h.3CBܚa= zdɡ،IM iǮ _2 J'FWr8梳BΙJT S&a?Қ[Ѝ=)+LښxjShv/6'N:weil ccD_&p9kpz&NPiϾ*.9HR#r5D)wE yjC;"x'{z pywnFs)Z~8M U 6Z-Jxn:йǥ7Q=zR;+=R(P:ۭ/^P ϭ(Z3sG$dR dsbaw zsB.p:)0ON۸qۓH4HB=~ci1擨 084Kރ0Hc1NP98 ?>P&3H㠤bst>Ou7ڞzqH1?J;{J3Ͽ isIJ=H#H2(CWJ8ݜQP˹q x:`Ź#VmF8M5AޓIQۥ$̤բ I"` ۃ*j-z$+N{-gZ;uNFrB◥98:Ru4tF=;)aHm!s3֐ ir4- Hq@{Ȧ-@C)iKvB? RA|H{csqGQK=A1ލS:sM(98(<`:f߭ ^bbiN2h=M(OQ8ǽ'$czqҞ2sR݁G4~P>?8R0z3Ь2zv4mXQmڞ99ȥ'ڀ{c{ց8JL1 cJ#(n 9ӺfsB^tKc ЊAmEF1I^Hcހ_LQe'Aқ\b\~&i@'p @$:L`#p0_iO,9M!#szP1HAr})I=( Ǡ>qNgF94`ҧSAϧg+}<#Acޓ<E4E㨠`PzsI_Ґ0Nsӭ)q/Nq֘[@;7n3JBpr; )< ;4 "`q֌ Aׂrzs'$ r4 N8ݑҀ}9֦\HRpr)H-`f0ێ34c߭0z )iZq8^1Z&bu'>n(u) ޛSAKx3HL3Jz) (hÓ߃@8ҌB\XƔIL947R @bZjNH2:R);?g<9Bs3 C @ys9jBazP J:S ϥ!9◩Zs@oƁti/jqG\P:SHB[Ҏ:L\J23Q4/9iҗRiH4 (cɥ'CIl&0 vOj[KpB0"ұE  "DD*ɐ q+HI'D&cwА1!H fF}A?Z~; H~_JM)q4;bVЂBI8D9)ҒPw)LA ~f~ s<ɥTzm㓊$)F"X ӰҚ0RCӏJPHRdU99TҜ2Tvy!h B)$p4RMF͟z]JhcPTcI.*ф"=qCvb&n={@ЮHn(88'֕4N(z kRCvxHT9i\G# AS'E3qЎk6SEe>@1"G֟nL[ ښ7` `KQ O0S{fT&R;@/ UTeO\H|%y ӮFYbWִC;ڐG$^?wq[M[\Lj!PeL%bUGObn;9z{9 rHJ lGQP=xMO:xF~k#!ִ˜L.eq駑mm$(\;⹛&G'8t%\mĕ;F8XSTK롉+Ms!Yr8=QJ*8\PE$iQ0KCq7L 񩠻ѿsZvͨ02jGUKؠޫS@&C֣Aq[bFz„nSkCVN*#ZB&2ҭkVVh]r*94t0 a֞d;LZH995fmXbZ^F.d;Ҳ`'=DA\|r$zڽ+Z^40I0yMjh\GD "FY3UWdbiZJLnwZr*(ϧ% P)u@;0sSOI!Rg8 ׵I &緥E'՟s2քs› zibQ֜6E w[֔sUpWwlioQH ;M!o"ڝ5.N܎*(pjpGZ0`H9SBIڣ|B )I+5SO#=r&*6p g ɜFOj PL|zQvvG^A~[`&`_j>z^KupʮNxogTgv<]sGܪn\$gc~ -XW9ZHr8 #Z,C/&撸GFNid?ņzM8- sSA1FI?JfKq{H'`hS}-v&I< x8P=HQJ;e$z@ 234A 9@M\+h#)H)`>qڌ Oi#N6Iv9=~p~ƒulP9KfR~,Yj Zi;#)WM;)tǵ=^*=q4ȥ籡 .AT)#ns:Rph 6@* ?)<4d'8[RsRr7G8RE#,)n2$\lI+ɸ']A;L*יQҪ۰WɩH0G < Qb޴*pwAg֌Z^4МH844( uJwOQx=(s@$hRE8`@2Fh=:R3~ xЖ87#֔r=h0.sڂA=9$lӎ1JN(zю}^EKEaON)1Fѐ@JPҁqHyG LCOޥ<);؞ha('@n~\q#7tcH:tOM;2pyڔd[&FO\RvHܷ{Rc Jwj/$II8zz1OqHg=4IG;1sFIS@zGj^0Ih'8n=i=!69Ӂ#0qJ )xnߊC}h sKw q'n(q1u;R)zu&j/~Z^ៗ`zG?ZAhNO'ځԏOj3OAGngHӊz~RMi PFsΫ\ZZqsDt y5_=䃏3#"[75]ZLD2⼫[$丐'suõ,rXUvFGN9]*88ҖC0qҧhB \n\Y[m8S)hNّ;9&>bOtFf``8jSL* :PX)'G֔&ST>`=g%d\46!ԒԴՍO7ړtLߠ'Ee%ri/6˘\8!cs&siQ&7rEcK4)=qqV$jO*I0Nj#AT6ǟqLN2sW.`JT:UFIՙ-wF:VVMqfT('sX! tcʣ>Q=NqQR )\iS¤ ]𴶡)&F)n]+(RLÒ;)J2z뚷i?dX %@Agv@l U"h%tkllR {ziXK׮1PfSZ /4j4H\y;wc56<e#UDX݇IjK=D89T# vqvbN̚S,*3NCGOZ)lX`gڏάQl~`r=rRUvT5ثs i0p+Dd;IRIXR4@|46gȡT&ċrbB"9K6qQ _NTV;EfxaqYZ̲I0IVIֆdh #7Zj(4;ԬJAbLZQiPF{I(L܅ ?7mf0;)> 3=OIrQG>_5n;Q`۰$SZR6!#"wg~r|#+c_OeeeN+TNVhh5ZܨK3:{&q[ǖ\qִF "w=nLDl㸦s^jH1T>͖%KxYVkVxD!Pmwzێ㍚([SO 5tҍ47k*J[ȾWD,,`.9I%bxi|Ϻr4VE{ԊȤ}6Y7\(w'*2|ܷp1JlM&Rcʏ#iĀJul<‹Aق7ZF|NzR_Ɲ( ;)#8TH`s'qi0Hq-ƣx2G*A'Ԏԑ2h+\1az{Ns׽?Pwz枃(Z̚1;9"(^R19zN94vs(\8(M"aϩ$JA'p[zTc ,&_tG]̎"Nku5=mF7fu^Kڮi7V?ZjdJqhN;%A/YI' \U_*F;vw5\ "1L⚳;S8OjS{>N=k /$w@>L' VbyM63,i0BCZLs߭)zq@HnE9HH?\Mk!rNGjZ\<z1ArF)ES厇A 9S0=)rr12 !SG4}&S4sJ<מ deԬt.J@&&>Pu 杀zDÎޜHiN KpH42g#R"sMPܝ*A3R)'p+`uS)Tu͞ <.rJ'4XƩe8%bzm Hgw{ fsF@i O&PmA 5?iaL +X ~PE jS;R'a^=4q=E!9HHP;8QHzc4;Q('nrH(4 B y(= 0 aq qH>~JI 8?vQ(@t/ӥ#z$=IR1֓q/zM<EzI$MKa)3 j"R3m`q]scE!SA‽gjR J\g?FzҜ`ޔFssI=@@X/?xJA`)sCЩ?.wN( 4O8}idR)ޓnwjR)}) H#0=g@rG)W$0(Z@u h$3Hp{ӱ2<(4ץ"'4!qF>l1 gҝ4@z3AgJ\v{P2iI}h8Zպ)Nr8iz1oZEg>|haL`:R4 b l~G@@8ZN"F3JHG3Kځ%W/?֐=hQޜy⓹c. Fqx  gJ:Q^sJ8~i#'/CL@h1GKh@旃B@P01s(ڕJ:L~$ BY-Io" `WР1є3pyU Y)h bG ($ΎQ\y<ª4rV^N+nn6L#"}}k WV6wQ[A+5eH<ӝ)LI75䰢CaAR<JۆҙE7vxcޘ ʐʄ;Ґ J'Y8FT(9bdo!F玵]Zm. -Py\5FRJ 縥(Qr{ӽdE5GZ{SbTi\g&5 e$hH_jE! ~'ȋi4}e\]V$;Tx;R0:u ךմa0@9VlvRO  e"7uѾC$r_hw21ThԭuAs) d)%ѷ>vAVWq/I#ib|=s V=y$󶜍 ?h>B{KĂ 8+5V8$NQZG' Ǎߖrp jKM)r@V;Rߴ(O¬*eFIH:<B *K_vԗW <*dl8`qB\ZB&'2CzS*(M z}*YI=0i Zo"Xwmj Cm/x!3UjKF7iIi= Ja~l䑚DQۻ.2ZP,gOLfb.0B}*EC ҴmDEViz4H#y%ϵEwԆ*Y!kwb8'%ؘV9kAUsT >aޥ9]NIþ!#SvYsJ߳ qkRZf8q<63@sГOx'߱v($:Ѭ~Pjཱྀ-q11VElop~hXeA䊷ysG`[dRp5egِV\Mo0A3ug;S:mVٚIBS* ϑDp=MM}[$ w ]\Ē bPÂ3VnXcg2q;+{VZ$4)ڐH5Jݱ7[zmC XhWe%D Jn*&Ս t#0vڳp>Z%@'Ve+3fÙYmb͜a8/ $MǸzpSB(,3ןJ:aMQy1ZpBri^9&ƅ,eE!+AVM>[u'9&{>a;}*t!z΄ Of (I#lG*dڠu%Q'Ҙ[ǥc6s@$ª~cc,3֝С#9){?Zc6<(  [MY y3>7O(zu yJ6BTN87ulCi貪G89 -Wxc=zw% Wa5Z:쌟"N[|drEZ4՗ nB)3)6 ǩT?oxn;F(D 3g?bM9wvZ7 #P$zւjQaDre`uo牋FSjdMhւB Jۊ-ODUH8"64ؤaxL0N +t'$1Uw>b1W`kO427pJյn}Xv Q[Yu.[jT}r=*E`H?J* 'vq3dRc84Дu#+JqtOKdP'h`kg:+߽ Y Pi"  Mb>(GjB9jw;qMqC ) aCF lu31L|@ QUJs0j5GZB9HUa 7<;fKץ"NqC`P9mu擀ZOΐP'{)R JS@$mڝ¦OP9i$ЄR ڗh};)\fsҐ`dہS ǯ4\=M.qSC ӕw8bRm]M I1I98?\ӳc҂(@P:E×Qɰڤg!@FQJest=obIfܻy֝AܿO$ڐcӸyU*M >m֝BiXgMA,sMq#=֜1֘AYwddp)sq֛2zr8qI4`;{R灚2OS%0{R&sҕF'HaNM.~p:sIZ`9 7pp)rf!=)3׹8ҐJkwAԀb8pG^lg4t{^B^ݍ( zP"l!@捠Ɨ=3A8,~A֓pz2@ ~\vsjC( JN:P mKRi${uw4NGE:ҎdޔcJ9Ҁ@&Iڂ4n;ɥʍG9ăNt!Cbu6IP9ޘإߚN3֐.2(4ȣ4;f:w(i47Qgas vD gfgSމ [?CQ9.^_+c]*yfrIfL1*#kSgL WH٤hsVMD !GH o-U:S ۠C؟%ø$=$GZr yP@ϩVLio!'gi,Ii Oj'̀+GaR$1 &ra=ׇdj=MI}죂i&mml*15'Fc8JcEd =Zo`F>RO5=G'sjt%e{Sq  ́VmǜwxU*m@c+9]POFrTzAZ T.3Z[R]ۓB3UCڤYVKpOcg0`wL(#`#"oJO }@"6R {PA<<֫@e$9ueo`)\6F hA"4x`zsWEV;+k 42`2I0j $|n~߷Ywm.>{RX/r0:W;Ƶߑ0w $-X=\#*Ƿ4f$;`r`c#U((R+3o dBexLN =kHDayw&@0֭ԧNqXJz#f*qTTJB ) }jI"Z,#1bяz;FBYMevW*#U8CЊ02VFVC84%TG<}i=5ٜ#9r֣\[95z FCN4ӼUdb\c U]n&*q7v ץYu-n j)M Ρۥf+h5Qm19`zSL'o#Jtq,b!X SJWDҍePy  ٥jO~;֬hzNHqSD `uܛȬu984 {l)> ;v@F<Ӱx($pHwn;BszRnܤI *Eg!O13HԈ1#[pKg<ZC8FIښd@t(/VS~nA5!cGz?#_ Ap'RoH8bW3;j5dqI݂fN3ӃJzdv tOPrxx_V:jx_ 6خ#qG&m25D5;Ѳ Xe3[4-JIϧZPI9;}=d=#Ґv3Sjd; 1"`p WG3uR(^NzLI3>U gG<#v5ju Jia%ЧZSWRyC+Amަ$F{ӂKzPIJyhBS qRg##=CHnNj!jF'S8~\v})sRR '#8 Qϩ"H9Ƞ #ޞ3zpA@p=RFO kq׽U OAa&6{ gu{dCM4#6XǥF[ q֙1i؞bNgR!ڑ{ӱq`R5,qҗcKnwA89$JWޜzRvPwB[3KRs)zJd$}) ;Rqyqր,iXsOOj%v56.pl't_"sQ'tm =;H~BZL2E46r)}uy=Kɡ~2-27CsG~*9'c=7N {34ЇNnp0~\g8Ƙ1iJ=:Ss/j:qHVa=f84o֪z?O T9ܱ)f{c㨦a! .OdXO8=)%5E_HgڌcJ: k0osM {h)hUygqBiZ{qޝJsƘ^Fhޕ͌㊖!88&ry)g c=@zA A\cw>=4s83֑ ޗ׽14A@sN#h?Jh'd⁝8s:R(LKM׌P8Ͻ8#HךCkBqȣ pH-uX.;'|]hqL[4 *n9RI' pNzQ掣bqR؁A>r8=dv821qG3P: u悅3 G<jiu4=#JBzR)4\ JP{ iq8 'w`> < .JN(R{w^)94141ȣQqG9Shlg ʖlR@~Lю(qA{R@z2sGOzOZhx=EaC+Gz}9ZLK,3ސt@^4t!$:/z篿SHhQ`JC~h?!<@\^֔ґI=E/z,1hP N8>ԭP.i1&h&6.;Rmi9(cbCŽ8ސ)@+v FA8@<(cF?JS֐H@8J8ڊ@=J\RthPF )9`3Ў!> RAVj33I!r ϥ(G9q E4^21R℀JQH:aTdƓ֐zQjp>h(^1^irqҀzbz g8>) Gq@4v{v4'z9F) 玕b(. f[4..aUUQMrZ$Yh'`Sj3wڳ]9RG#>u:)QOs2vidPPy]9+qq?durgdNB 58+S4aXA_ $D$t~nzS#mcI6FG\tpPQQO+3=PA 0:rݍg=l UقQ? '֜x_ң ,cBUS ojPs9c:"%P6{j02McS]6vyy{/"ILq7'LW5Jh"nR MEH5BW=$ gJٲ%AesIKK[C 8rz>KiB5rK>7&i}J+[etFY89JЧt|\8L@$•0y]Q2}*9J1#˜aXp)#rNpzg4 9NNyL~1Il㩤,Ahd2S߽HzJ)1'Lq*'`OSϭ y>ǦqJz~Їk"EW#VRKte;W8SӥKsh,SHͽ)!#.>\k@Rc,={k`|}j8zS"Ξ-F9#Eު@ޟfa㎵jD5"4SgaE S"?bMN h)=7ґqMg26w8:EsCFxʮrp)X0㊯^ |8"jw8+ˑӘ>9R3ggOqW19POaIc{$qɽ9;Es.% nw*GrX6Z {ٛB";*j `U͸ֲ/hrЩJlP;{E1s1ڹ wI2ŎMhpX&HxI\S;T\+cA#"BfrmmNM+˫^5R;ɡYrϡ\l`(P%SBL^iG$h-t\19vʦ9~lbl6٢9eR'{YWpBMsՃV5$WVcY*:uZūx\M*cU"Zx\/ GEӭ`3BTU 1a$ .)wV" >@{ըÃW>9fp0x-"8bBI\皙zrz/r3mێ bbU}|S:Q1A?J  ZfNFqIb$0= 4eqL F =MF@9NAbDX>ҮqAMk"ِ OR@887rW8gɨK|ʀ>B.GsHAè9H8 ܍r9566zB=zđasf848Td/Z8ǽy/Z}NDO/n#yMɞG'981s} $ǭ0T#ҘXss)O94qOtJzDfŭgO1TV-eDYMEٞ~,~}V&5ƣ9xH\º=-ĶV J9ǥ7\Kʥ u\zuP⺝?G$ ׊Cֶ Bͻ=+9+3%pneXÍҴ;$=*Dq%I"..U?zUYnel"EB MQ( f)>iF C*IJ3U/9<2d[N}jGFc'j&g[iIzzV'#>FFQPG8՝ MZFuzpy tiz RP9sLbMM\w4''hLQ#3Lq)3ڙ#N8$8M)2zi< )z)N9J.)zx;iԤp0zqw"f;ɨ2­szf;N87rqU?|ګ:qִLpР.wHr;VZZNIY=q wp1M$u?{֤Jȓx:TM!Cg9Hˡ&HrOQgڔqj%ț'OC}E,lB4'"l|LW{7q8Qj\2p3I\Yiq>Ӂ4Gsfi )P8f_H(kyF9FJs,O p{\`RFZn#&56Xy2Rp1ivNJn9-CN\&ǸOrrIv;܉?#8:@Frwpy4`zx#Ád_Q6 p:qn) b 4q8_H:ph8= /P9+LQ@Q8$G4̞J@>)qښ7c'ӓN q=)IOҗ#> zc6O#.}h'i'4DEN*YLq LpTLwRdv8jsmnޔRbJ"(9*) xQW%-qS€1ҔsHLGR-d7i3әdSpN4iR3J46})<(`ؼ֚)Ag7@hlS 7nƚ{<q)T IG4\P Pg= ΃qN?N@ҀI> ֞NO1FH Fa=r14 ǵ '֔ &7i  fQiKs)$f>qޓ:u~T0zP;yڐiO40@'m݉)?.ցP!yJ]zojvx4И׽/JH+<QxlPؽ:IsKN(˂GoZLsA'oly)!Fܚ^E0HSJ;HNzьRE( nޔg8/\&&F99)݈bnhМqFQr:P?Ƞ./=F1J3qIO s֗ =hF>lzR=pFi}iՊ=3$vjG8Bz=(\b썷8dtNzUynɮN5y{"8c~}ZeFrOGJ'48\TqIp0l<2wدd:bjˎa]˨rL˜t)6M'>'oOW4sKSEJ `Zu8C9cbIMf$h pX֦Wlx?.M!jp qKi^qۼ)99nbV UK w/[u+t}>FA5h&9 wH|;499V.?ƲȆg*ޝkaYr|ېR;V-D.W| &0zknbc"Lջ~|[w ZѴahKds$Y-#UBT}*lÞ6}G[H.\ƙ {ұWH_zcU=RoMI>ƞJɚ"^09>n]*&o?JC 4ˀp0j2yS5 js(R'=1JN#3T&Dq)Jʑf\)>Ҥ;c֤hENK=Y7oK^:Uh.x)D#yv9U\4sIޔoZqƤaTe WU%O\zSRLpڗQH& pTG9^*V8<7-lCR*aN9nؿs%GjZҟC;i}sҭ~|gDȫq$]RǥVaS= ܘ>pX R“ ^sɤsc' S)8ϧjGcsA,@>ZQdqJޙ(Ri\sz^@ǧj2^)^P =iH==)J{69=XIf2xl 8#)x9K$cqޙ,6åBx j 8ǭZfsVet؀U;tkU\ūn"[jD{rPRfrR0F1(: )TlBM!֥cF,*mjEwg R*BŀϓJAk*O'ˌМ9nԆ(õ KŠOT޽ )i^ARqfÌb'=)H4r(cBg.)1sҔĀp9zў3ҁpsBsGQ40r 4qҔ`4N(J @IyAI?i' Bw.~POJ8cBZ^6۵ QA?G^Ewzxa@_Q 8dG|;P!Ծ `h#48:3(ԣրzR^{(!&8zQ}zIӇ^{SN^E8@zր; HG vӆ: ◰1Kf8. @N1Pq8>g8Ҏ8i 1.7JJi̟ÕkS[yps[r݋vwJHZ-ӯᶍե;aC{@;FE+Hx$W jґ)sᱴ͍D)g'==*tRJ"v6*Tq۷KEm*Iwn֣ܾk͵K!~U:wnwq[ۭV|¹7sE5tLOkgYob#K&@s~br@ݎj)ogGhoJ)ͬ)3,}r0?ܮ VF@s5$A]TM8AN Wۤ-qpxoT6%r.D$+>Vx".q޲'֮53ɮ[3] OHfHqjZm͔ Gj$y[ݏN4{E<849EI&׏{ yqZ:3Jz}Ӯ 9e [y'U3jջK@H'mQvL!N~TFBCbǮOi0ffp(Ql;Qjt"XFR;R.i+yvz}*]6Z/=Hy@8=UucU[F;Gmt5O\GOݘ55y#y`suF*:#Rla!W"nԘyܢH$ښˁ$ sR#jÑB8t5gtd8)3ǭ\[9<ѷiO49!Yw0m^Tk\ipq,>4^ԥ c~8u)8FrIX!pGaMj,$! ֳz^Ą8SQӡVGXgXF}k.hLbGq+G M et(8۞-k0%B9,oi0Ms/Nkm'yÙ `xD- 6Y(PsOqT㑉?֜seV&qңG F(i|R` v4VK$;PO@I["`g((]-R?/AQNҜ0q=i=x߷=*…P=i#*>QLdR:QqQYOFMeM[ ڐXFI6dhpqT ycFQc.'liX18=~3Sgq nƏK)'J杛)mf#FIWT =) J ;PW] E;}⹨ddw~ZJ* +:Ey# '7$zq]% j!G{AmFNBQRF*>G{U999yi-p#(8Iӽh&-D־.\gk' 0AZZ{{Դ6[0 y 2 Ɇ@c5=;Tbe 8h(*n0=LT"rKpGNP@pH<@M4c SXs'+ҐFiݻP&3$31)0u'К#?֗$N &M ⍧󣀹})NqLB)jzj7ɧu\zm B8`J#c1^)$SD;sqP8)' #C#ROP;S]SUw~;ՅU&!s"ꦧHQYws1{A5{/zɻ9MHRS,CGW̙C&G\cˀ ?1I@Qz1cs3N(#4d2x\ԶZC⌖ 8[gbC>$&ok"z@("<}jp3`pO46?xǃNRu`dJؤ=z v)ى-7 ÃFRO[Z&`X}k(t,A XLA#zÌќ) up8(穥فŭR`Ӈ-{J9ima mi3Q)Đrf8E  w p(9:SFr)IϥVr~:J ;$"4t#&)Pzb>})xh籧ڛ)E0=ymǵ HNiHsϯJv2Gzi1 iy*1FSڃҎ3@;Kӥ/zP!zRjL>`&=iAׁ؅(9hv2֍LpHc% %`yu3L#e ~4izD*QtѬ_*y@Ղrwh˹N?aLc֕4F 9HoXX"¼Qvq֬iv9\1zĂI $OL9nn>&JɊ;lkd$|rd\jΑWcia!-ҥ#M g#:BF PHzwt-Q|֤PZI`drVP=z^sTv= 4n+DP{iª@*7=Jv'fFx)9R1!NTzҸia[3?:OSzh`B2F(oK9O8OznF?*{Wb2 rx4#n3QqM#8G#3U!aޜݍ8<GEƙ)ɄT@ `q$ v=h\q&FFJړ)8R:N9 4ނCpTsJF0{s֦${RCb\IhYm|ٝHfi"V*So-f@I1z}^y#~7v*meȮ(#X̷n;z}+Ϋ-59&e#v951BkͫI4v6@)/*,bGPH"@zko'q 8מx8#T32g!&Ʒrnc[tKsiiq4[ԅi0k.2"Mu[Hq#8\`LΘb7vEK(\LJ,W¨sОD7caN$li DY\L *ⴟ))8 u4 T$_(IԀ2zSܤݛ-I T.z{mJIJ"uC#?Ρ4$i#;T #z{)fn)L^YF"LA9S zzJR hV D0fOJqbJp QL?栓c򡡫1pim;I5!s5Zq*jV|v|6ӎiv'9_kIzqBWbKu3K#1bI95mVg7s3M+Tٛ cjo+S'L^vf YY8L F眨9Hgo`zd2vZ4dy9J8l[`FrprsuPApBb/Z洈d뮰J+Ese!VkF$lg޺Z +m=ZS؋{,c칤ܙCCn)+K\Ly}e[88=sHtj 0J1Rd7}*2z$1C1`;V(==ju'WPًl qd6ZqXnY-=AZo7v݊!mdyAUVfJƳ)Ҝ9ҋ}<3 QI[;SD+ ON#HO(Q\҃R' &rMOJ^zppJ)N=ƐR&wϽ>{1ҐNJRrqҏ#鎢3\ ~<Ӈ'Oqއ2F~g79;sF2Bd <(hhip<S.wc$=q)p9iONiA~+q屜w\6!N \4vSGǭ8=6; $[Aq@GB[O$vZI=y{ۯ4I"`ʑSQa2ԚNT<p:-qќ#4ޅOZL iXB:jU?)sH˴qT'Ir)G]JyQ8S@Ծ[0TcIG>Zץ 4Zx#'Z#Q9Gޛ  qnhx)J9'4PN9?);AGCxց-D69/FHz z^{> =3QGJNƂ0SwS2=iqz sIԏZT'-3L.(t>0;M<㎔u(:RuьRsE Sn1M4y ֔ց֔sOҀ@ZC1KК;~~\VcG s֗3FM5iLPrZSҍ:@$ø99h9ϭ6cPH)0\}S)ixZQy#pc@K{{ ҸRT84+9j[ӋL=:xKƬ L,\DŽDsO^wyTzqwo,4AY}VӠ>}R$e*,VTҙe,@2J:-rm0҈hqo+*?J/Ĉ3EJ@ˌ`yv+~ʱ\ qIR;jlY@wpK 1xhccZE nzwv?-@{5V @ i&A rKr'sB)'ԯo"&V+=09d\@gjc.ߺ?jT/&fi|2,R-u!&8"cxt_`魤R 9MĜӭi_j8]}y՝hPbF;35IcR`r=-VK *yʄC=y}ϋ$\2:sPIߋkM-3HX }ki◆rJj: /w,IcҲ%Yrzq]c)b喱ul1{~IG s y!8$JĦAh+XvvtI<⼂݂J=MwN,iA/XTmQj_r6~~NxQOLBg5⻄wI zdVqe9%+]%fiSr}R<c-r [h^fCB8^~|-<7~\6 9Wo mU;i1;ҍ)cOQh(|.;B5%N4$ier7^)߅\Uїj[}х\ {~lh;Tة-vsi7.ܒsJ8Qϵܮ +pNfg=s@^yS01GOzs.q4*Jpxǥ5HݜR@!nMaM(~~G60qiw)T$~^Y /^\Im #㧥#>0#=wP8^|;k%A!cyenK]¬X9cA< NO|EEfZag/nE _zKP[sHK Q򜞔n;A6Ԃ2F 1Qg6Z0^N 왗&L,ZRoZ滹*ިolʞpiӞyZiCNIouaq`Ma,r8q]+LudtⰩ"* ƹE*S럸F穫zM+d?ZxZ&AZhCՖGҩ1}WI֦SMnIUR!h=7n*P@4ӂVl$7Y$82j}Ҭ[8<j GGpkF6ܠS<؛5FLK v2cY1WO^FֹjXT#8jϥMLy gcH+ʽ ӥ1>qKFR13 =GT3R<0yyiG\#ݽFx#iI8Z# n)qJL8%>H7'Oz #M`r0 In(*qڙ-i<`x"Uzю=ܛw4 :29^0J* sNsJH#j~4&0S 2ln'2YIL(g)$X#$o喑MT*pO8g jS}GO3r'$33\23QەNd`dmz֜cP\X-ӿJAr7$5ELbڝd7Q/^*x.#{O9pBt&<>J֟e;Y:!U6tãNm'.~v^U](A!<榼xwCT&6so h*KqFWIδOSŘo}6&Tц;+`zPXpGL[1sQpzf4'0PFy=i޿ lIҲgd ݞ:Sv3Ai@'JiAiu}1ܼҮvLn%~QA5[) Sϭ,|N;؅dQ❊ =$$JrI+ k+w"ÛҔ2zSXGCKs֪d m"3ޔF1@ ֔LF9+A$ Fpdh=8_]IA.3GlPَ3ӵN8<J=:.9УG|$`WR={sw E;vA@@Zo֏◠kF L8;_z b&~u.2z:IJ@}A^=U<L4Hcޓޗ/@@JN{ o΀vҮT^xW4= RhC҃/ HKQqR=#)}uZހztQAHz#GZ\zQހ:0#44 a=)#ZN1@W^qpnFht&yNi\0=~ hprh'Kb1 }(i01SPzO&:+ ڀ0Cc4`s/n)g J@ ړ9=tC@nI'XzQ\p8>ˢXݳItH;B+?uc*Q8ɵ;H`%Xאַ#) G & &Qb*AHOo&5lBUq9Z$T%\>Uy8{t f=Xd?(~46O.o9jmppqNA,I\6;VLQIo;85v!h"E>r\Rs6- y$WT;V<\day\s(NTqN&jH98q"Xn+֥;$(/a_fu9(6F@Zm+--j8:b20n ֽ`Eֳ!a-1b.-7y 3ȘޮۘCxlʟ4)t ӂ)DY&`0 'P Z۾|˒gCYPmcqZS +1&frۉ< ҟNsޠePyKw~^"ʽ ֫q4,oM)=XZlFޥ W})m99?Jܑ92`}ޞNcMI`:T\E`y43J1P{ќ` zQ( Mҋ;nFypqIONn;L. p#5[)7Jԗ*c4j1G) y'#┐TH8@4< 41ʘkW21JqҐ0 5aL~TZv;T]=1R!I;><2䑌b;8\󊥱[MF C|a#ek JΨKDLTӽF=Ovduf OJRd\D\~4wԁ 8v r@"SsRy~YFcݑJE1Hi 2L% wF98cLF:!؏&TJ㶃R:sCe)dܕN 4֐F{rHTNhQ.O\҂ sk)epe.:LfVX;z$WnZI#3ڢ-d#$ԗy1$~'u‚֬G8w 慸Сj݃ Njehٺ2y09lު]9H»QSa>pܧTB*V3T#Q`n<.+GN2?NE!_+Йg{‫94ѐI%4yt= R;R p,{Rt# wqG;O&:9A!vaO=ۆaH@=#/RNb:P(a$?8c4|пt&88<ҜgAwzVQbz!{n x?\1Au4æ0iȦ-<1҇`I,!y4ǷZ cNUϭK5Hr@brGZ#iz.R$ qh{d ϥKz*Î<}鱩|S:$Z:Q̌>8#ab42ﻥ CizRx<4i훗hF=zs B OL7 Ê#$S )b4`9j` -6Hn1`sOr\GzA+18Q;jl}59գ3!ϭiArsTCS`Ԯ \qҌhݎol FM)?80vz ?{0 Sܖ.;:wr0ME)9="֨#KȤǭuAsF{4sϥA(`( Ɣ @A.xcP$zAqΔ1L 54g##ޫ_ICؓҬg͒iu$ٲ,ÜMsXiG^XI3bt OxP|Kp~N Vm#}ەY7ְ[4V)?a+-_ScIJmczU]a +{y`Ϸ55sH[7!kEM=;VAZق_:t'*zV lobIc8>`Xpz%XT"Rhs]4LIX(O`{.d\K"ȌF  5RNB1sR ١cx_iI39PW"IJ8{B0<`-[ouHm% zĿ J;3<]5oeQ={ L elQ5JMtRxq7" в{8Ԁ)Q~yZJܛ*LLH q׳u^9H{S 3Y֬vcmtF$m{}*iu1.c#&~RWu[I.]gNY v9籯7bƮwFƓ/zBAl吁tvEuڊYp Fc4%c~I85lvE+0yD^qzO]\v VF9$⧑s$ 8;<M"M0֎Pl\Jh ;3ޛ{F21ץԆ7i۱:{ON.2x8TE. p9n;'ӻq։LqOb#0-AM8nGF>\^tZW&" Қy䜁Nr䑚crX ͎Ozs/T΅P?֋j4*#wʿZ`Ki v>ø:Sv{1`3>z&Y+^;|RBV3 HiS[%-zT6ҟ))20jݞ @mMheB*֤W}O.֖ڌF2qOzю2s,J&.pFOjIbT׏ZdaI鑙eSU&Z^rnT"n9wKOlrD`GdO[V71(gmcW,=qwg8\iVU egGns׮it:!&F*=~((b=Ѓb@ = GvGrpzՒܐ)# UrE4:zL=Do#:@mR_OnsM#rGJ1O#Ҝ[hJiOcH?&QsZGz%_`H'hPz)zg"X^@{.1JC12F-8̖cP&Ӵ楉<23L69I*AyvSHǂ5VIfu0kv,ĞN9O;[Q(hgL䃌R 4xp)8#EF =|9=*qHGaA8qH6z vUJO2[$**ړ`UR= sAB?ƿ"zDСB!;x)+O?\Lɵz֗Zhl; hLRq1tqւ1ZQip8$S\)JM$tR)JWӂ{T֬3pry tC6:cb4QOn─Gx?֕@lRݞhQNJctr:zRC Ji `h#ө+=*y )N94L39Rp ㎆nKOzc6[JW8#JKV[zX|D`pv@*J'=Ik2Q#ӗs qI Gʂ9.NõK.6{=9&p:lXiqҰ@Ҏ-P8>W^ɩ <=in=(auS8i\gzQ(f8[⠕ jT#`NF:37VlI(2xF{R):nMq֣Kd?U!6ч: sHZdhI{S#&NNE>Kڅ{F9Δ`pjBs89Us9Ԋ=9 8О0:R@ZΆ#~?ZcOQrxiN(w}5N:#Ry>=pxb$3hWP.v46;<G=hN q1PS/9O(?. ZqA) @(׊4g3R:2Ǟ; :Cн֌c4 bN^ RcR09-xԼaڐdJ887J1OҐ0rzsJ{֗99C8t>gH'QqZnt{DaU.'5y" ֨ ]P9R=z=Fq3I5\@}+o=>2?*Fӯmf?t1Y$ty_Օz~UrolDѓ!<jp%1 ޱl"dˁV]ګ, kkochxUuЅP0F{TA8" q f+xBieI$%c;չbE*IA5}Yn݉dثM` Ja[j+YsglDKeQKvEm_T{E @=:s4xd\>O{1k1H瓾(ǭIDR'zblFQ;p zT͹24~T t|sVuړͥ:S O=jQQ瞴X~UxjN/S)^֡!N=9@-$ `8'㎝@Ѱ\1c{9lKTJݨ(c,s֐8"sO[Aˆ#QK8!m(3w5; nS+ܬw8Bw1`G4t'MHn@i <i $Ҧ H?J4/!7*Jc#U"Cԃ .(c_S6(pqSG"GbQ&ФT(TR\z 7McI$5QywVi'HQ~f?5*O"<9=d8U@+/ƞ&K8"1#Fy5+k1h+< !$.kµMJ}JI摝g'5£y]w#V[2(= gu9v1Id/#'NCxXF vJ9>)#"l68(lګݨU5'F_C!djS-@P'IF[ңd'ޞ4O 7(em-y[';VJTmF$W~9ZFQCn<<5F:"Gls20QКI-H2./\;N #E'7Sη `zcG㌊Cw1Y_zזYݧ٤U}ՠ$+|% tD29Uꌈ0T+yỶ3#e\NdけP2Icu ci9Lv'0NoJcʕiw\f$ Ic:I57%y ҋXlcF}p ~>P$74\SŒS3H3U`%$ 9"͕8Pl4Т!<8`rpjVUBvOqUεAnq#5tٜd; 9"{ұ' i$r7v!^=rir~oKnJyŰtM<8xGj C[# {Rg(,rn; bA [dpMFsM;{ngvRW$QC Qn9;}3OBQ#r+l{ @O=|JNx~b8i!#8qPFVPHw+*@}Rs3,AQGel` >yps[r3.f!OH.Y!2vJ`ysKSpϧZxK"l? Q`n3HOo.\S+Dwҽvp}99b~)z\`c%{sWq9%sH3F92HbG`T#$F\V#q֧V<T2sVJ@9?JN[ڡOl$qJ؝O. i;<ߥ8cڛ4JO'L1ޕq@{iA9rjL0N=<%*bF ޘlӕ?bsE2IFrv+ v@= E#|gFV!rGR9e!ki7EǚM޼[24@rFeT'Bo{" vJ`8:TKۥ&6œ񞞔#&;,?&8F)vߝ;XT)u4мi0s7ry3^8zIUx1SqYgNW;Jұq[cJ*7{Xi;xtȫ2\{56E[23=BGn:0Q@>)~cJj6rG&R;fFrfs1U) $#%*A85DY=I1JB# fylIvqڐNR2M֘ 8 M:Ex\gށX֟N18 B8Rz`K-ғ q9({1G q)9($dzA;u穥=}BzX1'=- >qH:j!8o|Sz` )9LGyvI4)Tc=)00pS:NflAMcz?fBx8P/j!uHbE8ݚNz#$HIdtmAAߗE `4Pҝ%%{\pJWljEޚS֝IrsA1T Đ·*i@bPT"AE 9<an&N$gp}=M3 7TJsJ3$& 9v8(pF(3H99O&e㞤y ;<`=GN@r=h鶃A Rp2ȧqQ/a/lt wJC(lQRӊ(@)8hdc40izKIsSF00ZMzbsJ9 OƓ9'ZE'ژ~)N74z7p?*,#3GV'ؤ cG'ʂ 8@ җH0s(B֐p2E(O>qsKc8;l暣w>zQs=sQB@aOjQqeHbJ^24 c\@ycn(Gҗ;Niz{u:Sy4gюs@QҏOJEϭ/3ϭ(Q})e19=(+q@0J{)gps\w-!S4@R҆B1ސg֗9 AANG$2O>NG)0F=qҜz (&@4dhLt IhasK4u4! ?^3 (z2>ZO_J\T`XŞ=ĥtCTet~8K0QsXqkuoʲiZzmʪ7IjB$1Uq?v&4] /҂@hR0zS .kvH_9$sMefZ{3a=z{R\1dj:UY0S[Z6^s[(MRW^N0d2O x!6>FkDEĎSOS $c2:0&W( k 5sONOyninwMRN;W-re=EF@$`b4h/DA4'\0涭'bjLJ]$..ߎ:R*'7vUԊbn9a~u&;Tp}z89JJW-mJFTX1 T8Os{8T&R1'5I6 ً&c:bقyٰFO&JCizOЯSG= Nkw·iCt 5`kNZv:̻) Ҷ$%2<VKF0|w}+-hye嬱9C*Q1W"!F'=9`Mz54՘H9̬,=YizA0< zH }+ tJUϴOs'r\}5d.}iUFßzV\;y`[0ɦ1ܸ)zt& 77Z@8Փj(? 8#ҁ py8@Ғ@We,Wa\J$ ) 8U]VX,'*RvFnpL#~Btyϻq$Z3pG\JyNiB==NM!8bW{[ÃԃN8קSQ;r ow9R\օ-D@23ArO(ZLLzlSqVbXyUf9)9RW)h^vU9E66YXS^**TuMOm\Z,2|*yƳfv- e󞸨diaB4(cV'k+!dT0F\X94e8c?dȯ=]t+*ְS:$ByvӞ;(#MwJv% iMVP?7_z2{Q`&%xiWvM5|֑>-.>`n{S68H4 bF]nxрUV^B82xdd4sPUA$b&Wo=Z sTHެR:ZLIiNN;&ga@)ɩ4ޥHzՄUb9>^3NjsJ lAriTnQHvL H0NiN&99}Qt784^A֐aGZ:sϧ!9搐49\s 27 ~4d4-جFzQwr)P ך^ >Ԋy==1=ۇSP83hޔ㧥&yJ!KRhL9&); NO^[ ƌv.q=h9݃ ^Ir}iH={Ӂq[A~vOF i1Њ{fjd@(%| SG'Ec5#1pXbE:sR#o~4DI|OJ e3:6q9 o=Z c8INIԏ2D3ޕ"8<ֺ AgZpx4ք7F>bhvR N1i:`^)Hh`] bwȠzl ;Җ8Ȥ8y >\u>n1zF?n )Q,u< :A8?ך?.>\wqaM(Ê RuG=\~Q(3Q(}~ԤJNh@# 9.GZ&"ޠ8\Ѹzh KIԃ)}izOx֑B^@OZ4ÑÓҸ{K̠|`ke›.#}*qCp$ik!W wt0"\w:H`9v=I5[<j`'@PfUI4bŶl,EnNNOJз}-_}+%u(̒"T D|pԹ-O_lL zV~qz1sYw*8rNIjc&~u#5U(D`oZ\,^òOGLVݽ. $\ck-\ W'QLqeѬnvm%°;yfV~VS+33U g*3A kBcӀ=gy'n V WK>Qު9V;j_[4]>X Q)kr|\56DLN d\2oq\!ibW;mJIQ/q{})؄ M^({+?P}ZP=Gzqh7)\iG`٩|$$lҜncw>9A#9+9{NFxo~,f`m#BPg[;!U8*n O3Mvp=8U~HF0(y: sQ9x2#7AL 3zyL :\1$nOr-ԃHmTϾko:cZx;BI'p{V~A00AQ1]ʠ0Xc}Dxى 9$48AަX,JL.0= (($Y$RqҤ i.qȧԒm榊YcuF0~2k4"kU>x$qG;?rzT6 N±[.7m{w8,QDwg'ޖ9b >KܹaV-.zUq:!HIlA$RԳc }o~k6hxsRAu#O##* $frN9H A,֘ҁT$!݌v0M4l!|4)iBs֐ҩ4NJzR rE\XI?vqtsUӥZiQzC }qRǧaPo*USɧbnnTPNzO K߯JPOp="rF??t:aލo<sM{S!1۱یc4H;Xr'67*I<cr)S!vBvbU3 #9dqsy hzz6nitl&=qTvu5<_@UG}Lp)c|{s\L$r;SyVsTD,ӷ{Tkv;dx&AQD7 bsJ8NM! cC0\q81ϭ={ I ъBc4 quOEb@ 2a4';'"~tQqqJD\),~%qޞRdPI/A [{S <sL3IJҢ=qR!{;_sۊy8 X֞N3ȧ]l8#ޚ9sN\J'hm;@JLJ7#ژ:JDf!\r)8zǑ рsEl+fS Xq tqF$;-GzYFx9(^-֠K{P6"'N36NmSPխw!'8w{T)(RBJT|=*>y$L4.Nıi6qOE)1^qU{Tџ򦞠qX8ȤRK A4c`;PN)'zWH!p{=Ȥ>ɥlz4玴9(n†8擏J7н^3N5H)ںOa4cgOƗ)LS} V RtϯaJq dma׊sP9i( [ӎs{13֗>'z+!sZ2bl>cPz19J kQq 1sCgץ&>`) /r0zPF{~`}yc n~QZwҚI =p7ds9tcH@'ԧOZ`88RzjL.ޓ98)O҆X@M83N)1`;hI2I`m' 8[j)y8?!9 QA48i Hg;m'8ZC9wS򞹣8v ( zRc*')N( jN!sPsPGij^@H:ԧj1ttcO4S)43Fqޘ1r3~4qiOʚ>ϥ 9PzPOZNG"1zITqKh%M!;;IHxah (p#)L6)q_!ҴIl^2*%RIFu&k@%sZ0jh8X>{}hgpѓc}M9MHEho"wcg^39'YY9hk\zZ^IP8MfE2yM`4r@d˨ s>}o3QSA ┣OS+[nXُJI4엌Vkf]OQ*G+~]m$1:q9ـܤuN5JB1'74pG'b%qN8$aJ0HT) I(^.0˨C&C{㚊B9mb9,4R.I?6sP^HH䞕 ef FGj㚯0 Z"6Wp{ @ڜzژ^% RsQQ`~Sץ4>>Hc;.Ŏ`kּHK9tZ}+9Fmhijʻc5Zyo$^e1砮 v9Fܹ :6]V TgPI{W3v 2[pGj%o30fvЛx҅84ȦʸL,1L>y\ ,;~AސzF{9)ZEi@Ȫ;z$sV$j/r)L3֘?Zs։\0z|)1[D~<դ!!~s)zs%HwJQT! ǵ934 b3Jb')sדOP6[`6&:i vFδK|A(H*!Gp֐ZA*Bs>$ T]F{g+wa{У>3I+c֜1PFiÃ-G+m(#'ݞR$pia'=IM' IRx*41Z8sI ')YgR R*4 5COBI1@y4 )X3I{ސ4?$ޕ"҅R4T}j!z(<Rx=)x8MyxrCb~ 8^JC B~YIҭ#f REBb1Jϭ=U'iNzh$$D`EsQgޥiv!9 Қ쑈[ۚnNS)Rp{S|{SА~jEMه-4 ǂip2O=Xi{UtA'ԑkrwl cgXqKړlgڌ VqH(=ڌ{Pafd$p)l~4(<Ҍc71Psu'JzԔ<9$b;S:ҟZF<֌qրS4 zvsC%  Җ#?JOҘ0xc8kP =h w!>&8z(qB4g.TG}sɧc4c֋z jO<.;@@3@;N1SAqH8@PJS)I?S04+cwЀ`0h$ ' )A@Ocڌ>١PxFF) n펔ø\ސZ00xLJ]_ZBFr;tG14tFIKH#+3^E.AE6֔ƎRg@J;v{z(8Ҍj@(Nir)i jE<@鎴z;ь~4wqP=;сz3ɡ0>ccz/ J?ڐ^+V\\!Ukl`V~h͊4 hHolhW^{4dl@"KdGg#{V~ zMc1]/Verg%Phm;DxR% 8ҥB-OH'R*2v3{S.u٣Y y]}LdIu6ƻ ykHR]". {kvǚq H>mH#Ҵc$L&ӱb2|Gqz8d4g8&1Yaq[wm%Q".1uwOϧQ)b>Jȸ9@j5kkʷ{Yev6G慖F'Sdv]=k-En{zlUM:[[3&S/9jkX\O͏*qŖG4bgbA=sUo,ӤUb! sTW6yq%Y2>1| jTB:FǟS]JÑ(Gzq>qցj >w]N8I)HJ 嗜R W|)KQC/CWW4zkA ~HN#t$nB6jC4j!I~21C)0D ri~~h);xϥ?4O8W!K 2IL <&5n+VnhimvH)"*s[vzǸwS`>Úr{m=Wr~CTyc&3*IemOjװ5cOy5r; r?IJQv5n5E O"f;j3~G~Cdq;}SLI+#6(z XqM*=& zSYhit(i E<`[G iB&^je&mrqKsfgd#>Ȯ_.4 qϸ.٪h 2GOe`0b:}?*u%*9UO9- {j#&'nqZ-q\.Ghf89T{rTiaHmGqF}=`zE!OKbi$TeKO86O:LsJ|_)G'.MW*856q VRs1֕\Sy18B@Eqj]´<#pGjxUGprj teqH?=l 5,dMabxάKs<Բ1 ҰBumu)|P9lH@P^[=OQ$\uO$ 9 U ʙ#y Ln5$VP1i:9aނcq vSc"AM9ץ8'f a7p9sAs5S[,3u#Ң/ɴi $Sd HG=@cS0T:$jg(Xej g#КWl.IJ7 8@3 sR݃ڣ)ҭ3&q)(~ێ ӰHXɋb .NZA@A40y!;"P:8'd*U, JΠ e%dFFLuOd57 qoKe("2^Kq\ zy#|Nz10?:솕l;ҜqO}*sedn"b8< GO @@]T Ih 03җ8繦37ь ; GH{Z`֢z0Jx_H3ۥ9H 3 ?:Uyz`7\ rzSwӺ{ynAHܠ[8`{PrEl8:w:9N)=;@< 9Ƙq@+tx#<ܤ! S'9CA#ȥPb{R'uHJ~4 4OlJÒi41PpZry4Sϧ*{wqD6rcMޗ=@] Hs:o(RGAAI֐j^۽'t"Xry~vRЊTwrzMH׽0`CRa ҆ZՉ xF;8)#wJ.U#nOJl Ĝ}i-8#+ǵP硨ܣ,@i%3Tw }IЈ30'ҬX F (Lt@Ϸ;}iCFI4!?.3JҝW$ҤXL*XyJ0sJŧd9G36{SW8J[f<1z|wҪ$,I4'Қq0?:7FG~4G621cd/N3A{׷JOɥ⍠ք\qNh;p=Ap8=1@ Ia0)@8FGj^zPr[zґ9GAK4_΍ϥT~Gk440B Fzw4 J1@R1(zq@1IG&shƀazhϯZ=iq c@'ց@ 8Ͻ.N F8i Rcڗ i4zNGR:=,OP뺌t\~tS%A"8b)O9(Xw9в]*wF8moY{4RBDOB~.dc$N4$@LSo=UGBs]07y͜?!H1+yjw1.Be"3ZZlB0'b4UAx 7&9`[u'~I[Jm5`$+ Y 33u~śq̾ =pښFrWKbو*dBx5: ׽.H@GOzQB@8$db7Z֬RJ4vPޏ0lV3ICX*H784bڹ'Z ̨'ҺKjRՈd%Q^uDyQgsԓnD"c$c99E+ &Ay>#yMGs4$J98o†Gfث&<.OoJGoUG3Oj6,R8RVr,j59b}iB9*CB*pG"\*)$tU!SN˜ø8a w3 'v#]VnI $kY[u[h!S!O^Myҙs'58u2Ğ9\ӷHݓ`:Rq. @)85_=pfON{dI3I>4r;RczqҞx41J44>UiLvY9Q,j{z݆$[S9%m̀'SIBkIx5EN\;kR+sNƐrNzCPݷӏj]!oQJX +[Qwx}wq@NI#ɰN9 ؠgzv9'UB˹ $~T=KddtFErYN_ 1VlT(}e%rG*5"aJ{vOCH8${BqA2Z=E" p1NEϭKcǮL+zsS~p: ND'4BTaS?Tv5G@@A$hf. }QKa\@>RGQқ8`R1ՆmNN)dH\Zp=8ى?J{zRpOsC8HG^$vTZ튋Y/J)u{rjŰ, Uڧd RC. =iBFJsm#D*Qa\9T s#ئ*xBFҒ bt=1D) id'24>bqڞw=) š=]fO*J硡\۸Bpz+j=y wN ڝG0e.? `J|ylhcOS9'g<Qbji['~빉U'(}iĎ)A8:b4'F0 G4g?A4+ vGVHi OjBF1מix& zRcvm9H]E'&OZ\hA&Ob׎mރq>4l-#o)C9~ $N(9@qRB{^ 3(`w=c'd ~TOzjӥ`1(=3p4Lޔ@&qNSHz}zҞ@$'֛׌Rwgi=3H{ց G)F0z1hȠws߯s:3PN1Ґ68qJhvu>c(1`M!%N@'T3^:HiX7~4ؠ1=1^0= &0(@ IGz\s?1Ͻ6I+9Sxإ9GJ.H@4sH)sjLr)8۟N(Rz1Ǧicw'8V4GҌ⁇^: h @s׊RI◚M#^s@ 40M0ҐYZ|Ȏz֒)82]ڤq1W  EjYq *%eW-:C+-i"gYiS8l ȮFh$@yAҷmn@>Rkut4MM'UjR+1)xԗ(Ğ\dcj뮭.vk׹UEW5{nY'J~Dٖ.L .VTl;c*Y$EGHƃ&Gu@;6rp iZi0lnjд9rD'ҹ&cau9p+:}%X'y T;69RT.9tCtOJBxqC(Z[|sZIjUϳ 0zRfTP.֓JLQ+g @"(n6G-n̏q;x`P;S5-lbG<}_4^Tz7g.E>[ Ȫ drIV5Σ$gj9[9qS0j|q@S7N(p9={ Cd})BpHۖЮ\qÔ ޴`cғM+=r TyPc uj6h1^gϭj藯g۾r²55B/\Ljo#~0=}v;cFzbGӧ];+gCk$L|'Jlnw"9ǵRcnԤgLFJA&?9WV .٪OӥkIvLS;Kq9*eI/'ֆ8In}*e]A`ę^kQЉb s1sSV9Sxʣh3KsHw$2)D -K4E@ZH 8b*WrIe-SW_cYgWFzI{oJw֣PIڴ7ƴO.ħ; 3|"_` p;F)Wǥ.Alɰ c57,28?YAjGB7Z 8 H#{w꟞\f`u[I5GmGsiSrAc?ǖN/đT!~՜cJA2Þ)F7)g4@n8R>DK3[&``/Ty+{Ǔi8hdq#(Syғy1R)0OAKcQX𬱆4Q 1qo+ ͂qȧâTj$bN{ !^,}3Jc47 քKqA$EF9HfrzǞ`})Aڀ2)ubJ`#9*iïSN/@4pS,0⎡G8!d:ϥHPߊBiÒEf/P1Ҕ?Fy=n-VrN8g&3֜BS^~aNcwGUցE1^k8R{[ ? w@#R6#A$)(/f=)Oɡ'(xu7)S y{WI #g@@Z8^4qo~Nhz9);hdu8H:tӚ2OCڐqhzw,q@ ?a< A411ڔ)8G(^zRqarw~n2SzZrO1J `I/~)`iG!|q@!9 ߭)os@ =qKpIs@3֔7I4ێ(h#949M;P0ȥAFsR`;#;QO|S p{SZ G hڌg;R4dqAC )@ړ^{ғӚ@'t\4th) ׎֝~4NyGގ٤!~}(AHr}gҎy B{'oƗ9pMt&\ӃIӁJ6!s =:i}(]9j341ޗ3t⓿|PAہ4c0psp$@jA`=2i~  >I)zpr)}i3#g\qIO1OJp֘$:{xG;ɦ8sxnzEs}SUHNytnP< ԥN]njR4zG9VBG!\`S.բ&^NɩOD\1(]y>9-èI,ʎ++G xڰ\O hI|qU{6sH5גzn% t+Gڌk( NQPKs)9ǠmMfeSC>8P}aƓ@7 HjHaֲ<ǂ~,)|v.ř t !1>Ҁ;fiXk2 ڂJJ Hky) S 8VڥH90֠[$zSpOS<&IP>arVMp1إ iŘcz@ݑM}q*aAfjvzEbsCms'oAwp @wW;։e%;r:ԃCp_9<=)2H9o~TTh0}iĜҋE O^5{Sq_!l tQ4"X66 n֎<O(HN3@(8g?6G搜:P},.^g#Jpuך 494l? 84rTgH+#/Qo q֙y<nĿISXt⚧wS>_BP>UނFLh GR\É iJ]۱3Q'pTuF}zQZ:8=3M ypi{HA8!]N*D]MuS{!_TyGv6UuB!\UFUkJjcu@aZYJ)U3ɷ9" MOZY*.~u&:!a 4Hvm'] G #n}(|F{Tݗ($Q:ޖ=`R@0( g4;SqOz,;?!;"/c Һ[f/z@E8g<OF{QA9@l>ѐOz_lR hү#&ip:69J:3緵0Q8GSG\8$P#vS+zE9#4?QQI ${hzҎ&1K8hA88N4GJ0KdzS g$c&)U\ϥ "ZA~4[?ZOOOZ\o cs֎ atƕ~n3ڃz qJ:ux @x#ތ r(jSq4{Pz惑Ku S~8>٠ugz@t4 :{M'攀@p:E 9 aI3hBl=}ĊLށ Rc7͏j>4'ӵ!J{R~)cF=hZ{Rp1֗`J(ӊN{`:hs(r};tF(߯4u 1I)sҜ4@ 1A#4g4vzN=3M:KW*.S8_|y<CBgq @P0{bJ3jBHyQԚ=hjDP~3\*\^ʬ =kfāWZwGu %:mnvF9|;cW+#֎4p#.i,$S2'y'r^Dxpy9Q' 8HI'w𴋈b G_V$*u98MdTyLIݏJ«2-}XPU)HU1P\BLbiH۩2V*3މWnUC)nlo<ICqʒy朡OҦF影Q=h%%<̪'ʦi`lVovNILwi\taGZqG4sI;['=)̌DŰi_gF-@ 5aOi |w+x4 AFNh{ƘpN7C^ `z@LO|y3;[*nzGS@.F˗.RFDn[J'pMJ$LK}ӑL vZ21稩wAiҚsWn˰z` |ԊEhkq6(n'eOjI'Sp3J{fNQ#<Ѡ\괹v #fi&]B8^c Nr5줃!*uJWwGM9jӕ}D=vZ+R)HRs, 's֠'$:tE9&@%{S2zSTj1 pMGBjz}` 2yc?s*q[ke`m#ӚʮԵԕ5})B{ZHpͤJH$rqJ#>9a,ԧGa֓;8iy=sH,32@1R= 3*sJdUqJ9v#?W XmCβuC3M kLr70+VSS%#c׭!9#fy9bO5l|#L:P\}*&bZ,6̤`v#0Aǽ4ZL$`SB3Kzg&s)JLA~E('֙ӭ@E wJNKЮ\⦎&'!9k9H.(AYF@K H|w }+eCNJ48P^pjG?R2cȐn*9B-m>FOsM(sFsVz85j݂QGR{5v"x`>H qU=zQSIl8% nju}*(!U ۵Gzrr{RhT8jOO&.ަfߓ(dRT\ix"GZrg{ ,Grq P=cTdSI,\0jGbO5 c-gc2G9jߐJ5&V` hnP9PR1holPb1O^Є2)d~>f=HӹDEIg4PqjC)ng-WoWDO^jnO&!Mji1)Èz^R3R[s׊~ZvN`ƟRP:Gj6杒IJV.< z~9FwsJ!9] }s@ g2sI9F}T1Lj q֓'u;݅PO'8֚8R14zQ=yGH_ ܐ4rx'<[>#z{ѻ G֎)h=3ҚǥSBD>aoXUqr#ڹ"ΫբP9 i:%#r=*]F6f1HPU՗'<~5EVrI svN㒸p93qXz`aFᎵ+ciJl_w s&WڃZEVZ9`GqȠT})2 =)x'ރRy(89K ZƎ8Wp}i ۏZ1|gi =G^Jwa{cST`NNkx1ҋdw=‘JG"0b 8'n{C(Sr7zS@A1Rps@М=  ϭ t<ǧzS12Hc=@ l s@z2zжq9RnzLP!H$Q !;G=iCg@!:^bAhBq|ړ2{PI'4bc=qHqbr8agIcH.(RPL=MqA'zJ^9K3iA'CA7A{ӺGjA1X? i0Ҕ0(` 1J:9 #֌sJ:! {x*OZL&A84(SցO89K@I O'׀)=!y): $('$@)灜1{PS=}f2|2N3@=G4c9a'g:qH)z 9q@P4qKbQ1G"71MwqK;RG#ӭ.xyqtxJ j(Qړ$)y{#8s@ :ǭOK@ AKS1H@=;SuҗPǵ'#9 8>>3I!sRRq3 uےmUW5ג3:tC`V@r9C*X ݽ3~ [9Ywp]] =1Z=;hjG[(gF#fB]O0%'۟k.ĭzn7LQmP;kI$wzjh4h7LJy#w3WiwBWsxf`~C筑"M'׊ϸ|lxIf[x6I=*YzR\Wb=i6}˃e5Z⁐x UvvcT 5!cOP1(Ln#R ڼGsEpCRJ MK{7g VagR;S99w7@1 0})CIq=C( R%aɦ4o'K'#) h'v5)p0)]kB@Ǯ9~~OzX Q`t:ԭF0r9 <HJNzPĐPFsM۴w ʆONi)!P@8<3xy,273 ܟS֑XdjqcBO @2S6zzkK0784\V#145wӣ:})`{R+pO4t71K(ڀRe=mk0Ԁa[֚‘1֔ig I:4cqGz@guRجwWNXk#y9X 5Wtѵ^P2&J 0ÌMrپ*^19 c 3;3RrM ҙ1 ēV[p2{B&ϗE@m׵1 E@zRUH˗Qڇ8dR)s+Z x3֮xǟ- ֱKbnN6G4pb#uQH8U6E3nw94`3pNИ+IFbQ, I!aʥBi`*20zޗ#1BF)7`9F;WO=:)G=6&pWaWn^3F6dkBEc9#hJRgK:v Tdxс`[ڳ]|ơ.d` Y<#(*5kBR-#>f)1 ,ASQPCP*#N+(Uf-qX]0x>$~U+G)[QvSDn$Ty֥ӕV #0ojF\{SC§8oΥ3)7#M\cc;g2iX.3D( ,[U& Q%zBcO ުxxC$g rčT{W,дdM{0ۃNj2Js[E|"F* ҝXj HW#R$qa*E_ҟ*{HM?(`G" J #Oq7ضÌUU'XZU,rdnnH8^& ܏ڥ`-=Ka,FEXpzU wa(қG֜ ֛zP1ֈ-qH S =j0~`h)h*0'9ْG'kfn1/^N.owX]:g2dfEnI4 ##Ҙ fJhmXXGpG =S!rl2($xƻ^Dp7/ZQ=(7asԚ^c RB)=r};{Q8!1֓v8)9 O0&sK>8֔hfLG|BHINO(ݚ8ޔs9(8ށzpr|c$TpLq]'aNwwBv>Gi9"O9LzvJ}{Ҏ!ҎxA 8) P $恎ߥ#-(wi982r(AqKv#LJF@,)JvzdRfh.sh<)@X8@z VAҟ@iipZ:Q=h@랣h@2 i@ujx8ѻzӇ# \8c) —RC iIy"GJaP{P< `np ''#>}1ޔx#Tx (QLBpO8*:`Rx( A!Og8JB3`g׭qK3a1Qg?)f}i2h1Jzs@$'RxKxAz MUyl wMM.7@0IbE2&0W&s)Np i=B )Y —!y(g qR5£@HH_҆=:kA-F G0qN9zw:U Roڠ֙NzCg[A5sRy OSvtJjf8A"78H=2=iTۃIxHG9?'Aɣ҄1qlHN98~{kcIt7 :T`wp3v0+5[MR8 2ֈI.{ԍ!߮*l?2D %P>_ϥF$$M<{Ӱ!e'ޚc<=~ՑʪSVUD~$13OZR9WU }*,"r|דO358fU%ЉMمq#>U+={8  'M+ܝg,TM#wdzjD.H݂isM$~4ߐ\g3Ii=E1f֐zbsRv[WV6fۃV⃀ `ՊLrOo#1] e- z$ְn4;=Mex^ilTsUpWKcO]Ƭ#p3…4`COMy\n8cW$t$OAr?t'fRFq*B+?J$[5Q6S|;~ ٦˜Ӌj94rR*4=)ⅸ\NI2~^ ZQ#`8GAL w@ 8$4>pMKӊvr91*T{UsqLLp]b$H?έ nLN~b/Nz`#ZnpzүsH g8kDsI!;3qFN1Q4) H8AON)@9J{vpzSHoq޵H9ǔ:g#jE1\.jS!fy#lN8u퓚2U[Zcةeoe9:*d+CZ⾸I~)O `R-&yv~rJNzvzd@9G0sx!2a~j qѱS$3Le\yJȒd26`wPJ3}=*ˌ䃌Sz+DfBs\`njn\1M} :zRG99'AMՄz 2N@JxAR Ҁ܁ޞXSWLNf8>c4p:h^ !HO|p+A=ANFh)I%=1ǭ&yE)qN` <޼cNT⛝i)Hd})KJw$\C8m g'3\Kgc֓ nds@iW~Fy'Niڀ{}E@`L0p8pxDC'8sJ@;R@rm=h4(#jOA1@`M3A#h a}i':PH!N)ƒMAڜޝ(A(>إC kuN3/p 4 &K#8#ZB7)r1N/y{Q޴' W7dSp٤w=ݹ41 ih qtYWzd4D@'>7sH{UPPՎ!;v榔9Om)OZx003ҭ3\pFy}sMP"ǭIwӻLz8iy3օHӭ({thܽ=R`whQփ;Gj(ޔ;WIt3җn:ZQP[wP!3JzQۦG.~`@3@ 88@Gr9JrN)27;8ch9wҌw`KÞⓌzLmǰ4 :Ӈ@.0=rF;fݽqI)ON( !yr}(umzР.9#[ԼGc@9'Bt@NriR=M ȥq/z^~ݟjWs׌RrxJ4c x!0EFx1R^AIjChךS@g8xHsLz =H2i`PPO9(\ @'Ӓ(4zNҀVf##ޓ8=) =p4g=)wdcךhBsz1K' zwt=)1H:phAGh n8/'a@xǡ׭ zҊp!Kޓ=ix@! )N@Z*h@9z Nց'^/΂w`L9QA$9G4ON1KzRuMp׭.G>IP Q7N/=GSHh{P= ژ K@=sGC ʏ—?.1@çOғJZ#(@d POoJQ($ccӵ0Icֲc?1x4jD{:gs>YmN.'յBDa,1<zI@]Ð+]o'$snjVB0zi>=ȃI>VC6}R5RȠ )2o(6ښ#)p۸ZkBS#d!0$?-#IN8* KBBA8JLߓ@aU0Rrӝ1JN}i=F4!aM<@3 sڙ'&QR3ҐlqwӧqM( $>6A( =y hxNiOA';Gn08ɣNTvA=(ITWq7 aҩ{t-zH< j3㨥gp3?ZlL$zSp#j F߇VOq9kÚmĮ Q~ :)`?388@Q)ehU@ K'*޳5'H}II4v؁ 2@]Z/OCT%j&NsR3/,3 eb*sU$+͠b;WIqv FcZb9,?97뚺IDݵ1I95nrLǦ*_ׯ 'M9GzBIi2y9)Hx3EHM$杌 ֒ s(Gj)JWLPyhdOR A⧈4jZk컣>QK2QbdFoRMg-[9X{U| ce\"'-Jx>A;qOhO'*+XEW;tD%NShb܅~9]j)$V'vHJ} \7NG~sǵBmK6-azTLA=iI1!q0\@r=)N&bpqzqPn=)F;S28&4 zԤ wBF9=i8HyzӸX1 5sŸz{Q帊8' ޜ F2qhf֐gt[Hlv,94>ZFjhOr}i{h,:ԓRh" ji0<V?zHG=꒳*/B|T9+j b:Sep2HnMɡ`n/^&8Q3X$|CTth#ڏLhF2Cu)0}iHӎ3Ґ(b;RgZq*oczHMI r; KבҔޓ7M!$p?V<@IzNzqZ\ԯa6!<{M(<)1ڝݎpiIhqRcSրSC(_A+pSӜȣis}(/U8M0WB;0)qGaHEh=8H{{S P9qN1֎4ZḤiǽ+9"g‚Frr/4y?ǥ.9R q4O==(Q@f:Rq c@ΐU4#ދiz=)zsrO&1 aHÐ:{:ӗ+֐t'v:V=34G~dr8?.{:uu⃁0HFHlQF2r {Ӄ(ap$GR@ҁZ(8Csإq bg(#ڗ`c4JvQߞ/^g#PuK)BM $z\ b1  4q@i7ZQ=(@s@Fz{SLB@ɣz'PSHn{R1@)K~ԝ@x\z;Ku4x@S/~) N8긠ϭ 8N(KG@Ҝcr=S0ir1RJBh-/qIځu9K R(H']E::cր94<`11.=z8$K!94cd H'iH!wkYbTacgq$. [+OΥ"P^$-b1JxU= &!cP=61:zv=jlB L#ڣFjAS߽)9^ 20h#hiAl&  C٧`OZ $MhMӕMuiRN03L;*n 89Ԍ9bSQ`S`T4p83z҂}) fNp#5])7U `^KD4&sH [pH,.FeKQ| i!F4蕘42w&X~T>֕qKs 3;[9]e#U5"HLWj9'})6G TD6RvCWoqM H!E<#dSBcZ76:dsNˁ4.JZRspzCkrTls۽HbQT&ܯ\Sqוҗ=E ܏i}ڎilŸYVx"~:>MYBװG-R!'?@+NI}sހh!G#N[R7ojr; [}=i̹`*ł ٜ6RP rO@xaL 6``uV䣄ۜʞ:؅ 5{LcKn'kVԅ#G5$bsG4q:b,INg'^Jjj|{qb\Kzml ɶ"gEX'85$BF!HǽW\:OR@lښX6* i &C[H£y.q@yR& ̓T&WߑZBuNNQr8Lr9qjq88g4ZN8rsP8zE9VG8:硧$j\V vAjvi(';PG"sGCҺғ g=֓Є<@8`M!#җu}hPsM+U)?|=*GZ`hDDt |Z7NN n;'9GϵHTdd RFh(ѻ9#= OPsKL8=z8&aB+d+KM 3ѴM;\9vddv1Fr:hA8)0iQA<;P$viI()v =)qp2iO<ژcYsE<(Urp=Ci^r1Rz6h)${JW{Kg\=.2=)1#'?Iҝr{hV9sڗ;z SSW<=P|=U4@q$. ! I0Ңjmz^UE?;#V!cirZ\{y$AR 1hHCc֓JSӞԠ4Q 9҇#G,E4{+' эA RcN`JqڎB nCF/GPjBK 'I4rA(/Hrj:4畤9iqh9Iأ<ؤi sSQ==hR4 =(Q@(JL)GL@p@*h vsh9;KҐ 3J8֘ 'NJ}) h/Z42yz JU4!ۜw \&qր8%GA84\jS3M^M)'#]C=t80Ⓝ!g)vr;W>sP>W\ӔE3 #ɯ>I2<'5XԞK۩g"NF;=΅e )9cJatSFv/'&лG4=(,H, =W 8ǥ(;u!,pN*UsIpتCw#>x֢VnJW(#E$~']Iӵ \REPg%ܵw%,ޑc 4WBZAri7ڣIpI=BRSC~NGJ4㚝<)B&)c_zF)җ,Ґޟq G>W E ZB4 Qzf==jBhSbPT*/\;Q G".@34˓T w## n#~zgAqv /* pzp QI&~aJm# ҐS1E`ަʐ(bHҕ irr.yҕ<ߵ.14t*NэkJ yxH"sLǽ 6<.!6Ö=k$ c|mf̊]x 4ަwa Ǒm ±O{m$.ii'=+B7PLpUV{2МH_عvLp}.Daqr]#K}♼KI\֩=&W,HZ#M"RH[jر^V3=zUo0z皐(t%c崰 C\+]1Lr+֮P'*QBOMD}M#% ˈ\'*G5S%c$}NsL,T RDNn80Hj-7V`{&2G$еF)8槺mdlsSV7#8jaҚqZi-"n/iI3sO~hMs6{Vt⩇NG^)T9O!lxqd1 V7'HM{Ǩ!lLAQ:RO9 3\j)$5"6!)U4.rҞmQM; kIPɉ"DNIEo:~`fC;dZX5.<_kIs4WxB,{62*Vrrrռ#k6cQēT[8i98'oJq<:J.NJNA惞d@?w9z^ބINȤ($R`gƔgQ~49 S.6G4џNbEa"Pim"M {U؊gzNCA"D$U ">`TUwRVhT4$ʎFcNKoҴJy4;2g*0: [X#<6WDpHTh`r;m dsG8MiG\y i᰸?D9YR%S5Q_8fB'mܓմ\T`o5q$8> hL,HrӸϥ;~jb(#9jhm*|')00E8}1ikNtᲠ)?QLpBbh@13i@q(lC^9\PAxм7қCwman5&8)Nr>Z JU`xQT&Lȧ~ھpp+9di3 PhRޮ 0_izbA:#.NЍמ*I6h,qҬx,w#p^<:T( :ut@$4К5\棐G9; L胮ATB*74b}hļҠ_8g 9)WLT `-)(:ԋ6R,B aRڤȐ*yʚ+!wu^$mQidzUmtCO@q׽9<iJaH R{CBc8a#7plߵ)%G'&p)(4f^J2I`\wNG@~>iA=(Θ RK&p)qAzPpIK MB4H9 (/b 9@sϭ҂4[8@NxN叽!=R qZ1{ASցl8`qKgzOOQq)~9Np3P! cZRzt8{v01@ޗqI+~#%@9y-3M/P}(c;Ea7`Sz䎔ϥ&HKGb(@p7?8J3h pT~zR'JzMƏLSi]!)G@ي N@=izAҝ@n&HFzӈڐ47)AHC!' c*P;9"#r~ BZLdү9 ##8i r2i4PNq.G=S @+לM=:ҏCî} 3JH>a#"F2:bQ@P4$^`1(/#H.џ҃m۞bdN)4Axim:RczZi^:zR%sҘ^{&CZL;rņ(B[ >sH842);.ѻ8֗-ǺwETF3M>C'}3bn@qM#&4jhQ,ri2F6?q qҗ8b g֧݊B'+4aN;XE`LJORPFXTH "'RD3T5*.7T7rJUU> w1ݟZ(eYk\܊S+KS= _3EGxJX;vvvtHiq֚`)3GZzLhn)A-Z *9 7:P) 1HF*$Z.=)bO=*@0+tv!A=3YK)ӯ=xq浄DҜ3P~aRQžzR<u{I9Hs/!UOIG09ސ hD6rsu'_Bt{^?@sR IsMPX㧥ϯmaWqҥ TdRc$ےڭBWzt xY~BL'j& 3EՔ|h] YN81SWs N F`jw̧V}MӺ$9q6VJ/3Q8Vُ"?# <,{Mmda{~t䢏UedS` 6>; 3sQH@bsɎ>etwJ?[ԙc0zP$jj8Y2= |ʄg9X\"OCm z,5kx=~9^!;ޘM16繠Ktzv@=?Z$czQdrF{P ](8\R4Z, y&w=($ `Р4 ?3A=@88w۸s;1 4:4N仁rzy>SHAbr{P=vx7w9)G@Wh$LN֐!ҕ`H􇓑K 4bd$Jv63c%\U=1V9>ԇ# sҋ AP )GJ;';v/{x#Hv7c#GoZ8ݜ JxR6?Ps@+l.`3փqM Olpip 7Kڙ(EWJ8citz@ +`1JpiOzmy;JszP R( fyJCӕH>0c&qJsցHGO8 7L7L@Ƞ G T(r[秧#zP {HH+)rxq |S7`c40;`փGc@A'#ҋzop {ҁ pq)xƐg4r($;Hx:1l`D9ݏ5QىD]}KDlBI>N` nLžr\l|gLw-iYQr3NK0\dՅs*N"nI## D=HiWӓ8ZZjNH1xw=( J@GƆ'֥*1V];~1g-Z.ͭ{TCZh4Sdm4r#V#vj;OԤV*894APGN֜Ҟˎ*֌[-Z'BRpMM m?*v \+1g4z T b۱ޜ@65 V%)ӊU㨩nHq:GP1QqZcHJҐqU!tx4pq\#N÷a^M=#c9#l{9ҡ<l1Q})"d8( r)ލl1Q\'JFSNSJ#OQޕ#: +8V;ҫ&;8M.M m%B7vQ=BR1l26Q)q؊D4G\`zStN\qDRz^ǥF1ҥ;@J '?Z^@1T8dzҺi8>Ɓ|߅>h*5zOr/>aOх/'Pp8CJp nO֤ gqz sȥq@!@BG tNP1)8=(@&9H4;ԜZR8f^(v)#c)ӚC?Jc R0& ֓`yo{ '(F'*|Jԍ=iڎ kj+)Gr3M9S@Q~ttGa^7 },"\Rt^zw )g#9za$){ҁގ~4 ʌ`҅ (8l>#'#Vp8P23K=F(8K $1`cQc4Jܟnрsq֖Ж>zuqty ޚ1[c9N)pAHn 'hq86 zw-pNncSFH()gF&R rk,`gG.=)4 ݺ Fx@"brq@0٤qKӌQԃqLF?w!0sFxI=hi֘9җ !1ڜG9'8 @4{SXqJ4 -C<ё)zc׽&F tF1I`:A҆7d~=h ܸ> &zғi'<ӺP|5O=")zJzP-h~8 3G!>P>]9?1 LӺ0`sځ`^Oƒڌg94J;Phhhڀ1`{P>ғj1LsHNǵ#q@^h9hR4ix#>Cڔ T4t(@'֌ (lZ'AqKZ03P߯Jd=hQz`zRޓ9ޢ $S%a搀7>,axXKO=W5]Dj:IJG|VAeorJWgE8`8^ҤҘqRX)㹨3s2bJpsMh gK1I"FsBn)|YF94!iaĀ#ۜMsB!ryУnIoրߐ9➧cL y=SXNpGjkA #ɤ%vUA `SJd01@dZL~fғe n-: BjD0uAJi#N*n=G /CLWw9M-y[Z#7dg l89Rn#/~TPF9sU;$2^;Wvrs҂nq֢(᳃֘bBw9'6XSv}[Oa8t JPOZmbi\*I=t*%\FvVVy,4(OCWv'λHZ`2:\j^/UzAs4f0Ȋ.ftysc٬}zxv7=3d*ŀ9z>+qnX,(H==+̌ҚT=?,{j Glh,W8J/) S)%3<2va19Mv4&XyosM\84r:qN JMݍ'4ΧR0R1L -10$S3~84rM$]:ӄ.AAmyK)j%,3±>0Nxǥ6#MrGZH f`Tc)qJyUW]+lnpba RRkZ)g( 9~_Aldʮ9AHHIzbX/q[@@Zx& t0M4gnqҐaH8NgdcސzAtPP1HGZ\4øun{ӷ qFr*CqOi#1s)ޘi -Eқ2x .[zdS@F1L/5&0M&!E )`@Q q#R֘px43OQF0ĴnٶTX9SY:Ո:ŜUV& jX$: f)%ӊZ4b;`TF8Ox!ME94@!H,!NZURni~Z2[vqu{\1H? .+\nK/I]B8ޏ) MsRg 3hzzCw^A/Ҁta|1Ԋh JI'a+ =sFT?Z^1IwϨBˎ١O3^q֚On"$ti3vx`bOZ:z JB)&y}(<~4u攎wH?(84 wc(zP:u }h zP,Np3F@8POjPI#4EŰsJ8@hcl'c֔974'a/#`z^p(-EzP1ސʔp@4ؙ.Bi;@{(x1@ZB1A;hN8gB֐r@z11.`'Cuw@1_"F=)=hd& qp#,AXjk`f,=kϷ]NI>֜n+un8X˜(``nBcs"c'J./Zih ޥB9`O6ThKwJ( :qNcOkQ')F)Zv!nUo ɑ*'nN1âa#*!nn <˘X" 1 Hj pzɦۈ.>ƴ"9WrJe#'q;qMgAjasZiʤGZB|ڡ2zՂ.j?+_֒z9ۑ0 Jڣis!=i6jW4|5$&*p8X?Θp-=#w{KL'ҩ 8⌖g%b9S񞝩*2`qR;8h{qR'9{g4ぶ0nX/40)KfFI'=7M+H@4: DA(+ދ3qЀ#ҝG'j¦b{ddnv{n2sFrOgV XdN)1L2q9ғC]=( )8SU'4+Fn4[99#' [ҕ/!B1JՔP#݊pud;@" zW]HK Ңd;ZLQ3yO0Xʹ$w1ېMO$cPX:wJVcv8UVvّfPp;X} oi1;6yEI7 )!4=ǥ? ہSvQCzn{tc8&%֙#n$z"co^98 @ g*J# 'Z_KsJrǭ6`$MAG&:{z kg 9J1OV!8<3R'!H>jh \Ӏ FzS7œ1)#=iBwj+j3dr{tNc4Hѻi;Lu dJLJQOLҎM!0 #ޢ 2)3cz$RA4lPb(P;JǵkQl)<"ЭqE8ǾhvQG~٧A 8@sN N~΃ޕ:b )!Fid~4"╁n( 1O=;~n9^G ϥ z7(֕)IwN=)&)ڑ}iOBCd`ȧJ@ZA9ŕ ҆895Y\:)>m  &Fܙ~_.ɥǭ {ƒc+;piI`p3@xQ\zgnM=I2:hB= 'N/QAhD}3OlQq1Zmt—'UN7(ќO pxH j0AG#s;ItI?0JsH2@8(\/\֠F3I 4h#1ӊi@Nh"zH ҂>c\LI >=})Oʐ8贀m{`N2)G=QJ\u$zlE~@=Hw\s /(sF2zwt@wڔN  G׌S=zQ)= (~>Z}F>.>Li6Z9< :ȀKPL̖x۞ NߝssO,3#ssYƛgQN3ԑ|I) p|-#֬Yt*4zsVi2ƠvT5)n#\^b ȨqF #z1 LvW > n+AZxH^~vc;zSeE=DI49ڕR9I* 5*;*Ք8`&f-H쐷Ck][kciœN >Ɛԋ˹PIhaZhViu]j[<͎4oR]z<Ӟ5sHWd<})=5WA/*McH!ޜ@ң4+zczv8R ܂qV X0GjO5~(%A#cob( qU**XjrihE,/sUEAךj9:wlInݷpU40CLg2F Z ihi9Z+{"L9PDO4V~4R`xM(: )zqAN&0hi9&ށX ch R֖rI4Oj^" 1H Ƞ.Ịel枼 FN ?j@P'8m4LWD@$sqbzS11I qA#9w q@=(Z]BbiOCT$iZ[V*  WŌz¤R2A8r{֧,bPHN =Os@:ӔA8irNQi d`Ԋw !瞔%AqKݦrT➣ښwHI^Ɣ(  1MZ3rNsi \Y :҆c.29ږAdᶞO"c4+ i>C J ta) 39y\!01H7p2:Ф8" E {vx=<&ҙ(r3 IK@4I4n$Ҏwz,SrRgohA␜qF$ J8}3 wMCqFy'wM1= zҩ,=}iE 8zc҆۵zN4u◐JOQygh wc;>wN\9z9ʝ8hdJU99=qLiFIi!P^;Qڌvl8N@r{R3֐)wt h'4ASxɥbO8}iRq@bq֎ Oz?.wpF)0sԹHA$RBjL)1H:xv ANA-hc{ӺR䃌p==OJ7#JOZH.*$u(2i } h) wjnN)pp8qԟ'SqϭAAqqL_qҔg$9H\zKtѱ6ڃԫ9+MT C}zTR"GJwB/#az*p3BTa6="LqihuzNHѸ vM`WvbѸ&Rg$us JBcJ'c6&AIisϮznXTbN[$c)S),϶MIޔgv@Թ9H:c(Oր“JH8JKAJ(nX:KקjAJGJ. |vMqH@ zB9vOh$9dH988(Bu>8ۓޜS n'9)lf?= {9 44 rM/7o)9|ԙ>ykq0A#/ZqI ⃜֔}hO4P8Iy͊V74 yǵ}0y=@v. NIHl u1@pJH'd` S֙7J9? Ki<ю(J8 x@'4HӎaL`c٤1@ fsJ(zO?.H֓GM0iA֔cqHB?QsN#ցȠrIZ@ڔzhɤ΁0FiFi2sKi`'7*:r(zOu&Q,vdEU~cYZdxg8۷#GSi *Aց #ҕfhq8Q׎(19=(Pè+7Ѕ3Fy#G<()_Q8|8#Rmm(֌>\9R"p@5&80yI qF+)Lm'^$ ƅ})v>ӂi.y%e'Tqץ0r3N7' N@Nx‚@U'41)3E=ie=iqM-cb9q=qHGG?'CO$P*GI'qG9.]gsxL;h  .j5hiq\fGZPqړdMj!COgT`8hcJ.@J=.lbw7fweģw5 摐8Z|Ly?t@\S&oPqI764Фڦ$g/qt|=M][>RE$Y`Fn{Uf*2S9=T c~&V)$ρ"LČL.q$z.3{@F:LTQP8]J`9>ԛ0i;ҚySޛ@%.x`Bqڎh!xփ'/Q@R9.)d ڃPM'4xi(J1ƚ(#>DՇwaHiGR"`x!P9Q& 9،fBaN/(P!X 8R֐0]LR0 1LJҚzaMP Z SZބ+Fqo\5g-uԲ2iGO^^S ;N`sE[<zx۠4wv=MxQB3ޤ砧}(ld##ԚrNA59!'8QM#'=zP@ OQܓ!ϥ$qKMQ!Os1O8ޝ -.:SOznpNiŃӊh܊^1SXg8/OM!RrE4ԚrT9+ #/#8p)Kn9 ~>~8r; f`=h'#'N}iGM1=rWhASB0?w#֍ŢC +}9ノޔ=Af1oFp)[ -j(t0g=i1yhEn2=jFQgga褾4w^iS#qJ Z K2{Ә#ڐ1&Ҷ$#})O S z h8=h#WzR#$R GSǥg]` Q41ǥc@B:z8FxB灐}&9iz=))v@4p(RKځ`J:dQA8zR`&9lJzr=i0zS{N)x;G 1@NsP_J>nB>jUʃ( 3߽)psbڎ4}{ Sq@67"g֗4{!:R KP$&zP}!lڝ3;;9Ih4)psRg=F{u! \## J9JSӧ4uӯR@aj#4{8jƦRWPDvӈc;85[Aq6vrwK疬=gT)5+{]#9Q**NsQC~}M9m !FqTR4r0*:|GYI<1Zx^hˆ]4l8+SL+1WYy*mƝ"1ǽ%Q5`8` %d7>n. 4Xli(U`R3IC𭃓i3TiJG nV<zR;=h4IoL[h!~>Wzbq3$R Or $OE?J=jXT#y4)ÜzR1rG4SZ9"fNqBԑ~#8 1NNqNhc<58'ڔ犍nhH88HRGr@* Z1H0:ا#۫/~%ޡN=kSC ~I\W.Sڮ+8+kl4ϖK1y\cJzl$li3fqqڐ 4{(4 {SQ8)JC Fp޴4`nR;P:Q)AHN9ɤ'uҕxSIZu$֗n{ҏCGZqT٩cyƹ4Ke "?(+PTsQILcu!Q .Қ3JWӭZ FqL(y-aiAH ֍[+R`d׊w&À;2s"rO" # 'BSXvI P+xpOJ8-Z^ P8r>!Rs) iGAȥF ϥn1%?#JoCbsZl{ Ў~(#R0zҰOJ^zQ9$)lJ\:# Jz玘l.=1Id҂FFs*N. r:sK+) A:`R1CJF 8i89y#L'q+};PB8'<ӣ?>ў(WӌSgڦd*rv}SC(8i\CCHo9\TzP-]9$gn8Lo@%v^-CG 85,Ei7we6E)EsXMMByҼP|d|sY_\LT9/ "N[ oboNYbd(lq֭,mx&ܾU?1*;SLin$O*s#)Xtco#>IB@fP?Jj;֡ Y#~^YҴ;_*I95tSj4َvdBH֔+?KBD n[4(g͒*vwD9NBS}˚Lrރc*xkY0BEe32*x_c޴JV7p00qIPF3׽`31 3OR[j=:;gv'WfE #c)}1:IZgS%6qbxU>}GoMH'lj;:hfgf  ]~"d.I۟\Tr1үiżw(8 T7EBIK%sSh2 w꿽H=֥nH 3Hfbý?Eb)qdBnt6R3Q^kelC2,_뺖7O&HHA9$wwn+I<דMsk:uݻK3_ӯbI6}n'r:uNXӄLNimKC'` X]r[o"("~P * X&GW*TUQd΃\ђ] 8{wK15&lyk$kJϷmʜtcq>A1V,%z1ȫ2qG9>T]['us9h-.q)]ÌqPh Hdp) csWl!E4lmZ$9=Jk{QJ|P}{ԯoo4Σ$d{ 㓹ec$ckCI YV<^[=Jhɕ3e$m+Wg1 T _6aIc7ax5.:K16=M+\wHT'^jgOV֙)Fzf+3NTB9lcl.in rGUQޡ'v3A+(tsJ0I$A;=1IKH.3PzAӀ8昆֧ILXV#S P{ӕsR*$( jwSN b@N#PųF:PE^:޴=)J.'19 (ʐ3TĞԒw 8hqB`K)O Ѕ<0ޛ2hqN: ךFrں;@6ZH *O^zԣ9N}kSQ^=)))pGZd߰@QڝG` i9?Z.ZF#)y$z|8B%<QO^F2 ZGP;Ei=!w( nHc˷Ӏ8Ұ@'83@19s&Fzum9@R݌u@2c}3Ҁ(=ZL94cdsҕrǮ9I(䓑ցuy9M/< f=sJ=`1Qv wR<4G cJR6Ɏ*q@<}i-csS€1KrA CSNh@8 @} 4sɥ/ zKJ[w v4搎8LOA1h$'/zrƕpOJǶ(-C`thHu4p1b=h<7ϰwސ=@`v''1MiFO,qV2F z֜sOJrz08p+aR#ƗQN{u1ۨ6}F:Ԋ`z^瑜 U"9>?+3M1R!ʜ-D"tsM{AҤ {Gn"1[ӹ& Ҍ8b ѓG4B[ ^sCcҟב@wA'$4G8'x'4b>@cZLrH4sw%UG8=(i# I;<7<JFmn<挓$A1~8~bJH\=hCo*˻8>]N5* (uq߷%޺Q9ҕM9 +}P {Ԑ#*~4VAwSӁHS93vyOj2M1'}eﻵ4y<199ڐeAކQ ğNRG0)y44Ӟ!}If-Ї{\H敲A$j۹#j&~yIsu⁓&, G;PAwqǷ}D9i3;S=;PR+N"8y۸ k8 ǥ.O8hPTԇ$OZ]ZP1J=)_LҁǧzHsKd}1IE/CFO.>c:A<+.}s^)9t {z1 2}:z`~!RM"h@(hx PpJ4YI<ӻ;sM#$u4$HK:Bx/lcޔӚB=|FF3J?hA( tFzSxcϭ0Zh(zRO|P}qHH\NzPixm c9m&9 $;4@1}M'LsJzsMC֎ǭ(z`4zQ}) `~)$u NҪ^%Xۂ[hYԟ,n](9)m^q. fk+ vG,B'$Jާt};7&GB9w=>T<-sdD¾Vo"XYO,8t-RhHvsRC!8Us*'r?=VAy 86Rޛ#GIdT/Ңsҭr.β Ky[9>+Ԓm*l}%Kr}$>b60IJT)$Z3<X. S$٤Shv6Xgfʥԩ\znW\Q G-<FխL_z$fV;Tt#7qZ@H!sڐΥI\Ϝsm[T{ǩ)F.GoAHx Fj {PAp@ r),zt5"I8ϵ0#0$P?(hfZVQۑHQ $sKNxI󋬬{.eb5U?I銻"y$y o5*mn cT|7L{,$}Zk)fsQnJe0ϥ/Xzt M8c=1]-1{V͡J4irܷ&3rFc&22g u)Q) 9M9+MhCBU ՟sAVlpƕw:,Nİ1W>DY ڷQ^m!!3:#= ظ3K`޹c҄ iB@#='.v]Z6.Nԝ]F'i3=Pc:sCcKqGp:B@FU4\A{ӘMzk`W u֑皾 ,mEXqTAXH&C+F;[YxtI+CK*͈98"a@Ld 7, t⻄PyGk3ng.S$~U_|LcץmDU9\[8<  94ӑ֙!)qp(4riGӕxjb)֐JCEtzCczA`"NJN3@=h֊2=)Ô\g4AI07=)G8<ӏ\L$sҤ<0O4PV^lⓧS9H֋ ' j@OȨ֟:b6nSG9$*O44JzN)x3iB?3g GJgCJI8J-=E3jPzOO9.2A8d5[J9<+ qQ 9^)WhJ.MAî &\AEɥb6~uH7JjxNOF.7t;aPK})g8hBO'y''9[SM/Q@i#9i:c|OJboN1ҜG龆 @V \Sڛ jw8q!8GT?֞ʤ98uCpH)A,FiȡCMlKc`b%Ryӥcm "78NhN2W'zk9n;H)H 8VCU@br)Y{;Ul)5%Ɨl|  z.ybr88I¹'#ӵ7ԣ<ϯ4@Xv#FN(! .Gh=qHZ=n&0isȧg$㓊5mi21Z s{P@\KۓҚsp&gP9/L>}}){ ґ;:Ž+ϵ#p3& :\QQ8Bc$zRJ3zRw=) JNF>'zQ2h`('z s@#ڗRu=qLC@1F}h'a8@gg1KQ ):qh+Gn{L֜LVqRmfӽ!BsRǣ*?§R20#V6Q!z94@>1F2b+HkO9ip;)wLҕ![Z\9ts]$t==4z7^hc(Irri.$)xݱv¡yJp'5#K^\)1MhŨ;ap1\GLsچv#DZcmd 6 #,u\~UYi -qPY'Rdn$^iq|c0bA1 . 987l{nƴ #R 4JCU [ 9N E=@LxAqs0AKbܼpi=})n ۛJZozRǭ Uz:j_=iI噆zj{hcso1$ )bԍ!Y°MG,`1 $w<\ilJ6,xj-Vl2oB&hYuޫ j#19 j^jE`*sڜĂ)s!)RAҘFӂ*IWzTinGTQXJwC56ݣzf@"bG>wRv7X)={ n=h`HJ 4IRi[_zc1RCA *V ӂ;4(!GJǜxB`fϖun`($RBgctXzO6~Ӏ'J|;q#А;5rϭGЊs0pZd$JǧJ$ c7p;қ6ќ>OQ;th {2=.rҘ ȧ ghG<{QG=iUTsRyP{$c  FSMVc~Js@P9BؖqJH}i23KI?AQϵ%x9r944˞Fqǭ '(8#6AwK 1R9=MI_Q=Oqq`ĭqAŠ hqr'§w'?i1 q?)ϭ;-d/ZUi'>OzG{;P@^é)؟j^=zSIM'hKu FE;n=)N4ᑞiA*w4^(8ǰ(Fzs@(A(c8"7`tЉ)B>MѨ8?zSp1)H9`澣CHю4`*␜fX((~֕C=H)>q bz`}WL8HHlcR3d<{Sp9';7s8 N6 G?Jbm-sH(H^J&0ɤ;Q z,+)iTg ;t9za-ON}t0@8~)JIیf[h(2WiTyh>p0(B 㨠w~H0=h1Ƃh='W M wc' ҂=h `RL98 ;4`vѰùR:R)Az{QhC }F)#$چ =9ڕ8a{SrOazyvjLB7bF?3)3?Z:c7sKr?:aLsK8HIޜ3z<3N\Ɛ$Rzh}إMҜ84SKc$zwF>\4g#Br8'=4-Fq@ I1J8S4i&9砥bA;nKīp8q*\ڜxvȎOCob\;)-ŨW1Hy8$XIa\^k2FsKb ۤ,Wϥ0Gge+܉RA@+N'ws&}UB~TGU9CbsnV4Z;zԗ"2Vt5%SnJ΢"P64/,PA sV"׭QO t۵qciV*}i,){ޝ̛k` Br5Ѣb08Vl"[I `ڙq>d-UXϐT rUY/®D-2O+kTҁlJ{p Fk../g1a8OX1ܜSCp>aXS-ՔdF'UԳH7-жi|k lnT|޼UJh3J;DxHͱssPo<`qE0=&IQrK|Ɯvb ҆^FN;R%G*Ӻ%jhjS4^soqHN1Ljaɡw4H֘ҧ\DO(Ҝ\i3fqzASN^W# sT J=)zMۚЌ gqM9$`Ұ!5fcCІ}I1=P3w4I:V8BJ\W?$ 1 OfZaZqgӭ7giHHa|p{@z {8'UMe p)sP1b8TRf Xn4X maT(d<(q6sVէ~OTB枰9Dmv8{ ΔAZP0:`pM#FG\Td~&&=M!OZ  @9hAz/m$NwHC"}Uw Ѱpi[#j>0=㎵ 'z]AIۊQZFM 3bd`[Qu=iG)^s@}h7@uO|ô[Ǘ}*\hv3TH ڼ}jNE>F ; iǐ3Ґa\VVMq{Q4è=E'R掼wp瞴rh$p<◯ғiONzPOcC{c5@`Hˈ}C={S_cArJ@SiqNqҵ\59\t͂{R):8:c@o^#m)sJFA/1C 1H4:~t\B sI==sHⁱ@p& 9C ךy8xGs@ӰrrsK ۥ):'H'Ҕ? @j2Hԇg֐u<Ґd;azQIg#h)ϧp@=(= 1;R4_CE&OAqKս)v ioJ8?ʀ@8$qN(@8(hAaAM.p8a\fNp{RzzӾZArFZ:KsG ֎p{iyE(zHy=)\hRXM#ގ3KHlAY` K'yBr s/W"G7`8fNv+n2vQn1MVfE_,uإRf!KrztW95Z+kKE'?-uBnl_^/,H}@ 2Wx;Mqb&Q yi'+{gE^ ಕzֱ=ڪP01芍zj.S[Al `XS'18:cP6[y>ߺ' g<岾B4^q"ԫ!'^j;!'j/~xPevVnmߕz泸8|;!(IJԒ-2)-(6!d;qv NYT+z 2+gOK]Rka|QОr_h-ޟCvd7r3ӎ+^KK[t*\Ҭníyˉd?9s[4O)7 >2B@I)$jV2۩X2=S f87Ze!~uօFbѴ0KoZ[es-:+BQ5qwa6^xX$|=Mp)Gg#{ sFs^CbwM\iYiZA9EÒ_We<ܹc+I{xSנÐ ?+-v ֦p22sh/ Jty94A}[)t=ꄠ<0;U0#4`)4DPN254O䚈dn4\L!%\`R#0']fIPO<6$ވxܑlD*wz$Xg8)c9#$pi^#`y^S se)SSk܊S>S0KԲ`E$uJ݀vFNr3׵ 7hhM9@F~pOK"v  ?9Zdp[UUP8⧚IP!lwqv{Sd&;Tdz73;c#̦?ZFsdGWrޮF\PEGFkT 8^sRC3Ϳէp[&0BFdb=1ޒ jSb@@a{@S89bMh1 `x>XJ6iWiXlP)#vjFCc94ؚ DR8 h탚at5KǙ fB̓A4sM]a'y#/aj&vrNJD<4gU6 AL$n>ӂNsۥ4z;f 8'4vN>p=3M$ڗHAJx֙F:SB7zm\&Uߕp(dk@t>"a4H4 xqކbPq!h_'A@ r ayӚhOq:\P0:Z>dqvM))g<Ҩ a4)x޳LWAgx2.mj3SOzV "0ivr7p;}8pijnvߡ&>lsS:c3R/ =iLp}0)3~dJ/=x4{ؙNM>Ri$s$4Wo%K&A4H]RǧZ` ~r= ބMɋh1@;~F(q˂  D{Ѵk\ӈIbæ;!F:v!3jNzHp ӳژyPhhI [#cu.8Pvlw{RCz @HJA#c "`c\B8>AJrO8G)3bG8=}iSL'{PZsǭ0pG˚|k$[KoC8 EF j|ZO@B:SNORh5}G^ϵ'ښ&8PǿHI8Iۖ< ޝӑSFsNC}(Hڌ@u3ڔg< Aۮ)3z. tO_֗##9N;P 884gҁǿJ1fCӸ('zHB qJxRir) K P@SK҂R8`O#E9EƄR ^ >ΌP( P-qiOړ1R=OsJiILkD4/҂q@ +S<Ҟtǭ C1֗Jh҃>mCNqMN> LN98ۏΌ`v{}8SSH/tSHbIp)0Bw@&!Z^sZ8`1D~a1Z=V+<  ?yMPF]N3Ruぃ^s 1 ={M`[FzkueX{Emcٶ9Ft 2AEqԇ,ZxGdPeIrFA:Bxں3$GfLdsx؄-ֺiiA8;}:*4[{7'6=y) Nm4?:FGd[a9G̾~?6[!.$`fZjζ9*0G^p<Hje\ 9ҳ(P;3AMpݬ[/ʙ)y\DT6z NXmEk 6ns΋56$1sZѹk"$W#OԎ(`zV.76ҫ7)L˓n+_qS#DAU XpS9JaQ=NMH-J6$jVBm.bE(SRѤlVIUp͓WA5A͎EF2)ׂPS z҅RzH$JHǭ\I&`5='x-xShȭbQ=iZnt'|Si!hU-@:-<4̓x$` ^qHH r@4i#ӵ.?~:R# !^hMĞ84 4N}TQH0xK Xԣ*& )C|&8XWzsd~4Y8iKr11CrBsJ=i8Wm49MDJnC 2L6^YA!vP@qS\F$"]'y.dhV4@^0ONx"e۱G~xhbLm!vY= rOqQ7 ! iM2D'Ҏ`E`Pc= Kl; ?+?HeI[$ggjpln&0 $ogL}U0cǽZȀ:P\:`#I Kyϙ1jS\mݑ] «zV</+M$+%ڡ?7#~m'1L9d1n`S|=$e=T%zU4Fye_%WE n`"b̠z̕yG֨pOTKہM*GlPiʼn5H/pQ)F*>})dAe@nqM@J0M4穧`cђX`M,w@42v_CN0dc;O3?0_<_0<ԀӈjXȀ9T isGA`ڣeq֥wiRuM9"|}+I"(_Qv+cc928rsLV"tA0Y:8?Mc;w<n%={T^W4\D<2iLtp3>fmyAIk }zP]x{}=i\VDu94:w>JH'҂z(݃SC3m.^E2'#Q7T=T^1IiOx8S7PIu&F:⎧tiO35׹@c)GZ@JL)x#pѐ:Quz1A=!΀sq֖lsZFB8cj0}) 4OLA=G:@hQh'4n޼h I( /\Gz8"sAROօzCbuށFrqڄqslQ4ڗ((ǵ 99>恋C ;Ru/jx(y>/#;qEh(J";x֔Vn#s>7q;<@8jCփ(a 84c\R zQI$I׽b֝֐挐:fB3FZLpON(KiG4N;P34g=Kێ MiylHxG4ƕ@cE6\r'8=+#VӦv꫑qyO57SZ1I9VW2JзkD!F޽9JlfavH[vZH$+!Wi':U`TV4:VJ(Q-bOGn%)K^c0%)So t,~W^E)ؑ M0#xޣUE--G?;O_Cց#1e<.@ҳI 8[g8 q4Q2{WHu2*e%sgU)${b[H㷺 {-'8=8Idy/Q9v:P6r~PpkqXр9GCC8=,xM0Au4/-)|IE%y9#7`%iJ`i Efϵ4{ԍnn& E;yZ dzR6[I=i98(u8=U$9&3M8Ȧޤ<қ4! )&E8搎iiB1M$7*Y\DG=j@cBpyjFe*E2zn҂N=z+]}-8ZC)IR6z{O=)Iz1IHW w‘w8_^\ix\N~&p DM }z ?/^|('|zPĮi3&sFp.;Ѐ9穠g `r0[V#Lv5W;yR/ 3O*qZ\\PpTNi=>lNO#NsچۜsMC$pM8)1)8AːԸnJE;Sr$T^)HH'H8n)=s@n1;ci@RZ \=)`ӵ+ LJ@'5.)ԗp,8#MG\4R /Tǽ8OjbJA4 "M+;G4.CIjbnr)4p)GAN»az\g1N\ !/ ['Nk pgGS*dAyɥ n8Fҁ\r#8ҀxJ"|bف' 杓vc {Ҕ81AHcqF6.QID%)@#4֜lq8'=)&ra14N8HcJr NgxJ@ IԏZQz_nKa0$P={}8ZzG948 ir<ӷFJ}(:\aۧ>Ni:gIS[d7{t+ϥIrS}AUqI2`q; #;=IqHsKۜt&NM>2[4s~a`N#.ryK aڗ=RsJ:{Kjq[ q4s)X@4 }9 `f#8ӥь'isu+b<0 lPy9 LsLb=xr>UpNO'@6 8@ Nh<+10(9Z;v8'"pݤHil&H#zA;iRg␓猊=ql(ӽڄ+dfSz<4`NG> IȠ~Ji<`N\d)ǧJcsJ{RvBN@=%j-G'CAF' T90&}J$'JjΤ e(>8?v@>i: g~1!=GC^}E4>9@u0ǥ'${H {r(Ҁ <(ޗnG8}iAA'ށwI}914 ґ}qނLJ>^E8EH@ Q(#sIʁ=)H< hc&)4sZE-RPWAhI!}xF>8BKj7sLV u$(1AKqj)Ns^zzRd^ 8x֚>(@&q֔HG3 ׵1 zPzz{c@~`3׭2~4=@ .M!$Ըh/OICAsFN lp8J==(nl$n&Sj,nǃHHOry1}mIݝێqOkO UMgApU̥p~_~Usw;cbK7y4mٲҸdrTpEvv8ɏ2YZ}у?-bA=n5?2y#+Z7W{#cWd(>3Oʠм,5i(JW .0:Ҳe9QzcZr~fLS=RJN229"ŋ{uu[6N_+HfB9Rځ+Eu ˹pJ3OE[Pǥ,VRy)8:au2ɵgk;v5",1x$&9 z*s3ʌR6B`h)cy pGB>hTF/_Js>&%'F+Sڅ`rHMYTԏgI?zwe!8q1Yʱ{p;Kg}ʺ3#Ao)En5ͮny9Ayf7gpGzi%Wτ!*.Z?QU{j-ȴC4E/U0Zd8 =:&H@㊠aJUDE;BY`rrS"[0~r=IيVN[6`]Wf$g2}⧿O2+$(O ji2pI X;;mf*Wh%:bw)RԈ*̒ͅm`r2)\|}ONh#sYR2Y[ƻX^}0R /QYhȗ#Bȸ28-dvx#V{[(5y9Ia?{$P-ŏ$"z&"ʌҬ[Z, AkM ҳo!X|O<5*yCx\٪A%iZfvNN[ړ + 1N8L9Zb@qS i O BqRG%ih (Q @CjA+gTR\Jbu-SI h RGSs$4cFphnO֘&1R:!if MƜڂx(#c8JFX@JzHN#}(<:v֣4x=xO-Ki<.ICH- 8&5N34Jc#TʣaQGZ  .Sy;1,$SXqAl/*aԱIT$P}{S46N#@B0)#=N737ACZqg֔S )27g"S8ޞ?ZAg*L Hi܍1曜NAcހV\m8ڜN;15Q}jQJzP#q+`js`v'8R[EJx99<0([2_QL9BhKc2;cwL'=)0q2f`Њ&pHJAނ[~4N3;vApHM.zSr0?N:{L@iYH$r)%; \;ӎGnGZ`9JI,;K Ҝ[##oS*G=i38 ~c q7'BxOA&9iO$[=) $c\Q1'辠u~SR 1 qސ1ҜؤaHvK׭!?.sϥ)\1 BKsҒGsI@ؼnc}2  }iI#ۊ>Ķp)sH O˃E0[4ciŁޓwq@Q~;(*X:; AJS:X+K! =1Ü xqi 8:Ua( 1@ާV$n8= 4w#G-t:Rt◜J^vJ=ǨLRn8=Ec{ʀ)[N (f 4\cY bI9C#9jxDSjⶤHi *vm}骥W=zFby]ޣpK~ l n1N?1ަ>S D*(Oi|ARWmpn+rdsu89f̓)(kAA"s[j>``Av5B˸)ԦJ説fA`|ҮaaW1l7|Um18&4qC}Jdnc xh$*z 1BmWU ZW _iBW # 收 ʶΪ`o, +ۊ|W?ήfj̽C frO4[A4lc .?:-]YJidKY?sqN3ؕͱh#+&Szd1 w(AzVfElvh=U$3d J"k ֜TrHhZ^ČrLsZ ]\Y{ yjde[yClʦ=+VǙR1VbY a5q3ҤnEpcҦkTEՇ'YD18 ;ts\I>M+Ta),Xif'Bj= Q,ލN`7{R$ia#viM$Oltx=q_S!8]049z>k֣, Ҏ!'b1isOTa Qvmv`wRb Bñ#)P携 pqC@lZUŽE8:hC?#oR*b1Th 8j6܃ߚrSRA¢=i4=a@GJjޞ#8&!rh.x9f s֌ڀ[ ,H4uGLqRě2XϭJj=<Җ␆C{#lfFDuJgVɞtzdl! ~jsQA#9 q~D=SLsh擜cvA GN{g IP A;H=SZ`$/\Tz9 pqNB` UڐBs84Hr:HR׊v1d RX E'$tⶃzuFGGN;v8sEzZPGoƣ 6ӾUy>azyj@y޿܁߽?wF1Ƞ y$8O* 6:Ppǥ .(s(;u)lQZy9qNB䁚Pۆ)JHzRDŁRqMV%H>$?4zSHiz;R846ht+>6 g'y'~A2V ސg4r=8p3z<*3N)=zdcMl& $M/ZU titzUnd1h8py##ނsϨg,pi4 })FH">n(9KsHZw rӎ="Ns6)8 'NMm]$78 pFA"wP$[ qcҚx{r1֎=h&pF{І3q3HMn4X28!@!( OZ\`[#Қ3Nq'PO"@>S&3){֗q@nPq֓1N8~i @IKF2HZ A4 @'#=p: vFR;iIb8`Hhw:>ir;qJ@nM }W$S~a`B !qƺjzȥN3HNq۞NzPўxEE`t8BJ; RHAb~i J^h1G)$gF}{ 6)>ԣ;Wƌd{Qr8\4tl//t@=)9ϭlv QQ@NKz4 A<揥nɠ>HI}hc)G'/9F1@mqKLQ=ixq@JHhޏzD9J1H"*gގп{4Hqy9#h_M&'cNPFւCD Ԯ}8Ebދc)q\-*G G?blE6!T,c#+)F6)6ֶu8B7T’܍}rJHN TVP' cÞís=!'6bpknQ\|[x~BUcVe; DԖxLw=4\LY@Q^}'w]o#V$R|hFR4e=J@ 2cE~3t|[ 4  }R0>u$MOq@1z ҃?!s@pp(GQ3Bh]}>th#uaړ}8i14fJ626 ޸ItM&[Ҧ/# rcD 3\-LZ>s^A9k:ΘGk$qJW8M8rTp3Ҁ[}+] ^k$?jNq\~Ϡ"ugb?#rf#*ހw),"S]ud9?wq>!x)#9m]#a֐ ¤ء۩p#2WMYTj{@Qh+r=댶sLiwIT2L@n/J,av(T= !,Ny .X󚌹4HHSpt·'f8 7_O>[B12Iļb~f[# 8֢y% PހNL` KbtY%dH׍"^.E %&0ē8Үr+" "[FOtitULVr\\N~Y[i uRHTZ1Ư);gTpR+U&;nǕ#!,ךNⶆ3(wL %{Gjs®00zlg$d:Eȳ 獘:$A8 ݎޠJprU?0rcSl'RO=ahف,dwSm!_=GJh`˴Jp;ˇ F<¦Ek4}v ]S]L#FK+C52G&ct?JhRݘY$T'q!1M +jI]YK|ù6 8*YA'`|`̋Tr@CWf,%+뵷W繶-S+յgkegEdOϻ)#Z<4uRc&@ `ceC7&i[.٨ǥV{riTrs4F3JncSC)!ɢ"dyh{5XޅSEj2 t#&$iTVf+Do&#MD2 BTd HϥPE18QtsEĉTqNn#8|*BmҪ=*n0pM9"$x ɫ*>\  MK֌3`qTĖ5rzqҟM3&Ÿc :Ru4` =5Abw;Q >0(94uS,AžNhT4jb8N#ޓ8Z,VO98(*w`c1 ݱR(ihЊM4:v 4ȧяJ/ZR1M9RQJ(Ը)9):Vf}=j\sW,MRdIYБzVHf8Z7/Z[CΓJ3>zdsMPqojfb8ӛ妦?)Bp" zRt\Ozh֜FAc)N?Q!n;o8x=p4n1-Gdu9A#ZU$9֞90di8W}})W=E O1S?ZL|͎cPBr)23h\g4d4HFsҜm5I QG&Gҁצ)mtºb L?3S9(!Gjr0nõ5<Ďo'LS1Alf !=)=zRr1)A+hZL9 j&I9 6tuPz)7y^vGGҐw+c4s7.=hf̄Ri1uv 8Kx$g,0&9Ә .HˆϽ)n]XzycǸĴ 8Aǥ+N)u$ 9M8e0ps֙F9#t4Ra֘}) c` h͡KqCd.3GnAGJ r8z;i ZLdA=iCց z]4uQT6;jq›>WG"hsۯZd㘎8i Bzt91hCqRsQznHPNvΐGQ=yq)g&{Qӌgހ  /NiALMhz\@lS@!\dM0bhRwAҜ㎴-@GZ:J)֝O_'81ԎTwx, ){r1K=?:2 9֓qҌc(QOvׁJ$A!y=?QKߥ l0i`=~aϳ V(=;WZFAѬnd̊GV..=纕Rxv>m%;TaU  ?E$B\it긤"FAȠ5PNykk Kc攐sҶY#.Hϵr^ %YQXpAsv \5_*Gj"zOj{€4iݞ*UHjS2q#D qE-cM'㝵 QҺDhTqH.@LjalSv 9u A~:x;2_9pF ?d}*sJ1P8\GubxrF4 !n]*)^GUrԫSؔK|ǵa3$Fik'JalAqjWܱoz$r:2c3#5PU1ޓˍ;i'ZnRR ԛQ>92sؙTz%ʏJdGq֙3JD*&B *F>lqMߜz@L$󻹦-9'#=OhEidS1dq8?f.LCt*$!=SX;= 9>ِZ'q$YX<Ay<):8p&܁̒Y&H㑊E^FYj˘n1qSCv`F nuĆh qQ\˿q9̢HGvU~Uװ|{m|nlx.KQkH*u+kzfpO5iX1JrIlR@PDcUSiILbuq b*L&=*24(DFNM!z`GzJ*9Ez8\ q*<iriSGB*!q$# 9I S)89TH)=f0qRM?!KAt9:2҃ /@j I ۸) +:tހ` J\(^I(Rl,8(#;qOf(̠zǐNvR",:N$vALbLN80h~RwF:Pr1Fx4gRn;5WV-MSc銱nyqUX c sZy7$\p{旒N=i283Qޙ$r1ޜf֙uG=?:hLс9rhF@(' 'F)1?.M/#LAi< P96M\v ;qH8h=q|v8I{=I~VLA) zRp_wCB293rOQMMpz:)1u"lRH8OMX1Ng<}/QM=31R8LT*AjP{=)ڸ=iA$1Nz@2i3yI>O_cHO+gu&04\dqޓhRI(]EpG>uzNr;v4szz҆A(._Z^:(8ƣ1.ZByJB28`})pOfz!Apv}h d4G'3LsKڐ#A^֐ZQhd?d)~t(#OŽzZQZ$+U{u$9kRD#A]^.!;WoR^5(/9%x&M}I2=y׈s"0>+ -mGۆZk0@<ȐbA{@>$,W&Rؘ)v}8 Z\8 iW=AW$.Cg) I U%%Yu$eX1'9 9464ʡG|eM*J=VnReX87zPz',43*4犿c''4X9ڢ<uoklDq}+07Jbc7 H'߸M i]*P3r 95a~LR^X0f#MCl9lS)8b3N #ww$#d^pԇR.eUmFX-OD `曰!887S?-5Jڹ ݅D X ar+*Ŝ(s0N&cZo$zQLJ6DNAKgzbMsש'V7f*VE#޳bĞI] I$Q}*qO`(U2]mhR[MuHdF9&O\Ur} q@է5ɲ1D*X3ǵXHYSsQOs)_r*Cqriw:Um4XVI4w.lw994+m6(O]"nNsL(z5<`[o9<;Uav뽀nI 7x}"rk)#Dѧ @ۻ2cUH ~57І'c1z[t&eNIrQS7?)ltQ+؊`q޳G|{fȓ4JTr:7FLnwD7̠`{/!+-~boRvjвd8eji2^C8il2@ОE0ܩ<6u2sh[mm#Um84\-%ilq-IޫI$c rHbixwHDLrs?.;Vilo$E8E4bVTpMQմ;kvQU#5km|vDc#g'$.s:h luZݮcur`1UaUr"\gwMŰ03Pqɩ†*\c2  xNzSI8ȠvB`9!R9%1'Lfp)w!9< q3Ҍ`S .>ԙ{qQ`Rl *QA#IҘ7r`H )69&6R-X,sT'2:TT$1v*V@zUW',~\UY Ms~lH"33N(3HPqE >;SSž)マ;ܮbp*0sV]LQ/IecmltNzIE| {GקJ^f`S<P=h$;ё{SQipphLcVb\OaL ث 5q =0@QiO'Z,,AR탊 QHi=)[))ҜN)p҂AxiOa҄瞔́h@cJR2i8 ɰH>%R4@'<hM&*s*k| 3h#cZ=1SnE\#͖N PNFqT)zqHut'4pzS4p/z\qP Ni@Ob8Q4lKڐx'#!ʚ!aé灞?1_QXɥHĐ gj#ri#hZIM֢t$bO4Axh^Wix TدpdBJ\=8coJpzژ˜qK6=`d=qJ\qOBzF@&9J\sB 1Ҍd{F4 v7*Ӟj@*G֋bB:D93QH%56_7rf+֞ .MZvds@?)p&9OJw 2u-1aWj^"JڊsP2)@M) { `6Zf϶:ԄeO4sU#'{fFsQe1IQ(㍀SpY~rZNAJð49lWb6 4 @p9+sA$@g?<A9 Wln'g׊^FߘHQpv1,y$PNi8 d}i]H$Қs҅`zy4cAG+rsHH ϯJ\ oh_yCNǎCSZ9AJ1R4 =t4@~4yQӨ?7l}): xnFA=nGT0\RetA3Ҝ>.2(g%p NyF2@'+y搦(ls`֙Zn21A4qҞF1M,!OA րEcBgK'8{RJqO\SUQq[ )qץcyFv;4LM @(tpi PNzRF?:Pr}(~4(iI\`<Aq}O֐ iu4jj1נ)3@3J:fa 9zjPxr=T)h#QBsJGu$WM3H 3ֻOhO,ҶS\ǢJ 6EOoy'W~+ kVpg\Ȥ>\Ѧ6q"Q"jcHČT as]\Z s~Z9+L }*&uH} R6O#.T(ޑ&|KqbLUrQ<.IG6>QF0=jp'qZzَx(GNyA&5Hé'jϘ< qJFo҂`Jp8CqzUn' I!1 Fj4q4N2zv @Ri'ЛTTF2GO6(ҽ[B(?JrlzFxh0R؇v[>#cXRc,q>J< "JSp9 5VKe۠ZhȺDXy DѶc[Ʀ9JLF3d^KuPT'z(uX#xOQWTڬC«3[] $p)O\#&AnH6OK+ʵʒ|9>$WM`eLtvHGaScdsڐ̠fA4!Tփ; P%Ն8+Yz|=bġ^=*ͳ0+kSt\*rGp6@hȪڌNr2gND2G#4x<|9H-!s4Qj^(W9@A$he<*kwqd0\@ʏΝ|)zzSb2 p8g-n~A~F݄/=2@R{Hiv{T{lSދ +epxbz=i4XW:u݁Hr?h;1NKfx4tpGQ@8sFq4*njaZ>e=*b?ʂ7u OJxRsR$-&4BB&@9FN( ō8DO=)w8Tjaw#c4ǂs{`}gKe-4#U'@#M=0)\L7#,#sҗf$=#&pzTC >]g t!yeǽ+ϵqNFJ<Ҥ/}*=ݨ61\5bYFPeqhOr4ԙң\P.qIHNE.yցOU*)si/%ؐcw})d$!sӰz>iFуbwi3T71ך Nzr}/\p'm.8m4֜yF}1WWfyZg#81F8wި>Nm<H+N#?J:8?9AQ)7-8cE< :3Ϸl8ɤ p8 Gl O 9 |RJݲi$ OU WXh'4f۷? F1׵R*֬ 29$kaϸ4'Қ]cN)If]Յ'Ƨ%POr8r)̌O~kEnbǐz r(*P>g<ӳ]hrA@=j)#R>L]˼cґcsBRǃKP$2O^jEEz.Hӓ9NdIwL#֠{U67QFS:HR1'b#@8+x{RՌϨϥu̚J#rYS?:̰Yu'h𠉴 cYVMBNbt ayӖqi^ { `]4\(bG%K$HG2rH^e`fP6V<:~0@`0?Z5= k.aU\a7Ԗ[̈ʭ_jvZP`JIEʎUc/¦Oҝ,cҷ;;;hGE i'y\nv)5ww+E luY3szVm!,ݽ*kcT#T5ԗ8E8XV5 w<7x%8+U#2ieI;ߘwk'S+\2M.ٔn m5: Mg q)x1tcg+f2t t}ZA'r%; [ܮbNe!Ĝ)%ɴ=CښS48DZIEHq Z$;RAml;H@Q׽3(4\jh zasH?wz횏z$)L/`+8s>HTRSJTydXՉ9'h1O Oظnj?1:hOlS.߭3b1]⫺jVqiR˜T>r #njtl;G U7 SVS4εiT;A>[&\j&pu?'k c<yG=i!Py<J 0)"=IJ@v掠 R`ҚyTrsAp~j9<2{L2i !Ãi2M41 qNϧHc֍nОh v 'tBGRc-)=PPA w7 Sqނmt; `3KszhQʜІ;# rMz҅9 Ґs@$H0\Pi |J\^8@$HD*39ps4/"Lvm I4x@{fH9jO(z󎔅e##vF S8)Ohs—$GA◧lLj[sޤv"F{ I=8 I/3z{ -DP@yO+˜FNzsHG^:S{#$BwQ,R0ێ84ag'#pJy'$9=ImXP:89MAܝJ9šsJ 0({⌜敹S>59xScșsVg)a)*AH6Cw⤞ՠSl\{NَҦ* Q!; n,2+Fބ~TɷaP34rOҁ9l.AsI0h88GhcAXv@j=yN H8㠘<{h42:; Έd 1yPkM.N4)F=617 q 8c#1@Ia߇4(׊: ROJqG`';RzsqR dE) u(  g p:=y!> qP>S@l0=ڀAzG^ iP}x'#`qcz0Ad``Pi1j3.6xҗ\v9isPH:^Gv# GLڞ>8=1 pGC@phN1NsJAփ4}q7c1H 3Ks@h^3Z:h=)0h !!\ӳ}(4r8hu8R=3HvR`֔uwB9q)ILp^Zs!9K>7FΪAi$2 `rTLEmPr),.KUwz_2({N] +Ƞi5px~5Aā\ b ﮥ*HZOĨYlnRs޵oܝ0k3췳J  }J{ w`lN=y4۫$ Řr:\<˔ k8-t^I?δIrF-F!Dώ*ҰťyW>I4r c%z9##NŭeUD$m>qCcVEyt u4 n N=ej:R/$n?uIqB^3lI/OcZF =mb}HXGq֟9 U+ | @@ cSx0rխɊU9)w1lnsA'Q@ 摁8 MhBS=)lќusBԜӗтIb4y 6ExKhRJaGAJ^# ץ1AqFFZBZp+?::Cr1:S28=p)z);y4ӂ1y=9ԟΗ#\:d_@np(H=x砠׵-vA9M~tA㹤 k R(}^)&9(}i#iVOp})0=)bcRJOOZ\ Z~`6Œc[zݔ>[5ͼ)@;A+xq< ă뎵+jOFA0sl@\cKwNqrp.rq1j @Xcy]8ZeBh$T}s5MTS?G^HqrRV;S{S¦߭5$$UԘH4p;QnFNGqY+O4`L❌i rYM$aA}s^-1 KkԉrIRY W.&Z(t9v_U< 搏@*.m& Bsֽ# Z*閬|A.])oqa T_Ibӈ:߁Qq0GQZ[4;!eR0ke$ɳfL>5zHUG͓U4 K[H% ]xxGmT޵6$E_fuge Trdi l5f64FPI9ߖ\F*aO 挓9>.qصG# &xf/`ߌ}+vѢz;#&y#f"x؃gV!Kd6quShYV{͉lP?v8PS+l^I5W*/N ]EqO'J%e{V]8J%s3R,opE\ELWҩ9ҴI&@G^܈"6\E-!٘}%Mt${0R8 GT${fƒFF4 T;+4 pWL*Fe$"Wr|mIߺGi}29FZH'p#qzS).GjT 6sc-R+q@8qMo(c zSǭ=8BӰZ y>Ӂ48u$)6@(<-׀(83I֔{KHLs 8)#8=( R{h84qsߚBvHxy_qn4Ou=@W۽) P|1Qy6#&"F䞦gihpAuOzb U}F)H8/_LӰixlqH@98g'Z\#ǽ4';Z_Q֘9Fh8Fx\iH d=}})qH:zP34ɊOSARNnI=h1}(8)c? qHߵ9<4^M R{8sKxS N_pIؔ8z{nPoc8Xwۜutj5l}*L҆894Sc')ہCM4db0vg#qڀч JM9#$~v-Eܓ:Rg/qM4 iOAQ0cޅ6Տ'x gN-Ihhm+ 0qHWx>z J|һ&wL8V2I'U "]ұ$D,@O6xJPl-j/Wr x@<[FqңQ=kS;?3`g=jM֡##Byni==qM&qԌ#S~aHpmpMP"LIKu9FOI%Nr)sSsi38 (&{#}i1)9=x)IyzӇ'Sjp=('`=:@^2(ڃHF= :RAqǐ)ҐuJ'PJ#P;f ua91@9t B{REޗhL< (#qGE@Ai8_Ηz9 P2R~lJ.!I<}zӈGP}A;@ȣޔs֓ ;Rv;r:PA bq߭ʐ&)J ӭ(pMdJLT@ hP)(b`cÒ88 w$r(ar&幦w wIj$l*W)PMfV&rBZArqP}l rOO0КKrqU SJNW1i L~4)CeAm<)ǽ4@aT`fRg)v1JiԧS2h[N:SrjE'ōj_$6NzTd0 $!rjzA!@уѸ@s`OZ0E hh 4wNޛM'qNoBqp:TobL+N95vz@4tMsޕ{;8ivɦ8%N'=oAŹɨ:R'Qq &.E7(# ǽ*^5RQ}"lOy5 "H .Fzc(❐ FG5V!qMhG=EisJ =@Q@y+L B8&;zTNj8S @aBH⟷.:.2,br8{a'46Hn;RH{nqWO⣊-֤{S@&Ni9ֆHҌsT$5NM4@ dT6cH* JI/ ֏LCA qr})bN:zSAT}i ҃R&ӷ9Mw!qMPK gӳHzHCSsdfW~QM#(=qRF20OJЁiF4t\Ґ! y4FԀNƉ:{Rzi #*0 $;9=#M'|\'KޅҐ݃J=i3."⛁8)@bOBxqN^G 7N`S{&;ޕO9&T}y`Iғhݻ({Zjjqxz :1'HÎ;>җP⎫QI(";P (cAP2iۏdP<B98`bs)~a3ֆVq# MFo$v˞ǭ8sj8_'A-cGH9ʁB\gH#4"I[$jփq hQz~tp0g8M/nM8F|P!G8&ނ3ZC{4#~0H8))yQ=;Qr:RA\bJ?ZC@٠N)s91Q9l· +QUۇBFGfTKɩ&MXtZ!GnfO,fY k)=JdcgҬ\ڛR[5;:W?:9?UI:YHj+vd ~u)Ywr4;\f-FmD#c5gN_7C7z9&"I 7A?{R+ x" V 1s99?^ytT"&=ɪ͌' zӒ,NijRe{Kn J'.Rb<*!M)`5o64Yc$t%rOS(s[c,)sL | \T2@6v5ڌyY'mF{aps@C#ƞ(c&jM؉ϥ 6"P QBќ <9#j%5,NR`|3$S:WQiA)Mf HI#&ہ8f ӭ(a&$CQǂؕ!u3MaH=i 'oJ`98(bSaKxR+nZ[ڭϥXI QLNjh[2x413TA9Z@Lgbn֚9J@;b57`{SYh@;p^*+vKiDX+hn2j=iONyҢNr3;AN HO1&ǚJZI5S{ә4:PH9L$s`?sRNMgKiҫrŽżJlsQDj꟔ Ap2K>8dBI @W;sB{Ӹ cLݜ8߭.JFE#?ʘ6F}i zPzФ!8<ҀA tOP91Rhc5F;w@V+P1҅f\V<o9SPr߅ IZz 4M!y< @08[P rbr(ю{P;ǥ8FQsҕQKdSn94ޒ),RQHb SQ)5!=(z4IIӁsz{ZP^A[zރ砤$ހrzvvKx9y)ÁJF:G; nR 'JR)'rrqPRkS}ZAU'rZ.qAУ uNw"8#N3A|kcހ{hq N 硤sځtn!:R7%q&I'4 8ݺRD=y oʔ| wÏ\}G^RuGjT#&3LP+x$cڌ@8@_A7sLS9.iId PćzuaHA)H$h,f٥'ߑT!NlJn9 nrFqjEsJGzvJ.I&`0Jamn/8)xrsI ݱ oQA}84 4Rw ~4})UgAsp3IR;H7%ha֖27S9',g ҁ#4dǚc8Ҕ}bԗU֑@#2HwnU:M'{ nOPzqBV&»Og*,I"8,Oz7sqJKh\sPOAң&Z%1W܅r:R;S[A;SV%P+߃N^{j?vJzR"Zs3ƕJO8J,}xG)^K cZeL[[{$sU%te3&zsMyG ӕ}):@`OI<K9;Lh䎴!H+ߊPAӚ^)<N9}iT`~4w~94t:Q64H9PG~8GN`\uҐ{gB\ځ@XRixIޗJ߭81LR{ wЉH#QFq޹ǭv,9[!q X>U-bGNP@ SXJHi g-ƨpN;PccJcDr%pqxHZg8vcdVcS˦  &1۟ZhLeP)e: w9;ROZyBCsJBȪ :S( zU7tis~u[[6+HxKE.NN89ljʈ#`yo@v4-㗱]"*%yҲ.k"^X'a_qFこ)R\QM}MJ[$rXkЩ+_nkWhJҫVFݘ㊊T@ƫpi*)Lk`bnEe]F{t\Hr ֔IDP8jOB};F9qz"U(ejIiYC*M*u暴mu+X7 Af]D2"jylMMS3'"Tv}*3؆0rz.~Q5ԙ+ 4RzrmH+rN,iP G^kzkҢSq`8QH8VFo_JQҦM,pM45w! 3ZW*y(,ss{¬jw`aNUYv(95]ػJPHӖcL3MXڎrq<)Iq0Ҁ Ivnҵʽd S{AaG x)3(p(3sHXzf9'֜h5ӗSi YS}iquȠP[qMH8dhVi| })G0CWjURiYA"M1P?1Ph c'4= &1s4B)9=@hh:cv;(ʑ@F=RpH8lb0O4#?4g'4XOq$qI]h֍w~lCzR g86WNإp$ GBx㚦 w4FMHqߵh!'Sic.d`53sO#Za)F3JlW)A48JN8N?0(?tsEI*C`HoQJO=;PqA8i\=) /sĝ=i28P9a  dӇ nG4R)ZÓ'9jHKqҚQʀ8pplq@#' ȥ"$ :\`9AQWQ˸NAh4X9RHAۜp{.3yv t9$~8!Y 6S 0HN3sJ]~ 1~SR(zb8 (r3Р4}@:L9*Ni9#R`1Qt$X cwAJ˂=a} ~4(9=) p}'SzqJjR99I[ 0:үSAu^NjEXHۀ;ҶsR"do}Fp})p0)NvN!0qہ8&Oq3R&pzsޔt<J:{c'Q~o7N)^8⁞?Jrz{b=ih?{gZ^9ɣ4pqJ=qȤ֗}hz;z 玔4\oANq@ :sҗ3!!=族P v I/$d~t8) 1=8F )=( SO$Ҝ3q@c4Ҕt4 C3Kh|&z^h9P[=y-AzSֆ J14yP0O0r:RҐwMG#&ϥ4;RsHL^=;cցqRʓNҠtpGJA 7d Hv UR5!1N ɣ=y;F8ǭ>/=PKBiJ8HO#ZQ w(=O z>S94 A(E N1J3q.+Z0G֠ SH # $J ΚҀszN\Fqpoҁ1xDEIH֍N8KN# #r}Eu8h#=)͜i4 v21҅R'=xT4aqhR A8=`d cnA #v P(jI=R1`}@2C{Ў7q\2hÀ3A9_'9Z,0TqIێh}zhP8N(4g$f;R\sCi{fr; H.I8'O.{ҎS Q'րLqsI~dA8n}hhBZ^3F0F /8#=I`4G= CZR88s@=d2R9@öJ^4ѝӉ8<(t`@1 KsiR%S- '?AMkIU$DS\ְUi ~\t$թ'2"E*UG${z c0E/>XKfc5:IX)d,Jw9(vXABI} c*Ff%:XRٴGW*vT5 ۩6D)VQ$:T8)ZRT*#Jh,Rl#J%&>: ܑ+IQ9(yY#ךm *Il *miBNj`elWI d&IAr$XsԚ!'ޤln'IkhS8&{!8 IqFv`g974w#y%3kO@+a: 6IVZ9O9$֛Кr0n!}iP( =)y_? $'=ǥ(nS@9H@%39#Xh@6v@tG8'c&AM!]4=3K?JP>\g@"y)@^늤CAn)9,;)9=:f#$~Ly\.F:R)܊:IO=rF*P5cqNw+\ø4)8Qǩ HMf;pA\wJd. Ub0=( JO&q끊hlN?L~Sr39(hU/M˟~)G$!Kaܑx1R8=M.O@XBpGqJ'JUUcLZNI҅'pO {: C2GI8 @؅nԤ@Tl;d-;O.vI}{ғnMޔHҐt85p8=E`~4#3K3z7b9Qd 8=?:>4PARJV`9n)79cNM"֢i#,iĜg=)9(% 4`q{Fx񎔜maߵ&=.~lPK"A NSI= I㸣(Sݞ}p CFO)X('qC@'l)'oJ:))psn-F}&x h9zSRC1MݐO~I'փ<:vpNF>ҞĘMSV893hErMuS[{vM`)FzWiG|R1g!$8hޓ9n{ x4̎ u'8|b/wS32yZ1hzQN֘:7d/ SJo$׭+gv@4>lPGIѿTƐyZRXw 9qH}FfݷFOCUɫ܂昣u#t/48$tܸ:vq#c֓#v'\ǽRփ)>ԄcqJM؃R@Z{9=sMix\g)ZPx2)dzRxbAԀSO=H@9s) >#<4 b`11H( `/>0Bs1HyN'׭'Sޜ0:x zQQaN{Q(^4h|U#O(:c4Z:P0s}hbj\ @fR'Ly!qZSIPNGx7}sƸg޽'h?drkͥr[=WRf;j l@UG9M1҆g 4)o78`nHJzuFS,JB` xg@ _k xt"VԐ*U:*y ϩ!5$9ڥ9roZ.)(@硥U9[<Ԩy2i0#4a)XM@犓ePI&X+FIOc;Q`wH zR zH {S>Pq=G$xzS7dT͖Z ܃5#˱I${T x}nI"qک\B\()XutڧY"9yeMt_qPmK>](WrUbXP?9qH'R5)v=he⁲1מsI=*U f)x?J_9؀}å5,;M5d`ӘQtP;F*@|,hcJ0i@!x<ӶW=Zycǥ0rzRA'4yBxL9 r3Hp8#!XOF+B!$ȩ 彪K13w5#(*Aa {J\!F(7JRrh-)Xzqޞ ڛ9s&s瑞 *zS56C|x6؎y4} Sm日4 crM |{PzZOrr=*>wҁ"oLSI8惂2hcǰƜ`P&r=(R3Lp"1M!n8&rt4n*i g4@Z\ U<Қ981qҨ$|H֔:Ӷ}4H1L/'ci8l/@{UŞ}Uiu fb8ǧJqN=harHȧIl9'ڞ1{Tlu&IֆPpcF:~x$.y Iqۥ!99@)Tz搒֓~\╄; qHF)} KOڛI Ji~`Ig95Cأ:Ґ0~غ;pȤ5kj 88ҔmB҂@ҝĐ 1ҡt( 8 As:3oJS?q=0 B;ۃZ]˃EQ)Fy>S%!:7 1ښI#ӕړ Ym#N'd1<=h+=hׂ)\p ޛ^iG=ؤaϵF(FCArzst~ztH9'ii8Pzv>Hw9>00)I性i@䇡9Z *<{#N>o)0 OF8^ d}ix) ݅"97vhz8CrV4ȠZ y4߽<Ҟҙ61z)9b=h?)4{xAiA6PJN9'4F@4n [89){@ PGKQ@l!V Py sJo~Q֐uI9i֓Qx}N1p&F)r1P{h_jBa⁜7|=4&t= C^?(&2s=)sJ^v~4A=y E(<+ݣ^r*KFyW:F|Cy,K*+Sj<SLxӨJARC? a9Q ` 3xU{]NLSYo=(BE6{4?{mvw2ꦕbZ2@4(vFQ lsiH})4"&A'$$psv\ x辶W#`8:vN;ԇi0}(|„`?zI>ǵJ>PT)sޤh %m iLJCWnSҧv]KJ$_β^}hWi6rk7=M=47I4^k7+*sN@MH:)P`L)HQ;Vyt٥}#cr]/zS2p8ڞ& n) Z@ 9 S(KD<.QjGbF3PҋA1 g0:ӷ’)rF0}hh'=8IjN҃PL u) h hzvcHy+ ;SIZktQ4 Kvj;JJO4 8BqZÀ(1hQ$2$6.vug8{SFz1J Ud9>\H9F08i; Z23i9ݞԸ)& zb6eM9aA&KPpI84d\HO' xlG8E0i#94GAޗ4-'#0ir1ןLSKvb !ԠbsqJyiwR1ZbLkdcʄך@֢hInz[(3hv` rigތZPp@LZQjD44WBgSL#'vph9qRciwҐR)8>ԣbS0:Ч?- 0F(׭+)ڍ׊92hm=Ӱ۸2I(ƌqj&ݒx9ӰN9-d␜`z< vFOȥRNqޑNnԆ>l )yJyp:֢1'3A)oHq/ݎZCC!t“<FxuuRJ:c)>A4R#҃(1GJOaփ(qhCN1A(z@Qɠ<Ѐ8?^Gjtoҋ ^zN>j ^ؤ ޔ #/%8j<`Nhh=GA1A?rhHB'P={SҐ:sH, ׎~qHG(n1q=JCHhڐ BK)N1hs׊:GZW`uIʓ@iQI{ "$~P1M֊Ԃi|JF6I֚ӵ!۳A1Ss'i)\);@@n|2D[89 *6%4$0s\`R( ‰ђxJ*cץ)|.z`4;00I w3J IJy+b I:bۓHάi6-dm8 ~+/NsN泦e-*R/3N?:&VQڙjx xĀ~.r@TQ3ykIƷff,G4s~H9PyZa(*A(|bqSAOXLR"'!؉ms#Bzq,F0Mt sQVjrr*/_Ε$P s!Tzi!qn9As@h84tqE3b1BB1Ƞ斏(*qU2h~)ATS`9`y)2vKք[FI4<$4,Y 4qzPMܓ֜ӊ)E,E! \Js9+ita8^ vU @$ӊ(T 3敤nau ! Ddތ33Ґm$9f M46@⚲`& L,kG4ұޔĜy6V8dLa*4PBFKip1Ljfj i"0O=)98c  q $0@=Jj(G'@8#ڀq@?Ŏ:P @dӹ&zQ/sHy jLA:Kr; qp:QpN{Ӿ(AGO!:R1qҏP KGQJ8 4{R/4;HRJz~ ;P1 \ h(zPF)w @z!1T< ə\`(VeE 7[ac*ʬoFS'u) '䋩=wu5N ەWpGz٬v@7מ鬮c˴LWݎ)nm,~73縧,FXUd@6MSؤgӮi #k85N8<*&T S^]>juH=E3Cn ޑsA 85FTP4O"LJ%lSfhQbX)X)ʄrG1Lr߁ĐO(MSq&M=ĵ,7˃T.Ho4A$Pql犖4)Ky"dQΞU^6 NON+!1,{4ަXG}ޣ'>ۻJRiBqӥ1M940i2rx$s"" QHhalg 7R8F;SZ4p(#ҷ>ܑ׵4 !K TLnj&+1`:s#nfM; L~4IE}$22h< 4C0DY^)9V S(j!TɨU>z@)Ԏ pW!iwSNXҡl3IQid4pzHM&1i4 qH[}:RsT}isNޫF0M(bcދ89Am@)Ld020?Jh< 8KLd61S49L3ҕ)!;o?+1liza`G fJ$qd۞3CAT[%y0)AFpM R 0x4V OTp9ڝè@N 9zE8yP1 D z҅ HHPVSZfߗ`;*U#5UKc(Pu;BI% 隄FiN:{vrN{P `aT^i2{ST}i^0}S";4qJGAGA#?9q@+`ǥ!\J4P +F*iFsN= js<4p';FrE9p3H@M1xjq;sQ,3E @>7$Rȣa\ <i{Ҟ\{ .S cJqH#ޡz揻MUZy(@БX}i8($^J~8Ni`SĄr:bRH"I#4n;}B`66)=h'$34%iTqSy#81o͓Fy#>J)֔O^) =G> g ؛3rCQi̓BCW!rF2iHX@o^ɥi  %8t1h::R֚O1җp PBvJJE;NzP2y@GBxZsҐ[olt9I iy"[J`S4᝾qıEZ3s^Fސui@'q{z?N W8)q=)h'=(LIހON ;ӳ9(HAKn9 tu)94qA2}i÷9RZ #RFysS0F@:'#+q@i)#ߜ`twӀsqzR7~ckP P8AC gz8[0#8  '֕F8^IA~}6v<=iQ^[ҀʎS):p? hJ:ph$Rss_}33Iӎh8 ( ۵ [QfԘ@8ԠAf;dsG~{pi? @?(8R \q֎p|DFع滭*"g1p:sEDŽ|-XW^rU;LOJafV\Z: zL:,pvqP$ݫӡtr`68l9QZyfIjWTdO֍!O٩v49Иȭ>tF d4 bwr=Q{U]"=&D ܎;Rm>#qʲy Tbf7T##!FaU&zϏj,O]zU˱ePY~5QϣgXEE ,͜h O^/ CxYV.JM3=hC@9i \JSH:8r<z@"NJa4b4\nTT/ fCZA&NG sbiTT8duq9"9@$ԑAAV0Oj,x֨.Ey94`8.JA4K@RiЦiPI* : THCH [8,zppIR)1G!94FM tZqj34iz)3g#,H($"KaxԿÊ@qځ!@''ހRn{jh-ڐi/=i1$#&Jc&1GSNؤ S\rjl =)1B/?6(*OTq€zN#+ +XLzR?7ҜNzv4rJO@ցN(}i.qИ0J0(c);~^=iphҍ=(}$q֜vsMH ~4(40eiç<ސtv7p~!œӉ ֛u_)HTGf+jk(JW$搜pnqI8]08&#֍h47>ǖrLe Fݒg sbv)i0t8+:x!sX6$ǩiqVՓO8<@8|~bNqޜ4>J⨆&y9~4iG4$c_Z\H/L$KbS7I⋊㾕!99C)(=#4ҁTn` ]41q#҅ k8<ӈq@ ()6 /89N 2;r FF֙B;Bo=iǎ1S24ސts|q4:RZEO/CLع==rMߏ(9$d^ҝ'Rh۷.bNHңzci LQB#}@ 6 3ў@=qȧz$41=P! (99#J0]A##= S9LP=)9<()y@P8#F{zԘ*?0=h Hh^^UqځA3i {tݩN@O/ggc= LKqښ~9mN}ME;.BmG rGQҌ{R#IKqH0Nh ֎1M i:Pp\ ԙœH#ڌtacҐrpxzR;m߭w=i3J4-'fy8ƀ ;N0>R ʃHH=9F9L7^28hvc8?#.r91@M;);N?JxaH2NO&NM)3K2`P<jLdҒph`>Fpsր@xnh旞QOzR=(&}zAz(_“PI@ ^䞔zrG$R'L**{'-Ú̋ZĖFK#1u+!c%.ZYN.Iq=6r=(HՊmZ QLV!i]y:t5^F[Ls?3Yrk0-ῌ,98 Bd9z,t!Ȧ&ړvch,/<UΉsl䏌g+[A,!Iev2m|a*Vkreҕl]xv2 =-ıJb5ZNfc(;z܄ n +2ka"nW~tb !Fqި> z拻fo2) L47=ϻ?Ϊ8ɜtrEˉ6NlI`~y UVcU 6<jU5F[r3 0RV$g?5s"X3R(9ɩcLN*QZR⛑hApnF{Qi3 ~e`H&qJ͎S+犇hϽx`{ÐM5NN@'׽AŸϭ,qҙ銕KvLKrA<惌Sw0)XPp**HҘN{U3}T\0O#D%) 6 fHXdQc=)ǚaa-2QI#P{H=iqN8 Ltɡ ]TJZBd)h~ А1[84 uB`(HZ>#KO8pFM)E!qxh/ϵ'qV9׊r@=)`h ݎh=8=hR1  3+P9SrM)_Z:0)x^i fv_֋qz' aN1H)GCN7Tz 44ym8U4\`sփҺ'94i93S uA8c9=Mgh RA44=E;8GCⓣ Ӊ@#qRFN9h zSՎ1ژv?1vKB)Fi 9'㕠yBc`$NjpOj=1Aݴt)R})p7c3׽+K}2sM:@`UA9F6h.}{9Ϊ;`{ ,;h惒;ьrishDj7;H8K=QSҨ5BE)4!F@ )?Z^&1qK .zg֪&-,$}F*JbfHe1gq'Nܥbi bUfF21\U ';yAMm( +yۚQ:.o\[/QJ98ZѢp)b8V77o6*ᙗNbzd7y6kxCbWCn\kjKm4xPʤPoSHKkyFQzzt?,۠ڪhhH׬ ;Je$77Gw 3٬׺Hl)nsS}*.T8?G{UZ}Ճ6@#>5HFXMݞ%sv#9ƥP3 Z5_nk+V,)Z\ &2} s ’[B6JR7 L[UNێyݜb2M8ӽ?JlG{SG@iՈ9(=.)G'0)'HzP1HacZ(+Sc=Lcqҕ#;aNɠLB( i#1He4 SRBĮ1zR1J3֞p :T@5T֋ AJԜ0L8RF[lsL BW*F@DV\ҳy@(DHFKUpsHb X0E5x’pIo}C܅W j"sOa-N-ڔCBmM.3M$憀.i ތ֔v:z(&09=W$X3N SI1: 7 ,4IXFmTwt'?JMԏ{P6N)3C[qɦW!4Ӛ7Jt~S 89℄Y@;TM.=hHe*Qqɤ@iPcV߽4X ղpƆu,:NPs8(IQӰGn S NijMIbv5,h1#U|ژ^۱PNËolќzR"}ɠ.{҂iB3Lnifi4v&~lߕM amDS@i2sԼnB 8=#:QbE.yJL@LJœf3JNE ^$/jCFI9#]liإ*1J 51) w晀Nh$( 9#4px1sR1 :a; 9⁖Px9iAk t8━P4́LrVr;ґ94 mA~&2}b<Қ+.M.V&H>'23k~kby@Rn(c4`4gSV(n8H_$QFO)]ԝWvr= g?ZZ0zvv^ix'TMއ<ӆAgT&^{D>n:+z3qT[ro)zgJNsբG+D'TliLP1I-F89<s"OSh[1*EOҘ>!h4 9M䞔rpJbcljo icS"ě3x0W=qMn(I~7?A8Ku;C)PeH1qҝ˂#1t$;ѝÑ@\T~X00;ӗ*OA8n)>ʹׁM4J6 `})>nQރҎA:R@ sH@)F0(=FiW#INi2BދiÚq8ǭ z-'PO?!6h$Sqw4{d}3RBb@h< 089up“9ӵ0$E<B1n.8ijpzqM l#Syn .Ry#:^ܜ)gBg8dsL# =HChA hCv㚔&sJҊkt.Sғv3 FqJz.q[)hT³^M`O"|-t(A1.p^֜U=sWsd}Rvs]v=QFGҎJA1;sq)q,0|t sAڐtҊCx\:M$7 84w1yt;fNbs;Nzw,!zITץ.h$ +A␎rFM)9kv1Gz]ޤSsҔ/^)3qN&4'OqրsP9ϥ)8qցҁ{bJNN:PFiqQ1zѴ)Rqސ?/\pqsC)l&su4qdu{tHz194Rys#8bi4qրxGOj?ʓ.S zuP_تǞس&̮1Ȫ8ЁgWR^N^J_86@~pUqqXZYp!dS՗\4kg(s94رʉw$e'R qۗxn᭣Muw` g8*,4ϨÁIq]pu¢G)}6?v6U|A JWi3YjS/-V]#=y~³T2Iq0X񐼒p嚕iH{Ԉ yڝsZ2IwDqҲn) נkHռi;qɮE5#Xs'n1T.e>C%F %sHVS٬sC7֘OKe$(ҟR#BA)Kv"ppxs@=GdΜATASNTWq"*HTC0A>F.@i֘6M9 ߥ O!=ԅH\:Ӄr) sMESlizP:g<) 1) $oqIr:RhwK/\Nɤ4*L9()`![NizfN(h*=iN$t}@G9l=)41u7 v [ d cǚU QIn"apqSkĚ@w6BsL}O1r @4(F=s@8W$u5*8`ذ2}+~R9+"\p9ӳڭnr6?$ғ `!@Z&_zU?z-'S}1{9<>OoSҘ=)mc@\;S1H[Ҕil+\BxixxwNUEi}OQ@4£44OOJpnt\ޔ6= Շ=i* hE(9u!Z@IA900jt Pr) |Ҁ ԉ МQx]CR22: i;`) 6ȤRrGjn8֞hKA9& Mڃ?}.;RN1uK`tfs۵ $)pF?*@4 qI&(u҂q\֢y;<`R82D IRVFi[($r;R2h qHI9=T1.0?w!5<} Bq/ҎI@L:Ҏ>PL\ҐS z3LDSϥ&2xKgS{`AO@QtqJ0 u)s` 9-K{S==)X PCzfGQځhZ 94OPx4tj^'(4C@ēQJ\Fy ޭZv ր׊`ß^1ހ6>7+O'R#Q rs^)I4pzҕ+{ A#i 3NO $0怹oy ҫ`AXbI$9=i0}% f̋e`TVz җ35,-1stJeXF|Uv;nFz0{TZz$n0RZ\O1^dP[zhٽqRj,@rb v,&90XI.u㎼ Ұehanǩ.ugJW0f k a0v/-=+|+lަDv?-`LY|zߚ31NpqUdYUC):k\5 onv`~u4"Fdx}$,p:Vhп:)+!Ŗd`+r"R-R T7jҍ:aKud奍-I[`+*drr+qZڊZ=8֔tԘu:ӳё1I9g7gJqa4b`rx4+P8}i !1p?ZNǥ(fNt9M S@e}iy 8VS=JCր1@I2 o9 =֌2(b3BAB ҐT` hĂ)I.8'N!sJV1HxS'$ sja$E(/d[ 8tϭ44m98@KsMc"FM66I=:R1!}Ah8'E;w$b @y $8恞) L c֛.?VoJkg@!)FHH2F==)=@(\b;F3֘q4֚#>Ԡ0dP\&9)J H(?9vЈr=9䎴})wqC[RNiAi 9Z!}iF8LN;‚o().XoqՁd[qQ늤rV}I^){"@4V90 O 4\{{SHqJW(nOQ=j?AqS.>T qҚЖ*)<\vN"݀3KB ڔu ڂ;R`݇.dti,{Ҕ‚mf.vϦ( 8Jz r)qhNO&ap{Ry=)HЄ,:Ό F AxJ~{bǸq1rqKG"=}[ l*җ kJ^HIqPFAu<Pz ]Sh(yqNAh9>8Kns c(#zsҁ )i4 9=hCz!?.:P$c$(=xHl9nltlsH;}ilqҀ: zӂB{r ~ug94 9H2b(nERH!#8ڗQ>ۚkaE. `U8=):юy4iq=֚*F)p1Hva?:q98\0x-.G\sM;zґqKQ4Tqΐ}> FcZ qJ帤9B:PґH?lbg NX^#ޔL01@iAJ4'L}C47JqiHR%9vH9L )$iޚ2:fґW m9Hv^&y4)/)5rR=O4gJN惕9>`ޘZąͫȣ*:UNsӊ4e׊?>2VDmzL擩?;$P9ޔ1H9h!{{LN#'N8֓ 61usKMUq?:ۻIl}Fse<͇ yن7.fa8?1CE?hd-PG=֜p Ehޝ@ȧƹmQ+H%1E"PhYD` ֮_ryr`mبFc~ʊѣlv<;7Zҭ6c#wn{7ś69-22A1ƑGIMxr&]vO_%{y%NAd9 sNj?3&t.LdvW'<ӕp*+Je${?F-Bc#APÒO4 AwT!~iaJW'E1Wr] =F;y,|Ut8r7iSE$=Iښiw{ђ r2zSAp9`?c$SX$iAM!;1@jP=j,'>"9L7L=8Nzn < ZL&J h348'={ёSdܓ֐i31K28i3NP6\"VCg4rznvO ֋C[p#)~iqg(&sH 4g:RI== EsAc?^ȶM/ );NABC&6za 79 vTgN݆I(OK8 sHlA:ґaN1J2P%sx%zsM݅;a9)vqۚ@KqR[ңsNnP0p&!9ݓQĤXS߅@\ t2n8ڒBIH'ݑSHT9XF (*FQH)QzA*e1J!9\ dJߋTNj9jqߖ) prU<rԃi҂@ȪLP:SWiw8hB"6ǭ3t?Μ:zg\Ԡp{zTjFG9~}KҔ/9)ឆ =hA֚d^(d}h%vj:. "RgӀLgƘPH(>)(P98)Kdqȣi;Pz+!ބ} ؜!f'zkq )đMR{J# )H]>l4rҗӥ.K4 E߽qr)I8#ӥ PJ9<ƒpH>Ӊͼ񎸥lOL^O R!^|Rրbuiq:sA8'4?)Hh^JϽcJ>lR/NbZO{>zNgEzU$BR 8/Em@es)srx23߽;8$݅)#{zRq[mhS@{P-9 y(ar( \pzE&Hڌw(k{9O'pG' 83C|23BbZ G|9JH 4u*U?)R/N3jJ%S= jPZ ``s(%HH9jAǩJz*Gq/%+0#>h$@b񎴘iAN# qH2pqJ3Z:=}i`H'ڄ4$Ҝ"H֐=qR4.qzRhkT4Jzi3ׁB=(z)s֗s z AqCTqѓAHNH/^ ~1.>Tqކ8qyy)N06=HA:Ӱt89iL KBus8.n8bzRIΌAUw tzv9uyRR@FG* nA;ґ1E yxh#@d4tp=<"ޜ1HFWz 4Sv3p.PzQ縠ch;ѐy>wPypyQF2q!{'Ҍq<I3x#g4#4`84֬rHKc#KyiF{0&Ş9c{{%rvVUWiN湥sufm8\Vi-Aqƺf6GɬUyױޚ_l"#w9F00jIT(Ɔ(Son1hcBz`A}9"l+/#ۊvBQ-t LPQZq)*&&Fi7oS57N1ޅ\sR͎)cQbQhtM741`fY=|$v7`ސ 2pyɵN1Gbj#tw /^3A@9>xA!Rg?0eXa ;O@A=MJ,A<0bx\ґNI%+׭8g=*EwZ3;_QT {PrNOjfp)6A"t`xz⑸Ͻ2އXS+uS nZ02O@IsXPI=x7(w>gVg9;ғƞC=J {R|`+ԃ z8 aڜc1IN)CcgOt:t)i܆Aޜ9N8G^iɃq? Qz~I h%|4֎ޭw%6sA$zi8 ҂X\٦F3_JwKFG8zqL\3Nq<A7\9'JwBC`2pМd.ܑA+3׭(l!ȡJq(Q? CҀ9CMJ1Zbp8gzQ@c'HcB1i|RhqޚqO)=hgQס(#4sLLL=946H"H8@ q0Ii|3d= 1KؑK>`8:i8F9BR:`P1FyZzSԂ3LA<}),x=)M!`XK~c@9R8{ўF1wSF23ӏpE.xsF8: =D'$r}! cK$R03d9L'={RzvAhҎ[ u1L܏ŒgќA/{IHH?)c#`2Y(t@ qGb=E.~b@Icޔ1#iF1zS&FcAt(ɣ硧q-J3֜~Q})É|ҟc3$.qN&&9N t cJ27x5/ qqH8=Q0i)f'`Qǹ<H#Fq]:)wjp G?.?F?/Nv>nS c9dp)O@xv01h'' o Ӟ3KA pOA91OCLRu@4A_ֺm9a)ƑOA^y=3s.҅4 /j1֤ >r:S}qLcFsґNX1ފSڐ0tp Tq@ޔPG$vNJCҀ ӯJi1ҔR:=FsE&@ў1JN (Fi?J`jv2)ݍLOJ\{c"րNԣ9" @0=4uHE.0 :=@#:P')H984tdђ9LԀ=8# jLvKۊ})^>``QN)z8׭pPq=ҋq8 ixZ!ut(4ŰrqJ=OzA@G8u g=qC;ݒIRsRА!?Z\ MCȥkZ%~av]ʪ4}q{kffX$?|@ZMt0`rO$*/T_*١qlW$v剬*W;4rķq!fjrj<$woue=ٱ9( #jj2M5 Y@kMTNppI%yzR.M(b?vh'4c=)F~tiOn(B 9TuzJUvq֙ 4 $԰0`J⍁'%EH Ԋ%H(XJ`瞔Ч9=)⠐3N@lFrz0hB}ǃEaI<H?#֚8l~4 @ɤi{SҐ84!=dsA]g.ӎ($w(xEP{H?nNx)-M j X4=y=髸:)T'ҝXґN1B2q-58 x+ңF83A@G͑HO4Rg1iq"7p(CHNOJN1(a٠=(d9;1hۓ@p ,$&zM+1NMc(N#֐O֟@hlqRlsM9r=# ր[ V4)4s:Q$4qҨQ2MH M:q>GjaRuLT1uJaPF; ڐ8=iN)tdTS^M hQg3RnR>Z)C6qB.8*d cI?Mˊi8ҢJݩ,O?ʚO4bqڐ8H&CNj&b[8E7ЁUⓧ!is/BTIL dF"*e"$ 娱V8wȧgiȪ"ZNisg-);p4;Ӹ^4E00AnԱ(#gL4Rd`8f~fM w,&g?Jn?:_J px p\x=+TQ"x4H?g1K,x) S@a=[$)Ln"*yZB2@!G_z0pWizc? b(S 8 g$ ?;f.)q}-ʗqG|u" N4%zP=Dn޴ONOJE#}Ď;v"4å''?;0zuwQat ݞzfAHbv?AA0F֛ʊ:N8@O=PNqIy#>qjÏ9/9ǥFzC)qJthw/@HO)I>\Ezь` !L@hOG\dy44ӱNs֎P0)GZ3g9B{ǽ&M@ZPr9杌p''ZU4)PMh<Pz@!~)GJ\( ZLh^=hǿ((hR4HO~ԹEގFx; ׵/J8JBh'@=(; w=)F?QRsAڎg=?la'M0W ug 1~RkbHجg ^~ |7L Œᤕ,I$fa?ι*WV- F]IcBɹFS< fIQ7r3I-zdOCQrHn[9q ˜I '`PH0$#RqȤ# ~\zӔ^FS g0:Aʓ搝Ɔ;cbDԘ,Fi] 0E4u߁Ȥc4zjӉ)JchnI8{6 c;QrY"cA4O^,y;BubF1҂HLNzSx' 䞵'('xdWr]Фʔe'Ԁ㞞'Ԃjq .F 4MMbLCʗ9QesKW.JURzҌF>R8􃟮hn3P22OҁizAL[GZwO4(#=(R2Pqwxsd҅iy qNJҝzS%n8/;Rgqހq'Q=6; &@3P;cMlzspc?Al(9 4TҔd{Ki*ץy4>|R(8 (#sւ}я҅(@~byr98h] <J;ҁt` J9woJA.6sҚņNg4I8J6 p f$ Ҝ=i? zpȤݒ &#4鍹qX\88\$n7cv9Ks8Tir1B4 3|Ұ;}1C$M\JLp(@y`OS@v;RhB~4sJz=^O9)^y8$ LgCvQch}D֑ϡɥ')\VN8\9&ڄʰӟZ\M pS-ӎn#iqM'S{h9^ߍؠ TM~nO{Iq@$qKz P0O s@ڎq“?΋ ^Gz:x=h^'R,x9(j@sGQ4ght#җ# 9G!}yIQ})Fqր9ǵ/@{{sސS u(;b^8'j9Gj9(\: R})#"y@'RHOSIH?*Cu)qH/c׽FA=(w@8ڔr94zw$hi9/l CNuLs)}h+4H9y҄ QtE48ɠL3K ڀGo~OdZϥ(R`huF⓽)9HI&áAi;Z`/AFOj35ruqIZVM4ڹdxpi1 kg-4~d#y 5eį#su*(+B7jbh'o0򼤗vbyQ@*7ahg4|Ѕ?) ').N2 M4%5Y08MqMޛ^( \XN}4{R qQڐdu>Sq) ӵ/v#:ӀJiII]E=iHAIA4CG<ѰQ9@zCzǭ.F@"s!}MIQM@4 ⃵z IP})Ű27'oaCNF7"H)8s@\41=iæqMaH$ $sޥ 6!\p SOJNb6ƄQp I1_zda))ZMĞqޓ*A-Nu9p)qڝϚyW=鰸ЌM'4ӗmݩU1J<`gPN)ͤOJcY!RN=)}imj\ibOS 7sKHO4dPTT4JӁN #\zozj4BNOO厔ibM8ǰ ښrG) y=*j qS(@ނ) ZIdcrHPTp2*0uJ?zĦҷ aF#45Af"p{>`!F#"Ȫ~^"EfqsMoz_Ԭ86Tfw;) 8qR>F!)w )Ci;OqMLzR7҆qh-@(LS J?iɠ9# h`ƕ)#" SK[pGT@*,'JoSׯ4#SmAj7DP2_hO܂I₁q]4&,[4ߺ NE10SL B(^ԟsJiێ>aJ%`10H$zS+h+cIvD[ЌO` g(zsܔ=֑H8qYa9\{ԃ'2Cz ZH1zirI$ qJqa~TQw9tc `dXj F>&Asޚ'=hB8)ӀaT)HR8wj H➼j08BdqsN񦌖$m#5BhPTc rjL)=3Qq7:ӻ{P&8}=%xI|PX1LbciN{SsN9GPA@ci $r HCj~HS#RO9D˸I08KA68'т 0H;@q@nI= |֚ 6q#ލí(lNJH;g/c w8#zTHW)r2 ; NȤ`  H9֐p:q2 E8d|֔QiXL|uqJ 94rhb})FOȧyb4sHXdwqN8ilPg9!878z :уBD/p=);dS) opsڂvsQ9HN04 OJ-*Ѓr3H MK lp>2AH]֝JhW&$K]˵xIJ7ۊF'$ǁޏAEsƜH␌M.A)ST943~`'ᐠƓ wOzqo֑IqO\Ӝ(4f I9 dtPԤcLmY 4 MCҜ0yj@R/j;(>bSN;(c0KK>'vO=~9"9J3@ ')؝gnc"iAr2)y,$fp Qr9bAߝq`uodc}(ݴsH\Rx 8qM#֑HFn“$s/9z~;=15/S#84zqJx#Z=N;dz\⁇ZW$`{3Ӛpn:SzRvӁEG֔c=h֔Eà#(8:.NzQ1iHߕzvgROS`ӥ(ji{ (Hk9}:R@9jRp=<:G9Lhœw@;4!)9t9ZLs@Jx4qJ@GnsI3zP9=i3z1xQw4dS G-cOS!ّOB>_v+gKZ{;ZNFyjoq a0< U9כI&'<ƭuE8u,wXq]M'R3ᔜЁL')JpQԋvB'i#ڥCH" ]z~\6sۥ4 `Q< {jbzRs(8vM/~(470(b@>2A4=1A)  EqQ.EN4@|SI C)2s.9 hӳ=i6bsqic1ϵH0sKqK\UJES8 ^ 1@i0jbTc&r)IW,y9waA^ WL$zN!2MԳm]R$Bp9&VXsO yl08 +'8&79=.4 *ApHRMؑb>8V4sQɪ3ԚI#d(dlM;?1N !`)iI橎Em(;@d4CzdqAq;srr810KqTץ!Gj\ ќc4=JL4)U`ijc)M>m IϥIC H+PȦ;>1N}iO9H{ҟZ;F`hJN6AKA)J4~{Sa֜;ѴL20lJB^ ?szAxA9Zhw_qJ=sM)vS'0V\{bm/A[8THJRŝx1ҩs AN1QŒwvsOqh3Zxl3Q1Hjhz>jv{M$8uek1O\@ v9=)PA*=i)ˀjMO0r?8aV)zR@ қwJw&CJQi Q.@9uGPk Zpi'`} M )p{Rb ^ߍ(zP =Bv7p$n*2;wЛ2>JcJA#J+'n;w~(8$R+qqdX\>ozqN4Bi*i15H;QL4-+ Q~)>)9?.ip\g4ԀsҞ֛sRړ :ҎOCCH8`sA3M;!z7c3IFFT'1C%۞)Axz^3@Ӱǽ x)hI A֜2RA#ڀjю} sJHF1HN{PKUO9 ho\Ry=R;7GFqL.zrZ/ۨ Q1ǭr'9(ZS;\@rOcJ9dAH9m2of(qyzȥ IMǧRm NM"L◥ dIG0R^I"$RGn:)cRO_AҌa sH|SH,= )ӊ)t֐  _sHxQQ\\ 8HzJ?J9ړ$⎹2 ZNz?֐>Z^)B){~45ђ@1CT6C剟by!>;_@B|C*$QH$5j_|\ Tgyjۿw?QXr9\1duAwiٝ3OSQ I5+axfIFikw|Tj B[ҝ"`w1\sM'#:Z0h 49=7RdS:ӱ})$vRCBlh8x#vܶI3O/S: ))7S["@F:TcsڕsRg☬(Sis8yLs1&OJߥ8'RcBLTHWIǭNT 9=j. }jQ qU5Ib:zU U\p})ңbssQN1IzqP<ASpaQ֓ d81 :8Px0+qR0BS˷fMT M 8Frԙ#f="RANz n13U #Ճ2}kn/cQ$oH0XQ?^:JpqTcm \<_jx|t2 lHTpxF0AH:bzhL9)8xЎ-Q@W9ONGJ3ӥR2{9&F1S~RSzEhwzp~49SOjd;89HrH_z\砡 SQ;*&*U)xq}hg"m?䞔n~&*M<ץ3H zP>_zByJpNښ۳g.pi S; @ q(0HGRlz\ÜҜ2X`uO!4)8M#⫠Fq^Ži7AI <7P0OR iI!LRҗ.wVLL>oG~FH%h^O`E/C=1Mr=C)$Ґx ,=Rv擸8B\|8(-=)'4qOAsv(Q9`bǽ!iNZs (#8'AJNI8@.Gzv1*Ϩ$ zR}E7=bgvtqg &p'OjN98-:(0=:Q}@Rs9v=#@}H4FzP&sMҝF@`pE}۽*1il4;is.qJQ>=i>ϿGp''Oڍ݇ a8HAH9)(qҔaH>`}8?I1)<wQq7vO([4c=:Q,9W NHJApن2rzP8΃Ԛ*s)z(QUЛu:hEhQ)W({/JݾQLA#@*(/RE1~ފ*G-=M8QT7֕GhHݨGz(zz(WA});( =iQE M 'Q@sRZ(AH(C CPPCB>E2^>R'~E;/E&>ڊ(E1: o_>4Q@o>j(~`Hbh5kl&O<Wj0fnb{EEo[zwE="D tP8ޢcS($Ș,~sEQHHU(~QBܮݨSb-!Š((c(T(D z(lKU)h/Q֞zE68=(E)S{QEHv|Se-֚MR%R(#H:EP gjZ(@:RJ(ԡOZFQH}Zih _Sޢ}((!(/ZSb}Vh) ᢊd@EB()l)E0{ IZ(IR(dL袐REaԕj7E8L}}c@zr) MBhY ƒ袩n/jsQEICicEDu:(M4QH}RC{ tP: (d '(e _J:(cݨۯE"G'ݦCE{z7AOp:QE"PzTåP#4E9jEE1ڊ(r|QVІ?iRC@uPKܚemE}(c1yљҥv(f(!JE4f,?Zr4QU˨vcE VZLEDA'4QMl.)*D_-P_E1= 袤i (B<)4QR'UҊ)~?E8}E ( ~)EtQL 0tQA=IEL^QLL>'-P[}(KO4)AJ:E@ (wu4QM Q֛ފ( >(^J sE B:QE&(*[<QE ߧ/oa ~REQEH HU:_i[h%{EFzEiJ(B/jSE/qV>?( n4 ǥSO—E auINE>{SR@}UP$5z$HqQLlomiri-ui-extras-0.6.3/tests/unittests/assets/testfile_portrait.jpg000066400000000000000000012107061455543116500257250ustar00rootroot00000000000000JFIF``C  $ #," '.0,)7(44418=9'.<2432C  2!!22222222222222222222222222222222222222222222222222 " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?8 RsAHK@'␜`c.p?O^)})N:ar8;sJs0CFq;J>p Wi8HqK"Qz′bc 9+9 X^9'('PxzPݩ:B:R#4qCɥ'.;;Rߊ8L=S{b#(x;tҎO|}iOiю{bcAtǧ41A#){ r0($Q@ 9#d{R n-b|:QP>RqNA.Rҏi9` A#@?1gN ~tgc&@=OLm9v` J,J . 8 ;Txd ysGH41 w'>q+rz@;W'Lbu=qHX`dqNʏcI3,|ipx&r9/SZ1(ApzPOn駎;/|L,3O.F1FGzL4-`_JP=sh3 AgBpM8m94y)&6Ii=1ɣGӠBsqFӐ; ښqނ}N!(v Gj\mѷ#4h=(6QQSp3H2=iq֓@杁߭ y&4z s恒hJ _P 9gך9Lh=:JL҂`&E7 z?Px=hi)yqҀ jN^N  g})8=@Tx@݌B EIўHLLP')g֗^zR w4 A9(9Oސ㓓@1r;u{x4OvsJO@84i=JPP0,}(9)GG +RZ_ZwL )aM`8qKϮEs<`Ɓ8\L(JLu6IwVduG' R:7ӰcjCҋP3ȥ$4~4=i=1җaGSϥc=8h/S(9iHS搞)'}ip#!<QM0K;Pr1{=FsCqрsڐggސ\>R}84q'& Jx)N1Is9`1ii8铎ƒGA<sJ@}&ZhO@Naߊ\ c8@Ҹi #~}z~TAAp)y{B9ǵX8ځs0808ґd @`AJ1;~nJp78*:zRAP0r=dc\ OzW v)'G)OQ@=8HJϽ.6Ƞ`6֗Hx?Ҕ6r3Ґ4sQKs׊CsKQۊpzsAI lR_J*lU|å(xB;}(IPNyi@${Pr>P9t=΅jW<{R1N)I }Lw=i~msM X ={POIZ ^1#!ipNzSVȣ4G##wR'$wz`c()@hwҗ*o}hbOQӶ)@F2@۽sHHN_ZLjK''֙S64 1qMqԃ#ސ==(PIh$ƁZq@s.ws):OjS~>^K4G9#)AZ8mRFh Ƿ:R :SrE40~)N(B zqKoZh4%@?Jey9b7>)=ir:Ҳz@O8qҌg(}OA#( TyRQсL5u9(֐l'8zS@&[ Z88d`n!t91^xG44Q֓OJ=)@Hh0bqR1M > ܀:)R`w4BN1@`cҗ<,5^OSRH@8=(79?<` Oҁߧ4qޗMO\`Qa \}h Ny9hw\Rd9.‘z"wȦ1!ϥ3#:}(iX^4{(z L`r:~t`9=t)n9@H~QS'#f=={ѷ4F֛OqRN(Lf=ip1֐sނy⁡N8@+4A/N)po9/c؏֗4g$`S@cg88XCxn{F;O~돥0y1Ms 8RdgB#u6-4:${c848=qEq{b#N8@\L(4ܨ4@3ȥRm b w'(8=8ïaFHǽ&\t`nޗ4qH CL7g(zzPsb d3Knzv;3M~x1G\7fhQQqҎ3@eGzLtdsIM @<~9҆M.8t搃1I\֘QP3ځӥ 7Lc4\Z '}GS37'-R3ҌQ=)٣ *04Lfv4L S$ ^:sK4!+8Ày88( zRRr3{Xa;w=;RB2z\ԘR>֞ppZ='L€_Z{ip9~t`4h'!4 m펴w{fjc=ioϭ;tҀ))ӊ@@{[=GJChLUv`&Ⱉ'BiH0)1@sA۞:`R>lQa47—33I=ip2@\zPNG Z^׭h#dE1H0~“ >(c$sA'򥸓 p;SR vSH8&|rSEh8ϭ)ғpB@<2;яN(}A8u~{Qpr(tuRc`v4ڗ@a9zgr: zLnöy$G8IN13J~lh۵0{20J9ր'{ 3?Z7g8R:Ӹ/JLybgӭ!'NsPnHҊa69(ךSӊ6ȠaqIaz`3ZOaJ2{Q4/==)084i9{R s2`Nj掣ʁ y@Ny4ÑԞ1=z'4ppGh\VqƓzQJMMNݚ1@؃ 3A`zӽi2 (y0(߭{RN٦- `vҗSrI\1QCn(lC 0G9C1JhIHrJ`~4=1pi23NӶ>΁#s梗v Nw>ހ=) ^܎P79 xz裥08Ah!}x=gQZBy9zO& jPF1aaC{Rc4v@9RcZRN8 Ao#擎}(tLvnrs!sK4r;Q⌜zt? '?*~R~[#0R#9o—hL\L14ރ =) c?Z}(=h= 7)9֌Hh=y0I&ӁG84;P@>(|)GiG#8q $dPst;4u 1HsR\B1XN1HAI4P2)sh\SP4!=3ڌg>$F1z 1F֐{րx9+ph繣<?:@TS@/zLyu`~!n/"ϯ$`SӨ׵4r:Sp 1JypM@ A9t1 saYM0^@|qJIښg.SBGHpGA4qLph/AJp9Lr4qg&j1A=cxzӇ!~Ph-iip1j $Ґ\u q׽tRdRIi1z1g=hsi14 f;PaK8! >g;9)N (#. ?7)>^F (4`ɡr3J Y1z0I, 8oj^ B})'N;a3Kǯ?:dzp)yh^ip=E7nr)օ ÁG{h9C\qKJOLsӑ@n4iX b= QۮM/_aI@^ `c4GLO8 v,3Py'Žyh~ԁ0h894t֟ACv8>a}sCqEa=> ) iO ߿ցLsRҎ:48n(=ippZR0zg!O;⋀ޗCqzQ(t L>O΂9 E.=SyԸ!<`MӚ nGNO4i{u怸z <悤qҘ-@gj98ɧzsL9taFnhhێ7;⃜xE5O^=)OZJhHR@;K=i).3F##iI~|iQpi r;PlIqzg:b>p\CAӀG!=R;ui3)x)2;) <8lzi((:PzQ4BAqH>8?*^!H fŒ9=$G qK8waFs#e$8%ѻR9(FqAItJv7gM}1X8$t=Rǭ Hz# JpF)Zd>SKnMҗq`>GʀMQHw畠BvNip0) pF 4aOSA9RJpšIS)h@@9M'㍾O9hSF}pG{un򁎔)HRn'1<Ґ9nM06)B (GZ0z`h4xԸ=8zQFMh=h$Q##Z )LJScz~tg֜;=i8' y$N&sPRhؠ޴Ja=yc<PC)zth9('4|q@0ҐG^4<`:g$ьu9sG| 8=8=iR=(֗+"M1.Ӂ8^:f $Ԥ9$w23zN7JWNHsJxґXgXAKqƌJN36'-NRcp)GOa8Qׁރс@9M (f\Nq<8 HB(s(";+~iitՏN)99LӺbGLv4J;ނ i 8 niR~=z3Eqzҟ:Rp}M4 Pp?*P0H$F>N1ɤxw<JCB)}h\Q(#ցL0(h?lyQN2x|h&sjvG#֍4 h! vORzќ At 4#"dҗi/qqA֐$giyr xҁzMx[J@ AM7=Zփ)9MjR2h=~ZVb7[3֗i@q QKLqFGJ@SޕB<pq֜@ `b cAQz 8o $4c}EB{SHi~ t&W/QR4Lt8jPǚ@w (CR:PN!{33O9'֛,vInRtޔt94ѐrNi`GQ}hFi^9P@`ZzR'n4g1`8A8>NJwNCHHE 42(#Р`M3FJ8h87sA$QQӊq3QNZLB@)NN(#8HGI(>ёӞy)bOhғ8杴/$09<#|(Ri b QLӐCB=M4sNvȠ9, ;zq҃s@4INqZ^zP-4Ѹv揔(ЙQHIp>Sh#@ I)'ӊnqE&j*,1m#~J@1sF(9ۊ>R:( Riz&@\擯=Ƞ)8(>攃K!;R߭8@9$Kt? ~tcaӭ8H0z߯G#(PzPiy cZ. L{g#\M΃ґ L68#^ pO4RiBgw 0#P{ґR~4 ?j$c4c94 sK>q拈;h猌8鞔az=1@;ΗQhקj`` =E*yǥ$gbAS}M֎I`4ǿ4c<`Ҍ}1F0A=;h )n;u4\V`3 ~QN@2&wt91@u ri2;ҀO^Q;1'Rq֐c3@ ٥nqA<@8=4.z㞞> [TO\NGbI'14990 Ѡ+6qHB`FA`1b8nE!2{sKޕT4`8{E bw71ETh#()6qH'&[R'ڗoz`&9M4SRRwӜb.OziP=4`QcH=E/9ӯ4K= 8Ƞ t ǵGQ.} ݨϨ[=8`0,=h&}i9=1Kbw`}GZNE/AӎǟJv&=iA>`sƁ48)9=%$aڌ/ 'O4ԧғ,1(bsϭ;&}sirGҰ=< 1צi|Ry 9isڐCFyIǹʎBs@#ݨQ=)}OOj@8܁z"d(@9Fp9{~4-sLI0Hqޗn֐1s'pzy֎H@#"lR|CLLQ@>9v@!A3M9)pBr2ixi9\ 69<`K #ib~23IɣƎ=1@_>; sQJKc'O+C){ QH2J'2~ ${h9;MŽ\J{gXr)7{OL~4s*6(͟CIH8ms=ws Nڃ:3P09Jn2iA9@;q`sn0OjKgR(uP$4o<❁R9{ӇNҹ$\`sߥ4:L`=i;*\$ONQK“%hBE)`FZcApGOZq2<hsE\LPF:iN:Iz` 挌b}iyԆ~(眜`t ) Z ЊiQ☮.s+gץ#?Pr1ҁq䓃ui ^f${zR3m'J17``R6F8PBHyЂ>X.s4rSx瞔ҼcSI8KHW¤vO`bH8gq!y(g 1{ p9F@\Ґ5hJLnš&{(*@"zҀt#94#48>lRBdIiNn{Pp;P`Izұ=/~)s(qA7{c֗+! s9L1M94 t4g8%GCKZNVcQ01qL@?JP &H4pyҐ \^)8ϵ h)=):S4);斓|޴$4zP;2;RS8h N}?zzcPq!9I4~?1 RcJI=((^zt;iI@y4OZBB0yC'i>is 4CKzI=8@H@$Py;bd 84ggAIg1H=:QJ:3ހAv8vQ4q36)81)8&1d8!c=iNRdIҎ/GNw2x4.NNqIx.h 9qрiؚ_\PpGZ8ɤϷ46Ґғ)r8zP9&s/ҀB=M(Fyҋ ?(Lc#ړ#']&@$9J>P'Qߥv$w!V3 MFc4 {0lP2)wvRtNBq׭Oz^/NH=3A)\@ns҂sތqϭ1FqI81"P1'$(QP:~ڌQ9ǭ6u=G'M  ->K`dڎ ޔOΝ qo 1׽.sIȦ8FAIa3`Q>ƐӚv'P:wbsT s4}) qN;b'ږs@ cZqJ1 ׊LKKÑց+ޝ)q2sB34i֓ojy@})\Cy(bސs=Nxx(؜ɣZQzA h@#ߥ&OƜ`RӲO[px#*Gzw!ňv9hh PZGh' 'rhN 攊qHv9)϶J 3Q HOƝwqx.4 xH 3O9w"3{𢓟Z*.22`J1u4tߓA}'Ptӭ8ansR=h#AHOOʀN+A {P6 ,&0(+6h=(Ԝ4$c=(Ҁs&M=#'4s]0Pq@t#ԃ#JH=i#1O')ɈW摾SҜ@QPsJ^qRcMuczQnc҃R8#AHB$=)x⓫g4sր!$uҏCJ 8OQr? wPJCƁS;u\c)!?.@=8ܓހKc=>n❓ҀHn"v1G@SB41r(B}iGNi?JiQځnwUGK36sHN1K94'ƁN`g惸 SiBW$~ӜNzSCM?J@G=I'ZCy 6qHsNۓcMa҂:qw=j >M8Ґe1FHMR Ap:Rí!Ӝb4 c?A yGsI{ӈ#!֐ןjPFzq$n8p; #1Aߝ.)ߥ sBw/|( 3H@J=G'M 3@#)8 )H9@{sIӌr )Ɓ#wniFG~E.:)랔w9;P1Tri;ҀSA?{M7ys~Bc8``ޓ>ހ`{Fri8<.|`J3O@js֎GҔqۯJN6>'&rczP?!ےzo;7'FFӊ@=NaPh$hE)<^LtǧKƌ8+`{G$fz CS(Q) M.$:ь+E?-EMN{QE'^84ᓓ&2r)pX r@<JF~lJ"1E)zp:`ϷqȠ\( Fi⌃^ԜP&$P0x(ǯZB= PsG#J\)!=):Ԡ`ǽ)AE'oc'Id`P AK94^LqE!ǽ Ӝ4[493N)TsR3)sϥۏLt##=1w$G?J1xR=( rL-3F[)O=ZirGsG'Lxn84J{S^6-g#Ayy4t {r1Cs9&c(;tP+4܌ӈ;O֘1hc!ONLD=3KE'N1ڔcQC) <($\3'9 :R iJ穡Fޔ1 $%&9ϵu19ӊoٍ%F)J=(E @1vA#p$I攪JG VҐC 8)\wRcicuJy&tK;^8\恦' >)ڐc< zuRq@$)IoL&b?T8 1!Gsɠz AҔ})qri9`jV ҁ+1FOIzh'&)Ǯiyqis4cPH894nG(x .yKR8Kьy~oƗ-Њq ӵ3I:ǠRqL@d/=Hb~)iwu@Bir3Ah݆; ( ciqs&rM d`%3N Q0I2;P &} 7p1Mxh?;$q ߮iy)N(h =Ozo tN#=)6R9ɠ&P#'S4`P3c?Zqfvbsc"qs3ғo~E穤 zSӴƔځX`>8(j{HOiܮ@Hq@l=P$]9>{R8d{zyRAM??%x4ߔ#Қ?%NHFN>Qړin8ȧ^}HnGa1Ԥd =  c4gF1KO=( pz҃ғi8ʑ^:Ng!#J㰘iNG$tFA \ǽ!ڗ+Kq&+? iJ~^h!Rz)?ZbiFh)p`&~qڜFG Z<GcKOjv: ?.(=A(;4JwV<`tjC)1ޞpsn1T+X3΅rF( 硤zazZ>;Sqsֆe( fj78W@2qLJ(Hq 8:wHGJZFq@u<т88q4uw╺:8O((iHi>EYqIy)pFqLBqy^)y:HAAa&ܞޝj `PGSJB0895sLg;iIf#FF1OA8F$P;>1ϵ49!5 ƐH9# 9P$zg4уe:~Pa=).?JRBƘ7ӇҜ8-F ?oF Pzbpz-pCt4 wFAڋ q)3i `Vi8~?Z8c׎ zLdЀ|֎ +DRcR)9^)O8GZM`zg/dR`0я^KM!XBTzE.:@$"҂3Glaq>P:`Qs@{bE9Ҍ^h=#KקZ9'q8x֎1—4ch%GN@GOΔ s3ѓzJ_Mϧ!>^)0)!~ v9NҎ:c(ɥ9NsEpƒQ3 dE3A :@9?`98QGG=()8b@`G$)0E/Z8I◌'4?(Qɣ8RdzӲ4y$ RAJqL.&qߊCZqb! JP1ӽ&qK4 Cހ(&+ Qzs@<8M$}>aӵ/lZ;:PM d3җ(޽({sKaa^oOOZ1R>gfn 5 TOAzS{Q4shMh+ TpzQ&NsހHA9})~SCHNsKޓ: #g'Gj0Ƙz>nt;0)ǯZ`=qԚ6db?& P&OQNc8R(b<<):zU;uM?Ҍ=;P xRG=ގxN);Q`ߛ<pS Nhd}==ֆZcw)h@{SR}(=zP0Bzh<Ӏb (%N8rO:!.qSpHAJGzҌszR)s4^\bz:ݩ84XN\IG sɠ}h RrO<@J6ƬÁϥ PYN6HLNSSI$r:P6 ɣp?@^1==hpipR4ԒzS'tz,as) C70BNxo.Xcu⏘!R?GHwc4q9)ޓ#?JD;>ӁG̤;x+sLiwRE( (>41\׭.GLS1sڝ@}pi <2(wci J91@'AIw)BsQ 1iN~4F=HHwv8? ^1JaawƁbrOZLH)@dڎw@=1Iߞ;Ry.!#3HϥB[z0t!9+⟔~q@cF21LBB9"JcԘ'j\ct&ipr9i$Jq#vzsz,;`t)zL4$!pzgҎzRӽ ^+֛cߵ/h`M!$z:'И~cLRqBǭ BHNHiN8zP1>@ Ɠ䎸wFC)9+t>#(@QjV(9IZS#t'z}tqu=zQh;y9::sJnX@@=H7ҝ㨤=sL,!;iHPY  #8؃֓1œ7J1H[Ӟԫ940i90q=qҁgғBqhcӭ/=1PH'0N) 8sH@&lt84noZv;O֐`p}qKhj2hn{F3Tq){iyi=)Cߍ( t4c}is@iF 3 chܹ9FwfE^0)`{q=zeANpi@'֓LONԸSM4‚s"=N:Rۊ 9Ži./F:P6h R җO!Q4|zi9zEq)Nޔ9hP47i9/G? zZq 4`p(PԀKJRz{P1IA?9i`4:6ƌC!8҃})PEh=iO=;SIn" !='h8zIJC:?ƌwb搎K(z I@:lPGlbSǧ&1ё׵m1 g@ۊ9җMw"Q 8p_AAlAi9Ԅ'#R;(`xi#8$}EIE=E(ڃ?‚ӷfx?J8C^?_AG$Є42=i@h'q$9MqREA sA#ӵݜ8)NS8zFh=G=zр*ZO ɡsGon@ȤK3`踷Γ{@^@@1;R w?Ҙ r{Sъ0GZp`Rm8)@9Bi9'htw 9xJLĚ@.2E4`ӹ4z}= p:Q4L&ng CsJz ^T"qH3>8sӿ8!O ҂G4/8<ҀII]ҌRfAJ4=+ؤ0=i ih;ll?Ύ(~'cgS9"Z r1Hs1גhぜa!;GQE$(\{O~0i`s =z8ځpM(rpx⁉z挏ʁSryⓞ(}H9$PcZO4#:^qh)NFiNy! @ 0zRc'”☬4})Np8qҀg)=G9$v.Ѝ'JNGLPxi3bq֔1K ,(ҐjB91B Ӟ91#>1sɠ]Dg?f')S4R3FNq=8H4 }h=9i֘`yc9==)_zqGR1i3Oz0HM8c>#4>1 F8sHN1ך9;@F K#M.sLtR(P; @xQҌ(@zҐoa֓{@qPz' 1қ>(.{FG?Jj.)Dw)'R9J1v8FxCzPN:QJL|ç_Z8Aϭsڋp֌ 08AR`)wQ@ 1GҏZ1h</P=9dAgw׽zsRrqKaRScC֗):`9>ԤqJ1Bb~z~P9j@04>ⓜb HqAP&"cVLtcyi ֎ v'1׭.2:Rp(b /<9 \Qztm⁉1IR3A#> Iϧ"9~4 iJ1iH4n@a8/?cIz,+֔p1߭'@\0x0;(@($)xG<҅ڗBw }P68'`<$sJq=(#9 OZZJ.&}i=  ?.*9${a>/LӥG'͞:R=h€z c$vTd izwg& iO</ܓZQ'@`1);})~S8Sq8,Sc#h'&`q&@lс ǥ&zaJsJ1ց08|!{~>wG 9(w'ҊvRbG&<1ۯozB:1x'w>dj49ӥS֗`ϵg֔`M .}kfoZ0;zu49)EL6ތ.bc'9.IL~ d(hqIa" Nh >th~n(qP~zJ&I)H:E)3HHn9>1.XBqG'<qAn(3C1Ҕ( C@xϽ&Z G/N(`})S&@$=qIniaqړ=R4gi; ]P 4sBq.78H2ǎ0hS 94@9'=i@ݑԹN8sI1IoAFI\3Hq=p)79z{\`~k9G|@9hPsCR)0$›Q82?~(B04"ҝ@$3_җ*LҞi2OPsN9 ph֖i7c;&qABךC20=iH c@JAse3ކ1z;IH,4uhNɧa~tïn);Ұ`fjaC(8'4|4XiL BARSnimE=(dԟʔ($Q\zzR#8-9xJwHAHb By4p0q󠡼\<&y8@ǥ!廊ZQ,I=(N@W[M(ZLRƋВiip'C.~g`֋g-Mc?Ip֌KFE8h䏥/QǯҐXNA4si&3ތH i >SG˞J`p?Z&zL.$Ss /#Qc:\QF}zRp:QƝozfI.hw4N[ px:QyCZvhw>&x# HH4zc`IA((H!JQ84 3L>}iI8sIԀc9cnj@r8ڐ}h# R)?Ȥ0$rZiԸȦ) RqRXc;NF?dHp94uC;P8 Z^41BTt)yPAցX9#'=4oP8vP=qHX_J84@e  'icӚE;<ӽ'tBWg>٠ Ғ8 \t? $\'Xz4֥P=.qrO#p ?!M=J8zP/qMnyT(Z9Ҕ6({VvԠq@s/_ iXk8;*zuGnM4s9ÚNI‾\]r91}89 ӈ4c< Ӻh>BrM #9K8v xR )wr'`'ւ=('ց8Ɛ{ƐpqK@yzF0sHW PHs ^^!9LvTRyn8KE4`΀W7~oj)vR1A"Kiz4h(җ4\-CIy)piq֏Ɯ @! zN=h \MaS7J1(cB)~;t@>Ԅ\w@!@(8) (z:c|){:RSJx2zBԇaS錚Ap){SO<`f4ޅׁJG<~ $Rsڔt9@(A74qz9^G!'sq HBL F0h~4pir9sHI4)Hqlҕ:sGN ` 3^i0<#֔{ǵ` ):N\RHmx LqQ)r;g47qHA91)8LSt&{r)F;A PHqF=bH :sI)CHG9v =җ*APjBҶ=ޓϥ'9@ޝ8c>osƁ 1P}.y#n  j'4`.0 .824s"M9)4-Dğ_j\x$zupM/Qڂ1L[3f14qJLA4sH,1֗=`c8'=)ÂjiN vсM qA#pWךqR r8b㠤NxRQSɠp;ik@ޜW'ޓ8a3Gj=:F$( '8FORyKb$7`rAJ;g$P3sSE/EE@"3JR8 zfgq@sF=(V?J;h@`g$fiJcw On.84@#4†4@J3@C6AS'84Nixh^ڐ`=:;QK}h|\8=hsL`bf)48hF} ?Jz;q4H "&GJqۯzBI){ڌc11M.M0pi(&֗ގF'&rGZ@ )ϽN>OҔ׵'(㸄gTqҀ\]'Z^q?J4BOcӮiHr) vސq=1ց/RO4qZn@=)y?#Zau) Bsޓaۭ!bNi@ ֤8i9z2F8gzn 0Q $>u;%OJ@4 9#LW '#\яjᓎi1F?>#h;s):6O;gQZBH{旯Lki~`)&iqށ9)$n~r?t@v$gN0A)24sڐڗNh~ԅa6GP?::dBR=h3R`zRv@!;*>aJCsBdpXhҏw`uj~Fh٤:zPc7@8H(szRzѵO>x֐3s^>bߍ ғd@g$і uN{◵784`v;C`cт#tFq)-E !Cҝ4= /(dzRdzK(IJ\ΗAƀg N;RdPEQJ1ԌhhӊNxSt`hsQ@!=KryAۓF2I ?)/.84cpx\,7)H(CI@!:P 3GM rA3}:cBt>c8KBҚH8=>iøj^xL}&rwezcVjLP=y4)qӜёJA=Hr01'(dEeGz`:u=E/IǥI|ݨh!qL1)RS'zR@I^=i4H=84W=h1XL'F >ԧPdf֐a_z@ryAo◧RuA{Q2}hԄ9N8'JSbu9QLH,Լf=Gl $dƒ=ߚR;uϿ4cN^SGNn(ތOJ9攐q@JR1N8ǵ&ib=(9ڂT􄕄rr1H|'QL}h@}$9b8?!Iq4!2)V4pI)ppiq{b@$'-AixƐ'ޗQJCNy$3J[=~ul{ߏZN—ԞiWGIڌLS \u4tzךO`4 ]͌R(qɧ`zP9M&=@NAG~)[p9K1QJ4=/֌z@j!3;R`{ 4s) #4◌vi2P=R4u@"~۟JL@2F[hbhdR`)iq, 2z>aP; G`ҋi4|zR~J,!TQI旦s@7h9Sip8C7g4 !Gў8Ԝ@ 7=iIlAsL (t}H zP@8Gc /`q@۞h`{qGmHy8 R9 cC}r~ޕFyzミZOҗ<;d m FiHnhE7EIW;{P2.0<ސ )ӽ&IM qAcԌ3; 4>4 ')* }=4֓ -ցPs)r}tJ=3!+-g'u?<;GqIǧ9_Z)МA4ϸ<WӻA x=F;ҏzԝp'Ӄ-hۊi Qӭ7v1Њ!8ƓPy8J2f0>{IO֗,=8=Ft`u J1AZц#AȤtޗ8I֘I>;ƌuhh?ʎwWe@㹥Rr0(=RcZCP;Fx<'ZM@=qR)IF (PsNL␚OZ\ ?hȦ}r9>^ۏǭQ^AQR ')y@P[HN:H:q@ sj@LsK9 )v;K^NqI89gIAH}##F9O֗:SzqځAϽ1OJz\,2XZ3۵4Gq@@=)9`Gj\?*9h tRc#.M34zѸ)z4!VKhh4|'L~ztœwuIQhB~A֗8p8 IBqސҔ'什tduN006h99'Ҁ@Hp:t ց ?CFI{rM)=WAUHA'w^R1FĈ8RR q{WNhڀ;Rz@/s@3ߥ/FMozLG8`23FI(ӥ_JLdqHbuьtuh<(>ԇ}:1iy43O(a! j\^O ӨlS{=)&i99 ~tisxVAix9 P:2=(rh—94O9Z7n;Ғqk H34`éK@^=)1AG0 hp('$t0cwBQd}3@yT7&9C֌8&ϥ=Н8ZJp#+{ix4i1掜@t f8J.COMǩ I'ցBp?JN=ic4 Re@ 'AҗP;DR~4I4qH$~p#"-/@ih4=h(R1M`Mi o#H,sJXcV?aqӰ){Q p-j\ :J= XhӉzE+P(^h8>€cHYcӑRK&)F:^r3Ҁ;G3ix4qM0d\ӇC@`c#)!ϽCqI3KzT@ך:u*y=E='Q;F0ir:S@ Q'@=M 9H@xI旧֔(sҀ4J'֜sڐA#8“#&ZR:zJB}1cnX.!;x99u4ӟZ0qKi?0 tZF=AV@E2x7b`FOqR)>WM!OzR:s H`'r)2IԌdSZ9Ӛ1~t`R+XBzqIM+8J9Nt;zQȠi4S SN3qJvG\ҒpiGJAڛӚNjP H$v4 Q3F4?@!9;i894csEq4hzҜ(vHTU{u}O(8(<ҕ*2}IqQG l@HNmP439e QqeR).&G' 88ʀwvd/ZEiNNHԋ۽mޘ8/42@4'z@p1HP=DhOPg֙#c'vzҜҎGҁqڔuq9}iz qx'CA:p}:P'"{(R^!1!-.ך^Sq s pi 4 =ldR{S8 z!ăZByK($b7w7zA40lЀE?z ‚;J>Ӝ4dxN)p8vKRrh h[9Q48@ ؊Nis4zZ瞔 q:iy׵*b)8JwS^:w>`qH8')X &48z4җ#=@onipA=;P}@H1Jx zSp@)p1ژG>Qؚ3l^rx 4)ךN:R=GSփʗQF9眊0q CӊQA'\u4.2(٠Bt"1Kj =c҂1/bH Qހqփz1>ajvs簦}(OziwJF,:)~ǽNG/P4=h@P 8Ͽz8jL.xbn;˚L0QZn:$qGQFiIҐ43KRړ`=8)iqC瞝!'iy LBu ic@E4O8@IҜH'4rh!9JI1i^{QSG׭ fӁa@4!`G~ qڌJy $q@q;>mhⓑsJu 3sFq^q)M (# 拂b8<GAxRqM}(#?*MSƐ198{^y@%qI'=()Qs=G4_J 09Z0ޓB8: :CzqƘCGJLW4rԧjB=z$/ˁ^eF=i0AV+`9&0)2s&V7=h89zw4_ǭ.ғ~SNsJv㹤v(AzR,4(ߥ8CM#ҁ/z>_z9IaH8dc8&Drfsz\qJ?(bϥ.@rh( :Q>r fZv!zh ^Bғ'`gOc}(؇?8^s҃*#NJQFG" Aa Q|az#4}).N O;PaF1Krx=(B`&2:qG<8֐GJ^}1X(h?^94^i;ph<HE!E/ t~t ތ-&O<`q X/HY|<[o1km-qMmiz2`bܩhԚ^ џABsA$#@H4sHbRt/hɥq'4Iu}OҔ.8y1F1>PJq4c-ޓ9@t;g h=GJ?J9)#=d;oĀG~Kl+IByG4X.~`2(p(@ c4g"FG40hsN2G.GC@/qJ0}}(9v AH<4ŨvqRdޕTIn5h 2OcWi#62{+mȟZѵ<ۚ?"H^#I2D} y3`sֺχ61\zٍét@ D&OyJ5qfGKSL?Z;0z(~!@AirI(߭1vɥR9'.p?JOC(zR|dg8L)H9⎝ҔtR<@93J2zva?@⍽@Yfvh@M/O =`@m@1HA?AKaӭ9W Tw9.F}.cF9#/4gdfH{ -#9)wbJH{ӹE?1۰qIS䜏GSJq0;PFH掽huڛJP=;HzPsɥ:4b@݀=H;Ru[Z0qI)zw!cRXJG z {ьu*TsM9p(lH9&2O=)iIzsIiq϶(:&pOz3K{QS)n&}֛#={ ^FsZNM/i$P Px tޔJ_s@ ӑI~;RW9J2GR>dSBiH8^093N0{Qir9ⓓhj}#ϧSK8Aڂ6ZP(}@j0җ Fi09=ALZ} I{ ALy4vפ-X1ߵf| i#?ҕzF1(3sJvhp(#Ҙ\)0r}qӚ`#֚{S=9IZW&g1Q_Z(hɠʔs@ xA 'Sb0)r=hqG8)2yp2(=i=zzRc=M߇4<ґiluք& sғ=G4P"} BH֖POZCG11hb? \d hǠ4݆2NiǑHNGzMP:f &8=L#piFF:S A1K^O  x\4tMG40ғ8Mds@as{)ztR")8>s h\J^E ݻ9@FphaF~)ҐO'4 K@`9jc>9z88/QKr F1y8ޔߨ@s{sJץ!z9#<z:<484}sH4z7(Qʀ܃$ZLgR|JQߌQq@:ҝ 4X@1ȣsJNy4 3q{v'8J}(v<{Ȧ K'sR4e4ⓧJPhm)'L&Ai`wwuq@ N}3KF) 9E8uu; NԸqN Sڔ ~NEtAϥ=h>&3ۥ b 4 '!s4ZCϿzRK{R(JN8:sH >ƚ|҃xZCڑ7A>)y#?0dZCyc!zO8^});LL'J943L9~aZ<ӿz}gԸԼJ\qqAhiw.[ gy8(9qF3RcZ,ގq})6S88Ls)q7 )4 ;.- ?*3KhF:#P9 ю8qր>zE AEx=0eaQۏzڼn"4BAIx`FAzUZ Ǹx3j%HRy5v-\GpßJ]ĖZnQ+7.FAz4)J4~=i=)y,b'Z3KBrCAa=HA`GQK(\瓎(> u8ɤP; OƗW F<qFzPIҗأ擑ց%}zRRiN6z&,1DlʲsV@c*ZYEkV$1s\Lj\Fmx(O5Ēkzoq~.j%jSݹ|U>;fC^05`S#?læ>h=W+*H.T#-IҔ9]'I8=i=Uey|1KGՐ@ QnJ;ׁA!p:T:Q\GzLqHR擎)1ҐwdCIҝ#4#"`8~sޓ ^ 8)I=Pyovқ8 0 sҐuA<\? Kpi1^h邼bxIp_€89Js@|xr}((`qIKGZ psJ #!ҏ"&Z:vcyҎ9 Nq@8ӻf2?*Pk`qoJ #&9`y=2h9($␁JH jz1)HL0M)9c4t=h i1:SP⌞Qڂ;ŪK΁oj0{N3ҁJ1٠q.gR\v&8M!Adc=`ϯIҝdݸ1NOxA)p:nv0N( ;SHg$$c >#Fiz8,'`s49*-֌cғ9J0}?V.q i$Nc&BdM&y8r2@@KP!4 _ǚBO| siH{ғϥ&M+ G=)Ϸ4=1K@dJu●CA.!OҌJ=8pq$Gg$zR}!1H2qR94I1XAv9a{҃4㖡aߊNh#g H#Nh =nAݍExǧ6F8j@njL/OZC09 [K(VڜÀj#TXXJ<eZ0&nGkF\ K`յKe9%p^~,m ЎVPHzQ61+к{3qҗ4ZdK`Ҍ IRq@1hz9Rw4^j:P; ?1JG=(8Z;GKHO@@=3dzt($vw)sǭM jQRwIi{qH?@G;4cF0'?z\bڗy#)~ ϭy&GN g4cZ;g&9(}o9S &}iNs$R`%E).㞔qGLR@"q%ql~/>PbֹNO݉*rл6` s|ՕY-5|) 4AefIqU;,m2*9s[ IeG*n]6CqnU6T zVOVLEu+cepM%>H]Qܱ8O\2:Zq7H 'HVYYFz8t?*Ut56FVIj&CI0?Jٵ?-FjuU@FIHQEHLt 1jX H7nsK@GХI k{w( !9J[:po]pNʼF8d#5zZ L <I\in£sJK2K! +gO(Ȕ_cꔥmNuF;+9 0<Ji2:G 9.:b0  r?Z08LO֗4q(Lb4c#tZ=PsK֓zCnO'4=)9Ƞ(=Ȥ&z3 &\8h `?ZQ0b8 Iӯ\Q>BW89.8h1i93L)4(8M+R 1ޛ)TNc9‸t)zӇdsw4s֔1RpI 1眚A{IG H2: LP!F=(8)y=)? L;ҌgF<LBBSgzC}OZzAҗJ~Oh0sJF8sǥ@W>@׽&@Ƞdz,p{N 1J1a`#L:1HqR!x G=N(R2s`GѴcҔ.-94zҁ)3Fj02)F{ޗHsLqۮz8) hzPߞǰGQzq"C@'Gy&p) @b&4 \(KM郟Zb`Oփ4dR`_Ɠd}izRwJGp)Nǭ&1Ҙ wf}@ޔ9I @"✪ǁI9(^3#KK;fzfۿzJs@~MpWKBqM\w@zvrEڎ1OOA'Z^ONF~;<©؎c$miMGb7r'?L6NiqB*8=`$pqt~^*+,lCOZשh8[H'ДM'X y!3]NeQlnO7Ajjd=;$Vhzw^=%ץC:"=MI I#"lҖUiwēL\`q1@(zoa2vKDCc!9PrG5H2p9W?]ZF`@:VK4\Þvc?Jsa$=yd~2O|UG2Fq$(!s)k>$g+dm8u;0|F^qsFFPWtR>AF{f'!Z={z`(v9N Q4`azM'N^qҌir}h1'@ ÊN(zt=G _SZ9 ARA9q@ïlPwcbHB gߚ)~~Ǩrh?׊8zQ88җqP 3iF \uJsހhi)@ZzN)yh4x3ҒvgB`Q89KIz;=(;zP=&@@>0F1׽y=j7m&SmQ$@|Q@MSR*V73z+dqNk%uٞ e8ssvR<eHYK#F^xX"s#`^rrSWL+c{$ulQ'?º /kV "`Z[Rtur+܉m%A PZs2wŃ[) 8 8*>G*3E8#5k \J/gއuCdW+m#@%Uob3%?Ϙ 8,6 ?on$YVLֱyn#ESdΎk+ JU;p*^[—VLdG]eY#$ Q;u5R?d壇b5't+m8$͐ +ddJ0v="ipn;l#V.qLq;[;BGn:W&'.p^r*7}jtz5-A04Aך澕ɫz Ũ# 5ł.ׁtwz"422nf\aXs'e~HQA}.7rS0ǓTz"z@gP*[:L97 f8r(Z+k+0pǭTJ?Φ EN.Fy5sP(b]|YO`iAg41}t 3>;>(`8'ҵ4I#lYw֮@5kC5w-ڄ1  }PsDxɴb̂,ƴ$=+NH؍ѱZ wC4JASiPGdNԽZOK{`EYÍ0ȥt/n9u'L@[QR)84 .8h JF84 EҎriA4!F9gL4H8sI9 L(zyCޜ;M=ayд1Cy3=#dw0p߅ELCHF9)~SK4#$v#҅8b7-֔~Tc?4 x 9L`ܑElsKݨԓBqNy;f`RNzJLg.(q;Ns€dLґNIO΋Q:QqF1ϵ"ăiZvuрQFc}E<+5 3'${V2.F%ݴc,cg\kk* ۡ5t|-vi1͏ʲf.2I=qUNbvJ nHޢZ[̐r e*QE{uey5-`GZR]3To( ԟANcu%pw Á6$Kds[:ZKw('#vC<_XZtй&$8}h4qM& SQJ0lPv4!Iғ84!ցAۊ\ҁR J@A`>nS H0iԮpqJG-sj@ñ"K4\裾H"jM Y++U5i0!YO"+B9=Ywݎ'(fc\xs`VΥ5ɖPp@ltT5&!"|uxS%1}mXl{[_ÜgV.svBq Z(021\ms@mYեurAI Ȭx_<唵Իܶ*JdvZMǠ\猼6Ť1BH S`t?O3{!6v׾&l[dڧYm|/P^Jo cYбMSW;?͜ :}=kd>c.I5Ry<}*'m I&X{YIfIϭVyoE"L{V:,hsO5POqC nliPx5B8ySW}@ ɨ sYʒJV;;jogi CTtkMAuE#/doSڵY"n4*QEh4@]>uT_ {Ix-Z ,Ћix|Ojɻ]]_PX鶮V7Nfݟ/JH8-"nȩe R5]$ׂi% I6ea,T)-դKT'M6gzO"z؋rg\1#>\1{U4xޙ=}*.ؑtq+ -Ɛ < ]FsMyHV(pSsKXκF`txė }*W9zвܬd^kKZ$-ķ 쐜3[1ڕŔƥHV#^&H&Oj瓾ȫ|ۄ|dvmj^fqW< M1_3iRԥm_=z 1 $7ݎ9j88=HeDb`R3ܢһ)l zSGӭ t=j1ۊN4=:vt(3HGaK@|ߕ 8 @ ۊL=iy4| h.Ii=J`QL99?i Q~i ! hzR84GN.GN94O4jNhǥ;x88@=( i2!X1OAB ==8E)HrgZ^8ӥ+ Mƌ`"2)roCⓞƗ4p>)N(,)[O1; ^ \R@ f47 CPy4  n^Δ ry6 {җ94AF} /E!2K:NF=)j\ p0hEL>z^(i<`=Z;w'ޘ:[XtoWe1?{.m/k2~BG-Y쎢9cN8f-X2O2B:(mbQ]Ъ<[O賷Á&ӳU:(h2P&4}9BL,+ys{n~+p| 8e]U+go^;WO^z{٣-_H% j^%%l-ҏ0aN37s+|櫞H==؛i-+VF-?M1Nq\u+fɍb@5}}sw+K$cdk7Re:Q:CœȪl~P3p>-3"q\O8H7ޞQFnsj?KFwZǭU-dTI]U^+[geOJg&> P~Oa@߼|{v`_I3ȅUPF=7u:6P)8 ߯*Z_*n%G_zIV$ߕE,"E4┵&|-|5w\Djt>r2#g֭w,n͕apZC9%=)#%4rIϽf8#71کSV3rfƙ9lRFjޥ,7Vo*]Ts= <'?[+h}&PeE6p)7N 6xSv%jH<ҽN2>&oνz_@^WMicm\NŽ:Py9sރ҂cjLR8hz=. ;0y@A PIPO;+ ړ;Oz9q RޓӊVx}(<:3'ށ Z#ܜSlJ=c!sҎ9SK0ޗhƅʔsG͞:8 yhHЄ0u:rF8`w)xyJ"Rzǯ :H>wK+Ir(l09@ؠR@g=8G8<( 3A {ڃZAc9;x\x\pTdy@ߑڍ٠dvN2OJ,7qv}Ұ\obE!=ZxlZ] 60rrJzU0 Vls@ ( fUQM'9QP\MQб' iiu.|pz0I Gˌ2iۚmZȫI_c˄6zU lE5hNR8>Vn~@U JDkV)KAhUY6zbyhaY1ȱJW)i³$⭓tHƻT,dfR)P8֒~Dk.BUv̗eO JٹhW |(Hٕ>ՉwxJ%O~a{huNu/v4C$BM_HL,Ƽ/<̄սjeMGsuhLhðAoK>MĨ-Zp ۶fwb0 B7fsoNJV;JrGi915JT /SnjgތmJ#7o(YğfƲt;ye@"xd1~u3OŴX'47֢Fx4ⷱ6D 䎄Å8>\p;uN؍shfbJt'>z4ѐsNp㚊Ur KOa@В"@w: Z6`3ڬLs3PǎP#\BAbL>eӽ[2sIL3O%NpMJr٦9M Y{ҭ;+튥. Fs҄{UeOUU2O#Բ.$Ҝ+Qa`u8=ZMA⤭BXP' EK`g Ԗ$j,2bsS#IK9dc=ϸ\QL9pP O4 4CtO"}J9=ĹG`=8&);Qr/RytTAVObM taCVeItȇ\HÆϧ֛}U,)caZ6-d4J = ֓rhBJM:8ߌP hA {9?z} ϵ Lt/J}sIڊ+\Q~fq+'=:Ӊ)40F#Կ6:P!8viFWpȣ CKJ5GP1Sg"'(`u,OqGP=1@q@r(sa4uh.!QG\E;1h&=)>`9ʜRGJ.;  aqB֔ZBL#Rc=qFF{Rs? pxS~ǽ(=(uގqތץ b=Gi{p8 h=3F֗4 ~T@30)ʼnk Re(sN4s*D` n*QbW? =i9izѰڐ"3ҐQK apjhEMҤ+ Pq2w ~UbqWE2y?4Q?xT Az'/i ZQ=#9iZ}KyKBvn+hZ2FAWC5jnᷯ m<Ύ9%jqg0RCdV}_sc`tW),%Z9&BIwcAW ʐkF`p0Kx*D<9|TJ} Q9n#R֩i7Χ ݜMs+,;p:ְ{{YD)6ʌ:,qT+k&;L2޵.^I9v~t Hޡ;'c/ @Nr*ÜyM?'M` 9x➡^=9zle9nF#>{7s+!CUkcU"aȐU d`UGL` qQ< Ԧ,908ՕY>YV%vo_{S& 9 (Sd9J桖U'x\ ԅm$<ҟI4&NE|g5|5BC\u=jm#pf.⢍_9-`_SUPsB0VVB3Hd95i@:znZCPjW@*j$EY8簨vEܣd)C0Ndm'L;ںT"ϕCv 1֯Js=JP\S qMsJ̣zR5؂ >/Q9JJy`r28n{{NG&YO)M[~oZqzt@7yHQ*Gj`)>d.O vqW& ڿ9hl^hC|sZUĦK(߄n9C[VHgb23+VqTΛ{,3~_N1V6͝VicilϾm\z6x)u MGnFNG?^]:'\7sw"\ZȬTyi4a%ڡR`'YYmd$vݼ{vr#gy;MBұU$A0hPnV)ڤ]pyLUbiCڶೳ)2ajUhAZy:B6ZRAm =P˴SSJɍ݁Z{M{w('+z}ܱu U؀!WCoIfB9QJ14F,{T.lM Mk05`1B8#Pc?8m Wԝv=JE x2Z/ xkf)Mcf?a*mjw#FM2)cDt#*W?޶M0\`=8IjSөmQiz^Z9)8pi tQE{`(Gzs)zm␁ǵ;{$GK)L0z:P2zюR';Ƃ>Q9dA ~4@&ҝsH;'8!}9TG79@zqF41J\ t9J1= 0`E/'^ @}ipi99=hGOJSQ! c!.^(9_ƀhAя :@` hbzA >}NOC.9#0&0O.8i9ɠ19@ 4i< p1LBO8'3‚8x97#hLAI:wO=;uҀh>^Œ9sFOjbAN@$1?*O 6 1Z\/>mZ. =G#9J]F(HO4QH@\pxK;R}> Jp:0yMN'ba:Rҗۨ(C֗1Өi=(㸣9434 R@AF@@+Jls>R=QaiN:O@~p9=E?Ja =p)8Fcm^}(Sѱ JN փɦ^ǃOJmNi2֝1Fǽ5A9(a48:8cϵeR|)߽wmb$B1F;Ews)Kl*9P i9*+>ڑ2G**qY͗vsR|!P`(֧(V>j5VV}@ﺤϵ7*iP rÒGJP*F4sϵ$#j+5vtb$TdsI m i)gJLt&9?J֨Ng{!ܒR#v#QGHfG>4[aB/± cUqOsC*|'U1nRFJԻU,pqϽ&4BU9es֚/qցт1Z21Hܒ@#́֙dBqi0؆nM>ӂ;U8\.Fjǜ {>ߥZBj j$0LWc銞m}oj="+b{jcn5:܃Ual1=hNh@ LzzFrq@lŽ\{uT)cMbpJqǭ4l2 #a"{Q: qJϨՍQsPQpp=AU$|gTLg5F9Y'sҲ6siqޡsJyqfhwR_ DtBGZ羆ì 0%Sj2QO ֜W"85dG)^Jl$v7|I{RD\TPAHR8ß9h,˜ZϺdeU"C<3V3@ꌪsϠ J܇/iI=H89Z$WQ(O S 䁶{Pyn'z&o[.K џ΁qix=4dQ@GAJ>n4hdPbqApF3CPH cwhQ}(gޝ98ӌӹv@\R)#z z8Z=҂}hZ0(^?1L~4s Sɠ:8{`ҌsLHwzh4u#4{ 8cRq58 7ˎ)4$k1L+LFcM{S׊iXb :sMf_RYIn>Ѷex#Z N-B).Cv8Է)6}?aH,Bjlc<}qPM> Ra钿^{6j6SYNVe=kufIhbnL4d(Xw ބR,HE8TdS" * 4 R@8Fi@͠Ea=i&-HwU_,c(*B z7,q~5!Tz<׵XB:ӰW PɼW7x#,#DP `\pIGFn=T6鑠GQ/> t]iJ*^Ԅx>Ϩ˭'ڀAʎ;Fiyu`89'#)) G4Qߊ.'>Q44`M)x=B@cۭI1JsϽ gҗ=h:tэcP4!z?΀gExGv8g9J uT8=-g=)0(9)Z rHTi"&:S#H7NiDg ^8SMѴ0zLWr)w.=csL v@.JrHC il:.G^jdtz-# V޷86YָI$WXah$A[Dc~KOSl۷,YûC]|RD%{֨']ܩ`39;5b氮fېXjlM%*!Jρ9m =a $ޠ@΁N8$ pN#  ؑl\pj @aaSz⠶\z:Ӹny݃T3F\!$wQ|8zQ`D&8N)m0}AtK󜚡ִ%Bjs!'Nvd.@y84r9R88T;7d`wDT+T!_mC X,69n3sOMj~{(1wv ! .\gE݃=3N\zP!=і=/Aۚagy;R)Xf]zӠlܝzS`)ƃj e&|>j>Xڐ;$ . ZIշM:(ة#?%F3?Vn'ҪOZH't4K%9^q֝o'4!۹grp'8WXg@WV)9FJs.OQdGl(M%?h Nxox`21OIMD3cOUpNZmc\rxPSw>;Rgj&x)yARx'#99ќt' 8#9Gt (FHqHb h<ӚJ)HG6wv:sFEOZPcQl5qތ€T3`ϭ!<)319R8掴a҂ssߥ;7F9#=N3; G(1!OA悧)sJ)9jbsӵHi@"Jz.9haOJ0GCJAȣ'!rzqApM/(ubm#&)O@((Vǵ/\f {RӰ֏ }8Aԅa1{QK:1@T<ڗ-A#ր8ן+g=h|/>RNE 8tL`;N Jq)8Kn(1ڂF88`~4AO=q{R2OJ)?H3ҍL4zS-GR*@Kf2)裟jd x<ќɥa؋{S0ӥDO9AXA0yrj=CRz.R &2zRAmE9<|6@.H#b!0h'by: JJFՉՁ#+/$?49)BAdĖA*$`GlmT>K4J@&:`En1BicR)8I2PÚC!%p5m d9bH|M#/ y8B7J]Km.Hv;WigZva}#nHC7\u@M V-g*02UB H9i ȶ|5eAԋgunI2HRzVV6{ԱyN8R8EIoLSD̪}*3dR AsOR6 B2ia Lv#pC }=q X߅,qOjL7R>HK*K3y3£-ҋZaSFFzvSI8" -P'YBi6k.sPųJI4ݽMW*.t&<ŃyfH?s Gܾs1xSc}ŏCQw.!)r9OH扁b9{r'' H}L'4Eci]?{"\-bXK,45WecX+A3O$ r:QN^\ T{Ph|innd{+芿szN$KԕDapx?J,0K-yX'ߏZ[4H$9Ӯ%=9'`q3J{MqF)XA֓_ŽOZBcA'ZR1JG4ހ`~Fi*2;Ҕ9TfԢQ6pw(EOBkXDQ6EfȻma{kBFV U]$Rye-tzVR^xFH(&N~+)K]7zzq?& ƘX9Ry" 8HH Ap8sޚhtֆ1K<8 hϵ.:Py=i ҌJ1G(0zP99) @@ցfqۥ}1F8֓ z ,֗q41sR08M1jLdQǽ 22M@XL})pLc'j\F2@!#I~)Bc@Ҍӯ(9ҁsޚr:S!^@O GOz 8vgZ^qK䁌Rt4}0;ua(z RP+'4'~4gz0RI8n޴}~.scx~t ڌgԟΔ=i~b:'NsJG<(үL֘֌g—hu3rh 2(9 0`Oɢ[()Gm4\.9!}hR:t4rA\np&HilM~ ! ' qF1.֓4\R/]/5#n+'ڣgHN0(!4!9<27! 9)!uj &`#nx ޚ\@\z S jҩ0hܷĸ#aXF eY܁,y-^ %"R"Zkk2wiv(\pH8l;B1;qNeu02]qV;`STPM0WK"LW%+_8N+6zV) @銌?&NނzcirHUfP>bM;#v 2|ܧ(13Cy*C{ н&p9HX<8`:~}yc، S994i8Xi& 5vէn} QWdQvVSr|K`1hR+69*A&eȸ_^bSFC=S:\{S| 3Fq p9cڱMj fkK}j@\j%C=CbDGBFiӹ,$QGsz":TxHIwQ,cG3Y1H-<)6!Yr3EF,4c2Xd%0EW $ze7]N2F8HTm 9v00?H'?jR8݋9 r)?ZA2Qө&qKV*d0Ӛ"5^ENh8 @'g$ՄLdwfRK*jV^X2[v)Ԅub֓('!X &5]}[Ss;"kfaus+n_w}Uvo$u$<^]J= tTIّ #=+ ]|2# kc$r2{ =-$ ȅ9OJ2u֥l7HY0Ǧ)gi q!*uN:TVm ?8iBn B6\֪!E"` Ǒ]>V x2뼰4,wav9''c''"ךLfjY' t:J0N$`c=a&Q '5jd^ z=LZK7"kKȪW>u۟$Q ~ªSHaq+6]Fsq#Lz2fJe{)*er3v+e$dUZ5ԭmq8+]ѫaG+PSѲ;6@]Is#B=O nJmP:L"KF#Ë'<k3-b*k6bn|*&=7K}2u!E:t(8q'R_..>S׾+t|Ч>esQqvaLPlRb ](A4 PRgԔaiyR&)IZAp(x&}~,!'\҃@ʀ҂3N9&R2; L7aC<ӻ=c"H[(E'403FMҗEPxgN2A@ÿKfmy ܆FW*O}fy$U'I^&جBQZ(9nCF8>ޘ_ʸyI "+XH~}K`0ud/'4䡈7eԎ2*h={RmUv)U&$¢{w?(V .Zz*g`E[um:$QzU+˫)<%e$sY!$ӕ0) ՙ:Xe+*zfwPڮȧ=>P%I!}k,#(T@#JPsjq8=Ҕ( ъ>RgH p8ă q`#1;/3\q*:#jte#bKp|7?f>D%SO=5@kQO@G e=tTP$㑓ǥg2\;sT  0 ;8:892>[RndHQY7H8]ɵ [r$n}h-ϸp@`)&0Z48wwMvKduSSF$ ]`Jn+nȯkh'S;#kы&ъ}s(\ld`yO62InkC[T, *^?ui./_b:Ukbڋ}F= j[@|3n8bmxja{W!vEcvKQwǾFfm GKŝ&#`su}ms !K/o^[@SQv^}Ne%qYwOzub|ʦ-ǽgCk@Z¢HB<'·Ӯ4ⶆaOjH%Tm)^-,0'@y>U$Qد9Fʩ:n=u{kL)GjŒ{۹ZC lwrXIZd=lp,Vc5YnⶆI fu9n瑎+DȓH7 vۢǿzq,i ΊwRo$\FgZ?:G+5k=OsJLiGj9oazc֚ <{Rh{)!)OQF(Q4?z⁰KN::4u01K ,ZS:@p/lv4@3(xځ ׭'(hv'\y+(K֐g9h'h&H"Fnr8q^ti0=rp})! P;qAqɣ$\CANHOncސ`) Oۊ#Jwvvxw~(#Nz{v9p(GPt~iJ ) 4vRG ujqϥ qFEj+=;r߉$iOQGO5 0g퇃)jǎbp! t+:#ir*TT9z 1rOLuPzt؋XhM8Jyy5(19D*[ң8OҥlR`r@Q:'4$Pƛln1zI:PL2![[A5˕,Ǟ*;ә%$PݐՄqG p:8I/H;OzLut1 Փ-\I#=+5 KdsWDLW%~5H.s~ DzOd%%c^E0ѾsQk*K g@8?S] D Ժnۗ7 SX(qjnmY:XJÎ{zufX"RpIz|sjC$v̓!s~CHOWs;ߓǦkӵi"by~*έv`T6ԟ]5dP]Il&#\lY\<]&-6WPK-Ql2'kmEdFvr)QW i;I"iOކ#fOfفcsI6b9'hjA.Ib@^g ]~}q9]5mmP36UhrɒUxgh:0wD @mTipT:N:SK6rQxEQݹp{Tzs)=MVd:dGJ.巛@XcW.В2J"ORљR,dTKzXzv4$z!0v4r&H͑I}9cϧ4.sbfDJ`?: C iYWG(Q1N[[|ik~)-u:=~Y+GKƙo4 7w!\V6 K )-ir-N_Y@.XYx[:ĂKG?"**[Ae7䏗j 䜞)FI th$ ϭ:AMGWs@2yD%4榈/K"!9!U$*uQ8 Ql:rHV&LG[qÂzc"m9>캌ǩȳ)GlFS$\qN$2{MsIXE5幁Ln1]OϋoJqXqVCMPZY;*S6'ӭb$Iq}3W n#я\W?$)Ċ|r=HIuWo(Bo$da޹dB'YMř㢾WBI5dUjmM@8TX͆t&$m o]MeIޣs894jW6BwNzWMmxGկH(Yȯ+n~3#v4vDVw9צ;bX 9^qIܬ{[%Gw塎W񫨬D4̍#d<֢[$J{sUn%lyGD( lk^OV8U[ޟx~zq1YYY9J`|1̠B9YX,X'f]o\ 1+7?x-B!g 1V2UdWx䴁-7SHc2}MCcLTc+. ^[ vo9c[yB܏@B0Cן 2)]>M|g3~E L N3h+bRߡ{()R`w¸3ڔ#2}isސ1K@!;۟ҌfR3SCt)'?JPvj^A8&})z^q@#1L0i{qK'\Lw(}h>ށ  S 4Ӟ9ҋ r(iq،ҟN\,7Rғh4N R Pāf ?/@\J1N~tpϥ=2 &Ν҆$@zBjw#"{HRZzC)Zvr(=(O&``hт:w#Jd&#ӦhwSxSFN)@8Zx`8S1<7OJp9ڐ*"\wM9I& [J$n=9Ɛ'VEFy5apzi)nhF p~MXhSR?FzrxPpyLPAϭ;n 4рyT@J ƂsHxR4 "7>9Ȧh$_iXTӚ8lZ3% ~U7['s6!] FI >gUlwnO4ű!%Fsi܀EBzTBWR 'tWRNG:րw1ޗy*rr)ꠜ2FrG@Huk>ʑoqڛiWZ! ]2fm5X3H1҈kK<lee|eWxXnY'fZ|Vs$F%۳ы97mr~蠵vTy9t 8zX$犰F:O @;W?,y9 vK'sGZ唕Sj@88l`cֶW!I9BLԧwU8wV+YN1!NzcM9*"X38#gϵTg=DZ UaM.OCTsIhaV@Rߌ{T3\v(GzRpr4 W%Y>ldiY1zS0RON))$i1C(#09X̌dǂqҗ`nsJgށI9Ǡ$Wh'cƝ$9 1dRdHJ@iѻۨDcSlڠt+kՆ㯷ҙwNhWV*+1m\tf)9bT{sZij@gqbnd& "DSvFf 311{V^$}k2/9,[[-A4ԓPNzԃ~+[â9'r{qy``ԁهj{Eg][qE#'܊^!WoVR7!$cnp;}k8E`lKi$KL8_AճvF +di2u;C-H-ʌ>Lf'I ztZ݂pǵM%VVLyҥ-v& s׊e KC 䓚+-3INI8D mLCKsSQ kKjLI@Zuo&o(INO^Oʠ*KH>}4܍g 2[h >Wiox KeAӯZ)FI(ߴu^7CV$UR|ȘT_ S(X Tu1*8$ 2K5q,16#=qU5$3l`gִ(chZb(ˀ8MnK8`bS+8#hEn}YӸz[ Nsk>\-E} x\_Csb?vKcyr[Iڲ\g@>gʎWIM,1;R:}u s5_7}< @"T}:S4q}9GS:3=;S; 4Е*AQֽdpIYc}Ѐ(z\GALh(h >!4.sLbg&s҅>9! =i1҂@~# 0K9Ґ`8{L`q`? B2(?v (RtAHzqHh828E`sҎPNH_Sދ A1zS9z={ӸjCMԠ x7'Ҍ7vϥ.KsPii9NEch 3Gh1L.IȤ:AqN9)sP; ϡ>xq4pO4~q 2)3ҁ\ Eo\lm'))Ǟh]E9ϵ<;TDs2JAuzr5ց8v9'Ң9$qSEF@S~lxԜ Gӭ1YqӊPej_0n2rzȣsQom6AG坾S5iXZaON #=iFV短&*p)=5h4k)Odw4 SZoZ1\g,4XЧkǧJ`nՍiR9Sg]}Wkx.CB!ĮAM'p#wҖE9,89V>yQ26iu7Ά 31=3ޤ{ cSr ؎!ty4 hgBDpdBEO漀4[>ٔe)ra|s>S]Y-AnimѝR JT?/ZHtf֡C b3ZzB?vBj6R~[8";ZTU H&' f2Ojn *c4 :dqSDFq֞?Jbp9z~4q$86<Iv+Mp u })U 8摙(YiE^do;ݽ[cO>G9P&!oP_j7)w4O)2J$:!+ðc l`g\CֺM]@<Ӟ̆XYP՜teKc M?JBʸ:0XU` NA;FFy'YpqP!DZԊJ8O EO*T< ԍA{ OR esҤQF03jm\S#7`BmC=*%7ɒh$mxFv5.ߘ b094\{l<9\XzU(UTĎ(٬vr}('OFM=62UЌN{mj*4LcvZu+wO `0+JTC.XԾ4GQrpyֽ&þC%RpUֵt-(đ6M++$<}^E7(ڲ ~rxq^y]ka"3ϼS0##KʿI5KtDA'T:^ZDq;a]+YO`xqn;g5({ySw ϧy%:?z,#=kWsGj."PIȉ Z*وKf zWl&E2A\ylnm,'f̏%AqV#fD]у%ؘOSxz]ǐdl$qktKneFדyZd lF$Gظ"Y+?QU;[+=滄)WDٙ#Px,pF]n9ʑ]j[5÷N ~|t:ĩ,I\v,?$@ 62f+am@:E$nn98/]{뫽9 m}Nˎ1]/p#`;.+ uqp,2F0UVVbY@@Tow2: vCee5}K,v(}:_4ZM'Zތµ++#ьRJ9hރP}9Z9($&(`8=ĠڗxwHs@恞V`v4r84/9Xi7J!#ڰc)kԀGZv2 8f)nV:l#CQRi1Dϩz2;[%M !'` }K8BUEr+/5ܴE/ Ju2xw<ʴM.謒qT.#z֌ āNK''q[#'Q5 ` [s׎:S1W ʬ"SMAWf"U#sJ >cRNy8F[kK %? 10(rFF)/)S.Ē;rԭ V$916HpEL򝄜 Rwd.9Rrhz}Njr ԨR),L;p <G=% qiNM; QdsҤ mwΝjHjdD=zb$HFpja$^S s 5<4 87JALsq-1ı4OA֚d) xI 9n VϵF[QJ0h9+4^m܇YEpA4,z = [D)2񬪻DڒX{Fy3ϥq$}7aBZ:| FI"iZC{ʔw*rCDxU튣@d=ILإذ稢@r90KT7ܕԒ܃jxlCRrS؞\5=Xsڢdfj[d#gwawRvZ65P,DrKi[l `KgҤvBoˎ/2j@XD*;BREd'#BylqPiYffRLu7r3ix3.6rnVAV4 6WMs"G$\Zw 'm_.2pT w&$eIA=klZ1]6@²z3{3Al20H_D\s ~t̐۴.rl9fX"rZlD6% S['V_P%Rk}΅"դ\K3"U{Yf W}q4EUϫVfI>mgl6xs[j.M96#tڜhʲӊ4$}cZOddگIiHT@sڮТ NaMK[Ku-n Xp#R2kw;޹UYG~+z@JKjR$R( unDˇY2qc ̴1Y8\}jNJzTa.ojFR{*XOzSOCCLejۑ޷t>iěpsR 27uX D$TEش]& 1mITޥ4h^P Jā& HF~OIJC͐O~jh/.m[̉0"qՆ$k -ww=OJms aAǸn>yue?Vwtg8JAhJ?Ii0r8ɦ Jv i;R~'( =t#qH{~ 33 ?_jvÎg#3I P+I4c}&9N#M$RiN1G'@;go<ґGuq !9iv `МQz9❐(0sHiwx ߨ攒GNt/zo~}( q杌Cښ Z1ha}9>#_JL@'4l!'/_3114 {Ҙ3Jpp)H0zc4089(M^t=&hd4|Ɠ")I(\`wB.h$W6<HH@lRI0sl4@&\3G4Wu4LEf=i z}5 S4iKARm8=*96=iH\ 7A?1B # {Ւt槍AI\sNq*3N)$0 J=h!9Q V9J JgH-v9ȦӁ62QU5ؚUe t+i"SaZH#\㜊'WܪiHjyuNjC&n)i"e皉2 14ędB4(SƠqѷ=zP]PsWn&!( (I?S޲pO$@*rjdZt]zƻ img؀^?ڮ"IAS=zgݭංBT$`~u3&SͩxϰUa6f@lq֫ɭM:F|{T%O޹sDapPk*hݿ_um"1=XI r1ZdJ7(J1+VpI9bʼN3ҳ$[&bBH" sjC1ӿEe-,T 6~梞v3V}} 2⧷%C(hUi 1n- w/41JxO;=+=C[[_c~@3伷P1Q@) 0*mDyCs3N½Be󊌕|gK҄+J>~9ұ~*ώ($`dpSn\,͂ATG$d֥KGuێiW/p@2Z+n$ n<i`3N,ۑڧQqچ7^i#}*!ֶJZvnmEd8OTuoQ6y# ^%K{#q8p}4mfipFFGV'jԦGXDQ[$dҸy(L 櫲s#vr9حe0• O'PRɎN*q,uFsM~zsޣ񃚌H'O-@<Ұ?;qڔXQe3R-y Vvm5>G~]dPҸ$y#n: 9[ӎ =yvd4[TrpjSҧM-X|njV )#8@y82Dz ƭC>(쁳Hn;rM;b;T.9QpzQ5rczJVws֚*O<͏LmrTb>Ү]W2+q 8WR]$ܜ DJZ[[x ,H`r+9RjOBRՓGe ݵh7nA+i+)$uǭfE2DI$pOaY!)f}Y~]Ʊu!!Y5†ybΩ_߃ ՝bzw: Z,"`c6KZ4d$tGfmp+Oy.d[ы| W()1tWZOʹG{EkM3)$THu8Zya W[1̔du跚# IKMX 8kS;c5WjiT-`Lp?\)u HrgpNҹT2QN-9ę ;aLT,C.w޶2ƀs籮XЍIc*@i+* 2 Z8+¥p4qY5,bV֎[X0{4d) :<G^`IqJN2=zQރփzƀ9IJ@P??ZFy=RAڿ{bb:#zLbqތ J)O@g4S₸9cs!Qw DOj:gJCA;pz 4l$8ϭ^1 q8uN4qLl0h#sKHq֗'Fh=)Bqڌw_19~tHqbh4R\AsH8cs@h|4Wzv zQAMqF3qO;xZf)6Ѩl;SX0ps@n40AiI>>(:LlM.)2悓a֚pqNnLdR1M֝OjB@Wb1Lbc( !=*H BP\=t@C{TÊAt#wK.v6q@ z S"Msړ5,FGOJJA{ʶGCڜZ0HX`"ĀsOe{' y7@H=MV>TNWo^`}S[ˋkw9܅z2}[JYAl3WFv5 u*7ctŴJ򜲲㞽;ݐL֬7 ncY- b٧wypiqE#]X#lw,OJ'5 jK89ϡMe @V\hPoXL33>p$ZW15r+"(MS7^r6ԓv1qhԌ#uR$ !t=\` :PyqѪ*nU!`^Xb6&b9RFTQa1<i(=yaBFݕ178i|5)*;wܝ)8ā5>2=Him:H?QŧfqOv_bzA$c>^!qI<|Tzt49#-3H8 y+DS*P9jkjwaaO 1M8{Q/!2 fw9U`qU#! .ֿKsȬ[8SS9ȧY{*}5)%\C3m70\.Cg(~U)q1#lK=)چ \jn=4Hdm/ r>-s׽+O\y#ȱ:\N,>\ V2n)KqҐq3$n-!Nu#縤#*{F.bViQsU{N&Ev.9 Nz?)Hg8#F#jvN:F ~?>[k"vR0Y>TP$|)=j,Gk=*Jq֬ vSMub~Ze 'Oӧ=1S>\3GN[ Vsis c50 y\I $`vڟ %M\Zu;\䊉KK] x-^X8ȢxbL^gB`dUM cڹovtrI-F-MT9 %\g`~S֬[C=y6nUgrMNt(泬%_MwHKeZQfLд@K3JNvT$SBXP*6Si&Rh؏UY4#qK!\; Ϊ`Gf<云(lqP23VjҰ}|[MJ6أ#0g*Ĉ$Z\r+599Dۇ\cC cNqު EH(Ӱ+2t=j0`ZC=3F=1@ǩ @z$gZ85l>S. OZBs;R9j0sRIQN3Fǥ=0IEҝN}4ڪ' HvaN1UnP1SKwJDzPiq)S0yM*ʞhl5 9iZv6aX]OATxtNF^QI I$TH2)z ǭ==j"nj:=ڽOOP$nm"}(hHy1*)NHJs05[2QTVIr5LU -ROo`2kFOS-]HDШi%:LW[Y QSAp13z'c*9>BKi$qI5Ŷ8{qJZLAih u;N \T8HxE/L~tdƘ9:cjCӯ'.h ŒPx9){R  J6LCґ&:H━(ǥ1|WzB//;T=Np}($+\7CZL1ӓPqE\d{RPzSkc#&0}8JF%*,=aMRant#:w8ޙ#[A96Ȧ7)f1ւا`ǥ0 zc'TW< H\ 1* z)a3w%<6 V;@#hayp Kx5e+"%u;~e3e&F!@$$R.7+6YVfbi'qOV)u0e AJj7褭BQBCM9Fpq]'<(5_4- A+M#gQBRX1Dq ۏfI#3aW4|Mrn7,ż2bsӽC*2ɰp4^VpHG=)bXbܱIr=E(M[08.pɫv.yV"AITœLi0*ӃN_+h2(W O$`q6FrYᱜid8+A<'LY݃=(^第S0lYZʬq<*Օl0 Ҩ4OrA5ks97c"h{5Myx$ h,;epsQӥY\xePH>b&*Kqc! O+TW9z2Wϵ^P1&QnZʔ!ONµӔ%@J؆Z䳏MV$! x9PGNE`֑F4h9݊ͤTӓ)c*>KBH lR* Qi@@#'# Nn)rZi` xs84HE|ҸH~|g=1139" `psRn 1ՙ.-iB5:QF7ERj@f=(P.CPmdrҤ*5E$˂9F TT;`r ޥ k. #z:9{ޘr29aš=Б `QjfNF}*PwLqJzzP|SP<Abq@6E,eOW*O^ YDN(CHUi42=4$ x(HTTcam 0߭ZLvڨ2l}7fϨ".Nk1\:b.2U6;VR>vp1Wtw#?_ҒFك/S\L_ki@8a⹪VhRmu+RCjP+ĖZ$RȪZ5Q$zS5]I"3OsJJ:Rhp/a5W0ۂrtct?]N=U; N~U9 yH7UIGZ؉]3J_*x#d.nyqj^zҕf8456k໔dep}{WRzWwp zW}kVol0?{l(a(64#9JL>Ǜ%EpϾ;ԵFN6vb1KۚN3=*p3IsNLE4sA1XSҐcKjzr):J8<Ӹ֓}ށ)~ch5 :R? 0sG8RWۚj>0) &=Jp0QqYJK4>i1 =04mJ O?8¡sRp9[.$fTc߽!q R䃑9jscM$IsP[P!_JkҐ =(3NeqʊDV=x4BŎ:ScCk&Fq4J*GQT90N :A1Q#3R㑓@]iizSdS`tE) 0iۓ&8($ ǡL] U'&}iAE4 `AT0H˂?J{PϚո" !dV!C[jrfDI+@sޥSGӱ(B}jHU`Fg774ФΖ@і\<8 ?g[^MU#u`r2+MnjsrE6nǭKq, 7 C6r JMEZS1 ԵzPm*m>K~Ny*{uQ)+U~`r8_r[;.cmnxZ7yXxPQI=qOk0YsYJL.i iM0Nsު\.HG"\!iZ%r{G!'y36KH+Vh"pH 53+ dJ֚rjq 8?s[65!.C9Z#@Jz֑|”oADO&QN`J2H3RI{UInѹ Hݴ*w3 U{sLҐqIZ b[$V F?13#8s@sSnz*C6>4>ndvUTǽe:mWK..xXPֵV ٌeH>hqw:r?Һnɑ2VeEec|ѥs0\s]<  {]%!tE=$݊H=i/8**}rHnOJzTj[9ax###X Fr:fMK2ch([2KulzNm*HB0I#6 -#{s효ͣ\d`nե51kMn#Aܒk:ᾥCUR"v\6 {֞[©,N5umq,02cSzƆkv!;[2"4=?>=V~è&x =C3ڻ+OqO''SGUBqޓ(#K#P-'!ҝMZϯZNiqd}h=3Kɥ jAG8_A&1ޟOҐ<խghc4s1WkTP |>C)7Q^iߡR0 iqE$9=)NsH _|v}+"uwۥI.$)ʐ1҃]Ê @`jPGQLi觨4n4..02;9Q)^d,=)SF:Ruy#݂A'J@^ʞiwsV0byE2)=:S |vB-(hL+dPÎjQ997`2;{f`x" t梒7#+=(q3҅І8rs֕" wn LV!8 )p!(,Ԁj BNHWڞG28tEQriP-S޷-f%= *ݬ>L)- 0fR3UT,G.~n+@>Ls֗9$mt$T*[MRAɠ.;lmԮ3FiPc8#H*xJжyva(=+:_D=[.$nr3zUk6ԵU]"'4{-eW"g בK$7qU$"\\dluf+#oJ܎#5LY7[qpr}Xfܵ2J ;'!*=zMKnۓvJd{NKE%%v5LǷ9pgHr%ƙxH#1N-VF*@{{qާ. 9*A=h0{NÝ3M.ޘZ QfYE3YM q}j3i5CK8&;bҹ^udbMxʱ(UX20跆9VMű*]>T$Uc7>|lSApHwCʌT2r3dE0rW>xJn˜3O0۵SHr1֔HNObon\vBۉP 2IGDg"[i0*s5xROqSCˌȥç<}* 8#=hL.M) F+jmc$Io$j:+QIph @'h#`^N$c 9ݴg5bc)iWz #\ Ojj =b5zWWq3FRN( 9Qńh$SaJNHtX%W? B~=+?7QMcZkI!5C:FaS׵y4V1Q巁v(*E,$ Њl~5RYÓ0+:浥fnTYaHd8;TkrxcҰ'{ZKe {RKhP0;{cjmFu2[ج EÃ{E8]U&jie sJ 䑘@,+0a+d՛㹜c =H \+B0Nh.qׂ9@>UvT"쇈$E*7@'Ҵ%6Eo1ϚǻݫmXSq+| "IMzMPzҎ(M'RGͻRzsU%4u9$OT#(c8m[6vfS3XMmNv7帊XV6(.T(Rղ^5]S7 S"HzcG ]5ƏpV.Y> s5m[TO*9axJ^3V.6'bI=+XǗz `8<҆lqW}>\dg56ԟ79($Ѻ S=9Xә憆)`G)1ބG,A}(u g:Tl~oJnri`N:RNh`qIu `lK(ZF#څ$ڕے8 'mHlbiSy4qSq!=w4RNi2hSrқŠr0'GlGRB*+ LRNJxb{h] MsUK9ڻ ԅN{U pMjaJD n@mr]3xU)Fo,S FnsI@U̞J9wmԔ`w4ɗo=A PGShZeaY"FOCSLKrd}*^Cy^J82=8M&HAj).a2q{k,4hXg Qӳ=:Clαqzg0HQ|A;VݴѯVHYR-Z՝1w؎#@<=Nhe{0 1ֺNNA c}XWg/sɴd婤s1m?xc<鰅$.j;+"-ZB[. "ռc:}ݦ]Pj(PX܅p@56f͚7Tɩj/׽@K HJ q{V1B@*?IVS];*'f O8w>l@֍1 =iׯSMXjwlx d=~t-3O85nԱ1YAR#4]ɔoD=') rJrY6oqmrixǽY0+3?=z-zz8z\5tTڹOk Zfe*@[vmi\1ҹ5/dd4VTTmة8al$%U[G gbt^GI;ӌd)*8NOF$UV,"_s /bSS} 7dF% }qW݀&<ؓS|~q:μYT0~G>QmDF[)4#=ZNg]v\K֚p 8ٴd(6q jhE4Smf TE6B8bʪXPn.Ymb{ ַm[@!/6%A~Sԫ=BA#ϷɆfҴ٢dAX(dPyUgsyx8gws _`0\oK71ma*jsupWwAODv˫5u+&3[T:V4'&1GS!{QAdU6'<4cѝ2[ڊf $ޗp+H@Pu Ɨ FcL^dOʷNczQr zPJi0)6Scƒ*s( ⥈aSHzS8Lc,1S)銭tYHvDs9&JpOjW=FEFrO8sޛqXc#7ݥ[5ea%wS#.$BTڤG ɦpؠ#e򦴋} Fi1GrXJ<ړ99 Z#qUZzɷ e7hC)UN &Ӓ ùp8X R\SUX=顉ڀϛ$S?o|PqG͜Ra}݃83HS⥁Nsj.NsN\Л(C9OfRwӺ21>JyaGN%b4KD!4,XcfQO\烏 iv;;4<dJDFzNHӸ<䎔\ ÌSCBQV%VnsSNi2~ɠM1XqRJ ya4$Zu#f#qn,zW9JXydvK`dsՎL'iRq'M@CI&'s2VG 涋2jډu*$rIWd$]k<.:޹"ky1mD6 4ɀ,Ҏ9$cEpis5v)U1urFbbW,k-Gtٳ?-# aH!}ilh`$+2} 26?:fzB V}M^;vPLcSq n|ciCo2e]❮Y <{r +sQ| ҳnrkAY1Y7sjRDNMzbBztSC6M=m'wzZ٘O}FRds^cH}א&F{t@& c"M=Ǧjs VQW=2: mcPKup5FXXм"R@sֱɥu[fliK^DwXմw-#nw7^$?.t֜e|1c ĎrVkW3bSʔ3n㩢{2GNG d|wrMpAHwk &P+>K9;*lhw'6! Rkk"Hy" R>W#8部:ȼt$q[6V3$St0˶L` +n gՕZF F'қҲgy[f]݉O5XAz7*a[O&Nz u4xhuaӚQ(̛=Y浶TkF,bkwc'{wۚS?)|b &8A>ᩭŔ )Xh㩽2u,3K/5(;LT7aQWTR=HT39kḭw4RQ\(ב@.M5fEWۓSƸ{C08擎QpRqO fn8`P-!84&o╅bRc6LT}9\cv`{ _g#"4j4R p9$0=i 'N@nB0O5 c7jm|MA+`f)==ANit6Bg !sMh'&7M9A=#8)TM^ԷnT8ߜd*Gq ։ xUH3Q.Um*!\fGV-[ms -#pps^9<kOU~ܱ\2Fҳ[h= -NP9gԊ]DŽ6fZ)7`qRWI>6RAgFQեނr=*khú$"6bؔ/9Yd}T,YPqmsZvR N]ޢQ\lvEY3qU7Z!a;yKAJ2yIJ%A*VP11\cxe? A1*A&FO&ý(vNINr6G-qS0iP?$g<͹ǥHhV`x⚙RVmHR*)X{PʱXsz>iO s;qۻ⃆xJ6qFvY?O׊}u\+/CT X]d\wNZz EZ8~Q:$:N⡦ރnuv48\qB⦗J9"2a>ljFI0]䉀I>wFNW? w??ZC7ӵB 暌 mqBLs͞zSyrp@Eۚr2RJj5A5!4"`4 5=i"ŽN=iڐ݉P?54ϥ^43ϔtx?1kzBj͸@nwGO"# $N3 v VrcT-+fO:֐![w-R2Y c8-EsI8L'>ssMR*.U> \`R4{FiC:I,ssJo4=:Aֆ2Px^)֍?HX=,=CR# JQ:P'D7҆Qߥ J99kAz%PSR#$u4 9T T #fFjFг1f#MN@$fdEUbaMpڛMT^8$TGw h S"sGt =1VCaj vڟ*`ZP9\ӳ%VP=ZUg⥷0s]=EfᮈQ@$sgQuZrr8{խ щ)rxMV9VYjx1c3SKGbPiYNMzzv6)=Ef#֣ffgH=1VRNZ\%POAIߵFGJЮ#ɟjFmN8rz98ųѕAkOp2.pFz}5y`YH!'=~n? *ז )A$r).n#Fw`6\ߑs- ]AXk1\ϟ7b(D;>va H?r-i=YdV]\v* {Vޠ4mC2r~ |V^iq t1m^-F F9޶M%b-sn{D\3A#Æprzs\e,،gjW56F8HtWL_]O&?EZֶ?bX;C" M:/1kygQsR祊W>nŠ)ÂN(l#z Tj0XwOzbǖ1JQ\fCt$LltY[9Q1cSAJ0:Ty( HX'f`rҘbA;qW?2X "*0bu^qK,Z'#Jj(ƚ$b&INVFrFO=*wlEXZ::۞.=K$#brީyS3HNEBD1q85 ٫G*rl 'w>)NiBʛ|ا٠xcnCR>27 qy F Tm苎Bhby`G<Ң 8 {VD9G;tIw{, !#i v;`1v'O%[vnJ2@4*XR0LP0pCd@fe.I)ҕ\I+rz0FGcޓqcNKBty}M>1L4ڬ;txnLN>(0d8jfp)鵰@'a7؍8'W"NGH [!C i򑃚" 4m>WB=ii@T:1Ȭ;iŐέʬ;i4y2g9^Ƶdj}jgZ$rVMܯ.q)N;ϸ0~a23Aޔ5$q@9 pi>92T@vɤq RqĀ:qڀi0׽?#111@;q@?UPG1)TcjBLy^z)́\9908ǽ8LZ[]HJd'3Ft;#'Nx s&c)ۚdl'Aej>q#;$NqҐm`摢Pe+(I"8Ҡ`A'Elf NNsOЖ3l 3֞ lc:I'IY6r*c*>fw(Uwd1)JeW#9z/ph|m K@ӣPB^Լ@O@Hz8''Snة'fSҘ`AME6߭<6:q{RHWi>>^*ר T*ʪ0rUsBy20iI9C¯+H'& ďm#c)T4P-xNGjw#O'# sWdWCRAb@ǁMIbr ;#9V8 4ˌ“䎜r`֡ bG$1U`f©~U`X/3Z^8.gPI*%%Nh,r;Rcf< 㯭El8?ZM[BF7QSmu9bV82\6D iheO,Y984GUA|u5\q{?7ҥ!P@CIfɹĚF'r*:eGFwsQ^9pzPc5D2U91:P;$S^njSB0.sҍF1ǭ9zvHrF Z+?lPnPN֛ؑTcv#aP<~P۰"WVt\ um}kJĒ1T'roΪ1i -/qޔMR}A:k.[~?ngr*)\INo gT` UUc8lysYܴG48Cc@&ӟ&?8#i_j5H~h?wh݂N8L#p9JpI)2h ލKJyƤ{J~)08#P4呔ir2zQFI)ʎOⰎ*FA;!OZzBK=*G(ei#i7N1Ҥ9$dtԦ/SsM8 3#.mmA_MCw ڵ඙,A*-Ym՗)0x&-C&уJ+$HxđOm`$tv4qO_ZakL9Gh C I21}CU:RE-FBu=8T:5aclqM;c '@bM#rI=*v9 S׬lk},$62{֭<)$T%aAo[qݑqsc*{K9; l:.pq#FUFNN9Nfochsnc$SAPzVޛ X8TZ5eg(Pa[n[3>О*պBJUaFXT:Scs)Yݩzԁ-!FO;l1Ҟ0Ni!<ȧ9)vzo'ւa1ִtL8<Z;@#:WYEy.SXZFu g@^+LYfWUHi͇]SG-Δud$ʄgsh˲qwji%If5ەiWWf뤎@e۳҆ߥ1j8_Zqle=^g$ Ь#✟{'5Lo|!rK $t<#ַrL0ϰ5my]Yv湛7lz)wZ++T8?@65g4<G0JQ)hRXGsJu* " 7)Ʉ4\-q iCp9{擯Mؑ=ipE)oAI2?tsHpsM=hRc<2zr)RbhE T˟_褑v0VSJS{JO5+ tr Z`!E9ӑZϽ!Hǭbd}j+ʼ `R41ւ9GҜdج4 8(p wӥ7zqJ)ƞNz fO9+<Ը(AFyrM(Pm XE*OZljdZ{w69Xq$a+!0jBkt5=8}*5`@ao s S**1[/+hd#qWFdg`tWc"qbEFZK>Bw5>$} FW YĶr@F/j |*\Pk8lH* ,6;++jXmX6NFmv`g\&1*J^"5*T F=M\[Fn6'ԥ˳ VB GsQYϼ(L6drjM 2HYOzֵ 8V5nbF@R1_\,1N…+ESѣdzVCV؈8嗧9Q!44+dqޗ 8ǮE \])=1֜X4;xZ7sN9 O,r2WE"pi"$~9*Hy6R7SRpi?*{<jhFS=*%eQsZ)pky*m^k;2Fp*WԀ/S=jcNWؑ gb.MMVQ*d]ܵ9G0G rjHj[*)#P6pČCC֚dt<6E!Ez"ԛj}Idq(hGE8M8pMRi ϩ<茷DsҪtϥh3 lg >ԯ֛=*EcSsJ+zMus)—3-@c4qҜ 0֝c+>fN e5v3'+$`DcJU.ұ6VPѧ-X l݌jLإXDQY[֥cd7N:sv|CMK5դd"26m*gB/C@u,aN}e@ Dl*&4$@* Y^+N(g@}z:y"!i\ilPVVGZҎ8>Z'i(ⓑVI!B n2M0F҃p1Z3FF(cҠ6W{T;1rA4Hќ|'Յ3F*оڐ^hCfP4ꋐ:V e@Q6852YJ[Bc5bp9 eKA#<8VH\aƒ5 2l<$dU=:vSM-O1BmϭHUG6k.sޢ'ID*iUxiFڜzsޟP$ ;T@ O9ϰJ] r)yc)#Bnv"8> sx{Qaon;Caқ&㊝_zS$l)cchbvzSR) [4;[BX[Nx b+h rixT`ƍhLqR ޢӀɠ J:bN'[׵dI䌜jI^;$S48kH j-̼0"9 kf8'gu4֪ *֞g$vALNH\SF94{D@i<)sƋ#"x^}j3gnr1RRCpCҐ+' O4c̻zbBAjAq֣zwf2BO]OZ`$ zHwH}hˍ>6֗ԌJpr.1)ҟ 8lЂÆy_Ɨm@␲6h?8 $cc#֐1ܰ:N B8+H bh8>P3+{S{Ԥ@GStjp# rM\ $R;M{֜51[#p?\sdV"x[)1^A1֢ R2,q5~awFw,k8ϡO)݀sZwVc7YA$jz`M=ڰ#v֞FI!UBYr$֎. F73s{8rW9 ߊSGqe4%wo c,djKk۞:ڛkpv3N}ktc罂1E+.A(HiIԭ[lBhHP{!5!$STӉ4 e-$ n@vALJB[Y ?.;zj22 [*p?[(@[4v,2 ܬ>b]~5+O%6r{U;$F̋IC,LH[ ڲSc"ès]J[AKF (HP@4щ&]WnL6 G?lYV"&gC+uVCE87 5t0gUA=qZ6͂:[U+\(i+$c|wCxRݍ)k[j0_dv$J./1Àxd=}Ql|5]a.Io?42~% 6_z%lo 2Cj6E?*В(2֣xB&ղ WFH#үG D9dz۴hy5f6KqR~nr)sk䒫i'1In})8q\(.CT$s)="\1֔zPK waĎ;cx4sM#6GI=iUszzPĬFM $:R1Pxwb]c*S>N"bP`e))9*=9R)&=N~@v R*>҄rO kӲ1L$~ ]~9 ;`8'8(w`sޝp D͏ c;riK`sRnȨɢö<Ҹ':w84\MtLņ;X wbVe8'Uu&Ǡ@zTJyu#kc"(A+\OCYkrJ(,k.%Oʭlr>NZnB9f `QEb\w*Ic>Fm&G"HFlJo,ןJx$veA ` <v'l bFG^i%~_JZErE)'<2y>qK7V-v6 |j]N}IXa@@5brBc'jkHdIlU 8;8GRdlb94䫢)#) \ۇNi ƙi@_{@ܹ7 Ըh{%gă $b PGa:ҝǒOJ` )GJA2Ú C`:LmvYY:zTesJ_8" R;wjs 9m}VaaSGF\䜚=Qd }H̽H֤5Y ;lb"lu5\dURLXN(WH9Ȥ$ԞQ9lV*aG~)[W q֠Qti!FP:RlsQr'Jmҝp.Ӛ&PphǽY##$sOk<6n'ԓTV^`z](.ȫm:vXv95Q}j8.rZǭLkCXI-Sh US M#[wc+;<䞂w+l3AzKf\7*Br F>W:JY"dXN ަ*I9( R͜h߰q]bC򑕮-8Se00ŌairdT0]:n$溉W8 kS!)nE08ґ[AO]wiʭNC3F'ے@ܜ=;MǯߊZ!CJh+F$1ya} C*u[]`.E/!s1cN ))qR2HxqWM!sOv gnSBoҤPAR@lP&<ۜڢ+u})3xa0TRvrI ?x+SOiBg<~Ui\]6'ӭ~S2JvToe .8ֵ]F\;nq9q!{̽"YB# EVSP*FS AVNd9$@LVH|za9i@ACh~ro$B*ĊH2֛ɤ 1XGJR P'#+0M)3v!qS..pzqWȼ98**6tMr*%*/zTC+2xU`G@K_jм$ne5m=*ֲ3l SϦ>x5 㠪Y9V=hy&˿S֢&HWOjDkΑ5dVҦlTOSDRINJn%F}*s(^^PT=*=ҵLige`敥Ị֐}i"k6"n_>W4>3RqIw orDhya5e%wfwL'pAہUCT"PlC)]-+ C,r}QI$_dt芒Z<2OJe">+Jy#"I0SC*0.LO=>WͮuaqM z2s;@0ASsA 1ދ40ȤcƜ{AP k\tߊ\H{zSCچ$ak | ԈLn@#4~֤iUz 0 &qL1iIB F9M&hRpEL84cړv'QèVE8 m-rzPx"dSp8ҌFьSst0\du59gSQq@d]p%69il$T16GV~ty1=)64$eCNT{*g֐cҤQӓHoו<ӰR'Ҷ4*!?{"ϭI LA;(06#d i[nFkH gkK2$k4=뮚22:>RNq-J_ǨZq0:R jLs')? pyVbˑzSP7M܎;AP}i2@'?J s4d) A׵ Ϧ()GyG~6{zR11OԝS-Ԟ=)HGZCwR;6&IҜC 89iv$f»H{qPQt 5%7&ySS&\lZ ]MɅPF8#/VĆ-Pqx=>&ټU*a gι?º9=d n\k)x)ʌRĈI ac*F22EVviQ9!63NlV&(*FjcVX3 PS*9GB4dHڞDVqO8#i[A[ߘJ8,~q֐3HSKONԀE $cv"B3k (S*!ޜqrP =GZ" Z8&z` lTw;˔ pKJ ,EwaW$5zU+؀9ȥ'@ Z\}g1UI"@);,+ >VV #ld+;>ݫbYu$'%NKcU$v'dyO#>P ̰]O#9g{Y&X VMܱ8 8Ak;Qح:^.Չ] IfG\")2rX`j2i$f9OCyV*-UG]}E=T 3SvyV ' 9kҮM S$kj$FH>-<,Ǧi'Xj8  Ja ")Os9۸Tw~ARۯpG9 HpDJ)3ZM.:U-OS-5-;SB{.  dO fp=+JoK}WX1Zn !Q!b3po*&݀_aM6 a@(Pyn޴_:HnYR]|1;hI HPO 'I8#n.`:I m5?0IQ d08ix ȸ$TOm ;.KiĂHm;G=:T7WPsNk{/`qU~#,p8QD^0$RѨdR*ܱۢ=j`MN9:2{5؏yT8Uhj;ɰ~b>Þ 6rMrPX&||; zoݹsn/A ֔ǽDģd)CoY*$ueUO#4s篦iEH8eiI֖<. N,HSD pjdWgFF0:sڝ+"xW\g&BG'o~(lt4J'w<$m1*}sAF&sܓE@ٚJw@iy%F0:I4ys"0ih*pG<-8tciؖ[')AԻ=(ڐ*NGZ銍9)2ҋ b9'B|=&n9Ռ݂<^˜AI@đz,0I ;SqM)f P0b OvhC)xiđVxoW)jen>%(h }jɣqKۨZ{t880ȓIJ |ăԌOyjcd`FQTX$fhQC\rDj)&U%{i9cӚPjJ7_zTP50Nנ\0(8hA'֘f@74`8w4СW4lp8%ӧz LcQ"cPڞvS~^x4o`OsQc;^xv[YZ9p*00N3N@"TV@O,MmF~ѕkJqTN5gzҘ̄F4i杳h晃ޟzP4/4=)ssH/z;})hϵaOzOuN4piS JRsMRY҃Fi1{#wAawdR$`c4w'qrir:QP #ӺR ?1(z;R.{PhHN)TGy#oҍÚvqUNFc+"K5 kH 1U(hj8ɥɧL$ z|;whʸ\Ko+)qKpR=9x.6GD3e6ar ZFwX 4K(kv1#@AvCL~SR`W\ޥ8!&#*G`v>h}(;F9OOR >*#&2H"cTjA7ҹ兰&ths3ovU]FSB`եnR TpGR]͜mƞ=qIT@lcdm=.rE]܌SC$R\ =GJ陶Xc@Oq4*F!o4<әꦓq֨5r@I<yz` I+9JTg9>qҤA^bx#8 iډӷ*}ՇAqhnixcqM8OFPcPP@#<Rpy=ERr:Ҵ;@nB=ܱZ'vȫẘr2qS;BdӬ:۷?ZEumor@< g]:̆{ [%}q҈Pi$RR9DjGZ\ԘT7 `u0'&\njlq @)(€=( h=Rs@=;]6c'SdQΝ#71ғԽPnAL*Nz `x㯥<9^}l\T*g pe@PTNk0gjHb.,HI ]jC'UI ncdliP#"19?埖$:=uCKVxGE3TaJZ::<1jWuR(r)@YOLQ`ԘӏJhM)[ṭZX5[d2NBPC Cwqjl^_[؟38z~3|j($K,Nwr.w X.q;"n:/5JK%=Tt\DD q&n@@$g< q.FC>3q$g`sRM$PIc5ZI&vm;ը߰. ,Z/$߽6H$, F+TR]&iHRN < Dgxh*ʆTxhqBM# [=U'm֚T֣G}=Q;%zS$SԨE%X٘X6ODsOWTܸ r2MFy5&}f %FϜեJfH9VVr1ڤI8a_kɀ1@ަ23gqC9ާmf*d1qf;vZf4I:("ӚRNMWZp'&'ߊWnVŲ6V9oO;~ Ut'GEczҘ0H$H$)9Ӂub = '44vWdHN8M e\Hۡ1ce=`4F\S[?W$F^ym]~V1ƆF p4g8)U8< J鐿pqH7)ҐX r8_SBbwCNIh!8GQH۱ڋ<`< f!2&:#R砥eqC&DsҞ?Vc|՛oj,ZL`pQ*Yd9&).9B?'<ʂ'qI{qJ;I`0G\ڣ"(7g:f :` U #sΖ5NGƿdq'"᳷ɁF,|U{feY2:3J)&H皬O<g ,NyVbZvUPqךN1מ3ڙ B38H};!#F*3ޫ`nPJ3BBKaܖ6F}iHn*y.G99=j行FO=i'lINgn)R KPҸ8{=:9.= 0=M/\R/#ԫZ <{r KN,O4N? 8u% U溿 +ik,c݃S=Lm!PPx58mch70ў`k,UĹsB:ig $1-UW,NMBG^j4(rr0zҭ$6`~k:5l`{U-v~glp;Uxn8 z#A<*uu?:EAE`]~n5+D6jյjJHtxYE=vbc ŔH|f#]eNq{F4g9}ުĻ"?td*6Y,l sa8ګFHn{{<=)LJҀq9 py]ag>Ib3ڔ#Ɔ1p0:R8<ph(֞ 36G^b^җ ץ5 qz  ֜)JI);cJ&I PsI Ѱҗb0:ީrQ\C>tQ1!WywP{r;w'K6ӤTkwIt>YǥaR:29 L느FWnO8MzS )#==U*C_ʋb5))qR) E;QҼuj&gc(!sh\&"ğ/)') \KB0m9 z=,[қZv[*1DǠ4卜LqD > t vgP Djɧ) *$wO))p*)1-z}άlg)|Ք\Ns޶KF`\_@ *7T2VS% kBld+k<eNQ,;9,1Q I\4d >a+nqY<ci+Ҳ4؋{n} S xiX iVY8ZU9NrqL!ߞاx.@z.qqkXq4~uP@j=ԃ]eV1;|Af~Vm 7%(^St?Z煞0'<%0$&E3*@.\֖fKتJ,8HO֭\ZD@o% c 37UM`*AIGҒ(̀՚ڥ[L vj;9wT\redUSONjYǷQi $?UKwE k9fǞvw:EVĶ|ǜ+t&b}jr4dҳrO\LL#5/P$fHI"JEsL3Hx#iDў~w$E8䙤A @H41d =OL支~^N֣PsP&J8$k6s1E!9җvaBi@8GL[z4H85!sLV֥RqӚ1S#q4#c~7*%'84n_iQ"f]saQDQHņ 9yuo A#9!vj-|TXl,+9nY lj&l;Ӛe&i#^r);ڑ֗?ZZai43g{dtOpA-B 1 cޑsJH4SH.ndmҢ8M(\y8}c+ NJ#.[*<7qBd1;!dݩ'R^x c$O*8ToQEqm'SOL\C)d4#nx Jc Hʠ2qCcJxtJR"4ЎژTmϧZn1Qsӭ@WR9+ʱGSp1HzJ#iC)z p)1Sa7 1 Ԧ gozXpS۵;`:TݓE1Wvx)b q0NqQr9JUGCI׊9Jh@j6*ujlr}i1;cҔ=)ޝ;!=iasNoZz1}*Ydطʰ0uQY.'JڸpFx=J8Bw \pgZ-I~? e>m,Vl?CY\S[e ^W3( U<њ -]ҶN%+0 WBJTHPu'֝s&ʊp5zў X?f߳v`'hV7/i8 +ToKab-$m7jn"=ϥpI4gd/ye ǕeGze+x;~e\[tPǹ՜!AyK1]. YpqHACOU^RZm R9({d{"zo04h9)RhI8sޔmI+&Fr22:P@qC8lG8qޚ U\W&*}j7Bœu+ <<0`f8=1@Xh0Wb 1`iHWUz)չt1ƅ"u.1S$n ӵD:ČxND\\$$.Ҙw0xsM8?Qp!O8)<xP$tƍQ)YIʁ~ :+63U,0-ʷ(p;wi͢ƹNWy T!+ky.\H<;UMJHݿҜeaUބ=IS~\VcmGl_"EϧTX6“[YJYV3G ձ9FN* #G+.z'*e#2 9~P /1zPe\<Ċ@CrJԬ`m'=k7dRCϵ;*Hf:Wj%"4IXr3ѰÿY\J5_H~WԤ2Y9 e֔F)XGmo5$Y^$? ٲ`K)-/}08$PK ]\8ߡ2׳@ӢȪX `] gLv^xg+%?zr \ c4rObp#9 VhoFnsM*PЬ)<ֆ'y4M+p9B 穩6?x`@y2&$}Ii e5*\qg:3EKv7G8*#8S6c#H2S9&nSҖrqNf#jW~S#ǵA.iѳg)e' ښI1g' td8ɨiTtvqDNsJRpG1F{ub0qҭFT8ǽ45q. " P*5vЮ]SjC:a8"VC8*i9MHZzj8O"y`HPv^ M+ 28b<\~}j2{3+0\u{ zM(dg$Pt-Bk!vs3^[[c\>ob{7`[PH>f1NXo5&def^dF8Pir:BKKpT@`u>Յ:'`wdV$eDˀ9Hx\1#P;BT&'QO 8ِjČN{`Z22*BTj>aR3VC1Np0vRDqڧDqϥN sT_ 秽J `{T9Aޕ"K!bGҚ8Ne=J{ wZ2;ҁkጀjaZ $$*5'$$v38,,wA?ކc})P1R"y8R?XL~20ސvf$YdzbKF9U! 1)+'K±l񲪱@JI z`zs,O}*eX3Һ"sRL3#hFy"(41FyS+$*+x[C)ELҒdܛTTԏR~ܮ.R(S9R8޵bs<L[rƁ#Lیs֣*)#,NqXL]{f]6l~(j,=;Ҝ1zv\*;899YB? pK=. '҅ntji%W#l{b{~F4źI1֭eG@R"ز-T,Q*z5v+u <k,8fI#2o“/ǥ TN/1u8h$a{Qc2s@Up9zMM8? ,=-EMSnE$Rd">9" XFE*1R)p&QCץ2GGM0縪bFD[jp|٤W,9EA Ҙi"yNbJQ#O)j Nx 2VN}~gB1Q'H9U|cU9QTSs֛Nxz`N)z԰c;`zM-J~ i+442'RvjоB Q:'=s44dԤ'ӊrT)\|`ϵwLvĂ$b5Ƭ7TL1]m/@k :#5]P603޲n/`b%,N5zd~Ӵ+ήK#1#ߚy*]{UwrNCdR*&*&~kErq)drFj^ȘݓAPNNny3si@ށ'?:Ⱥћ!W}jXbwefuE.>T_ݔ˂|RM9#g ʽ>4T1FIȅ * c+K;] 3׿^nsVjrb<08#ڈVq%M3'Y `XrN9_ c2^/sQrűG';Jd=}+HTeHأ[Qe$c]i1˹Ղ$-ŌqfL+Uth.Q&5s `qSAo$@V:|'Egh@owSj]yry)=*;fb!<!jbv5gkq V鉤G$}2eKxTVbO`CMk]yѲjNXڜnpZk >88Wo[smA2-5܆?(#K[h@]]:IVlF{ի0ﺩ{[bW69d2s*rjϚzrr*nRB#g#Lz8֩4:ԯl˴1Ӆͳ$HN# ~5(`Oօ֒Ǽ&”is'\zSN;qMرO4r* bh"vՁ5w@E J@ ⚹6,^ dR".DP:dI"ğz~ >R0)Cv9$4҄LC:gwn!=NjE ąREzJާyi44UsuA%֕8ڡ2 s5*(=$ ڝ~?S/ӭ..8aIJԖd~hܧmnZ61G_ֵ" |$Q*16G$g#8rDUt= T J+.[n zӰ 7)U *c.O֊inJ98)QsHp>nY+J=A b e늂H) bsJYvNT\^9P "&sPr(;1AsW c" C8\&I1ECS83Ғ dz٨G5& $n gh #5#=qCܮRpNM(jo`9@HV"=Fv=*7 0=<*8h0< ēRSA"u$Q2\T=Scܵ*=9ۿSҤFP}K}MԳڄ+Hl8 I!8暸[U(5ccҗFIC`!BQg5 <{`$dx?yT/52$jPwqAS0A87&LR no@(4l 5YP? RKi!Q8p}qM-={SlN$)R${pA$QҜJ}M02(4gJyTGuH\p Qր=zҕ=sց\ `#99nmQ2oei汜":Q3iV(d{#W i7CnLe þ!{t&cJMB&1b̼WM4\[ :e',smVA73.?3\;N˖P6 v5gPԑm# BȠnf *{T =j6Zyqz _ Em =9JbId~9# J}ic,&`e30xsL##M zw<S $OЖ#*dҡ@1V HB[ ~4[ !ăԀaH8J0I捬0phi25{cޚ0AKk{P-SҚ`># :;9ڠ8 ֬C'=EL]#PFw=ZQNzyQj=jt++C'9=0:STw=kH #br[vUጐZ@ EW%\d:Q(zfӋoRǩvSȦ@PzSf?nps{SNH4 z;b1'N3Rv@צ1-:S܁ғ)u=iKr8*<ņXa@!ЄSs:+JW8I"'ݞ8-Y"dSMNw9f`F+t=:??z 5H0lci۵:r?ƙ5*v9*5Ӓkt_K q4Xc »f%+eC+Wqar=ɓI˄'E6Htuw]G^dx"Zr;99WʕE Q;F3X&lXVS⚧ M0OV]nc*`Q%'&B3O |ԓ TL1\9uzGj2ʸzjaқkd"1ڰu5BxZW2c˸gUeCHZ!s2$~~0>ۆ*f8Le@sU6@sɭ [ NY j= kg.F;TBy,7e'R>hnsT`l *2xP2@n@0H$>:xﻊrA |Xy&Ũ+ۘʫy [qDY1gs♦X!$ $gKyx3>P:"H{{t jbrhgX5{㊸F68O 8W9浹Lp!=Jc! \0S[ Z1 .ҚA^a{`{ҁoz7p09 TtnsM Zw5(-qwysvF'!n q "6SdHJwΙK<*#5 vkq #( c$ #(d>=M*{ǵiv.$K7Oғ1C,{V>. hSaX4Gg8lo*BXMu8ۻEm2Ҵf`I'q+ӸZFN2TE#$I0AǠ] 0wBndZ52 #Z3wđE1`wARV".3LU ,/sgT6kMn#U vcVZܨ#9(mYbgڰ<ɤVFo'沌vh2TE"UۨFeFL;Td,n{NM< ֤3Arp@4 )G#iG׭;j ㊁F:xSXW =*\eG' FǧJE$@<ӋsJɦ8lc!PjeQǜt4քRIIx Sc j1T'SR4FNrv)-SDvPq'M'I aJBW RR`\B:ihZ 0|ԬNHG|53Wj6VRȦ$=I  VO)͚(E6HI8žj*JHzh( 'UT`\ÜpjFPAb{LVQjªE60{(v1Rj;RL/rc4MDnMKu" =Ѱh iVJGݕ<})I >n=) r\լ`拍$h c84Ũ'4:R N6}i\uib)#^O,0(<b 핕z*)ݨbbռ$dW^ɡ],RN9~5J¶ <~Q칈yCؚM"".})-?#rc*y {ss{AϽTB;'aE(!uӖ<ՒdS0ԬXU6+،J旜dԱ㞢Q  @I)  N GrJUF:RNH0tS^恵a:dND< ŸNA:Q)Zp;z[;ZkO>,AVh@|S O9QF6H&=i1.BI=Ў2E^F,(StRhz<#N ā|SDp=HqW`tZ$AҞ=*9q r<`T`zS=hehHhXtjnhڕ2HUsM»IW򓌏JέFFo}.L3$ɭ;_h6Xm u[YZS5ˡ$Q+y1FoF?ʪUtF:dv`(767Hޑc3Qo9xk*1 5avI&Piel6=+}NLѷ׷W^ڢZʛUJ0O\ Dq]D#Mu+I%&`2G&^! #+Y$E j[\"Vl튱akjg}O-) B'4+!$4V8dzqoe&. 1I E"ȇNEG"lvTܹz8Qg{; I"BI(׃ڲ1em/DKly_spk! Hc;NW-c}9AYrxwĪ`.ebH :̓Nj9̨W6l9'8U<{RZZ͈{c(9k>=E :+۸'(,<ҔS͜Uq6wxF8@ǧ9`7wV= qiJ1Mu R.H#?*`Dw9;FsX~tŨ'ڜ䓜T|t >#M<8)9I yM##!TN2S@$ jX%&,TJ=vԿ2iȪUsԞkgdRlFֱl :IYDfK;HJ忼j}q,y @m\Vī6S@ڤ*I#*>a=kΤp6s۱M[I :VUfOPخKO$no ʻNM@Hjd˨_ %`'5f-^9 8FFOW$Y7d$Y*ɳ$* <5e9gqIDisWV&H#⚛D]_Q9'4,hߐn( s.Zk#rq44* P~jMxH0ԙ R! -0Fi m#ch|P h@ `t y8=jDZpzQ!_*'@i[h9!#J(4BŊTg*EN 緥$RBԌR$p*!R4#?9cSHsBuJp􁘓s ސQpd# #V\ozЍFh`HT9z ZFb8ۀhw M2RN2:G\T@\C֙.x\UEUVTQ֜cCS# '080E#+ y0I~82icK  !hǙ!9O"{l3ɩq85R1H0:捽iĄ\*MJ#^sR#VwI aV_=jk`Vd U$怰 jzsLP4*Úbˣ9$(ǭYH6 =.7GEcmq8銕^0#)S'9hpyޔ@I`s1OMr*2p}icrzHĬFLiQ$qR"+3qϭ&Q4R@&wJ=)I7uMF9&iUԌ/^}P—sҗ*8昝[}ZBF*3Z]pZbB;qW*&6LqsT9czk'ޗ$p{Qqڣ=ܣj<ל~!*یPXcM&_hӂ\ځnwt4HLSI֕ bcz h Fp. tH״mZEF-"9p5k$b~A&eݎ$qkIPI $үK>[8wckN ͱjɩI%E1X19oyVF,{q[+tew'; "^y!H;IۚZ'#%JF9X-u{DFpGuX<';EHO+cF8=@SOҍC7PGQ:׾j6:GOE@x@#85/dg*A1Uɸ N\J.[x}K88 9@UXCܐZCҜaHKf9=$ "C 73Nedajv4ln2D(pW5RUx8 rjƯ/cP'v>ќ[ӊsL?^jn6"cFN ipPi=iyR`wL6%qޘ۳ ʜ:nG\SCͥ}2sAErL~RⓞҀsQp2ZQ=ssAHRd9ғq4`@L82;)wA4ۜg2)r2(Ve\ٲ%~SpBpTm9jQB.LmYe_FTgǥ<w2i&#KyHC(Sv"Qn&Vvpܴ-$`|'*rrNM0{bʼn#'iMsu AbzVYt9@clca~*f슂4.cs_$Iy[ZKĖ%20|;V5ȕΆ싗+ C 띺HwXGpAi)#R2!V OA#95њۊ⪹hO=qS[3V{v*H`^"#>b;ւVX}4f,F.}m؁@WʽOrFFYG_q +EypG܄f 9` {Wս&S)$6.:< C]Ok2H 8#89p6͹vs򥷊I03S9)jRN:iS?!fI\*!=WK1O(>sV@c<J2h]Nb]>3{ThזlfGA(bѧ BuU^v99mJHV1\:_]m΃4m6Ěa$r{gaJ"\|܌Ulgh^]}X/.CX#ImWg/l)j Z,,O+C*6񜞤 Kn 6+RNx,VrbfNx{<+V0N: 뮍17dZjPqL? 2=GZ̹(3{W~_i'n݂UԉR\.O4ǁ$J6 wi XU_Z6O.:ִU̝#dlV=ut;wV76qEi84Pu0P*WFϧ O=*nAR drhKDVpwğ<{Ѱz4Ļ*wjuRX;b+QIݶ J6NI=)1LD89IzRx1AZFn3ʜѷ`k 1O pK̦p{S`d.T>k+>czl۰})ml5'z-VkiE2>}1L n'.GMmit1)!-N 4y!(eƊ R䞠9@Y" [κ D7'`P +fH\'/O}-MII]ǠڂC=37A0qҕJkA=Q) D)FsCHjDEF$htPTzTmT%4Z~aCTӊVa=)9Sݳ9>JFV ҝ hS5}i3ƙ7Ծ\7jH,}co͎ԵT(*rjd(sUQ1ڥW-װc+JYG\\,p#A9L Uٰ=i POzP J(1LOBOcޚpI=p'Қn:<ݧ'UbmSn r ~Cs?ɥ-ip+I;y0i暰Xz1RZsڝ;V&|TJʃ5e">TIha@"ܐĚ28t\(y57 銂@A8`z&4` 8gL @bpG=HR1}`zSO_ZbkrsϥXf:fBYRXqҕvFsMB4@Lр:{rjF)=hj5lqGH1{SCMu mQ T2qMt=hl@#5$cHJW+:ұw4;S"7!Xnt5A/N9sjS 7*$$>kic(8tܹ~z}@zM>U#/ n]V UVE^oVMאNc!,^swO!z4F@$S8,t94V'wĨGрxXtJ\}A {sU#K;0te|u*wRCBC#Cک4&䃑MӇB3g=N)Ǟ)rAJB Fzpϥ&ܶ{Põ =sPU UsFrnÎ{u$ !VU=P*i ӽI,[Fi W)caEBUޜ\7Zap8HPIIQ灞#qJb !g=ph U0&Q9>ӎ#wRIX`dgBd֓W*Ϙ:A T|h/#*~E"c$UfQBH 4۸$[P%>`20`11Yb.OpsR}z QEk|0]dMe~[>Ql 7SJ.emw4Jj9>$ʬ2D%ҳwvGSOKN\yQb\G<z ^. uZ2,kR@ǭY'EN.Rp'SIMVqQJ;ҮA5ࡘr:t]#S9i0vC;~A6Fz{AJ#];^<)jx +WI`YAӎyUdh(x5,*zM%C̖qīu9eF=}Ӥa'd۫ +e8>I;]\l[<`@RiŰ=;n6Hނ\AO j!9R8s@z;90сi3( E AaF1H@Ґ$@#4㰧2ZPWzӰogH18b@YzUiN(B< ٩vy 7NǕ*=`Ҷ@ ])X6Xѿ2M 1 cCN(c :D?{$c640ݪ\b+ /@/֘1 WTjb?AwMd!H {f*XYzfz*PFQ'SU/2QqC枘P7 G {+)i#'c9R~iIb>%E.G&FGZ~M9] nMVҝ:V M#S@#1"^zPbONzQJ i+($~8Sv3N4bGۑTpԬáPLU p$5{;8k'TW KhZ.瑃Ҳ'uK#͚&U<>uc?JXf E$Ƚ*ϔ/y$JUNqF#oj|J9e=*sYE +VwJl2mZN3RpS2:h؝Âj,aUL,.-zt?T-j{o5s@<m#}ִNt<Ґ幮?ه "ϦƤs.ŸnG].}[soD%w皁|3"$~줎d=Z{rF*>qq<< 8S"K0qQK?0=;Vq,=+1=*ԉiaY(VYw4=@MTGj{Fi_lupO 9$T-F<z^5e>eU[<I1F'CXLE{淬+ݨE8'+Ӵ?KM0u'ꨭ cM9;FVvٹN8T.lW~e]xʹnǧ\𺲟+Q[H@V'4Vfe_ƈJ]ĉ2+߷E]±8JVE=t'[0rbK)W!I8$pYO94:slΨCj&NS\S0q]* v9jRé^ sYfhyX/ozPyN;֟"-IrƙzV˞k:+2ȱ_4cx?g\CA#;W=ɨN OTNYnd hꔒd U Z2q#k\hk$Hv_5qDFdvUf2E$r;;0I$ AI%X<Փa4^Mc{kم4ȸ<ն2Q2Ano cU ,U *s1ہV~.5JH^>o,Z@sy<Ò;{ itEP2Z6O5\4{hZܸ2 cuNkR0p:'5J2K=(vSɠnb02}1M#jKi8?M) 6 FųwIIbrN{3"6r9 W#5\ߵd %ט=k9G*2f3޴KRMfD$V Iܳ? ɛ" F {Bj{ ROo1F6sQ;bq)9R8#N1[Nps5Co `0zFQ()݃9K d>dG[F*y iPFz2:ћg3]vy <  1=Q0ph@ASYN:cANg5%S)x=?:c#N; "i uD=JPA< 9'K)A=){PnjJûBs qQ Ê#!_zi!'5 F&v>&1ZRpOcXE0B iCcCAGץc<9&7aҜv4 `9PyiqNJzT O*z24X6H}j#Y4Xi9<4Ӈ1MPZ 1JAOz!PM4b:pLqJvE)!g`)/+##PԆ#0 fcRJPV4!i |1!+ ?:H֬#Pޝp+édfdLi<W,$x"nq޲F "uF*9`@ɨazVUbT`ҩ^tjHG˂x)VD51eqPs0E ̀MK)>15RVW|(uApTdJ8N0PΪĕmW˸HʪHܔOZ( $bWIuchI=+#"Tvϵskrqj4249ps]=TpTФNj5;"#VZxoZw+ظ+FiHHc<ՁpEstdp<W$I1B\H8P*)|W2(݌jF`psY7pfpkV69wg{b쭕-+bwӃ7<`'?+^ҠrN:*& 0PV`H$4J >Lhª=҅}L[;OĈyֲ^ǂ2H4oѯ#9SS ;{M̜Ւ64p+:M}68aC}+u:wen [<ùOQƷp6SvSi]%+:fcB)"-aF< {&`cZD_ ߼JeWE^w0 :Mhǻp&xxa*}EuYѨ@)>AZA7m4&9SL+k 6֧7]jʳtRrqޚe.!%\G"A{-śsGsشZBi+%Q;֙EoN,?;GCβ'zw܉B[Uvs =?JVnNWT*V5KV,lHI V#FyAg4s ~~°%`֬51q<w(#}1Ek";/ ";48Ml|cq6pz4u9bL1"yT*9秥#1 bF:ų,BT&J{ QcE۠L!Oƞ=X8'ץPƫ!gC=_ g06pGYe󤘇3BcŸ k>1bT;ІJH$nSR4eܼbvg}x&\kFBBdŸg̏9WNc@֤08+q.4ؑ g2`dVq7 BUVĖ)#~\>dʑ\Z3q*z 89q8gbtQ֚A'"ži^F)Ai o#ijk'9`C4Q"62)=ǚzS4G;J\IO K&x50 :Up܊@)x,\ h@=,>n܁jlOZnړC r;e9 ^j"'#˷Ҟ8 /+q_?)Dܨ{)Õ4^YP6Nޘ]7.xjq&mlCco?;w_Qs$s4$2qzҡif76>TZCMgo)eǯ5*FWltq̱a¨M&AVWW`K@YGQݲ?5aGzagr8Zdڍ#Zл1Dfّ(z㊩vU1ZіDrsXhC{ȩar*iFC`z֦4t$?|p09Eo!`\}kYZzk#uG9iAXZc5]V\Z 4q׊bIqYZ0֝ܶp)2QJHg"+qҜ `yic"@;摊:Rttau-G.89L_Z0&TTK=LҐn P;Qmi"nxҕpy <`/ABsNng n3FSbT LsL?ZrLHpx4=@֔pqޚJyA/AJ䚉S#fmzԅ2ye" Z@AԓPǒؤA`sCH>V*@G7,0qR})Lr; P͞E4i1%i⛿#@ 0 &wtr:kٌdJ<eqO2 &A >SH~ b9Q@i Ir3Rv >:OF=(x+ du֡V8.:Bh8&y)4p3j0 `7 n=4\@OH; &M(ecQRf 1T֚␂3I0Yo#YnR:}jazTAKX'AREqQi9ǰS#)eVxP'yn&B<.1R`&10܈0 UyOl>nUEcoN: klW'C֤lnlCNg F[MwTǐ`(PH0H0b=Ggvd֜2zRՆr)ўڕ@|h#d<ךi+41LJl:й$gJQ\ybF>F봟Zt'*8G$tm1Zix+=j@8=iXIŧG9nW$y) @㌃^mu,L 1W+|U5y72;VRHT;tvz JPcp&R`P'V/QZ-iya kv/B?:ɦd>b88#O weO|{R ֋0A:ti8.7|0M52nPJqI^rjl4J>~Ze pAȧ^siRcދ 󎿕*Th ZĎ$x4V~sNRJ窞+cN,Ap@)(꣉n݀*&ƋoZslw#QNL'ڳ5 T5 >nM1B'U;DK1!wOL vOa=Z2= AT`Vq7dx2v? Ȓ4?{+Z%Y@s_& k}qTJI,n0^kKEXH\v}*ރ:O@7궻l!H0Ĺ4W&:}>Q6)Z#+=Tι]Lt @$۬~b+mlĵ8ylm0e?69\?ƹ ]ٙzתM rMdhs$f#*P[Hؑ5ro6$.sZ9hdұ+z{Vn6*$rX`>j #?u{[V}qBGn ͏LSN#sw'Rd.̳gJi1eA5P2 իU('6 ؾj.zRZQ)ܻc)H1k'<֞sH.Puapz`杅=qAB)e^q4 ;sJ2z ~tn̸#|tq>N{{sN7ÂW9QqR FR 烊 ֍v>6ÌjwcRq(NXw r&÷$Z{e`MܚU 7Z9mJx`c5BwJd9eAl+3vEqBȞ[uYyJMo 4 P0qƭ[^*gRkYylʱܒYO2;qKbљw]}sscI m z,32GUo{*8g%I= tʮkzCdqSOc'?hz+cF=:ԙ xJ0}HwdhdT3ژNIsw?I:S5AVqLM08<Go4ܗ#&ry“ӆiUH=(Rx )4g#JI>/z9̿J\ҎH4ͬi{Nf1>ޝA  ι\R~7@G:2Hƈ*zv798zqސD##%ROv0g=$+ABX(ҫF( ##jY G=Xѻ۟-g[0<7LVL4H^@X9c ؞XwFW+UMFFqZRP$U)a! 8@qSlm`~Gnr@"͍K~bp+i[p'7{I%a6xޘr; Eo=JLy#e`n=C&@pgPoԑUvHR!R~T9{jB0%% 0G]Ê|`?<XԌVpDCo՟_ ,X ;䊵iIiE O QXj1a꼊Y}Jc2 3:V8^0q2Z1o4j%#%zS{q s ZpF^Ub}vzV-O*ʱ٭+<8#pSV3)izr$!<:vjƹ3ԧW*H`8n)OvN< ܦ6 8F{ԾX8hX躝~ṇvts9Gjoj tֱ꡿տXPa:ݍGiZKu)#µb2ur=2ts<售msxsuww/$Þ0JȄo"bm; CBH4rsRNSi'V j{W\Oz8Vm@hx=jrPu^h֦Iczr!BRJbP 9|dAYE8zv;E/ dhP9n١(=A})c4T'z1K񺣑VSzLQ=sң:wUd.'!$sw*H7zb$  OU~z⋈t$_aCh,@zuw{dŸ#UILԖʠ_$ +$ݼLq'WW Z;GzN+zЪ9<Ղ0'UyN(?P`@ Esosn)1$t.獷 ah.78R7^=aXǥjio GVi8NWhƝVb|2nAsmt sᮚEp|11Jɐ7hKhβDܼ~岎r]Cj$kgX?0997I+EK0ЋԊJ 5"8U* m9昀6:ҞH&BU|;dHtLPh psɨIXcpI4=lRh )Ҟ;'?JLc֜8SU@#H1h#o LvSs)HӇL.VL=iy=i09`dҙKQX n{bIsFd p3@5ZQM(!=Bej6e9FY ix+;Dj/,94*Ԋw,-I7!BxTsp һ+MGB 4д% UwSi⪆cORqBBlf}QئTb,#ޥi98 4<͌0$W梔*|&8ԛ3-#iAҝ!$s!q&ҧ'4C$ӜtR/V0'C b<<H:Z sҁhL׭Hϸ(5 jDaو>Rn6| bހr1MwʬKI$-(rj2x1jYY*P*[[dSR=yS'PmqZp*I1kMC?;FzTsjoceV: !k@il$gH)dt d)'$*l~IBx+:=&ޢj q҆8⁁t\PHk:4jNMU!c cN9F(?*1Ls;;w.sTUSƥXpHiRIhP3:3;.O@ihAZBlpRzi!Ǧ*Y[;v3?6"; c?/cRd$e`uaޘBbIRF'"D$iGBpiJɩcb* @$NϐhdAUq$};ԊO&2:xMgH=DT_˸a [ DҀ)LSa nW5 By[r?b8]V[LܔMf^KlUףHFN}+U |R%֧ =H9/S=kBR@۰NӁWuJɄ &4CO>|P)cһKk;N#\Oz$vsIɝ֢pK4a$Aȩn0# 6:VJ3.Q{zօc TDk׹U#zҳlثr#F-Aoy"Xr8@ $lŊ3C-Υ3SjCWD,I<'n*H<0!rG8<+R%e8n°9.vQϽF$p2;tbEBپSuOYw9RҲh,i&$py*2w9nsVN \8 ׊b04N@w&$r=MK Q#q5yL4Ӹ"A#Pʠx0vxRȩ*BJWN@=]U 7{X7R(= 39E 0#8={ F@k0BN}{[лx{SFV2(}hdqO\󎔅/'C@&D@ԤviNiXcQ9Oiq:^aP2FqSb79r 0xGLMhKZL 4rjn; h%GҔjRXFMt J2:?HiҤ_QLI$tJC0P'a G)H=GzcChAw\ ;'qAv")0;'RړHxh pRL~a cW< =:r ɦ-Jrivb@:e\  TnϽ h84B*7 zV`G5!b8u =LϭFAgsdT==y`MKcwj\}j"GQ68ZLڛApF9+dj T]Xi6EF14!ZRYrxR' R*;T|OL RXYr֞6 zTr8ȩ#l!J"HwQMsɨcA:1z3RGzqaLH<ԑBMңHis֩z櫱:HDX#Jڍ3TĀEU؛8ej j<SC5rOnyRMvZ_-o.^fsR;FGJev=sr9RW{T0iFO4O l;<Ѫfq3ls'$z|P^0NsR>6[0s\쪸P0)e%:u'8Hw#N*RL`5^+.ddzRmRdRcHCqSޜpy}h2ČhB@S*% סsҠEqیTŶ q/RT3P6lԫ QOFj([wA+Y=)_'1h lt(`I,FS{($.q?=zTkh#hÈU,;T2:R*T.s:SILS€@5wHMMJ.޵,DiXmHeb+vj7R{SӁFO;H,l 8`P ʌWȠB{0[cqM,Oȫh85"dG84'裥;$E<?UY9❝Iؼ9pǁUF\r}j`>dՍ"r[!O֛,ǰi$b[鄓yt ;+>q8s`S8+:.zA-دU&$t'fv^T3.MwGsX6*;]:g\4m"iؖyբEks=9;48&@0:R.pwjPFxnuzSNQ S) `Ӹ iH9 g o?y>[ƍ)GJaLw6;h>OJ4jP$db1L[ҌaHҚ@ƟRmiN)JG4\ ӥ;uJqM!҃;R `zҌv40!zcc(Ð8Dt4)K䎕;ʞ}*A#H2 &yғVM84w\4$B1N8ԁҗ'h>T*GJzR`F pM8a1HM W t4zfӸ\~F8cޜ9(\K b:T\b% sT@cWbzUg4i1ۜ l`21HF(z 3+6'J⛒0)sOzN0qKhWM61ڠqSJzc0a1WsRMUm| $p~ M($lR`Kx`b.OjsV#xM \87ص/!W?>Xj CɨqVC!jXuX0۱S-̎#a3YC帗Uq ˊS5u 8\1x<%mђ2EU1Amz6`ThcPM r;Um!RIW0Gq9'h)+:R !?0jpN)H8iGJA'~ @u iQ׵+r8A`x3^1E 4ߚn <3wM;1`ӷڐ=q03ZIcɩLeIpq׊{d S 9p8#)Hi`s$VÙrįn)ArތsOQnBN[rIja]r7yyHzavR.HcL(schZ  ucn}; [Q憆 i%RqRYVl$1YW;7~V 1infW~N9i$S2J̱TJ3TdbH82)iQ@Ȧ2iQ*!y@Xzm$zJ.$2͞_ʟ&T82pڐ6U/>reX_Q&$1h,yb۽p1SFQO'] zT'9lEq&T1Y7HPN|8<LI]d*V~.FF)אd5i<0vpOQ!ԅ>!Uy@N09(ypA4u$h%>SUPB-Oth %u(pl52ϑ Rnx{nITGb,3 unxɝ#drj#*Q?JB@>L7#asڦRtC* @I$H- ;zФNP M sCb6i.@.23]ӊT#Ԫi\DR =(ޘ\R3J6]£e`߭$$=A⚽h@Zj?k:1ށy8Fi`B=i.CJ`4n1JIlR$zTGGh故vZڃ@2p)IpjVv531JR/uSUN| M R[~q5g6$܁8cVҲ'l ^,?w 0]cM6BvSVF͂2;$qOS8iְ8 6 pd'oB3sM6+@$攆C֭*"6qӌyyya4GjqێPbtn(\,.@ӥ4 Ay@.#K8)>ԠwGZ}jOSl7NpF(VQژ8#ޟV"9߰wU" ;搰LZpJwZ:~wdeEdi@y&Ӷǣh%[\0,G5 ryLѝ}ҼJH0'cH5F")⣳8隔n^ wZ5Fen.HoGn{ pSR7ww*ѿ\jFPT 1H$pifRdxqQ̡ҫYrE4>4@x9e,6<Z\6ڤȑC)ژԇb@0@ 8㠧)C!$;Td'ݥ@\u]4D7tϥ!`4 I)t=*6<) }_ OA/8#M9=sO9$;dsOqVXQ6Sd\#TNsKG{zSn_qޓCL4qIT+7w'$cFI s@ZP?c&rVZ5ZhH9TXR'dR[F3wlO;@@9N)"'ԑRD7 SR JgS*4XV IB}b W $#,n8<#*I"$i!*v-W#uU#JLrF|aC7sn_3{tp0qI(yZy{N:bՒ G=(*蟌X2qޒ5⣝ .\Z09?H$rm)P9'c %p$V!8#0'"4(PX(%1pTW%\IP"H-AyECY+VPIF{.#c\l 3ԓMfNjUr*C !.;2 }i&{|ĩ8@F2Aoʾ*A6H㫓SAPQr Q=p' KVh>e9]9<є{`3c֌bI xd44bʐMI; W" 8NsVqMIV[z[3h<zc&cHny#)0G#4;"8&ӚC0=i7*,ELr3Jp*&cqE g;'!,9"49=hOnȥҀ3B}N)w(05 lzSD6ANqJHp@SON{P NO EӷzP"Ējtoz皱,QB4XbN*LÃUnH YI8jorI9f*${P&Rl^h-1J%m r DCc#8Mu l]te8x]0FNM)RA5zXPx07 r:/.8 ֹ%x G4Dx5Ld8 Ẕq횓8U6bSa"8aK 0xg*`A bc?(n٦q3vr)'GV^"V\/$BlR)bҞTms#)qH&Lu^ F"$ӭSF$A2}M0Ige$hM}?LRqq֚N1bLxmѸ;"8d9oZ1OIbuqP>cAH8b8=))i+/lO6/_z,"pz{)cҚCqSFt4cۜMBޭH=0J' 0CȨoQҧ%r}c9!`:jʹ=N<:p4S( _%IsҫL حw*[FsPCEUsI!6W%vWgOˎXTM;^8su'IHQ1B9&^dH“ǩ5y,`U{ǁ)J('NO 2*@/h l\ 8[$|sjBśVdv"YRێ()&4⟐H,#+6lE&#.2A➒g ڝ<$@{=Ha5XGk@m^Da;ٝ ?7$3kR6t&3u>X\S@7"hiƁԏj6>KN DZ 3MF2 ]!OZBT~,P/;ڬ*;;OaPX%X`a˚NW)6} 2yځ=W$t2)Ŝǵ4n`)(F VSNE uSs)I^ c G u&6pqA,iE#8Ґ>qށ``Gѻ)8R #'4E3i2c܌S:nGc(o4ŻQ9Nv&;k*;!&d]` 8ʍ{vCLa#Pr}*}Ill$D[xcNۚ]銖;wxxҎ:_ciHR c88tgHilFq/OZM<cHI@j't&gM{RiA NElP!ųzpi@L`HpCub84hVP(f8  V 4Nq֓h=[Q@iNFiȡҗ aA9jрC6y3<ȱҟ'Ҙ$.QH=)HQ!p9ЃNLS1pBI8MD1R(`I?H i3zNz9ݩ N1߿Jv[Ӛ\pn0zRc= UEԣ\TS0cqsZz^{dk8cdmx-@ym&%Z\;Q޼A"93]N(08~sXNGDjw; PT8`;UH[ աr1IQLҰ\w5 xS@<{LSKZbdGZ^(n{Rdʆ; zsڛ(NiPz?\ y3H :tC"9>$Ԩ۾ }x@z.x#􇓞S=ij@G8zNG84*hi93F`׊C=2)3jy#czZ]iϥ84 Տ iGCO`)TS:s0 0g8RAޢ `܀z԰7yejKE~,d1ORL1cQ^=%XdY;:5 js|zvk0S E$6(0TęDiA P 'c}q99=&i9JYD09?_h{5^"`Lut6_B 51MuHIcPq'!b@IOZPyELivz%hZv!ɖJb&R~l*'&Uϥ:A穢Vtw^ vzW`9RRY~e<Ҫ8O+=i:zPRsG"RT, zD < ҝzr)B9_jx_^Q#NpHXLM"2)9SR18{-ۑM}KѰVӜD9jm|#!kE1@+J;3R)8U~Ҭ:q"z2*2*@9#9縬smo>RÞzRHrGN/$@fEr-Td;shi-rKH9[qLSkm,ȵ#쭞>ls+-9.MRc^KSƤe^? 5IʖB@o,9.Ug8nE=BfojUGejK#-N m,j"© +X4yFc~EEp3Ab945--i2q;UOβqr_ Xe8i456tGuʠ]dKwʐW749pw,qJtPjܤg5QڑHikbҤ;h)KCL84eӘ@!)9O. cQ$3!-j~7 LHn 5 Odi ӀQAE8yu{]ޣ&B`g4`yg#O@=(9chwӥ/qM;P;ތJO(;)yHTv3נ#ޓҕzdaNIϭhl =sRTXiOA xjnrO=hAyS $ o$1wu`Xm)K b(Lq~Fs֗=9W'Լ֙qJLa*r nCHl'mB7)W"yVb,ƞqiqAJq0HcTnR% bx^jI f=osQimrYM[a6y-Tr;Ա0)@Z I?9xXn=Kpmf?4IPԚΉ\gY3$jqgk4̪zj, J lG"QiE)TqEMu"d#`Y/)8=*Y++޴ЅV+rx Lc4LXON)F<y=+D&941`w44$R{K$S&O 0=)M4ӃOQ\\PxNpO&`!ASJk )QщDi8j5abaC~ s{ZА6RGv^8&W$*ڌp}i@SX=*SRm拌gl vT2XgMİ:El[nqֶ$`I*뚛U@Xo'Y v,RY USwЖy'Lѝ%$F߱S9)_Z2n[qb0sWbԕN[$~5Lc)]ئTla-Fq4ShaZ*A4($(F\{[Lm4 1⑔(zh,H4F6Ԉ9O]M+!?v!RsMQaP%az@"8=)փf841Xi*)QG:0RCl`1QS򧹪 iF8*Kw5b=ix5SzЁ\FpGҎZ0"` jLsLiȤ!8 HxR=)U8)aà!O!t;Tu'r:Ǩq@)E'`80)BpiUz*GR^OZ\c zNP=iTgo=hVb~&)HH)9M$ΝtJ\4 R zoŽ;PZv;8۽t44Rsإa!r:RvH}ќP R1Iғn}i#ji.sɣX(/ q֕zhu4!M֦ ( E+]ғ'uGD'>ܑtA: |.;Q}@X4į^sNA0ɩvoQܷk+F3V}Ip QRBR( 3u[iP{U@,AJ4 A:zm2\3Y:ͽqָ86`i' w39FAJ_A\svD{qRG$L{N41w7J a$u`Sؓ20yɡ\^xH2x.7azOzsL\'&s;)Z=3M%)@'Rvg֐'Wc+{QRQv ڐp1NL: =jN29I9y`f#8Gz0t+Fyɠc$p`''JpOҍ@2O($~4&qb9SH Za($Qa XAsiȠ~c\ұACͧaT}(#=(a b)ڣ3Aր(֑B#8ib Z6'ԁxL@^sV0oƂC˂0*Gb4#gB"98W["ĬҸ=S+ 1ޑX\Ҙ\ 6Kȿ7NH0QAEH'v$G Qᅌ[;Աd|E8sޣtRi5%1qx|TB^*g0y/t!Y7G045&֯>$C}C\^g暱r˲ qQ l)z4WC+%24RpOjC['"8M m@Qr6&F%`:1JW<9^ֆ qIar( qMРёތJV{n=(/4 4{OZ\bЄJ^ir0 ɥiCs@@J,O^=#*Xr{jZAb2s>u{6EJ%0CqA+b9=j8]K)⃹Q_$r!21ۚHF)62eI5OUve \DKITupF*-bFkE$K)u\gC_hf1a`SI +;ۻܲȪ[ x5e1"2;%[qSDW$T[ZsPw#FO~0j 5%+`݇ ĎJclf'LV AQ II*q8)2GdѸd߷#);F84)9qJSd\!@4@ڑvzUیJM;lr:Q:tkgxlЧ@Qȣ4qn}i4 AciNhCb[,c|뫰T\#䞜W<`sxTJ EFmca+5azZײF Oa*=^PpEF+y&I>ÚQ$sh z+c֚*vTOZr2""i$-R '}\p~z7x=I7svcqS6y)W! 94ӈD'q8OެA @178ǥ; ֒Y6!n3>IB"u=VɭeT@Cd7bڊ5s5 RK§F5ܢb9OaC!ڢ8rG֗ )8EW]̬'48 Sr*5)7 x9;@Q<hQN80bi=s)#v=IiRnE *r:e9KQ!H‘vR(n(@Iۑi`bHrL҂zq@<7*{~i&9`{m Ѕb SJO-R X+UP{Q=hQe$R8ϟWd.2iN9ȥ  @s9N/Zr8""E.:ԣgPqFhĤRMO#0^Uu=*1FǿzEX$A_ʬKnLE! 9(8R&iN)8n{JR'͒hcm44Cz ҂}OJ?  /\ "p)qa4E"r )ɠ3G`Uy4z:h(Z=)rR}(x;gQF0hTi[sJ8r?ȸ=$xE#bX*MKؤUr8j*z4 IaCsV2ȩQ$v95_ag^%b6*;i zmLQŒ;F-e%WN|7ӱ#|E67lS;B F ?i)f4X;{pyVaGQOaF8JRy52˼Tr˾H =1ǥ6+zZx*ұ# cC*Hduu@N:Usr;f3VyDjÅ*qڠKIZŊ++qF[(!ehrZ4SI0Ur=gq㡪[VS=jlg:& 0y1Ұc8B-ASB&#;sQivxRdx<Ӕh'iH9=饱p~\cgrڢ8NΖ԰$2=cM͛ ̹Z$fp9JMe};`[S[v Ѯ{#7QC*:r !&Ȩ.eGئwC,ںFT}ݍ]sQ[8`+|y4˹=9z̥+G=+U$1ǿ8 H6H4z'4yC@Y$fҠOLdi 3E$uyz rQOZ>A".7DE 8!E2FQ,q2`@"(fD*P$o+cp j5))s5T U G4`Wˈ8IҦfݔsG0M1!1j6p&ae3ڄHq8ȍ\jD@x❴<~`9!ǰ'ohȦ6WyշQʃѢc8lIz[ܛӑVQGZ. A-S@ Qt(AӜnIdzSv$ӎn[Ҕ`})(} !:qA 2JF#3Ui6'rAviQ<BeoL̀*6@3@L$N}E!79ri{ R%zҜ@x;R8Ff֔ctzPFi :Rgi1Ka a҂Fx4™;y$FEHg>Ԣp{ӎxZVǹ8N/R٤Y'84&8,GzqHYS G5|dUGdz M6Gf"nӟI*on;T Q}*g8:FǷ8dͶFIJzXۆ`&+OPUPr Mo&M wK&{qE>ǀjT*l.&{ Aa#A5/]w`lgV#v'ԭ(X%dy<Թ KR%ӜR-ҤJsNS'rL.qZw}F']Ҕe?4NrORi頠>qBHTq[HI(\drE++qJrH)fX{w.n5qp{sґ0H犛-rlp[F򉻾iP:-pH#_1ۓI)8ɤrт󊄻1H9#h,m2[@V&2\nqۊH0lJ#Yvf1qUTPtLPvdzT,kUV%+ҥirq 42 zsPcxSN $S -I,spUJ]ϽIr/,pK/9Z+Cԣ Qs҂qQPH=(#8x4E<{QaX9=:,EnJ,R-19"~AT[Hjڠp>O8Tr*]# }Xsb\ƹ a$B7YIjA܎Ƌh20X`dPz u9]ɌҰ+ t6eR9rJM"#l9W~f $Ԗ+[rN:S+T4L2dScCљ{Or:T1ّ{jݳ(FsQ<]g?CgQ v]ZWdY&m~ZϹ5i6;v皓r<EBNA9#H!(4em;B)ăqS 1U$Ҽ,֋1XrG^i,BqOr7S/]U#jU%v< E]MiQOJmhJӠ,{XbhȢj B󺲼Kxb<{⎃873US!.2vR72 H,[RG4 O'5˖ e=jf$߅].1Wq⤉J\H9:W}9Kz݉\v)&r5 dnIԲ=Ri3J*%e,HۚWP'1H GQ*um8& "MR4ŐN :1ZiX.=Xj9o0st\H#[RY" ZW-V !-'[[Ny'M(_ߊ>_#՝щ峚 :jH e1N/jm 2j}v8-Eob&J _z\GlHfP DivAE 2)Oڛ>lz.H1ⓟڔh z6(~ͤyLZ@) jCNh%R:ԃ> 6E<=iq # H[ RA}i[VW*3qBҐ0#.G!㎴m r=M1sϥB)/ qJpM0"[4zRVrӺ ROJ,&/8q(1L җ4c8'˚wpd LPðí'NGCFHCPq9u#֚4 O z<{1@4MIOF֤ P&uSS0R7Қ0i b<bsHxc~ca4mjsQnx 8>5pdSJB sM3Bl:AjLKS=XzI ,EL O~Oi2ܞM) X5I@V4^)F"M`?0zQ㧥 w曁JwJF֝ A9`S@8=)wQQGj44 K<әGjC0)J8!)v==)1NSJ2sH.т1AZqZ `r v&kбJ:NR ZJ.HrgT*x XbA_QMf\ry*yJdZBl ANFxr15  X@ 犌3 98$8a v}jur!&n8RPr2{TaK S3NȔ$җiZΤY*; Te`R+Xm9}9ۏMlIHֳv\EX5&8&ifR%-dr9OQTh"T:S&l'Z2Qn[!<KQq*qO~[o΀tW/Nn?JIrpQAC~*j[=zUb%W#85* AU 9 y-9M1 C֤"(9Tz RXLӱn/-b#pfPGՅucm-בlB0X{wE$c#a]er0Hrt QJFSU4(H4QJj!Mh՘7qӓҦ,m%2.િOҹu',ʼn5u=]$셉PrFiGl3J2xLJn%ʡ) Gcywk >V\!U,DiOaH$V;G5M%W,ME2cr}bwI>/u'{mc.' ͻ>1▤shjV*Ft{T:ysns2}* ~uBmnn %+е$܋ҹ ZV b0B4b.wB<@Pqg=HhVi mÊϚI SWϔA?ŚskH+VA:c'5BI$sZ2aS-F+)ZE `Ǔj[`ŘRƆܻzOV$'Cbqm@s)(j24bQp)L)?JUnLqg[V\jXf94ubO6h3)̨]py!QW "}8c@ YM<NU(س !yN1y1#HD82G- jV*ߦLհNݪ1*[9d7Ɔ!e5뚭Y$'*9.H^&d!MZ.kOgJv]N-ЉD8ۊq8={.]84`Lcgcֲdm2N8fvm+:"W#M&c [E Uf׎UjX*($MCjn(ܿ09'C|} d~IȄwo(qY([H'Ĥ_mȁ:"qj4ۉ "sYQ06-֊w` 7`9rTӃI6&l8c#5 L @+F94qK[ .irMIjh^t9֏9 2\Q4@*y+5ϵJ1P<1)JRzdVJHҙg("jpڎ3ҁE.r==iFT(Ұ8P~("b /pb!F˞iĐ.F)>+B)T6Lc'46: \}h$4dzsF;**nWLB Kl8 ) !Sj3zЇ#NQ`88Ѽrh4`i13JJ `KgRAҖQۚCriw`')~Iv1H@<OoQKǽ&ivҸqޔ9zPT(Rԭ=.vj騥"{P6pǣNx9iFqFA2H>lJdfN(e$#.:ujPW4)h&L9Lm)FFhVqe 4gd(5"on Hr) '$:3L,+6ڔTPK?Hς Z%6R!$GTǥ U4̿D0>e?z c*m Wt &BH:4Pw֕c`@3bnI\Rft/.n9si4`]pM2]ۜӏP2@q3O}JqG#.wCLh 0Av31FTq=IXW6⚪M;|SRG=K+ң{7//boS?ZT bC n,1zQq vy=m;b[h9擨4f21ݴg'['nId,*>mcvFHVP9l+7&0~GLtz^WVmΓuf&fGJ[v26ALb'WEijZї$?φxFI$00X lQ$sVUסZM"fS ѨPShi$es+"*#2?Vfe~ԩ/4Ry*I>w+MRLŎFI cb%"Kh=c cZǕ%fF\Q-C1ZqL`Xƹ$fdf$<1]w!W`Rl}酆)$N4Nhرn)$,TsZ1p Ч` #)rߍ4cpipqҐ;Ӄ g(c4ݦ?03ɧT=;Ԫoz0*f"ǥ9q?:M4RP$dr{RnTJ0Ut \#^i6#QG$3+Jriw`_6L8s@XB9HwIP$sJJһz22ri5/ϏbșyFӝXv 9Hii9iJwc4ݽ; c)ԠR/Rn8m{SN0 !XEPGJYϵ9pSGJ7!=i<OJiQ!;y'ڗ1N:1O>`Ć\8(S`2łt*ɩ%YI zTy#B'I< aޞ5Bb*4-ҐHz8&\Mi|zg4ޞLpChw[5㡥'Rxa/1ǥ[a7sW-;b4m`d%d*q0 9ⲣղ84͚sipڪUT9,`I~Y@\\Zi.7<)CNX SUn-#03+anj(=rZi36ʟecugQzSDEXc9#Uo5Z̉4bRӽS*dWQBQ&4,>Si<Zb;fb0=Iw?SQKq" WgPAIEޭo-ak3H%AC7qhhoU"y6Lu8o?Z-E B(UVc9C::ВA'w&Lո '9朗`YXvT%i)qPrCwLD `fz:Hی˽-㜊 qEnTUCs2I @P1\?is5ipޘ.KDZFWa蠞'f#"NF^%lDP!翡/5f Ywm<RC/F.wu5g~V njU$9Ux~"jTj2HȝJbzsޭLGM15؈*OZO ."OR1(AbdOZr>ݬ+/ InPi^ U8)CFawjPFTIJH9Qc4OZLg}i켎=IҼ-Rn|Sr;q)lO!qPogs&PSpNxt&=w #֢VS8ip4i^80lgh! 8ܒzRzS›9F(%2@s׭(RAɧ;s:R18⛖B~4qژ I wTR=)2A8) u?TYSm;܀2(M6=.M'N` (9BJKE&$~Ji2h\~IqZ21>Z:@ǭ;AaJi;V99M NьsNiBirAL&w>Ɨq4?ZhVgiz2i>&'ӻ598' ҲjP\h9Is@; ZAf֋NH(xJB`tsWv=@,J^kB)rz`wn4A GOQGx}i4b214-t"zqC(r9Mބi0 Ȥ*I;E?9#44854ƁJkNGZ8ҁ̊qG֚QO*qN1@E0a5JW=M1(N*A$i7QrQ484ǧjږ;I77JA;X{)wBOc0hR=h P (J+'\ T[1RC*OԱXW'ENZb (N21OE`J)ɴo8*11RNܜqZE\`҆]hxQFRM(8#+SJI4'Z0AӇc@bRM40iڛޗ( \$ $ޓ ZV~p(id`SzQhI6ӯZ^4 LJDF80JGcPJri`Jmؑ8 94GRГP+D##>BxD*wTdRܤf2O5CWw?VtA$l/3gg5IzO%9$`Y83's+8Tv>!hs!tLLFi+;uue5BEb3"m#T̿ 6YI4 jR)⭼ b[}&|pD㪑R}a2Z`%ƤWqtٜԟk?ē,bةu`ȪqSHJ>Dޭ?l񃟭g%-隕Fry|۷Ms*3ppsi#6}=*2=% gB#d. FL{mO8B2njqPLP)G4&65xNp)Cp:ԋ`"FXcFIX;my34XYb9D,A$sQq&9ϥR7Dd)1v \~MGQ;5෽ >Q\RsOcM0 yzkAE%>'҅֞dI;%E?c:*E946W(F{PXK2Ƞu&S*޼ul. m&EhhG2@#8qU=i$sGZb'#'4@|@l4SQ3FF\qN- qep[LK#{԰!=) ϥ+#i+;ѓ-H"Tը䆎y4N?t-T`D[ӹ=jd$xrzF*9zU ]KINGzS bЪxXUE8-gI3SE8ڴJ~}jZa^T̨s;մ\d-jG5m,;*[4ZPڨ#*vNGJ[$۠1Z`&W)Gnz!B:{VZ`zTj}Q2(T1V.ݪضpyE$RQgYTǭJ"֦Xv@]᳚g1Z c:PE) նJDQNpmJiwiv2[S  V0O"˓Ӛ\홑g=A&|x=)DoP8Y >R'l^8cvjrmӞ}Mڞ4r9V=iI.#qG/a\J_-I?"b2?NXKr)+@V"I"̦g\ ;qcۚR2:SHMQ aڔ#zP =sK׽)jr6&d?`i|jG̈TuRd9N= ѨqS屐1ҳh99UN/%%Ly`cia ӱ*8朒q,yN[mZLNQ),[6%zO[DN9Du$9t`ZLJwP2|ա]#bOc`n,S'l7czhn(H|`)T62N3RmHbwqzѱ-،ԋ9tNAv0:@0d M<(ѴJ';Q ߵJ1@8V#QwF[jP2O4ǀ~_ރ5-Uԉ`lԫ3SƝ?mY[Bq=EH`RQLb WxbHIV6<SjUc5&IaN@NךV) 3攃8Ӈ=)0л$J秸8wJrx7vqOzh\q' Q~,1Y)=ZS8p3ЁsiGZ#41^1Wr?fz ^rhx@ y44ϗ' y:Rd;1pޙ =EQg+ 7#ޔZP iƑJ1&x:qJh #zL9>^{S忭(p*:RWv;j3I46.:bN1*1i=TXdhaK1EP;`?/f}G5#!zSSx?4~KK3҂6&E1\Qg֜'Ԍ94-'o'.9RSƁKMR`R\g.05/|PW\4})@Jv; iZNA t6h'4@;v i ϥ8jVaqn*L10py8Zu)8.=h❎y‸y)Q8rysПzi\JCٳ7B9i hzѰMTKzӄdv<,OҐsԦ'1N "M5c1@)X: N3V~ﲶA` `pẙni'$G!R;ւٞsih:3G=kPixK+6#(vlg.ps8i;ڮ1 Ҕ{s[?`A$Ӆ g RCw0B`w)RI =(v}1M6q($rit}OOz6HFH5m",@Ԫ8u @=Z G8R)PM"3SIr)GaH[LOL'֐( )y 'h)B8=yJB /= nݺRqI = Zt)C02h NiwM9$Ӛ, > pcҘq bG$9 ҟ^ b8 =q@HqSrI(995ޤ=zq@|㊎Nm)ʒ̹ Ϲ8i`1Khfȅz03J"Qy|Yl,G/H%8>d,"P0G>V&$\9bʅ : O)8D=P#М k)1V`1+֕'R$ qQcVN*܆œZ_i$AS w"$\更d>Ď(% )Z<ZqLw]6S¡^i3aI4ē{RO4݇<i1HWF߃V dJʀǷ/`QAvKH=D.x[^RidbQJ =+pD N  OC[4=(0zSdFa- )N[qS{Fseԟd`0(xX0 Ai.@:#PNWO^գH7ctfX>(vcq@SqMAnj{ nX[2t;p nvyj3J,7X62瞃ڏ5#xm 3 ,z3)Oڶ8flS݉FjPAMDlфyOZi=zɈ֕c{~r*4Jrl\ Sy?jSg)F[0zuQG(tq@y9fҚ.08JSG ")UtIsZRN:Rcԭ: ix>XBF6jç.r1Gj|)v㱡Eٕg?/zAux4GJi$ӣȤC9ɭ0-4NpyDZ.b/P ֯ {R(()$zfʆsN?vXx#󎔚fV6뜑ڗ@8NH*Dh۵ c=:G֜HKpX~ SFG~iA'r0RیN3Bus7ERsHNP;4 )6sޤb3mc&@;T4xJz79MnsNxyFvjw#N⥆G>y{r8)х*P{Tzt# ӜP@ȩpr;3@F3F .sO$)&~^zRum?p3JCW$;~t 2WgfiUGɠ sR`2 dҸ#aJ#v3O g9cQa7g#i{Jޙ+8dbcF=M/ԥxJ\f zug 4/q<`m98;Ѱ g(@> yQu4r zwVƌsK)c~xMJZݠ㰧0zw"(OI0;x9QB2LzbKvҹ PFzRlTlT}@?Z {TIC9y|(QRҕƵr4y4׀)T眞1Ou)Bs  gҀBbgq@zS?gR>6_F<Fh 8ސ&$b?8ёϵXGAE? r~r:SS:P+dMrz{mn94'ߊ?<*>O~"XN>F}Cp@&7s@O qaHsMދtrG4Lb~ lQgmGϹMI(, nU\!:S6{Շ!z52l3,GcF~\kq)bEp2qVQӟʉ;Ec9G8'[wڕU~4X&rqAj=FqV )<` G$^GD[T)lV|='4!EئTyM R'[t!9[<5(LƜ{CVX3jTBF*o,rUJ#2@oj,Jn90A䎢GZ ۚRx䢶(yzrM(/G4(~ E.GJq9rxi]IhOR/qz\xHTPGJP]zl)7op?CU]ǒr*E A c9(u!qK*OlPH1@< - ֔;sJ ӰI{S sN>hh[ $)NsҔ{fJcY{GJ8h{4 NPM)p{`NGj9Jq+1ޔSZ8Ja&ޓ`N#Ӏ|A.-ƅ_|Mri['=}2Fq4h-֜qFFsRGZ7!9=06Aj\;$Gҍ; *F/Aȧ009J;F0zP.i ?/^ ;N)=M8zo'ZVOJ]`zsqg-Cu4X:NCc1aBNWM4W=*ׯzB'ӵ8.ynpiX bF3H38R.'&PI$sF3=h1T ?(HP9CV=^ c94G8d`; *٥<ڗnNG4X!p: p\\z~j{ wB}i1O84Z. h)à\rM"aM=U8PsqN+'\Rhi&K~x߭N@5ȫ * n"FW9>:=)v3:=b=IEwgR[;S*hӧTDE*G9Jsڥ;ӕy vfia,v>4StgyTv#֦D2q{Tх9(jPub^qF9`8qޤ=)+JZaa-c҂O֝H +H; `a# ҋ䞢c`XaM |>cyO> ߽(dH]nF#5I e юK T8<%c8F8 Qߥ; OC8sIqM61ڃH#8;{k }iy#qvZ8++Hi\J b(yLRQRih(7zfT&ɣ 8i+UE' 8{! F@z={RAOLt铞1IߟΞC(GF6NyPcv玔\s.O4pzЖ4`,8#40zRrOQGƶ28lc]iH!7#=iR;ycE; ;+@Hےy4t&R;;R*M7n(r\  1O`lk&rzvS{Kqb Oy4=h ,H[TjA8713\jL*)0б40i 94 ~+Swt9杖sSB g9P^3N\wJ@8KA;*2{ҨKRC֘'s4SsJ}(AǹWTg=uP8Pyd {Q`E)9PԌg{rl "'8#ӽ*E9v0vю*mwtOvlJ+FhJ9ߥ<99a]2>¸' p;ܻir#8" P~"݆:S "H S,`s#EӞVI< dasOXsjYi3b#oXg5-qXTF3?rw#5*p lFۀN~i<aI[*0=1;.@'XWQ"&x>(R;P4}'HhB۝zjQe%GU4qS_:+P'#HHl4m =i7: hSݩ#FM4ӽ2^`1M=ϵ3q<=zxҡp9Cc z~W1ilT"4A߭'$晓Dcnt/; e!o>.ۥ<;\ip##qR| 7:lRU W(@CCDX7 aiͻ248:S)i98*u<4I4 I֝ mjBT6NA,;`!R'(@8 4n;J@M+ ua4~n ҆Zh8lPMa$Qas1wxXK~}J6H=iA^z)x{Q`J@xG3Jy؛A O\SQǭ{b/ Z0āJ tJ8$ )sSGq(l5Э۽8i܊iG"Ɓ@z\nޗkUl+ !9Ƞ'P@!1!KAKdtҝ@H^#(*x9i'9 qgpiaz t J(H$ORZnOV0Ph Cv┩fA{'\7vix!V 6샐z`z1zLM& gCЊ~иZPw} "[&x#44^+Ҕr@(C׵<(Z4*{Rq*BcB2@+dRƁ=J`O 2 8IǯjaH<{Ґ'(#8 6})6Ԟtt&nڣ`E<xZknx 'O%zM}{Ps)XwaaI=}jE @4l4"drXښTg4)h9D|㧽QftnwpGJ Z(v S ^wS# Z9D# O8ђG=$߭L#XAi3DQp žЈZ8Ո9+#D*b*PvsE "FDxˎ  T9OxqNUlg=R;sZC@5 ^ 8:iT֗ӵ6GJCb6z枸օzhӱ!߭IIqқ N cNj.&󦓞i58:ӰR9ɤ'4'8X7Jos g{*S>]$){wrAdv4&xZ9=zR gdjBG=qL njFqϭ_RUl0*e8dbNJ$ ^3H ׌S% cvrr*9 #ZȎB3zh< ڀԠ 5!U MӯJW\4d{Ӕ)qҹ[ iTgsJPpx4ɧNx+ԟN'\az_ҟ8<HCEHpOJxI)g?J'қu OLΪ}玽 U֭>1U082dXkmsR1`3y34:wKv&cǾ: ddf3S3@ozӟz={Թ$9y79nch- IБR*>FiA~\{ץ( ښ[<Ķp|QJUrx0zqRn`0M+ }A21ڪWbxvSLafLgpI `9<AOOOhaQ7ӻ;yersL9vb[~ DPG\SݢzZs? sE8ЉlMsژԻTA^8¥ JA>F \g(튡^A:Sip8Ix'@iA "shƶoO=)K@wc\#zT8$jVzNX v3P1qM$Toizu8)X"3:{ p8^9c9&שOjqq;#+I)1F NE),s#/48NL$sN&7R*f!\0GJp  Kc1zsڜZ\JbHor'N)i6oJES)B.B<>أ8!/aڜTiJpBH3bß'pOc4)3(#zz`<Ӹ80qH4 a#y=r==iQ"z?)@4Ih><B$gځ!\R9'4asO/,F}(A&ʎ6=(wb3м`cNmwf^ьӶPG&P =j@9\R6; M:I-Lf @iDezANx8 li 8HLh7`r1!x)vas  :Pp#A? 7vp?Z9+*Tߵ5lbwg#<1=H1$w y<ӗC`{Sh{  9~ciT ہH,{7H}8fO:lSk]>S¥ 617b G1@=jR$S9jd'z-G$gGZCwU\wg TD8ԙ-ހ#Ed X搁LfbpO4828AzMǚMݩzqà$p;T@p;!#SI>;۞3ڡܝiX7Ap1&#( p;SpSߌwT7ip>Nך>ƣWrj&Su O_3TyW 79#lmvhcB)_;yv1?dѼdY23giQ[rG"3cӜr{oǩ9=8 pv'ҁ90\j!xX|@\ cc!"kM*S)u ?h+ANJ# 0{'\tdr*d$QHrph5oA!qOI=8"A)1Wji? ];h[Jtvچ4 m9(4*6*5!BhH0O3gކӊdGz8l' 04ȱrNGjL{TW4?0dbqRygsM>a7 pqސ'>7$ݳx4na)펔!TgР`d 'g?;1ɤۜcXt>Qs)wcEU8~pWp?ւQ s ٥ 'e iC~`9RJoin8 Q}M sJT3֔)֏Pti0sN=Oҋ!LhӆHrhnW$УSO#9,] jE9Jp@揻N; sr>sO;cۚR> Ӡ?91j:SњvkϘP {RNNOj,+:~4'cG֔8XoA~Jv{i?!\C *N$kaҔgzRzVk ~F}8Ǹ鞴 sԼ<)^dp0g֝קGҁ  ⑾48JB{ކ`g|QzR9 ǵ:HHci'P ;#aqȧ CF=M& lm8Ag4$6F(B\KdJm /9y9 ߍ8t4!1FHyޚyJ2v~0&+2$|JAɦ0HE5p4;&b(͆Č?;|'i ` g5.$qNH)4`n1FO/av۞|S2å?A#yKA'94s8T'`"0=w|<AO; CHPyڔ;c>(nHU) (sJ# ۜ㚕W'BW0)?7EfsR6k%QO"7;OJHw⥲r3SG1r5%QK9S #u 3zSd!rjA;ƕ8m$$JzϥH8ǰC ܎#Iqލn `H@a>ԛ4.H<Nqq`}J|})TuGz!#9^j@s@lG,HU8dn*1$ULcRBo%HFqSӓRm+#O\QGF6d{HJLz~TG"`;TR9PHdU|Bz pR1JT7QFB@3;׽x$A7ǚ\FҔF 0WV>#b hAI#A<ϭN৵&ߥ8GNh,{~4#"=*⸀0$"p? 3,344 rYh񞝩@(sFh2= .8<4v7c=i7tZ+A}(gjsJ‹`HN)0'bvIFzgǥ&x#Ґ{pK NEF>ϵ8=zt⁷֙;=qNx4sz, 7ϵI<})G$tIZP0?^}@MP?6q@;!v'iB@zQApqOq4xD& gҔ#8nw'T3oug?xr;x>ڔqx8=(8ɧ Q# ~4&># zRӠ<֙"xNQ'j( -D T)9FOH-FzAZfZzX piqMn80((C( xa/aS(tՁ{Ӷ=qhco 3dԄ;rM<at4D8R19MlDGJ#Kѓh#pdS~yQ`i:u┓hP:c?Z6 | ޟ H4 zz=)vpcFE;AJC=x7; -KcMۀ?<,:C~e֥1l5 HFIHrP= Nb5.f b}!T(-ƘjTI4LS2x 0*0GcPjqvH sN!{D``摋 =UI:zCy׮iKv}Ҳ=(}ozSg4:aN#$@-ga'(>i2+ HϥN+@5Un$nA^;SG65ReXpszGqǓM* h6zAڞCS&F=9؜H{dL*zh0S:5RKsQ*Azx|H,1,Uˈ2/VQ$1&_ƄܒMr*]aH:^F^TiB҂x松OU3N$vQ2r$.֫69I,ב9&;R0bpޝiOUV#"hwAҚ<)\}iD91(lة1);;UT`gJ\`z 9n V-3lL,0>TMRcH Thrؖ犵ǯ"0 >=jg$"sY;ŲaǜS0EIJi9.* Y]&cS$L mjE) BN*#w+`⑪@w֘I^N3N PN:7p㕥<ւ1821G֚G4`OAސ9ѐI=: =&HQށ s@Nt )Ob]*FŽ941l57N@@IO :R+Q`)μ)r{ /a*qHIdb'qv2 iO\wRZcרO#Ҍ ԯp cG )riJ{w6B>a9IoLM&44܃JM[f R'ގz ӱiAҜ1E =0q6y'Ac{W=i1S4ڄ#$cjt㓂)[l Iá(rOR">QeYw Cf`@InqҌ3*mjrh1FFj}4q+0+4QDk='GѴu9ZI8aڔ$g֓#&&F1i{`I)v0:a惞siøޚ|8J^|߅NBa$qM8#=r .PqYppZh~R3=iA9Ȕ,3J<5_y*X-U5b`21R2y#s \Tkb n<hKE9rFI!ǭ.>b;SыU#jfFG+69Yi<V }M 2.7j,A0ܳ ՍPՍ"R8@ lOjC[Tn2zG'5AL ٨F(H=zPr3g=(99 z։[#Nj8ۂ421;ԡQQ;)1u֤~)\4CM˜}܌\`1VZVȪwMZJ\M*ʨ#93V@ )1)I)JL.ưURH:l7p3 p2BmSJ>rrx)1q9R;{,|;dqaڧL*5,G¶0*Yv}hduaRѤl)sD*s9<0X;8a& 5,h@֠3@ =HyNڼ`apG_JL6O׽!Rg@R("iwc!b1GJR88HRqϩh8GaIKb1~tr(Znz{SѰ7b,&Ɓױ=0[N.dJ短B`D2 ϵB/2 c ϭ)tP>\` M:p=) 84FHg*эg!q=5Ij8zw~]; ` ⃐Ny摁,? {26Cׁͧڜ#Gq֢!$J tI A/E;r#F܃4F6qcN)pp=hL04gPW (8LMd jA#coNh%N)؃y:GSpieJ  Z_3c֐+ 4d {(l"088w!9@!1ڃ1Naq$/M;$ivP+Gn{9h\4R:”qߍ ȧ8SxhB sƐy)6؄xtzB0Ni8XuF5s&BoJU2 RH90\~ip9=)8>ԀRcҐ0=)TךBd=.&Hy9y<Ѵ7&lxR瞟J~׊@0NFcLOF!SnT0La Ґ@qғh$Z} *֞6OIb1@@3ӿz知(Ҍm 8.NM8LT:8x$ {nzЋIqC۽&9(LА6c֗*sJ c߭;  GJkvN3=MԴ4z@c׵7s9Gb8 Bq0ip7u4K; >hwIj2H+@b.Hȧ`<1iI84?(3ڕ +&iTG!Ac]{Qd!6H1q;p2x4 ښWi;S%NsCs((  y#Ґ{S\HG)T f4SEVuԞM;LS0=iX>^ҡ=E;*=aHB g֗n~^? eDnޔdt ҀHb`q=Ҁ'JRAx3 @V87|})@&FyCBPx|qQڗ֕~zSyli.}\s>yv8Tq08^z\=wfGB)XФ\Hib*jBOj~ 0J`AQ@ AFޤo98=G=A#$Ӱ=1ޗ>Pn=)wcx" SOp2)1`|gҍ98#OqG?ʚ c@'Ma5+1Jø&9N6itO|fsF9s+ r*XbU*ݤq9á 'b{XR3ո#3 ÀYsv5 vf13Q!!}_ E4CDAk(I-zV&Vf9nJ I:MfuͱKbG5O9) Ăp)c*}GN1۝^ iK^s/╇I<b8g4F6̺bT猃RH'㉐shl`ai0_B$Y109a׊Né2r'+ !w'7#>ԃhcSzy⫇aS=hi-6[Yv0r Kx3Ȫaڄ͕KhY!ǯ438Q+UT.zjU+qU=6OZ}Ll:tHR`{P60AzY^W/\I$pjؒRt!@J2\DVJtFm-Kr#NUbd՟58RL茓C68<{m )59u'zb]HϵNT9;R\lQ=jVG4ݙ)="A)=)=dLgLJ0[8cg&ܟ*zNΤ4r&2:qVRTRHzTn+F'S1ۚasޘ<ҷn0Dȗ?7S6GO q%z™1lsRi9 HSA"68q pyEarj%cXܱ_ j?+uHssScTORyJj.R =Jjn=Mw}=yckdc48jv&ۉ>P> F'BBLoNvP:FŃc=rHsUb9 -7B 6})،SD9.9sQEe\ )C<SK:fKȨpҪJ]pj&lCJ=NNsUc7&gsQi2Hj۰qғ%H9h;HSߐ֗(r3`Ұ\C=s@ qO4z Tڠ.8Gn;T-(cLh 㚲#.н sVbܠd=j$ 0>j)x!N8㩡@IN$H؏w(gw&xN8u#4zqҌ7N(`sҤH*P@9"dg9;_/ZbrhٞȦ0^i~Q -)H 0"0wuING!3{ӹʜg⃞r(!@x1ҎXa~})3jF\t$g ##44tk q{ JrS(ss@Rd4{S$!9ZE94rFh8 i `3KG\SX c1'iI?/ rx6"s N8 Hi>`r4 Z!y=){^y8<Ӳ fs@'$Sʮ9=6-Dhq>=G= ~jTy#.WW$ D߸)q֔iƀsҝiF'=i܁4/u `AjFAR;([yHHQqJaqfszӘ0ƒ8#-ٽ)1ƌRZ B!qObc.]yCsִ-.Z%Iڔѵ)(ոo#o+GjA1uPsUvTZS l3=,IS< ҞeaQC2]E;c,Spj!#b?”H1/5;fR2F5]0&2sMF~RT<ڒ}Tc=s֨.GjlzbGzSQ&S9x#i 9#?L}j.01z&RԞa\sP;x53ӵ'ǥ&#j6у}q;Kr20بHrF 5[xi7T%ԓ)JShV#IvHɩ6:Tg=)Ո qNw⃀AHnyqc9l{.O!bc.Jz0$fsc&0:qH8-\ҵ듚cg@"܌ҕ*LP0zJM]12fR9=ɪ*D$hh>nQ9Nz$h[nu V:!pRqzThFHMPA"ݚ)@>v@dbP7vG#zѵ$z~5VFMdڧOP8U=CC' i ҕF:KpI4oAIO"G''=i620Q6ASZ@h,=hqR )j"#np=i+{wxR <MzR_HQ֙y=hB$ E<O>P:JiH 'Oz r~jx1qd9ݪM|jH$ H,>ĀsNT[N2F?:V*R@ST88ZM>Q9t&&y;K$3۽1MP9$Ka4#  LE81کDR,jAsT 4J7W3fD#Zn{QGЌ;t"1`PTsp:|Z /Iz >jBGNԼ5 $soqE၎x`Hf) G^{RdPWA-=)ɣ949=Q砤-w9hHSKڞq0yHp[N^@pޔA`ԡ^cHNaJLx>\mpzcWrj(?ҩܟJUd 4Km "Q- LfA5-ĤƠg8( eT`9߯ZQ)yϐ J~*VG(*;*`@;щ`57r)XNl V$сST`s֜6U.yc1E$4czz g9Ii'Zp۟)1@t@8 T1ښ#9[``}iz>f=:PvG^ƤQ(A#nA &8 qzLJI<4nJORgڏ1NA?0R)c|0R"pj VU]P3КaG_zjxaVdR+i{rF+}j1*F?zJR'Bl2wѕ?du" ?x .qޡ';sJ-Z舥Pq4qZ0x4kzU#sJ:t5'T3CX {JBpG_=GQPU!a;R-۞'=*oVAGjSQQUc$R0R2DlqJŧ9#<j̊s/'2ȀI#8|}k(9Vm .G 6O֔eqQeH^:T˹.RpxHΧBARޕiHXM=9'QB'yÎM i PN~}iqK9(nA> d Ay4as׊q @XBsF8%HǽM`Uug"Bٜg,80 ȨOjyr;MWz#@n8N¯Si Mb['=hR2G #?6sIt0nH.3=)94p<;$?*5*MϠKrf~t: g J9;b0E1i{Ƒ$ը$cJ6HSԳHt.yvр.~[0 Ұ^j&Įe.cisl>^Ք:cvC8^ҨnXت8$cV]ngJZ S=PܜwסV0 3 f,z#,I*&jI8؇ ppsR#:OX}i]"89z8J,3ڗQg͹Ԏ9FoqcCy#.3K3Ѩ3nN)WGN) @P+HN3$t.z㎔+úcP)2JcHw1jG'=i<֏zRݞ1Zapy۷m0w5&Brs29.̕F@ȡ \JfsJŷqCH8xyz RM, ~*x^:SIlRo~Hc֘N ޵ T r9X/!_¡ppIE!;wUA:dvHKQBIqBNp)۸h$Ƙxx84ǜ$秵a}(#zR#U ƏRmhH#?z6RҰiF8,sq^R.ӏcP*U-)|M1Q9TrDe|֦\0m<~#pYrM6$A8oLT(=qRR7+ Z\L|oZ'nj8'JnN:␵qCLZ@.;@>E(c's7 ]tiOH.&1gp#oOz$~m )LpiqҀ}GPh;[8RXTC`?I\ړ ö)v:6riFlph^K>0NA}yQ%hԋZVtH>YoGZE2{ҐI@4^M&s {w^;&0sڗ)p|{QdMr{R8IgcnF{֐ӇNN~ De|i:dR`rITI sIӯ4fM vښ&DөHc1:zO!zu?)̠r:t@'Kiv. &M0qMʁN=)m8"({u#ӎӚh) 1֜23LzQ@`T85#UN2N'U@㠦|ÁSnvv"Anj @|T5TSscـQ r$r)6 MIW)1ivo(8 zTebL"$6ҖLcg>fE2Z71S!\zXCjA #$f8#4<M ҰqfJsFy`"QgOjisZPy+fN 2z4Uz&jiȹ1ⳕΘ(v|>W@:-acL,F~OҲóL[=x-= X:A^Հp:eiW730ĨoדYqr@FبΣZ$L 1O)*Q\ׅ~G3)IћqV|2J=ݳmr?RL}@H%g(I4 NU2pdY#56OQ845s2s1t:}kDd|s5@#n)^ArrsBDɈi۱GF0j!7pf?wgOSHF3҃pԓ+jT94-AJ_]!H@ߛ4C\b\skt$Zs`t0:朤H윀G~iE:^84gE#2T})"r{6/4c&34I9=( ihj\`ez6x+Uiqժ4ȩ`Lqw8gHV"9ibr) =RQv9>64ܜ`Ozf M~1sR4rLc=*Mj0Tsҁ.њdEF\ԀFYsLz2I@bE'ER #Jw8WKaĪr1Kav4CKD瞙"ZD'4޽)r֌ބZ~ڟ9cq98Sz`q')\RjN 78{Tp9#S`4v=0zqHH<5N~fi~SNd i\:gpa zM4=_ dSA~M\MtӲFm'84d7 JԏAv N$.0)7@4ex zS&zdq:7 3Sp-H3HsppLǚj6RTÊRsNQRr6qҞ7&zdG PZ bBC8nv3PpV$6t; 92ZjCG˷ =iFGޜGLi" [`R8LbG4M7 L:G>+g5.<+ dwev^,G0QYu;LIޭ%Hc ''Ίp]I`Ӭ9'oj4T*Xh. [O"U5u!Ҵ֭{p)K,ҤY'U~qP6\adF3g?5rJ/g"Pe|SR{ǟpD8B2z'QS}*S$*g;ԬW+"Sw׵Z9FE$ .GCM;րQaݤ.^@{Q2x =h@;ԝf<1yj)O49:%Z2pAiqp8;t;XnzUdferi2c;Mx4x`O4 /#3 ;vz0yN!!yZL҇~ԅ4p~QRޛDw%<cN7Sբ^SwsI";d`)*Zn13ޓ<ҶO|R ܞ\]u)mZ)PiN'< Rð"n'n qO?!q4`)@HGjBL7/@9ira#Jyqڛs4 ٥ إ POh$z񧸶(R眚qއ]0^iFޜ~>t&  ;)Ak+i=(M206uNpqBG{R3L; `ԡH8cw'֐4;=>#mv@3`SԊvCsS? iv!@"JT0zReA" ւ@ ]gьzЅ͠x;cR ^Cȧh[+F_U1on(Sf0vOB cqT-0x5]LMNܵ_d2>.z9R34ϵ58[hA (L`J[#(\ƆM6wN*'߽H>,:zգ91p8Q RzsI͌U1LVu! z~晑OtLQx./jL1۵)\vbqҜ Œ6ۍ9űc*cc_33C;cGZ1Oz3W zfR4HsM4z~Tq׎y8f] S4 (4!FcqŶ ܐiNE HҀG@rzS'Q d)B)H拔4*Aj!8983Niv >N9cQxݎ:SIq'ޤ1"'R8sg"9D^LSA*b~(\n>`c=)6& (ҜK7-jY zRIi0qӵ!nI= )hӵ)qR >|Z@zs&J@ڕTp zЁLtxz!:~41!$;G<dgs8fځ.}) lc<Fv+u (lA7nl8qASǦx=H7㞽c鞂^ƞ9J`=(LޗsHpq4B3ғ'x`NSyHm!:rN}O S>b k{ӻ4Ҙ-798\*(0(0Hj~d׭F7f{ĝnV?{".H9ZEylqϽHp}j- ry$Z@4Lԥ$` *vS#CPi N$ vH1`sN~I2RzqIylޚX*c-2ff=:>i24 NO^vLf q5k.镈?eB>W8T_svEc[pNIeSGӜU$H&p'Mm-M3C`}3҉",wcj]j퍕Mio$ɓvE1,cUQ]=jc,KgQ3R>` =aa\5 IMd"U.xG4`Ai To~-/D8?ցo"c{~tair5|-^)Hs yԊ qRǪEȨ֍T&NsjT_ziaU q}iHDKDUb ԌU(ROiI㎣ֆ a Lӹ#t; @~`vs'!1KI9UՄ%T.⣭&7r{`%9z^(ғڒZP =p=sҞ: y=)0djscM<4G &I(_@S)9'A!ByR`&}O'ց{ތœXcIZ5*Ѱ kOZ8'6 |zR0"RlR SsӸl}znz=iq849@2G֤3ژx*#+ c;iC#'>dh'Ip1T (抋.#4 c֘ Kǽ 8?^)[SLB1IP r=g0|#֘R> uΕҌ g'LΘ#o4vRdt)jK] $tQ ӑ(qK{P6Sd7,s`Kݩp =c)1ڜ7!T7ӷc֔3 Pwc™ m884yϹc4!q:0HJv8dM۞֐t;hoƐzs@ ÚI;h !f zg+2@r94 p c4: •Ǹ1Md7JSҁ9RZ>1۵! uOARm qHl!NI4%rGHAzS O&zKFGzB.O ӄDG@U8i8ƄE>Se1B)@)aL*KJG*0N[c_Wr8Uij !;(R8ʂ90sL \(f8*9#)mR '?֜E#aNGZi⍌9=)19#4q@aM;x<ӗ#qZP#4$2?LIt#s@_Z(uz8s{P;3oZp:M <"KaIӛ!T$PA$Mӹ3&9jaGBIOzN'ҒbkgZPUsҚKc 9?pr:Q9nҁސ)5[H^x'Ҁ? B=goAO᳹GUpNMUnI6LOTlNOsj: ? fי40x&sc) +jCЏ!ݟMVZbu\EllӲv-'=@$8Ўy=TLRfoi.B'Snݴ:Ua*p5UqTY"̓ſXQ|Fwʩicj|Tw.Zt8L2ioѓQ5V3$h< ֺ ?}iOHB90M#'v$#Rɡ zy^~aA LA搌8&2s5tT8BR);pG^icyi@1@ێ#8nyJ=MJU`=.A^O~=).p{8rs!*p1L7z@ӈ֡! 45N43KA!z1#4ӊp'KӎҟQCJϭ&G1$AcKy)7y4\,Hy09&("dS(QyӚ\ZW(0)֐z@~`1MݥI)SrrvI\dgI'wV mG$`V8?ZpSkj/92q􆞂<~T9 RA sI/cHҐuL b>i0r&N !9p~)9.T(|}icwRsIӂh : y)Pp(j?0Uש=*>FqǵD J wN}hE}jM\p8ݪVW0sTAFz$ dAqJ08t&I⁈X 9RsAR0A!րS0I?vA GC*?4RQJXp4'#$?"esZ ݊A#ϧ$M“Eh&;^zE?JhZAFisCu[ch E/ 8FI@%:c4ӎ8!'( #nyFy9?Pp4XwN)xA{Oajr0(?+4ӽɵA(׊_'8ԭHRcG4  =i# Sk=)ƌ/QJ@㧥 <ғ)K{QvhIȩދ ጞ>3gP&< x>?Z bh?{>ا;}h8"~7 #6)"cJsjh:j4s֛N8I^( XMw _jSqS>Ɨ/ޓP94\5cx#֟814NcJ6HqQRqSn*#4&x)d<3s~⧨=wU{R)߭!{4&ɥSsZ9 p {Q&8 $xqN H?6x`lO)Jd~tx Fr)28Ü<|3֘_>8ZaG߹␛Cgg(H0JÁ8?Zvu(KM*uG:Ӱa 9JIqIgz,$^4RKzDFϵJK`>lpi&ے3ޓ-h"\݇"|uG<+ sty{b :ўsGӷ\т~ qsJo7O/9O'+ӽ89 .0Ò ;$P[+qj!rxx 0;RHwc8翽'vOZp47i;>pzIdz @~ Þ^S'z}i;fxsLO#8I4X7d=xɨ_8jbR܁ך L99(ĘtsŒ搌qz!Zp~ø@Ӱc:ZCKy9Q`z~SۊB[sA{}i45*(52'g:wh,9)dٔ"C P^A=j7ǥ8`cM.3Ҙb22龤¦v(=)ŵ'x!9?ZQ}Yp2*|<2xzv N^i'4n?0$h=3J2Z9\)؛BG֜6)QRdqr=:!z1 FHtoQ>W Ld8n܀OglO#1i8?(֗2RjF'l8OFxʐ$LpiAԃL9Ԙhb?dqx&)J6@۰zyئdfnqױ?ϵ8dc1;CAҔ|9vqM\b8#yf.(QM`P8䟥/B}&NA郚w @#qC m"9+ 4o<sJ3ڏNLhAQM; :=1Xo9i~Sn @ǽt 9ziޞŲ{=1 8f'n=(~n*0mӾ`0nO=ڹtHW u'Zn3 ╈뜚coA挱)/2) 69PO>\~8N@8ԋ8 A魁uq;!'9" #)IQzAϿ;8= ;)[ Rpӽ'> A,G'ޓ>첑&{Ѹz84t(ݑs@/&iz:`McnsE-@)<JrsA0`y'ʌ`@Ͻ&s@_@#OA"&2}[\7p$QS9* R< v)r{ sHjHry.2y !\{tzDHVq=(Uyt_%r01PަHqN:Z^NIrhߊnT杜bC`L|?ʜGˌv'79Οa(Ԥ:#(L6psL8c4`}֤PlrqIסkHy?B:ԟ 2Xûcc<ҒyڕȲlҟYN*L.C}xӀ>$i ]zSq#%j&n= = ҀZ Y\{}MxnR`sNB3+s@#ޓ<ƄN,~ݠ7<Ӂ=7P; 1Fq֗p=?:M0:88 Rp(ӚWiL `䌊x۟@haR{֙㚓M8}(h$c.: nF Ksӊz[qk`m9J.*Z)PF9O /'4qEAqI9'ғ ىB9q/8<9 ETSvsK#!2 sғ$~qh;q 1[N(c6R|ݲ4!; ۃҕBZBbp}@^RӜ9=<¸*<҆R2N9Nǭ;qs{RN F~^-j 8A N:$)9=ރdHG4Q:N>[wP&9=iB?x<4B;}#0h;sڔHhB *U1ԃJAEFiN9KsN8Hs& ҁ4I挞H 8x AzNIӊל԰FўS:ӕFi oZiu.9$ۊEhPޓw!A;c&'RBFG0bGzBH4ҍ:Ұޢs84ԟt)y91J<@q )3@X894s/8ޚ˸*JK@TJɩ|$C57BN#9vJB #RT jM!FP9օiB(7) ޔ)'#Zr?Z, ZƝjGޅ~iYp~)Ȥ\O!RsNq1@tn##מ:bS8npy>ԻAS4aޗ䎂E2FN=힔 ;J" Q PI8+JMAJ 1'Az_gSh 1 SE!&<&IiÌ}i1Ԋ=(sE&}E(ϧZ`N)sR*Aȧ֐+=I'L7 SC2÷c4U9&{.M&+ 0r{bKn})9M۠F)4@h}i[FO"s8(*Lry8G}02:'{H94r)21KV `S)@IcNU= t|Z8R8$Swg^p8r AbrzA+cْ:PqzTy7:a7a~_cڛ)x^W LR9>րqM4t砥cSE6-⓫4&Μqތ}uZVPxQ֐^KaS#wn` l8vM(* q&q T<ӕuzQN&i!z1d{SQ8)>a)3FpsJ0@i^3H:UGU#R19ڤgz#.OPLZ$sPG(n@c֎y:n mɉ4؎39'q֌/@y ;yHHNғ@\h[F$)FFIJzP2ҁkpx9gcjCR*)$ќXAIG= ^*2 ;1 LkF8O ,6Jj|b0rM 9XiyjSspғ#AN МM/53BB~"N;S֩&N\ w< l7ڐ#ƞ@r3EZ)>OJd n:~T# ރNiU.ӎ(>P/8rOJL`Z`Qϧ1ޓ=~n̅R@4aIjA#LwO9Z>sF)z`Shv KBx48+րWGR0h2 .؎sH3K)0܏JM @@4`=iPǷNnt;'M!n(4A7dt)7v=)x`Muý('=(q)rGz!" TZpGn=hڹ'.LvsQh= /=;x89+ nLsO%{I_Ƅ9$ wF)p3㷵~4rI=E aҔg\ N? \;SI=谶wch=8b(ЯϽKEGVH1I擅zRIАT}r0qqSI}fc4<_Ҕ~lS#$=8!Sq רRwmh$(I!2dqړ?!$3ǭQ7WQ48=Ğ ւI=@jɁ%H9"NI&n9d.E!#)@Y0:7 QӑJx1 )9q\c<SoEqMROjUULV@HBy'V^F:w\!#46ޣKb+ qߥ7~('Ja`H2MU pqA8E'ҋ 1Tr3IۚGP&9ΐbz~zg$hiߧ g'lZT| QOOJif<BJqE#Q4\p0O13Aaۭ p80sSz@7Hva@n:vu'"N{R(L'CR" -k:N$IʟJbBr8~\RsccZLSڔtHqSH$8SLtMcHڜli0sFrA(0Emր0y\RQp~7 לs(:㎽)@m@)nOҐG=( 88ڍziqHGsFFL!G͊v'}M.~ԫ i'J:GBIGjn({:f)h%F(Zv€a3jPy0{R|֐l<F`tn1('#EV ӱjB14$D83'i@{8, IqI =QJMXDt!38&iTt+XRS})3_&;"0`N)X.3 cOz 'O2o"i7 t d҂h>KR1SD[[=\pqAiWݸJ#kZ<{I4q40G$(`1E ⃜`R@nHBC49,O_ҁzA6q7>ԧQHJ\ 2㩥QS7Rm`AjE*rHJZI=)#5& q)I iMqwN٠#$INa q5: qFђ>^L\7"0qM>cpoJ.Z`rxm@_,4Ñ=8[#Ё"e()HHQ"&G<1Nd#Zv u~4X5A#>h9zR3R H7Qp=9Z^$tH^hni@'˓1@u^;Q14Q9@` ~3ҔJE#>=, ϽgA֝9XG҅?LРZdPCcp)[HZNs&[ Tj1rCiON;q; A4 M@u!bHx+7n~ӃN1z@nӀ4ctE$@9׵8R9T>^ B~S֌6Mn9F bĒvFO EYh i2Ď&7c4~T6FƚIjB X.@!'֎{I'Ƌc<~4߇j28RL4 ҁ4{qE8ҔҀHf4sK9=h ! n)~]( $9I ?*ǯ>:x4a .fIJ~4sqR;uO_Z~9$*ndsGnzsOlcM:1G4<;cFsPU%4T؀zRu=i6"HMt$vuPuGJviېhж |qGޘjPH.]?Š9H 㠥p}i=.h$ Nq;R`s^O{3րZ`G#nXҌ\ 8ú҆/(}(2:jpSRR@hIc wcRC1JNAFTw4 0t@e E,>1ޗԘ[ N(#"'KG=1Ͻ&sv;'=9$GHZ4'Aʌ(QPC{S$p/*@XzB9'jW)4JGzbNvq!QRǀ h&=ir3Aޗ .NAxڀzлz&vQMJQ)z@֢/z iqJrzzh#= 8c— q@zSpsLc֐g׊SirG=)CV'&p0=KO4'47!sb~2 w8@L~=XW sJahvˎ;$ SNAiw4V'A[҄luڙpFEI# {zNiq C^98"Lg<Iu4IZhMqS)4֌NJ2I#bHT^Q;Fߦ)62y4`#8Aޗ LJNryӲsށrzA9&91@lvu G҆4׵ y)sjƝ1S>Ԃuq֗#84v =;RҔfzvI3ndcލh i~n$P7dnڌy;R1ӽ+0ԁ[L=EH7 &R3iK3s1ԼGSgʗCޛZ^H Aup$)qZp_S@Ѓzt(4 v Ӱ2^9܌ixvu3IsLZRdhvO1H5Z^E$6. J⃏ƘXP )2:S4NOA)#ǜЬO4\^28қGTzb)>0q4ݸg4gݎP?ZpI pHݸq4еdy^r()~^{ReG q .&h9 5"!8hʓ4rNGpF?5֍J jt ('!.JՀ@le+ N̄"Mb ,cO(폾(!ǥO(U QNS7,: 802:Rc9H%{#=Gpziua i8e(Cvq:AFϵ"9Ҍc>GziA ! b.p:fg7h9\=yS2h<9R㸧a#/A ❴&d@$#)p1`^FtspxPǿ .E'0?_jr( ހb`f?J NE4T&̌@ N)#& ҁn c0HzKJ@s<)8班#18(#S8=i)8.J(6i_' A4rq*b);vNAޘ'aG=)4:ҒqMqOZߊ7B;q4N)F b[h$ibF=t*yA'jK`zڗ$c4c}) bǃК;G?, ר-$n`bAGPM.8`Н QL(Nќ$۽ 0NqIǎ 5{M=;SFvv ]B;h"'[H(nzq+v@"[8*@9&vS3iݺ}{RHh $dRvOn㱤=xS݉bҁG@=;R=XG9֔zބ6&I#ڇ~jG6$' 9H/_ZP894`P=hWFǵ.SJqפO!scҐ[){Ӱh;3J—vx8ⲸQ Pc>dtRR|uHSRIR V)_Ҧ19# Ӹp1ڕsz6n RcNs@M.y4L2oJHk l  9{ԣ'\m A?J848il;]8<xsLE(8 <~q3N Ґ vIFsJ1:)6ԟg{dZsZL('[s@#ځ7A8nHȤ.;Ըqʜ` Et#0[Q=$+q9LezCz f=M!:sچF3f3,~Ӱdlք\g/"d 6F Rۏ7bzLCOZ*ic!])'R_Ҟ#'Rdx1Ҝ0Ҝ?\ wPM7O)Pvԩ4p9 Rp JV Pc9)ӷZa)1GRLg8 Z L)T~Zip qH2G\&8cZ 1K$sAA-~4cގr;r8iXH ڗCL@pG9p.J@9CgzтF3J8T&=i>eJIaX6OqFӂKoZFCVrJPc*$Rs@ZډsH:ҞbP7f!8ZQ>ޜSH8޽i0{u M3ZJNԘʚ@kAGuސ=;Qri 9=irqM?ΚQ'})6Nhz'p;u)~QS@Wl7֗HH4rGj`\r3SǶj5y&H9>֍IXw$ FM#4de4 !^}E+"ckmփO`%b[cFA{R &mӱ"1GzSr1ȤTXM k1;.ZFr1S@ 71QKہa2NI$P烊7Ú'994#>#L}㊐9x= S֌3q@7qO\\qy!VQF#rLhHF:Kp:Ѩ *; nPi4Oy=֣w 5'8 oөi^ԙ6hiq})b jku'*y杴ZQ<A;%oRPdtWHd #=# 3@6K8)FFrr=)؞`V;cHGLG0 =(9-qҘa`IF=]{9ncH;AwbKbN=(˒AlO$57e㑚p ɦTpqN {ދc1 ~FIPaKsH< ‹l t杂GNݨ; O\S. sOChm6%{߮)NE38#ҁG4֚pNs;S:PJ{R3Ԭ'ap1ތP1O>1Fޣք$u\cQ߁kT@#:r9h^v &ц#8=bw Ғ ?*ʤ#>rD =3BҹHw'9bx`-nn&V'#ޔdSy(cQb[PzNc җ=;Sc9c#8@mrNAʓ#FrxW<`R@Hv h& \q )F{P;=iQ~7^H=zV~`sA4Xbizǭ/#Hz .GQC`sJvHZ ؠ7~$R'& Ȝ2cQF*0 ?nDGݾZ~:Pw%!=0Nz1rzH$.WڛNrqAK}ƍH7P1LhQF{vi1Y8ǥ8l$қ4qpF 4ߗ<Լ9$c_Jvy;Sz?;j v! c/=ZܞiFqӯZzdc`x<>Q`S #SNi{PA?ZVd惻'ۏ aOs);1qA>{R ҍ)>\ZEcZ1)=1Kz!֣CM9Nn=1C ySZh DZ䡧#"6==i08 MҘ6؜b1Q&͢m ¸q晰g5xڡ']d$)!J ) p*P& O5i rF/zpeRiKz4 3RdK`i>RqӤڛN( _QMbGɦ-cݎiCz^qY CbveVL)6Omi,=j&T@~cSw'A$GN?);X?JTxwd@ZOԋ80 lPvRo8S꘩6@BNU0֧W =?.3 Ϧ)zQJjA1֗f%ⁱǚHϮ zFh {Ұ\ʗ$ ?㴜+18>| L$tP8a `E \?e`.:C\ӳ8 W` “>Ɣd.g?E4)+QW9N’Ǟأ#iր:چ$HҗI=iAjE1#҂3qA9$4 9y'\֚.1ݾ!l`ѻE)}i@w?&hAK>(vw #JPz08#z0s@ȥJ@SJЇk!8鞽)F):Jaf7gJs=i/n&&.HTd0GJMKR3R8w9(Z֔t$w#zcFM(c4y4:P5qFgMO"rhpx'ؚoO~\M T=(vQ;=0i:O4 @C0h)iQ 4\oPw'Zv) ªӂJDzzN+v%') |t☪=OK9#-i7~03z84x'֞@ $dVdɴ;s#OS7@93KON4 cǟZbsEÆCN0^gұWk`'摹u搮y'6ǽw(hsP;iϱרJRONXKq4ҍiNޙ&؀ Ɛ; :'8ϭi۽zP6q1֗v9'Ґ? L担.Kt4})j6?1<!,֢cL{ ;w(0h&^x+ӽ=6TFYH(d@jmsNd%sQZYsޘ\`R9j<`E<7ZF:x;1ޘ+#`*q=lGM68q7T"!y`)$n?CL@C`⌞;sGS@ 3P=dt>RUf8( p\qN>QhHsVx>J#Vfd8gY3X}I<2wU61$ Ufe'|RvNCHz2 Y@?7+凵43tHG9Ҥ H8^}i%RubG5KB^A臮)$jv\ c5a4-UsHmԞ^9׊/s40y?8y&0{fnOOjcZ 9@2ƀ; `Fi  I!F})N"M uT*|F8U髃W"Wfd?H3tǽ8m#}}*a韽yJzLӠHOAF948/Hwp)'@bFG;Rt=Hc9iICF0;h9{R;h};pJdsN1ғ|޹4\֗gz0@9&מ;Ԩ23ۯңS/LC)j;8'e4b1H)"OA0F3ޚˎ{S?J }~>p2Ԡ{U-zC cO{ H sHCH8Z^f0CTשZC܊6+lF( Nw}(9.}  p)\ y4 hր]2EI@ 8Fsj^z HxӾnxN0-qv>nuQN })Xw=zaR#?Jcu{Rcr6`'ۀs֤瑟LAAM i[;H;=OKcj8Z>l(=i@SJK*\ OACI\sKx \z,zF @''ր$C CFI8=3JH J Z@iw@ 3у׵&WK.0){P6ףB=8HK޴Cc)8iG]96p xQZj$38&3wXRW]i4:Q#=i:t"wJYqzw3V81N0y{m$EL6mS*EIځ0͸zRc)ʼgzяs:Ra4Qz918ٌ2?6\;9=h*rH⋊OSNH#4?&9 G~g8N=)-p1ɤo~JLx94r~&Ͻ2ZBN`g42ʄ5szP?0vrOsC :Ԡ{4 d 9$ut䃏H,󻎔?|R֌j.9)qǭ'v9XgJvA3Qx;F1p'8NZGR0iT ҹJ,N fw? 49B+Aӭ!$liX#3@h4c Sp9sޟa =4d &2i \ @-})@@%q2qM=iRh tx=xZdLO({sO4/D*iwcRz0zBҐ2q/c™Ӱ7d8gҔ@qKR IҔ㌊LS򧐼|1FJ nبO4bG$P6jFO^ !='@)AȠJ0F{򠴁i8u<3ȠW۟:dPL‸l1M83zP9]E49Ns.LS4R3A; q8m@Q}@Vࡺ'Ӏ>ؤBc<`Jb62l:pj8۷sSl*ve'@NԠH0U"e@GH1Qf\yGG}nFvnjoLA+)ӮiCl2Gj0GJ')rRwLޤDh5ZWi>.¡ sN8IrF=8+Q"뷚pN01EDyϧ%}i[8SCxTC`@֌uǵc:wfП*"yZv JP1M0ұD1a)^hMHLMkNiiL*8SŽj"+I=D@vFlW\+CZ3A `sIH֗p[%V20r}i2px,D "G#<ѱzb'i9wO[esEqǿ񚴡SMX)H!xړi[Aap44g#'!zQ׽܁Aߝ|vOsi\r{S=Ɲ֤`B ۃրF3R}{Pp1NqA8=HZsހzRgpUCR9یdPG4\v=!*GiRsi >`(@( @N8 v'2 ) #@),8ZaUo)0nj]NGj@^G"%@Vǵ 4i(av=~\sPGqQ{E=ӥ4* BA<{P]CHrN Xu<'>R1҂xdPϵ; tNbKtڐ i! BI/\ Jz(}(,@(Ml:@8"~FE78wNɂn_7vGzf@f 5k :bI RAv2dfpsqr9ǭ``r3OR{;Izc4JwZ'$O>AN:zQ`/'ॎ1F3מ{S9#jzۻ ) c d'. CO(*v p{Ҟi>\Vۊ\i(*y"@jM1IyEEEPNsڐsקA@}ycnE (?cE0֔i>AFH87=HQ@7#J#7i)Rv$q$`搂sҟ曻 P>[ GA>֔11SF9U`qڗ (ro AOJp RR:7pH$p33K@aT`sJHiFq֐s%xnMې9/ǵ&4;*:) @SP=F8e$bd#89v9 10p=)׎C׵;h(QyMFB<ɞ1' Y =4/=OJ8z o 8Zrސi@\q@buS?4qܓEv4>àHÓK G)ќPrr9C@N1\8ms  @Yn@.?.:Rs$P̜AWOr皑vȦ;~tǨ<i$)B&3N;)IiG'J`A$v(<Ҕ`gLsxbqi{SJ71r3JrF28'5Jw) ֛)ipNrx4g׭.Ahl u4q֐S 1 F r3N0){t9iF7`%Й9)捿CrQڔHqXLAPFhc=sOܽ1ɠ~3ӊ2t@?ւh,.Cl \>:1K a$zR;ZŒRlvrHҥt$@E+}r#ެ[Bia'|Eoǚ0{T#`Sh}i9R6'R29)`r8;A'vwpIJD1ԞdM` z);[ڪFE4>\ TVqMۑ>\m \NIz\9.r:'_Ҕ_zӖ@1Vv~bMV9ZPvҥEDԞhS*BzS QurZ#v b8Cʌ 2oPJ:w<ҏW#=ZW)! '6 R  ךhR*9`G=*@`#y[v Ud`)5DÝOR!x5KA"H3 q)※!G^h+ @8s@;)·8KԚCMQۭ(sN` $JGQq(J>P0#T9%OZ$94j%:P5t&anIPzSL Ɗ|pp=jl<֡a"۷ӌ'Q}F=N1NqN69ǥȍvJ>C: '֥C'%{7*¬*M!hƚBg4-g~9Jq' L*Ǟiw}hpXrg@9IozB0H,ÐNzӷ1ց܊L CB{SO8zvq6c=h &rNHϥs#E;lG=A ww${RH{c*ښ ;c*䎘ݨ $&Fp:p0R20:RiwR7 ߥ=MҘ0is8y?hhwޙM8/׊Q[ 1JHn1ӧ)9H}HrG4 ϠҨ]ݎsFӌƒ֓ wNԉz @sm(d0H{'z0O֌G8a6wq`0OI׾( S1r)1ۜ.4yN=eOzRi1zJqӦ((n02)Tc")I@ǥ $r:OڑZ9M$Δ V+`P~{S7tš0:1csn~TT2cn㎢@aޓ=I[hLI/Ɏ= [x*-0sF#G4uMLvI #9'9-Đ>UZ* R3,COLҕ'qTIA:c 7Ѩ@ xS8:p{4p :Rr)Q`ns1F4׭I\M!ZC98y4`ʎg4mR=inhhnyN!&9#m!q@#t@k p})w4~>H8 ڐmGZvLmLZU=Hێ1(FNy/)s@ϮIIc z3c;nM9 r(vp`:M!QHUxKA7ъq\9$R;R9Ҁ }( w8p~BW Jq;GzRNqM%xBy$Hqaǽ&{J4sas=No8&:Jf(6CXevȱEfV<b&<0BsGJN"zR T { d4XqSJKN)+֜$98MfB@#49"V`v Tݚrb(጖=l$ QV([wvbjW-1<~29;NG< axNKjJ zӗJ09zqB{unZa&58`zC/ANjERG=*(y߃O%ˊB0=p1Ob[C2>ajRwwLQԒi4dB:( Nm p(( 'ɧ~jt@9BHV}I,`ޗflniխpsz4ӭ`u<ҌRm>x=搒O8`i\)R]iN1hJHIXL\b=M#p8Prr;JxHq {\ΐqۭw(i s7ڔmN'p˜Lx1ɥa膒@3t1O$g5t^=qI rvj-usJ&lG֒cG e i<&J^)RNp8ܕ< d8K9zb#$`҆$!lt=:7֓EJCp:(RS֢ 'S)38椴(9J -H{ `OJLӭ29h]8' Ȥlڃp('Qh$h-s)x#(2ޢ EA34F:qGGs@{i pV8Qǽ#"@;4gig:Pz) 2`iHv>XM.T:PKnދ@8qJ Ǩ#.~ t&lM;RISg @8=iD@<(RNIڞ۱!SS=7 \f#'s7J,%ayFIVxj&𠎿\Ӻ8ݞ0) +EØm4ÃR1֎mb>`JO1RzF6s3_z^Q(ݜ҄{ #9]8!P:ҝړBa+t K @b9?Pђ8'( f4t(Ǟ8{4Us=y@Ha@ zԹޔ+(ۚώM&9#ސh^OJ :R:A=Gjl,؀xx>*PAE q飃J; CޤPSsQ{Qk֗?!*pM lbn(>MF)˷#6@3H:Ҕ`PЊZ giے9fldH4iaNGQ`LKzUR9$vE2pJ_ALi@PAON4j q@$ }x&}Rg-^a{u\ FV>p)y)pq;G❅=+f m!qZjWHQnGªH 94q@'7s.=lz"_$eIWpJ 5'@Q$&ep? SiS3味j6A|b&#JnoTNi%'J.Y#yl1W |@3pՋ<  UcwJܒI٢y ~g9J7KɟHo* i p?JyiGNԦf\{ѨY"284R& HK)ϭ 8F-&;ҥJO51j3j(f`>RpA9#$RrǯNQ/BA `rF Lp1Rʈ4O4vF =hȋN3=q^9$b|ç7z\tޏq2Fy$2Qg w0fϰAH$c<`P8)ۆ*?g9@ 4 w&(/Z`qҚxJ2rE/Nh-Dp  ޼Җ(@E?Z3{)c})YI?.Ԁr3@MyRc#zCdv@F$Nr0 !Q`izsҔh3ˌ u 2Ҝy$h\;t1/ޠ)2#oj\;SI펔ړ&\x6?J^$i}97J1ցpçzSs(HsH^wnQހHE1@9=N:“'@҂=Gq1}$i1JIaI2;Rzځx½s)Qc8;  PN=z)FF)x#hP@ 8J=3C``ҐF1ޜHƋLsJvL^b4ࠎE7;\wH=8=?nqsE9ޔ`zr;PP#zR~Jb'ZQzR`84ZA.qG1sF &ؘ$t}),68GozP?*H̃qJ>M BgjPF=xc47^>[C`Hhbp;sIƒAzJ?60us0p&+:R!1Sc# J{>\|r=9h*IqF) `zӳ!8:f`8֘i7pqcz1r)w9҄VqScގhEIp:FN)8@@'$J:sh4 @)ۭлH'L(zg($ LiTl{c{zw5@vzҎOM ӥ( z 㸠n\n9y7' J23{P?yA+8z掇ZM;hyq7  qԀz t@Ӻ zpEycѓ:ڔ.?Ɠ \Ґ-w {Qѕ~cȥH3I׸QHyϽ-Jڀsa改#j$RD;ךFsޘ4`4۴ 1^X @=)1Hq䌓H3~4,s.ؙF8hI &i>OL})/K{月SԿ!OqIFOl~duӽ#Bq֞Iנco1cwL?+Fs4 GzcG$pi :瞴͓gՉA?^0x ރm=sTBQ #R3LH{Va"n<4S#,D#b3L<6;ɓS7dy5H4.XJM',,._IV|)=>ϭ.n&I8=( RO!X:pOSE{SE_zP 'A=JCBddJQj CB}) Q^Bpj#')@t ?0t)xg~TOZ@.ps3O&z9wOsI(4ĄbQn{n.gzXzsHCLm7zIzQQcI gli@R渧(98#z8maހgҝ_QߚP3ס.Ǧ{fCHv@=)M"0AsA%#OJ9ϵ _I'9W=^&n})W={g4 }io8R^9J2r3LOzNy8yAJFq lj /U) j_A@Z840} I -O/#ȧd8?7ғ`AdcOiJh+DK{A_5FŇi[08L`'d-p'$lmDϠF+p/lcu4hY7g<~ud{@1Zsr[+F}j@Zo.F}MnT#<o1S3ځlI m̹v;nc8t?/zًt4l1C7Zn})1i4[9=Q;՝¯Bz*Ȓ{=jE2!zBzIpN6jC5:V-rrj2TJX2i=E=bv<Ty*Q81U]XzF0sRޞH8Z_s iOCLӎɪ[ӺAj\r<6N3ԇ44N Ói$zvx4dEEǵ.;T^M1l/G94&MOCǽ.1HܮW;q{RDJdPI:PHn?ڐqӧ&:Q@ ?* Aڸ7A7Q$hQy@zRaRg#@'hjQ#h%$q&Oj24 HM3zP+^ZN8c@& i.gK1ǵ7-H Jv@֚hw'ۭ4;sNpI2 .I9Ͻ.y=i1ցh}hE RG>dA>n$N:SOsӁLNd66{PpzRD.=;f{b:Jli @zS1QG;h֍ړH('Q@KE'\ QoM\7.22( u\c7r1K(:R@PсNḃGN)-zvNr8aqE@##igA €iXS+pswR1Z!q@:Z^qьb㧽2wEBzӃ5y( zbq)HN'bM##A"ߞ]si$qB:IER3K늑sۜl6KTNx $0#iV{ R6Fsge@05(4 CMuZ1 z//mɌtYpH\g4A@jvd7Gsґz\)=i ps} SRKHԘPN{P;v7uJHh{j 8`xIzU@QM9;f޺#9"w?JRiw(^(q8+(`cRLsN+9{z@\.&FqhܭEg SOjh# Fۧ#p2r}ixebi JڊMZ.$FG ~}ъ.C ֗5q4@ ֖Ac r>z搂I"O5"Z!!9ob rQj-dȽj2EVkq9⌁ܣ<ړ?{+ a'StcM@IEr{ =({ P(zv z`dgFޗ9'HrqA,>6A0WuG{ұ'r(E!G#8R}ip$ vBqdBLsmǶ(#t=;Ps!sCKFx۵xhr}(c#HNi$M4[#iă'oiJ92NOzin3R6h?&8G4aJ)(gp1Ҁ#/=!ڞ0$(n(S0֗.I( IrynIb(:R;R2sdjX4 S g&zgOQh yA±;i2Y[[\goZ_MZ.;R>Y>&4 |A@99#c UsOpt4®dIөiBryE n923KBM5@VO¯SRѐ3T݈LF+ApT@ݣ*SnW\qRPwUkj$.ӥ<J=v.I8ZkvpzreF#Jd*( *528ߕ=R|d7O"Wk`iT01<}EX Ҝw`siF1IUruFGPv6?GR?+ X @qGJyGJnʚ%(az@JfA(I@f⃃ޞ01M3q޴CJU]vc.;42qEa=O|! 3q -P-r$L#&o`)W'"M0 98jq>Y@Pܧ‚\RA*^i'< MA@Z2}yECp{0=N=GZ8nqh4n"u:94!:SsޚAU8ȦJbZLJLQl7Z<-!x$ONi88<+ WqaNzS94 94'4wNfBpiX*G#h8)ߌfx9LM qڅ#'?'>*u44r'RAPRt╋% {J4Sm7n c77Nny0qTӱdӀM02kw4(֍BvzzRA=4. ݅< q4dI&@3J@ZeOLSI J7|q)y{M珥pzz҅`zQ4JhZ1bSZy3*Pr}1G 7?!JKS R-;h|w$T.z)΍}l0HTнoD89ɨ;.R18"H$YV@1 5!QBb-l.~{J`i4}◑j0OZb>$cDJɠ٥P@mG.쎦 N5 RSH00V8M 2`sHc'C犕d9Tr'9 &1G$G@pG҇r>u#Q=B; =KC88OҚ6Ծe`ڹ8Qn'SFiypb{T#sg=*fcпQN: т8&@,GjAs4@?7=:拃C ֛>ϵn ҩSJhe篥6Mǖ$cځHi F/ry84ÕS ^Jy5'Z;ܣZ8Ѩ]W&9{Swr0;Ҝt4pAjvǽ-B <Q=(;}NiH6qJ(H@ s@41ځXL=})8_Œ9Х}:PCt1Jy $ 9$y q?RbMQ/ʼoƙVAB* .@4;uR=)@!Pypyg!Ї{gO {zB㰥ϭ6B)qK9F2 R+2 #"'H/Ҹ1R9ҐH N`N\lL`BNFjfҫb*{ԛK/*>0z;(*=$H"sK^Y^GQ)E2:Ee#=K0# iAR*q=jx$g#T2 ~sS4 /jW4pЮ֛qBOjkS+[(#ԅ@ea󎴅׽#"< ST7 sڄ/6#(9ɧF 9 qڪ"vc捥^ XP?SA#"RzPqi F{y4}RRO4 Fi'ir֍ 4b'/!A9%{u$pwnh'IdzrOAR>R ֗\1ţ>>3A`G+ 8$t=(Li¡֐h) T*ZCxb  3AiIJ ^P1z uI40韭h]GqK׵! kS3 Z(J "{a˨R1ʆ'#\Hv4”Њ9_J/i>hіJQU؃҂A<ŒQb4o=CmS,B0IB9ғ)2:KHT\9Gg_ƒ -I`8QH4a6F1ߊg=AvNy4 qм&]ÿ#2h!9$ROQr8=,>àjcvJ_ F:Y!x;3`8AIzwP'\r(Qۯ> A' ݏ49`? atÞilԇM i'\àsKh-o=(;)C3N0vdj3P+XB=^xF9M/zw})N8J*.M#ސt8nil=O ֓nا1-ӻcߏjL09` ҽ7bL*Zr7?ɪC#*.Ñ*8;ґ;l5acϖgzԒhm&;0~iXbj5.P5HXE#UA~Gm $hc9cޅq8ǡTH$H\ey3$ 2G֊z=\vI9ecCG=zRu(;Ԡ';ӎҧ#<ӈgV@:҂ZwE8`6qKI8hUdI*4$4ǭ6FG$zQ=, y80^i9)zuX.!##4qy/zҨ#'b$ {vR=zRqҜq4 J4rI94 z.\tP9h߶uSڥ'4HN)n=(Hhf̐GzVGG7-LDڍsN'jO;ЄЄgɡC  UZ`ў=qIn!z䞴0{3fc {qRH!;`hc#;[1:i[pǕ'13@}GLU pS֎Ҝi qځc(WV Np9wqH}M' cH9Pzki ;d7vs܊r?\1? Qxi$5e#)YF2iT2|Qiw=RNwݺP$tB#&9#4A=d':R،Prv$Tt)F'D$G^Mw\vi71pS1Ɠ'={ђJds4hJj.F 9}hu8=;PA2Fp:R#94\i$ڔRN(BvPGU֐w! f8$v\SÎoQ~ԀM.NT4'9(?1ʌ(߭(3Fµހ;g2IKQ`/֓RIT=LmCڌJQp{R($/AtҘXԼ旁ۚ6;f.20sE )jj)$x(FyiAI '4*=sJ8i\ѐ;b܎S21M$PQK+;0s9490zNzR8惌Q`&9F{ =)g9'GzR b9z[=jnOz,vAslү9F?w|hI]JzduT'lޟ4g8#C`~4<Q &O_QO`hMƔ÷gPVp4:uʥ#E+9?$PĶAw\zf]M89qiq׭Lcy|A~`徣Ì|Q*TƝ!"h<8xLJY9c+!$gxڔt )F9҄A:F}yJP34Wƒy`iU|)PIn?V8nx 9tSR1sG;( =)O{PF2{0;z7g84(;OLMl(>OSLx֔;P3FGҕƵO攞HH9F LchldtXvB1g:#4!R=sHKg.sCHfL:RQw3A$`e n!$@㞔 ai94`.OqxGbȤ=C.>O(<4h);;SH'A'DXRI^ڌH#{}I xz ?z_=)1qTLKA9& G_zR1AoAzñ)0/?րғ=F)A PRsRJAP P)g?Jpdb8ȥ\|Ǔ7ORL.&IqH98`:S~lӏ|BMMIpso@ǭ L4Xi OрE'ҐYsN?'n:B' )2a(An$ E(PON {zR8tI4"vR*|뜊p$qֆ9֐!O>ԧv8 p)@LR ր'1.JӔ4֔q@sJ})Npy&=i2$0N$=;P@m#j&zWg|B \71u8΅sQ7J3u413Ncirt %F)l I$ڀr( 7ONI ̇aҧ3ՏH*G03M=1F@rE I8'ޘ1Iisɠs4To=AӊQ;\Jp(&A=w=) AڍÜqA'Ӏs})ӽ0;Jp=Aj{ *IrM&dr 8 \xaCsҫ1۵4vpn URzL.ISIsGҎs\B ȤE)dvL``s@Z = g&O^iW8 H!l@&vyн^tJTrMޔ~מf!ڀ)AQ&<\NhcހH3K{SHnja!qO9sH29'QrrG)N7dP4v( W<`Q 9@o.Xq\` RcSqN 県 Oj\P ? l d qNMr׭' aHcp0)Rd@c9҂H8Nh[ǜ\I8ʂAP9dhi$RI=)\4@ Cih' qns=q=i?COQh.#җ#n잼҂pq#4(#'Q#ڝD)A9R/ 8' =hH$vҒ ݎRn[KcR^O<)A@<;uIʐ;~?JQN 4ێ?*B) Q4ƅ<=G@ rip}hLE?,8⊂t0*qMy<Є Ԡ ƓH1FcaS=zPpO1'#xP$!*qiH ӭ(PN .#`qL` L4ݣ8S4ҋܖ8rF7.O$tڕ8xs)=(d<6 `iq0z㞧ҙ6%ONiI3H8$bT8i0xRiqhі=Mÿ_j2{XFh3ކ5OivpzփM`՟cg9`NlGr zR8Ó7M p3Bi(ih;֎: y֓zhlPO$:sJpIFq;QSAp{Qhqh C>2pM8徴 OJ,!p:dwFka46O<ހNOc֋ `]})ŷ}idfï=n8=M'#$&'vGӽ ֐`haH)|b-T@ J7.G=Z߁㟭/9)duA)@펔^#9=A_ƛJ_Ph#ir<5#4c?)<IsL5w>4؄"qJpqIC?ҀN:{GA{黡SFA!Aay4| s@Z^)s:Qi(G=iā€@w&119Aۭ{TRS@OΚhQޗ$7 |ܜS _~HpO@i84| i֓+vsO@4O)M<RGʽ W<ڌԸHza]qNz) P  lP0NF0M!lR94@.PpGaO֌ey1: ;= !`uPŨP[@x$R_H`OKǑi98=)WvHni H'G9揯 =)7ۭP=j@/*=)(<qHN9^ɿD~JN8"wsH~{Kp:{ip3ӵM yFH71HIӽi'JUfܓҔv/!}HvNzJ^;TQdF{qjERsɣ 9O@`A9⌒#>psJ7pxӁ$I'98'[h;]h H@ ᳟ZC8iح@q {Q< L{DQXx l73׵OSM^ӊ.;6 G 2x#P-$p9楙-C򣿭UJOrVس Xd֋LYҫ)`jI5!H@iWs^h^ 99n&NqHs۽40 Fߕ)ސZ !JRÚD\ 'cZy.}Ҍ cyj_76HrGNV>a8=M;S@tAVf'i{c4\jq@ :џj2c98G ԠASO$!SՙFR1Hz='(ȤQLVbsyx>{◀8@֓qSsJ1Z"~94g?74d6-sbqҀ9=1H^h]ϩj\q)8BLPO^(;;i P݀^@'R940 0}x88$X㯥Rv{!sK8$PzqNF1ړP qW; +v"Js cւqL6֔FiʔHX.y4G1U?x?Z]$r{ԛ NOQː~jGڧ=sGR&qޗcH)7TC 0xb0w#`E{u) .:M,a:z=h&I?;}=pIqsE,*R0sڅM߸1Csҗ$tƝ8'͒֐ q֐Hǩ4'N繥4Ҕ: |ÑҗR$G4A'9P?N n01;9Ȥ zJO^;Qq\`Q0OzsSSqº{ ڝ&psGxI sM8悐ڏ>AyfCQHI֐xNKM*ؠ>SR s׌RN ,PzR2֗ӡ h($d`{R=(9 !b:sZ9( ┟_Z>c3LBsܐ=hPYAKp=hVsg8)83ޤnvGZ@Gn=< '`~1SP@7^9`}4b2=IhOm9nE?ʁ9R)y&cs7zRN +v=46qN >}hƒKq ^jXLmjqJw憯;2'.U,TLXrqZpi("4Wxȧ1hO*GҪ8U4C}yOJgփ+sⶠJBMEIÉ#ϭ!n)1qҔgҐ#aN31Ǩ<1u#߅+`}i298~nXbAɣ$RA$GlѨB1&3z 8FA> Ws8m+y'\9`8l s@Ӱ;{Zh#'SH<650`z{S@8?*AÀP)˚Гh^sMgn4㍧=}j, `ݴ sNi0c)A4=GwFy??CIQbX Q9>y hyc~lPI ҌAЯ4*FTK@J LZF~4#H${T```S s0I 9N1֘#(CV%#֞8)vzf[ӷ0E74٦h8gM'h})Hhz68hdJOzS(P8瞔s1HN8Ij Rޞn/<@k}(#h B@>)8ց88$p(ÃQI #4Acޛ?$)3) 1?Z2:R8~0GZN>r)i9iюM!I z"RCۀzLcg=i 4~am֝m8#vH$7#Xsچ_asi0Ar Җ^i P{ v:Qs$/V==O49W&22x1GlJq 7@Π i Cm$udcL5biOZBR/{RF7n@x:[8.~WۚOLp]N0J: A={QG)o)  @\_ 9-qiP'qJ@&ސsrr.ьG9n=)0 * ZL)49֚z)~h3M;#Zv1o94gRR<.֎HsMzr=)'?nx)ӯZi] ӎ8/Hǎ1v%8ct/qA<xT^ڙGz2chͻ I㹧dGɧv j_N)pz#PJ+GaE" V - ^cA==HS[$`vyRŒ1ހ I~FӜ՝j\ Χ O" hԌbo8/oƓ I9a'0}zRiAP898#攓(`('w7N86Ԙ>l#C qxʓ8*9@3A9=ޑG'gzQ?GCK"i F9M㨥#M ;ˎ)r#0nq0M\Pr))++{PIR1FҹwP1M'9EPJH\VlҒszR1:Ҝy :r9┆=hzc ӈ^)ޘ}}x^E!Cr2qǭ<NzXLh^K9@4\I4zғ$SJl^=h#=)1h8ҘNhHIF}/{zq7\уvz=={pJ4b$JZ@3I _>g1҂O^;c2sޔ )>( moޓ3N js֗99$Rgҁ PۀRϵj ON'Z3iݞ}iSR#ҔM+ 1: z8ҞzRo-X:sRs^z L:R?tȤNssȥF=)8 Rء:2O gOT V8֓874Mq \cD~Ϡї=WbU)i8E ?JVmO}*~֌ɻBFsڤ+4' d'4㚔)6bx4D8ZH.v=h&B7͌~\sF 횒5'fDWQP ݏj`9'9[xסO, E=㚜ۨ'4A=9Kb4OO^PxN߻[qqD QܓҔm4Þ3N$NE o`ҁPF>O#Qޭ\QaS܎E(-N0N%ء?:Q~tQ)9v'{ҶBځci8?ʀ$4ߍ384 })8| ~i1A8*n$P\tD^AI#?&>CvwS֔f8qCڂM:v{v.1$ѻNi_P:qA 4P bq3.H= cw$SE&< qJPzw'99z4IҁF6Iҗ;q׽kh$ᓜB mRrzԎ렻F1LzLS$9:8'Qq@\HxR}pzP>vz`:qI=}]HQ-q (=( qIׂҕ0GJPIӽ١; yAOJcA:֔`ӱd;$'8~q}iH!$ g 1GN)0ȥ==hH`|qӽ8QH8"l&[&gJQ~i0]F[3@xHZI871J֓zc /J2G${RRzQ'n9&;.׊ldsoZ^?J0 SR*lU~psT"t)&)^i1qJHkQ88C;f/=6=z(%$) F,zҏLP@9ڼEoQH99(Mn"-ښ@y @iv ^3Q֐֗-&ӡ@=O_aN`ƀğJFP;ڂF(AA:P-yޔ`3RpF9֔é=hGX2:v$q{QP۾lwR01z8*O4 sHގ42A уPWq4'f zqP~fAۨ<82)<QHClomiri-ui-extras-0.6.3/tests/unittests/assets/thorns.jpg000066400000000000000000000723111455543116500234740ustar00rootroot00000000000000JFIF!nExifII*  (1 2i!PanasonicDMC-GF1GIMP 2.8.102014:12:02 17:47:01PrintIM0250d  ' ''''^''''"BJ"'d0221Rfz   |H0100  )   a 2014:01:26 22:14:122014:01:26 22:14:12d PanasonicQ !J"$%R &0291'() *+,-./0123b 456789:;<=>?@ABCD EFGHIJKLMv N* OPQ" R S" T!UZ[\]^_`a!c0132F !DVEPDBAF @ʯ̯@1P eƯȯد\\ίүЯO DԯLگ2`bdfhjlnpr"$V&[9(?֯8]0" 24&6A>AEfhjlnrg7pC*A$8. "> 0&@¦HsI6 "$&*>.Z(,024BDF D|~JFHNX@UBf xZza \wZdbfL " 8 WBbF1fh`md/e@BD4F{hAj PȨP¨`ʨPĮ̃ƨ@Ψ $4&  1"(/*4, .0.2 HJLNPRTVetXZ46dddBDF8:<jtFDާ`b@BDFHJLNPRTVXZ\^ҧħ̧ΧЧʧd§ST "$&(*,.02468:<>NPRT`bdhfjpvVXES YC  ̫h FD"DD$XZ \ ^ `bdfhjln@ATB<"$&(*,.02468:>IAVDS.  CM DAEBM|w <ML;0{~V(+_#@? EP.SAkNXG6^Y%Z3^}H.4^)VR`9 8I  >b0 PRSTFCCVe?s PIJNNSSl!QabArnb( ToOKJ;LV Ne`ru0-dP NJDKZ*nONeZswLB OHBLW6Qc^0qsqXw JNJI MXMee:s{L NKL3KW+v9!Oei2+szR #AQKKANU)  !Oed:ttHL$v RJM!MMLPfareWBCZ     LNSDF9210022200449999:99:99 00:00:00>LUMIX G 20/F1.700BG3154473NO-ACCESSORY00000009999:99:99 00:00:009999:99:99 00:00:009999:99:99 00:00:009999:99:99 00:00:00 R980100V!^!(C,!'!,'$'2/,5BoHB==BafPoر񿘛C/22B:BHH! @P@ (P@, @ @@ @P@(P @@ (@ (P %%  (P Ҁ粀  @M @(cj @ (;@@ 8(( PHҀ @ 86P@@2^@( "U@çK3j @BC2\֬?,R^1%MZ@2$Pz# wlެ P ' 9\M@@^r @ q9WSk'2t5@ @@^'3[( Py PN@/((Pw @I InMB@@`%:z PΗ{Erz` ( (PIzm-Prz` (P$4MP( @L%:((P  (dmwl#4 P ClެN[@P( %*"t^[7(P@  [:yL3{[$j (P(_GK`1Nd(N(Z@4 PAC˵CCPsp GC[$A`3zr(av 3`@ x=tRB]/b}`M(afHX'TP&LuX@ @'Ԣdt:[ 1`%An %Nz4N J @EP3`/Ct b Rè\w3z(q^q1 壮Q⌍NX; 9zSCJ4"3Z'@ ( &ΉKh%,8] Ctv]B*%3J(=V]@@ (( GǨ  $( Q .\u[S0@):+d@@ Mp3D47h$&Fdrd֋ KL`8 ƀ (3z5D%23a ( 5Z3L7(-3ݠ@I*`@P@9Ax lMRҊAFVT13P%(Ȱ 3Ъ`l@˚l%&Lî%ɓr: J A!ie'"4NM  ,<᳤(d9-(r5SZ/2v(:P H`& CBM@@-$& b}c{&,& i@N{,13@hA4C'4S4 2{4'cP1:&,(dޔУ& dР,@M8 q:l@D '1ȝQlЀ+{WB`6/2-1N{1 ",( @9hKb@(<ît ;A i5SRd`ފ1 j3,(C'BΧ27v =vZ17u0:RBdCt#Z3Ԛ#ˣB n'*cˠMh%@@@;9Y@`y zPS9:Rs6&@a I" 좑CB"-ƢBf5s5@` ( ͔(Ct:q@ 󳥖l{BT3A4 N$9sN#z1D:)4(":9C /s R:@ (@`,PPC99[7yzl% :ls5! bV(M鑣;:TP@@\lKZd;SMP@ 9$-$( Q s!Mh峼TԨ1kH22S`'#ږu),+`T&\k#G&cPhs @9,PPd-[K TdlbbS:93N1欌͢88w5#BRP$$'º9: ⷢk0B,P@ҥBfl( n\,R[Γ#v^9bV5Vʰ,4Y$dΆ 7#qC` &I2JJQ@GIwyL t%)m-MR-$e(38DRlA)wa(( ,-$(5e*3iaJ[cT-[l@͙BBJBTȖ  @B ,*@@Z-(FfD$$%3,A@ @(Z !$.@@@@(bP(((QbKJBBA!$I@D("H(PPXP(D )D @@  B(PPX ( բ@JA  @ (,@(X -Z   ,@ P )m@"   P(@P "@RA) @( B,@ P,( T A) AH@B(*PPXP(X )hP "@@,*(PP"P(X) )@ @@@`P(  R A@ @(*(B(h"(R () 01!@`p2AP"Bݳzq_)sOWUFFHwtQ՘(F&&,K$\'D1^:G&'~bEZ"S IhN}ER^tAO;ɜQϩ2RczQelLHW)Ǩ[$-\jL*H6_4鶤Ćd̷>bN ڮK32DU8RADΊKt %XF4*5+j\zҘw#P'}ORQƗL@S>h[N uS?q TqDF vkѕF$00STvN ̙՘Rb`uEEI m4.o-lC$^iW4/]"^mGFn% ͗<H̖cMZ;.%wdW[wT(kbU6ɒC=cU\=!kbgRBMuj>[/~={lvב TƘLAmW\vr-u/+u@bDlœQ 2 ;*XV*lo:QRQTnRd#4fL(>;6jSΊffl1f Ř 'iMOwxV]v(13: h{vjDƟTP3SiR`&q{Z'Dj Κ)Rn͙;C1f!j9Gc;z1ӑ)01[0D.ib݁'0?d DbJOS֯?./CaRի揖uFt-.®)p>)ƟJ4I$vnS u'RJ_ϛT- iLE3S>̑֡(JJџ픨ZvZ ȨR9lJb8Ηd1h%JڴPZBQ+&KbR*o}9v܋'ND@йCT'j5ԫ6V*EFGd9T_{MK8uIՙSe.0e%lεϓj_]5!W 6-nC1[ZfO9n~|$I;slԊSld$H܉+71]Y'y'bUP|Н*U7lMLvI$I$I$o={Y2&N&dO]RNNII6Y MRMDhm"$I$|Y2l$2H o#9ۑIsy$I$I'g?? `p?qTmB.%!` 10p@PQa?}gţ>=cŹx OF68jxSo@8}8Yu ,` D:GRHsn$!d2BB"̑6Z,1OGБ=jZeO)qOH3FF(Yln_* !10AQa`q@pP?! .۱MWWfS 8 y}QԃUDkPC祸0-' C%\ \G͟p2'lZjCe@߲-ܧfXz?Q4}Z,<&nۡ/mrD7o'.`r/Ѕ7\ 'hUC-غthK޵ #0R砠41{ XR:?^|0mM\/ Ghf'E(1jF}bGb~Xlhk̗hh?UvW6bwBhk c1PK͋ ;jiFq>D_7T%vXF J- (&- h 6$$<'|?,ZZ!44'5x؟_- Xc aakQwX*R! Zw. V}Sh~|'pS3K-E&lm Q6H'g8#v웞@XM=޺S[e- -= ϓr*+剜&;$\-I}K._",%l\6*i=~# R5ڿ4N?Ԛ&(S rp9b]#Cc{=-( ?К|<&ɍ}&".XCTĬK;={aEmُG QwXO-HUlKcEJrk\[0!+8Bk>c&E K&)u'~z}~3`O?ޕrДW :&/vA*IX6=Yz-Y_y|c-~hhi75xNz!l"IpA\p"afRW Vn<6ֵƖZL;&='a8>[x }{ai}|?)0&{NQ%҄Jl'?PrS &\J P'z-\ Bt[\Q>(>Q|q6}aD{ n4-غ- }VD'U-r6f#=$ZurTKC+I(|i!yH,6-&Y'r5Tn|1wX83JSBc)Ea13J<6.T t>,^ O4}LoبYzw$1b4,1ADY [8eAhM OrZK6gJ,B`Jք&/E';UP!ݝ_Zryhxbӄ!c.!;.Qm,pwirC!.<bRh3pXetR-;nD Qj9% h{1ba2aL3\\6_ᆊlsx f G`Ar1"7_4;z667~ U>bGЍ$o 66̅)JQ9 gAٺ1vh/O: |5D K:mߗJR)J\E.R(ފ&Z/J%ܱwV*5DvB RsˆmVH=Jv<]M R)JR)JR)JR)JRR)K 7*KD {e<%rH68Ba.D_ĥ)Jpˆ(ʼn@L(qlDZB󗨱FȖB\M 蹥)J^)p)JR)JR)pQ)KNfve-eR[Nޕ2'0!B((XRe/URbAx;=p5y,(2)J^ R攥)JRiJR/QK `xLO#KӸl.nLAQnSQJ ,Nt ޭ\Ql\Ru/?S>_#=4|? """"""""""""n"""" ""."""n"""""""""f""""" $""""""&""""""""""""&"""." ""."""""""""""""""""""n"""n """"""""""""""""""""""""& ""."""""""""nb""""""""n"&"""&"""""n""""$""&"."""""""." """,""""n"""". ""n"" .""&"""&."""""n" ,.""""""&""""""""n$ "".!"""""""""""""". l""")""""""""""""33"% "n΀""."!""""""""""'1"01$""&""#.""""".L""n""'""""&͑1"""""k"""".ݑ ""."".""""nݑ]̀""""""""nݑ ".n"""]ݑ ̀L""'N""W" .""a*&" ݑ]""&%b""Mݑ]\"")g""""&"SQ"""L\"""""" ]ݑ"".""Lݑ]""""&"ݑ̑".""n"" ݑ""".m" ݑ""# ݑݑ]]" ^ř L͑]΢m 333}ݑ]L ̀]ݑ33333?ݑ̀\S ݑ]333333337ݑL[333?33=ݑݑߡݑ3333] ̚ݑݑ?33]ݑT%W*L \M%A"5]3na&MS̀ъ.&]]ݑum#&$JW_vrM]"""}]33Sy6ńr @ j".]2n"-&䀈Ͽ{s΄T@Fn.3..&{$ʞQLH߳O ?H`΢&"?&*o&J!LW8W?UW.0 .&blh , H7a] K7w̃o|s9N@bn.o.nkeT ]HLAUyϷXDi{V1eq7u!٣qʍN*"J߶,@e?{L4̄+37&m."*$Y fm"$""ys3"jlI*.3>L "". )W(L(V@$ Ul3" ̂""} %WLn Bl3"$L̪""Y %ZhYjlE3"$Lά"o3 {qBH,OYj732 Ľ"3y aӽj.DWY 73" "?y bh ӿ3"̄#?y .wH`f ?3# ̀#?Lb{D**ET7{"L̀37Fb®(wT`Hw#"@ "37տtn*]w3;4 L"3?9YѷD.$AM{w37>̀L ̧*3YQȗqVɓs;{3.l@LL̢#?3]jYs{,uɓ1?.l ` AP0@p?c8ÄYW^+'jy:R`ZXjq dT !P*B[+,p!)q\w '}\:P|^%vDl R2?" `0P1@A!p?"ucOzʧ1sZJNTN`CS0BhB ԍ`5sj Iҳ0iτ)<QQGQP4ue0Cua8` `X?uU.S=&<Ǭq,T 0CԨO8 ?>AC!8N"V06!"/؇! M( )'1 =u"("+< E"Txˀbbj\p NO-!1 0AQaq@`pP??l_2>w3?B۟/nߌ$:M06z6QGOOow5ez0=Yz'{b6L6$t7Au l3@|ndඦ {R_ :ߢ[_3=!mP 20D6 Ck`\ʓ(Yɍȇ;:nSa?Iʁ32YW/>u|PtɄfif ܡv_; Z 7(g)}B_X]*ߒΛfڙ(=} c53qgXJ wgv &;A~.!WEthD0ŗ~qvӚ97! p<"{_  B @<ʝF5ЭB;C~A&~ )A37Dwu!, R?`^ e!2)݈fUC:yaylzBMX"^^-`}cDيU|@j Çd,iyP"fq& S{Kz:- މEg ,H͑s6he?x=!ȽvgLy7T؏`VK)#?GA7CDܛn<"eȽ-p+'~e&~s˷*["zЗH qY֊CX&Sw_y~j2͞}&{lk({Gb5y$ x0C% @hC{#ATBAQ/Q2,K9$0GucBnmGS(-@;MC_65.e/lYD.Y,v`cl\9byQdLb$Qm R8PJE\"7U C;\%ߡ1@{d^"j 7e?JOVngMa*5`g/xJP$MT#fRJJ#3 ](Fw7/UX0 P+0= :/)<ܬo +up<K Еٰ*IdRbe 5 E ecgtnP,u3`Eh*ю!Wټ(Y؉%2&P3"E&;4%$Rҭ4b2 JHMX6_S_t}:( BtM4[Xy Z4tdቂ"jPAla+͛Eh("l6i᾿$Db\9 ]"Le4N(& "ǥ\ ?9cmnз.>K^/~ rڎT QIq^03&sF&thQ e  d̓v 6~J,sngX'ٖdR̰ Eǿi:QB "TlD;GLL;u0%i k K6ŧT:^C*@ l+s$.F6f"z+=tD!STDW +RňMbw7Ef QR4`p&chAoob^=T+ǔ'1J>ޗv^[k~+%|RKw7GZa^8lb]1p 6ʼ& .*m.oaF)4YkDwEXZQ_גKCɗ{02tQwЧc[ Nᨉ0ehB5  D!% SqbdZT]@֥DQ %`E>1j a,pUU݃qMuFǒщ7?I^oU?ٽbewe٦R?{ wR zT4]C42D"`K #Ųb Ql*P-y:0A ޶Z܉?@ABCD EFGHIJKLMv N* OPQ" R S" T!UZ[\]^_`a!c0132V  !DVEPDBAF@ʯ̯M@}% _ƯUȯد V\\ίүЯOwDԯ"_گ2`bdfhjl npr"$V&[9(?֯80 24&6?>AEfhjlnrg7]p+*-$*. " 0&@¦HD 6 "$&*>.Z(,024BD)FD|~JFHNX@B xz \ZdbfL " - WBbV 4f`de@BD4F{hjK"PȨP¨`ʨPĮ̃ƨ@Ψ $<&% <"%(*<,%.0.2 HJ LNPRTV etXZ46dddBDF8:<jtFDާ`b@BDFHJLNPRTVXZ\^ҧħ̧ΧЧʧd§ST "$&(*,.02468:<>NPRT`bdhfjpvVXES YC  ̫h FD"DD$XZ \ ^ `bdfhjln@ATB<"$&(*,.02468:>IAVDS.  CM DAEBM{}wqyt&*Bmy?Lerv$&c ilxnyb"f6PRSTFCCV_3_dZ? a$RGePaONq5ESYWeYd]8; s)PHiPaMN:93JRYWc]b^  "m-OHbLcPM;MUZVaZd[:8 "-PHhP`NNɶT;D< NOI %K&„\cW?]&P𨼀$U:4ZL2=*VfrD[,K\U6ЛI3?Xv }ƿv].<F-CM @cc>ֵuYتe cm l1Teiud_Ts5/$;G޻t? 'NGՙuhgrzc8EeFҼ(qQe̒E瞵gsU&p|MSZ!-՜Kt-WbDPUGmu}7O,5H0̊E?=+]i zm"HR)1RM""&*R)GLTRb SE+6)qK\ULR"[H{VpG;W<}+M߄.P:u^xnMuж" 6;溸~J0\dD.V:iF-͢xjqmZ2?..,DR$6: nuQ -k&ik'\P?*1ߓX-]ſkۧ݌xc56X6?N dwQYi8P?`OI'6tViPʒL#:tk8agvOEUazo=XOZw2J\h]BGi 0ƄtGE[:`#9`Ty&I'd^cEEQO&Hq>6\wiy+O% keh^( 7>^:r1PJI^+5SN=^yL-mNj%-nf)*#<ʸu]A\]30]ס2㶻D,ÃTMkr"-` Hs/?W5O:%}$M%v'FQ]j X?&5RQ0JhÖ<ZͻiΌ3cREBEz#"ixILRE?Q`$.)إP.)@F-_FY f|!Zef}Y><_*v*߇]u[1S5 HdKyRH2."ֲ|M& ^7uR,ÃaqYZ~gx'+13D͂p"=n.h-MЃn;wea9:K|[@iWιd/l 8@Xrr>?M6]OGfMp񥞏a7 `FA]KYu2%NQ{i E.lړ1]pyb+vrDWI SLLTRb,RRM#Q@.)SRN(@+k#,{M}P? {VfWJ1F#*zeV˄YxYsi/nnFIk dIcau讥,*M(=3I,J~gc+t#hԺ6?>6aiϭYơ2ҬC|v;QImtz~}p9ծ^4.<@V/ߖ ;K71  WNk#Zؼ\t1WC@vIPkϧ]/Qm FhZLST#` 1\敭^inC6"M@7ݻ=+F15]5ba%ܥ8U ILV)+#6E; niTRE!&)1@R␊m&()qN1 ;)B!RN;m3]m^¶]4gsQOju$îi~ɋU7%2'[a~xWxR\$3б5q #qW#=Z0OehopseBR\Wԭa.S9xZy.nfckn,Fg;g7ڜڋ$cZV0tܥj.JUab ɭp PH#fhWO0̧}TٝW $x&(t&(@b.Mj]P[iqHE "E?m p)TS!iiiBʹiivOȅC)1iK#mR⛻CG=mk?'KYEقMΩX=FCqp?K9'x O8>c\rFf`i2[<.B`{}@4i)+󏺧l ~j(ы3 VD{hIs⍵&6[hRm0!HVI!I+HV"+M"byP H(!E-PҊ(lj9Yn(/~z?ԓInUVDMOՇz( (Bw() P1 %PaC#=h@CC !   ڱ_dO O@G"f%S%H)L !*4|հ3(bO2spN d0dӣN-E(̸B J &CȉpQ2B \#$)ʝ8OΔ)KS,R(HGaJpPJpS$dJd"3H&ZIJR "H@D( JdD\!beܮTK%5(i$%|EtВ Bd d"d1de۾ RRr@JJ |pm{BGI%Z]W8S%) 2Iھ%2I1HBM:_>uE)$ Ta~aX|>xnm'> {⾿z:ŭLgi.X(!2FJ &/]QIM$H}ǔ(>-jӗEO~Re,^x/+ɢV٬CNJJ`)$b~.)lM7o]Kv MY%L>z2)1d -)Lmp|i->b;.2?/|Ձ]tymF-YON~ЦD dDR$1=~KmNO\_"j'FR%;5gk)lsU5EavO`NR_5VSp0Q?U*I!&ocn)qJF}nX6T[N-՝>!Rw;o:>iS#$dH$␓M_櫟 ȝ앷:v}3%our[9sG\caC6ԋ9o~7LKaEH6! /%$· ޳n0?uccM~I>ܾ0 y}GiAtwYaHA"lQub#k͍VWtam{}Ǝ8FG|#wl=f^} &BLO'bs}m 絷Nw&cKn&m}0~ _H_14U\=nφ?>N@ @R!:i'ouh>G}F/,pPYv6ǿEMQzkk[$`Fh,1q;5FQ`,0IVNI4>5o[K:l)}<E[_<O]g^c_)}PwVNɘ2#!HۓMš4'Uߘ6̾O}~꺺ծD`̵ןWp9 pu|Ϗ 4BCDRRbMR*9}x16_btVnލn2&0Zo(>w,6@R$Cd#!2 Cn)h O{Wׇn4l~۾ rv+rWnz!29a,4@a*D 6hM4#/oW٩W7vtv{?&5tQ͎~ 9" #dh)HMhNA)B9]lE~,/=!r{qZ G,y dC d Jd& *n-E14Li%1t5:'h,mP, wfUm}CeWھs]WrdqlBd'M&S!)O k/ľo]U{7]Ƀ|mOG2!SB MۋrM 6Bv7̓/c- UIg!!#,SNHm4Ӑh>W}t_Վ%yYhj})r@$fH)ӦJ4MM$)O]>6YZn42QrY &HSEu\"K HRSpb+ao;?IQ3gIs8 [I)RC*՜Zqi1$ Hy?{/QbY@p @SE?, 0@!"%#&}uu_} :BWuuBBӯ}+WU +u_B (PB +B_]WT(PjU(DK(PB(P]U|+PN'g\RlNOĵ3k9c՝'Y 7pt.I D|+u]PlF.Kcۆ_BAfɉ9LgSs3 6OP+]WºWk9: ?RS9j'8S!c~Sԥg'GG$ {Fi - СB u]W_LeeAlx5#.ND'ؤ CxIW9IqzoUS/H7xl`ZyZ8!DQtȡB (PBՉZ DB=SSYC4]x8ΜLN2 p3O7^~s7N g慴wwWlhAPB (PB w_U Q6aA#eKkZ5ntbZ,G8kZޢM<7gY$nԩTC$`ɜUB1)o^XtD_2x:*x0fS QB (WB1ɱ0`WUl]Ml@r|7rc^((0Gdk^܉,i&@#'xGNM ;gqC5HmnSXӈ3xv-Q3řx6bODvtD!{8g 9 MP$I/s4& HS#e(?$=!dq홊` 2ܛ4 @F-O6̅\77ws%n(7'||b[`dPPq)Qiᅄ|wZ db򣍂F&䐜)pZ va)yN2Op\XdQ0Ʋkz*dǙ$I 3&!?Jb{`gС_ f`CUƕܤmdTOg u]W]m4-) & 9FȡOur\r^>&ΏGme%f1Z9@xVvDyWHLQXw*h>SG G6fvpbly  +hG")-|CT?Kc}_1E<&RIIULNcNхK!6,6_Œ#k%EA-Y73II|[ 9\Ӎ T8=~`cP^Shi\O+ Q.K^ax$ / _* -8-$A [s1|IG0{j@IJ:-&BI$|"m=F#lHxc8"e<<˒_=,zBu_C[2MPl]eܦr we?ȐJ' ;v\(lF299ɥ)ED[[;{87vfjs sw(PB (WՁ\˺^M%%<·J2 \$r1۵jVL%yJ=r9UB (PB +w8 yr,JNV0nb^ܦs_DOTjfm+3FCJݳB (PB (PBR}KΧ`:՟%-rc+s39 S#kK诅uB (PB uBuB p:ݫ,ϛ /ʒdORI*@'pL(PB (PB (PB (PB (WF%HW_6m@Z1 ЭIHxv9CFB (PB (PB (PB (PB %&D]GߙPwSb% ~!K0h0;~1V(PB (PB (PB (PB (PBhA.3ݑ%nP॰3arG3Orնҵ膳"RKcf= (PB (PB  B (PB \dބЕ-,˞!1,;3xSޗYk0kbuB (PB (PB (c (PB (PvLe' H o"j^}o-- ߗ н(PB (PB (PB (g(PB (PB NYn+/%}B (PB (PB (PBp00+(PB (PgmRW51UYkv89B (PB (PB (PC#ry\Q&믘噴B! 1A0Qaq"#2R34@r$DSbcs?'rXCp.t =O:/4U_9h8U诤:_F u,fVKK6F8&aoi\=@h!2Lb!U`<%wUʥ–u`~_Bfy#j2mSPʪS,a{,9fTMKkg]U)=PWcK~*0jʾ7 s8h*ij߳jy&Q\uoZ"ϫ܏ 5wROQHIj$#8rvS._5؈0yuc s[rwUЩ`NPA-KZSaQqR7jqܤdSLZ+n߈ĥc ntU\UfWqN"9EԻRVaԈ\j%YY5F:7F723QJY²b/wH{u_m*qR5lݗT $6 s65yɪ<:?`8F& MQ-XQj鼽`^Y~aTpVC+fl:Mhܰ)M;;|!ϵ-wܬizJ! E'FNJV4-Y}8]Sʻ>P?iK 5:6Ғܺt\yGL&ֺk}1A!dFC'ZMcE\].z9+5jHV2G۟69$?T-k)c1#m=:F4;^|{-)ֿI|Nգ>fQ P kGHD>ҭ$2JoV>IN|~Z3]@Gs âk8rLdP9ĠAUℭ}w,60eҤmc\q$Y XlQsRfl,ssCX5ыe7/MU{}8X9߂hdG:]ێKuDTkz,.BV+ݴLS#/!䟬8'ިoIW@_WCާI~lM 8}БTI bBcUN2䢒L>Êc,m V!IJK=EMV[uLe!c4#Ht7c{U% { C#b؅Vph'pCAsEsAaH+ Z*CxgbM#2ii{É퉩e+ZUeu) ?qlfa\Z+q݇vX{=NFJqIR/ZsJ|2r0:^BRXmW'tUf'寡Ϳz)F=-/i[`ܢ iyġ^DH[ uC+d(D jm>pDQ7鏜U*F]=qHrRqcq]>ʣA*ۭlh{)&d*Ӎ~JtM#f(61~MsqzRI#m6dMrޭ+[bmh@E18+_:Gv^)RP/sdPga(`:L (!:J8lZ-ժBtFvbMĭU?_#9,㳳"\_ЉiaJp_"&D.8@̇SХlwӲti쎤LKҪ+=bVF^II l"3,KtemXj!YԲUȼY #4bi߼P;S^) {j<žzLtN'4E]yhëm `C[%|̬ i-aqrxo*TR>}i-Ld2ZڹSYR%۝}-]iG(z!uꋉ֑ZnUk٥&SNT0nP њli[/m`Wuin*S Lc^aAKM90Β:&Aqҥ'Ŕԁ}#HJ Թ S~#hU&ss|-N%p8dMmq;r2WN%6)3AX5M~A8.sL˅K'!0<#|&2)wfu<-W|LRM1Ӛn8I9|oN4xc)d5.&N?N*a-jDt撳U* [ԺeCXa~be1??XCB)-yP/ϫ:KqN$\qV[f} k GC-*N'^ͩJMl-A×J]TӟyHsM_'=NW#)*=!8"JWa#i~|""i=:~-tJlEHdtO72l/H5e-@`~~1IMK=MuZV.z:ڒm%in&IIN =vE,ҩQq肄$:-Nh V[6S99NQB9ztC4Ҩ#~YI*>VO"w\6uL)-laЮN%ek2rj-'KKnt%[`>t-T頔c&e+#?0U!tI77;5|N!v2mV-ˏɗ&*N:ol֋EƧ N0lRl/ |a3.(mmN=қw&\u* #R&mx"lZ,>7Se?:@2=T;=amWZ*Xie2%~7ۇgeJZ,jَ}m^rDeƒX KsNtۯFH'pN~NJHJK \GOͥ vE~q&j4oGgx'&U09$zEFzfUelANKY%DCw c(kWmUd[xmlsa,)76mω1T~+NgƉCwDdB.ښ/bvGqFMJzY$pT k(p _V!K"bZGpӘ q݅o03nmLYR @_N4 rhlX@61ҥSO<:3 ۳9E`gOpe-y@$ģ#%G2|ލ!՜Em8EgUXb_#'3 @#V !"1AQaq#2B3PRbr$@CS%Ds 5ETcdu?j(!H_"7ˆ[.:bQDNg\#A{pXmnl+aQ]0~|2q?U#v;q{qZmr\O~+NFmP'7?th Ӛ :bsu9u>vNJv V)j*U<3))O2HcĴ.v\B2v#R,O>eeg֩e"#o#a=ɞ|nM!jJcT4nNOYpo9dO9+N/sE¢1NQGڄ#ƤJ0-!N8m\h1K,6؍ꋻ{T`ṖQ KapZPPćjYt"3rSpq,s'h'2 eԄ8bϴqĈK[L.DkJuULRc#n!+%mmV$l4bKmMd.@ WKΥ'Rۋ] T0nCjBodEz«"ѵ7";Yд'n ^MY (Z}\eNcRUg0ߢ > (4'3O /3HgS~#ɫ3UE2jRZ-V '"b3STZ-z,9o.Mq6m>I7?ŐFζumjz,KgG)x<&d!7MyӖXE !kbՁmOf:QպV)n7^ܗhҬA)=bK%;4KKd}֮q%r/Z݆eɨUm1pV@\fސ;>S &pӷ]:G;~ W+z3u$Mv'eYp T(2H,[lqDOŔy%-'DT9[x[ِ5pakfݟ)m5'e>6Ov<5\LmƝz9om2˧ -6n?H!?ӹJ˚]1@HE%rTNE9tXbBm')lMv%'r`6 ,7:g=9`sŧ)^Qc|J8WG)eHK~*U)({;H:|6z'Gܸq?}=UEWCꬡ:-[vT6S(^> 1qV8ھҲ wiRnҦ@9N 8qGu6=Xҕ-,Vve CLi󆍈u?G`$aé;T/ivag*"a<*IAp=RM!J$L/}44Zr*K}JR V[b~]*onvYr2:g5j Xy ot-.5斕vFfmH#) P[e< UaӢNuaur\L85o5P*svpS 㶝KFoxa),Eo;ĉ'#d4S=6 ܏2Z]mǓqez) ӊJku8t(Q?誣'BOkAJI}IC1ugD<ތNj"J:KIqO9,7ZF9nVIY}g{f Z kx Ltju`C:(ٙ-q>DJ n#רڣSW5GDՇդٶ{eq<|yIK_zU`ɧ)CI)V\4㨎VklFF܇nXtxͦRu^^^*L~pyU{/û (^x*[%%\ʬAu*};4G%ѳ\}%[֞Z ftbԳUs46⢹" bM~g$֡sip V'к6IV%n;=m~A[O;p{El;v>|\<;~2K:=uJ#YsX+:ZWj(jdq2Á6Y}lz#-xLh{VG_FG.m.l_yYzaTTZn|Ib:Z[uHQ֢J7 ZɎJa.Uj6*uVm[tH --pLjB.G:5VmTy,+1q`_ fmgSaX\yl)+Z2O4t# 1 V%'qhؙu"-ժnxT_Xh%Q{K9QI<j|U9[<8b<^%:;2q 53|^>JDkjM@uyAr[Im-6]$Z ^t.C+2em%[mcW2hd)1B`-tu"@s))P(6ףti~/ ,sw&""i~]Ѥ$+)Z0,~qdUeY~'݄mMr,|n944 9Ss!n\?NKv1z;mݝC@Ij%E&JWWK[ഌ<.{0U~ npsZI)X>؝կLgbmxz,ϰajK >6s LPceum%^8TN̲^C!aCj12$UKe$'dbs"n9ڕF:< ʷZBT$xf<֣%]AG$\^]tQ6L/pTc"­[݇Q :9[Yrjdo)Im[ָӎ].-u'•vNXR }j(oVY}ȶn $*e'T ,1!Wp+nM&seڅ<,Mb 'KE1yL t1G"Se$Xw`R[Ne{W0$j lrÑdq % JR{bN?dJvE5v1_ |%Wii'4u$$-dzy`}Jm~n}ttALߒ ^ sҚ殢J).#mז>&Mvӕ'o4vaQ(DbԬy')m(hIlr%P嶛yxjr;}pL itr-FoCyO+ G aӫT9[𿔾.F7z8ed̢gWtw }؃6PGr"BNXn[IU˥* BHB8r:!P(]bjvɧ. {#i\ ÇaFRN^yQzXx skkلNT@˳]/lW]{qɲrS pH %RZQECudN[+2v N&3+aPGSلAuzlٞ,jZy[y4&GSJ)RriD y{Qi[SȲ)fH*r"h(:_)̑tZ(v[m#6j@[l0pcA25;0;/m/@\OK%(rev VWh;6GR$a)[> pOPi?iC[KBZ#VSMR1x}Pr1~'C6NNm1*.p MӘ-CSQanDP3e!L8%-#n8qFtԭp3Zc)jT:wiLP~>sḳ^5O:`Eoil -Z2tOv}#gC/Us'SPiDu'yI\]FE+怪D d=>U0mdeޞ*#E1[#Z>o^,E:ۚ3gj§U_nv2kn9PShQNx=%|3$ᆔ{Vu/!nJLv֧'Þ)n)wZk>̞8TWiJݔKRb*N])g.UlrGۄo o{SYkNasJRde;.y~nN{2"+b.'IV< WmzjDn%;D͊aDqlTn/E;?I:C8l!Vvi*4/PœqjqŒdVx+j5Gz^8]6tb2Wnusd>Ҟʛ= VB'6PԚ|st7flr2n@\rO[e:b{:6!^H$%"R[ Jϛ4JBs$xXǜ9[h)ş1 n˺+Vn2tEKtBW:S.gw{ʱ26mKl#-H Gߌ7Yk^M$CGlv+˻:x{OݎXrTfBww>=!Ve%Ys|4:ʢ:u[Iec*q:Y)g&<ꎔH'/ s&q5+]s#|.MN3nKFһ9(ߙyd48F#“ܔI`; ؏Vvhm̜"حSyt=d2̅(z_B;d36-LP|qHK{]"RUXSc+>J5X!ͣ3tBoTLRé<=X!e VQʂ$4Ї®ݬ2ڤ*a 9粱J';Wo)άǗ~iB,<ܸC&qD{ vaUsX|du- ^YO*i{Y dJӿVPl"@~䅼 Z=xuC^Q!CG9䱧ΊʓƓ sAᄱ)DBbmS-ʖXFx"YDNS~Ֆo(:;O0ijN$y3e1q &اߗZO)!1AQaq 0@?!BTP%J*WRJtTR+J]J*TRD*$HBRq*J*TRu*T]+Q:*T*TJ*TRJ+R}*TRD*$IRJ*TbJ05*RJ*T]R+utTNReJOQ$HJ*TRJ*W=?TI]D變+n$RD*TRJ*TWAjV3S QuSDÝB_ *WCJ變R *TP%J*@@"\XΜv$@*΀% [obsdV^YRyh5{!2CfEɺva_ #0] ] $]HtTDTP%J*TRJ26AY6eHTkdUp4i{x C 62Df m9,s3_{J9UĴ3 !0϶%KBJ=*WP%J*P G<xswtJ/0p`\%^bEUՠJ?:);*2w+yTr$d7Ju|8 ЊJ׆R NGZ;`* w5Si=C 0t'Et$IQ%DTT P JU~|ً}րSW>s^gE%ΟLl@*ͫf4}vT*ʗau=b{Ō 8|w(RT)KgNmSEB^%'S^@c,lLj0?&b h6҄12l(`Xy4,py_CZx.}Gi uq9@Y@y@%ט؎kڹzGRJ* P!mt?ܵw)k@ܻa 7+U|ʊlD0V+p,`d^zx5&}b -r32m4BfHqG G )s34f4: j]S|8 bQx3*պ136Jv!9;lu!/~&h;yBk\=xta*TRDV*%ATd( ]ٍAU;*,4.<5y\&ʨv?mp}E4,bc#DnjSj Y o"ʩȗe4 El=(9 ߉\+)|?NQzC#2/Yqf^mN ƪ\ x6ehRyaMpP*ȹe:~Ȑ.]jڿ?y5(82yPVnZ]\k# 'CЩ] P%@ʟa'Ki݈nvUn詵2z [bfxHX{P/V{jϛ9hv XkP\)a7b/5S |Br''mlm\8|Nk'H"(p~uf IRt_.xF.Ġcas 0aNNcYïFp34XHF*TJ*T P%@Tz=j~IH[^hni0n~`,nA@|\=n H Ta+TT+xIP%pYy!V),82X61N;1< j9u˙9X*Rv-6zVVfi55 wF斖[bcj޷^.6r?!UYZ~s HJ$ ǩ] %a%C dܯag6@ANB!` //Lցqh" kBBJT۫Vp"&uWYQpAHяzr1hY >(-rķ\d:U*~l{ 䲇&%&seP*t9Ώ7P44͘3+#(U>uZeJe^IR0÷C >T P J?2 (Z٫"jYt+0)n0~ x3a#PZ@bc 2VY}5vn. 谊`m{rҳP~6D/y#3P3t`Fy)j`kr+N+`*=j$R*> 0 A$:Vo-Ёxk յ1_Vmq‹MZ`orκAt(mܩ z@Tc>|0abKuz*TRJ$H a~:*EJbk ~w#gw%A"? De-eYjR7󒬧 h)Ө]-VuRJR*=~OECEB *TO8&t[]51L?J g''&'Ll7`1 RnTq@9]q vblJz`-O Pp@AG =]yru]>'p."u 4Ft 0+6@%$ijW2M&҆̽jg6N<h:@@=&|: Au?۫oc Y _P~gTu\݉ ][{`|)N+2gJl_/ 7G#2%N/}^=D^wL)=WZ~O_}>zL0@C b"v t"ꦴ!Tkjiw缪*9^>jgoN8ql0ô`t0᯿OsӷN@!G~4$ <Ȍ(?ywʳDR's+~t;Ozpy_w(*!?ӧ P⏅/4_wEA=h nK31g. шܺK n?be类^xeXd+[WYWm41y tݼbZDvwƻb 6LQ6A1E1-XRB`OSǎ)8#H/K@at" j*kɧӑc4vsH9"냡!4 Ma]e]@3b8:K_Ә{`>Rmׇ!%`iΓ ~S a䜕|x~_HXWv8:Fafq:\t h.c(̴sOS-|c0n '1ۙ=*RU.F]U]*ex4*|ӃK(ƃ!B^%_zC.ѹ} c̺:BVEcW0N̘}.TϺXңx#o陖/bP6M[Z3 y]s#Rq)}4V3$5 = `F?@v>3=<n} EK7{́c>36=ࢇcMļ&UKΦevt&Zz@\o uV_kWP:f)u{,XU;|) #ځ]P*g2"~Rbc8NYJ9mkp|.-P֗9am]Ӏxɡ_2e۶RK*`s3L}Rʄ\K+B45(}-@^=ykj!A-]cZIq -UP[5@jt{bϼ06!]/Wp"PPF@QLmLɅ9kf3܀ L%Tq!Lr>W0@ܺnףW -8P@ H"S (GpUM6\. ^0Kk'g"@wq\-gQP폸qh(HYx11??/h*_*smV=P紳?Igvh:rxWOW=0+fg~NG%~ᗪ>-,,b+d0%q(~OIj.ӧJ*2*7~!=~&SiQ|SP!T{4K>,:=c# Ffhb-BѸ72K5-s3 `*uG#1>T(_{cT/߬0zogŞ7̲r%]2f]qYt ιk2,Qo4.~N#{}QpuåSCe3KXZnW,b\l\2}0˸\/ f5!R똺j]LcXD-n}/1E,= zCU_2}+h5P?S}4˨K{>*Qw#!(No34GpG!zchC%|A%UAx3 A A:)".ru`ui6k*Qf]x$J5V"hc^.%2:K^I0laX&U2s-ij.tXZŭ`Ȇm<uA^rj 2c湋eX8hPQ1ɑ3\f*rKPa!es!~jG!w lV^j\ZP^VfUeh*_IZgPțLcA4P!l8v6'R/*ي8K q̽Ae0.l8C#i6+kSCd7wnm91љXnܽC tB fV(Jos1n0 ,C~V!F> ?zGD03PQ7ޓ&!1AQaq?4]J 4 hĥ3xu:̪Qz;T5O"*nĿP(AuuH+KuS(%Ubfe/2%k0iau, tFU+Ĭ\љKRJURgrVnWHAu2j!Pb*UJDV @ÙT*D Lͳ)rbq,%]ffV k1 @ޠ19b"J!*u)RB4-J0TbVe Z]|B}LXL!*3qeyp&`AI dVu@,ѻ,kM'ͼSXajY;QZPAeuEփ\|&R 1_mJ1*İqV x)ƙ CqDw䬘?47]{~=FG!UG|D|gn sV4NFZcAǕD,jp@/qMCUD \0j +0|_棙uWv'=d.C m{Fv"{pK* &[f)cMC7Y%(QߨWs }.&īQ5q+kcip<s'߿ZȞr@R8*R6,K`w#cF,( Q#9B;HvIUѵt9 v-m9趉z.QĬKR⬞P\ g v5GNv#*omdq`bdQAˉxSx-`} 6:ӟtsB*F;Zac Ja4$ 7 2"G[I`&RtB% cΟ-+[\(p2—R(9{-r|MM[KSXͮ9%=\xcVӃؙ@g*JJɈSVd%E3/9.2*W .ޙcqAM(6'83sWֆ8p0/{2z3@Na3$KhݲxyyhT,/KpGs85q jU߈)-% kQaOt{"Z dZ䷘u zc*?sF0LD`hekF2lQ8NU[qw%~"k)#&N _zEb}f\Q#{>˚\~0/*Q9~Jm\?(?`߾& B% 'Y^bd FZKnX[>=u7\exzJ0kʔs/ :(sK|ީ=`\ T}^~j3ZCPD ձ)Gگ.b\'P!QSu+ XSZ`,jSqb/owEql\NWTɦ'QVznydWfzǔU걃1{be/3ۍ?[2,~( q`iHbj3bOZ|]8 b~0uBLzGԄlyuэP^ :"xqٮ)2&YztxR$;HTɩ{}]WDM9bjH8RţLO[CLlhosvbvb+XIwQX u|w1lͿWg ل-Un w>0pd7hE]Ϭ#Ad{{rT<*U H\!P}SW% J|‚39Qe[ I8TzV#:B) WIɄAT`NN[t%K0 8$xuSe>16S$1-Z&Npz9>1|O: kɉh7=n^K?c9W;ƬX` {SX#ύ`V]?o _89pb,%eV ;:r DLDH~<Ц>*r# 0ŔΏ4%TH+scBP'Q̙"j/x*HqZ+vvkQ&ғ&!k*abV^"b#!1wx#f/snϜ αwC(5Gsy7Rjyc|XƱI3Įl1dX7q7_0sWU9kZ0!pIY$xx7B%zJIbAfK{&- ´2ԳW$I$ðBb+}d5ɴHy31J@Y[N@BaARI= ԒaE$q d 1N3˟E}0YHdfEUn79Ej!1yC5j~:n+D/~rۃXds8f`a!5tTD""yc?VL#xntr>0:&' *]aׇ^?yi[Z=6P|à S 'hJBI(BM؉ðrIPqZˀ:a TEԲڃ"Ad W L.c;AIi2K6@* 'hIB<ŝą)E\\%1d&.8M۪SqY*X93Zu|/w9x1.Pek#-2zǚA_|cVN'|c_X4M0'3}^D&4S}.t$$Nðrq u7__&Rt B0 [&؍/2)ϠBBЄ%4D"Wp KT f/+sEMbC WNԬ(*KA ]&'fd,%lJQ3j;x!. B_T.@AHaW=&H4ʓ (Dt8!Sw`DވquS8N25Do)l򗑪MdšOl#rsQAQ=c5Ł kxFX:|| 32a`~ވTNbrD{ƟDnc0+BM#ByڈiT  2"8섂30 _Qy1 HEt!-g$ՇMUlS `,H3u:nJ IR 5(  ! zPv4X}|41:MN~p",L,ɖx<7XI(qNq,B$˪xfHY]H3pXG&/x90?QĠA)'NXlMU# 6' l{vœۓ6.132LAvzT*!A@8) tWc4D䀐xV#r?3 ES ,tSZ/b@Bq@}ƚ@N0/M4e3( @xPQ~g s,%OY -k(^2C mkcFN%,3?xc-Z97ۄ}>4a y, ¦⵼7%yrutZcQ@CZ mWx\n U/$Ħ鳌ȴe8bOdLr`EI1^p)ڶcuoIAE~ bkB*m̒=BêD8tZQ@40c1(R:iT% L2ԐiڼȂAS% &"G!J 9R|Z%٠{%|'D\Ůl|B6%5E ɮToZZ2˸bDL:L@lÄp4t"qDF%#McR5  [sYZ&&->% MnL:qbi+-a@ЅXY&ɉĕdZ%NP1( <$bv.(a;" C^fz<yD1ܞQ3 3 ;+rH˽a0yaµn,TO^rUBW8 uAMm#ej$ B$@jp`4  v᭣ ;HBQ @cILX!{X%ȜaCHChu ra (ԩ"xJ^n' ;ƒTmdĬEj&$> 6]1`DlQ X<$EA1;. ,¨BW!beІ oX XߤS2㚏)*eHӴ[2n'1Cpœg L6qn%t(B %HZȁFy˙~%Px(uyďlCS8b;k%nx&w99#"OuxYP()[Im\%饰u-UM`n*2(ݜĒ2 G HJ^CSl  A8-YWʰ1CP4 rs#hħ3(b(R2|>_3L( bVuzF ]4$%pPSrՕv0MAd& IQEuDV `XJ<܎8N$@:e Dh1G.D/Hk+sx>c2T*R1KЦrXJڎ;hMLCo:"fW3P]հ:4Qtѻ'Ԗz08ҊO_jKƮTX"z6љ ); {e^P;$,-7U3IT3zrYY~7qn~=c x,U})5k<2]]pq/x:Ú˶E2# "H%2HRaWELrM9[E@4892hҁ4:%^bT(ojX'~؀%dO"j!ATܡ?c6H,nq9ht:@⥖_eC(AqN2Kȡ(EG5`Bst"Vw@wiDL̉%|cG([i`ve` (w' $FTŠ"v!K̃%LX(B!!'qy c`Mu}k:7M#t"]cԎ&uPkHby73K$#l%:j^pF;ѬD U+5%bqq FO 6 B''@lIbsd=7Êp "Gu~ rkWŔE"0]Jƨ`Yf@\`=aY"LwgJ"G'M5S RTbdR(A D**"JRN,3ǴVAeTH= (ĸ'_0N*5ܤbőы7GQtZ-CpI{9m\%cY4XHzdBA?BUMnXM=Tp>H,rYI*BH TJ.FˋU f*D6%!03q,L@2X#6swx̬u?̑&*|d<>g#>{RkX)"c(²͘ (Z\M@!j`HLzJEw$9%[5#!pl@6F!0'x.@@Kx/![FFZ'J0 Xb8qNRн>1u$r#ɓ xqE}|.F5d bG1n^* m{Z51nUk>1}7[Ǧk4@E~rV <}.kk}%eꜳ.08?{j7c3o֨&@R50.Rэ@K|q,9#S0,s5Ib(zGN@Wb>vII"$&Ќvq2F -)7g"R/ $ #u4#[Ə.u'S1pxJL#sTq`l3:y}yA8JE㶮r_}c Lx=bAP YSBIY'Ɋ7]swǎL_aF&J;Pq8@=8ƏzEQLkX5:gCA8˚('~r%w2m6E%z(4R%}9vg-~A!ZARK@6MBl$@]V(7Q$8!QEE^BKY9X^21,K O*MŒ\̾:8R| s%Ȱf킣 n(ZB:SGz\xȐN6*&wH]wv񝠍OD/~q}/Iόg׌f4cibq\c}bz%cV&sx$F8D*w׈ⴏY" =MFǼx !,f)@ VZ2'm' n*9a$ୠyD" y$ 4.""(+.=iCAW4f^sk2d+ C?8x1_bK~5PD/$IN6X8eֳv"XM֢c9De1,Ш]\jqj!Ķ9ƖD87+X|ѿy4рX;(WNfuΧ!Ca+s5upO?<)r@9hxX+EV5/`4 2C1XSdžW(b  *Zױ±ƈpY%gHgC[ϊy<MtAyʰR 71;LŴDQ>qx|1Wk6;<2_x#Mo"y `B4Gg@  'J,¬o 욟i7 Z4`9bFj{xA&N8K>fdo!qJ#-=d0g%W1Y+~5O";{,FA?8c}dMy 0W8]'(*p fMD:iA,Xj3]~]_u,]`)lomiri-ui-extras-0.6.3/tests/unittests/assets/windmill_rotated_90.jpg000066400000000000000000001463041455543116500260340ustar00rootroot00000000000000JFIF1ExifII*  (1 2i!PanasonicDMC-GF1GIMP 2.8.102014:12:01 10:07:01PrintIM0250d  ' ''''^''''"BJ"'d0221Rfz   |H0100   )   @# 2014:01:26 01:06:382014:01:26 01:06:38d PanasonicQ !t"$%|&0291'()*+,-./0123456789:;<=>?@ABCD EFGHIJKLMN*OPQ"RS" T, UZ[\]^_`a: c0132V   $V&[9(?֯80 24&6?>AEfhjlnrg7]p+*-$*. " 0&@¦HD 6 "$&*>.Z(,024BD)FD|~JFHNX@B xz \ZdbfL " - WBbV 4f`de@BD4F{hjK"PȨP¨`ʨPĮ̃ƨ@Ψ $<&% <"%(*<,%.0.2 HJ LNPRTV etXZ46dddBDF8:<jtFDާ`b@BDFHJLNPRTVXZ\^ҧħ̧ΧЧʧd§ST "$&(*,.02468:<>NPRT`bdhfjpvVXES YC  ̫h FD"DD$XZ \ ^ `bdfhjln@ATB<"$&(*,.02468:>IAVDS.  CM DAEBM{}wqyt&*Bmy?Lerv$&c ilxnyb"f6PRSTFCCV_3_dZ? a$RGePaONq5ESYWeYd]8; s)PHiPaMN:93JRYWc]b^  "m-OHbLcPM;MUZVaZd[:8 "-PHhP`NNɶT;D< NOI %K&„\cW?]&P𨼀$U:4ZL2=*VfrD[,K\U6ЛI3?Xv }ƿv].<F-CM @cc>ֵuYتe cm l1Teiud_Ts5/$;G޻t? 'NGՙuhgrzc8EeFҼ(qQe̒E瞵gsU&p|MSZ!-՜Kt-WbDPUGmu}7O,5H0̊E?=+]i zm"HR)1RM""&*R)GLTRb SE+6)qK\ULR"[H{VpG;W<}+M߄.P:u^xnMuж" 6;溸~J0\dD.V:iF-͢xjqmZ2?..,DR$6: nuQ -k&ik'\P?*1ߓX-]ſkۧ݌xc56X6?N dwQYi8P?`OI'6tViPʒL#:tk8agvOEUazo=XOZw2J\h]BGi 0ƄtGE[:`#9`Ty&I'd^cEEQO&Hq>6\wiy+O% keh^( 7>^:r1PJI^+5SN=^yL-mNj%-nf)*#<ʸu]A\]30]ס2㶻D,ÃTMkr"-` Hs/?W5O:%}$M%v'FQ]j X?&5RQ0JhÖ<ZͻiΌ3cREBEz#"ixILRE?Q`$.)إP.)@F-_FY f|!Zef}Y><_*v*߇]u[1S5 HdKyRH2."ֲ|M& ^7uR,ÃaqYZ~gx'+13D͂p"=n.h-MЃn;wea9:K|[@iWιd/l 8@Xrr>?M6]OGfMp񥞏a7 `FA]KYu2%NQ{i E.lړ1]pyb+vrDWI SLLTRb,RRM#Q@.)SRN(@+k#,{M}P? {VfWJ1F#*zeV˄YxYsi/nnFIk dIcau讥,*M(=3I,J~gc+t#hԺ6?>6aiϭYơ2ҬC|v;QImtz~}p9ծ^4.<@V/ߖ ;K71  WNk#Zؼ\t1WC@vIPkϧ]/Qm FhZLST#` 1\敭^inC6"M@7ݻ=+F15]5ba%ܥ8U ILV)+#6E; niTRE!&)1@R␊m&()qN1 ;)B!RN;m3]m^¶]4gsQOju$îi~ɋU7%2'[a~xWxR\$3б5q #qW#=Z0OehopseBR\Wԭa.S9xZy.nfckn,Fg;g7ڜڋ$cZV0tܥj.JUab ɭp PH#fhWO0̧}TٝW $x&(t&(@b.Mj]P[iqHE "E?m p)TS!iiiBʹiivOȅC)1iK#mR⛻CG=mk?'KYEقMΩX=FCqp?K9'x O8>c\rFf`i2[<.B`{}@4i)+󏺧l ~j(ы3 VD{hIs⍵&6[hRm0!HVI!I+HV"+M"byP H(!E-PҊ(lj9Yn(/~z?ԓInUVDMOՇz( (Bw() P1 %PaC#=h@CC !   ڱ_dO O@G"f%S%H)L !*4|հ3(bO2spN d0dӣN-E(̸B J &CȉpQ2B \#$)ʝ8OΔ)KS,R(HGaJpPJpS$dJd"3H&ZIJR "H@D( JdD\!beܮTK%5(i$%|EtВ Bd d"d1de۾ RRr@JJ |pm{BGI%Z]W8S%) 2Iھ%2I1HBM:_>uE)$ Ta~aX|>xnm'> {⾿z:ŭLgi.X(!2FJ &/]QIM$H}ǔ(>-jӗEO~Re,^x/+ɢV٬CNJJ`)$b~.)lM7o]Kv MY%L>z2)1d -)Lmp|i->b;.2?/|Ձ]tymF-YON~ЦD dDR$1=~KmNO\_"j'FR%;5gk)lsU5EavO`NR_5VSp0Q?U*I!&ocn)qJF}nX6T[N-՝>!Rw;o:>iS#$dH$␓M_櫟 ȝ앷:v}3%our[9sG\caC6ԋ9o~7LKaEH6! /%$· ޳n0?uccM~I>ܾ0 y}GiAtwYaHA"lQub#k͍VWtam{}Ǝ8FG|#wl=f^} &BLO'bs}m 絷Nw&cKn&m}0~ _H_14U\=nφ?>N@ @R!:i'ouh>G}F/,pPYv6ǿEMQzkk[$`Fh,1q;5FQ`,0IVNI4>5o[K:l)}<E[_<O]g^c_)}PwVNɘ2#!HۓMš4'Uߘ6̾O}~꺺ծD`̵ןWp9 pu|Ϗ 4BCDRRbMR*9}x16_btVnލn2&0Zo(>w,6@R$Cd#!2 Cn)h O{Wׇn4l~۾ rv+rWnz!29a,4@a*D 6hM4#/oW٩W7vtv{?&5tQ͎~ 9" #dh)HMhNA)B9]lE~,/=!r{qZ G,y dC d Jd& *n-E14Li%1t5:'h,mP, wfUm}CeWھs]WrdqlBd'M&S!)O k/ľo]U{7]Ƀ|mOG2!SB MۋrM 6Bv7̓/c- UIg!!#,SNHm4Ӑh>W}t_Վ%yYhj})r@$fH)ӦJ4MM$)O]>6YZn42QrY &HSEu\"K HRSpb+ao;?IQ3gIs8 [I)RC*՜Zqi1$ Hy?{/QbY@p @SE?, 0@!"%#&}uu_} :BWuuBBӯ}+WU +u_B (PB +B_]WT(PjU(DK(PB(P]U|+PN'g\RlNOĵ3k9c՝'Y 7pt.I D|+u]PlF.Kcۆ_BAfɉ9LgSs3 6OP+]WºWk9: ?RS9j'8S!c~Sԥg'GG$ {Fi - СB u]W_LeeAlx5#.ND'ؤ CxIW9IqzoUS/H7xl`ZyZ8!DQtȡB (PBՉZ DB=SSYC4]x8ΜLN2 p3O7^~s7N g慴wwWlhAPB (PB w_U Q6aA#eKkZ5ntbZ,G8kZޢM<7gY$nԩTC$`ɜUB1)o^XtD_2x:*x0fS QB (WB1ɱ0`WUl]Ml@r|7rc^((0Gdk^܉,i&@#'xGNM ;gqC5HmnSXӈ3xv-Q3řx6bODvtD!{8g 9 MP$I/s4& HS#e(?$=!dq홊` 2ܛ4 @F-O6̅\77ws%n(7'||b[`dPPq)Qiᅄ|wZ db򣍂F&䐜)pZ va)yN2Op\XdQ0Ʋkz*dǙ$I 3&!?Jb{`gС_ f`CUƕܤmdTOg u]W]m4-) & 9FȡOur\r^>&ΏGme%f1Z9@xVvDyWHLQXw*h>SG G6fvpbly  +hG")-|CT?Kc}_1E<&RIIULNcNхK!6,6_Œ#k%EA-Y73II|[ 9\Ӎ T8=~`cP^Shi\O+ Q.K^ax$ / _* -8-$A [s1|IG0{j@IJ:-&BI$|"m=F#lHxc8"e<<˒_=,zBu_C[2MPl]eܦr we?ȐJ' ;v\(lF299ɥ)ED[[;{87vfjs sw(PB (WՁ\˺^M%%<·J2 \$r1۵jVL%yJ=r9UB (PB +w8 yr,JNV0nb^ܦs_DOTjfm+3FCJݳB (PB (PBR}KΧ`:՟%-rc+s39 S#kK诅uB (PB uBuB p:ݫ,ϛ /ʒdORI*@'pL(PB (PB (PB (PB (WF%HW_6m@Z1 ЭIHxv9CFB (PB (PB (PB (PB %&D]GߙPwSb% ~!K0h0;~1V(PB (PB (PB (PB (PBhA.3ݑ%nP॰3arG3Orնҵ膳"RKcf= (PB (PB  B (PB \dބЕ-,˞!1,;3xSޗYk0kbuB (PB (PB (c (PB (PvLe' H o"j^}o-- ߗ н(PB (PB (PB (g(PB (PB NYn+/%}B (PB (PB (PBp00+(PB (PgmRW51UYkv89B (PB (PB (PC#ry\Q&믘噴B! 1A0Qaq"#2R34@r$DSbcs?'rXCp.t =O:/4U_9h8U诤:_F u,fVKK6F8&aoi\=@h!2Lb!U`<%wUʥ–u`~_Bfy#j2mSPʪS,a{,9fTMKkg]U)=PWcK~*0jʾ7 s8h*ij߳jy&Q\uoZ"ϫ܏ 5wROQHIj$#8rvS._5؈0yuc s[rwUЩ`NPA-KZSaQqR7jqܤdSLZ+n߈ĥc ntU\UfWqN"9EԻRVaԈ\j%YY5F:7F723QJY²b/wH{u_m*qR5lݗT $6 s65yɪ<:?`8F& MQ-XQj鼽`^Y~aTpVC+fl:Mhܰ)M;;|!ϵ-wܬizJ! E'FNJV4-Y}8]Sʻ>P?iK 5:6Ғܺt\yGL&ֺk}1A!dFC'ZMcE\].z9+5jHV2G۟69$?T-k)c1#m=:F4;^|{-)ֿI|Nգ>fQ P kGHD>ҭ$2JoV>IN|~Z3]@Gs âk8rLdP9ĠAUℭ}w,60eҤmc\q$Y XlQsRfl,ssCX5ыe7/MU{}8X9߂hdG:]ێKuDTkz,.BV+ݴLS#/!䟬8'ިoIW@_WCާI~lM 8}БTI bBcUN2䢒L>Êc,m V!IJK=EMV[uLe!c4#Ht7c{U% { C#b؅Vph'pCAsEsAaH+ Z*CxgbM#2ii{É퉩e+ZUeu) ?qlfa\Z+q݇vX{=NFJqIR/ZsJ|2r0:^BRXmW'tUf'寡Ϳz)F=-/i[`ܢ iyġ^DH[ uC+d(D jm>pDQ7鏜U*F]=qHrRqcq]>ʣA*ۭlh{)&d*Ӎ~JtM#f(61~MsqzRI#m6dMrޭ+[bmh@E18+_:Gv^)RP/sdPga(`:L (!:J8lZ-ժBtFvbMĭU?_#9,㳳"\_ЉiaJp_"&D.8@̇SХlwӲti쎤LKҪ+=bVF^II l"3,KtemXj!YԲUȼY #4bi߼P;S^) {j<žzLtN'4E]yhëm `C[%|̬ i-aqrxo*TR>}i-Ld2ZڹSYR%۝}-]iG(z!uꋉ֑ZnUk٥&SNT0nP њli[/m`Wuin*S Lc^aAKM90Β:&Aqҥ'Ŕԁ}#HJ Թ S~#hU&ss|-N%p8dMmq;r2WN%6)3AX5M~A8.sL˅K'!0<#|&2)wfu<-W|LRM1Ӛn8I9|oN4xc)d5.&N?N*a-jDt撳U* [ԺeCXa~be1??XCB)-yP/ϫ:KqN$\qV[f} k GC-*N'^ͩJMl-A×J]TӟyHsM_'=NW#)*=!8"JWa#i~|""i=:~-tJlEHdtO72l/H5e-@`~~1IMK=MuZV.z:ڒm%in&IIN =vE,ҩQq肄$:-Nh V[6S99NQB9ztC4Ҩ#~YI*>VO"w\6uL)-laЮN%ek2rj-'KKnt%[`>t-T頔c&e+#?0U!tI77;5|N!v2mV-ˏɗ&*N:ol֋EƧ N0lRl/ |a3.(mmN=қw&\u* #R&mx"lZ,>7Se?:@2=T;=amWZ*Xie2%~7ۇgeJZ,jَ}m^rDeƒX KsNtۯFH'pN~NJHJK \GOͥ vE~q&j4oGgx'&U09$zEFzfUelANKY%DCw c(kWmUd[xmlsa,)76mω1T~+NgƉCwDdB.ښ/bvGqFMJzY$pT k(p _V!K"bZGpӘ q݅o03nmLYR @_N4 rhlX@61ҥSO<:3 ۳9E`gOpe-y@$ģ#%G2|ލ!՜Em8EgUXb_#'3 @#V !"1AQaq#2B3PRbr$@CS%Ds 5ETcdu?j(!H_"7ˆ[.:bQDNg\#A{pXmnl+aQ]0~|2q?U#v;q{qZmr\O~+NFmP'7?th Ӛ :bsu9u>vNJv V)j*U<3))O2HcĴ.v\B2v#R,O>eeg֩e"#o#a=ɞ|nM!jJcT4nNOYpo9dO9+N/sE¢1NQGڄ#ƤJ0-!N8m\h1K,6؍ꋻ{T`ṖQ KapZPPćjYt"3rSpq,s'h'2 eԄ8bϴqĈK[L.DkJuULRc#n!+%mmV$l4bKmMd.@ WKΥ'Rۋ] T0nCjBodEz«"ѵ7";Yд'n ^MY (Z}\eNcRUg0ߢ > (4'3O /3HgS~#ɫ3UE2jRZ-V '"b3STZ-z,9o.Mq6m>I7?ŐFζumjz,KgG)x<&d!7MyӖXE !kbՁmOf:QպV)n7^ܗhҬA)=bK%;4KKd}֮q%r/Z݆eɨUm1pV@\fސ;>S &pӷ]:G;~ W+z3u$Mv'eYp T(2H,[lqDOŔy%-'DT9[x[ِ5pakfݟ)m5'e>6Ov<5\LmƝz9om2˧ -6n?H!?ӹJ˚]1@HE%rTNE9tXbBm')lMv%'r`6 ,7:g=9`sŧ)^Qc|J8WG)eHK~*U)({;H:|6z'Gܸq?}=UEWCꬡ:-[vT6S(^> 1qV8ھҲ wiRnҦ@9N 8qGu6=Xҕ-,Vve CLi󆍈u?G`$aé;T/ivag*"a<*IAp=RM!J$L/}44Zr*K}JR V[b~]*onvYr2:g5j Xy ot-.5斕vFfmH#) P[e< UaӢNuaur\L85o5P*svpS 㶝KFoxa),Eo;ĉ'#d4S=6 ܏2Z]mǓqez) ӊJku8t(Q?誣'BOkAJI}IC1ugD<ތNj"J:KIqO9,7ZF9nVIY}g{f Z kx Ltju`C:(ٙ-q>DJ n#רڣSW5GDՇդٶ{eq<|yIK_zU`ɧ)CI)V\4㨎VklFF܇nXtxͦRu^^^*L~pyU{/û (^x*[%%\ʬAu*};4G%ѳ\}%[֞Z ftbԳUs46⢹" bM~g$֡sip V'к6IV%n;=m~A[O;p{El;v>|\<;~2K:=uJ#YsX+:ZWj(jdq2Á6Y}lz#-xLh{VG_FG.m.l_yYzaTTZn|Ib:Z[uHQ֢J7 ZɎJa.Uj6*uVm[tH --pLjB.G:5VmTy,+1q`_ fmgSaX\yl)+Z2O4t# 1 V%'qhؙu"-ժnxT_Xh%Q{K9QI<j|U9[<8b<^%:;2q 53|^>JDkjM@uyAr[Im-6]$Z ^t.C+2em%[mcW2hd)1B`-tu"@s))P(6ףti~/ ,sw&""i~]Ѥ$+)Z0,~qdUeY~'݄mMr,|n944 9Ss!n\?NKv1z;mݝC@Ij%E&JWWK[ഌ<.{0U~ npsZI)X>؝կLgbmxz,ϰajK >6s LPceum%^8TN̲^C!aCj12$UKe$'dbs"n9ڕF:< ʷZBT$xf<֣%]AG$\^]tQ6L/pTc"­[݇Q :9[Yrjdo)Im[ָӎ].-u'•vNXR }j(oVY}ȶn $*e'T ,1!Wp+nM&seڅ<,Mb 'KE1yL t1G"Se$Xw`R[Ne{W0$j lrÑdq % JR{bN?dJvE5v1_ |%Wii'4u$$-dzy`}Jm~n}ttALߒ ^ sҚ殢J).#mז>&Mvӕ'o4vaQ(DbԬy')m(hIlr%P嶛yxjr;}pL itr-FoCyO+ G aӫT9[𿔾.F7z8ed̢gWtw }؃6PGr"BNXn[IU˥* BHB8r:!P(]bjvɧ. {#i\ ÇaFRN^yQzXx skkلNT@˳]/lW]{qɲrS pH %RZQECudN[+2v N&3+aPGSلAuzlٞ,jZy[y4&GSJ)RriD y{Qi[SȲ)fH*r"h(:_)̑tZ(v[m#6j@[l0pcA25;0;/m/@\OK%(rev VWh;6GR$a)[> pOPi?iC[KBZ#VSMR1x}Pr1~'C6NNm1*.p MӘ-CSQanDP3e!L8%-#n8qFtԭp3Zc)jT:wiLP~>sḳ^5O:`Eoil -Z2tOv}#gC/Us'SPiDu'yI\]FE+怪D d=>U0mdeޞ*#E1[#Z>o^,E:ۚ3gj§U_nv2kn9PShQNx=%|3$ᆔ{Vu/!nJLv֧'Þ)n)wZk>̞8TWiJݔKRb*N])g.UlrGۄo o{SYkNasJRde;.y~nN{2"+b.'IV< WmzjDn%;D͊aDqlTn/E;?I:C8l!Vvi*4/PœqjqŒdVx+j5Gz^8]6tb2Wnusd>Ҟʛ= VB'6PԚ|st7flr2n@\rO[e:b{:6!^H$%"R[ Jϛ4JBs$xXǜ9[h)ş1 n˺+Vn2tEKtBW:S.gw{ʱ26mKl#-H Gߌ7Yk^M$CGlv+˻:x{OݎXrTfBww>=!Ve%Ys|4:ʢ:u[Iec*q:Y)g&<ꎔH'/ s&q5+]s#|.MN3nKFһ9(ߙyd48F#“ܔI`; ؏Vvhm̜"حSyt=d2̅(z_B;d36-LP|qHK{]"RUXSc+>J5X!ͣ3tBoTLRé<=X!e VQʂ$4Ї®ݬ2ڤ*a 9粱J';Wo)άǗ~iB,<ܸC&qD{ vaUsX|du- ^YO*i{Y dJӿVPl"@~䅼 Z=xuC^Q!CG9䱧ΊʓƓ sAᄱ)DBbmS-ʖXFx"YDNS~Ֆo(:;O0ijN$y3e1q &اߗZO)!1AQaq 0@?!BTP%J*WRJtTR+J]J*TRD*$HBRq*J*TRu*T]+Q:*T*TJ*TRJ+R}*TRD*$IRJ*TbJ05*RJ*T]R+utTNReJOQ$HJ*TRJ*W=?TI]D變+n$RD*TRJ*TWAjV3S QuSDÝB_ *WCJ變R *TP%J*@@"\XΜv$@*΀% [obsdV^YRyh5{!2CfEɺva_ #0] ] $]HtTDTP%J*TRJ26AY6eHTkdUp4i{x C 62Df m9,s3_{J9UĴ3 !0϶%KBJ=*WP%J*P G<xswtJ/0p`\%^bEUՠJ?:);*2w+yTr$d7Ju|8 ЊJ׆R NGZ;`* w5Si=C 0t'Et$IQ%DTT P JU~|ً}րSW>s^gE%ΟLl@*ͫf4}vT*ʗau=b{Ō 8|w(RT)KgNmSEB^%'S^@c,lLj0?&b h6҄12l(`Xy4,py_CZx.}Gi uq9@Y@y@%ט؎kڹzGRJ* P!mt?ܵw)k@ܻa 7+U|ʊlD0V+p,`d^zx5&}b -r32m4BfHqG G )s34f4: j]S|8 bQx3*պ136Jv!9;lu!/~&h;yBk\=xta*TRDV*%ATd( ]ٍAU;*,4.<5y\&ʨv?mp}E4,bc#DnjSj Y o"ʩȗe4 El=(9 ߉\+)|?NQzC#2/Yqf^mN ƪ\ x6ehRyaMpP*ȹe:~Ȑ.]jڿ?y5(82yPVnZ]\k# 'CЩ] P%@ʟa'Ki݈nvUn詵2z [bfxHX{P/V{jϛ9hv XkP\)a7b/5S |Br''mlm\8|Nk'H"(p~uf IRt_.xF.Ġcas 0aNNcYïFp34XHF*TJ*T P%@Tz=j~IH[^hni0n~`,nA@|\=n H Ta+TT+xIP%pYy!V),82X61N;1< j9u˙9X*Rv-6zVVfi55 wF斖[bcj޷^.6r?!UYZ~s HJ$ ǩ] %a%C dܯag6@ANB!` //Lցqh" kBBJT۫Vp"&uWYQpAHяzr1hY >(-rķ\d:U*~l{ 䲇&%&seP*t9Ώ7P44͘3+#(U>uZeJe^IR0÷C >T P J?2 (Z٫"jYt+0)n0~ x3a#PZ@bc 2VY}5vn. 谊`m{rҳP~6D/y#3P3t`Fy)j`kr+N+`*=j$R*> 0 A$:Vo-Ёxk յ1_Vmq‹MZ`orκAt(mܩ z@Tc>|0abKuz*TRJ$H a~:*EJbk ~w#gw%A"? De-eYjR7󒬧 h)Ө]-VuRJR*=~OECEB *TO8&t[]51L?J g''&'Ll7`1 RnTq@9]q vblJz`-O Pp@AG =]yru]>'p."u 4Ft 0+6@%$ijW2M&҆̽jg6N<h:@@=&|: Au?۫oc Y _P~gTu\݉ ][{`|)N+2gJl_/ 7G#2%N/}^=D^wL)=WZ~O_}>zL0@C b"v t"ꦴ!Tkjiw缪*9^>jgoN8ql0ô`t0᯿OsӷN@!G~4$ <Ȍ(?ywʳDR's+~t;Ozpy_w(*!?ӧ P⏅/4_wEA=h nK31g. шܺK n?be类^xeXd+[WYWm41y tݼbZDvwƻb 6LQ6A1E1-XRB`OSǎ)8#H/K@at" j*kɧӑc4vsH9"냡!4 Ma]e]@3b8:K_Ә{`>Rmׇ!%`iΓ ~S a䜕|x~_HXWv8:Fafq:\t h.c(̴sOS-|c0n '1ۙ=*RU.F]U]*ex4*|ӃK(ƃ!B^%_zC.ѹ} c̺:BVEcW0N̘}.TϺXңx#o陖/bP6M[Z3 y]s#Rq)}4V3$5 = `F?@v>3=<n} EK7{́c>36=ࢇcMļ&UKΦevt&Zz@\o uV_kWP:f)u{,XU;|) #ځ]P*g2"~Rbc8NYJ9mkp|.-P֗9am]Ӏxɡ_2e۶RK*`s3L}Rʄ\K+B45(}-@^=ykj!A-]cZIq -UP[5@jt{bϼ06!]/Wp"PPF@QLmLɅ9kf3܀ L%Tq!Lr>W0@ܺnףW -8P@ H"S (GpUM6\. ^0Kk'g"@wq\-gQP폸qh(HYx11??/h*_*smV=P紳?Igvh:rxWOW=0+fg~NG%~ᗪ>-,,b+d0%q(~OIj.ӧJ*2*7~!=~&SiQ|SP!T{4K>,:=c# Ffhb-BѸ72K5-s3 `*uG#1>T(_{cT/߬0zogŞ7̲r%]2f]qYt ιk2,Qo4.~N#{}QpuåSCe3KXZnW,b\l\2}0˸\/ f5!R똺j]LcXD-n}/1E,= zCU_2}+h5P?S}4˨K{>*Qw#!(No34GpG!zchC%|A%UAx3 A A:)".ru`ui6k*Qf]x$J5V"hc^.%2:K^I0laX&U2s-ij.tXZŭ`Ȇm<uA^rj 2c湋eX8hPQ1ɑ3\f*rKPa!es!~jG!w lV^j\ZP^VfUeh*_IZgPțLcA4P!l8v6'R/*ي8K q̽Ae0.l8C#i6+kSCd7wnm91љXnܽC tB fV(Jos1n0 ,C~V!F> ?zGD03PQ7ޓ&!1AQaq?4]J 4 hĥ3xu:̪Qz;T5O"*nĿP(AuuH+KuS(%Ubfe/2%k0iau, tFU+Ĭ\љKRJURgrVnWHAu2j!Pb*UJDV @ÙT*D Lͳ)rbq,%]ffV k1 @ޠ19b"J!*u)RB4-J0TbVe Z]|B}LXL!*3qeyp&`AI dVu@,ѻ,kM'ͼSXajY;QZPAeuEփ\|&R 1_mJ1*İqV x)ƙ CqDw䬘?47]{~=FG!UG|D|gn sV4NFZcAǕD,jp@/qMCUD \0j +0|_棙uWv'=d.C m{Fv"{pK* &[f)cMC7Y%(QߨWs }.&īQ5q+kcip<s'߿ZȞr@R8*R6,K`w#cF,( Q#9B;HvIUѵt9 v-m9趉z.QĬKR⬞P\ g v5GNv#*omdq`bdQAˉxSx-`} 6:ӟtsB*F;Zac Ja4$ 7 2"G[I`&RtB% cΟ-+[\(p2—R(9{-r|MM[KSXͮ9%=\xcVӃؙ@g*JJɈSVd%E3/9.2*W .ޙcqAM(6'83sWֆ8p0/{2z3@Na3$KhݲxyyhT,/KpGs85q jU߈)-% kQaOt{"Z dZ䷘u zc*?sF0LD`hekF2lQ8NU[qw%~"k)#&N _zEb}f\Q#{>˚\~0/*Q9~Jm\?(?`߾& B% 'Y^bd FZKnX[>=u7\exzJ0kʔs/ :(sK|ީ=`\ T}^~j3ZCPD ձ)Gگ.b\'P!QSu+ XSZ`,jSqb/owEql\NWTɦ'QVznydWfzǔU걃1{be/3ۍ?[2,~( q`iHbj3bOZ|]8 b~0uBLzGԄlyuэP^ :"xqٮ)2&YztxR$;HTɩ{}]WDM9bjH8RţLO[CLlhosvbvb+XIwQX u|w1lͿWg ل-Un w>0pd7hE]Ϭ#Ad{{rT<*U H\!P}SW% J|‚39Qe[ I8TzV#:B) WIɄAT`NN[t%K0 8$xuSe>16S$1-Z&Npz9>1|O: kɉh7=n^K?c9W;ƬX` {SX#ύ`V]?o _89pb,%eV ;:r DLDH~<Ц>*r# 0ŔΏ4%TH+scBP'Q̙"j/x*HqZ+vvkQ&ғ&!k*abV^"b#!1wx#f/snϜ αwC(5Gsy7Rjyc|XƱI3Įl1dX7q7_0sWU9kZ0!pIY$xx7B%zJIbAfK{&- ´2ԳW$I$ðBb+}d5ɴHy31J@Y[N@BaARI= ԒaE$q d 1N3˟E}0YHdfEUn79Ej!1yC5j~:n+D/~rۃXds8f`a!5tTD""yc?VL#xntr>0:&' *]aׇ^?yi[Z=6P|à S 'hJBI(BM؉ðrIPqZˀ:a TEԲڃ"Ad W L.c;AIi2K6@* 'hIB<ŝą)E\\%1d&.8M۪SqY*X93Zu|/w9x1.Pek#-2zǚA_|cVN'|c_X4M0'3}^D&4S}.t$$Nðrq u7__&Rt B0 [&؍/2)ϠBBЄ%4D"Wp KT f/+sEMbC WNԬ(*KA ]&'fd,%lJQ3j;x!. B_T.@AHaW=&H4ʓ (Dt8!Sw`DވquS8N25Do)l򗑪MdšOl#rsQAQ=c5Ł kxFX:|| 32a`~ވTNbrD{ƟDnc0+BM#ByڈiT  2"8섂30 _Qy1 HEt!-g$ՇMUlS `,H3u:nJ IR 5(  ! zPv4X}|41:MN~p",L,ɖx<7XI(qNq,B$˪xfHY]H3pXG&/x90?QĠA)'NXlMU# 6' l{vœۓ6.132LAvzT*!A@8) tWc4D䀐xV#r?3 ES ,tSZ/b@Bq@}ƚ@N0/M4e3( @xPQ~g s,%OY -k(^2C mkcFN%,3?xc-Z97ۄ}>4a y, ¦⵼7%yrutZcQ@CZ mWx\n U/$Ħ鳌ȴe8bOdLr`EI1^p)ڶcuoIAE~ bkB*m̒=BêD8tZQ@40c1(R:iT% L2ԐiڼȂAS% &"G!J 9R|Z%٠{%|'D\Ůl|B6%5E ɮToZZ2˸bDL:L@lÄp4t"qDF%#McR5  [sYZ&&->% MnL:qbi+-a@ЅXY&ɉĕdZ%NP1( <$bv.(a;" C^fz<yD1ܞQ3 3 ;+rH˽a0yaµn,TO^rUBW8 uAMm#ej$ B$@jp`4  v᭣ ;HBQ @cILX!{X%ȜaCHChu ra (ԩ"xJ^n' ;ƒTmdĬEj&$> 6]1`DlQ X<$EA1;. ,¨BW!beІ oX XߤS2㚏)*eHӴ[2n'1Cpœg L6qn%t(B %HZȁFy˙~%Px(uyďlCS8b;k%nx&w99#"OuxYP()[Im\%饰u-UM`n*2(ݜĒ2 G HJ^CSl  A8-YWʰ1CP4 rs#hħ3(b(R2|>_3L( bVuzF ]4$%pPSrՕv0MAd& IQEuDV `XJ<܎8N$@:e Dh1G.D/Hk+sx>c2T*R1KЦrXJڎ;hMLCo:"fW3P]հ:4Qtѻ'Ԗz08ҊO_jKƮTX"z6љ ); {e^P;$,-7U3IT3zrYY~7qn~=c x,U})5k<2]]pq/x:Ú˶E2# "H%2HRaWELrM9[E@4892hҁ4:%^bT(ojX'~؀%dO"j!ATܡ?c6H,nq9ht:@⥖_eC(AqN2Kȡ(EG5`Bst"Vw@wiDL̉%|cG([i`ve` (w' $FTŠ"v!K̃%LX(B!!'qy c`Mu}k:7M#t"]cԎ&uPkHby73K$#l%:j^pF;ѬD U+5%bqq FO 6 B''@lIbsd=7Êp "Gu~ rkWŔE"0]Jƨ`Yf@\`=aY"LwgJ"G'M5S RTbdR(A D**"JRN,3ǴVAeTH= (ĸ'_0N*5ܤbőы7GQtZ-CpI{9m\%cY4XHzdBA?BUMnXM=Tp>H,rYI*BH TJ.FˋU f*D6%!03q,L@2X#6swx̬u?̑&*|d<>g#>{RkX)"c(²͘ (Z\M@!j`HLzJEw$9%[5#!pl@6F!0'x.@@Kx/![FFZ'J0 Xb8qNRн>1u$r#ɓ xqE}|.F5d bG1n^* m{Z51nUk>1}7[Ǧk4@E~rV <}.kk}%eꜳ.08?{j7c3o֨&@R50.Rэ@K|q,9#S0,s5Ib(zGN@Wb>vII"$&Ќvq2F -)7g"R/ $ #u4#[Ə.u'S1pxJL#sTq`l3:y}yA8JE㶮r_}c Lx=bAP YSBIY'Ɋ7]swǎL_aF&J;Pq8@=8ƏzEQLkX5:gCA8˚('~r%w2m6E%z(4R%}9vg-~A!ZARK@6MBl$@]V(7Q$8!QEE^BKY9X^21,K O*MŒ\̾:8R| s%Ȱf킣 n(ZB:SGz\xȐN6*&wH]wv񝠍OD/~q}/Iόg׌f4cibq\c}bz%cV&sx$F8D*w׈ⴏY" =MFǼx !,f)@ VZ2'm' n*9a$ୠyD" y$ 4.""(+.=iCAW4f^sk2d+ C?8x1_bK~5PD/$IN6X8eֳv"XM֢c9De1,Ш]\jqj!Ķ9ƖD87+X|ѿy4рX;(WNfuΧ!Ca+s5upO?<)r@9hxX+EV5/`4 2C1XSdžW(b  *Zױ±ƈpY%gHgC[ϊy<MtAyʰR 71;LŴDQ>qx|1Wk6;<2_x#Mo"y `B4Gg@  'J,¬o 욟i7 Z4`9bFj{xA&N8K>fdo!qJ#-=d0g%W1Y+~5O";{,FA?8c}dMy 0W8]'(*p fMD:iA,Xj3]~]_u,]`)lomiri-ui-extras-0.6.3/tests/unittests/sampledata.qrc000066400000000000000000000005011455543116500227650ustar00rootroot00000000000000 assets/testfile.jpg assets/testfile_portrait.jpg assets/windmill_rotated_90.jpg assets/windmill.jpg assets/thorns.jpg assets/croptest.png lomiri-ui-extras-0.6.3/tests/unittests/tst_ExampleModelTests.cpp000066400000000000000000000022771455543116500251540ustar00rootroot00000000000000/* * Copyright 2013 Canonical Ltd. * * This file is part of lomiri-ui-extras. * * ubuntu-ui-extras 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; version 3. * * ubuntu-ui-extras 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 . */ // Qt #include #include #include #include // local #include "example-model.h" class ExampleModelTests : public QObject { Q_OBJECT private: ExampleModel* model; private Q_SLOTS: void init() { model = new ExampleModel; } void cleanup() { delete model; } void shouldHaveThreeItems() { QCOMPARE(model->rowCount(), 3); } }; QTEST_MAIN(ExampleModelTests) #include "tst_ExampleModelTests.moc" lomiri-ui-extras-0.6.3/tests/unittests/tst_PhotoEditorPhoto.cpp000066400000000000000000000175741455543116500250350ustar00rootroot00000000000000/* * Copyright (C) 2014 Canonical Ltd. * * 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; version 3. * * 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 . */ #include "photo-data.h" #include #include #include #include #include #include #include #include class PhotoEditorPhotoTest: public QObject { Q_OBJECT private Q_SLOTS: void initTestCase(); void testBasicProperties(); void testOrientation(); void testRefresh(); void testRotate(); void testCrop(); void testCropWithExifOrientation(); void cleanupTestCase(); private: QTemporaryDir m_workingDir; }; void PhotoEditorPhotoTest::initTestCase() { QDir rc = QDir(":/assets/"); QDir dest = QDir(m_workingDir.path()); Q_FOREACH(const QString &name, rc.entryList()) { QFile::copy(rc.absoluteFilePath(name), dest.absoluteFilePath(name)); QFile::setPermissions(dest.absoluteFilePath(name), QFile::WriteOwner | QFile::ReadOwner); } m_workingDir.setAutoRemove(false); } void PhotoEditorPhotoTest::cleanupTestCase() { // temporary dir will be deleted when m_workingDir goes out of scope } void PhotoEditorPhotoTest::testBasicProperties() { QDir source = QDir(m_workingDir.path()); QString path = source.absoluteFilePath("windmill.jpg"); PhotoData photo; photo.setPath(path); QVERIFY(photo.path() == path); QVERIFY(photo.file() == QFileInfo(path)); QVERIFY(photo.fileFormat() == "jpeg"); QVERIFY(photo.fileFormatHasMetadata() == true); QVERIFY(photo.fileFormatHasOrientation() == true); } void PhotoEditorPhotoTest::testOrientation() { QDir source = QDir(m_workingDir.path()); QString path = source.absoluteFilePath("windmill.jpg"); PhotoData photo; photo.setPath(path); QVERIFY(photo.orientation() == TOP_LEFT_ORIGIN); PhotoData photo2; QString path2 = source.absoluteFilePath("windmill_rotated_90.jpg"); photo2.setPath(path2); QVERIFY(photo2.orientation() == RIGHT_TOP_ORIGIN); // Test updating the original PhotoData by changing path photo.setPath(path2); QVERIFY(photo.orientation() == RIGHT_TOP_ORIGIN); } void PhotoEditorPhotoTest::testRefresh() { // Work on a copy to avoid disturbing other tests QDir source = QDir(m_workingDir.path()); QString path = source.absoluteFilePath("testrefresh.jpg"); qDebug() << QFile::copy(source.absoluteFilePath("windmill.jpg"), path); // Load the file. PhotoData photo; photo.setPath(path); Orientation orientation = photo.orientation(); // Now overwrite it with another file with different rotation and verify // the new data is correct QFile::remove(path); QFile::copy(source.absoluteFilePath("windmill_rotated_90.jpg"), path); photo.refreshFromDisk(); QVERIFY(orientation != photo.orientation()); } void PhotoEditorPhotoTest::testRotate() { // Work on a copy to avoid disturbing other tests QDir source = QDir(m_workingDir.path()); QString path = source.absoluteFilePath("testrotate.jpg"); QFile::remove(path); QFile::copy(source.absoluteFilePath("windmill.jpg"), path); PhotoData photo; photo.setPath(path); QVERIFY(photo.path() == path); QVERIFY(photo.orientation() == TOP_LEFT_ORIGIN); QSignalSpy spy(&photo, SIGNAL(busyChanged())); photo.rotateRight(); spy.wait(5000); QVERIFY(photo.orientation() == RIGHT_TOP_ORIGIN); spy.clear(); photo.rotateRight(); spy.wait(5000); QVERIFY(photo.orientation() == BOTTOM_RIGHT_ORIGIN); spy.clear(); photo.rotateRight(); spy.wait(5000); QVERIFY(photo.orientation() == LEFT_BOTTOM_ORIGIN); spy.clear(); photo.rotateRight(); spy.wait(5000); QVERIFY(photo.orientation() == TOP_LEFT_ORIGIN); } void PhotoEditorPhotoTest::testCrop() { QDir source = QDir(m_workingDir.path()); QString path = source.absoluteFilePath("tmp.png"); QFile::remove(path); QFile::copy(source.absoluteFilePath("croptest.png"), path); PhotoData photo; photo.setPath(path); // Verify cropping a vertical strip at the left edge QSignalSpy spy(&photo, SIGNAL(busyChanged())); photo.crop(QRectF(0, 0, 0.1, 1.0)); spy.wait(5000); QImage cropped(path); QImage compare(QSize(10, 100), cropped.format()); compare.fill(QColor(0, 0, 0)); QVERIFY(compare == cropped); // Verify cropping a square from the center QFile::remove(path); QFile::copy(source.absoluteFilePath("croptest.png"), path); photo.setPath(path); spy.clear(); photo.crop(QRectF(0.4, 0.4, 0.2, 0.2)); spy.wait(5000); cropped = QImage(path); compare = QImage(QSize(20, 20), cropped.format()); compare.fill(QColor(0, 255, 0)); QVERIFY(compare == cropped); // Verify cropping a thin strip from the top after rotating the image. // Incidentally this also tests rotation of an image without EXIF tags QFile::remove(path); QFile::copy(source.absoluteFilePath("croptest.png"), path); photo.setPath(path); spy.clear(); photo.rotateRight(); spy.wait(5000); spy.clear(); photo.crop(QRectF(0.0, 0.0, 1.0, 0.1)); spy.wait(5000); cropped = QImage(path); compare = QImage(QSize(100, 10), cropped.format()); compare.fill(QColor(0, 0, 0)); QVERIFY(compare == cropped); // When rotating an image without EXIF, the orientation is fixed QVERIFY(photo.orientation() == TOP_LEFT_ORIGIN); // Test progressive cropping by carving off the bottom horizontal strip and // then cropping the center part of it QFile::remove(path); QFile::copy(source.absoluteFilePath("croptest.png"), path); photo.setPath(path); spy.clear(); photo.crop(QRectF(0.0, 0.9, 1.0, 0.1)); spy.wait(5000); spy.clear(); photo.crop(QRectF(0.1, 0.0, 0.8, 1.0)); spy.wait(5000); cropped = QImage(path); compare = QImage(QSize(80, 10), cropped.format()); compare.fill(QColor(0, 0, 255)); QVERIFY(compare == cropped); // Test a cropping rectangle outside of boundaries QFile::remove(path); QFile::copy(source.absoluteFilePath("croptest.png"), path); photo.setPath(path); spy.clear(); photo.crop(QRectF(-1.0, -100.0, 2405.0, 2.0)); spy.wait(5000); cropped = QImage(path); QVERIFY(cropped.size() == QSize(100, 100)); } void PhotoEditorPhotoTest::testCropWithExifOrientation() { QDir source = QDir(m_workingDir.path()); QString path = source.absoluteFilePath("windmill_rotated_90.jpg"); PhotoData photoData; photoData.setPath(path); QVERIFY(photoData.orientation() == RIGHT_TOP_ORIGIN); QImageReader photoImageReader(path); #if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)) photoImageReader.setAutoTransform(true); #endif QImage photoImage = photoImageReader.read(); // Crop a vertical strip at the left edge QSignalSpy spy(&photoData, SIGNAL(busyChanged())); photoData.crop(QRectF(0, 0, 0.1, 1.0)); spy.wait(5000); PhotoData croppedData; croppedData.setPath(path); QVERIFY(croppedData.orientation() == TOP_LEFT_ORIGIN); QImageReader croppedReader(path); #if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)) croppedReader.setAutoTransform(true); #endif QImage croppedImage = croppedReader.read(); // That crop should not have changed the height QVERIFY(croppedImage.height() == photoImage.height()); } QTEST_MAIN(PhotoEditorPhotoTest) #include "tst_PhotoEditorPhoto.moc" lomiri-ui-extras-0.6.3/tests/unittests/tst_PhotoEditorPhotoImageProvider.cpp000066400000000000000000000065501455543116500275030ustar00rootroot00000000000000/* * Copyright (C) 2014 Canonical Ltd. * * 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; version 3. * * 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 . */ #include "photo-image-provider.h" #include #include #include #include #include #include #include const int SCALED_LOAD_FLOOR = 360; class PhotoEditorPhotoImageProviderTest: public QObject { Q_OBJECT private Q_SLOTS: void init(); void cleanup(); void initTestCase(); void testEmptyOrInvalid(); void testNoResize(); void testWithResize(); private: PhotoImageProvider *m_provider; QTemporaryDir m_workingDir; }; void PhotoEditorPhotoImageProviderTest::initTestCase() { QDir rc = QDir(":/assets/"); QDir dest = QDir(m_workingDir.path()); Q_FOREACH(const QString &name, rc.entryList()) { QFile::copy(rc.absoluteFilePath(name), dest.absoluteFilePath(name)); QFile::setPermissions(dest.absoluteFilePath(name), QFile::WriteOwner | QFile::ReadOwner); } } void PhotoEditorPhotoImageProviderTest::init() { m_provider = new PhotoImageProvider(); } void PhotoEditorPhotoImageProviderTest::cleanup() { // temporary dir will be deleted when m_workingDir goes out of scope delete m_provider; } void PhotoEditorPhotoImageProviderTest::testNoResize() { QSize imageSize(400, 267); // Work on a copy to avoid disturbing other tests QDir source = QDir(m_workingDir.path()); QString path = source.absoluteFilePath("testcache.jpg"); QFile::remove(path); QFile::copy(source.absoluteFilePath("windmill.jpg"), path); QImage image = m_provider->requestImage(path, 0, QSize()); QVERIFY(!image.isNull()); QVERIFY(image.size() == imageSize); } void PhotoEditorPhotoImageProviderTest::testWithResize() { QSize imageSize(1408, 768); // Work on a copy to avoid disturbing other tests QDir source = QDir(m_workingDir.path()); QString path = source.absoluteFilePath("testcache.jpg"); QFile::remove(path); QFile::copy(source.absoluteFilePath("thorns.jpg"), path); QSize small(1408 / 4, 768 / 4); // Request a size smaller than the image QImage image = m_provider->requestImage(path, 0, small); QVERIFY(image.size() == small); // Request the full size image = m_provider->requestImage(path, 0, imageSize); QVERIFY(image.size() == imageSize); // Verify that requesting a smaller size still works image = m_provider->requestImage(path, 0, small); QVERIFY(image.size() == small); } void PhotoEditorPhotoImageProviderTest::testEmptyOrInvalid() { QImage image = m_provider->requestImage("", 0, QSize()); QVERIFY(image.isNull()); image = m_provider->requestImage("do-not-exist.jpg", 0, QSize()); QVERIFY(image.isNull()); } QTEST_MAIN(PhotoEditorPhotoImageProviderTest) #include "tst_PhotoEditorPhotoImageProvider.moc"